From add18301143dcacf6a95c0bbfa74971d065f6dba Mon Sep 17 00:00:00 2001 From: anatoly yakovenko Date: Fri, 16 Oct 2020 10:38:12 -0700 Subject: [PATCH 0001/1076] Token stake pool (#493) * init * instructions * instruction progress * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * update * wip * update * wip * clippy * builds * builds * wip test * init testcargo fmt * update * wip stake instructions * wip * comment * update * update * update * init cli * Address review comments Co-authored-by: Jon Cinque --- README.md | 14 +- clients/cli/Cargo.toml | 24 ++ clients/cli/README.md | 3 + clients/cli/src/main.rs | 811 +++++++++++++++++++++++++++++++++++++ program/Cargo.toml | 36 ++ program/Xargo.toml | 2 + program/program-id.md | 1 + program/src/entrypoint.rs | 24 ++ program/src/error.rs | 53 +++ program/src/instruction.rs | 180 ++++++++ program/src/lib.rs | 16 + program/src/processor.rs | 617 ++++++++++++++++++++++++++++ program/src/stake.rs | 148 +++++++ program/src/state.rs | 114 ++++++ 14 files changed, 2041 insertions(+), 2 deletions(-) create mode 100644 clients/cli/Cargo.toml create mode 100644 clients/cli/README.md create mode 100644 clients/cli/src/main.rs create mode 100644 program/Cargo.toml create mode 100644 program/Xargo.toml create mode 100644 program/program-id.md create mode 100644 program/src/entrypoint.rs create mode 100644 program/src/error.rs create mode 100644 program/src/instruction.rs create mode 100644 program/src/lib.rs create mode 100644 program/src/processor.rs create mode 100644 program/src/stake.rs create mode 100644 program/src/state.rs diff --git a/README.md b/README.md index 3567af82..2ec24679 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,12 @@ -# stake-pool -The SPL Stake Pool program and its clients +# stake-pool program + +A work-in-progress program for pooling together SOL to be staked by an off-chain +agent running SoM (Stake-o-Matic). + +Each SoM needs at least one pool. Users deposit stakes into the SoM pool +and receives a pool token minus the fee. The SoM redistributes the stakes +across the network and tries to maximize censorship resistance and rewards. + +Full documentation is available at https://spl.solana.com + +Javascript bindings are available in the `./js` directory. diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml new file mode 100644 index 00000000..f4b67484 --- /dev/null +++ b/clients/cli/Cargo.toml @@ -0,0 +1,24 @@ +[package] +authors = ["Solana Maintainers "] +description = "SPL-Stake-Pool Command-line Utility" +edition = "2018" +homepage = "https://spl.solana.com/stake-pool" +license = "Apache-2.0" +name = "spl-stake-pool-cli" +repository = "https://github.com/solana-labs/solana-program-library" +version = "2.0.1" + +[dependencies] +clap = "2.33.3" +serde_json = "1.0.57" +solana-account-decoder = { version = "1.3.9" } +solana-clap-utils = { version = "1.3.9"} +solana-cli-config = { version = "1.3.9" } +solana-client = { version = "1.3.9" } +solana-logger = { version = "1.3.9" } +solana-sdk = { version = "1.3.9" } +spl-stake-pool = { version = "2.0", path="../program" } + +[[bin]] +name = "spl-stake-pool" +path = "src/main.rs" diff --git a/clients/cli/README.md b/clients/cli/README.md new file mode 100644 index 00000000..1016e9e4 --- /dev/null +++ b/clients/cli/README.md @@ -0,0 +1,3 @@ +# SPL Stake Pool program command-line utility + +A basic command-line for creating and using SPL Stake Pools. See https://spl.solana.com/stake-pool for more details diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs new file mode 100644 index 00000000..dccfbdd9 --- /dev/null +++ b/clients/cli/src/main.rs @@ -0,0 +1,811 @@ +use clap::{ + crate_description, crate_name, crate_version, value_t, value_t_or_exit, App, AppSettings, Arg, + SubCommand, +}; +use solana_account_decoder::{parse_token::TokenAccountType, UiAccountData}; +use solana_clap_utils::{ + input_parsers::pubkey_of, + input_validators::{is_amount, is_keypair, is_pubkey_or_keypair, is_url}, + keypair::signer_from_path, +}; +use solana_client::{rpc_client::RpcClient, rpc_request::TokenAccountsFilter}; +use solana_sdk::{ + commitment_config::CommitmentConfig, + native_token::*, + pubkey::Pubkey, + signature::{Keypair, Signer}, + system_instruction, + transaction::Transaction, +}; +use spl_token::{ + self, + instruction::*, + native_mint, + pack::Pack, + state::{Account, Mint}, +}; +use std::process::exit; + +struct Config { + rpc_client: RpcClient, + verbose: bool, + owner: Box, + fee_payer: Box, + commitment_config: CommitmentConfig, +} + +type Error = Box; +type CommandResult = Result, Error>; + +macro_rules! unique_signers { + ($vec:ident) => { + $vec.sort_by_key(|l| l.pubkey()); + $vec.dedup(); + }; +} + +fn check_fee_payer_balance(config: &Config, required_balance: u64) -> Result<(), Error> { + let balance = config.rpc_client.get_balance(&config.fee_payer.pubkey())?; + if balance < required_balance { + Err(format!( + "Fee payer, {}, has insufficient balance: {} required, {} available", + config.fee_payer.pubkey(), + lamports_to_sol(required_balance), + lamports_to_sol(balance) + ) + .into()) + } else { + Ok(()) + } +} + +fn check_owner_balance(config: &Config, required_balance: u64) -> Result<(), Error> { + let balance = config.rpc_client.get_balance(&config.owner.pubkey())?; + if balance < required_balance { + Err(format!( + "Owner, {}, has insufficient balance: {} required, {} available", + config.owner.pubkey(), + lamports_to_sol(required_balance), + lamports_to_sol(balance) + ) + .into()) + } else { + Ok(()) + } +} + +fn command_create_token(config: &Config, decimals: u8) -> CommandResult { + let token = Keypair::new(); + println!("Creating token {}", token.pubkey()); + + let minimum_balance_for_rent_exemption = config + .rpc_client + .get_minimum_balance_for_rent_exemption(Mint::LEN)?; + + let mut transaction = Transaction::new_with_payer( + &[ + system_instruction::create_account( + &config.fee_payer.pubkey(), + &token.pubkey(), + minimum_balance_for_rent_exemption, + Mint::LEN as u64, + &spl_token::id(), + ), + initialize_mint( + &spl_token::id(), + &token.pubkey(), + &config.owner.pubkey(), + None, + decimals, + )?, + ], + Some(&config.fee_payer.pubkey()), + ); + + let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + check_fee_payer_balance( + config, + minimum_balance_for_rent_exemption + fee_calculator.calculate_fee(&transaction.message()), + )?; + let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref(), &token]; + unique_signers!(signers); + transaction.sign(&signers, recent_blockhash); + Ok(Some(transaction)) +} + +fn command_create_account(config: &Config, token: Pubkey) -> CommandResult { + let account = Keypair::new(); + println!("Creating account {}", account.pubkey()); + + let minimum_balance_for_rent_exemption = config + .rpc_client + .get_minimum_balance_for_rent_exemption(Account::LEN)?; + + let mut transaction = Transaction::new_with_payer( + &[ + system_instruction::create_account( + &config.fee_payer.pubkey(), + &account.pubkey(), + minimum_balance_for_rent_exemption, + Account::LEN as u64, + &spl_token::id(), + ), + initialize_account( + &spl_token::id(), + &account.pubkey(), + &token, + &config.owner.pubkey(), + )?, + ], + Some(&config.fee_payer.pubkey()), + ); + + let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + check_fee_payer_balance( + config, + minimum_balance_for_rent_exemption + fee_calculator.calculate_fee(&transaction.message()), + )?; + let mut signers = vec![config.fee_payer.as_ref(), &account, config.owner.as_ref()]; + unique_signers!(signers); + transaction.sign(&signers, recent_blockhash); + Ok(Some(transaction)) +} + +fn command_assign(config: &Config, account: Pubkey, new_owner: Pubkey) -> CommandResult { + println!( + "Assigning {}\n Current owner: {}\n New owner: {}", + account, + config.owner.pubkey(), + new_owner + ); + + let mut transaction = Transaction::new_with_payer( + &[set_authority( + &spl_token::id(), + &account, + Some(&new_owner), + AuthorityType::AccountOwner, + &config.owner.pubkey(), + &[], + )?], + Some(&config.fee_payer.pubkey()), + ); + + let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; + let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()]; + unique_signers!(signers); + transaction.sign(&signers, recent_blockhash); + Ok(Some(transaction)) +} + +fn command_transfer( + config: &Config, + sender: Pubkey, + ui_amount: f64, + recipient: Pubkey, +) -> CommandResult { + println!( + "Transfer {} tokens\n Sender: {}\n Recipient: {}", + ui_amount, sender, recipient + ); + + let sender_token_balance = config + .rpc_client + .get_token_account_balance_with_commitment(&sender, config.commitment_config)? + .value; + let source_account = config + .rpc_client + .get_account_with_commitment(&sender, config.commitment_config)? + .value + .unwrap_or_default(); + let data = source_account.data.to_vec(); + let mint_pubkey = Account::unpack_from_slice(&data)?.mint; + let amount = spl_token::ui_amount_to_amount(ui_amount, sender_token_balance.decimals); + + let mut transaction = Transaction::new_with_payer( + &[transfer2( + &spl_token::id(), + &sender, + &mint_pubkey, + &recipient, + &config.owner.pubkey(), + &[], + amount, + sender_token_balance.decimals, + )?], + Some(&config.fee_payer.pubkey()), + ); + + let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; + let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()]; + unique_signers!(signers); + transaction.sign(&signers, recent_blockhash); + Ok(Some(transaction)) +} + +fn command_burn(config: &Config, source: Pubkey, ui_amount: f64) -> CommandResult { + println!("Burn {} tokens\n Source: {}", ui_amount, source); + + let source_token_balance = config + .rpc_client + .get_token_account_balance_with_commitment(&source, config.commitment_config)? + .value; + let source_account = config + .rpc_client + .get_account_with_commitment(&source, config.commitment_config)? + .value + .unwrap_or_default(); + let data = source_account.data.to_vec(); + let mint_pubkey = Account::unpack_from_slice(&data)?.mint; + let amount = spl_token::ui_amount_to_amount(ui_amount, source_token_balance.decimals); + let mut transaction = Transaction::new_with_payer( + &[burn2( + &spl_token::id(), + &source, + &mint_pubkey, + &config.owner.pubkey(), + &[], + amount, + source_token_balance.decimals, + )?], + Some(&config.fee_payer.pubkey()), + ); + + let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; + let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()]; + unique_signers!(signers); + transaction.sign(&signers, recent_blockhash); + Ok(Some(transaction)) +} + +fn command_mint( + config: &Config, + token: Pubkey, + ui_amount: f64, + recipient: Pubkey, +) -> CommandResult { + println!( + "Minting {} tokens\n Token: {}\n Recipient: {}", + ui_amount, token, recipient + ); + + let recipient_token_balance = config + .rpc_client + .get_token_account_balance_with_commitment(&recipient, config.commitment_config)? + .value; + let amount = spl_token::ui_amount_to_amount(ui_amount, recipient_token_balance.decimals); + + let mut transaction = Transaction::new_with_payer( + &[mint_to2( + &spl_token::id(), + &token, + &recipient, + &config.owner.pubkey(), + &[], + amount, + recipient_token_balance.decimals, + )?], + Some(&config.fee_payer.pubkey()), + ); + + let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; + let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()]; + unique_signers!(signers); + transaction.sign(&signers, recent_blockhash); + Ok(Some(transaction)) +} + +fn command_wrap(config: &Config, sol: f64) -> CommandResult { + let account = Keypair::new(); + let lamports = sol_to_lamports(sol); + println!("Wrapping {} SOL into {}", sol, account.pubkey()); + + let mut transaction = Transaction::new_with_payer( + &[ + system_instruction::create_account( + &config.owner.pubkey(), + &account.pubkey(), + lamports, + Account::LEN as u64, + &spl_token::id(), + ), + initialize_account( + &spl_token::id(), + &account.pubkey(), + &native_mint::id(), + &config.owner.pubkey(), + )?, + ], + Some(&config.fee_payer.pubkey()), + ); + + let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + check_owner_balance(config, lamports)?; + check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; + let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref(), &account]; + unique_signers!(signers); + transaction.sign(&signers, recent_blockhash); + Ok(Some(transaction)) +} + +fn command_unwrap(config: &Config, address: Pubkey) -> CommandResult { + println!("Unwrapping {}", address); + println!( + " Amount: {} SOL\n Recipient: {}", + lamports_to_sol( + config + .rpc_client + .get_balance_with_commitment(&address, config.commitment_config)? + .value + ), + config.owner.pubkey() + ); + + let mut transaction = Transaction::new_with_payer( + &[close_account( + &spl_token::id(), + &address, + &config.owner.pubkey(), + &config.owner.pubkey(), + &[], + )?], + Some(&config.fee_payer.pubkey()), + ); + + let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; + let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()]; + unique_signers!(signers); + transaction.sign(&signers, recent_blockhash); + Ok(Some(transaction)) +} + +fn command_balance(config: &Config, address: Pubkey) -> CommandResult { + let balance = config + .rpc_client + .get_token_account_balance_with_commitment(&address, config.commitment_config)? + .value; + + if config.verbose { + println!("ui amount: {}", balance.ui_amount); + println!("decimals: {}", balance.decimals); + println!("amount: {}", balance.amount); + } else { + println!("{}", balance.ui_amount); + } + Ok(None) +} + +fn command_supply(config: &Config, address: Pubkey) -> CommandResult { + let supply = config + .rpc_client + .get_token_supply_with_commitment(&address, config.commitment_config)? + .value; + + println!("{}", supply.ui_amount); + Ok(None) +} + +fn command_accounts(config: &Config, token: Option) -> CommandResult { + let accounts = config + .rpc_client + .get_token_accounts_by_owner_with_commitment( + &config.owner.pubkey(), + match token { + Some(token) => TokenAccountsFilter::Mint(token), + None => TokenAccountsFilter::ProgramId(spl_token::id()), + }, + config.commitment_config, + )? + .value; + if accounts.is_empty() { + println!("None"); + } + + println!("Account Token Balance"); + println!("-------------------------------------------------------------------------------------------------"); + for keyed_account in accounts { + let address = keyed_account.pubkey; + + if let UiAccountData::Json(parsed_account) = keyed_account.account.data { + if parsed_account.program != "spl-token" { + println!( + "{:<44} Unsupported account program: {}", + address, parsed_account.program + ); + } else { + match serde_json::from_value(parsed_account.parsed) { + Ok(TokenAccountType::Account(ui_token_account)) => println!( + "{:<44} {:<44} {}", + address, ui_token_account.mint, ui_token_account.token_amount.ui_amount + ), + Ok(_) => println!("{:<44} Unsupported token account", address), + Err(err) => println!("{:<44} Account parse failure: {}", address, err), + } + } + } else { + println!("{:<44} Unsupported account data format", address); + } + } + Ok(None) +} + +fn main() { + let default_decimals = &format!("{}", native_mint::DECIMALS); + let matches = App::new(crate_name!()) + .about(crate_description!()) + .version(crate_version!()) + .setting(AppSettings::SubcommandRequiredElseHelp) + .arg({ + let arg = Arg::with_name("config_file") + .short("C") + .long("config") + .value_name("PATH") + .takes_value(true) + .global(true) + .help("Configuration file to use"); + if let Some(ref config_file) = *solana_cli_config::CONFIG_FILE { + arg.default_value(&config_file) + } else { + arg + } + }) + .arg( + Arg::with_name("verbose") + .long("verbose") + .short("v") + .takes_value(false) + .global(true) + .help("Show additional information"), + ) + .arg( + Arg::with_name("json_rpc_url") + .long("url") + .value_name("URL") + .takes_value(true) + .validator(is_url) + .help("JSON RPC URL for the cluster. Default from the configuration file."), + ) + .arg( + Arg::with_name("owner") + .long("owner") + .value_name("KEYPAIR") + .validator(is_keypair) + .takes_value(true) + .help( + "Specify the token owner account. \ + This may be a keypair file, the ASK keyword. \ + Defaults to the client keypair.", + ), + ) + .arg( + Arg::with_name("fee_payer") + .long("fee-payer") + .value_name("KEYPAIR") + .validator(is_keypair) + .takes_value(true) + .help( + "Specify the fee-payer account. \ + This may be a keypair file, the ASK keyword. \ + Defaults to the client keypair.", + ), + ) + .subcommand(SubCommand::with_name("create-token").about("Create a new token") + .arg( + Arg::with_name("decimals") + .long("decimals") + .validator(|s| { + s.parse::().map_err(|e| format!("{}", e))?; + Ok(()) + }) + .value_name("DECIMALS") + .takes_value(true) + .default_value(&default_decimals) + .help("Number of base 10 digits to the right of the decimal place"), + ) + ) + .subcommand( + SubCommand::with_name("create-account") + .about("Create a new token account") + .arg( + Arg::with_name("token") + .validator(is_pubkey_or_keypair) + .value_name("TOKEN_ADDRESS") + .takes_value(true) + .index(1) + .required(true) + .help("The token that the account will hold"), + ), + ) + .subcommand( + SubCommand::with_name("assign") + .about("Assign a token or token account to a new owner") + .arg( + Arg::with_name("address") + .validator(is_pubkey_or_keypair) + .value_name("TOKEN_ADDRESS") + .takes_value(true) + .index(1) + .required(true) + .help("The address of the token account"), + ) + .arg( + Arg::with_name("new_owner") + .validator(is_pubkey_or_keypair) + .value_name("OWNER_ADDRESS") + .takes_value(true) + .index(2) + .required(true) + .help("The address of the new owner"), + ), + ) + .subcommand( + SubCommand::with_name("transfer") + .about("Transfer tokens between accounts") + .arg( + Arg::with_name("sender") + .validator(is_pubkey_or_keypair) + .value_name("SENDER_TOKEN_ACCOUNT_ADDRESS") + .takes_value(true) + .index(1) + .required(true) + .help("The token account address of the sender"), + ) + .arg( + Arg::with_name("amount") + .validator(is_amount) + .value_name("TOKEN_AMOUNT") + .takes_value(true) + .index(2) + .required(true) + .help("Amount to send, in tokens"), + ) + .arg( + Arg::with_name("recipient") + .validator(is_pubkey_or_keypair) + .value_name("RECIPIENT_TOKEN_ACCOUNT_ADDRESS") + .takes_value(true) + .index(3) + .required(true) + .help("The token account address of recipient"), + ), + ) + .subcommand( + SubCommand::with_name("burn") + .about("Burn tokens from an account") + .arg( + Arg::with_name("source") + .validator(is_pubkey_or_keypair) + .value_name("SOURCE_TOKEN_ACCOUNT_ADDRESS") + .takes_value(true) + .index(1) + .required(true) + .help("The token account address to burn from"), + ) + .arg( + Arg::with_name("amount") + .validator(is_amount) + .value_name("TOKEN_AMOUNT") + .takes_value(true) + .index(2) + .required(true) + .help("Amount to burn, in tokens"), + ), + ) + .subcommand( + SubCommand::with_name("mint") + .about("Mint new tokens") + .arg( + Arg::with_name("token") + .validator(is_pubkey_or_keypair) + .value_name("TOKEN_ADDRESS") + .takes_value(true) + .index(1) + .required(true) + .help("The token to mint"), + ) + .arg( + Arg::with_name("amount") + .validator(is_amount) + .value_name("TOKEN_AMOUNT") + .takes_value(true) + .index(2) + .required(true) + .help("Amount to mint, in tokens"), + ) + .arg( + Arg::with_name("recipient") + .validator(is_pubkey_or_keypair) + .value_name("RECIPIENT_TOKEN_ACCOUNT_ADDRESS") + .takes_value(true) + .index(3) + .required(true) + .help("The token account address of recipient"), + ), + ) + .subcommand( + SubCommand::with_name("balance") + .about("Get token account balance") + .arg( + Arg::with_name("address") + .validator(is_pubkey_or_keypair) + .value_name("TOKEN_ACCOUNT_ADDRESS") + .takes_value(true) + .index(1) + .required(true) + .help("The token account address"), + ), + ) + .subcommand( + SubCommand::with_name("supply") + .about("Get token supply") + .arg( + Arg::with_name("address") + .validator(is_pubkey_or_keypair) + .value_name("TOKEN_ADDRESS") + .takes_value(true) + .index(1) + .required(true) + .help("The token address"), + ), + ) + .subcommand( + SubCommand::with_name("accounts") + .about("List all token accounts by owner") + .arg( + Arg::with_name("token") + .validator(is_pubkey_or_keypair) + .value_name("TOKEN_ADDRESS") + .takes_value(true) + .index(1) + .help("Limit results to the given token. [Default: list accounts for all tokens]"), + ), + ) + .subcommand( + SubCommand::with_name("wrap") + .about("Wrap native SOL in a SOL token account") + .arg( + Arg::with_name("amount") + .validator(is_amount) + .value_name("AMOUNT") + .takes_value(true) + .index(1) + .required(true) + .help("Amount of SOL to wrap"), + ), + ) + .subcommand( + SubCommand::with_name("unwrap") + .about("Unwrap a SOL token account") + .arg( + Arg::with_name("address") + .validator(is_pubkey_or_keypair) + .value_name("TOKEN_ACCOUNT_ADDRESS") + .takes_value(true) + .index(1) + .required(true) + .help("The address of the token account to unwrap"), + ), + ) + .get_matches(); + + let config = { + let cli_config = if let Some(config_file) = matches.value_of("config_file") { + solana_cli_config::Config::load(config_file).unwrap_or_default() + } else { + solana_cli_config::Config::default() + }; + let json_rpc_url = value_t!(matches, "json_rpc_url", String) + .unwrap_or_else(|_| cli_config.json_rpc_url.clone()); + + let mut wallet_manager = None; + let owner = signer_from_path( + &matches, + &cli_config.keypair_path, + "owner", + &mut wallet_manager, + ) + .unwrap_or_else(|e| { + eprintln!("error: {}", e); + exit(1); + }); + let fee_payer = signer_from_path( + &matches, + &cli_config.keypair_path, + "fee_payer", + &mut wallet_manager, + ) + .unwrap_or_else(|e| { + eprintln!("error: {}", e); + exit(1); + }); + let verbose = matches.is_present("verbose"); + + Config { + rpc_client: RpcClient::new(json_rpc_url), + verbose, + owner, + fee_payer, + commitment_config: CommitmentConfig::single(), + } + }; + + solana_logger::setup_with_default("solana=info"); + + let _ = match matches.subcommand() { + ("create-token", Some(arg_matches)) => { + let decimals = value_t_or_exit!(arg_matches, "decimals", u8); + command_create_token(&config, decimals) + } + ("create-account", Some(arg_matches)) => { + let token = pubkey_of(arg_matches, "token").unwrap(); + command_create_account(&config, token) + } + ("assign", Some(arg_matches)) => { + let address = pubkey_of(arg_matches, "address").unwrap(); + let new_owner = pubkey_of(arg_matches, "new_owner").unwrap(); + command_assign(&config, address, new_owner) + } + ("transfer", Some(arg_matches)) => { + let sender = pubkey_of(arg_matches, "sender").unwrap(); + let amount = value_t_or_exit!(arg_matches, "amount", f64); + let recipient = pubkey_of(arg_matches, "recipient").unwrap(); + command_transfer(&config, sender, amount, recipient) + } + ("burn", Some(arg_matches)) => { + let source = pubkey_of(arg_matches, "source").unwrap(); + let amount = value_t_or_exit!(arg_matches, "amount", f64); + command_burn(&config, source, amount) + } + ("mint", Some(arg_matches)) => { + let token = pubkey_of(arg_matches, "token").unwrap(); + let amount = value_t_or_exit!(arg_matches, "amount", f64); + let recipient = pubkey_of(arg_matches, "recipient").unwrap(); + command_mint(&config, token, amount, recipient) + } + ("wrap", Some(arg_matches)) => { + let amount = value_t_or_exit!(arg_matches, "amount", f64); + command_wrap(&config, amount) + } + ("unwrap", Some(arg_matches)) => { + let address = pubkey_of(arg_matches, "address").unwrap(); + command_unwrap(&config, address) + } + ("balance", Some(arg_matches)) => { + let address = pubkey_of(arg_matches, "address").unwrap(); + command_balance(&config, address) + } + ("supply", Some(arg_matches)) => { + let address = pubkey_of(arg_matches, "address").unwrap(); + command_supply(&config, address) + } + ("accounts", Some(arg_matches)) => { + let token = pubkey_of(arg_matches, "token"); + command_accounts(&config, token) + } + _ => unreachable!(), + } + .and_then(|transaction| { + if let Some(transaction) = transaction { + // TODO: Upgrade to solana-client 1.3 and + // `send_and_confirm_transaction_with_spinner_and_commitment()` with single + // confirmation by default for better UX + let signature = config + .rpc_client + .send_and_confirm_transaction_with_spinner_and_commitment( + &transaction, + config.commitment_config, + )?; + println!("Signature: {}", signature); + } + Ok(()) + }) + .map_err(|err| { + eprintln!("{}", err); + exit(1); + }); +} diff --git a/program/Cargo.toml b/program/Cargo.toml new file mode 100644 index 00000000..820586ef --- /dev/null +++ b/program/Cargo.toml @@ -0,0 +1,36 @@ + +# Note: This crate must be built using do.sh + +[package] +name = "spl-stake-pool" +version = "0.1.0" +description = "Solana Program Library Stake Pool" +authors = ["Solana Maintainers "] +repository = "https://github.com/solana-labs/solana-program-library" +license = "Apache-2.0" +edition = "2018" +exclude = ["js/**"] + +[features] +no-entrypoint = [] +program = ["solana-sdk/program", "spl-token/program", "spl-token/no-entrypoint"] +default = ["solana-sdk/default", "spl-token/default"] + + +[dependencies] +num-derive = "0.3" +num-traits = "0.2" +remove_dir_all = "=0.5.0" +solana-sdk = { version = "1.3.17", default-features = false, optional = true } +spl-token = { path = "../../token/program", default-features = false, optional = true } +thiserror = "1.0" +arrayref = "0.3.6" +num_enum = "0.5.1" +serde = "1.0.112" +serde_derive = "1.0.103" + +[dev-dependencies] +rand = { version = "0.7.0"} + +[lib] +crate-type = ["cdylib", "lib"] diff --git a/program/Xargo.toml b/program/Xargo.toml new file mode 100644 index 00000000..475fb71e --- /dev/null +++ b/program/Xargo.toml @@ -0,0 +1,2 @@ +[target.bpfel-unknown-unknown.dependencies.std] +features = [] diff --git a/program/program-id.md b/program/program-id.md new file mode 100644 index 00000000..eae20664 --- /dev/null +++ b/program/program-id.md @@ -0,0 +1 @@ +STAKEPQQL1111111111111111111111111111111111 diff --git a/program/src/entrypoint.rs b/program/src/entrypoint.rs new file mode 100644 index 00000000..d916cd5a --- /dev/null +++ b/program/src/entrypoint.rs @@ -0,0 +1,24 @@ +//! Program entrypoint + +#![cfg(feature = "program")] +#![cfg(not(feature = "no-entrypoint"))] + +use crate::{error::Error, processor::Processor}; +use solana_sdk::{ + account_info::AccountInfo, entrypoint, entrypoint::ProgramResult, + program_error::PrintProgramError, pubkey::Pubkey, +}; + +entrypoint!(process_instruction); +fn process_instruction<'a>( + program_id: &Pubkey, + accounts: &'a [AccountInfo<'a>], + instruction_data: &[u8], +) -> ProgramResult { + if let Err(error) = Processor::process(program_id, accounts, instruction_data) { + // catch the error so we can print it + error.print::(); + return Err(error); + } + Ok(()) +} diff --git a/program/src/error.rs b/program/src/error.rs new file mode 100644 index 00000000..eaf507c3 --- /dev/null +++ b/program/src/error.rs @@ -0,0 +1,53 @@ +//! Error types + +use num_derive::FromPrimitive; +use solana_sdk::{decode_error::DecodeError, program_error::ProgramError}; +use thiserror::Error; + +/// Errors that may be returned by the StakePool program. +#[derive(Clone, Debug, Eq, Error, FromPrimitive, PartialEq)] +pub enum Error { + /// The account cannot be initialized because it is already being used. + #[error("AlreadyInUse")] + AlreadyInUse, + /// The program address provided doesn't match the value generated by the program. + #[error("InvalidProgramAddress")] + InvalidProgramAddress, + /// The owner of the input isn't set to the program address generated by the program. + #[error("InvalidOwner")] + InvalidOwner, + /// The deserialization of the Token state returned something besides State::Token. + #[error("ExpectedToken")] + ExpectedToken, + /// The deserialization of the Token state returned something besides State::Account. + #[error("ExpectedAccount")] + ExpectedAccount, + /// The initialized pool had a non zero supply. + #[error("InvalidSupply")] + InvalidSupply, + /// The initialized token has a delegate. + #[error("InvalidDelegate")] + InvalidDelegate, + /// The token swap state is invalid. + #[error("InvalidState")] + InvalidState, + /// The input token is invalid for swap. + #[error("InvalidInput")] + InvalidInput, + /// The output token is invalid for swap. + #[error("InvalidOutput")] + InvalidOutput, + /// The calculation failed. + #[error("CalculationFailure")] + CalculationFailure, +} +impl From for ProgramError { + fn from(e: Error) -> Self { + ProgramError::Custom(e as u32) + } +} +impl DecodeError for Error { + fn type_of() -> &'static str { + "Stake Pool Error" + } +} diff --git a/program/src/instruction.rs b/program/src/instruction.rs new file mode 100644 index 00000000..63cbe43c --- /dev/null +++ b/program/src/instruction.rs @@ -0,0 +1,180 @@ +//! Instruction types + +#![allow(clippy::too_many_arguments)] + +use solana_sdk::instruction::AccountMeta; +use solana_sdk::instruction::Instruction; +use solana_sdk::program_error::ProgramError; +use solana_sdk::pubkey::Pubkey; +use std::mem::size_of; + +/// Fee rate as a ratio +/// Fee is minted on deposit +#[repr(C)] +#[derive(Clone, Copy, Debug, Default, PartialEq)] +pub struct Fee { + /// denominator of the fee ratio + pub denominator: u64, + /// numerator of the fee ratio + pub numerator: u64, +} + +/// Inital values for the Stake Pool +#[repr(C)] +#[derive(Clone, Copy, Debug, Default, PartialEq)] +pub struct InitArgs { + /// Fee paid to the owner in pool tokens + pub fee: Fee, + /// Nonce used for the deposit program address + pub deposit_nonce: u8, + /// Nonce used for the withdraw program address + /// This program address is used as the stake withdraw key as well + pub withdraw_nonce: u8, +} + +/// Instructions supported by the StakePool program. +#[repr(C)] +#[derive(Clone, Debug, PartialEq)] +pub enum StakePoolInstruction { + /// Initializes a new StakePool. + /// + /// 0. `[w]` New StakePool to create. + /// 1. `[]` Owner + /// 2. `[]` pool token Mint. Must be non zero, owned by withdraw authority. + /// 3. `[]` Pool Account to deposit the generated fee for owner. + /// 4. `[]` Token program id + Initialize(InitArgs), + + /// Deposit some stake into the pool. The output is a "pool" token representing ownership + /// into the pool. Inputs are converted to the current ratio. + /// + /// 0. `[]` StakePool + /// 1. `[]` deposit authority + /// 2. `[]` withdraw authority + /// 3. `[w]` Stake, deposit authority is set as the withdrawal key + /// 4. `[w]` Pool MINT account, authority is the owner. + /// 5. `[w]` Pool Account to deposit the generated tokens. + /// 6. `[w]` Pool Account to deposit the generated fee for owner. + /// 7. `[]` Token program id + Deposit, + + /// Withdraw the token from the pool at the current ratio. + /// The amount withdrawn is the MIN(u64, stake size) + /// + /// 0. `[]` StakePool + /// 1. `[]` withdraw authority + /// 2. `[w]` SOURCE Pool account, amount is transferable by authority + /// 3. `[w]` Pool MINT account, authority is the owner + /// 4. `[w]` Stake SOURCE owned by the withdraw authority + /// 6. `[w]` Stake destination, uninitialized, for the user stake + /// 7. `[]` Token program id + /// userdata: amount to withdraw + Withdraw(u64), + + /// Update the staking pubkey for a stake + /// + /// 0. `[w]` StakePool + /// 1. `[s]` Owner + /// 2. `[]` withdraw authority + /// 3. `[w]` Stake to update the staking pubkey + /// 4. '[]` Staking pubkey. + SetStakingAuthority, + + /// Update owner + /// + /// 0. `[w]` StakePool + /// 1. `[s]` Owner + /// 2. '[]` New owner pubkey + /// 3. '[]` New owner fee account + SetOwner, +} + +impl StakePoolInstruction { + /// Deserializes a byte buffer into an [StakePoolInstruction](enum.StakePoolInstruction.html). + /// TODO efficient unpacking here + pub fn deserialize(input: &[u8]) -> Result { + if input.len() < size_of::() { + return Err(ProgramError::InvalidAccountData); + } + Ok(match input[0] { + 0 => { + let val: &InitArgs = unpack(input)?; + Self::Initialize(*val) + } + 1 => Self::Deposit, + 2 => { + let val: &u64 = unpack(input)?; + Self::Withdraw(*val) + } + 3 => Self::SetStakingAuthority, + 4 => Self::SetOwner, + _ => return Err(ProgramError::InvalidAccountData), + }) + } + + /// Serializes an [StakePoolInstruction](enum.StakePoolInstruction.html) into a byte buffer. + /// TODO efficient packing here + pub fn serialize(&self) -> Result, ProgramError> { + let mut output = vec![0u8; size_of::()]; + match self { + Self::Initialize(init) => { + output[0] = 0; + #[allow(clippy::cast_ptr_alignment)] + let value = unsafe { &mut *(&mut output[1] as *mut u8 as *mut InitArgs) }; + *value = *init; + } + Self::Deposit => { + output[0] = 1; + } + Self::Withdraw(val) => { + output[0] = 2; + #[allow(clippy::cast_ptr_alignment)] + let value = unsafe { &mut *(&mut output[1] as *mut u8 as *mut u64) }; + *value = *val; + } + Self::SetStakingAuthority => { + output[0] = 3; + } + Self::SetOwner => { + output[0] = 4; + } + } + Ok(output) + } +} + +/// Unpacks a reference from a bytes buffer. +pub fn unpack(input: &[u8]) -> Result<&T, ProgramError> { + if input.len() < size_of::() + size_of::() { + return Err(ProgramError::InvalidAccountData); + } + #[allow(clippy::cast_ptr_alignment)] + let val: &T = unsafe { &*(&input[1] as *const u8 as *const T) }; + Ok(val) +} + +/// Creates an 'initialize' instruction. +pub fn initialize( + program_id: &Pubkey, + stake_pool: &Pubkey, + owner: &Pubkey, + pool_mint: &Pubkey, + owner_pool_account: &Pubkey, + token_program_id: &Pubkey, + init_args: InitArgs, +) -> Result { + let init_data = StakePoolInstruction::Initialize(init_args); + let data = init_data.serialize()?; + let accounts = vec![ + AccountMeta::new(*stake_pool, true), + AccountMeta::new(*owner, false), + AccountMeta::new(*pool_mint, false), + AccountMeta::new(*owner_pool_account, false), + AccountMeta::new(*token_program_id, false), + ]; + Ok(Instruction { + program_id: *program_id, + accounts, + data, + }) +} diff --git a/program/src/lib.rs b/program/src/lib.rs new file mode 100644 index 00000000..fc5cac6c --- /dev/null +++ b/program/src/lib.rs @@ -0,0 +1,16 @@ +#![deny(missing_docs)] + +//! A program for creating pools of Solana stakes managed by a Stake-o-Matic + +pub mod entrypoint; +pub mod error; +pub mod instruction; +pub mod processor; +pub mod stake; +pub mod state; + +// Export current solana-sdk types for downstream users who may also be building with a different +// solana-sdk version +pub use solana_sdk; + +solana_sdk::declare_id!("STAKEPQQL1111111111111111111111111111111111"); diff --git a/program/src/processor.rs b/program/src/processor.rs new file mode 100644 index 00000000..9fb8fcbf --- /dev/null +++ b/program/src/processor.rs @@ -0,0 +1,617 @@ +//! Program state processor + +#![cfg(feature = "program")] + +use crate::{ + error::Error, + instruction::{InitArgs, StakePoolInstruction}, + stake, + state::{StakePool, State}, +}; +use num_traits::FromPrimitive; +#[cfg(not(target_arch = "bpf"))] +use solana_sdk::instruction::Instruction; +#[cfg(target_arch = "bpf")] +use solana_sdk::program::invoke_signed; +use solana_sdk::{ + account_info::next_account_info, account_info::AccountInfo, decode_error::DecodeError, + entrypoint::ProgramResult, info, program_error::PrintProgramError, program_error::ProgramError, + pubkey::Pubkey, +}; +use std::convert::TryFrom; + +/// Program state handler. +pub struct Processor {} +impl Processor { + /// Calculates the authority id by generating a program address. + pub fn authority_id(program_id: &Pubkey, my_info: &Pubkey, nonce: u8) -> Result { + Pubkey::create_program_address(&[&my_info.to_bytes()[..32], &[nonce]], program_id) + .or(Err(Error::InvalidProgramAddress)) + } + + /// Issue a stake_split instruction. + pub fn stake_split<'a>( + stake_pool: &Pubkey, + stake_account: AccountInfo<'a>, + authority: AccountInfo<'a>, + nonce: u8, + amount: u64, + split_stake: AccountInfo<'a>, + ) -> Result<(), ProgramError> { + let me_bytes = stake_pool.to_bytes(); + let authority_signature_seeds = [&me_bytes[..32], &[nonce]]; + let signers = &[&authority_signature_seeds[..]]; + + let ix = stake::split_only(stake_account.key, authority.key, amount, split_stake.key); + + invoke_signed(&ix, &[stake_account, authority, split_stake], signers) + } + + /// Issue a stake_set_owner instruction. + pub fn stake_authorize<'a>( + stake_pool: &Pubkey, + stake_account: AccountInfo<'a>, + authority: AccountInfo<'a>, + nonce: u8, + new_staker: &Pubkey, + staker_auth: stake::StakeAuthorize, + ) -> Result<(), ProgramError> { + let me_bytes = stake_pool.to_bytes(); + let authority_signature_seeds = [&me_bytes[..32], &[nonce]]; + let signers = &[&authority_signature_seeds[..]]; + + let ix = stake::authorize(stake_account.key, authority.key, new_staker, staker_auth); + + invoke_signed(&ix, &[stake_account, authority], signers) + } + + /// Issue a spl_token `Burn` instruction. + pub fn token_burn<'a>( + stake_pool: &Pubkey, + token_program: AccountInfo<'a>, + burn_account: AccountInfo<'a>, + mint: AccountInfo<'a>, + authority: AccountInfo<'a>, + nonce: u8, + amount: u64, + ) -> Result<(), ProgramError> { + let me_bytes = stake_pool.to_bytes(); + let authority_signature_seeds = [&me_bytes[..32], &[nonce]]; + let signers = &[&authority_signature_seeds[..]]; + + let ix = spl_token::instruction::burn( + token_program.key, + burn_account.key, + mint.key, + authority.key, + &[], + amount, + )?; + + invoke_signed( + &ix, + &[burn_account, mint, authority, token_program], + signers, + ) + } + + /// Issue a spl_token `MintTo` instruction. + pub fn token_mint_to<'a>( + stake_pool: &Pubkey, + token_program: AccountInfo<'a>, + mint: AccountInfo<'a>, + destination: AccountInfo<'a>, + authority: AccountInfo<'a>, + nonce: u8, + amount: u64, + ) -> Result<(), ProgramError> { + let me_bytes = stake_pool.to_bytes(); + let authority_signature_seeds = [&me_bytes[..32], &[nonce]]; + let signers = &[&authority_signature_seeds[..]]; + let ix = spl_token::instruction::mint_to( + token_program.key, + mint.key, + destination.key, + authority.key, + &[], + amount, + )?; + + invoke_signed(&ix, &[mint, destination, authority, token_program], signers) + } + + /// Processes an [Initialize](enum.Instruction.html). + pub fn process_initialize( + _program_id: &Pubkey, + init: InitArgs, + accounts: &[AccountInfo], + ) -> ProgramResult { + let account_info_iter = &mut accounts.iter(); + let stake_pool_info = next_account_info(account_info_iter)?; + let owner_info = next_account_info(account_info_iter)?; + let pool_mint_info = next_account_info(account_info_iter)?; + let owner_fee_info = next_account_info(account_info_iter)?; + let token_program_info = next_account_info(account_info_iter)?; + + if State::Unallocated != State::deserialize(&stake_pool_info.data.borrow())? { + return Err(Error::AlreadyInUse.into()); + } + + let stake_pool = State::Init(StakePool { + owner: *owner_info.key, + deposit_nonce: init.deposit_nonce, + withdraw_nonce: init.withdraw_nonce, + pool_mint: *pool_mint_info.key, + owner_fee_account: *owner_fee_info.key, + token_program_id: *token_program_info.key, + stake_total: 0, + pool_total: 0, + fee: init.fee, + }); + stake_pool.serialize(&mut stake_pool_info.data.borrow_mut()) + } + + /// Processes an [Withdraw](enum.Instruction.html). + pub fn process_deposit(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { + let account_info_iter = &mut accounts.iter(); + let stake_pool_info = next_account_info(account_info_iter)?; + let deposit_info = next_account_info(account_info_iter)?; + let withdraw_info = next_account_info(account_info_iter)?; + let stake_info = next_account_info(account_info_iter)?; + let pool_mint_info = next_account_info(account_info_iter)?; + let dest_user_info = next_account_info(account_info_iter)?; + let owner_fee_info = next_account_info(account_info_iter)?; + let token_program_info = next_account_info(account_info_iter)?; + + let mut stake_pool = State::deserialize(&stake_pool_info.data.borrow())?.stake_pool()?; + + if *withdraw_info.key + != Self::authority_id(program_id, stake_pool_info.key, stake_pool.withdraw_nonce)? + { + return Err(Error::InvalidProgramAddress.into()); + } + + if *deposit_info.key + != Self::authority_id(program_id, stake_pool_info.key, stake_pool.deposit_nonce)? + { + return Err(Error::InvalidProgramAddress.into()); + } + + if stake_pool.owner_fee_account != *owner_fee_info.key { + return Err(Error::InvalidInput.into()); + } + if stake_pool.token_program_id != *token_program_info.key { + return Err(Error::InvalidInput.into()); + } + + let stake_lamports = **stake_info.lamports.borrow(); + let pool_amount = stake_pool + .calc_pool_deposit_amount(stake_lamports) + .ok_or(Error::CalculationFailure)?; + + let fee_amount = stake_pool + .calc_fee_amount(pool_amount) + .ok_or(Error::CalculationFailure)?; + + let user_amount = pool_amount + .checked_sub(fee_amount) + .ok_or(Error::CalculationFailure)?; + + Self::stake_authorize( + stake_pool_info.key, + stake_info.clone(), + deposit_info.clone(), + stake_pool.deposit_nonce, + withdraw_info.key, + stake::StakeAuthorize::Withdrawer, + )?; + + let user_amount = ::try_from(user_amount).or(Err(Error::CalculationFailure))?; + Self::token_mint_to( + stake_pool_info.key, + token_program_info.clone(), + pool_mint_info.clone(), + dest_user_info.clone(), + withdraw_info.clone(), + stake_pool.withdraw_nonce, + user_amount, + )?; + let fee_amount = ::try_from(fee_amount).or(Err(Error::CalculationFailure))?; + Self::token_mint_to( + stake_pool_info.key, + token_program_info.clone(), + pool_mint_info.clone(), + owner_fee_info.clone(), + withdraw_info.clone(), + stake_pool.withdraw_nonce, + fee_amount as u64, + )?; + let pool_amount = ::try_from(pool_amount).or(Err(Error::CalculationFailure))?; + stake_pool.pool_total += pool_amount; + stake_pool.stake_total += stake_lamports; + State::Init(stake_pool).serialize(&mut stake_pool_info.data.borrow_mut())?; + Ok(()) + } + + /// Processes an [Withdraw](enum.Instruction.html). + pub fn process_withdraw( + program_id: &Pubkey, + stake_amount: u64, + accounts: &[AccountInfo], + ) -> ProgramResult { + let account_info_iter = &mut accounts.iter(); + let stake_pool_info = next_account_info(account_info_iter)?; + let withdraw_info = next_account_info(account_info_iter)?; + let source_info = next_account_info(account_info_iter)?; + let pool_mint_info = next_account_info(account_info_iter)?; + let stake_info = next_account_info(account_info_iter)?; + let dest_user_info = next_account_info(account_info_iter)?; + let token_program_info = next_account_info(account_info_iter)?; + + let mut stake_pool = State::deserialize(&stake_pool_info.data.borrow())?.stake_pool()?; + + if *withdraw_info.key + != Self::authority_id(program_id, stake_pool_info.key, stake_pool.withdraw_nonce)? + { + return Err(Error::InvalidProgramAddress.into()); + } + if stake_pool.token_program_id != *token_program_info.key { + return Err(Error::InvalidInput.into()); + } + + let pool_amount = stake_pool + .calc_pool_withdraw_amount(stake_amount) + .ok_or(Error::CalculationFailure)?; + let pool_amount = ::try_from(pool_amount).or(Err(Error::CalculationFailure))?; + + Self::stake_split( + stake_pool_info.key, + source_info.clone(), + withdraw_info.clone(), + stake_pool.withdraw_nonce, + stake_amount, + stake_info.clone(), + )?; + + Self::stake_authorize( + stake_pool_info.key, + stake_info.clone(), + withdraw_info.clone(), + stake_pool.withdraw_nonce, + dest_user_info.key, + stake::StakeAuthorize::Withdrawer, + )?; + + Self::token_burn( + stake_pool_info.key, + token_program_info.clone(), + source_info.clone(), + pool_mint_info.clone(), + withdraw_info.clone(), + stake_pool.withdraw_nonce, + pool_amount, + )?; + + stake_pool.pool_total -= pool_amount; + stake_pool.stake_total -= stake_amount; + State::Init(stake_pool).serialize(&mut stake_pool_info.data.borrow_mut())?; + Ok(()) + } + /// Processes an [SetStakeAuthority](enum.Instruction.html). + pub fn process_set_staking_auth( + program_id: &Pubkey, + accounts: &[AccountInfo], + ) -> ProgramResult { + let account_info_iter = &mut accounts.iter(); + let stake_pool_info = next_account_info(account_info_iter)?; + let owner_info = next_account_info(account_info_iter)?; + let withdraw_info = next_account_info(account_info_iter)?; + let stake_info = next_account_info(account_info_iter)?; + let staker_info = next_account_info(account_info_iter)?; + + let stake_pool = State::deserialize(&stake_pool_info.data.borrow())?.stake_pool()?; + + if *owner_info.key != stake_pool.owner { + return Err(Error::InvalidInput.into()); + } + if !owner_info.is_signer { + return Err(Error::InvalidInput.into()); + } + + if *withdraw_info.key + != Self::authority_id(program_id, stake_pool_info.key, stake_pool.withdraw_nonce)? + { + return Err(Error::InvalidProgramAddress.into()); + } + Self::stake_authorize( + stake_info.key, + stake_info.clone(), + withdraw_info.clone(), + stake_pool.withdraw_nonce, + staker_info.key, + stake::StakeAuthorize::Staker, + )?; + Ok(()) + } + + /// Processes an [SetOwner](enum.Instruction.html). + pub fn process_set_owner(_program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { + let account_info_iter = &mut accounts.iter(); + let stake_pool_info = next_account_info(account_info_iter)?; + let owner_info = next_account_info(account_info_iter)?; + let new_owner_info = next_account_info(account_info_iter)?; + let new_owner_fee_info = next_account_info(account_info_iter)?; + + let mut stake_pool = State::deserialize(&stake_pool_info.data.borrow())?.stake_pool()?; + + if *owner_info.key != stake_pool.owner { + return Err(Error::InvalidInput.into()); + } + if !owner_info.is_signer { + return Err(Error::InvalidInput.into()); + } + stake_pool.owner = *new_owner_info.key; + stake_pool.owner_fee_account = *new_owner_fee_info.key; + State::Init(stake_pool).serialize(&mut stake_pool_info.data.borrow_mut())?; + Ok(()) + } + /// Processes an [Instruction](enum.Instruction.html). + pub fn process(program_id: &Pubkey, accounts: &[AccountInfo], input: &[u8]) -> ProgramResult { + let instruction = StakePoolInstruction::deserialize(input)?; + match instruction { + StakePoolInstruction::Initialize(init) => { + info!("Instruction: Init"); + Self::process_initialize(program_id, init, accounts) + } + StakePoolInstruction::Deposit => { + info!("Instruction: Deposit"); + Self::process_deposit(program_id, accounts) + } + StakePoolInstruction::Withdraw(amount) => { + info!("Instruction: Withdraw"); + Self::process_withdraw(program_id, amount, accounts) + } + StakePoolInstruction::SetStakingAuthority => { + info!("Instruction: SetStakingAuthority"); + Self::process_set_staking_auth(program_id, accounts) + } + StakePoolInstruction::SetOwner => { + info!("Instruction: SetOwner"); + Self::process_set_owner(program_id, accounts) + } + } + } +} + +// Test program id for the stake-pool program. +#[cfg(not(target_arch = "bpf"))] +const STAKE_POOL_PROGRAM_ID: Pubkey = Pubkey::new_from_array([2u8; 32]); + +// Test program id for the token program. +#[cfg(not(target_arch = "bpf"))] +const TOKEN_PROGRAM_ID: Pubkey = Pubkey::new_from_array([1u8; 32]); + +/// Routes invokes to the token program, used for testing. +/// TODO add routing to stake program for testing +#[cfg(not(target_arch = "bpf"))] +pub fn invoke_signed<'a>( + instruction: &Instruction, + account_infos: &[AccountInfo<'a>], + signers_seeds: &[&[&[u8]]], +) -> ProgramResult { + // mimic check for token program in accounts + if !account_infos.iter().any(|x| *x.key == TOKEN_PROGRAM_ID) { + return Err(ProgramError::InvalidAccountData); + } + + let mut new_account_infos = vec![]; + for meta in instruction.accounts.iter() { + for account_info in account_infos.iter() { + if meta.pubkey == *account_info.key { + let mut new_account_info = account_info.clone(); + for seeds in signers_seeds.iter() { + let signer = + Pubkey::create_program_address(seeds, &STAKE_POOL_PROGRAM_ID).unwrap(); + if *account_info.key == signer { + new_account_info.is_signer = true; + } + } + new_account_infos.push(new_account_info); + } + } + } + spl_token::processor::Processor::process( + &instruction.program_id, + &new_account_infos, + &instruction.data, + ) +} + +impl PrintProgramError for Error { + fn print(&self) + where + E: 'static + std::error::Error + DecodeError + PrintProgramError + FromPrimitive, + { + match self { + Error::AlreadyInUse => info!("Error: AlreadyInUse"), + Error::InvalidProgramAddress => info!("Error: InvalidProgramAddress"), + Error::InvalidOwner => info!("Error: InvalidOwner"), + Error::ExpectedToken => info!("Error: ExpectedToken"), + Error::ExpectedAccount => info!("Error: ExpectedAccount"), + Error::InvalidSupply => info!("Error: InvalidSupply"), + Error::InvalidDelegate => info!("Error: InvalidDelegate"), + Error::InvalidState => info!("Error: InvalidState"), + Error::InvalidInput => info!("Error: InvalidInput"), + Error::InvalidOutput => info!("Error: InvalidOutput"), + Error::CalculationFailure => info!("Error: CalculationFailure"), + } + } +} + +// Pull in syscall stubs when building for non-BPF targets +#[cfg(not(target_arch = "bpf"))] +solana_sdk::program_stubs!(); + +#[cfg(test)] +mod tests { + use super::*; + use crate::instruction::initialize; + use crate::instruction::Fee; + use crate::instruction::InitArgs; + use core::mem::size_of; + use solana_sdk::{ + account::Account, account_info::create_is_signer_account_infos, instruction::Instruction, + program_pack::Pack, rent::Rent, sysvar::rent, + }; + use spl_token::{ + instruction::{initialize_account, initialize_mint}, + processor::Processor as SplProcessor, + state::{Account as SplAccount, Mint as SplMint}, + }; + + fn pubkey_rand() -> Pubkey { + Pubkey::new(&rand::random::<[u8; 32]>()) + } + + fn do_process_instruction( + instruction: Instruction, + accounts: Vec<&mut Account>, + ) -> ProgramResult { + let mut meta = instruction + .accounts + .iter() + .zip(accounts) + .map(|(account_meta, account)| (&account_meta.pubkey, account_meta.is_signer, account)) + .collect::>(); + + let account_infos = create_is_signer_account_infos(&mut meta); + if instruction.program_id == STAKE_POOL_PROGRAM_ID { + Processor::process(&instruction.program_id, &account_infos, &instruction.data) + } else { + SplProcessor::process(&instruction.program_id, &account_infos, &instruction.data) + } + } + + fn account_minimum_balance() -> u64 { + Rent::default().minimum_balance(SplAccount::get_packed_len()) + } + + fn mint_minimum_balance() -> u64 { + Rent::default().minimum_balance(SplMint::get_packed_len()) + } + + fn mint_token( + program_id: &Pubkey, + mint_key: &Pubkey, + mut mint_account: &mut Account, + authority_key: &Pubkey, + amount: u64, + ) -> (Pubkey, Account) { + let account_key = pubkey_rand(); + let mut account_account = Account::new( + account_minimum_balance(), + SplAccount::get_packed_len(), + &program_id, + ); + let mut authority_account = Account::default(); + let mut rent_sysvar_account = rent::create_account(1, &Rent::free()); + + // create account + do_process_instruction( + initialize_account(&program_id, &account_key, &mint_key, authority_key).unwrap(), + vec![ + &mut account_account, + &mut mint_account, + &mut authority_account, + &mut rent_sysvar_account, + ], + ) + .unwrap(); + + do_process_instruction( + spl_token::instruction::mint_to( + &program_id, + &mint_key, + &account_key, + &authority_key, + &[], + amount, + ) + .unwrap(), + vec![ + &mut mint_account, + &mut account_account, + &mut authority_account, + ], + ) + .unwrap(); + + (account_key, account_account) + } + + fn create_mint(program_id: &Pubkey, authority_key: &Pubkey) -> (Pubkey, Account) { + let mint_key = pubkey_rand(); + let mut mint_account = Account::new( + mint_minimum_balance(), + SplMint::get_packed_len(), + &program_id, + ); + let mut rent_sysvar_account = rent::create_account(1, &Rent::free()); + + // create token mint + do_process_instruction( + initialize_mint(&program_id, &mint_key, authority_key, None, 2).unwrap(), + vec![&mut mint_account, &mut rent_sysvar_account], + ) + .unwrap(); + + (mint_key, mint_account) + } + + #[test] + fn test_initialize() { + let stake_pool_key = pubkey_rand(); + let mut stake_pool_account = Account::new(0, size_of::(), &STAKE_POOL_PROGRAM_ID); + let owner_key = pubkey_rand(); + let mut owner_account = Account::default(); + let authority_key = pubkey_rand(); + + let (pool_mint_key, mut pool_mint_account) = create_mint(&TOKEN_PROGRAM_ID, &authority_key); + let (pool_token_key, mut pool_token_account) = mint_token( + &TOKEN_PROGRAM_ID, + &pool_mint_key, + &mut pool_mint_account, + &authority_key, + 0, + ); + + // StakePool Init + do_process_instruction( + initialize( + &STAKE_POOL_PROGRAM_ID, + &stake_pool_key, + &owner_key, + &pool_mint_key, + &pool_token_key, + &TOKEN_PROGRAM_ID, + InitArgs { + deposit_nonce: 0, + withdraw_nonce: 0, + fee: Fee { + denominator: 1, + numerator: 2, + }, + }, + ) + .unwrap(), + vec![ + &mut stake_pool_account, + &mut owner_account, + &mut pool_mint_account, + &mut pool_token_account, + &mut Account::default(), + ], + ) + .unwrap(); + } +} diff --git a/program/src/stake.rs b/program/src/stake.rs new file mode 100644 index 00000000..940ad7e9 --- /dev/null +++ b/program/src/stake.rs @@ -0,0 +1,148 @@ +//! FIXME copied from the solana stake program + +use serde_derive::{Deserialize, Serialize}; +use solana_sdk::{ + instruction::{AccountMeta, Instruction}, + pubkey::Pubkey, + sysvar, +}; + +solana_sdk::declare_id!("StakeConfig11111111111111111111111111111111"); + +/// FIXME copied from solana stake program +#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] +pub enum StakeInstruction { + /// Initialize a stake with lockup and authorization information + /// + /// # Account references + /// 0. [WRITE] Uninitialized stake account + /// 1. [] Rent sysvar + /// + /// Authorized carries pubkeys that must sign staker transactions + /// and withdrawer transactions. + /// Lockup carries information about withdrawal restrictions + InitializeNOTUSED, + + /// Authorize a key to manage stake or withdrawal + /// + /// # Account references + /// 0. [WRITE] Stake account to be updated + /// 1. [] (reserved for future use) Clock sysvar + /// 2. [SIGNER] The stake or withdraw authority + Authorize(Pubkey, StakeAuthorize), + + /// Delegate a stake to a particular vote account + /// + /// # Account references + /// 0. [WRITE] Initialized stake account to be delegated + /// 1. [] Vote account to which this stake will be delegated + /// 2. [] Clock sysvar + /// 3. [] Stake history sysvar that carries stake warmup/cooldown history + /// 4. [] Address of config account that carries stake config + /// 5. [SIGNER] Stake authority + /// + /// The entire balance of the staking account is staked. DelegateStake + /// can be called multiple times, but re-delegation is delayed + /// by one epoch + DelegateStake, + + /// Split u64 tokens and stake off a stake account into another stake account. + /// + /// # Account references + /// 0. [WRITE] Stake account to be split; must be in the Initialized or Stake state + /// 1. [WRITE] Uninitialized stake account that will take the split-off amount + /// 2. [SIGNER] Stake authority + Split(u64), + + /// Withdraw unstaked lamports from the stake account + /// + /// # Account references + /// 0. [WRITE] Stake account from which to withdraw + /// 1. [WRITE] Recipient account + /// 2. [] Clock sysvar + /// 3. [] Stake history sysvar that carries stake warmup/cooldown history + /// 4. [SIGNER] Withdraw authority + /// 5. Optional: [SIGNER] Lockup authority, if before lockup expiration + /// + /// The u64 is the portion of the stake account balance to be withdrawn, + /// must be `<= StakeAccount.lamports - staked_lamports`. + Withdraw(u64), + + /// Deactivates the stake in the account + /// + /// # Account references + /// 0. [WRITE] Delegated stake account + /// 1. [] Clock sysvar + /// 2. [SIGNER] Stake authority + Deactivate, + + /// Set stake lockup + /// + /// # Account references + /// 0. [WRITE] Initialized stake account + /// 1. [SIGNER] Lockup authority + SetLockupNOTUSED, + + /// Merge two stake accounts. Both accounts must be deactivated and have identical lockup and + /// authority keys. + /// + /// # Account references + /// 0. [WRITE] Destination stake account for the merge + /// 1. [WRITE] Source stake account for to merge. This account will be drained + /// 2. [] Clock sysvar + /// 3. [] Stake history sysvar that carries stake warmup/cooldown history + /// 4. [SIGNER] Stake authority + Merge, + + /// Authorize a key to manage stake or withdrawal with a derived key + /// + /// # Account references + /// 0. [WRITE] Stake account to be updated + /// 1. [SIGNER] Base key of stake or withdraw authority + AuthorizeWithSeedNOTUSED, +} + +/// FIXME copied from the stake program +#[derive(Debug, Serialize, Deserialize, PartialEq, Clone, Copy)] +pub enum StakeAuthorize { + /// FIXME copied from the stake program + Staker, + /// FIXME copied from the stake program + Withdrawer, +} + +/// FIXME copied from the stake program +pub fn split_only( + stake_pubkey: &Pubkey, + authorized_pubkey: &Pubkey, + lamports: u64, + split_stake_pubkey: &Pubkey, +) -> Instruction { + let account_metas = vec![ + AccountMeta::new(*stake_pubkey, false), + AccountMeta::new(*split_stake_pubkey, false), + AccountMeta::new_readonly(*authorized_pubkey, true), + ]; + + Instruction::new(id(), &StakeInstruction::Split(lamports), account_metas) +} + +/// FIXME copied from the stake program +pub fn authorize( + stake_pubkey: &Pubkey, + authorized_pubkey: &Pubkey, + new_authorized_pubkey: &Pubkey, + stake_authorize: StakeAuthorize, +) -> Instruction { + let account_metas = vec![ + AccountMeta::new(*stake_pubkey, false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(*authorized_pubkey, true), + ]; + + Instruction::new( + id(), + &StakeInstruction::Authorize(*new_authorized_pubkey, stake_authorize), + account_metas, + ) +} diff --git a/program/src/state.rs b/program/src/state.rs new file mode 100644 index 00000000..f6a7d022 --- /dev/null +++ b/program/src/state.rs @@ -0,0 +1,114 @@ +//! State transition types + +use crate::error::Error; +use crate::instruction::{unpack, Fee}; +use solana_sdk::{entrypoint::ProgramResult, program_error::ProgramError, pubkey::Pubkey}; +use std::mem::size_of; + +/// Initialized program details. +#[repr(C)] +#[derive(Clone, Copy, Debug, Default, PartialEq)] +pub struct StakePool { + /// Owner authority + /// allows for updating the staking authority + pub owner: Pubkey, + /// Deposit authority nonce + /// for `create_program_address(&[state::StakePool account, "deposit"])` + pub deposit_nonce: u8, + /// Withdrawal authority nonce + /// for `create_program_address(&[state::StakePool account, "withdrawal"])` + pub withdraw_nonce: u8, + /// Pool Mint + pub pool_mint: Pubkey, + /// Owner fee account + pub owner_fee_account: Pubkey, + /// Pool token program id + pub token_program_id: Pubkey, + /// total stake under management + pub stake_total: u64, + /// total pool + pub pool_total: u64, + /// Fee applied to deposits + pub fee: Fee, +} +impl StakePool { + /// calculate the pool tokens that should be minted + pub fn calc_pool_deposit_amount(&self, stake_lamports: u64) -> Option { + if self.stake_total == 0 { + return Some(stake_lamports as u128); + } + self.calc_pool_withdraw_amount(stake_lamports) + } + /// calculate the pool tokens that should be withdrawn + pub fn calc_pool_withdraw_amount(&self, stake_lamports: u64) -> Option { + (stake_lamports as u128) + .checked_mul(self.pool_total as u128)? + .checked_div(self.stake_total as u128) + } + /// calculate the fee in pool tokens that goes to the owner + pub fn calc_fee_amount(&self, pool_amount: u128) -> Option { + if self.fee.denominator == 0 { + return Some(0); + } + pool_amount + .checked_mul(self.fee.numerator as u128)? + .checked_div(self.fee.denominator as u128) + } +} + +/// Program states. +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum State { + /// Unallocated state, may be initialized into another state. + Unallocated, + /// Initialized state. + Init(StakePool), +} + +impl State { + /// Deserializes a byte buffer into a [State](struct.State.html). + /// TODO efficient unpacking here + pub fn deserialize(input: &[u8]) -> Result { + if input.len() < size_of::() { + return Err(ProgramError::InvalidAccountData); + } + Ok(match input[0] { + 0 => State::Unallocated, + 1 => { + let swap: &StakePool = unpack(input)?; + State::Init(*swap) + } + _ => return Err(ProgramError::InvalidAccountData), + }) + } + + /// Serializes [State](struct.State.html) into a byte buffer. + /// TODO efficient packing here + pub fn serialize(&self, output: &mut [u8]) -> ProgramResult { + if output.len() < size_of::() { + return Err(ProgramError::InvalidAccountData); + } + match self { + Self::Unallocated => output[0] = 0, + Self::Init(swap) => { + if output.len() < size_of::() + size_of::() { + return Err(ProgramError::InvalidAccountData); + } + output[0] = 1; + #[allow(clippy::cast_ptr_alignment)] + let value = unsafe { &mut *(&mut output[1] as *mut u8 as *mut StakePool) }; + *value = *swap; + } + } + Ok(()) + } + /// Gets the `StakePool` from `State` + pub fn stake_pool(&self) -> Result { + if let State::Init(swap) = &self { + Ok(*swap) + } else { + Err(Error::InvalidState.into()) + } + } +} From 9ead0dd890a280151b1ed485dd3735de78d13f68 Mon Sep 17 00:00:00 2001 From: ysavchenko Date: Mon, 19 Oct 2020 14:26:05 +0300 Subject: [PATCH 0002/1076] Changes to stake pool program address generation (#647) * Added address type in programm address generation for the stake pool, renamed nonce to bump seed * Formatting fixed --- program/src/instruction.rs | 4 +-- program/src/processor.rs | 68 ++++++++++++++++++++++++++++---------- program/src/state.rs | 4 +-- 3 files changed, 54 insertions(+), 22 deletions(-) diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 63cbe43c..e14c287b 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -26,10 +26,10 @@ pub struct InitArgs { /// Fee paid to the owner in pool tokens pub fee: Fee, /// Nonce used for the deposit program address - pub deposit_nonce: u8, + pub deposit_bump_seed: u8, /// Nonce used for the withdraw program address /// This program address is used as the stake withdraw key as well - pub withdraw_nonce: u8, + pub withdraw_bump_seed: u8, } /// Instructions supported by the StakePool program. diff --git a/program/src/processor.rs b/program/src/processor.rs index 9fb8fcbf..ddde0118 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -23,10 +23,22 @@ use std::convert::TryFrom; /// Program state handler. pub struct Processor {} impl Processor { + /// Suffix for deposit authority seed + pub const AUTHORITY_DEPOSIT: &'static [u8] = b"deposit"; + /// Suffix for withdraw authority seed + pub const AUTHORITY_WITHDRAW: &'static [u8] = b"withdraw"; /// Calculates the authority id by generating a program address. - pub fn authority_id(program_id: &Pubkey, my_info: &Pubkey, nonce: u8) -> Result { - Pubkey::create_program_address(&[&my_info.to_bytes()[..32], &[nonce]], program_id) - .or(Err(Error::InvalidProgramAddress)) + pub fn authority_id( + program_id: &Pubkey, + my_info: &Pubkey, + authority_type: &[u8], + bump_seed: u8, + ) -> Result { + Pubkey::create_program_address( + &[&my_info.to_bytes()[..32], authority_type, &[bump_seed]], + program_id, + ) + .or(Err(Error::InvalidProgramAddress)) } /// Issue a stake_split instruction. @@ -139,8 +151,8 @@ impl Processor { let stake_pool = State::Init(StakePool { owner: *owner_info.key, - deposit_nonce: init.deposit_nonce, - withdraw_nonce: init.withdraw_nonce, + deposit_bump_seed: init.deposit_bump_seed, + withdraw_bump_seed: init.withdraw_bump_seed, pool_mint: *pool_mint_info.key, owner_fee_account: *owner_fee_info.key, token_program_id: *token_program_info.key, @@ -166,13 +178,23 @@ impl Processor { let mut stake_pool = State::deserialize(&stake_pool_info.data.borrow())?.stake_pool()?; if *withdraw_info.key - != Self::authority_id(program_id, stake_pool_info.key, stake_pool.withdraw_nonce)? + != Self::authority_id( + program_id, + stake_pool_info.key, + Self::AUTHORITY_WITHDRAW, + stake_pool.withdraw_bump_seed, + )? { return Err(Error::InvalidProgramAddress.into()); } if *deposit_info.key - != Self::authority_id(program_id, stake_pool_info.key, stake_pool.deposit_nonce)? + != Self::authority_id( + program_id, + stake_pool_info.key, + Self::AUTHORITY_DEPOSIT, + stake_pool.deposit_bump_seed, + )? { return Err(Error::InvalidProgramAddress.into()); } @@ -201,7 +223,7 @@ impl Processor { stake_pool_info.key, stake_info.clone(), deposit_info.clone(), - stake_pool.deposit_nonce, + stake_pool.deposit_bump_seed, withdraw_info.key, stake::StakeAuthorize::Withdrawer, )?; @@ -213,7 +235,7 @@ impl Processor { pool_mint_info.clone(), dest_user_info.clone(), withdraw_info.clone(), - stake_pool.withdraw_nonce, + stake_pool.withdraw_bump_seed, user_amount, )?; let fee_amount = ::try_from(fee_amount).or(Err(Error::CalculationFailure))?; @@ -223,7 +245,7 @@ impl Processor { pool_mint_info.clone(), owner_fee_info.clone(), withdraw_info.clone(), - stake_pool.withdraw_nonce, + stake_pool.withdraw_bump_seed, fee_amount as u64, )?; let pool_amount = ::try_from(pool_amount).or(Err(Error::CalculationFailure))?; @@ -251,7 +273,12 @@ impl Processor { let mut stake_pool = State::deserialize(&stake_pool_info.data.borrow())?.stake_pool()?; if *withdraw_info.key - != Self::authority_id(program_id, stake_pool_info.key, stake_pool.withdraw_nonce)? + != Self::authority_id( + program_id, + stake_pool_info.key, + Self::AUTHORITY_WITHDRAW, + stake_pool.withdraw_bump_seed, + )? { return Err(Error::InvalidProgramAddress.into()); } @@ -268,7 +295,7 @@ impl Processor { stake_pool_info.key, source_info.clone(), withdraw_info.clone(), - stake_pool.withdraw_nonce, + stake_pool.withdraw_bump_seed, stake_amount, stake_info.clone(), )?; @@ -277,7 +304,7 @@ impl Processor { stake_pool_info.key, stake_info.clone(), withdraw_info.clone(), - stake_pool.withdraw_nonce, + stake_pool.withdraw_bump_seed, dest_user_info.key, stake::StakeAuthorize::Withdrawer, )?; @@ -288,7 +315,7 @@ impl Processor { source_info.clone(), pool_mint_info.clone(), withdraw_info.clone(), - stake_pool.withdraw_nonce, + stake_pool.withdraw_bump_seed, pool_amount, )?; @@ -319,7 +346,12 @@ impl Processor { } if *withdraw_info.key - != Self::authority_id(program_id, stake_pool_info.key, stake_pool.withdraw_nonce)? + != Self::authority_id( + program_id, + stake_pool_info.key, + Self::AUTHORITY_WITHDRAW, + stake_pool.withdraw_bump_seed, + )? { return Err(Error::InvalidProgramAddress.into()); } @@ -327,7 +359,7 @@ impl Processor { stake_info.key, stake_info.clone(), withdraw_info.clone(), - stake_pool.withdraw_nonce, + stake_pool.withdraw_bump_seed, staker_info.key, stake::StakeAuthorize::Staker, )?; @@ -595,8 +627,8 @@ mod tests { &pool_token_key, &TOKEN_PROGRAM_ID, InitArgs { - deposit_nonce: 0, - withdraw_nonce: 0, + deposit_bump_seed: 0, + withdraw_bump_seed: 0, fee: Fee { denominator: 1, numerator: 2, diff --git a/program/src/state.rs b/program/src/state.rs index f6a7d022..77e5fe23 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -14,10 +14,10 @@ pub struct StakePool { pub owner: Pubkey, /// Deposit authority nonce /// for `create_program_address(&[state::StakePool account, "deposit"])` - pub deposit_nonce: u8, + pub deposit_bump_seed: u8, /// Withdrawal authority nonce /// for `create_program_address(&[state::StakePool account, "withdrawal"])` - pub withdraw_nonce: u8, + pub withdraw_bump_seed: u8, /// Pool Mint pub pool_mint: Pubkey, /// Owner fee account From 9ba95c44cec61a5c0907bc1253341c944fd4aa31 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Oct 2020 13:47:45 +0000 Subject: [PATCH 0003/1076] Bump serde from 1.0.116 to 1.0.117 (#660) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.116 to 1.0.117. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.116...v1.0.117) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 820586ef..49e677e0 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -26,7 +26,7 @@ spl-token = { path = "../../token/program", default-features = false, optional = thiserror = "1.0" arrayref = "0.3.6" num_enum = "0.5.1" -serde = "1.0.112" +serde = "1.0.117" serde_derive = "1.0.103" [dev-dependencies] From 80115c28b8c1a0df9e52bfa70a30206fe9bcb7b1 Mon Sep 17 00:00:00 2001 From: Yuriy Savchenko Date: Tue, 20 Oct 2020 22:02:05 +0300 Subject: [PATCH 0004/1076] Stake pool improvements and fixes (#665) * Added address type in programm address generation for the stake pool, renamed nonce to bump seed * Formatting fixed * Bump seed calculation moved to the smart contract, test for fee > 1 added, state length public constant added * Added claim method to stake pool, fixed program address generation in token mint and burn calls * Refactored signers management when calling other contracts * Signers formation put back into calling functions, deposit/withdraw/claim method reworked, state serialization bug fixed --- program/src/error.rs | 3 + program/src/instruction.rs | 60 +++++++----- program/src/processor.rs | 185 +++++++++++++++++++++++++++++++------ program/src/state.rs | 8 +- 4 files changed, 199 insertions(+), 57 deletions(-) diff --git a/program/src/error.rs b/program/src/error.rs index eaf507c3..1fb19e7b 100644 --- a/program/src/error.rs +++ b/program/src/error.rs @@ -40,6 +40,9 @@ pub enum Error { /// The calculation failed. #[error("CalculationFailure")] CalculationFailure, + /// Stake pool fee > 1. + #[error("FeeTooHigh")] + FeeTooHigh, } impl From for ProgramError { fn from(e: Error) -> Self { diff --git a/program/src/instruction.rs b/program/src/instruction.rs index e14c287b..296f32e5 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -25,11 +25,6 @@ pub struct Fee { pub struct InitArgs { /// Fee paid to the owner in pool tokens pub fee: Fee, - /// Nonce used for the deposit program address - pub deposit_bump_seed: u8, - /// Nonce used for the withdraw program address - /// This program address is used as the stake withdraw key as well - pub withdraw_bump_seed: u8, } /// Instructions supported by the StakePool program. @@ -48,29 +43,42 @@ pub enum StakePoolInstruction { /// Deposit some stake into the pool. The output is a "pool" token representing ownership /// into the pool. Inputs are converted to the current ratio. /// - /// 0. `[]` StakePool - /// 1. `[]` deposit authority - /// 2. `[]` withdraw authority - /// 3. `[w]` Stake, deposit authority is set as the withdrawal key - /// 4. `[w]` Pool MINT account, authority is the owner. - /// 5. `[w]` Pool Account to deposit the generated tokens. - /// 6. `[w]` Pool Account to deposit the generated fee for owner. - /// 7. `[]` Token program id + /// 0. `[w]` Stake pool + /// 1. `[]` Stake pool deposit authority + /// 2. `[]` Stake pool withdraw authority + /// 3. `[w]` Stake account to join the pool (withdraw should be set to stake pool deposit) + /// 4. `[w]` User account to receive pool tokens + /// 5. `[w]` Account to receive pool fee tokens + /// 6. `[w]` Pool token mint account + /// 7. `[]` Pool token program id Deposit, /// Withdraw the token from the pool at the current ratio. /// The amount withdrawn is the MIN(u64, stake size) /// - /// 0. `[]` StakePool - /// 1. `[]` withdraw authority - /// 2. `[w]` SOURCE Pool account, amount is transferable by authority - /// 3. `[w]` Pool MINT account, authority is the owner - /// 4. `[w]` Stake SOURCE owned by the withdraw authority - /// 6. `[w]` Stake destination, uninitialized, for the user stake - /// 7. `[]` Token program id + /// 0. `[w]` Stake pool + /// 1. `[]` Stake pool withdraw authority + /// 2. `[w]` Stake account to split + /// 3. `[w]` Unitialized stake account to receive withdrawal + /// 4. `[]` User account to set as a new withdraw authority + /// 5. `[w]` User account with pool tokens to burn from + /// 6. `[w]` Pool token mint account + /// 7. `[]` Pool token program id /// userdata: amount to withdraw Withdraw(u64), + /// Claim ownership of a whole stake account. + /// Also burns enough tokens to make up for the stake account balance + /// + /// 0. `[w]` Stake pool + /// 1. `[]` Stake pool withdraw authority + /// 2. `[w]` Stake account to claim + /// 3. `[]` User account to set as a new withdraw authority + /// 4. `[w]` User account with pool tokens to burn from + /// 5. `[w]` Pool token mint account + /// 6. `[]` Pool token program id + Claim, + /// Update the staking pubkey for a stake /// /// 0. `[w]` StakePool @@ -106,8 +114,9 @@ impl StakePoolInstruction { let val: &u64 = unpack(input)?; Self::Withdraw(*val) } - 3 => Self::SetStakingAuthority, - 4 => Self::SetOwner, + 3 => Self::Claim, + 4 => Self::SetStakingAuthority, + 5 => Self::SetOwner, _ => return Err(ProgramError::InvalidAccountData), }) } @@ -132,12 +141,15 @@ impl StakePoolInstruction { let value = unsafe { &mut *(&mut output[1] as *mut u8 as *mut u64) }; *value = *val; } - Self::SetStakingAuthority => { + Self::Claim => { output[0] = 3; } - Self::SetOwner => { + Self::SetStakingAuthority => { output[0] = 4; } + Self::SetOwner => { + output[0] = 5; + } } Ok(output) } diff --git a/program/src/processor.rs b/program/src/processor.rs index ddde0118..0a02f62a 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -40,18 +40,29 @@ impl Processor { ) .or(Err(Error::InvalidProgramAddress)) } + /// Generates seed bump for stake pool authorities + pub fn find_authority_bump_seed( + program_id: &Pubkey, + my_info: &Pubkey, + authority_type: &[u8], + ) -> u8 { + let (_pubkey, bump_seed) = + Pubkey::find_program_address(&[&my_info.to_bytes()[..32], authority_type], program_id); + bump_seed + } /// Issue a stake_split instruction. pub fn stake_split<'a>( stake_pool: &Pubkey, stake_account: AccountInfo<'a>, authority: AccountInfo<'a>, - nonce: u8, + authority_type: &[u8], + bump_seed: u8, amount: u64, split_stake: AccountInfo<'a>, ) -> Result<(), ProgramError> { let me_bytes = stake_pool.to_bytes(); - let authority_signature_seeds = [&me_bytes[..32], &[nonce]]; + let authority_signature_seeds = [&me_bytes[..32], authority_type, &[bump_seed]]; let signers = &[&authority_signature_seeds[..]]; let ix = stake::split_only(stake_account.key, authority.key, amount, split_stake.key); @@ -64,12 +75,13 @@ impl Processor { stake_pool: &Pubkey, stake_account: AccountInfo<'a>, authority: AccountInfo<'a>, - nonce: u8, + authority_type: &[u8], + bump_seed: u8, new_staker: &Pubkey, staker_auth: stake::StakeAuthorize, ) -> Result<(), ProgramError> { let me_bytes = stake_pool.to_bytes(); - let authority_signature_seeds = [&me_bytes[..32], &[nonce]]; + let authority_signature_seeds = [&me_bytes[..32], authority_type, &[bump_seed]]; let signers = &[&authority_signature_seeds[..]]; let ix = stake::authorize(stake_account.key, authority.key, new_staker, staker_auth); @@ -78,17 +90,19 @@ impl Processor { } /// Issue a spl_token `Burn` instruction. + #[allow(clippy::too_many_arguments)] pub fn token_burn<'a>( stake_pool: &Pubkey, token_program: AccountInfo<'a>, burn_account: AccountInfo<'a>, mint: AccountInfo<'a>, authority: AccountInfo<'a>, - nonce: u8, + authority_type: &[u8], + bump_seed: u8, amount: u64, ) -> Result<(), ProgramError> { let me_bytes = stake_pool.to_bytes(); - let authority_signature_seeds = [&me_bytes[..32], &[nonce]]; + let authority_signature_seeds = [&me_bytes[..32], authority_type, &[bump_seed]]; let signers = &[&authority_signature_seeds[..]]; let ix = spl_token::instruction::burn( @@ -108,18 +122,21 @@ impl Processor { } /// Issue a spl_token `MintTo` instruction. + #[allow(clippy::too_many_arguments)] pub fn token_mint_to<'a>( stake_pool: &Pubkey, token_program: AccountInfo<'a>, mint: AccountInfo<'a>, destination: AccountInfo<'a>, authority: AccountInfo<'a>, - nonce: u8, + authority_type: &[u8], + bump_seed: u8, amount: u64, ) -> Result<(), ProgramError> { let me_bytes = stake_pool.to_bytes(); - let authority_signature_seeds = [&me_bytes[..32], &[nonce]]; + let authority_signature_seeds = [&me_bytes[..32], authority_type, &[bump_seed]]; let signers = &[&authority_signature_seeds[..]]; + let ix = spl_token::instruction::mint_to( token_program.key, mint.key, @@ -134,7 +151,7 @@ impl Processor { /// Processes an [Initialize](enum.Instruction.html). pub fn process_initialize( - _program_id: &Pubkey, + program_id: &Pubkey, init: InitArgs, accounts: &[AccountInfo], ) -> ProgramResult { @@ -145,14 +162,28 @@ impl Processor { let owner_fee_info = next_account_info(account_info_iter)?; let token_program_info = next_account_info(account_info_iter)?; + // Stake pool account should not be already initialized if State::Unallocated != State::deserialize(&stake_pool_info.data.borrow())? { return Err(Error::AlreadyInUse.into()); } + // Numerator should be smaller than or equal to denominator (fee <= 1) + if init.fee.numerator > init.fee.denominator { + return Err(Error::FeeTooHigh.into()); + } + let stake_pool = State::Init(StakePool { owner: *owner_info.key, - deposit_bump_seed: init.deposit_bump_seed, - withdraw_bump_seed: init.withdraw_bump_seed, + deposit_bump_seed: Self::find_authority_bump_seed( + program_id, + stake_pool_info.key, + Self::AUTHORITY_DEPOSIT, + ), + withdraw_bump_seed: Self::find_authority_bump_seed( + program_id, + stake_pool_info.key, + Self::AUTHORITY_WITHDRAW, + ), pool_mint: *pool_mint_info.key, owner_fee_account: *owner_fee_info.key, token_program_id: *token_program_info.key, @@ -163,16 +194,24 @@ impl Processor { stake_pool.serialize(&mut stake_pool_info.data.borrow_mut()) } - /// Processes an [Withdraw](enum.Instruction.html). + /// Processes [Deposit](enum.Instruction.html). pub fn process_deposit(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { let account_info_iter = &mut accounts.iter(); + // Stake pool let stake_pool_info = next_account_info(account_info_iter)?; + // Stake pool deposit authority let deposit_info = next_account_info(account_info_iter)?; + // Stake pool withdraw authority let withdraw_info = next_account_info(account_info_iter)?; + // Stake account to join the pool (withdraw should be set to stake pool deposit) let stake_info = next_account_info(account_info_iter)?; - let pool_mint_info = next_account_info(account_info_iter)?; + // User account to receive pool tokens let dest_user_info = next_account_info(account_info_iter)?; + // Account to receive pool fee tokens let owner_fee_info = next_account_info(account_info_iter)?; + // Pool token mint account + let pool_mint_info = next_account_info(account_info_iter)?; + // Pool token program id let token_program_info = next_account_info(account_info_iter)?; let mut stake_pool = State::deserialize(&stake_pool_info.data.borrow())?.stake_pool()?; @@ -223,6 +262,7 @@ impl Processor { stake_pool_info.key, stake_info.clone(), deposit_info.clone(), + Self::AUTHORITY_DEPOSIT, stake_pool.deposit_bump_seed, withdraw_info.key, stake::StakeAuthorize::Withdrawer, @@ -235,7 +275,8 @@ impl Processor { pool_mint_info.clone(), dest_user_info.clone(), withdraw_info.clone(), - stake_pool.withdraw_bump_seed, + Self::AUTHORITY_DEPOSIT, + stake_pool.deposit_bump_seed, user_amount, )?; let fee_amount = ::try_from(fee_amount).or(Err(Error::CalculationFailure))?; @@ -245,6 +286,7 @@ impl Processor { pool_mint_info.clone(), owner_fee_info.clone(), withdraw_info.clone(), + Self::AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, fee_amount as u64, )?; @@ -255,19 +297,28 @@ impl Processor { Ok(()) } - /// Processes an [Withdraw](enum.Instruction.html). + /// Processes [Withdraw](enum.Instruction.html). pub fn process_withdraw( program_id: &Pubkey, stake_amount: u64, accounts: &[AccountInfo], ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); + // Stake pool let stake_pool_info = next_account_info(account_info_iter)?; + // Stake pool withdraw authority let withdraw_info = next_account_info(account_info_iter)?; - let source_info = next_account_info(account_info_iter)?; + // Stake account to split + let stake_split_from = next_account_info(account_info_iter)?; + // Unitialized stake account to receive withdrawal + let stake_split_to = next_account_info(account_info_iter)?; + // User account to set as a new withdraw authority + let user_stake_authority = next_account_info(account_info_iter)?; + // User account with pool tokens to burn from + let burn_from_info = next_account_info(account_info_iter)?; + // Pool token mint account let pool_mint_info = next_account_info(account_info_iter)?; - let stake_info = next_account_info(account_info_iter)?; - let dest_user_info = next_account_info(account_info_iter)?; + // Pool token program id let token_program_info = next_account_info(account_info_iter)?; let mut stake_pool = State::deserialize(&stake_pool_info.data.borrow())?.stake_pool()?; @@ -293,28 +344,31 @@ impl Processor { Self::stake_split( stake_pool_info.key, - source_info.clone(), + stake_split_from.clone(), withdraw_info.clone(), + Self::AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, stake_amount, - stake_info.clone(), + stake_split_to.clone(), )?; Self::stake_authorize( stake_pool_info.key, - stake_info.clone(), + stake_split_to.clone(), withdraw_info.clone(), + Self::AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, - dest_user_info.key, + user_stake_authority.key, stake::StakeAuthorize::Withdrawer, )?; Self::token_burn( stake_pool_info.key, token_program_info.clone(), - source_info.clone(), + burn_from_info.clone(), pool_mint_info.clone(), withdraw_info.clone(), + Self::AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, pool_amount, )?; @@ -324,7 +378,73 @@ impl Processor { State::Init(stake_pool).serialize(&mut stake_pool_info.data.borrow_mut())?; Ok(()) } - /// Processes an [SetStakeAuthority](enum.Instruction.html). + /// Processes [Claim](enum.Instruction.html). + pub fn process_claim(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { + let account_info_iter = &mut accounts.iter(); + // Stake pool + let stake_pool_info = next_account_info(account_info_iter)?; + // Stake pool withdraw authority + let withdraw_info = next_account_info(account_info_iter)?; + // Stake account to claim + let stake_to_claim = next_account_info(account_info_iter)?; + // User account to set as a new withdraw authority + let user_stake_authority = next_account_info(account_info_iter)?; + // User account with pool tokens to burn from + let burn_from_info = next_account_info(account_info_iter)?; + // Pool token account + let pool_mint_info = next_account_info(account_info_iter)?; + // Pool token program id + let token_program_info = next_account_info(account_info_iter)?; + + let mut stake_pool = State::deserialize(&stake_pool_info.data.borrow())?.stake_pool()?; + + if *withdraw_info.key + != Self::authority_id( + program_id, + stake_pool_info.key, + Self::AUTHORITY_WITHDRAW, + stake_pool.withdraw_bump_seed, + )? + { + return Err(Error::InvalidProgramAddress.into()); + } + if stake_pool.token_program_id != *token_program_info.key { + return Err(Error::InvalidInput.into()); + } + + let stake_amount = **stake_to_claim.lamports.borrow(); + let pool_amount = stake_pool + .calc_pool_withdraw_amount(stake_amount) + .ok_or(Error::CalculationFailure)?; + let pool_amount = ::try_from(pool_amount).or(Err(Error::CalculationFailure))?; + + Self::stake_authorize( + stake_pool_info.key, + stake_to_claim.clone(), + withdraw_info.clone(), + Self::AUTHORITY_WITHDRAW, + stake_pool.withdraw_bump_seed, + user_stake_authority.key, + stake::StakeAuthorize::Withdrawer, + )?; + + Self::token_burn( + stake_pool_info.key, + token_program_info.clone(), + burn_from_info.clone(), + pool_mint_info.clone(), + withdraw_info.clone(), + Self::AUTHORITY_WITHDRAW, + stake_pool.withdraw_bump_seed, + pool_amount, + )?; + + stake_pool.pool_total -= pool_amount; + stake_pool.stake_total -= stake_amount; + State::Init(stake_pool).serialize(&mut stake_pool_info.data.borrow_mut())?; + Ok(()) + } + /// Processes [SetStakeAuthority](enum.Instruction.html). pub fn process_set_staking_auth( program_id: &Pubkey, accounts: &[AccountInfo], @@ -355,10 +475,12 @@ impl Processor { { return Err(Error::InvalidProgramAddress.into()); } + Self::stake_authorize( - stake_info.key, + stake_pool_info.key, stake_info.clone(), withdraw_info.clone(), + Self::AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, staker_info.key, stake::StakeAuthorize::Staker, @@ -366,7 +488,7 @@ impl Processor { Ok(()) } - /// Processes an [SetOwner](enum.Instruction.html). + /// Processes [SetOwner](enum.Instruction.html). pub fn process_set_owner(_program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; @@ -387,7 +509,7 @@ impl Processor { State::Init(stake_pool).serialize(&mut stake_pool_info.data.borrow_mut())?; Ok(()) } - /// Processes an [Instruction](enum.Instruction.html). + /// Processes [Instruction](enum.Instruction.html). pub fn process(program_id: &Pubkey, accounts: &[AccountInfo], input: &[u8]) -> ProgramResult { let instruction = StakePoolInstruction::deserialize(input)?; match instruction { @@ -403,6 +525,10 @@ impl Processor { info!("Instruction: Withdraw"); Self::process_withdraw(program_id, amount, accounts) } + StakePoolInstruction::Claim => { + info!("Instruction: Claim"); + Self::process_claim(program_id, accounts) + } StakePoolInstruction::SetStakingAuthority => { info!("Instruction: SetStakingAuthority"); Self::process_set_staking_auth(program_id, accounts) @@ -476,6 +602,7 @@ impl PrintProgramError for Error { Error::InvalidInput => info!("Error: InvalidInput"), Error::InvalidOutput => info!("Error: InvalidOutput"), Error::CalculationFailure => info!("Error: CalculationFailure"), + Error::FeeTooHigh => info!("Error: FeeTooHigh"), } } } @@ -627,10 +754,8 @@ mod tests { &pool_token_key, &TOKEN_PROGRAM_ID, InitArgs { - deposit_bump_seed: 0, - withdraw_bump_seed: 0, fee: Fee { - denominator: 1, + denominator: 10, numerator: 2, }, }, diff --git a/program/src/state.rs b/program/src/state.rs index 77e5fe23..696a7955 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -12,10 +12,10 @@ pub struct StakePool { /// Owner authority /// allows for updating the staking authority pub owner: Pubkey, - /// Deposit authority nonce + /// Deposit authority bump seed /// for `create_program_address(&[state::StakePool account, "deposit"])` pub deposit_bump_seed: u8, - /// Withdrawal authority nonce + /// Withdrawal authority bump seed /// for `create_program_address(&[state::StakePool account, "withdrawal"])` pub withdraw_bump_seed: u8, /// Pool Mint @@ -67,6 +67,8 @@ pub enum State { } impl State { + /// Length of state data when serialized + pub const LEN: usize = size_of::() + size_of::(); /// Deserializes a byte buffer into a [State](struct.State.html). /// TODO efficient unpacking here pub fn deserialize(input: &[u8]) -> Result { @@ -76,7 +78,7 @@ impl State { Ok(match input[0] { 0 => State::Unallocated, 1 => { - let swap: &StakePool = unpack(input)?; + let swap: &StakePool = unpack(&input[1..])?; State::Init(*swap) } _ => return Err(ProgramError::InvalidAccountData), From c24f6161c743c53aa44dc777ab7e89cb787bb685 Mon Sep 17 00:00:00 2001 From: Yuriy Savchenko Date: Wed, 21 Oct 2020 15:21:54 +0300 Subject: [PATCH 0005/1076] Added stake pool instruction interface methods (#684) * Added address type in programm address generation for the stake pool, renamed nonce to bump seed * Formatting fixed * Bump seed calculation moved to the smart contract, test for fee > 1 added, state length public constant added * Added claim method to stake pool, fixed program address generation in token mint and burn calls * Refactored signers management when calling other contracts * Signers formation put back into calling functions, deposit/withdraw/claim method reworked, state serialization bug fixed * Added instruction interface methods * Fixed signer flags for accounts in stake pool instruction creation --- program/src/instruction.rs | 141 +++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 296f32e5..f9d0e0eb 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -190,3 +190,144 @@ pub fn initialize( data, }) } + +/// Creates a 'deposit' instruction. +pub fn deposit( + program_id: &Pubkey, + stake_pool: &Pubkey, + stake_pool_deposit: &Pubkey, + stake_pool_withdraw: &Pubkey, + stake_to_join: &Pubkey, + pool_tokens_to: &Pubkey, + pool_fee_to: &Pubkey, + pool_mint: &Pubkey, + token_program_id: &Pubkey, +) -> Result { + let args = StakePoolInstruction::Deposit; + let data = args.serialize()?; + let accounts = vec![ + AccountMeta::new(*stake_pool, false), + AccountMeta::new(*stake_pool_deposit, false), + AccountMeta::new(*stake_pool_withdraw, false), + AccountMeta::new(*stake_to_join, false), + AccountMeta::new(*pool_tokens_to, false), + AccountMeta::new(*pool_fee_to, false), + AccountMeta::new(*pool_mint, false), + AccountMeta::new(*token_program_id, false), + ]; + Ok(Instruction { + program_id: *program_id, + accounts, + data, + }) +} + +/// Creates a 'withdraw' instruction. +pub fn withdraw( + program_id: &Pubkey, + stake_pool: &Pubkey, + stake_pool_withdraw: &Pubkey, + stake_to_split: &Pubkey, + stake_to_receive: &Pubkey, + user_withdrawer: &Pubkey, + burn_from: &Pubkey, + pool_mint: &Pubkey, + token_program_id: &Pubkey, + amount: u64, +) -> Result { + let args = StakePoolInstruction::Withdraw(amount); + let data = args.serialize()?; + let accounts = vec![ + AccountMeta::new(*stake_pool, false), + AccountMeta::new(*stake_pool_withdraw, false), + AccountMeta::new(*stake_to_split, false), + AccountMeta::new(*stake_to_receive, false), + AccountMeta::new(*user_withdrawer, false), + AccountMeta::new(*burn_from, true), + AccountMeta::new(*pool_mint, false), + AccountMeta::new(*token_program_id, false), + ]; + Ok(Instruction { + program_id: *program_id, + accounts, + data, + }) +} + +/// Creates a 'claim' instruction. +pub fn claim( + program_id: &Pubkey, + stake_pool: &Pubkey, + stake_pool_withdraw: &Pubkey, + stake_to_claim: &Pubkey, + user_withdrawer: &Pubkey, + burn_from: &Pubkey, + pool_mint: &Pubkey, + token_program_id: &Pubkey, + amount: u64, +) -> Result { + let args = StakePoolInstruction::Withdraw(amount); + let data = args.serialize()?; + let accounts = vec![ + AccountMeta::new(*stake_pool, false), + AccountMeta::new(*stake_pool_withdraw, false), + AccountMeta::new(*stake_to_claim, false), + AccountMeta::new(*user_withdrawer, false), + AccountMeta::new(*burn_from, true), + AccountMeta::new(*pool_mint, false), + AccountMeta::new(*token_program_id, false), + ]; + Ok(Instruction { + program_id: *program_id, + accounts, + data, + }) +} + +/// Creates a 'set staking authority' instruction. +pub fn set_staking_authority( + program_id: &Pubkey, + stake_pool: &Pubkey, + stake_pool_owner: &Pubkey, + stake_pool_withdraw: &Pubkey, + stake_account_to_update: &Pubkey, + stake_account_new_authority: &Pubkey, +) -> Result { + let args = StakePoolInstruction::SetStakingAuthority; + let data = args.serialize()?; + let accounts = vec![ + AccountMeta::new(*stake_pool, false), + AccountMeta::new(*stake_pool_owner, true), + AccountMeta::new(*stake_pool_withdraw, false), + AccountMeta::new(*stake_account_to_update, false), + AccountMeta::new(*stake_account_new_authority, false), + ]; + Ok(Instruction { + program_id: *program_id, + accounts, + data, + }) +} + +/// Creates a 'set owner' instruction. +pub fn set_owner( + program_id: &Pubkey, + stake_pool: &Pubkey, + stake_pool_owner: &Pubkey, + stake_pool_new_owner: &Pubkey, + stake_pool_new_fee_receiver: &Pubkey, +) -> Result { + let args = StakePoolInstruction::SetStakingAuthority; + let data = args.serialize()?; + let accounts = vec![ + AccountMeta::new(*stake_pool, false), + AccountMeta::new(*stake_pool_owner, true), + AccountMeta::new(*stake_pool_new_owner, false), + AccountMeta::new(*stake_pool_new_fee_receiver, false), + ]; + Ok(Instruction { + program_id: *program_id, + accounts, + data, + }) +} From cbb19cdd4975e884e8b62a3bc3b65dc46902c6d2 Mon Sep 17 00:00:00 2001 From: Yuriy Savchenko Date: Fri, 23 Oct 2020 15:25:53 +0300 Subject: [PATCH 0006/1076] Interface accounts added as read-only, fixed mint authority on deposit, fixed stake pool stake deserializing (#702) --- program/src/instruction.rs | 38 +++++++++++++++++++------------------- program/src/processor.rs | 4 ++-- program/src/state.rs | 3 ++- 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/program/src/instruction.rs b/program/src/instruction.rs index f9d0e0eb..6f7e1881 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -179,10 +179,10 @@ pub fn initialize( let data = init_data.serialize()?; let accounts = vec![ AccountMeta::new(*stake_pool, true), - AccountMeta::new(*owner, false), - AccountMeta::new(*pool_mint, false), - AccountMeta::new(*owner_pool_account, false), - AccountMeta::new(*token_program_id, false), + AccountMeta::new_readonly(*owner, false), + AccountMeta::new_readonly(*pool_mint, false), + AccountMeta::new_readonly(*owner_pool_account, false), + AccountMeta::new_readonly(*token_program_id, false), ]; Ok(Instruction { program_id: *program_id, @@ -207,13 +207,13 @@ pub fn deposit( let data = args.serialize()?; let accounts = vec![ AccountMeta::new(*stake_pool, false), - AccountMeta::new(*stake_pool_deposit, false), - AccountMeta::new(*stake_pool_withdraw, false), + AccountMeta::new_readonly(*stake_pool_deposit, false), + AccountMeta::new_readonly(*stake_pool_withdraw, false), AccountMeta::new(*stake_to_join, false), AccountMeta::new(*pool_tokens_to, false), AccountMeta::new(*pool_fee_to, false), AccountMeta::new(*pool_mint, false), - AccountMeta::new(*token_program_id, false), + AccountMeta::new_readonly(*token_program_id, false), ]; Ok(Instruction { program_id: *program_id, @@ -239,13 +239,13 @@ pub fn withdraw( let data = args.serialize()?; let accounts = vec![ AccountMeta::new(*stake_pool, false), - AccountMeta::new(*stake_pool_withdraw, false), + AccountMeta::new_readonly(*stake_pool_withdraw, false), AccountMeta::new(*stake_to_split, false), AccountMeta::new(*stake_to_receive, false), - AccountMeta::new(*user_withdrawer, false), + AccountMeta::new_readonly(*user_withdrawer, false), AccountMeta::new(*burn_from, true), AccountMeta::new(*pool_mint, false), - AccountMeta::new(*token_program_id, false), + AccountMeta::new_readonly(*token_program_id, false), ]; Ok(Instruction { program_id: *program_id, @@ -270,12 +270,12 @@ pub fn claim( let data = args.serialize()?; let accounts = vec![ AccountMeta::new(*stake_pool, false), - AccountMeta::new(*stake_pool_withdraw, false), + AccountMeta::new_readonly(*stake_pool_withdraw, false), AccountMeta::new(*stake_to_claim, false), - AccountMeta::new(*user_withdrawer, false), + AccountMeta::new_readonly(*user_withdrawer, false), AccountMeta::new(*burn_from, true), AccountMeta::new(*pool_mint, false), - AccountMeta::new(*token_program_id, false), + AccountMeta::new_readonly(*token_program_id, false), ]; Ok(Instruction { program_id: *program_id, @@ -297,10 +297,10 @@ pub fn set_staking_authority( let data = args.serialize()?; let accounts = vec![ AccountMeta::new(*stake_pool, false), - AccountMeta::new(*stake_pool_owner, true), - AccountMeta::new(*stake_pool_withdraw, false), + AccountMeta::new_readonly(*stake_pool_owner, true), + AccountMeta::new_readonly(*stake_pool_withdraw, false), AccountMeta::new(*stake_account_to_update, false), - AccountMeta::new(*stake_account_new_authority, false), + AccountMeta::new_readonly(*stake_account_new_authority, false), ]; Ok(Instruction { program_id: *program_id, @@ -321,9 +321,9 @@ pub fn set_owner( let data = args.serialize()?; let accounts = vec![ AccountMeta::new(*stake_pool, false), - AccountMeta::new(*stake_pool_owner, true), - AccountMeta::new(*stake_pool_new_owner, false), - AccountMeta::new(*stake_pool_new_fee_receiver, false), + AccountMeta::new_readonly(*stake_pool_owner, true), + AccountMeta::new_readonly(*stake_pool_new_owner, false), + AccountMeta::new_readonly(*stake_pool_new_fee_receiver, false), ]; Ok(Instruction { program_id: *program_id, diff --git a/program/src/processor.rs b/program/src/processor.rs index 0a02f62a..bacd85e1 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -275,8 +275,8 @@ impl Processor { pool_mint_info.clone(), dest_user_info.clone(), withdraw_info.clone(), - Self::AUTHORITY_DEPOSIT, - stake_pool.deposit_bump_seed, + Self::AUTHORITY_WITHDRAW, + stake_pool.withdraw_bump_seed, user_amount, )?; let fee_amount = ::try_from(fee_amount).or(Err(Error::CalculationFailure))?; diff --git a/program/src/state.rs b/program/src/state.rs index 696a7955..30c1618b 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -78,7 +78,8 @@ impl State { Ok(match input[0] { 0 => State::Unallocated, 1 => { - let swap: &StakePool = unpack(&input[1..])?; + // We send whole input here, because unpack skips the first byte + let swap: &StakePool = unpack(&input)?; State::Init(*swap) } _ => return Err(ProgramError::InvalidAccountData), From d65a6b0e5497672e3b5072e0cbd1a17980ca9f63 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Thu, 22 Oct 2020 21:44:27 -0700 Subject: [PATCH 0007/1076] Port SPL to solana-program and `cargo build-bpf` --- clients/cli/Cargo.toml | 14 +++++++------- program/Cargo.toml | 12 +++--------- program/src/entrypoint.rs | 5 +---- program/src/error.rs | 2 +- program/src/instruction.rs | 8 ++++---- program/src/lib.rs | 11 ++++++----- program/src/processor.rs | 14 ++++---------- program/src/stake.rs | 4 ++-- program/src/state.rs | 2 +- 9 files changed, 29 insertions(+), 43 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index f4b67484..8b330f4b 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,13 +11,13 @@ version = "2.0.1" [dependencies] clap = "2.33.3" serde_json = "1.0.57" -solana-account-decoder = { version = "1.3.9" } -solana-clap-utils = { version = "1.3.9"} -solana-cli-config = { version = "1.3.9" } -solana-client = { version = "1.3.9" } -solana-logger = { version = "1.3.9" } -solana-sdk = { version = "1.3.9" } -spl-stake-pool = { version = "2.0", path="../program" } +solana-account-decoder = "1.4.3" +solana-clap-utils = "1.4.3" +solana-cli-config = "1.4.3" +solana-client = "1.4.3" +solana-logger = "1.4.3" +solana-sdk = "1.4.3" +spl-stake-pool = { version = "0.1.0", path="../program", features = [ "exclude_entrypoint" ] } [[bin]] name = "spl-stake-pool" diff --git a/program/Cargo.toml b/program/Cargo.toml index 49e677e0..a61de1fb 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -1,6 +1,3 @@ - -# Note: This crate must be built using do.sh - [package] name = "spl-stake-pool" version = "0.1.0" @@ -12,17 +9,14 @@ edition = "2018" exclude = ["js/**"] [features] -no-entrypoint = [] -program = ["solana-sdk/program", "spl-token/program", "spl-token/no-entrypoint"] -default = ["solana-sdk/default", "spl-token/default"] - +exclude_entrypoint = [] [dependencies] num-derive = "0.3" num-traits = "0.2" remove_dir_all = "=0.5.0" -solana-sdk = { version = "1.3.17", default-features = false, optional = true } -spl-token = { path = "../../token/program", default-features = false, optional = true } +solana-program = "1.4.3" +spl-token = { path = "../../token/program", features = [ "exclude_entrypoint" ] } thiserror = "1.0" arrayref = "0.3.6" num_enum = "0.5.1" diff --git a/program/src/entrypoint.rs b/program/src/entrypoint.rs index d916cd5a..a7afa8c8 100644 --- a/program/src/entrypoint.rs +++ b/program/src/entrypoint.rs @@ -1,10 +1,7 @@ //! Program entrypoint -#![cfg(feature = "program")] -#![cfg(not(feature = "no-entrypoint"))] - use crate::{error::Error, processor::Processor}; -use solana_sdk::{ +use solana_program::{ account_info::AccountInfo, entrypoint, entrypoint::ProgramResult, program_error::PrintProgramError, pubkey::Pubkey, }; diff --git a/program/src/error.rs b/program/src/error.rs index 1fb19e7b..1c42aa57 100644 --- a/program/src/error.rs +++ b/program/src/error.rs @@ -1,7 +1,7 @@ //! Error types use num_derive::FromPrimitive; -use solana_sdk::{decode_error::DecodeError, program_error::ProgramError}; +use solana_program::{decode_error::DecodeError, program_error::ProgramError}; use thiserror::Error; /// Errors that may be returned by the StakePool program. diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 6f7e1881..488534bf 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -2,10 +2,10 @@ #![allow(clippy::too_many_arguments)] -use solana_sdk::instruction::AccountMeta; -use solana_sdk::instruction::Instruction; -use solana_sdk::program_error::ProgramError; -use solana_sdk::pubkey::Pubkey; +use solana_program::instruction::AccountMeta; +use solana_program::instruction::Instruction; +use solana_program::program_error::ProgramError; +use solana_program::pubkey::Pubkey; use std::mem::size_of; /// Fee rate as a ratio diff --git a/program/src/lib.rs b/program/src/lib.rs index fc5cac6c..10dda2c6 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -2,15 +2,16 @@ //! A program for creating pools of Solana stakes managed by a Stake-o-Matic -pub mod entrypoint; pub mod error; pub mod instruction; pub mod processor; pub mod stake; pub mod state; -// Export current solana-sdk types for downstream users who may also be building with a different -// solana-sdk version -pub use solana_sdk; +#[cfg(not(feature = "exclude_entrypoint"))] +pub mod entrypoint; + +// Export current sdk types for downstream users building with a different sdk version +pub use solana_program; -solana_sdk::declare_id!("STAKEPQQL1111111111111111111111111111111111"); +solana_program::declare_id!("STAKEPQQL1111111111111111111111111111111111"); diff --git a/program/src/processor.rs b/program/src/processor.rs index bacd85e1..2922f6b4 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1,7 +1,5 @@ //! Program state processor -#![cfg(feature = "program")] - use crate::{ error::Error, instruction::{InitArgs, StakePoolInstruction}, @@ -10,10 +8,10 @@ use crate::{ }; use num_traits::FromPrimitive; #[cfg(not(target_arch = "bpf"))] -use solana_sdk::instruction::Instruction; +use solana_program::instruction::Instruction; #[cfg(target_arch = "bpf")] -use solana_sdk::program::invoke_signed; -use solana_sdk::{ +use solana_program::program::invoke_signed; +use solana_program::{ account_info::next_account_info, account_info::AccountInfo, decode_error::DecodeError, entrypoint::ProgramResult, info, program_error::PrintProgramError, program_error::ProgramError, pubkey::Pubkey, @@ -607,10 +605,6 @@ impl PrintProgramError for Error { } } -// Pull in syscall stubs when building for non-BPF targets -#[cfg(not(target_arch = "bpf"))] -solana_sdk::program_stubs!(); - #[cfg(test)] mod tests { use super::*; @@ -618,7 +612,7 @@ mod tests { use crate::instruction::Fee; use crate::instruction::InitArgs; use core::mem::size_of; - use solana_sdk::{ + use solana_program::{ account::Account, account_info::create_is_signer_account_infos, instruction::Instruction, program_pack::Pack, rent::Rent, sysvar::rent, }; diff --git a/program/src/stake.rs b/program/src/stake.rs index 940ad7e9..7077291e 100644 --- a/program/src/stake.rs +++ b/program/src/stake.rs @@ -1,13 +1,13 @@ //! FIXME copied from the solana stake program use serde_derive::{Deserialize, Serialize}; -use solana_sdk::{ +use solana_program::{ instruction::{AccountMeta, Instruction}, pubkey::Pubkey, sysvar, }; -solana_sdk::declare_id!("StakeConfig11111111111111111111111111111111"); +solana_program::declare_id!("StakeConfig11111111111111111111111111111111"); /// FIXME copied from solana stake program #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] diff --git a/program/src/state.rs b/program/src/state.rs index 30c1618b..1bae9a7d 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -2,7 +2,7 @@ use crate::error::Error; use crate::instruction::{unpack, Fee}; -use solana_sdk::{entrypoint::ProgramResult, program_error::ProgramError, pubkey::Pubkey}; +use solana_program::{entrypoint::ProgramResult, program_error::ProgramError, pubkey::Pubkey}; use std::mem::size_of; /// Initialized program details. From a6ab2733c803fcaac89bb78e67de800660fb6297 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Sat, 24 Oct 2020 19:33:08 -0700 Subject: [PATCH 0008/1076] Clean up stake-pool copypasta --- program/src/processor.rs | 98 ++++++++++------------------------------ 1 file changed, 25 insertions(+), 73 deletions(-) diff --git a/program/src/processor.rs b/program/src/processor.rs index 2922f6b4..cd908505 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -7,14 +7,10 @@ use crate::{ state::{StakePool, State}, }; use num_traits::FromPrimitive; -#[cfg(not(target_arch = "bpf"))] -use solana_program::instruction::Instruction; -#[cfg(target_arch = "bpf")] -use solana_program::program::invoke_signed; use solana_program::{ account_info::next_account_info, account_info::AccountInfo, decode_error::DecodeError, - entrypoint::ProgramResult, info, program_error::PrintProgramError, program_error::ProgramError, - pubkey::Pubkey, + entrypoint::ProgramResult, info, program::invoke_signed, program_error::PrintProgramError, + program_error::ProgramError, pubkey::Pubkey, }; use std::convert::TryFrom; @@ -539,50 +535,6 @@ impl Processor { } } -// Test program id for the stake-pool program. -#[cfg(not(target_arch = "bpf"))] -const STAKE_POOL_PROGRAM_ID: Pubkey = Pubkey::new_from_array([2u8; 32]); - -// Test program id for the token program. -#[cfg(not(target_arch = "bpf"))] -const TOKEN_PROGRAM_ID: Pubkey = Pubkey::new_from_array([1u8; 32]); - -/// Routes invokes to the token program, used for testing. -/// TODO add routing to stake program for testing -#[cfg(not(target_arch = "bpf"))] -pub fn invoke_signed<'a>( - instruction: &Instruction, - account_infos: &[AccountInfo<'a>], - signers_seeds: &[&[&[u8]]], -) -> ProgramResult { - // mimic check for token program in accounts - if !account_infos.iter().any(|x| *x.key == TOKEN_PROGRAM_ID) { - return Err(ProgramError::InvalidAccountData); - } - - let mut new_account_infos = vec![]; - for meta in instruction.accounts.iter() { - for account_info in account_infos.iter() { - if meta.pubkey == *account_info.key { - let mut new_account_info = account_info.clone(); - for seeds in signers_seeds.iter() { - let signer = - Pubkey::create_program_address(seeds, &STAKE_POOL_PROGRAM_ID).unwrap(); - if *account_info.key == signer { - new_account_info.is_signer = true; - } - } - new_account_infos.push(new_account_info); - } - } - } - spl_token::processor::Processor::process( - &instruction.program_id, - &new_account_infos, - &instruction.data, - ) -} - impl PrintProgramError for Error { fn print(&self) where @@ -608,23 +560,19 @@ impl PrintProgramError for Error { #[cfg(test)] mod tests { use super::*; - use crate::instruction::initialize; - use crate::instruction::Fee; - use crate::instruction::InitArgs; + use crate::instruction::{initialize, Fee, InitArgs}; use core::mem::size_of; use solana_program::{ account::Account, account_info::create_is_signer_account_infos, instruction::Instruction, program_pack::Pack, rent::Rent, sysvar::rent, }; - use spl_token::{ - instruction::{initialize_account, initialize_mint}, - processor::Processor as SplProcessor, - state::{Account as SplAccount, Mint as SplMint}, - }; + use spl_token::instruction::{initialize_account, initialize_mint}; - fn pubkey_rand() -> Pubkey { - Pubkey::new(&rand::random::<[u8; 32]>()) - } + // Test program id for the stake-pool program. + const STAKE_POOL_PROGRAM_ID: Pubkey = Pubkey::new_from_array([2u8; 32]); + + // Test program id for the token program. + const TOKEN_PROGRAM_ID: Pubkey = Pubkey::new_from_array([1u8; 32]); fn do_process_instruction( instruction: Instruction, @@ -641,16 +589,20 @@ mod tests { if instruction.program_id == STAKE_POOL_PROGRAM_ID { Processor::process(&instruction.program_id, &account_infos, &instruction.data) } else { - SplProcessor::process(&instruction.program_id, &account_infos, &instruction.data) + spl_token::processor::Processor::process( + &instruction.program_id, + &account_infos, + &instruction.data, + ) } } - fn account_minimum_balance() -> u64 { - Rent::default().minimum_balance(SplAccount::get_packed_len()) + fn mint_minimum_balance() -> u64 { + Rent::default().minimum_balance(spl_token::state::Mint::get_packed_len()) } - fn mint_minimum_balance() -> u64 { - Rent::default().minimum_balance(SplMint::get_packed_len()) + fn account_minimum_balance() -> u64 { + Rent::default().minimum_balance(spl_token::state::Account::get_packed_len()) } fn mint_token( @@ -660,10 +612,10 @@ mod tests { authority_key: &Pubkey, amount: u64, ) -> (Pubkey, Account) { - let account_key = pubkey_rand(); + let account_key = Pubkey::new_unique(); let mut account_account = Account::new( account_minimum_balance(), - SplAccount::get_packed_len(), + spl_token::state::Account::get_packed_len(), &program_id, ); let mut authority_account = Account::default(); @@ -703,10 +655,10 @@ mod tests { } fn create_mint(program_id: &Pubkey, authority_key: &Pubkey) -> (Pubkey, Account) { - let mint_key = pubkey_rand(); + let mint_key = Pubkey::new_unique(); let mut mint_account = Account::new( mint_minimum_balance(), - SplMint::get_packed_len(), + spl_token::state::Mint::get_packed_len(), &program_id, ); let mut rent_sysvar_account = rent::create_account(1, &Rent::free()); @@ -723,11 +675,11 @@ mod tests { #[test] fn test_initialize() { - let stake_pool_key = pubkey_rand(); + let stake_pool_key = Pubkey::new_unique(); let mut stake_pool_account = Account::new(0, size_of::(), &STAKE_POOL_PROGRAM_ID); - let owner_key = pubkey_rand(); + let owner_key = Pubkey::new_unique(); let mut owner_account = Account::default(); - let authority_key = pubkey_rand(); + let authority_key = Pubkey::new_unique(); let (pool_mint_key, mut pool_mint_account) = create_mint(&TOKEN_PROGRAM_ID, &authority_key); let (pool_token_key, mut pool_token_account) = mint_token( From 6d4a0df0e02413b3b4be3d7e2c736c1bdc1569ac Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Sat, 24 Oct 2020 20:01:49 -0700 Subject: [PATCH 0009/1076] Groom Cargo.tomls --- program/Cargo.toml | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index a61de1fb..24d3a5ce 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -6,25 +6,20 @@ authors = ["Solana Maintainers "] repository = "https://github.com/solana-labs/solana-program-library" license = "Apache-2.0" edition = "2018" -exclude = ["js/**"] [features] exclude_entrypoint = [] [dependencies] +arrayref = "0.3.6" num-derive = "0.3" num-traits = "0.2" -remove_dir_all = "=0.5.0" -solana-program = "1.4.3" -spl-token = { path = "../../token/program", features = [ "exclude_entrypoint" ] } -thiserror = "1.0" -arrayref = "0.3.6" num_enum = "0.5.1" serde = "1.0.117" serde_derive = "1.0.103" - -[dev-dependencies] -rand = { version = "0.7.0"} +solana-program = "1.4.3" +spl-token = { path = "../../token/program", features = [ "exclude_entrypoint" ] } +thiserror = "1.0" [lib] crate-type = ["cdylib", "lib"] From 2f83495c7757d45f094f7ad8b81949295ab293d1 Mon Sep 17 00:00:00 2001 From: Yuriy Savchenko Date: Thu, 29 Oct 2020 18:19:48 +0200 Subject: [PATCH 0010/1076] Unit tests refactoring and success deposit test added to stake pool program (#718) * Interface accounts added as read-only, fixed mint authority on deposit, fixed stake pool stake deserializing * Unit test refactoring, added success tests for deposit, updated stake account program id * Warnings fixed * Removed random key generation, used Pubkey::new_unique instead * Imports optimization * Unit test architecture updated to remove separate invoke_signed declarations --- program/src/processor.rs | 344 +++++++++++++++++++++++++++++++++------ program/src/stake.rs | 2 +- 2 files changed, 293 insertions(+), 53 deletions(-) diff --git a/program/src/processor.rs b/program/src/processor.rs index cd908505..519d7470 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -273,6 +273,7 @@ impl Processor { stake_pool.withdraw_bump_seed, user_amount, )?; + let fee_amount = ::try_from(fee_amount).or(Err(Error::CalculationFailure))?; Self::token_mint_to( stake_pool_info.key, @@ -560,79 +561,198 @@ impl PrintProgramError for Error { #[cfg(test)] mod tests { use super::*; - use crate::instruction::{initialize, Fee, InitArgs}; - use core::mem::size_of; + use crate::instruction::{deposit, initialize, Fee, InitArgs}; use solana_program::{ account::Account, account_info::create_is_signer_account_infos, instruction::Instruction, - program_pack::Pack, rent::Rent, sysvar::rent, + native_token::sol_to_lamports, program_pack::Pack, program_stubs, rent::Rent, sysvar::rent, + }; + use spl_token::{ + instruction::{initialize_account, initialize_mint}, + processor::Processor as TokenProcessor, + state::{Account as SplAccount, Mint as SplMint}, }; - use spl_token::instruction::{initialize_account, initialize_mint}; - // Test program id for the stake-pool program. + /// Test program id for the stake-pool program. const STAKE_POOL_PROGRAM_ID: Pubkey = Pubkey::new_from_array([2u8; 32]); - // Test program id for the token program. + /// Test program id for the token program. const TOKEN_PROGRAM_ID: Pubkey = Pubkey::new_from_array([1u8; 32]); + /// Actual stake account program id, used for tests + fn stake_program_id() -> Pubkey { + "Stake11111111111111111111111111111111111111" + .parse::() + .unwrap() + } + + struct TestSyscallStubs {} + impl program_stubs::SyscallStubs for TestSyscallStubs { + fn sol_invoke_signed( + &self, + instruction: &Instruction, + account_infos: &[AccountInfo], + signers_seeds: &[&[&[u8]]], + ) -> ProgramResult { + info!("TestSyscallStubs::sol_invoke_signed()"); + + let mut new_account_infos = vec![]; + for meta in instruction.accounts.iter() { + for account_info in account_infos.iter() { + if meta.pubkey == *account_info.key { + let mut new_account_info = account_info.clone(); + for seeds in signers_seeds.iter() { + let signer = + Pubkey::create_program_address(seeds, &STAKE_POOL_PROGRAM_ID) + .unwrap(); + if *account_info.key == signer { + new_account_info.is_signer = true; + } + } + new_account_infos.push(new_account_info); + } + } + } + + match instruction.program_id { + TOKEN_PROGRAM_ID => invoke_token(&new_account_infos, &instruction.data), + pubkey => { + if pubkey == stake_program_id() { + invoke_stake(&new_account_infos, &instruction.data) + } else { + Err(ProgramError::IncorrectProgramId) + } + } + } + } + } + + /// Mocks token instruction invocation + pub fn invoke_token<'a>(account_infos: &[AccountInfo<'a>], input: &[u8]) -> ProgramResult { + spl_token::processor::Processor::process(&TOKEN_PROGRAM_ID, &account_infos, &input) + } + + /// Mocks stake account instruction invocation + pub fn invoke_stake<'a>(_account_infos: &[AccountInfo<'a>], _input: &[u8]) -> ProgramResult { + // For now always return ok + Ok(()) + } + + fn test_syscall_stubs() { + use std::sync::Once; + static ONCE: Once = Once::new(); + + ONCE.call_once(|| { + program_stubs::set_syscall_stubs(Box::new(TestSyscallStubs {})); + }); + } + + struct StakePoolInfo { + pub pool_key: Pubkey, + pub pool_account: Account, + pub deposit_bump_seed: u8, + pub withdraw_bump_seed: u8, + pub deposit_authority_key: Pubkey, + pub withdraw_authority_key: Pubkey, + pub fee: Fee, + pub owner_key: Pubkey, + pub owner_fee_key: Pubkey, + pub owner_fee_account: Account, + pub mint_key: Pubkey, + pub mint_account: Account, + } + fn do_process_instruction( instruction: Instruction, accounts: Vec<&mut Account>, ) -> ProgramResult { + test_syscall_stubs(); + + // approximate the logic in the actual runtime which runs the instruction + // and only updates accounts if the instruction is successful + let mut account_clones = accounts.iter().map(|x| (*x).clone()).collect::>(); let mut meta = instruction .accounts .iter() - .zip(accounts) + .zip(account_clones.iter_mut()) .map(|(account_meta, account)| (&account_meta.pubkey, account_meta.is_signer, account)) .collect::>(); - - let account_infos = create_is_signer_account_infos(&mut meta); - if instruction.program_id == STAKE_POOL_PROGRAM_ID { + let mut account_infos = create_is_signer_account_infos(&mut meta); + let res = if instruction.program_id == STAKE_POOL_PROGRAM_ID { Processor::process(&instruction.program_id, &account_infos, &instruction.data) } else { - spl_token::processor::Processor::process( - &instruction.program_id, - &account_infos, - &instruction.data, - ) + TokenProcessor::process(&instruction.program_id, &account_infos, &instruction.data) + }; + + if res.is_ok() { + let mut account_metas = instruction + .accounts + .iter() + .zip(accounts) + .map(|(account_meta, account)| (&account_meta.pubkey, account)) + .collect::>(); + for account_info in account_infos.iter_mut() { + for account_meta in account_metas.iter_mut() { + if account_info.key == account_meta.0 { + let account = &mut account_meta.1; + account.owner = *account_info.owner; + account.lamports = **account_info.lamports.borrow(); + account.data = account_info.data.borrow().to_vec(); + } + } + } } + res } - fn mint_minimum_balance() -> u64 { - Rent::default().minimum_balance(spl_token::state::Mint::get_packed_len()) + fn account_minimum_balance() -> u64 { + Rent::default().minimum_balance(SplAccount::get_packed_len()) } - fn account_minimum_balance() -> u64 { - Rent::default().minimum_balance(spl_token::state::Account::get_packed_len()) + fn mint_minimum_balance() -> u64 { + Rent::default().minimum_balance(SplMint::get_packed_len()) } - fn mint_token( + fn create_token_account( program_id: &Pubkey, mint_key: &Pubkey, - mut mint_account: &mut Account, - authority_key: &Pubkey, - amount: u64, + mint_account: &mut Account, ) -> (Pubkey, Account) { let account_key = Pubkey::new_unique(); let mut account_account = Account::new( account_minimum_balance(), - spl_token::state::Account::get_packed_len(), + SplAccount::get_packed_len(), &program_id, ); - let mut authority_account = Account::default(); let mut rent_sysvar_account = rent::create_account(1, &Rent::free()); + let owner_key = Pubkey::new_unique(); + let mut owner_account = Account::default(); // create account do_process_instruction( - initialize_account(&program_id, &account_key, &mint_key, authority_key).unwrap(), + initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(), vec![ &mut account_account, - &mut mint_account, - &mut authority_account, + mint_account, + &mut owner_account, &mut rent_sysvar_account, ], ) .unwrap(); + (account_key, account_account) + } + + fn _mint_token( + program_id: &Pubkey, + mint_key: &Pubkey, + mut mint_account: &mut Account, + authority_key: &Pubkey, + amount: u64, + ) -> (Pubkey, Account) { + let (account_key, mut account_account) = + create_token_account(program_id, mint_key, mint_account); + let mut authority_account = Account::default(); + do_process_instruction( spl_token::instruction::mint_to( &program_id, @@ -658,7 +778,7 @@ mod tests { let mint_key = Pubkey::new_unique(); let mut mint_account = Account::new( mint_minimum_balance(), - spl_token::state::Mint::get_packed_len(), + SplMint::get_packed_len(), &program_id, ); let mut rent_sysvar_account = rent::create_account(1, &Rent::free()); @@ -673,48 +793,168 @@ mod tests { (mint_key, mint_account) } - #[test] - fn test_initialize() { + fn create_stake_pool(fee: Fee) -> StakePoolInfo { let stake_pool_key = Pubkey::new_unique(); - let mut stake_pool_account = Account::new(0, size_of::(), &STAKE_POOL_PROGRAM_ID); let owner_key = Pubkey::new_unique(); + + let mut stake_pool_account = Account::new(0, State::LEN, &STAKE_POOL_PROGRAM_ID); let mut owner_account = Account::default(); - let authority_key = Pubkey::new_unique(); - let (pool_mint_key, mut pool_mint_account) = create_mint(&TOKEN_PROGRAM_ID, &authority_key); - let (pool_token_key, mut pool_token_account) = mint_token( - &TOKEN_PROGRAM_ID, - &pool_mint_key, - &mut pool_mint_account, - &authority_key, - 0, + // Calculate authority addresses + let (deposit_authority_key, deposit_bump_seed) = Pubkey::find_program_address( + &[&stake_pool_key.to_bytes()[..32], b"deposit"], + &STAKE_POOL_PROGRAM_ID, ); + let (withdraw_authority_key, withdraw_bump_seed) = Pubkey::find_program_address( + &[&stake_pool_key.to_bytes()[..32], b"withdraw"], + &STAKE_POOL_PROGRAM_ID, + ); + + let (mint_key, mut mint_account) = create_mint(&TOKEN_PROGRAM_ID, &withdraw_authority_key); + let (owner_fee_key, mut owner_fee_account) = + create_token_account(&TOKEN_PROGRAM_ID, &mint_key, &mut mint_account); // StakePool Init - do_process_instruction( + let _result = do_process_instruction( initialize( &STAKE_POOL_PROGRAM_ID, &stake_pool_key, &owner_key, - &pool_mint_key, - &pool_token_key, + &mint_key, + &owner_fee_key, &TOKEN_PROGRAM_ID, - InitArgs { - fee: Fee { - denominator: 10, - numerator: 2, - }, - }, + InitArgs { fee }, ) .unwrap(), vec![ &mut stake_pool_account, &mut owner_account, - &mut pool_mint_account, - &mut pool_token_account, + &mut mint_account, + &mut owner_fee_account, &mut Account::default(), ], ) - .unwrap(); + .expect("Error on stake pool initialize"); + + StakePoolInfo { + pool_key: stake_pool_key, + pool_account: stake_pool_account, + deposit_bump_seed, + withdraw_bump_seed, + deposit_authority_key, + withdraw_authority_key, + fee, + owner_key, + owner_fee_key, + owner_fee_account, + mint_key, + mint_account, + } + } + + #[test] + fn test_initialize() { + let fee = Fee { + denominator: 10, + numerator: 2, + }; + let pool_info = create_stake_pool(fee); + // Read account data + let state = State::deserialize(&pool_info.pool_account.data).unwrap(); + match state { + State::Unallocated => panic!("Stake pool state is not initialized after init"), + State::Init(stake_pool) => { + assert_eq!(stake_pool.deposit_bump_seed, pool_info.deposit_bump_seed); + assert_eq!(stake_pool.withdraw_bump_seed, pool_info.withdraw_bump_seed); + assert_eq!(stake_pool.fee.numerator, pool_info.fee.numerator); + assert_eq!(stake_pool.fee.denominator, pool_info.fee.denominator); + + assert_eq!(stake_pool.owner, pool_info.owner_key); + assert_eq!(stake_pool.pool_mint, pool_info.mint_key); + assert_eq!(stake_pool.owner_fee_account, pool_info.owner_fee_key); + assert_eq!(stake_pool.token_program_id, TOKEN_PROGRAM_ID); + + assert_eq!(stake_pool.stake_total, 0); + assert_eq!(stake_pool.pool_total, 0); + } + } + } + + #[test] + fn test_deposit() { + let fee = Fee { + denominator: 100, + numerator: 2, + }; + let stake_balance: u64 = sol_to_lamports(10.0); + let user_token_balance: u64 = sol_to_lamports(9.8); + let fee_token_balance: u64 = sol_to_lamports(0.2); + assert_eq!(stake_balance, user_token_balance + fee_token_balance); + + // Create stake account + let mut pool_info = create_stake_pool(fee); + + let stake_account_key = Pubkey::new_unique(); + let mut stake_account_account = Account::new(stake_balance, 100, &stake_program_id()); + // TODO: Set stake account Withdrawer authority to pool_info.deposit_authority_key + + // Create account to receive minted tokens + let (token_receiver_key, mut token_receiver_account) = create_token_account( + &TOKEN_PROGRAM_ID, + &pool_info.mint_key, + &mut pool_info.mint_account, + ); + + // Call deposit + let _result = do_process_instruction( + deposit( + &STAKE_POOL_PROGRAM_ID, + &pool_info.pool_key, + &pool_info.deposit_authority_key, + &pool_info.withdraw_authority_key, + &stake_account_key, + &token_receiver_key, + &pool_info.owner_fee_key, + &pool_info.mint_key, + &TOKEN_PROGRAM_ID, + ) + .unwrap(), + vec![ + &mut pool_info.pool_account, + &mut Account::default(), + &mut Account::default(), + &mut stake_account_account, + &mut token_receiver_account, + &mut pool_info.owner_fee_account, + &mut pool_info.mint_account, + &mut Account::default(), + ], + ) + .expect("Error on stake pool deposit"); + + // Test stake pool balance + let state = State::deserialize(&pool_info.pool_account.data).unwrap(); + match state { + State::Unallocated => panic!("Stake pool state is not initialized after deposit"), + State::Init(stake_pool) => { + assert_eq!(stake_pool.stake_total, stake_balance); + assert_eq!(stake_pool.pool_total, stake_balance); + } + } + + // Test token balances + let user_token_state = SplAccount::unpack_from_slice(&token_receiver_account.data) + .expect("User token account is not initialized after deposit"); + assert_eq!(user_token_state.amount, user_token_balance); + let fee_token_state = SplAccount::unpack_from_slice(&pool_info.owner_fee_account.data) + .expect("Fee token account is not initialized after deposit"); + assert_eq!(fee_token_state.amount, fee_token_balance); + + // Test mint total issued tokens + let mint_state = SplMint::unpack_from_slice(&pool_info.mint_account.data) + .expect("Mint account is not initialized after deposit"); + assert_eq!(mint_state.supply, stake_balance); + + // TODO: Test stake account Withdrawer authority } } diff --git a/program/src/stake.rs b/program/src/stake.rs index 7077291e..0a901f84 100644 --- a/program/src/stake.rs +++ b/program/src/stake.rs @@ -7,7 +7,7 @@ use solana_program::{ sysvar, }; -solana_program::declare_id!("StakeConfig11111111111111111111111111111111"); +solana_program::declare_id!("Stake11111111111111111111111111111111111111"); /// FIXME copied from solana stake program #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] From 63ff6c6c16f09b29a354137e5e227001c6586cc9 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Sat, 31 Oct 2020 21:45:09 -0700 Subject: [PATCH 0011/1076] Update to solana v1.4.4 --- clients/cli/Cargo.toml | 12 ++++++------ program/Cargo.toml | 5 ++++- program/src/processor.rs | 9 +++++---- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 8b330f4b..2cdb2b44 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,12 +11,12 @@ version = "2.0.1" [dependencies] clap = "2.33.3" serde_json = "1.0.57" -solana-account-decoder = "1.4.3" -solana-clap-utils = "1.4.3" -solana-cli-config = "1.4.3" -solana-client = "1.4.3" -solana-logger = "1.4.3" -solana-sdk = "1.4.3" +solana-account-decoder = "1.4.4" +solana-clap-utils = "1.4.4" +solana-cli-config = "1.4.4" +solana-client = "1.4.4" +solana-logger = "1.4.4" +solana-sdk = "1.4.4" spl-stake-pool = { version = "0.1.0", path="../program", features = [ "exclude_entrypoint" ] } [[bin]] diff --git a/program/Cargo.toml b/program/Cargo.toml index 24d3a5ce..9ac344f6 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,9 +17,12 @@ num-traits = "0.2" num_enum = "0.5.1" serde = "1.0.117" serde_derive = "1.0.103" -solana-program = "1.4.3" +solana-program = "1.4.4" spl-token = { path = "../../token/program", features = [ "exclude_entrypoint" ] } thiserror = "1.0" +[dev-dependencies] +solana-sdk = "1.4.4" + [lib] crate-type = ["cdylib", "lib"] diff --git a/program/src/processor.rs b/program/src/processor.rs index 519d7470..0839c1d6 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -563,9 +563,10 @@ mod tests { use super::*; use crate::instruction::{deposit, initialize, Fee, InitArgs}; use solana_program::{ - account::Account, account_info::create_is_signer_account_infos, instruction::Instruction, - native_token::sol_to_lamports, program_pack::Pack, program_stubs, rent::Rent, sysvar::rent, + instruction::Instruction, native_token::sol_to_lamports, program_pack::Pack, program_stubs, + rent::Rent, }; + use solana_sdk::account::{create_account, create_is_signer_account_infos, Account}; use spl_token::{ instruction::{initialize_account, initialize_mint}, processor::Processor as TokenProcessor, @@ -723,7 +724,7 @@ mod tests { SplAccount::get_packed_len(), &program_id, ); - let mut rent_sysvar_account = rent::create_account(1, &Rent::free()); + let mut rent_sysvar_account = create_account(&Rent::free(), 1); let owner_key = Pubkey::new_unique(); let mut owner_account = Account::default(); @@ -781,7 +782,7 @@ mod tests { SplMint::get_packed_len(), &program_id, ); - let mut rent_sysvar_account = rent::create_account(1, &Rent::free()); + let mut rent_sysvar_account = create_account(&Rent::free(), 1); // create token mint do_process_instruction( From a15a7d2621a403cf753b143fb2804ca60feb37ce Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Sun, 1 Nov 2020 00:22:04 -0700 Subject: [PATCH 0012/1076] Drop lifetimes --- program/src/entrypoint.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/program/src/entrypoint.rs b/program/src/entrypoint.rs index a7afa8c8..b4ee96c2 100644 --- a/program/src/entrypoint.rs +++ b/program/src/entrypoint.rs @@ -7,9 +7,9 @@ use solana_program::{ }; entrypoint!(process_instruction); -fn process_instruction<'a>( +fn process_instruction( program_id: &Pubkey, - accounts: &'a [AccountInfo<'a>], + accounts: &[AccountInfo], instruction_data: &[u8], ) -> ProgramResult { if let Err(error) = Processor::process(program_id, accounts, instruction_data) { From cc6c13d42c073ffd9e2618419d4fa8ab1bd219dc Mon Sep 17 00:00:00 2001 From: Yuriy Savchenko Date: Mon, 2 Nov 2020 23:03:54 +0200 Subject: [PATCH 0013/1076] Added missing accounts to the interface to call stake account program (#763) * Interface accounts added as read-only, fixed mint authority on deposit, fixed stake pool stake deserializing * Unit test refactoring, added success tests for deposit, updated stake account program id * Warnings fixed * Removed random key generation, used Pubkey::new_unique instead * Imports optimization * Unit test architecture updated to remove separate invoke_signed declarations * Added missing accounts (sysvar clock and stake account program id) to calls to stake account program * Fixed formatting * Fixed stake pool deposit unit test * Temporarily removed stake-pool cli from main workspace * Fixed warning in token program * Fixed warning in token program v3 * Fixed warnings in token swap program * Fixed warning in token cli * Sysvar and program id params reordered --- clients/cli/Cargo.toml | 1 + program/src/instruction.rs | 27 ++++++++++++++++--- program/src/processor.rs | 53 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 76 insertions(+), 5 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 2cdb2b44..19c73cd1 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -18,6 +18,7 @@ solana-client = "1.4.4" solana-logger = "1.4.4" solana-sdk = "1.4.4" spl-stake-pool = { version = "0.1.0", path="../program", features = [ "exclude_entrypoint" ] } +spl-token = { path="../../token/program" } [[bin]] name = "spl-stake-pool" diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 488534bf..3b365158 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -6,6 +6,7 @@ use solana_program::instruction::AccountMeta; use solana_program::instruction::Instruction; use solana_program::program_error::ProgramError; use solana_program::pubkey::Pubkey; +use solana_program::sysvar; use std::mem::size_of; /// Fee rate as a ratio @@ -50,7 +51,9 @@ pub enum StakePoolInstruction { /// 4. `[w]` User account to receive pool tokens /// 5. `[w]` Account to receive pool fee tokens /// 6. `[w]` Pool token mint account - /// 7. `[]` Pool token program id + /// 7. '[]' Sysvar clock account (reserved for future use) + /// 8. `[]` Pool token program id, + /// 9. `[]` Stake program id, Deposit, /// Withdraw the token from the pool at the current ratio. @@ -63,7 +66,9 @@ pub enum StakePoolInstruction { /// 4. `[]` User account to set as a new withdraw authority /// 5. `[w]` User account with pool tokens to burn from /// 6. `[w]` Pool token mint account - /// 7. `[]` Pool token program id + /// 7. '[]' Sysvar clock account (reserved for future use) + /// 8. `[]` Pool token program id + /// 9. `[]` Stake program id, /// userdata: amount to withdraw Withdraw(u64), @@ -76,7 +81,9 @@ pub enum StakePoolInstruction { /// 3. `[]` User account to set as a new withdraw authority /// 4. `[w]` User account with pool tokens to burn from /// 5. `[w]` Pool token mint account - /// 6. `[]` Pool token program id + /// 6. '[]' Sysvar clock account (reserved for future use) + /// 7. `[]` Pool token program id + /// 8. `[]` Stake program id, Claim, /// Update the staking pubkey for a stake @@ -86,6 +93,8 @@ pub enum StakePoolInstruction { /// 2. `[]` withdraw authority /// 3. `[w]` Stake to update the staking pubkey /// 4. '[]` Staking pubkey. + /// 5. '[]' Sysvar clock account (reserved for future use) + /// 6. `[]` Stake program id, SetStakingAuthority, /// Update owner @@ -202,6 +211,7 @@ pub fn deposit( pool_fee_to: &Pubkey, pool_mint: &Pubkey, token_program_id: &Pubkey, + stake_program_id: &Pubkey, ) -> Result { let args = StakePoolInstruction::Deposit; let data = args.serialize()?; @@ -213,7 +223,9 @@ pub fn deposit( AccountMeta::new(*pool_tokens_to, false), AccountMeta::new(*pool_fee_to, false), AccountMeta::new(*pool_mint, false), + AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(*token_program_id, false), + AccountMeta::new_readonly(*stake_program_id, false), ]; Ok(Instruction { program_id: *program_id, @@ -233,6 +245,7 @@ pub fn withdraw( burn_from: &Pubkey, pool_mint: &Pubkey, token_program_id: &Pubkey, + stake_program_id: &Pubkey, amount: u64, ) -> Result { let args = StakePoolInstruction::Withdraw(amount); @@ -245,7 +258,9 @@ pub fn withdraw( AccountMeta::new_readonly(*user_withdrawer, false), AccountMeta::new(*burn_from, true), AccountMeta::new(*pool_mint, false), + AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(*token_program_id, false), + AccountMeta::new_readonly(*stake_program_id, false), ]; Ok(Instruction { program_id: *program_id, @@ -264,6 +279,7 @@ pub fn claim( burn_from: &Pubkey, pool_mint: &Pubkey, token_program_id: &Pubkey, + stake_program_id: &Pubkey, amount: u64, ) -> Result { let args = StakePoolInstruction::Withdraw(amount); @@ -275,7 +291,9 @@ pub fn claim( AccountMeta::new_readonly(*user_withdrawer, false), AccountMeta::new(*burn_from, true), AccountMeta::new(*pool_mint, false), + AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(*token_program_id, false), + AccountMeta::new_readonly(*stake_program_id, false), ]; Ok(Instruction { program_id: *program_id, @@ -292,6 +310,7 @@ pub fn set_staking_authority( stake_pool_withdraw: &Pubkey, stake_account_to_update: &Pubkey, stake_account_new_authority: &Pubkey, + stake_program_id: &Pubkey, ) -> Result { let args = StakePoolInstruction::SetStakingAuthority; let data = args.serialize()?; @@ -301,6 +320,8 @@ pub fn set_staking_authority( AccountMeta::new_readonly(*stake_pool_withdraw, false), AccountMeta::new(*stake_account_to_update, false), AccountMeta::new_readonly(*stake_account_new_authority, false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(*stake_program_id, false), ]; Ok(Instruction { program_id: *program_id, diff --git a/program/src/processor.rs b/program/src/processor.rs index 0839c1d6..3a642af9 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -46,6 +46,7 @@ impl Processor { } /// Issue a stake_split instruction. + #[allow(clippy::too_many_arguments)] pub fn stake_split<'a>( stake_pool: &Pubkey, stake_account: AccountInfo<'a>, @@ -54,6 +55,8 @@ impl Processor { bump_seed: u8, amount: u64, split_stake: AccountInfo<'a>, + reserved: AccountInfo<'a>, + stake_program_info: AccountInfo<'a>, ) -> Result<(), ProgramError> { let me_bytes = stake_pool.to_bytes(); let authority_signature_seeds = [&me_bytes[..32], authority_type, &[bump_seed]]; @@ -61,10 +64,21 @@ impl Processor { let ix = stake::split_only(stake_account.key, authority.key, amount, split_stake.key); - invoke_signed(&ix, &[stake_account, authority, split_stake], signers) + invoke_signed( + &ix, + &[ + stake_account, + reserved, + authority, + split_stake, + stake_program_info, + ], + signers, + ) } /// Issue a stake_set_owner instruction. + #[allow(clippy::too_many_arguments)] pub fn stake_authorize<'a>( stake_pool: &Pubkey, stake_account: AccountInfo<'a>, @@ -73,6 +87,8 @@ impl Processor { bump_seed: u8, new_staker: &Pubkey, staker_auth: stake::StakeAuthorize, + reserved: AccountInfo<'a>, + stake_program_info: AccountInfo<'a>, ) -> Result<(), ProgramError> { let me_bytes = stake_pool.to_bytes(); let authority_signature_seeds = [&me_bytes[..32], authority_type, &[bump_seed]]; @@ -80,7 +96,11 @@ impl Processor { let ix = stake::authorize(stake_account.key, authority.key, new_staker, staker_auth); - invoke_signed(&ix, &[stake_account, authority], signers) + invoke_signed( + &ix, + &[stake_account, reserved, authority, stake_program_info], + signers, + ) } /// Issue a spl_token `Burn` instruction. @@ -205,8 +225,12 @@ impl Processor { let owner_fee_info = next_account_info(account_info_iter)?; // Pool token mint account let pool_mint_info = next_account_info(account_info_iter)?; + // (Reserved) + let reserved = next_account_info(account_info_iter)?; // Pool token program id let token_program_info = next_account_info(account_info_iter)?; + // Stake program id + let stake_program_info = next_account_info(account_info_iter)?; let mut stake_pool = State::deserialize(&stake_pool_info.data.borrow())?.stake_pool()?; @@ -260,6 +284,8 @@ impl Processor { stake_pool.deposit_bump_seed, withdraw_info.key, stake::StakeAuthorize::Withdrawer, + reserved.clone(), + stake_program_info.clone(), )?; let user_amount = ::try_from(user_amount).or(Err(Error::CalculationFailure))?; @@ -313,8 +339,12 @@ impl Processor { let burn_from_info = next_account_info(account_info_iter)?; // Pool token mint account let pool_mint_info = next_account_info(account_info_iter)?; + // (Reserved) + let reserved = next_account_info(account_info_iter)?; // Pool token program id let token_program_info = next_account_info(account_info_iter)?; + // Stake program id + let stake_program_info = next_account_info(account_info_iter)?; let mut stake_pool = State::deserialize(&stake_pool_info.data.borrow())?.stake_pool()?; @@ -345,6 +375,8 @@ impl Processor { stake_pool.withdraw_bump_seed, stake_amount, stake_split_to.clone(), + reserved.clone(), + stake_program_info.clone(), )?; Self::stake_authorize( @@ -355,6 +387,8 @@ impl Processor { stake_pool.withdraw_bump_seed, user_stake_authority.key, stake::StakeAuthorize::Withdrawer, + reserved.clone(), + stake_program_info.clone(), )?; Self::token_burn( @@ -388,8 +422,12 @@ impl Processor { let burn_from_info = next_account_info(account_info_iter)?; // Pool token account let pool_mint_info = next_account_info(account_info_iter)?; + // (Reserved) + let reserved = next_account_info(account_info_iter)?; // Pool token program id let token_program_info = next_account_info(account_info_iter)?; + // Stake program id + let stake_program_info = next_account_info(account_info_iter)?; let mut stake_pool = State::deserialize(&stake_pool_info.data.borrow())?.stake_pool()?; @@ -421,6 +459,8 @@ impl Processor { stake_pool.withdraw_bump_seed, user_stake_authority.key, stake::StakeAuthorize::Withdrawer, + reserved.clone(), + stake_program_info.clone(), )?; Self::token_burn( @@ -450,6 +490,10 @@ impl Processor { let withdraw_info = next_account_info(account_info_iter)?; let stake_info = next_account_info(account_info_iter)?; let staker_info = next_account_info(account_info_iter)?; + // (Reserved) + let reserved = next_account_info(account_info_iter)?; + // Stake program id + let stake_program_info = next_account_info(account_info_iter)?; let stake_pool = State::deserialize(&stake_pool_info.data.borrow())?.stake_pool()?; @@ -479,6 +523,8 @@ impl Processor { stake_pool.withdraw_bump_seed, staker_info.key, stake::StakeAuthorize::Staker, + reserved.clone(), + stake_program_info.clone(), )?; Ok(()) } @@ -918,6 +964,7 @@ mod tests { &pool_info.owner_fee_key, &pool_info.mint_key, &TOKEN_PROGRAM_ID, + &stake_program_id(), ) .unwrap(), vec![ @@ -929,6 +976,8 @@ mod tests { &mut pool_info.owner_fee_account, &mut pool_info.mint_account, &mut Account::default(), + &mut Account::default(), + &mut Account::default(), ], ) .expect("Error on stake pool deposit"); From 8e4b0a608fbba4718d85c1de10663aad560d6c15 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Tue, 3 Nov 2020 09:33:32 -0800 Subject: [PATCH 0014/1076] Back to no-entrypoint feature name --- clients/cli/Cargo.toml | 4 ++-- program/Cargo.toml | 4 ++-- program/src/lib.rs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 19c73cd1..d1bc00ee 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -17,8 +17,8 @@ solana-cli-config = "1.4.4" solana-client = "1.4.4" solana-logger = "1.4.4" solana-sdk = "1.4.4" -spl-stake-pool = { version = "0.1.0", path="../program", features = [ "exclude_entrypoint" ] } -spl-token = { path="../../token/program" } +spl-stake-pool = { path="../program", features = [ "no-entrypoint" ] } +spl-token = { path="../../token/program", features = [ "no-entrypoint" ] } [[bin]] name = "spl-stake-pool" diff --git a/program/Cargo.toml b/program/Cargo.toml index 9ac344f6..846360a5 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -8,7 +8,7 @@ license = "Apache-2.0" edition = "2018" [features] -exclude_entrypoint = [] +no-entrypoint = [] [dependencies] arrayref = "0.3.6" @@ -18,7 +18,7 @@ num_enum = "0.5.1" serde = "1.0.117" serde_derive = "1.0.103" solana-program = "1.4.4" -spl-token = { path = "../../token/program", features = [ "exclude_entrypoint" ] } +spl-token = { path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" [dev-dependencies] diff --git a/program/src/lib.rs b/program/src/lib.rs index 10dda2c6..ac91d963 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -8,7 +8,7 @@ pub mod processor; pub mod stake; pub mod state; -#[cfg(not(feature = "exclude_entrypoint"))] +#[cfg(not(feature = "no-entrypoint"))] pub mod entrypoint; // Export current sdk types for downstream users building with a different sdk version From 26a8b2a7fdfdaaec7ee55fe2443a01de512f112e Mon Sep 17 00:00:00 2001 From: Yuriy Savchenko Date: Wed, 4 Nov 2020 14:34:25 +0200 Subject: [PATCH 0015/1076] Added positive tests in stake pool and fixed several bugs in instructions (#788) * Added positive tests for withdraw, claim, set owner, set authority, several bugs fixed * Fixed PR comments * Fixed constant with leading zero * Deposit tests refactoring --- program/src/instruction.rs | 5 +- program/src/processor.rs | 401 +++++++++++++++++++++++++++++++------ 2 files changed, 337 insertions(+), 69 deletions(-) diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 3b365158..da8f5f98 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -280,9 +280,8 @@ pub fn claim( pool_mint: &Pubkey, token_program_id: &Pubkey, stake_program_id: &Pubkey, - amount: u64, ) -> Result { - let args = StakePoolInstruction::Withdraw(amount); + let args = StakePoolInstruction::Claim; let data = args.serialize()?; let accounts = vec![ AccountMeta::new(*stake_pool, false), @@ -338,7 +337,7 @@ pub fn set_owner( stake_pool_new_owner: &Pubkey, stake_pool_new_fee_receiver: &Pubkey, ) -> Result { - let args = StakePoolInstruction::SetStakingAuthority; + let args = StakePoolInstruction::SetOwner; let data = args.serialize()?; let accounts = vec![ AccountMeta::new(*stake_pool, false), diff --git a/program/src/processor.rs b/program/src/processor.rs index 3a642af9..32ebf353 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -607,7 +607,7 @@ impl PrintProgramError for Error { #[cfg(test)] mod tests { use super::*; - use crate::instruction::{deposit, initialize, Fee, InitArgs}; + use crate::instruction::*; use solana_program::{ instruction::Instruction, native_token::sol_to_lamports, program_pack::Pack, program_stubs, rent::Rent, @@ -632,6 +632,8 @@ mod tests { .unwrap() } + const STAKE_ACCOUNT_LEN: usize = 100; + struct TestSyscallStubs {} impl program_stubs::SyscallStubs for TestSyscallStubs { fn sol_invoke_signed( @@ -702,12 +704,18 @@ mod tests { pub withdraw_authority_key: Pubkey, pub fee: Fee, pub owner_key: Pubkey, + pub owner_account: Account, pub owner_fee_key: Pubkey, pub owner_fee_account: Account, pub mint_key: Pubkey, pub mint_account: Account, } + struct DepositInfo { + stake_account_key: Pubkey, + stake_account_account: Account, + } + fn do_process_instruction( instruction: Instruction, accounts: Vec<&mut Account>, @@ -759,26 +767,34 @@ mod tests { Rent::default().minimum_balance(SplMint::get_packed_len()) } + struct TokenInfo { + key: Pubkey, + account: Account, + owner: Pubkey, + } + fn create_token_account( program_id: &Pubkey, mint_key: &Pubkey, mint_account: &mut Account, - ) -> (Pubkey, Account) { - let account_key = Pubkey::new_unique(); - let mut account_account = Account::new( - account_minimum_balance(), - SplAccount::get_packed_len(), - &program_id, - ); + ) -> TokenInfo { + let mut token = TokenInfo { + key: Pubkey::new_unique(), + account: Account::new( + account_minimum_balance(), + SplAccount::get_packed_len(), + &program_id, + ), + owner: Pubkey::new_unique(), + }; let mut rent_sysvar_account = create_account(&Rent::free(), 1); - let owner_key = Pubkey::new_unique(); let mut owner_account = Account::default(); // create account do_process_instruction( - initialize_account(&program_id, &account_key, &mint_key, &owner_key).unwrap(), + initialize_account(&program_id, &token.key, &mint_key, &token.owner).unwrap(), vec![ - &mut account_account, + &mut token.account, mint_account, &mut owner_account, &mut rent_sysvar_account, @@ -786,7 +802,7 @@ mod tests { ) .unwrap(); - (account_key, account_account) + token } fn _mint_token( @@ -796,15 +812,14 @@ mod tests { authority_key: &Pubkey, amount: u64, ) -> (Pubkey, Account) { - let (account_key, mut account_account) = - create_token_account(program_id, mint_key, mint_account); + let mut token_account = create_token_account(program_id, mint_key, mint_account); let mut authority_account = Account::default(); do_process_instruction( spl_token::instruction::mint_to( &program_id, &mint_key, - &account_key, + &token_account.key, &authority_key, &[], amount, @@ -812,13 +827,13 @@ mod tests { .unwrap(), vec![ &mut mint_account, - &mut account_account, + &mut token_account.account, &mut authority_account, ], ) .unwrap(); - (account_key, account_account) + (token_account.key, token_account.account) } fn create_mint(program_id: &Pubkey, authority_key: &Pubkey) -> (Pubkey, Account) { @@ -840,6 +855,42 @@ mod tests { (mint_key, mint_account) } + fn approve_token( + program_id: &Pubkey, + token_account_pubkey: &Pubkey, + mut token_account_account: &mut Account, + delegate_pubkey: &Pubkey, + owner_pubkey: &Pubkey, + amount: u64, + ) { + do_process_instruction( + spl_token::instruction::approve( + &program_id, + token_account_pubkey, + delegate_pubkey, + owner_pubkey, + &[], + amount, + ) + .unwrap(), + vec![ + &mut token_account_account, + &mut Account::default(), + &mut Account::default(), + ], + ) + .unwrap(); + } + + const FEE_DEFAULT: Fee = Fee { + denominator: 100, + numerator: 5, + }; + + fn create_stake_pool_default() -> StakePoolInfo { + create_stake_pool(FEE_DEFAULT) + } + fn create_stake_pool(fee: Fee) -> StakePoolInfo { let stake_pool_key = Pubkey::new_unique(); let owner_key = Pubkey::new_unique(); @@ -858,8 +909,7 @@ mod tests { ); let (mint_key, mut mint_account) = create_mint(&TOKEN_PROGRAM_ID, &withdraw_authority_key); - let (owner_fee_key, mut owner_fee_account) = - create_token_account(&TOKEN_PROGRAM_ID, &mint_key, &mut mint_account); + let mut token = create_token_account(&TOKEN_PROGRAM_ID, &mint_key, &mut mint_account); // StakePool Init let _result = do_process_instruction( @@ -868,7 +918,7 @@ mod tests { &stake_pool_key, &owner_key, &mint_key, - &owner_fee_key, + &token.key, &TOKEN_PROGRAM_ID, InitArgs { fee }, ) @@ -877,7 +927,7 @@ mod tests { &mut stake_pool_account, &mut owner_account, &mut mint_account, - &mut owner_fee_account, + &mut token.account, &mut Account::default(), ], ) @@ -892,20 +942,63 @@ mod tests { withdraw_authority_key, fee, owner_key, - owner_fee_key, - owner_fee_account, + owner_account, + owner_fee_key: token.key, + owner_fee_account: token.account, mint_key, mint_account, } } + fn do_deposit( + pool_info: &mut StakePoolInfo, + stake_balance: u64, + token: &mut TokenInfo, + ) -> DepositInfo { + let stake_account_key = Pubkey::new_unique(); + let mut stake_account_account = + Account::new(stake_balance, STAKE_ACCOUNT_LEN, &stake_program_id()); + // TODO: Set stake account Withdrawer authority to pool_info.deposit_authority_key + + // Call deposit + let _result = do_process_instruction( + deposit( + &STAKE_POOL_PROGRAM_ID, + &pool_info.pool_key, + &pool_info.deposit_authority_key, + &pool_info.withdraw_authority_key, + &stake_account_key, + &token.key, + &pool_info.owner_fee_key, + &pool_info.mint_key, + &TOKEN_PROGRAM_ID, + &stake_program_id(), + ) + .unwrap(), + vec![ + &mut pool_info.pool_account, + &mut Account::default(), + &mut Account::default(), + &mut stake_account_account, + &mut token.account, + &mut pool_info.owner_fee_account, + &mut pool_info.mint_account, + &mut Account::default(), + &mut Account::default(), + &mut Account::default(), + ], + ) + .expect("Error on stake pool deposit"); + + DepositInfo { + stake_account_key, + stake_account_account, + } + } + #[test] fn test_initialize() { - let fee = Fee { - denominator: 10, - numerator: 2, - }; - let pool_info = create_stake_pool(fee); + let pool_info = create_stake_pool_default(); // Read account data let state = State::deserialize(&pool_info.pool_account.data).unwrap(); match state { @@ -934,77 +1027,253 @@ mod tests { numerator: 2, }; let stake_balance: u64 = sol_to_lamports(10.0); - let user_token_balance: u64 = sol_to_lamports(9.8); - let fee_token_balance: u64 = sol_to_lamports(0.2); - assert_eq!(stake_balance, user_token_balance + fee_token_balance); + let tokens_to_issue: u64 = 10_000_000_000; + let user_token_balance: u64 = 9_800_000_000; + let fee_token_balance: u64 = 200_000_000; + assert_eq!(tokens_to_issue, user_token_balance + fee_token_balance); // Create stake account let mut pool_info = create_stake_pool(fee); - let stake_account_key = Pubkey::new_unique(); - let mut stake_account_account = Account::new(stake_balance, 100, &stake_program_id()); - // TODO: Set stake account Withdrawer authority to pool_info.deposit_authority_key + let mut pool_token_receiver = create_token_account( + &TOKEN_PROGRAM_ID, + &pool_info.mint_key, + &mut pool_info.mint_account, + ); + let _deposit_info = do_deposit(&mut pool_info, stake_balance, &mut pool_token_receiver); - // Create account to receive minted tokens - let (token_receiver_key, mut token_receiver_account) = create_token_account( + // Test stake pool balance + let state = State::deserialize(&pool_info.pool_account.data).unwrap(); + assert!( + matches!(state, State::Init(stake_pool) if stake_pool.stake_total == stake_balance && stake_pool.pool_total == tokens_to_issue) + ); + + // Test token balances + let user_token_state = SplAccount::unpack_from_slice(&pool_token_receiver.account.data) + .expect("User token account is not initialized after deposit"); + assert_eq!(user_token_state.amount, user_token_balance); + let fee_token_state = SplAccount::unpack_from_slice(&pool_info.owner_fee_account.data) + .expect("Fee token account is not initialized after deposit"); + assert_eq!(fee_token_state.amount, fee_token_balance); + + // Test mint total issued tokens + let mint_state = SplMint::unpack_from_slice(&pool_info.mint_account.data) + .expect("Mint account is not initialized after deposit"); + assert_eq!(mint_state.supply, stake_balance); + + // TODO: Check stake account Withdrawer to match stake pool withdraw authority + } + #[test] + fn test_withdraw() { + let mut pool_info = create_stake_pool_default(); + + let user_withdrawer_key = Pubkey::new_unique(); + + let stake_balance = sol_to_lamports(20.0); + let tokens_to_issue: u64 = 20_000_000_000; + + let mut pool_token_receiver = create_token_account( &TOKEN_PROGRAM_ID, &pool_info.mint_key, &mut pool_info.mint_account, ); + let mut deposit_info = do_deposit(&mut pool_info, stake_balance, &mut pool_token_receiver); + + let withdraw_amount = sol_to_lamports(5.0); + let tokens_to_burn: u64 = 5_000_000_000; + + approve_token( + &TOKEN_PROGRAM_ID, + &pool_token_receiver.key, + &mut pool_token_receiver.account, + &pool_info.withdraw_authority_key, + &pool_token_receiver.owner, + tokens_to_burn, + ); + + let stake_to_receive_key = Pubkey::new_unique(); + let mut stake_to_receive_account = + Account::new(stake_balance, STAKE_ACCOUNT_LEN, &stake_program_id()); - // Call deposit let _result = do_process_instruction( - deposit( + withdraw( &STAKE_POOL_PROGRAM_ID, &pool_info.pool_key, - &pool_info.deposit_authority_key, &pool_info.withdraw_authority_key, - &stake_account_key, - &token_receiver_key, - &pool_info.owner_fee_key, + &deposit_info.stake_account_key, + &stake_to_receive_key, + &user_withdrawer_key, + &pool_token_receiver.key, &pool_info.mint_key, &TOKEN_PROGRAM_ID, &stake_program_id(), + withdraw_amount, ) .unwrap(), vec![ &mut pool_info.pool_account, &mut Account::default(), + &mut deposit_info.stake_account_account, + &mut stake_to_receive_account, &mut Account::default(), - &mut stake_account_account, - &mut token_receiver_account, - &mut pool_info.owner_fee_account, + &mut pool_token_receiver.account, &mut pool_info.mint_account, &mut Account::default(), &mut Account::default(), &mut Account::default(), ], ) - .expect("Error on stake pool deposit"); + .expect("Error on withdraw"); - // Test stake pool balance + let fee_amount = stake_balance * pool_info.fee.numerator / pool_info.fee.denominator; + + let user_token_state = SplAccount::unpack_from_slice(&pool_token_receiver.account.data) + .expect("User token account is not initialized after withdraw"); + assert_eq!( + user_token_state.amount, + stake_balance - fee_amount - withdraw_amount + ); + + // Check stake pool token amounts let state = State::deserialize(&pool_info.pool_account.data).unwrap(); - match state { - State::Unallocated => panic!("Stake pool state is not initialized after deposit"), - State::Init(stake_pool) => { - assert_eq!(stake_pool.stake_total, stake_balance); - assert_eq!(stake_pool.pool_total, stake_balance); - } - } + assert!( + matches!(state, State::Init(stake_pool) if stake_pool.stake_total == stake_balance - withdraw_amount && stake_pool.pool_total == tokens_to_issue - tokens_to_burn) + ); + } + #[test] + fn test_claim() { + let mut pool_info = create_stake_pool_default(); - // Test token balances - let user_token_state = SplAccount::unpack_from_slice(&token_receiver_account.data) - .expect("User token account is not initialized after deposit"); - assert_eq!(user_token_state.amount, user_token_balance); - let fee_token_state = SplAccount::unpack_from_slice(&pool_info.owner_fee_account.data) - .expect("Fee token account is not initialized after deposit"); - assert_eq!(fee_token_state.amount, fee_token_balance); + let user_withdrawer_key = Pubkey::new_unique(); - // Test mint total issued tokens - let mint_state = SplMint::unpack_from_slice(&pool_info.mint_account.data) - .expect("Mint account is not initialized after deposit"); - assert_eq!(mint_state.supply, stake_balance); + let stake_balance = sol_to_lamports(20.0); + + let mut pool_token_receiver = create_token_account( + &TOKEN_PROGRAM_ID, + &pool_info.mint_key, + &mut pool_info.mint_account, + ); + let mut deposit_info = do_deposit(&mut pool_info, stake_balance, &mut pool_token_receiver); - // TODO: Test stake account Withdrawer authority + // Need to deposit more to cover deposit fee + let fee_amount = stake_balance * pool_info.fee.numerator / pool_info.fee.denominator; + let extra_deposit = (fee_amount * pool_info.fee.denominator) + / (pool_info.fee.denominator - pool_info.fee.numerator); + + let _extra_deposit_info = + do_deposit(&mut pool_info, extra_deposit, &mut pool_token_receiver); + + approve_token( + &TOKEN_PROGRAM_ID, + &pool_token_receiver.key, + &mut pool_token_receiver.account, + &pool_info.withdraw_authority_key, + &pool_token_receiver.owner, + stake_balance, + ); + + let _result = do_process_instruction( + claim( + &STAKE_POOL_PROGRAM_ID, + &pool_info.pool_key, + &pool_info.withdraw_authority_key, + &deposit_info.stake_account_key, + &user_withdrawer_key, + &pool_token_receiver.key, + &pool_info.mint_key, + &TOKEN_PROGRAM_ID, + &stake_program_id(), + ) + .unwrap(), + vec![ + &mut pool_info.pool_account, + &mut Account::default(), + &mut deposit_info.stake_account_account, + &mut Account::default(), + &mut pool_token_receiver.account, + &mut pool_info.mint_account, + &mut Account::default(), + &mut Account::default(), + &mut Account::default(), + ], + ) + .expect("Error on claim"); + + let user_token_state = SplAccount::unpack_from_slice(&pool_token_receiver.account.data) + .expect("User token account is not initialized after withdraw"); + assert_eq!(user_token_state.amount, 0); + + // TODO: Check deposit_info.stake_account_account Withdrawer to change to user_withdrawer_key + } + #[test] + fn test_set_staking_authority() { + let mut pool_info = create_stake_pool_default(); + let stake_balance: u64 = sol_to_lamports(10.0); + + let stake_key = Pubkey::new_unique(); + let mut stake_account = Account::new(stake_balance, STAKE_ACCOUNT_LEN, &stake_program_id()); + let new_authorithy_key = Pubkey::new_unique(); + let mut new_authorithy_account = + Account::new(stake_balance, STAKE_ACCOUNT_LEN, &stake_program_id()); + + let _result = do_process_instruction( + set_staking_authority( + &STAKE_POOL_PROGRAM_ID, + &pool_info.pool_key, + &pool_info.owner_key, + &pool_info.withdraw_authority_key, + &stake_key, + &new_authorithy_key, + &stake_program_id(), + ) + .unwrap(), + vec![ + &mut pool_info.pool_account, + &mut pool_info.owner_fee_account, + &mut Account::default(), + &mut stake_account, + &mut new_authorithy_account, + &mut Account::default(), + &mut Account::default(), + ], + ) + .expect("Error on set_owner"); + } + + #[test] + fn test_set_owner() { + let mut pool_info = create_stake_pool_default(); + + let new_owner_key = Pubkey::new_unique(); + let mut new_owner_account = Account::default(); + + let mut new_owner_fee = create_token_account( + &TOKEN_PROGRAM_ID, + &pool_info.mint_key, + &mut pool_info.mint_account, + ); + + let _result = do_process_instruction( + set_owner( + &STAKE_POOL_PROGRAM_ID, + &pool_info.pool_key, + &pool_info.owner_key, + &new_owner_key, + &new_owner_fee.key, + ) + .unwrap(), + vec![ + &mut pool_info.pool_account, + &mut pool_info.owner_account, + &mut new_owner_account, + &mut new_owner_fee.account, + ], + ) + .expect("Error on set_owner"); + + let state = State::deserialize(&pool_info.pool_account.data).unwrap(); + assert!( + matches!(state, State::Init(stake_pool) if stake_pool.owner == new_owner_key && stake_pool.owner_fee_account == new_owner_fee.key) + ); } } From 0fcc7929fd8bff1efc433e58b0873b3e1d674f02 Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Fri, 6 Nov 2020 09:15:27 +0800 Subject: [PATCH 0016/1076] Fix broken stake-pool docs link and make readme's consistent (#805) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2ec24679..b3d5a412 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,6 @@ Each SoM needs at least one pool. Users deposit stakes into the SoM pool and receives a pool token minus the fee. The SoM redistributes the stakes across the network and tries to maximize censorship resistance and rewards. -Full documentation is available at https://spl.solana.com +Full documentation is available at https://spl.solana.com/stake-pool Javascript bindings are available in the `./js` directory. From 31776e41a86e59f5753e1260302b1c7a18432793 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Fri, 6 Nov 2020 09:18:20 -0800 Subject: [PATCH 0017/1076] Bump solana version to v1.4.5 --- clients/cli/Cargo.toml | 12 ++++++------ program/Cargo.toml | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index d1bc00ee..8d8d9d14 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,12 +11,12 @@ version = "2.0.1" [dependencies] clap = "2.33.3" serde_json = "1.0.57" -solana-account-decoder = "1.4.4" -solana-clap-utils = "1.4.4" -solana-cli-config = "1.4.4" -solana-client = "1.4.4" -solana-logger = "1.4.4" -solana-sdk = "1.4.4" +solana-account-decoder = "1.4.5" +solana-clap-utils = "1.4.5" +solana-cli-config = "1.4.5" +solana-client = "1.4.5" +solana-logger = "1.4.5" +solana-sdk = "1.4.5" spl-stake-pool = { path="../program", features = [ "no-entrypoint" ] } spl-token = { path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/program/Cargo.toml b/program/Cargo.toml index 846360a5..356e3cbb 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,12 +17,12 @@ num-traits = "0.2" num_enum = "0.5.1" serde = "1.0.117" serde_derive = "1.0.103" -solana-program = "1.4.4" +solana-program = "1.4.5" spl-token = { path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" [dev-dependencies] -solana-sdk = "1.4.4" +solana-sdk = "1.4.5" [lib] crate-type = ["cdylib", "lib"] From d7935617de59bc5eb65868739230beb057602d86 Mon Sep 17 00:00:00 2001 From: Yuriy Savchenko Date: Tue, 10 Nov 2020 16:36:05 +0200 Subject: [PATCH 0018/1076] Stake pool CLI added (#806) * Implemented stake-pool CLI with create-pool, deposit, list and withdraw commands, fixed several bugs in underlying smart contract * Several typos fixed, some error text clarifications. * Fee parameter in stake pool creation changed into two: numarator and demoninator * Refactoring to resolve pool request comments * Added merge to stake_receiver account when claiming whole stake account * Removed unused import * Withdraw bump seed calculation fixed --- clients/cli/Cargo.toml | 2 + clients/cli/src/main.rs | 1090 ++++++++++++++++++------------------ program/src/instruction.rs | 4 +- program/src/lib.rs | 2 +- program/src/processor.rs | 40 +- program/src/stake.rs | 17 + 6 files changed, 596 insertions(+), 559 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 8d8d9d14..e5d730fa 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -17,8 +17,10 @@ solana-cli-config = "1.4.5" solana-client = "1.4.5" solana-logger = "1.4.5" solana-sdk = "1.4.5" +solana-program = "1.4.5" spl-stake-pool = { path="../program", features = [ "no-entrypoint" ] } spl-token = { path="../../token/program", features = [ "no-entrypoint" ] } +bs58 = "0.3.1" [[bin]] name = "spl-stake-pool" diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index dccfbdd9..67003aa7 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -2,27 +2,44 @@ use clap::{ crate_description, crate_name, crate_version, value_t, value_t_or_exit, App, AppSettings, Arg, SubCommand, }; -use solana_account_decoder::{parse_token::TokenAccountType, UiAccountData}; +use solana_account_decoder::UiAccountEncoding; use solana_clap_utils::{ input_parsers::pubkey_of, - input_validators::{is_amount, is_keypair, is_pubkey_or_keypair, is_url}, + input_validators::{is_amount, is_keypair, is_parsable, is_pubkey, is_url}, keypair::signer_from_path, }; -use solana_client::{rpc_client::RpcClient, rpc_request::TokenAccountsFilter}; +use solana_client::{ + rpc_client::RpcClient, + rpc_config::RpcAccountInfoConfig, + rpc_config::RpcProgramAccountsConfig, + rpc_filter::{Memcmp, MemcmpEncodedBytes, RpcFilterType}, +}; +use solana_program::{instruction::Instruction, program_pack::Pack, pubkey::Pubkey}; use solana_sdk::{ + account::Account, commitment_config::CommitmentConfig, native_token::*, - pubkey::Pubkey, signature::{Keypair, Signer}, system_instruction, transaction::Transaction, }; +use spl_stake_pool::{ + instruction::{ + claim, deposit, initialize as initialize_pool, withdraw, Fee as PoolFee, + InitArgs as PoolInitArgs, + }, + processor::Processor as PoolProcessor, + stake::authorize as authorize_stake, + stake::id as stake_program_id, + stake::merge as merge_stake, + stake::StakeAuthorize, + state::StakePool, + state::State as PoolState, +}; use spl_token::{ - self, - instruction::*, - native_mint, - pack::Pack, - state::{Account, Mint}, + self, instruction::approve as approve_token, instruction::initialize_account, + instruction::initialize_mint, native_mint, state::Account as TokenAccount, + state::Mint as TokenMint, }; use std::process::exit; @@ -37,6 +54,8 @@ struct Config { type Error = Box; type CommandResult = Result, Error>; +const STAKE_STATE_LEN: usize = 200; + macro_rules! unique_signers { ($vec:ident) => { $vec.sort_by_key(|l| l.pubkey()); @@ -59,7 +78,29 @@ fn check_fee_payer_balance(config: &Config, required_balance: u64) -> Result<(), } } -fn check_owner_balance(config: &Config, required_balance: u64) -> Result<(), Error> { +fn get_authority_accounts(config: &Config, authority: &Pubkey) -> Vec<(Pubkey, Account)> { + config + .rpc_client + .get_program_accounts_with_config( + &stake_program_id(), + RpcProgramAccountsConfig { + filters: Some(vec![RpcFilterType::Memcmp(Memcmp { + offset: 44, // 44 is Withdrawer authority offset in stake accoun stake + bytes: MemcmpEncodedBytes::Binary( + bs58::encode(authority.to_bytes()).into_string(), + ), + encoding: None, + })]), + account_config: RpcAccountInfoConfig { + encoding: Some(UiAccountEncoding::Base64), + ..RpcAccountInfoConfig::default() + }, + }, + ) + .unwrap() +} + +fn _check_owner_balance(config: &Config, required_balance: u64) -> Result<(), Error> { let balance = config.rpc_client.get_balance(&config.owner.pubkey())?; if balance < required_balance { Err(format!( @@ -74,68 +115,95 @@ fn check_owner_balance(config: &Config, required_balance: u64) -> Result<(), Err } } -fn command_create_token(config: &Config, decimals: u8) -> CommandResult { - let token = Keypair::new(); - println!("Creating token {}", token.pubkey()); +fn command_create_pool(config: &Config, fee: PoolFee) -> CommandResult { + let mint_account = Keypair::new(); + println!("Creating mint {}", mint_account.pubkey()); - let minimum_balance_for_rent_exemption = config + let pool_fee_account = Keypair::new(); + println!( + "Creating pool fee collection account {}", + pool_fee_account.pubkey() + ); + + let pool_account = Keypair::new(); + println!("Creating stake pool {}", pool_account.pubkey()); + + let mint_account_balance = config + .rpc_client + .get_minimum_balance_for_rent_exemption(TokenMint::LEN)?; + let pool_fee_account_balance = config .rpc_client - .get_minimum_balance_for_rent_exemption(Mint::LEN)?; + .get_minimum_balance_for_rent_exemption(TokenAccount::LEN)?; + let pool_account_balance = config + .rpc_client + .get_minimum_balance_for_rent_exemption(PoolState::LEN)?; + let total_rent_free_balances = + mint_account_balance + pool_fee_account_balance + pool_account_balance; + + let default_decimals = native_mint::DECIMALS; + + // Calculate withdraw authority used for minting pool tokens + let (withdraw_authority, _) = PoolProcessor::find_authority_bump_seed( + &spl_stake_pool::id(), + &pool_account.pubkey(), + PoolProcessor::AUTHORITY_WITHDRAW, + ); + + if config.verbose { + println!("Stake pool withdraw authority {}", withdraw_authority); + } let mut transaction = Transaction::new_with_payer( &[ + // Account for the stake pool mint system_instruction::create_account( &config.fee_payer.pubkey(), - &token.pubkey(), - minimum_balance_for_rent_exemption, - Mint::LEN as u64, + &mint_account.pubkey(), + mint_account_balance, + TokenMint::LEN as u64, &spl_token::id(), ), - initialize_mint( - &spl_token::id(), - &token.pubkey(), - &config.owner.pubkey(), - None, - decimals, - )?, - ], - Some(&config.fee_payer.pubkey()), - ); - - let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_fee_payer_balance( - config, - minimum_balance_for_rent_exemption + fee_calculator.calculate_fee(&transaction.message()), - )?; - let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref(), &token]; - unique_signers!(signers); - transaction.sign(&signers, recent_blockhash); - Ok(Some(transaction)) -} - -fn command_create_account(config: &Config, token: Pubkey) -> CommandResult { - let account = Keypair::new(); - println!("Creating account {}", account.pubkey()); - - let minimum_balance_for_rent_exemption = config - .rpc_client - .get_minimum_balance_for_rent_exemption(Account::LEN)?; - - let mut transaction = Transaction::new_with_payer( - &[ + // Account for the pool fee accumulation system_instruction::create_account( &config.fee_payer.pubkey(), - &account.pubkey(), - minimum_balance_for_rent_exemption, - Account::LEN as u64, + &pool_fee_account.pubkey(), + pool_fee_account_balance, + TokenAccount::LEN as u64, &spl_token::id(), ), + // Account for the stake pool + system_instruction::create_account( + &config.fee_payer.pubkey(), + &pool_account.pubkey(), + pool_account_balance, + PoolState::LEN as u64, + &spl_stake_pool::id(), + ), + // Initialize pool token mint account + initialize_mint( + &spl_token::id(), + &mint_account.pubkey(), + &withdraw_authority, + None, + default_decimals, + )?, + // Initialize fee receiver account initialize_account( &spl_token::id(), - &account.pubkey(), - &token, + &pool_fee_account.pubkey(), + &mint_account.pubkey(), &config.owner.pubkey(), )?, + // Initialize stake pool account + initialize_pool( + &spl_stake_pool::id(), + &pool_account.pubkey(), + &config.owner.pubkey(), + &mint_account.pubkey(), + &pool_fee_account.pubkey(), + &spl_token::id(), + PoolInitArgs { fee }, + )?, ], Some(&config.fee_payer.pubkey()), ); @@ -143,299 +211,358 @@ fn command_create_account(config: &Config, token: Pubkey) -> CommandResult { let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; check_fee_payer_balance( config, - minimum_balance_for_rent_exemption + fee_calculator.calculate_fee(&transaction.message()), + total_rent_free_balances + fee_calculator.calculate_fee(&transaction.message()), )?; - let mut signers = vec![config.fee_payer.as_ref(), &account, config.owner.as_ref()]; + let mut signers = vec![ + config.fee_payer.as_ref(), + &pool_account, + &mint_account, + &pool_fee_account, + ]; unique_signers!(signers); transaction.sign(&signers, recent_blockhash); Ok(Some(transaction)) } -fn command_assign(config: &Config, account: Pubkey, new_owner: Pubkey) -> CommandResult { - println!( - "Assigning {}\n Current owner: {}\n New owner: {}", - account, - config.owner.pubkey(), - new_owner - ); - - let mut transaction = Transaction::new_with_payer( - &[set_authority( - &spl_token::id(), - &account, - Some(&new_owner), - AuthorityType::AccountOwner, - &config.owner.pubkey(), - &[], - )?], - Some(&config.fee_payer.pubkey()), - ); - - let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; - let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()]; - unique_signers!(signers); - transaction.sign(&signers, recent_blockhash); - Ok(Some(transaction)) -} - -fn command_transfer( +fn command_deposit( config: &Config, - sender: Pubkey, - ui_amount: f64, - recipient: Pubkey, + pool: &Pubkey, + stake: &Pubkey, + token_receiver: &Option, ) -> CommandResult { - println!( - "Transfer {} tokens\n Sender: {}\n Recipient: {}", - ui_amount, sender, recipient - ); - - let sender_token_balance = config - .rpc_client - .get_token_account_balance_with_commitment(&sender, config.commitment_config)? - .value; - let source_account = config - .rpc_client - .get_account_with_commitment(&sender, config.commitment_config)? - .value - .unwrap_or_default(); - let data = source_account.data.to_vec(); - let mint_pubkey = Account::unpack_from_slice(&data)?.mint; - let amount = spl_token::ui_amount_to_amount(ui_amount, sender_token_balance.decimals); - - let mut transaction = Transaction::new_with_payer( - &[transfer2( - &spl_token::id(), - &sender, - &mint_pubkey, - &recipient, - &config.owner.pubkey(), - &[], - amount, - sender_token_balance.decimals, - )?], - Some(&config.fee_payer.pubkey()), - ); - - let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; + // Get stake pool state + let pool_data = config.rpc_client.get_account_data(&pool)?; + let pool_data: StakePool = PoolState::deserialize(pool_data.as_slice()) + .unwrap() + .stake_pool() + .unwrap(); + + let mut instructions: Vec = vec![]; let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()]; - unique_signers!(signers); - transaction.sign(&signers, recent_blockhash); - Ok(Some(transaction)) -} -fn command_burn(config: &Config, source: Pubkey, ui_amount: f64) -> CommandResult { - println!("Burn {} tokens\n Source: {}", ui_amount, source); + let mut total_rent_free_balances: u64 = 0; - let source_token_balance = config - .rpc_client - .get_token_account_balance_with_commitment(&source, config.commitment_config)? - .value; - let source_account = config - .rpc_client - .get_account_with_commitment(&source, config.commitment_config)? - .value - .unwrap_or_default(); - let data = source_account.data.to_vec(); - let mint_pubkey = Account::unpack_from_slice(&data)?.mint; - let amount = spl_token::ui_amount_to_amount(ui_amount, source_token_balance.decimals); - let mut transaction = Transaction::new_with_payer( - &[burn2( - &spl_token::id(), - &source, - &mint_pubkey, - &config.owner.pubkey(), - &[], - amount, - source_token_balance.decimals, - )?], - Some(&config.fee_payer.pubkey()), - ); + let token_receiver_account = Keypair::new(); - let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; - let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()]; - unique_signers!(signers); - transaction.sign(&signers, recent_blockhash); - Ok(Some(transaction)) -} + let token_receiver: Pubkey = match token_receiver { + Some(value) => *value, + None => { + // Account for tokens not specified, creating one + println!( + "Creating account to receive tokens {}", + token_receiver_account.pubkey() + ); -fn command_mint( - config: &Config, - token: Pubkey, - ui_amount: f64, - recipient: Pubkey, -) -> CommandResult { - println!( - "Minting {} tokens\n Token: {}\n Recipient: {}", - ui_amount, token, recipient - ); + let token_receiver_account_balance = config + .rpc_client + .get_minimum_balance_for_rent_exemption(TokenAccount::LEN)?; + + instructions.extend(vec![ + // Creating new account + system_instruction::create_account( + &config.fee_payer.pubkey(), + &token_receiver_account.pubkey(), + token_receiver_account_balance, + TokenAccount::LEN as u64, + &spl_token::id(), + ), + // Initialize token receiver account + initialize_account( + &spl_token::id(), + &token_receiver_account.pubkey(), + &pool_data.pool_mint, + &config.owner.pubkey(), + )?, + ]); - let recipient_token_balance = config - .rpc_client - .get_token_account_balance_with_commitment(&recipient, config.commitment_config)? - .value; - let amount = spl_token::ui_amount_to_amount(ui_amount, recipient_token_balance.decimals); + signers.push(&token_receiver_account); - let mut transaction = Transaction::new_with_payer( - &[mint_to2( - &spl_token::id(), - &token, - &recipient, - &config.owner.pubkey(), - &[], - amount, - recipient_token_balance.decimals, - )?], - Some(&config.fee_payer.pubkey()), - ); + total_rent_free_balances += token_receiver_account_balance; - let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; - let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()]; - unique_signers!(signers); - transaction.sign(&signers, recent_blockhash); - Ok(Some(transaction)) -} + token_receiver_account.pubkey() + } + }; -fn command_wrap(config: &Config, sol: f64) -> CommandResult { - let account = Keypair::new(); - let lamports = sol_to_lamports(sol); - println!("Wrapping {} SOL into {}", sol, account.pubkey()); + // Calculate Deposit and Withdraw stake pool authorities + let pool_deposit_authority: Pubkey = PoolProcessor::authority_id( + &spl_stake_pool::id(), + pool, + PoolProcessor::AUTHORITY_DEPOSIT, + pool_data.deposit_bump_seed, + ) + .unwrap(); + let pool_withdraw_authority: Pubkey = PoolProcessor::authority_id( + &spl_stake_pool::id(), + pool, + PoolProcessor::AUTHORITY_WITHDRAW, + pool_data.withdraw_bump_seed, + ) + .unwrap(); + + instructions.extend(vec![ + // Set Withdrawer on stake account to Deposit authority of the stake pool + authorize_stake( + &stake, + &config.owner.pubkey(), + &pool_deposit_authority, + StakeAuthorize::Withdrawer, + ), + // Set Staker on stake account to Deposit authority of the stake pool + authorize_stake( + &stake, + &config.owner.pubkey(), + &pool_deposit_authority, + StakeAuthorize::Staker, + ), + // Add stake account to the pool + deposit( + &spl_stake_pool::id(), + &pool, + &pool_deposit_authority, + &pool_withdraw_authority, + &stake, + &token_receiver, + &pool_data.owner_fee_account, + &pool_data.pool_mint, + &spl_token::id(), + &stake_program_id(), + )?, + ]); - let mut transaction = Transaction::new_with_payer( - &[ - system_instruction::create_account( - &config.owner.pubkey(), - &account.pubkey(), - lamports, - Account::LEN as u64, - &spl_token::id(), - ), - initialize_account( - &spl_token::id(), - &account.pubkey(), - &native_mint::id(), - &config.owner.pubkey(), - )?, - ], - Some(&config.fee_payer.pubkey()), - ); + let mut transaction = + Transaction::new_with_payer(&instructions, Some(&config.fee_payer.pubkey())); let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_owner_balance(config, lamports)?; - check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; - let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref(), &account]; + check_fee_payer_balance( + config, + total_rent_free_balances + fee_calculator.calculate_fee(&transaction.message()), + )?; unique_signers!(signers); transaction.sign(&signers, recent_blockhash); Ok(Some(transaction)) } -fn command_unwrap(config: &Config, address: Pubkey) -> CommandResult { - println!("Unwrapping {}", address); - println!( - " Amount: {} SOL\n Recipient: {}", - lamports_to_sol( - config - .rpc_client - .get_balance_with_commitment(&address, config.commitment_config)? - .value - ), - config.owner.pubkey() - ); +fn command_list(config: &Config, pool: &Pubkey) -> CommandResult { + // Get stake pool state + let pool_data = config.rpc_client.get_account_data(&pool)?; + let pool_data: StakePool = PoolState::deserialize(pool_data.as_slice()) + .unwrap() + .stake_pool() + .unwrap(); - let mut transaction = Transaction::new_with_payer( - &[close_account( - &spl_token::id(), - &address, - &config.owner.pubkey(), - &config.owner.pubkey(), - &[], - )?], - Some(&config.fee_payer.pubkey()), - ); + let pool_withdraw_authority: Pubkey = PoolProcessor::authority_id( + &spl_stake_pool::id(), + pool, + PoolProcessor::AUTHORITY_WITHDRAW, + pool_data.withdraw_bump_seed, + ) + .unwrap(); - let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; - let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()]; - unique_signers!(signers); - transaction.sign(&signers, recent_blockhash); - Ok(Some(transaction)) -} + let accounts = get_authority_accounts(config, &pool_withdraw_authority); -fn command_balance(config: &Config, address: Pubkey) -> CommandResult { - let balance = config - .rpc_client - .get_token_account_balance_with_commitment(&address, config.commitment_config)? - .value; - - if config.verbose { - println!("ui amount: {}", balance.ui_amount); - println!("decimals: {}", balance.decimals); - println!("amount: {}", balance.amount); + if accounts.is_empty() { + println!("No accounts found.") } else { - println!("{}", balance.ui_amount); + let mut total_balance: u64 = 0; + for (pubkey, account) in accounts { + let balance = account.lamports; + total_balance += balance; + println!("{}\t{} SOL", pubkey, lamports_to_sol(balance)); + } + println!("Total: {} SOL", lamports_to_sol(total_balance)); } + Ok(None) } -fn command_supply(config: &Config, address: Pubkey) -> CommandResult { - let supply = config - .rpc_client - .get_token_supply_with_commitment(&address, config.commitment_config)? - .value; +fn stake_amount_to_pool_tokens(pool_data: &StakePool, amount: u64) -> u64 { + (amount as u128) + .checked_mul(pool_data.pool_total as u128) + .unwrap() + .checked_div(pool_data.stake_total as u128) + .unwrap() as u64 +} - println!("{}", supply.ui_amount); - Ok(None) +fn pool_tokens_to_stake_amount(pool_data: &StakePool, tokens: u64) -> u64 { + (tokens as u128) + .checked_mul(pool_data.stake_total as u128) + .unwrap() + .checked_div(pool_data.pool_total as u128) + .unwrap() as u64 } -fn command_accounts(config: &Config, token: Option) -> CommandResult { - let accounts = config - .rpc_client - .get_token_accounts_by_owner_with_commitment( - &config.owner.pubkey(), - match token { - Some(token) => TokenAccountsFilter::Mint(token), - None => TokenAccountsFilter::ProgramId(spl_token::id()), - }, - config.commitment_config, - )? - .value; +fn command_withdraw( + config: &Config, + pool: &Pubkey, + amount: u64, + burn_from: &Pubkey, + stake_receiver: &Option, +) -> CommandResult { + // Get stake pool state + let pool_data = config.rpc_client.get_account_data(&pool)?; + let pool_data: StakePool = PoolState::deserialize(pool_data.as_slice()) + .unwrap() + .stake_pool() + .unwrap(); + + let pool_withdraw_authority: Pubkey = PoolProcessor::authority_id( + &spl_stake_pool::id(), + pool, + PoolProcessor::AUTHORITY_WITHDRAW, + pool_data.withdraw_bump_seed, + ) + .unwrap(); + + // Check burn_from account type + let account_data = config.rpc_client.get_account_data(&burn_from)?; + let account_data: TokenAccount = + TokenAccount::unpack_from_slice(account_data.as_slice()).unwrap(); + + if account_data.mint != pool_data.pool_mint { + println!("Wrong token account."); + return Ok(None); + } + + // Check burn_from balance + let max_withdraw_amount = pool_tokens_to_stake_amount(&pool_data, account_data.amount); + if max_withdraw_amount < amount { + println!( + "Not enough token balance to withdraw {} SOL.\nMaximum withdraw amount is {} SOL.", + lamports_to_sol(amount), + lamports_to_sol(max_withdraw_amount) + ); + return Ok(None); + } + + let mut accounts = get_authority_accounts(config, &pool_withdraw_authority); if accounts.is_empty() { - println!("None"); + println!("No accounts found."); + return Ok(None); } + // Sort from lowest to highest balance + accounts.sort_by(|a, b| a.1.lamports.cmp(&b.1.lamports)); - println!("Account Token Balance"); - println!("-------------------------------------------------------------------------------------------------"); - for keyed_account in accounts { - let address = keyed_account.pubkey; - - if let UiAccountData::Json(parsed_account) = keyed_account.account.data { - if parsed_account.program != "spl-token" { - println!( - "{:<44} Unsupported account program: {}", - address, parsed_account.program - ); - } else { - match serde_json::from_value(parsed_account.parsed) { - Ok(TokenAccountType::Account(ui_token_account)) => println!( - "{:<44} {:<44} {}", - address, ui_token_account.mint, ui_token_account.token_amount.ui_amount - ), - Ok(_) => println!("{:<44} Unsupported token account", address), - Err(err) => println!("{:<44} Account parse failure: {}", address, err), - } + for (stake_pubkey, account) in accounts { + if account.lamports < amount { + continue; + } + // Account found to claim or withdraw + println!("Withdrawing from account {}", stake_pubkey); + + let mut instructions: Vec = vec![]; + let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()]; + + let stake_receiver_account = Keypair::new(); + + let mut total_rent_free_balances: u64 = 0; + + // Calculate amount of tokens to burn + let tokens_to_burn = stake_amount_to_pool_tokens(&pool_data, amount); + + instructions.push( + // Approve spending token + approve_token( + &spl_token::id(), + &burn_from, + &pool_withdraw_authority, + &config.owner.pubkey(), + &[], + tokens_to_burn, + )?, + ); + + if amount == account.lamports { + // Claim to get whole account + instructions.push(claim( + &spl_stake_pool::id(), + &pool, + &pool_withdraw_authority, + &stake_pubkey, + &config.owner.pubkey(), + &burn_from, + &pool_data.pool_mint, + &spl_token::id(), + &stake_program_id(), + )?); + // Merge into stake_receiver (if present) + if let Some(merge_into) = stake_receiver { + instructions.push(merge_stake( + &merge_into, + &stake_pubkey, + &config.owner.pubkey(), + )); } } else { - println!("{:<44} Unsupported account data format", address); + // Withdraw to split account + let stake_receiver: Pubkey = match stake_receiver { + Some(value) => *value, + None => { + // Account for tokens not specified, creating one + println!( + "Creating account to receive stake {}", + stake_receiver_account.pubkey() + ); + + let stake_receiver_account_balance = config + .rpc_client + .get_minimum_balance_for_rent_exemption(STAKE_STATE_LEN)?; + + instructions.push( + // Creating new account + system_instruction::create_account( + &config.fee_payer.pubkey(), + &stake_receiver_account.pubkey(), + stake_receiver_account_balance, + STAKE_STATE_LEN as u64, + &stake_program_id(), + ), + ); + + signers.push(&stake_receiver_account); + + total_rent_free_balances += stake_receiver_account_balance; + + stake_receiver_account.pubkey() + } + }; + + instructions.push(withdraw( + &spl_stake_pool::id(), + &pool, + &pool_withdraw_authority, + &stake_pubkey, + &stake_receiver, + &config.owner.pubkey(), + &burn_from, + &pool_data.pool_mint, + &spl_token::id(), + &stake_program_id(), + amount, + )?); } + + let mut transaction = + Transaction::new_with_payer(&instructions, Some(&config.fee_payer.pubkey())); + + let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + check_fee_payer_balance( + config, + total_rent_free_balances + fee_calculator.calculate_fee(&transaction.message()), + )?; + unique_signers!(signers); + transaction.sign(&signers, recent_blockhash); + + return Ok(Some(transaction)); } + + println!( + "No stake accounts found in this pool with enough balance to withdraw {} SOL.", + lamports_to_sol(amount) + ); Ok(None) } fn main() { - let default_decimals = &format!("{}", native_mint::DECIMALS); let matches = App::new(crate_name!()) .about(crate_description!()) .version(crate_version!()) @@ -477,7 +604,7 @@ fn main() { .validator(is_keypair) .takes_value(true) .help( - "Specify the token owner account. \ + "Specify the stake pool or stake account owner. \ This may be a keypair file, the ASK keyword. \ Defaults to the client keypair.", ), @@ -494,205 +621,107 @@ fn main() { Defaults to the client keypair.", ), ) - .subcommand(SubCommand::with_name("create-token").about("Create a new token") - .arg( - Arg::with_name("decimals") - .long("decimals") - .validator(|s| { - s.parse::().map_err(|e| format!("{}", e))?; - Ok(()) - }) - .value_name("DECIMALS") - .takes_value(true) - .default_value(&default_decimals) - .help("Number of base 10 digits to the right of the decimal place"), - ) - ) - .subcommand( - SubCommand::with_name("create-account") - .about("Create a new token account") - .arg( - Arg::with_name("token") - .validator(is_pubkey_or_keypair) - .value_name("TOKEN_ADDRESS") - .takes_value(true) - .index(1) - .required(true) - .help("The token that the account will hold"), - ), - ) - .subcommand( - SubCommand::with_name("assign") - .about("Assign a token or token account to a new owner") - .arg( - Arg::with_name("address") - .validator(is_pubkey_or_keypair) - .value_name("TOKEN_ADDRESS") - .takes_value(true) - .index(1) - .required(true) - .help("The address of the token account"), - ) - .arg( - Arg::with_name("new_owner") - .validator(is_pubkey_or_keypair) - .value_name("OWNER_ADDRESS") - .takes_value(true) - .index(2) - .required(true) - .help("The address of the new owner"), - ), - ) - .subcommand( - SubCommand::with_name("transfer") - .about("Transfer tokens between accounts") - .arg( - Arg::with_name("sender") - .validator(is_pubkey_or_keypair) - .value_name("SENDER_TOKEN_ACCOUNT_ADDRESS") - .takes_value(true) - .index(1) - .required(true) - .help("The token account address of the sender"), - ) - .arg( - Arg::with_name("amount") - .validator(is_amount) - .value_name("TOKEN_AMOUNT") - .takes_value(true) - .index(2) - .required(true) - .help("Amount to send, in tokens"), - ) - .arg( - Arg::with_name("recipient") - .validator(is_pubkey_or_keypair) - .value_name("RECIPIENT_TOKEN_ACCOUNT_ADDRESS") - .takes_value(true) - .index(3) - .required(true) - .help("The token account address of recipient"), - ), + .subcommand(SubCommand::with_name("create-pool").about("Create a new stake pool") + .arg( + Arg::with_name("fee_numerator") + .long("fee-numerator") + .short("n") + .validator(is_parsable::) + .value_name("NUMERATOR") + .takes_value(true) + .required(true) + .help("Fee numerator, fee amount is numerator divided by denominator."), + ) + .arg( + Arg::with_name("fee_denominator") + .long("fee-denominator") + .short("d") + .validator(is_parsable::) + .value_name("DENOMINATOR") + .takes_value(true) + .required(true) + .help("Fee denominator, fee amount is numerator divided by denominator."), + ) ) - .subcommand( - SubCommand::with_name("burn") - .about("Burn tokens from an account") - .arg( - Arg::with_name("source") - .validator(is_pubkey_or_keypair) - .value_name("SOURCE_TOKEN_ACCOUNT_ADDRESS") - .takes_value(true) - .index(1) - .required(true) - .help("The token account address to burn from"), - ) - .arg( - Arg::with_name("amount") - .validator(is_amount) - .value_name("TOKEN_AMOUNT") - .takes_value(true) - .index(2) - .required(true) - .help("Amount to burn, in tokens"), - ), + .subcommand(SubCommand::with_name("deposit").about("Add stake account to the stake pool") + .arg( + Arg::with_name("pool") + .long("pool") + .validator(is_pubkey) + .value_name("ADDRESS") + .takes_value(true) + .required(true) + .help("Stake pool address"), + ) + .arg( + Arg::with_name("stake") + .long("stake") + .validator(is_pubkey) + .value_name("ADDRESS") + .takes_value(true) + .required(true) + .help("Stake address to join the pool"), + ) + .arg( + Arg::with_name("token_receiver") + .long("token-receiver") + .validator(is_pubkey) + .value_name("ADDRESS") + .takes_value(true) + .help("Account to receive pool token. Must be initialized account of the stake pool token. Defaults to the new pool token account."), + ) ) - .subcommand( - SubCommand::with_name("mint") - .about("Mint new tokens") - .arg( - Arg::with_name("token") - .validator(is_pubkey_or_keypair) - .value_name("TOKEN_ADDRESS") - .takes_value(true) - .index(1) - .required(true) - .help("The token to mint"), - ) - .arg( - Arg::with_name("amount") - .validator(is_amount) - .value_name("TOKEN_AMOUNT") - .takes_value(true) - .index(2) - .required(true) - .help("Amount to mint, in tokens"), - ) - .arg( - Arg::with_name("recipient") - .validator(is_pubkey_or_keypair) - .value_name("RECIPIENT_TOKEN_ACCOUNT_ADDRESS") - .takes_value(true) - .index(3) - .required(true) - .help("The token account address of recipient"), - ), + .subcommand(SubCommand::with_name("list").about("List stake accounts managed by this pool") + .arg( + Arg::with_name("pool") + .long("pool") + .validator(is_pubkey) + .value_name("ADDRESS") + .takes_value(true) + .required(true) + .help("Stake pool address."), + ) ) - .subcommand( - SubCommand::with_name("balance") - .about("Get token account balance") - .arg( - Arg::with_name("address") - .validator(is_pubkey_or_keypair) - .value_name("TOKEN_ACCOUNT_ADDRESS") - .takes_value(true) - .index(1) - .required(true) - .help("The token account address"), - ), - ) - .subcommand( - SubCommand::with_name("supply") - .about("Get token supply") - .arg( - Arg::with_name("address") - .validator(is_pubkey_or_keypair) - .value_name("TOKEN_ADDRESS") - .takes_value(true) - .index(1) - .required(true) - .help("The token address"), - ), - ) - .subcommand( - SubCommand::with_name("accounts") - .about("List all token accounts by owner") - .arg( - Arg::with_name("token") - .validator(is_pubkey_or_keypair) - .value_name("TOKEN_ADDRESS") - .takes_value(true) - .index(1) - .help("Limit results to the given token. [Default: list accounts for all tokens]"), - ), - ) - .subcommand( - SubCommand::with_name("wrap") - .about("Wrap native SOL in a SOL token account") - .arg( - Arg::with_name("amount") - .validator(is_amount) - .value_name("AMOUNT") - .takes_value(true) - .index(1) - .required(true) - .help("Amount of SOL to wrap"), - ), - ) - .subcommand( - SubCommand::with_name("unwrap") - .about("Unwrap a SOL token account") - .arg( - Arg::with_name("address") - .validator(is_pubkey_or_keypair) - .value_name("TOKEN_ACCOUNT_ADDRESS") - .takes_value(true) - .index(1) - .required(true) - .help("The address of the token account to unwrap"), - ), + .subcommand(SubCommand::with_name("withdraw").about("Withdraw amount from the stake pool") + .arg( + Arg::with_name("pool") + .long("pool") + .validator(is_pubkey) + .value_name("ADDRESS") + .takes_value(true) + .required(true) + .help("Stake pool address."), + ) + .arg( + Arg::with_name("amount") + .long("amount") + .validator(is_amount) + .value_name("AMOUNT") + .takes_value(true) + .required(true) + .help("Amount in SOL to withdraw from the pool."), + ) + .arg( + Arg::with_name("burn_from") + .long("burn-from") + .validator(is_pubkey) + .value_name("ADDRESS") + .takes_value(true) + .required(true) + .help("Account to burn tokens from. Must be owned by the client."), + ) + .arg( + Arg::with_name("stake_receiver") + .long("stake-receiver") + .validator(is_pubkey) + .value_name("ADDRESS") + .takes_value(true) + .help("Stake account to receive SOL from the stake pool. Defaults to a new stake account."), + ) ) .get_matches(); + let mut wallet_manager = None; let config = { let cli_config = if let Some(config_file) = matches.value_of("config_file") { solana_cli_config::Config::load(config_file).unwrap_or_default() @@ -702,7 +731,6 @@ fn main() { let json_rpc_url = value_t!(matches, "json_rpc_url", String) .unwrap_or_else(|_| cli_config.json_rpc_url.clone()); - let mut wallet_manager = None; let owner = signer_from_path( &matches, &cli_config.keypair_path, @@ -737,55 +765,33 @@ fn main() { solana_logger::setup_with_default("solana=info"); let _ = match matches.subcommand() { - ("create-token", Some(arg_matches)) => { - let decimals = value_t_or_exit!(arg_matches, "decimals", u8); - command_create_token(&config, decimals) - } - ("create-account", Some(arg_matches)) => { - let token = pubkey_of(arg_matches, "token").unwrap(); - command_create_account(&config, token) - } - ("assign", Some(arg_matches)) => { - let address = pubkey_of(arg_matches, "address").unwrap(); - let new_owner = pubkey_of(arg_matches, "new_owner").unwrap(); - command_assign(&config, address, new_owner) - } - ("transfer", Some(arg_matches)) => { - let sender = pubkey_of(arg_matches, "sender").unwrap(); - let amount = value_t_or_exit!(arg_matches, "amount", f64); - let recipient = pubkey_of(arg_matches, "recipient").unwrap(); - command_transfer(&config, sender, amount, recipient) - } - ("burn", Some(arg_matches)) => { - let source = pubkey_of(arg_matches, "source").unwrap(); - let amount = value_t_or_exit!(arg_matches, "amount", f64); - command_burn(&config, source, amount) - } - ("mint", Some(arg_matches)) => { - let token = pubkey_of(arg_matches, "token").unwrap(); - let amount = value_t_or_exit!(arg_matches, "amount", f64); - let recipient = pubkey_of(arg_matches, "recipient").unwrap(); - command_mint(&config, token, amount, recipient) - } - ("wrap", Some(arg_matches)) => { - let amount = value_t_or_exit!(arg_matches, "amount", f64); - command_wrap(&config, amount) - } - ("unwrap", Some(arg_matches)) => { - let address = pubkey_of(arg_matches, "address").unwrap(); - command_unwrap(&config, address) + ("create-pool", Some(arg_matches)) => { + let numerator = value_t_or_exit!(arg_matches, "fee_numerator", u64); + let denominator = value_t_or_exit!(arg_matches, "fee_denominator", u64); + command_create_pool( + &config, + PoolFee { + numerator, + denominator, + }, + ) } - ("balance", Some(arg_matches)) => { - let address = pubkey_of(arg_matches, "address").unwrap(); - command_balance(&config, address) + ("deposit", Some(arg_matches)) => { + let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); + let stake_account: Pubkey = pubkey_of(arg_matches, "stake").unwrap(); + let token_receiver: Option = pubkey_of(arg_matches, "token_receiver"); + command_deposit(&config, &pool_account, &stake_account, &token_receiver) } - ("supply", Some(arg_matches)) => { - let address = pubkey_of(arg_matches, "address").unwrap(); - command_supply(&config, address) + ("list", Some(arg_matches)) => { + let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); + command_list(&config, &pool_account) } - ("accounts", Some(arg_matches)) => { - let token = pubkey_of(arg_matches, "token"); - command_accounts(&config, token) + ("withdraw", Some(arg_matches)) => { + let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); + let burn_from: Pubkey = pubkey_of(arg_matches, "burn_from").unwrap(); + let amount: u64 = sol_to_lamports(value_t_or_exit!(arg_matches, "amount", f64)); + let stake_receiver: Option = pubkey_of(arg_matches, "stake_receiver"); + command_withdraw(&config, &pool_account, amount, &burn_from, &stake_receiver) } _ => unreachable!(), } diff --git a/program/src/instruction.rs b/program/src/instruction.rs index da8f5f98..591a7225 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -256,7 +256,7 @@ pub fn withdraw( AccountMeta::new(*stake_to_split, false), AccountMeta::new(*stake_to_receive, false), AccountMeta::new_readonly(*user_withdrawer, false), - AccountMeta::new(*burn_from, true), + AccountMeta::new(*burn_from, false), AccountMeta::new(*pool_mint, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(*token_program_id, false), @@ -288,7 +288,7 @@ pub fn claim( AccountMeta::new_readonly(*stake_pool_withdraw, false), AccountMeta::new(*stake_to_claim, false), AccountMeta::new_readonly(*user_withdrawer, false), - AccountMeta::new(*burn_from, true), + AccountMeta::new(*burn_from, false), AccountMeta::new(*pool_mint, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(*token_program_id, false), diff --git a/program/src/lib.rs b/program/src/lib.rs index ac91d963..b1233b96 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -14,4 +14,4 @@ pub mod entrypoint; // Export current sdk types for downstream users building with a different sdk version pub use solana_program; -solana_program::declare_id!("STAKEPQQL1111111111111111111111111111111111"); +solana_program::declare_id!("AYyuDZeEKcDDyqRHgM6iba7ui2Dkc9ENUpUhfMd58N8e"); diff --git a/program/src/processor.rs b/program/src/processor.rs index 32ebf353..6dbb1366 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -39,10 +39,8 @@ impl Processor { program_id: &Pubkey, my_info: &Pubkey, authority_type: &[u8], - ) -> u8 { - let (_pubkey, bump_seed) = - Pubkey::find_program_address(&[&my_info.to_bytes()[..32], authority_type], program_id); - bump_seed + ) -> (Pubkey, u8) { + Pubkey::find_program_address(&[&my_info.to_bytes()[..32], authority_type], program_id) } /// Issue a stake_split instruction. @@ -186,18 +184,20 @@ impl Processor { return Err(Error::FeeTooHigh.into()); } + let (_, deposit_bump_seed) = Self::find_authority_bump_seed( + program_id, + stake_pool_info.key, + Self::AUTHORITY_DEPOSIT, + ); + let (_, withdraw_bump_seed) = Self::find_authority_bump_seed( + program_id, + stake_pool_info.key, + Self::AUTHORITY_WITHDRAW, + ); let stake_pool = State::Init(StakePool { owner: *owner_info.key, - deposit_bump_seed: Self::find_authority_bump_seed( - program_id, - stake_pool_info.key, - Self::AUTHORITY_DEPOSIT, - ), - withdraw_bump_seed: Self::find_authority_bump_seed( - program_id, - stake_pool_info.key, - Self::AUTHORITY_WITHDRAW, - ), + deposit_bump_seed, + withdraw_bump_seed, pool_mint: *pool_mint_info.key, owner_fee_account: *owner_fee_info.key, token_program_id: *token_program_info.key, @@ -288,6 +288,18 @@ impl Processor { stake_program_info.clone(), )?; + Self::stake_authorize( + stake_pool_info.key, + stake_info.clone(), + deposit_info.clone(), + Self::AUTHORITY_DEPOSIT, + stake_pool.deposit_bump_seed, + withdraw_info.key, + stake::StakeAuthorize::Staker, + reserved.clone(), + stake_program_info.clone(), + )?; + let user_amount = ::try_from(user_amount).or(Err(Error::CalculationFailure))?; Self::token_mint_to( stake_pool_info.key, diff --git a/program/src/stake.rs b/program/src/stake.rs index 0a901f84..9d6caf48 100644 --- a/program/src/stake.rs +++ b/program/src/stake.rs @@ -146,3 +146,20 @@ pub fn authorize( account_metas, ) } + +/// FIXME copied from the stake program +pub fn merge( + destination_stake_pubkey: &Pubkey, + source_stake_pubkey: &Pubkey, + authorized_pubkey: &Pubkey, +) -> Instruction { + let account_metas = vec![ + AccountMeta::new(*destination_stake_pubkey, false), + AccountMeta::new(*source_stake_pubkey, false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(sysvar::stake_history::id(), false), + AccountMeta::new_readonly(*authorized_pubkey, true), + ]; + + Instruction::new(id(), &StakeInstruction::Merge, account_metas) +} From aaf2da701260c75ca9b3a5eefe1b2396dbcfabe1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Nov 2020 12:39:52 +0000 Subject: [PATCH 0019/1076] Bump solana-program from 1.4.5 to 1.4.6 (#826) Bumps [solana-program](https://github.com/solana-labs/solana) from 1.4.5 to 1.4.6. - [Release notes](https://github.com/solana-labs/solana/releases) - [Changelog](https://github.com/solana-labs/solana/blob/master/RELEASE.md) - [Commits](https://github.com/solana-labs/solana/compare/v1.4.5...v1.4.6) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index e5d730fa..bfabe20d 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -17,7 +17,7 @@ solana-cli-config = "1.4.5" solana-client = "1.4.5" solana-logger = "1.4.5" solana-sdk = "1.4.5" -solana-program = "1.4.5" +solana-program = "1.4.6" spl-stake-pool = { path="../program", features = [ "no-entrypoint" ] } spl-token = { path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.3.1" diff --git a/program/Cargo.toml b/program/Cargo.toml index 356e3cbb..7dc9a431 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,7 +17,7 @@ num-traits = "0.2" num_enum = "0.5.1" serde = "1.0.117" serde_derive = "1.0.103" -solana-program = "1.4.5" +solana-program = "1.4.6" spl-token = { path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" From 3d9c46380c9fc08b34773c1ecb30a4a728c37370 Mon Sep 17 00:00:00 2001 From: Yuriy Savchenko Date: Thu, 12 Nov 2020 17:44:08 +0200 Subject: [PATCH 0020/1076] Added set-staking-auth and set-owner commands to stake pool CLI (#827) * Added set-staking-auth and set-owner commands to stake pool CLI * Error handling refactored, fixed new fee owner setting, fixed set owner arg group settings * Added check for fee account mint to stake pool initialization and set owner methods --- clients/cli/src/main.rs | 212 +++++++++++++++++++++++++++++++++++---- program/src/error.rs | 3 + program/src/processor.rs | 18 +++- 3 files changed, 211 insertions(+), 22 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 67003aa7..f06d9fb6 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -1,6 +1,6 @@ use clap::{ crate_description, crate_name, crate_version, value_t, value_t_or_exit, App, AppSettings, Arg, - SubCommand, + ArgGroup, SubCommand, }; use solana_account_decoder::UiAccountEncoding; use solana_clap_utils::{ @@ -25,8 +25,8 @@ use solana_sdk::{ }; use spl_stake_pool::{ instruction::{ - claim, deposit, initialize as initialize_pool, withdraw, Fee as PoolFee, - InitArgs as PoolInitArgs, + claim, deposit, initialize as initialize_pool, set_owner, set_staking_authority, withdraw, + Fee as PoolFee, InitArgs as PoolInitArgs, }, processor::Processor as PoolProcessor, stake::authorize as authorize_stake, @@ -361,16 +361,16 @@ fn command_list(config: &Config, pool: &Pubkey) -> CommandResult { let accounts = get_authority_accounts(config, &pool_withdraw_authority); if accounts.is_empty() { - println!("No accounts found.") - } else { - let mut total_balance: u64 = 0; - for (pubkey, account) in accounts { - let balance = account.lamports; - total_balance += balance; - println!("{}\t{} SOL", pubkey, lamports_to_sol(balance)); - } - println!("Total: {} SOL", lamports_to_sol(total_balance)); + return Err("No accounts found.".to_string().into()); + } + + let mut total_balance: u64 = 0; + for (pubkey, account) in accounts { + let balance = account.lamports; + total_balance += balance; + println!("{}\t{} SOL", pubkey, lamports_to_sol(balance)); } + println!("Total: {} SOL", lamports_to_sol(total_balance)); Ok(None) } @@ -419,25 +419,23 @@ fn command_withdraw( TokenAccount::unpack_from_slice(account_data.as_slice()).unwrap(); if account_data.mint != pool_data.pool_mint { - println!("Wrong token account."); - return Ok(None); + return Err("Wrong token account.".to_string().into()); } // Check burn_from balance let max_withdraw_amount = pool_tokens_to_stake_amount(&pool_data, account_data.amount); if max_withdraw_amount < amount { - println!( + return Err(format!( "Not enough token balance to withdraw {} SOL.\nMaximum withdraw amount is {} SOL.", lamports_to_sol(amount), lamports_to_sol(max_withdraw_amount) - ); - return Ok(None); + ) + .into()); } let mut accounts = get_authority_accounts(config, &pool_withdraw_authority); if accounts.is_empty() { - println!("No accounts found."); - return Ok(None); + return Err("No accounts found.".to_string().into()); } // Sort from lowest to highest balance accounts.sort_by(|a, b| a.1.lamports.cmp(&b.1.lamports)); @@ -555,11 +553,109 @@ fn command_withdraw( return Ok(Some(transaction)); } - println!( + Err(format!( "No stake accounts found in this pool with enough balance to withdraw {} SOL.", lamports_to_sol(amount) + ) + .into()) +} + +fn command_set_staking_auth( + config: &Config, + pool: &Pubkey, + stake_account: &Pubkey, + new_staker: &Pubkey, +) -> CommandResult { + let pool_data = config.rpc_client.get_account_data(&pool)?; + let pool_data: StakePool = PoolState::deserialize(pool_data.as_slice()) + .unwrap() + .stake_pool() + .unwrap(); + + let pool_withdraw_authority: Pubkey = PoolProcessor::authority_id( + &spl_stake_pool::id(), + pool, + PoolProcessor::AUTHORITY_WITHDRAW, + pool_data.withdraw_bump_seed, + ) + .unwrap(); + + let mut transaction = Transaction::new_with_payer( + &[set_staking_authority( + &spl_stake_pool::id(), + &pool, + &config.owner.pubkey(), + &pool_withdraw_authority, + &stake_account, + &new_staker, + &stake_program_id(), + )?], + Some(&config.fee_payer.pubkey()), ); - Ok(None) + + let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; + let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()]; + unique_signers!(signers); + transaction.sign(&signers, recent_blockhash); + Ok(Some(transaction)) +} + +fn command_set_owner( + config: &Config, + pool: &Pubkey, + new_owner: &Option, + new_fee_receiver: &Option, +) -> CommandResult { + let pool_data = config.rpc_client.get_account_data(&pool)?; + let pool_data: StakePool = PoolState::deserialize(pool_data.as_slice()) + .unwrap() + .stake_pool() + .unwrap(); + + // If new accounts are missing in the arguments use the old ones + let new_owner: Pubkey = match new_owner { + None => pool_data.owner, + Some(value) => *value, + }; + let new_fee_receiver: Pubkey = match new_fee_receiver { + None => pool_data.owner_fee_account, + Some(value) => { + // Check for fee receiver being a valid token account and have to same mint as the stake pool + let account_data = config.rpc_client.get_account_data(value)?; + let account_data: TokenAccount = + match TokenAccount::unpack_from_slice(account_data.as_slice()) { + Ok(data) => data, + Err(_) => { + return Err(format!("{} is not a token account", value).into()); + } + }; + if account_data.mint != pool_data.pool_mint { + return Err("Fee receiver account belongs to a different mint" + .to_string() + .into()); + } + *value + } + }; + + let mut transaction = Transaction::new_with_payer( + &[set_owner( + &spl_stake_pool::id(), + &pool, + &config.owner.pubkey(), + &new_owner, + &new_fee_receiver, + )?], + Some(&config.fee_payer.pubkey()), + ); + + let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; + let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()]; + unique_signers!(signers); + transaction.sign(&signers, recent_blockhash); + Ok(Some(transaction)) } fn main() { @@ -719,6 +815,68 @@ fn main() { .help("Stake account to receive SOL from the stake pool. Defaults to a new stake account."), ) ) + .subcommand(SubCommand::with_name("set-staking-auth").about("Changes staking authority of one of the accounts from the stake pool.") + .arg( + Arg::with_name("pool") + .long("pool") + .validator(is_pubkey) + .value_name("ADDRESS") + .takes_value(true) + .required(true) + .help("Stake pool address."), + ) + .arg( + Arg::with_name("stake_account") + .long("stake-account") + .validator(is_pubkey) + .value_name("ADDRESS") + .takes_value(true) + .required(true) + .help("Stake account address to change staking authority."), + ) + .arg( + Arg::with_name("new_staker") + .long("new-staker") + .validator(is_pubkey) + .value_name("ADDRESS") + .takes_value(true) + .required(true) + .help("Public key of the new staker account."), + ) + ) + .subcommand(SubCommand::with_name("set-owner").about("Changes owner or fee receiver account for the stake pool.") + .arg( + Arg::with_name("pool") + .long("pool") + .validator(is_pubkey) + .value_name("ADDRESS") + .takes_value(true) + .required(true) + .help("Stake pool address."), + ) + .arg( + Arg::with_name("new_owner") + .long("new-owner") + .validator(is_pubkey) + .value_name("ADDRESS") + .takes_value(true) + .help("Public key for the new stake pool owner."), + ) + .arg( + Arg::with_name("new_fee_receiver") + .long("new-fee-receiver") + .validator(is_pubkey) + .value_name("ADDRESS") + .takes_value(true) + .help("Public key for the new account to set as the stake pool fee receiver."), + ) + .group(ArgGroup::with_name("new_accounts") + .arg("new_owner") + .arg("new_fee_receiver") + .required(true) + .multiple(true) + ) + ) .get_matches(); let mut wallet_manager = None; @@ -793,6 +951,18 @@ fn main() { let stake_receiver: Option = pubkey_of(arg_matches, "stake_receiver"); command_withdraw(&config, &pool_account, amount, &burn_from, &stake_receiver) } + ("set-staking-auth", Some(arg_matches)) => { + let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); + let stake_account: Pubkey = pubkey_of(arg_matches, "stake_account").unwrap(); + let new_staker: Pubkey = pubkey_of(arg_matches, "new_staker").unwrap(); + command_set_staking_auth(&config, &pool_account, &stake_account, &new_staker) + } + ("set-owner", Some(arg_matches)) => { + let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); + let new_owner: Option = pubkey_of(arg_matches, "new_owner"); + let new_fee_receiver: Option = pubkey_of(arg_matches, "new_fee_receiver"); + command_set_owner(&config, &pool_account, &new_owner, &new_fee_receiver) + } _ => unreachable!(), } .and_then(|transaction| { diff --git a/program/src/error.rs b/program/src/error.rs index 1c42aa57..edb6ca8c 100644 --- a/program/src/error.rs +++ b/program/src/error.rs @@ -43,6 +43,9 @@ pub enum Error { /// Stake pool fee > 1. #[error("FeeTooHigh")] FeeTooHigh, + /// Token account is associated with the wrong mint. + #[error("WrongAccountMint")] + WrongAccountMint, } impl From for ProgramError { fn from(e: Error) -> Self { diff --git a/program/src/processor.rs b/program/src/processor.rs index 6dbb1366..f1b99d0f 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -10,7 +10,7 @@ use num_traits::FromPrimitive; use solana_program::{ account_info::next_account_info, account_info::AccountInfo, decode_error::DecodeError, entrypoint::ProgramResult, info, program::invoke_signed, program_error::PrintProgramError, - program_error::ProgramError, pubkey::Pubkey, + program_error::ProgramError, program_pack::Pack, pubkey::Pubkey, }; use std::convert::TryFrom; @@ -184,6 +184,13 @@ impl Processor { return Err(Error::FeeTooHigh.into()); } + // Check for owner fee account to have proper mint assigned + if *pool_mint_info.key + != spl_token::state::Account::unpack_from_slice(&owner_fee_info.data.borrow())?.mint + { + return Err(Error::WrongAccountMint.into()); + } + let (_, deposit_bump_seed) = Self::find_authority_bump_seed( program_id, stake_pool_info.key, @@ -557,6 +564,14 @@ impl Processor { if !owner_info.is_signer { return Err(Error::InvalidInput.into()); } + + // Check for owner fee account to have proper mint assigned + if stake_pool.pool_mint + != spl_token::state::Account::unpack_from_slice(&new_owner_fee_info.data.borrow())?.mint + { + return Err(Error::WrongAccountMint.into()); + } + stake_pool.owner = *new_owner_info.key; stake_pool.owner_fee_account = *new_owner_fee_info.key; State::Init(stake_pool).serialize(&mut stake_pool_info.data.borrow_mut())?; @@ -612,6 +627,7 @@ impl PrintProgramError for Error { Error::InvalidOutput => info!("Error: InvalidOutput"), Error::CalculationFailure => info!("Error: CalculationFailure"), Error::FeeTooHigh => info!("Error: FeeTooHigh"), + Error::WrongAccountMint => info!("Error: WrongAccountMint"), } } } From 2b3e4bfb75656c348b179b93ef5b6086878e8cd6 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Thu, 12 Nov 2020 09:19:39 -0800 Subject: [PATCH 0021/1076] Upgrade to Solana 1.4.7 --- clients/cli/Cargo.toml | 14 +++++++------- program/Cargo.toml | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index bfabe20d..2deedc90 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,13 +11,13 @@ version = "2.0.1" [dependencies] clap = "2.33.3" serde_json = "1.0.57" -solana-account-decoder = "1.4.5" -solana-clap-utils = "1.4.5" -solana-cli-config = "1.4.5" -solana-client = "1.4.5" -solana-logger = "1.4.5" -solana-sdk = "1.4.5" -solana-program = "1.4.6" +solana-account-decoder = "1.4.7" +solana-clap-utils = "1.4.7" +solana-cli-config = "1.4.7" +solana-client = "1.4.7" +solana-logger = "1.4.7" +solana-sdk = "1.4.7" +solana-program = "1.4.7" spl-stake-pool = { path="../program", features = [ "no-entrypoint" ] } spl-token = { path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.3.1" diff --git a/program/Cargo.toml b/program/Cargo.toml index 7dc9a431..1118f39d 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,12 +17,12 @@ num-traits = "0.2" num_enum = "0.5.1" serde = "1.0.117" serde_derive = "1.0.103" -solana-program = "1.4.6" +solana-program = "1.4.7" spl-token = { path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" [dev-dependencies] -solana-sdk = "1.4.5" +solana-sdk = "1.4.7" [lib] crate-type = ["cdylib", "lib"] From a97866b77885324eb61a764e307c0c15cb0ec413 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 13 Nov 2020 13:11:39 +0100 Subject: [PATCH 0022/1076] stake-pool: Add end-to-end testing using ProgramTest (#828) * WIP: stake-pool: Add end-to-end testing using ProgramTest * Run cargo fmt * Add deposit test and extra requirements * Update Cargo.lock after rebuild * Bring token program sdk version back to 1.4.7 --- program/Cargo.toml | 3 + program/src/entrypoint.rs | 2 + program/src/stake.rs | 108 ++++++++++- program/tests/functional.rs | 356 ++++++++++++++++++++++++++++++++++++ 4 files changed, 467 insertions(+), 2 deletions(-) create mode 100644 program/tests/functional.rs diff --git a/program/Cargo.toml b/program/Cargo.toml index 1118f39d..5bb92c08 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -22,7 +22,10 @@ spl-token = { path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" [dev-dependencies] +bincode = "1.3.1" +solana-program-test = "1.4.7" solana-sdk = "1.4.7" +tokio = { version = "0.3", features = ["macros"]} [lib] crate-type = ["cdylib", "lib"] diff --git a/program/src/entrypoint.rs b/program/src/entrypoint.rs index b4ee96c2..ee0cb497 100644 --- a/program/src/entrypoint.rs +++ b/program/src/entrypoint.rs @@ -1,5 +1,7 @@ //! Program entrypoint +#![cfg(all(target_arch = "bpf", not(feature = "no-entrypoint")))] + use crate::{error::Error, processor::Processor}; use solana_program::{ account_info::AccountInfo, entrypoint, entrypoint::ProgramResult, diff --git a/program/src/stake.rs b/program/src/stake.rs index 9d6caf48..61bc63c4 100644 --- a/program/src/stake.rs +++ b/program/src/stake.rs @@ -2,9 +2,10 @@ use serde_derive::{Deserialize, Serialize}; use solana_program::{ + clock::{Epoch, UnixTimestamp}, instruction::{AccountMeta, Instruction}, pubkey::Pubkey, - sysvar, + system_instruction, sysvar, }; solana_program::declare_id!("Stake11111111111111111111111111111111111111"); @@ -21,7 +22,7 @@ pub enum StakeInstruction { /// Authorized carries pubkeys that must sign staker transactions /// and withdrawer transactions. /// Lockup carries information about withdrawal restrictions - InitializeNOTUSED, + Initialize(Authorized, Lockup), /// Authorize a key to manage stake or withdrawal /// @@ -102,6 +103,55 @@ pub enum StakeInstruction { AuthorizeWithSeedNOTUSED, } +/// FIXME copied from the stake program +#[derive(Debug, Serialize, Deserialize, PartialEq, Clone, Copy)] +#[allow(clippy::large_enum_variant)] +pub enum StakeState { + /// FIXME copied from the stake program + Uninitialized, + /// FIXME copied from the stake program + Initialized(Meta), + /// FIXME copied from the stake program + Stake(Meta, Stake), + /// FIXME copied from the stake program + RewardsPool, +} + +/// FIXME copied from the stake program +#[derive(Default, Debug, Serialize, Deserialize, PartialEq, Clone, Copy)] +pub struct Meta { + /// FIXME copied from the stake program + pub rent_exempt_reserve: u64, + /// FIXME copied from the stake program + pub authorized: Authorized, + /// FIXME copied from the stake program + pub lockup: Lockup, +} + +/// FIXME copied from the stake program +#[derive(Debug, Default, Serialize, Deserialize, PartialEq, Clone, Copy)] +pub struct Stake { + /// FIXME copied from the stake program + pub delegation: Delegation, + /// credits observed is credits from vote account state when delegated or redeemed + pub credits_observed: u64, +} + +/// FIXME copied from the stake program +#[derive(Debug, Default, Serialize, Deserialize, PartialEq, Clone, Copy)] +pub struct Delegation { + /// to whom the stake is delegated + pub voter_pubkey: Pubkey, + /// activated stake amount, set at delegate() time + pub stake: u64, + /// epoch at which this stake was activated, std::Epoch::MAX if is a bootstrap stake + pub activation_epoch: Epoch, + /// epoch the stake was deactivated, std::Epoch::MAX if not deactivated + pub deactivation_epoch: Epoch, + /// how much stake we can activate per-epoch as a fraction of currently effective stake + pub warmup_cooldown_rate: f64, +} + /// FIXME copied from the stake program #[derive(Debug, Serialize, Deserialize, PartialEq, Clone, Copy)] pub enum StakeAuthorize { @@ -110,6 +160,28 @@ pub enum StakeAuthorize { /// FIXME copied from the stake program Withdrawer, } +/// FIXME copied from the stake program +#[derive(Default, Debug, Serialize, Deserialize, PartialEq, Clone, Copy)] +pub struct Authorized { + /// FIXME copied from the stake program + pub staker: Pubkey, + /// FIXME copied from the stake program + pub withdrawer: Pubkey, +} + +/// FIXME copied from the stake program +#[derive(Default, Debug, Serialize, Deserialize, PartialEq, Clone, Copy)] +pub struct Lockup { + /// UnixTimestamp at which this stake will allow withdrawal, unless the + /// transaction is signed by the custodian + pub unix_timestamp: UnixTimestamp, + /// epoch height at which this stake will allow withdrawal, unless the + /// transaction is signed by the custodian + pub epoch: Epoch, + /// custodian signature on a transaction exempts the operation from + /// lockup constraints + pub custodian: Pubkey, +} /// FIXME copied from the stake program pub fn split_only( @@ -163,3 +235,35 @@ pub fn merge( Instruction::new(id(), &StakeInstruction::Merge, account_metas) } + +/// FIXME copied from the stake program +pub fn create_account( + from_pubkey: &Pubkey, + stake_pubkey: &Pubkey, + authorized: &Authorized, + lockup: &Lockup, + lamports: u64, +) -> Vec { + vec![ + system_instruction::create_account( + from_pubkey, + stake_pubkey, + lamports, + std::mem::size_of::() as u64, + &id(), + ), + initialize(stake_pubkey, authorized, lockup), + ] +} + +/// FIXME copied from the stake program +fn initialize(stake_pubkey: &Pubkey, authorized: &Authorized, lockup: &Lockup) -> Instruction { + Instruction::new( + id(), + &StakeInstruction::Initialize(*authorized, *lockup), + vec![ + AccountMeta::new(*stake_pubkey, false), + AccountMeta::new_readonly(sysvar::rent::id(), false), + ], + ) +} diff --git a/program/tests/functional.rs b/program/tests/functional.rs new file mode 100644 index 00000000..3e5d2286 --- /dev/null +++ b/program/tests/functional.rs @@ -0,0 +1,356 @@ +#![cfg(feature = "test-bpf")] + +use solana_program::{hash::Hash, program_pack::Pack, pubkey::Pubkey, system_instruction}; +use solana_program_test::*; +use solana_sdk::{ + signature::{Keypair, Signer}, + transaction::Transaction, +}; +use spl_stake_pool::*; + +use bincode::deserialize; + +const TEST_STAKE_AMOUNT: u64 = 100; + +fn program_test() -> ProgramTest { + let mut pc = ProgramTest::new( + "spl_stake_pool", + id(), + processor!(processor::Processor::process), + ); + + // Add SPL Token program + pc.add_program( + "spl_token", + spl_token::id(), + processor!(spl_token::processor::Processor::process), + ); + + pc +} + +async fn create_mint( + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + pool_mint: &Keypair, + owner: &Pubkey, +) { + let rent = banks_client.get_rent().await.unwrap(); + let mint_rent = rent.minimum_balance(spl_token::state::Mint::LEN); + + let mut transaction = Transaction::new_with_payer( + &[ + system_instruction::create_account( + &payer.pubkey(), + &pool_mint.pubkey(), + mint_rent, + spl_token::state::Mint::LEN as u64, + &spl_token::id(), + ), + spl_token::instruction::initialize_mint( + &spl_token::id(), + &pool_mint.pubkey(), + &owner, + None, + 0, + ) + .unwrap(), + ], + Some(&payer.pubkey()), + ); + transaction.sign(&[payer, pool_mint], *recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); +} + +async fn create_token_account( + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + account: &Keypair, + pool_mint: &Pubkey, + owner: &Pubkey, +) { + let rent = banks_client.get_rent().await.unwrap(); + let account_rent = rent.minimum_balance(spl_token::state::Account::LEN); + + let mut transaction = Transaction::new_with_payer( + &[ + system_instruction::create_account( + &payer.pubkey(), + &account.pubkey(), + account_rent, + spl_token::state::Account::LEN as u64, + &spl_token::id(), + ), + spl_token::instruction::initialize_account( + &spl_token::id(), + &account.pubkey(), + pool_mint, + owner, + ) + .unwrap(), + ], + Some(&payer.pubkey()), + ); + transaction.sign(&[payer, account], *recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); +} + +async fn create_stake_pool( + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + stake_pool: &Keypair, + pool_mint: &Pubkey, + pool_token_account: &Pubkey, + owner: &Pubkey, +) { + let rent = banks_client.get_rent().await.unwrap(); + let rent = rent.minimum_balance(state::State::LEN); + let numerator = 1; + let denominator = 100; + let fee = instruction::Fee { + numerator, + denominator, + }; + let init_args = instruction::InitArgs { fee }; + + let mut transaction = Transaction::new_with_payer( + &[ + system_instruction::create_account( + &payer.pubkey(), + &stake_pool.pubkey(), + rent, + state::State::LEN as u64, + &id(), + ), + instruction::initialize( + &id(), + &stake_pool.pubkey(), + owner, + pool_mint, + pool_token_account, + &spl_token::id(), + init_args, + ) + .unwrap(), + ], + Some(&payer.pubkey()), + ); + transaction.sign(&[payer, stake_pool], *recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); +} + +async fn create_stake_account( + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + stake: &Keypair, + authorized: &stake::Authorized, + lockup: &stake::Lockup, +) { + let rent = banks_client.get_rent().await.unwrap(); + let lamports = + rent.minimum_balance(std::mem::size_of::()) + TEST_STAKE_AMOUNT; + + let mut transaction = Transaction::new_with_payer( + &stake::create_account( + &payer.pubkey(), + &stake.pubkey(), + authorized, + lockup, + lamports, + ), + Some(&payer.pubkey()), + ); + transaction.sign(&[payer, stake], *recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); +} + +struct StakePoolAccounts { + pub stake_pool: Keypair, + pub pool_mint: Keypair, + pub pool_fee_account: Keypair, + pub owner: Pubkey, + pub withdraw_authority: Pubkey, + pub deposit_authority: Pubkey, +} + +impl StakePoolAccounts { + pub fn new() -> Self { + let stake_pool = Keypair::new(); + let stake_pool_address = &stake_pool.pubkey(); + let (withdraw_authority, _) = Pubkey::find_program_address( + &[&stake_pool_address.to_bytes()[..32], b"withdraw"], + &id(), + ); + let (deposit_authority, _) = Pubkey::find_program_address( + &[&stake_pool_address.to_bytes()[..32], b"deposit"], + &id(), + ); + let pool_mint = Keypair::new(); + let pool_fee_account = Keypair::new(); + let owner = Pubkey::new_unique(); + + Self { + stake_pool, + pool_mint, + pool_fee_account, + owner, + withdraw_authority, + deposit_authority, + } + } + + pub async fn initialize_stake_pool( + &self, + mut banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + ) { + create_mint( + &mut banks_client, + &payer, + &recent_blockhash, + &self.pool_mint, + &self.withdraw_authority, + ) + .await; + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &self.pool_fee_account, + &self.pool_mint.pubkey(), + &self.owner, + ) + .await; + create_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &self.stake_pool, + &self.pool_mint.pubkey(), + &self.pool_fee_account.pubkey(), + &self.owner, + ) + .await; + } + + pub async fn deposit_stake( + &self, + stake: &Pubkey, + pool_account: &Pubkey, + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + ) { + let mut transaction = Transaction::new_with_payer( + &[instruction::deposit( + &id(), + &self.stake_pool.pubkey(), + &self.deposit_authority, + &self.withdraw_authority, + stake, + pool_account, + &self.pool_fee_account.pubkey(), + &self.pool_mint.pubkey(), + &spl_token::id(), + &stake::id(), + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[payer], *recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); + } +} + +#[tokio::test] +async fn test_stake_pool_initialize() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await; + + // Stake pool now exists + let stake_pool = banks_client + .get_account(stake_pool_accounts.stake_pool.pubkey()) + .await + .expect("get_account") + .expect("stake pool not none"); + assert_eq!(stake_pool.data.len(), state::State::LEN); + assert_eq!(stake_pool.owner, id()); +} + +#[tokio::test] +async fn test_stake_pool_deposit() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await; + + let user = Keypair::new(); + // make stake account + let user_stake = Keypair::new(); + let lockup = stake::Lockup::default(); + let authorized = stake::Authorized { + staker: stake_pool_accounts.deposit_authority.clone(), + withdrawer: stake_pool_accounts.deposit_authority.clone(), + }; + create_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake, + &authorized, + &lockup, + ) + .await; + // make pool token account + let user_pool_account = Keypair::new(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user.pubkey(), + ) + .await; + stake_pool_accounts + .deposit_stake( + &user_stake.pubkey(), + &user_pool_account.pubkey(), + &mut banks_client, + &payer, + &recent_blockhash, + ) + .await; + + let stake = banks_client + .get_account(user_stake.pubkey()) + .await + .expect("get_account") + .expect("stake not none"); + assert_eq!(stake.data.len(), std::mem::size_of::()); + assert_eq!(stake.owner, stake::id()); + + let stake_state = deserialize::(&stake.data).unwrap(); + match stake_state { + stake::StakeState::Initialized(meta) => { + assert_eq!( + &meta.authorized.staker, + &stake_pool_accounts.withdraw_authority + ); + assert_eq!( + &meta.authorized.withdrawer, + &stake_pool_accounts.withdraw_authority + ); + } + _ => assert!(false), + } +} From 851c354c1893d320f7d031b99d1cc70510caa650 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Fri, 13 Nov 2020 17:57:21 -0800 Subject: [PATCH 0023/1076] Update to Solana 1.4.8 --- clients/cli/Cargo.toml | 14 +++++++------- program/Cargo.toml | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 2deedc90..5f371223 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,13 +11,13 @@ version = "2.0.1" [dependencies] clap = "2.33.3" serde_json = "1.0.57" -solana-account-decoder = "1.4.7" -solana-clap-utils = "1.4.7" -solana-cli-config = "1.4.7" -solana-client = "1.4.7" -solana-logger = "1.4.7" -solana-sdk = "1.4.7" -solana-program = "1.4.7" +solana-account-decoder = "1.4.8" +solana-clap-utils = "1.4.8" +solana-cli-config = "1.4.8" +solana-client = "1.4.8" +solana-logger = "1.4.8" +solana-sdk = "1.4.8" +solana-program = "1.4.8" spl-stake-pool = { path="../program", features = [ "no-entrypoint" ] } spl-token = { path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.3.1" diff --git a/program/Cargo.toml b/program/Cargo.toml index 5bb92c08..3b678192 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,14 +17,14 @@ num-traits = "0.2" num_enum = "0.5.1" serde = "1.0.117" serde_derive = "1.0.103" -solana-program = "1.4.7" +solana-program = "1.4.8" spl-token = { path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" [dev-dependencies] bincode = "1.3.1" -solana-program-test = "1.4.7" -solana-sdk = "1.4.7" +solana-program-test = "1.4.8" +solana-sdk = "1.4.8" tokio = { version = "0.3", features = ["macros"]} [lib] From 212b7ec5af051496e3721b25d5df49aecb66f9ab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 14 Nov 2020 02:36:33 +0000 Subject: [PATCH 0024/1076] Bump bs58 from 0.3.1 to 0.4.0 Bumps [bs58](https://github.com/mycorrhiza/bs58-rs) from 0.3.1 to 0.4.0. - [Release notes](https://github.com/mycorrhiza/bs58-rs/releases) - [Commits](https://github.com/mycorrhiza/bs58-rs/compare/0.3.1...0.4.0) Signed-off-by: dependabot[bot] --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 5f371223..8475c3ff 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -20,7 +20,7 @@ solana-sdk = "1.4.8" solana-program = "1.4.8" spl-stake-pool = { path="../program", features = [ "no-entrypoint" ] } spl-token = { path="../../token/program", features = [ "no-entrypoint" ] } -bs58 = "0.3.1" +bs58 = "0.4.0" [[bin]] name = "spl-stake-pool" From 88f24749bb8a099bf1b022f0cb427f12e420b94e Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Tue, 17 Nov 2020 17:26:59 -0800 Subject: [PATCH 0025/1076] Bump solana version to v1.4.9 --- clients/cli/Cargo.toml | 14 +++++++------- program/Cargo.toml | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 8475c3ff..dc55f709 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,13 +11,13 @@ version = "2.0.1" [dependencies] clap = "2.33.3" serde_json = "1.0.57" -solana-account-decoder = "1.4.8" -solana-clap-utils = "1.4.8" -solana-cli-config = "1.4.8" -solana-client = "1.4.8" -solana-logger = "1.4.8" -solana-sdk = "1.4.8" -solana-program = "1.4.8" +solana-account-decoder = "1.4.9" +solana-clap-utils = "1.4.9" +solana-cli-config = "1.4.9" +solana-client = "1.4.9" +solana-logger = "1.4.9" +solana-sdk = "1.4.9" +solana-program = "1.4.9" spl-stake-pool = { path="../program", features = [ "no-entrypoint" ] } spl-token = { path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" diff --git a/program/Cargo.toml b/program/Cargo.toml index 3b678192..bf6219c1 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,14 +17,14 @@ num-traits = "0.2" num_enum = "0.5.1" serde = "1.0.117" serde_derive = "1.0.103" -solana-program = "1.4.8" +solana-program = "1.4.9" spl-token = { path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" [dev-dependencies] bincode = "1.3.1" -solana-program-test = "1.4.8" -solana-sdk = "1.4.8" +solana-program-test = "1.4.9" +solana-sdk = "1.4.9" tokio = { version = "0.3", features = ["macros"]} [lib] From 40ae0fdff409c5223054130f1cb582b40464524d Mon Sep 17 00:00:00 2001 From: Yuriy Savchenko Date: Wed, 18 Nov 2020 23:47:42 +0200 Subject: [PATCH 0026/1076] Added negative tests for stake pool (#857) * Added negative tests for stake pool * Claim refactoring, error codes fixed * Linter errors fixed --- program/src/processor.rs | 684 ++++++++++++++++++++++++++++++--------- 1 file changed, 536 insertions(+), 148 deletions(-) diff --git a/program/src/processor.rs b/program/src/processor.rs index f1b99d0f..e301bb24 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -637,11 +637,12 @@ mod tests { use super::*; use crate::instruction::*; use solana_program::{ - instruction::Instruction, native_token::sol_to_lamports, program_pack::Pack, program_stubs, - rent::Rent, + instruction::AccountMeta, instruction::Instruction, native_token::sol_to_lamports, + program_pack::Pack, program_stubs, rent::Rent, sysvar, }; use solana_sdk::account::{create_account, create_is_signer_account_infos, Account}; use spl_token::{ + error::TokenError, instruction::{initialize_account, initialize_mint}, processor::Processor as TokenProcessor, state::{Account as SplAccount, Mint as SplMint}, @@ -740,10 +741,48 @@ mod tests { } struct DepositInfo { + result: ProgramResult, stake_account_key: Pubkey, stake_account_account: Account, } + struct Deposit { + stake_balance: u64, + tokens_to_issue: u64, + user_token_balance: u64, + fee_token_balance: u64, + pool_info: StakePoolInfo, + pool_token_receiver: TokenInfo, + } + + struct WithdrawInfo { + result: ProgramResult, + } + + struct Withdraw { + stake_balance: u64, + tokens_to_issue: u64, + withdraw_amount: u64, + tokens_to_burn: u64, + pool_info: StakePoolInfo, + user_withdrawer_key: Pubkey, + pool_token_receiver: TokenInfo, + deposit_info: DepositInfo, + } + + struct ClaimInfo { + result: ProgramResult, + } + + struct Claim { + tokens_to_issue: u64, + pool_info: StakePoolInfo, + user_withdrawer_key: Pubkey, + pool_token_receiver: TokenInfo, + deposit_info: DepositInfo, + allow_burn_to: Pubkey, + } + fn do_process_instruction( instruction: Instruction, accounts: Vec<&mut Account>, @@ -833,37 +872,6 @@ mod tests { token } - fn _mint_token( - program_id: &Pubkey, - mint_key: &Pubkey, - mut mint_account: &mut Account, - authority_key: &Pubkey, - amount: u64, - ) -> (Pubkey, Account) { - let mut token_account = create_token_account(program_id, mint_key, mint_account); - let mut authority_account = Account::default(); - - do_process_instruction( - spl_token::instruction::mint_to( - &program_id, - &mint_key, - &token_account.key, - &authority_key, - &[], - amount, - ) - .unwrap(), - vec![ - &mut mint_account, - &mut token_account.account, - &mut authority_account, - ], - ) - .unwrap(); - - (token_account.key, token_account.account) - } - fn create_mint(program_id: &Pubkey, authority_key: &Pubkey) -> (Pubkey, Account) { let mint_key = Pubkey::new_unique(); let mut mint_account = Account::new( @@ -989,7 +997,7 @@ mod tests { // TODO: Set stake account Withdrawer authority to pool_info.deposit_authority_key // Call deposit - let _result = do_process_instruction( + let result = do_process_instruction( deposit( &STAKE_POOL_PROGRAM_ID, &pool_info.pool_key, @@ -1015,15 +1023,151 @@ mod tests { &mut Account::default(), &mut Account::default(), ], - ) - .expect("Error on stake pool deposit"); + ); DepositInfo { + result, stake_account_key, stake_account_account, } } + fn do_withdraw(test_data: &mut Withdraw) -> WithdrawInfo { + approve_token( + &TOKEN_PROGRAM_ID, + &test_data.pool_token_receiver.key, + &mut test_data.pool_token_receiver.account, + &test_data.pool_info.withdraw_authority_key, + &test_data.pool_token_receiver.owner, + test_data.tokens_to_burn, + ); + + let stake_to_receive_key = Pubkey::new_unique(); + let mut stake_to_receive_account = Account::new( + test_data.stake_balance, + STAKE_ACCOUNT_LEN, + &stake_program_id(), + ); + + let result = do_process_instruction( + withdraw( + &STAKE_POOL_PROGRAM_ID, + &test_data.pool_info.pool_key, + &test_data.pool_info.withdraw_authority_key, + &test_data.deposit_info.stake_account_key, + &stake_to_receive_key, + &test_data.user_withdrawer_key, + &test_data.pool_token_receiver.key, + &test_data.pool_info.mint_key, + &TOKEN_PROGRAM_ID, + &stake_program_id(), + test_data.withdraw_amount, + ) + .unwrap(), + vec![ + &mut test_data.pool_info.pool_account, + &mut Account::default(), + &mut test_data.deposit_info.stake_account_account, + &mut stake_to_receive_account, + &mut Account::default(), + &mut test_data.pool_token_receiver.account, + &mut test_data.pool_info.mint_account, + &mut Account::default(), + &mut Account::default(), + &mut Account::default(), + ], + ); + + WithdrawInfo { result } + } + + fn do_claim(test_data: &mut Claim) -> ClaimInfo { + approve_token( + &TOKEN_PROGRAM_ID, + &test_data.pool_token_receiver.key, + &mut test_data.pool_token_receiver.account, + &test_data.allow_burn_to, + &test_data.pool_token_receiver.owner, + test_data.tokens_to_issue, + ); + + let result = do_process_instruction( + claim( + &STAKE_POOL_PROGRAM_ID, + &test_data.pool_info.pool_key, + &test_data.pool_info.withdraw_authority_key, + &test_data.deposit_info.stake_account_key, + &test_data.user_withdrawer_key, + &test_data.pool_token_receiver.key, + &test_data.pool_info.mint_key, + &TOKEN_PROGRAM_ID, + &stake_program_id(), + ) + .unwrap(), + vec![ + &mut test_data.pool_info.pool_account, + &mut Account::default(), + &mut test_data.deposit_info.stake_account_account, + &mut Account::default(), + &mut test_data.pool_token_receiver.account, + &mut test_data.pool_info.mint_account, + &mut Account::default(), + &mut Account::default(), + &mut Account::default(), + ], + ); + ClaimInfo { result } + } + + fn set_staking_authority_without_signer( + program_id: &Pubkey, + stake_pool: &Pubkey, + stake_pool_owner: &Pubkey, + stake_pool_withdraw: &Pubkey, + stake_account_to_update: &Pubkey, + stake_account_new_authority: &Pubkey, + stake_program_id: &Pubkey, + ) -> Result { + let args = StakePoolInstruction::SetStakingAuthority; + let data = args.serialize()?; + let accounts = vec![ + AccountMeta::new(*stake_pool, false), + AccountMeta::new_readonly(*stake_pool_owner, false), + AccountMeta::new_readonly(*stake_pool_withdraw, false), + AccountMeta::new(*stake_account_to_update, false), + AccountMeta::new_readonly(*stake_account_new_authority, false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(*stake_program_id, false), + ]; + Ok(Instruction { + program_id: *program_id, + accounts, + data, + }) + } + + fn set_owner_without_signer( + program_id: &Pubkey, + stake_pool: &Pubkey, + stake_pool_owner: &Pubkey, + stake_pool_new_owner: &Pubkey, + stake_pool_new_fee_receiver: &Pubkey, + ) -> Result { + let args = StakePoolInstruction::SetOwner; + let data = args.serialize()?; + let accounts = vec![ + AccountMeta::new(*stake_pool, false), + AccountMeta::new_readonly(*stake_pool_owner, false), + AccountMeta::new_readonly(*stake_pool_new_owner, false), + AccountMeta::new_readonly(*stake_pool_new_fee_receiver, false), + ]; + Ok(Instruction { + program_id: *program_id, + accounts, + data, + }) + } + #[test] fn test_initialize() { let pool_info = create_stake_pool_default(); @@ -1034,8 +1178,8 @@ mod tests { State::Init(stake_pool) => { assert_eq!(stake_pool.deposit_bump_seed, pool_info.deposit_bump_seed); assert_eq!(stake_pool.withdraw_bump_seed, pool_info.withdraw_bump_seed); - assert_eq!(stake_pool.fee.numerator, pool_info.fee.numerator); - assert_eq!(stake_pool.fee.denominator, pool_info.fee.denominator); + assert_eq!(stake_pool.fee.numerator, FEE_DEFAULT.numerator); + assert_eq!(stake_pool.fee.denominator, FEE_DEFAULT.denominator); assert_eq!(stake_pool.owner, pool_info.owner_key); assert_eq!(stake_pool.pool_mint, pool_info.mint_key); @@ -1048,12 +1192,7 @@ mod tests { } } - #[test] - fn test_deposit() { - let fee = Fee { - denominator: 100, - numerator: 2, - }; + fn initialize_deposit_test() -> Deposit { let stake_balance: u64 = sol_to_lamports(10.0); let tokens_to_issue: u64 = 10_000_000_000; let user_token_balance: u64 = 9_800_000_000; @@ -1061,187 +1200,303 @@ mod tests { assert_eq!(tokens_to_issue, user_token_balance + fee_token_balance); // Create stake account - let mut pool_info = create_stake_pool(fee); + let mut pool_info = create_stake_pool(Fee { + denominator: 100, + numerator: 2, + }); - let mut pool_token_receiver = create_token_account( + let pool_token_receiver = create_token_account( &TOKEN_PROGRAM_ID, &pool_info.mint_key, &mut pool_info.mint_account, ); - let _deposit_info = do_deposit(&mut pool_info, stake_balance, &mut pool_token_receiver); + Deposit { + stake_balance, + tokens_to_issue, + user_token_balance, + fee_token_balance, + pool_info, + pool_token_receiver, + } + } + #[test] + fn test_deposit() { + let mut test_data = initialize_deposit_test(); + + let deposit_info = do_deposit( + &mut test_data.pool_info, + test_data.stake_balance, + &mut test_data.pool_token_receiver, + ); + + deposit_info.result.expect("Fail on deposit"); // Test stake pool balance - let state = State::deserialize(&pool_info.pool_account.data).unwrap(); + let state = State::deserialize(&test_data.pool_info.pool_account.data).unwrap(); assert!( - matches!(state, State::Init(stake_pool) if stake_pool.stake_total == stake_balance && stake_pool.pool_total == tokens_to_issue) + matches!(state, State::Init(stake_pool) if stake_pool.stake_total == test_data.stake_balance && stake_pool.pool_total == test_data.tokens_to_issue) ); // Test token balances - let user_token_state = SplAccount::unpack_from_slice(&pool_token_receiver.account.data) - .expect("User token account is not initialized after deposit"); - assert_eq!(user_token_state.amount, user_token_balance); - let fee_token_state = SplAccount::unpack_from_slice(&pool_info.owner_fee_account.data) - .expect("Fee token account is not initialized after deposit"); - assert_eq!(fee_token_state.amount, fee_token_balance); + let user_token_state = + SplAccount::unpack_from_slice(&test_data.pool_token_receiver.account.data) + .expect("User token account is not initialized after deposit"); + assert_eq!(user_token_state.amount, test_data.user_token_balance); + let fee_token_state = + SplAccount::unpack_from_slice(&test_data.pool_info.owner_fee_account.data) + .expect("Fee token account is not initialized after deposit"); + assert_eq!(fee_token_state.amount, test_data.fee_token_balance); // Test mint total issued tokens - let mint_state = SplMint::unpack_from_slice(&pool_info.mint_account.data) + let mint_state = SplMint::unpack_from_slice(&test_data.pool_info.mint_account.data) .expect("Mint account is not initialized after deposit"); - assert_eq!(mint_state.supply, stake_balance); + assert_eq!(mint_state.supply, test_data.stake_balance); // TODO: Check stake account Withdrawer to match stake pool withdraw authority } #[test] - fn test_withdraw() { - let mut pool_info = create_stake_pool_default(); + fn negative_test_deposit_wrong_withdraw_authority() { + let mut test_data = initialize_deposit_test(); + test_data.pool_info.withdraw_authority_key = Pubkey::new_unique(); + + let deposit_info = do_deposit( + &mut test_data.pool_info, + test_data.stake_balance, + &mut test_data.pool_token_receiver, + ); + assert_eq!( + deposit_info.result, + Err(Error::InvalidProgramAddress.into()) + ); + } + #[test] + fn negative_test_deposit_wrong_deposit_authority() { + let mut test_data = initialize_deposit_test(); + test_data.pool_info.deposit_authority_key = Pubkey::new_unique(); + + let deposit_info = do_deposit( + &mut test_data.pool_info, + test_data.stake_balance, + &mut test_data.pool_token_receiver, + ); - let user_withdrawer_key = Pubkey::new_unique(); + assert_eq!( + deposit_info.result, + Err(Error::InvalidProgramAddress.into()) + ); + } + #[test] + fn negative_test_deposit_wrong_owner_fee_account() { + let mut test_data = initialize_deposit_test(); + test_data.pool_info.owner_fee_account = Account::default(); + + let deposit_info = do_deposit( + &mut test_data.pool_info, + test_data.stake_balance, + &mut test_data.pool_token_receiver, + ); + assert_eq!(deposit_info.result, Err(ProgramError::InvalidAccountData)); + } + + fn initialize_withdraw_test() -> Withdraw { let stake_balance = sol_to_lamports(20.0); - let tokens_to_issue: u64 = 20_000_000_000; + let tokens_to_issue = 20_000_000_000; + let withdraw_amount = sol_to_lamports(5.0); + let tokens_to_burn = 5_000_000_000; + + let mut pool_info = create_stake_pool_default(); + + let user_withdrawer_key = Pubkey::new_unique(); let mut pool_token_receiver = create_token_account( &TOKEN_PROGRAM_ID, &pool_info.mint_key, &mut pool_info.mint_account, ); - let mut deposit_info = do_deposit(&mut pool_info, stake_balance, &mut pool_token_receiver); - - let withdraw_amount = sol_to_lamports(5.0); - let tokens_to_burn: u64 = 5_000_000_000; + let deposit_info = do_deposit(&mut pool_info, stake_balance, &mut pool_token_receiver); - approve_token( - &TOKEN_PROGRAM_ID, - &pool_token_receiver.key, - &mut pool_token_receiver.account, - &pool_info.withdraw_authority_key, - &pool_token_receiver.owner, + Withdraw { + stake_balance, + tokens_to_issue, + withdraw_amount, tokens_to_burn, - ); - - let stake_to_receive_key = Pubkey::new_unique(); - let mut stake_to_receive_account = - Account::new(stake_balance, STAKE_ACCOUNT_LEN, &stake_program_id()); - - let _result = do_process_instruction( - withdraw( - &STAKE_POOL_PROGRAM_ID, - &pool_info.pool_key, - &pool_info.withdraw_authority_key, - &deposit_info.stake_account_key, - &stake_to_receive_key, - &user_withdrawer_key, - &pool_token_receiver.key, - &pool_info.mint_key, - &TOKEN_PROGRAM_ID, - &stake_program_id(), - withdraw_amount, - ) - .unwrap(), - vec![ - &mut pool_info.pool_account, - &mut Account::default(), - &mut deposit_info.stake_account_account, - &mut stake_to_receive_account, - &mut Account::default(), - &mut pool_token_receiver.account, - &mut pool_info.mint_account, - &mut Account::default(), - &mut Account::default(), - &mut Account::default(), - ], - ) - .expect("Error on withdraw"); + pool_info, + user_withdrawer_key, + pool_token_receiver, + deposit_info, + } + } + #[test] + fn test_withdraw() { + let mut test_data = initialize_withdraw_test(); + let withdraw_info = do_withdraw(&mut test_data); - let fee_amount = stake_balance * pool_info.fee.numerator / pool_info.fee.denominator; + withdraw_info.result.expect("Fail on deposit"); + let fee_amount = test_data.stake_balance * FEE_DEFAULT.numerator / FEE_DEFAULT.denominator; - let user_token_state = SplAccount::unpack_from_slice(&pool_token_receiver.account.data) - .expect("User token account is not initialized after withdraw"); + let user_token_state = + SplAccount::unpack_from_slice(&test_data.pool_token_receiver.account.data) + .expect("User token account is not initialized after withdraw"); assert_eq!( user_token_state.amount, - stake_balance - fee_amount - withdraw_amount + test_data.stake_balance - fee_amount - test_data.withdraw_amount ); // Check stake pool token amounts - let state = State::deserialize(&pool_info.pool_account.data).unwrap(); + let state = State::deserialize(&test_data.pool_info.pool_account.data).unwrap(); assert!( - matches!(state, State::Init(stake_pool) if stake_pool.stake_total == stake_balance - withdraw_amount && stake_pool.pool_total == tokens_to_issue - tokens_to_burn) + matches!(state, State::Init(stake_pool) if stake_pool.stake_total == test_data.stake_balance - test_data.withdraw_amount && stake_pool.pool_total == test_data.tokens_to_issue - test_data.tokens_to_burn) ); } #[test] - fn test_claim() { + fn negative_test_withdraw_wrong_withdraw_authority() { + let mut test_data = initialize_withdraw_test(); + + test_data.pool_info.withdraw_authority_key = Pubkey::new_unique(); + + let withdraw_info = do_withdraw(&mut test_data); + + assert_eq!( + withdraw_info.result, + Err(Error::InvalidProgramAddress.into()) + ); + } + #[test] + fn negative_test_withdraw_all() { + let mut test_data = initialize_withdraw_test(); + + test_data.withdraw_amount = test_data.stake_balance; + + let withdraw_info = do_withdraw(&mut test_data); + + assert_eq!( + withdraw_info.result, + Err(Error::InvalidProgramAddress.into()) + ); + } + #[test] + fn negative_test_withdraw_excess_amount() { + let mut test_data = initialize_withdraw_test(); + + test_data.withdraw_amount *= 2; + + let withdraw_info = do_withdraw(&mut test_data); + + assert_eq!( + withdraw_info.result, + Err(Error::InvalidProgramAddress.into()) + ); + } + + fn initialize_claim_test() -> Claim { let mut pool_info = create_stake_pool_default(); let user_withdrawer_key = Pubkey::new_unique(); let stake_balance = sol_to_lamports(20.0); + let tokens_to_issue = 20_000_000_000; let mut pool_token_receiver = create_token_account( &TOKEN_PROGRAM_ID, &pool_info.mint_key, &mut pool_info.mint_account, ); - let mut deposit_info = do_deposit(&mut pool_info, stake_balance, &mut pool_token_receiver); + let deposit_info = do_deposit(&mut pool_info, stake_balance, &mut pool_token_receiver); // Need to deposit more to cover deposit fee - let fee_amount = stake_balance * pool_info.fee.numerator / pool_info.fee.denominator; - let extra_deposit = (fee_amount * pool_info.fee.denominator) - / (pool_info.fee.denominator - pool_info.fee.numerator); + let fee_amount = stake_balance * FEE_DEFAULT.numerator / FEE_DEFAULT.denominator; + let extra_deposit = (fee_amount * FEE_DEFAULT.denominator) + / (FEE_DEFAULT.denominator - FEE_DEFAULT.numerator); let _extra_deposit_info = do_deposit(&mut pool_info, extra_deposit, &mut pool_token_receiver); - approve_token( - &TOKEN_PROGRAM_ID, - &pool_token_receiver.key, - &mut pool_token_receiver.account, - &pool_info.withdraw_authority_key, - &pool_token_receiver.owner, - stake_balance, - ); + Claim { + tokens_to_issue, + allow_burn_to: pool_info.withdraw_authority_key, + pool_info, + user_withdrawer_key, + pool_token_receiver, + deposit_info, + } + } - let _result = do_process_instruction( + #[test] + fn test_claim() { + let mut test_data = initialize_claim_test(); + let claim_info = do_claim(&mut test_data); + + assert_eq!(claim_info.result, Ok(())); + + let user_token_state = + SplAccount::unpack_from_slice(&test_data.pool_token_receiver.account.data) + .expect("User token account is not initialized after withdraw"); + assert_eq!(user_token_state.amount, 0); + + // TODO: Check deposit_info.stake_account_account Withdrawer to change to user_withdrawer_key + } + #[test] + fn negative_test_claim_not_enough_approved() { + let mut test_data = initialize_claim_test(); + test_data.tokens_to_issue /= 2; // Approve less tokens for burning than required + let claim_info = do_claim(&mut test_data); + + assert_eq!(claim_info.result, Err(TokenError::InsufficientFunds.into())); + } + #[test] + fn negative_test_claim_approve_to_wrong_account() { + let mut test_data = initialize_claim_test(); + test_data.allow_burn_to = test_data.pool_info.deposit_authority_key; // Change token burn authority + let claim_info = do_claim(&mut test_data); + + assert_eq!(claim_info.result, Err(TokenError::OwnerMismatch.into())); + } + #[test] + fn negative_test_claim_twice() { + let mut test_data = initialize_claim_test(); + let claim_info = do_claim(&mut test_data); + + assert_eq!(claim_info.result, Ok(())); + + let result = do_process_instruction( claim( &STAKE_POOL_PROGRAM_ID, - &pool_info.pool_key, - &pool_info.withdraw_authority_key, - &deposit_info.stake_account_key, - &user_withdrawer_key, - &pool_token_receiver.key, - &pool_info.mint_key, + &test_data.pool_info.pool_key, + &test_data.pool_info.withdraw_authority_key, + &test_data.deposit_info.stake_account_key, + &test_data.user_withdrawer_key, + &test_data.pool_token_receiver.key, + &test_data.pool_info.mint_key, &TOKEN_PROGRAM_ID, &stake_program_id(), ) .unwrap(), vec![ - &mut pool_info.pool_account, + &mut test_data.pool_info.pool_account, &mut Account::default(), - &mut deposit_info.stake_account_account, + &mut test_data.deposit_info.stake_account_account, &mut Account::default(), - &mut pool_token_receiver.account, - &mut pool_info.mint_account, + &mut test_data.pool_token_receiver.account, + &mut test_data.pool_info.mint_account, &mut Account::default(), &mut Account::default(), &mut Account::default(), ], - ) - .expect("Error on claim"); - - let user_token_state = SplAccount::unpack_from_slice(&pool_token_receiver.account.data) - .expect("User token account is not initialized after withdraw"); - assert_eq!(user_token_state.amount, 0); + ); - // TODO: Check deposit_info.stake_account_account Withdrawer to change to user_withdrawer_key + assert_eq!(result, Err(Error::InvalidProgramAddress.into())); } + #[test] fn test_set_staking_authority() { let mut pool_info = create_stake_pool_default(); - let stake_balance: u64 = sol_to_lamports(10.0); + let stake_balance = sol_to_lamports(10.0); let stake_key = Pubkey::new_unique(); let mut stake_account = Account::new(stake_balance, STAKE_ACCOUNT_LEN, &stake_program_id()); - let new_authorithy_key = Pubkey::new_unique(); - let mut new_authorithy_account = + let new_authority_key = Pubkey::new_unique(); + let mut new_authority_account = Account::new(stake_balance, STAKE_ACCOUNT_LEN, &stake_program_id()); let _result = do_process_instruction( @@ -1251,7 +1506,7 @@ mod tests { &pool_info.owner_key, &pool_info.withdraw_authority_key, &stake_key, - &new_authorithy_key, + &new_authority_key, &stake_program_id(), ) .unwrap(), @@ -1260,13 +1515,82 @@ mod tests { &mut pool_info.owner_fee_account, &mut Account::default(), &mut stake_account, - &mut new_authorithy_account, + &mut new_authority_account, &mut Account::default(), &mut Account::default(), ], ) .expect("Error on set_owner"); } + #[test] + fn negative_test_set_staking_authority_owner() { + let mut pool_info = create_stake_pool_default(); + let stake_balance = sol_to_lamports(10.0); + + let stake_key = Pubkey::new_unique(); + let mut stake_account = Account::new(stake_balance, STAKE_ACCOUNT_LEN, &stake_program_id()); + let new_authority_key = Pubkey::new_unique(); + let mut new_authority_account = + Account::new(stake_balance, STAKE_ACCOUNT_LEN, &stake_program_id()); + + let result = do_process_instruction( + set_staking_authority( + &STAKE_POOL_PROGRAM_ID, + &pool_info.pool_key, + &Pubkey::new_unique(), + &pool_info.withdraw_authority_key, + &stake_key, + &new_authority_key, + &stake_program_id(), + ) + .unwrap(), + vec![ + &mut pool_info.pool_account, + &mut Account::default(), + &mut Account::default(), + &mut stake_account, + &mut new_authority_account, + &mut Account::default(), + &mut Account::default(), + ], + ); + + assert_eq!(result, Err(Error::InvalidInput.into())); + } + #[test] + fn negative_test_set_staking_authority_signer() { + let mut pool_info = create_stake_pool_default(); + let stake_balance = sol_to_lamports(10.0); + + let stake_key = Pubkey::new_unique(); + let mut stake_account = Account::new(stake_balance, STAKE_ACCOUNT_LEN, &stake_program_id()); + let new_authority_key = Pubkey::new_unique(); + let mut new_authority_account = + Account::new(stake_balance, STAKE_ACCOUNT_LEN, &stake_program_id()); + + let result = do_process_instruction( + set_staking_authority_without_signer( + &STAKE_POOL_PROGRAM_ID, + &pool_info.pool_key, + &Pubkey::new_unique(), + &pool_info.withdraw_authority_key, + &stake_key, + &new_authority_key, + &stake_program_id(), + ) + .unwrap(), + vec![ + &mut pool_info.pool_account, + &mut pool_info.owner_fee_account, + &mut Account::default(), + &mut stake_account, + &mut new_authority_account, + &mut Account::default(), + &mut Account::default(), + ], + ); + assert_eq!(result, Err(Error::InvalidInput.into())); + } #[test] fn test_set_owner() { @@ -1304,4 +1628,68 @@ mod tests { matches!(state, State::Init(stake_pool) if stake_pool.owner == new_owner_key && stake_pool.owner_fee_account == new_owner_fee.key) ); } + #[test] + fn negative_test_set_owner_owner() { + let mut pool_info = create_stake_pool_default(); + + let new_owner_key = Pubkey::new_unique(); + let mut new_owner_account = Account::default(); + + let mut new_owner_fee = create_token_account( + &TOKEN_PROGRAM_ID, + &pool_info.mint_key, + &mut pool_info.mint_account, + ); + + let result = do_process_instruction( + set_owner( + &STAKE_POOL_PROGRAM_ID, + &pool_info.pool_key, + &Pubkey::new_unique(), + &new_owner_key, + &new_owner_fee.key, + ) + .unwrap(), + vec![ + &mut pool_info.pool_account, + &mut Account::default(), + &mut new_owner_account, + &mut new_owner_fee.account, + ], + ); + + assert_eq!(result, Err(Error::InvalidInput.into())); + } + #[test] + fn negative_test_set_owner_signer() { + let mut pool_info = create_stake_pool_default(); + + let new_owner_key = Pubkey::new_unique(); + let mut new_owner_account = Account::default(); + + let mut new_owner_fee = create_token_account( + &TOKEN_PROGRAM_ID, + &pool_info.mint_key, + &mut pool_info.mint_account, + ); + + let result = do_process_instruction( + set_owner_without_signer( + &STAKE_POOL_PROGRAM_ID, + &pool_info.pool_key, + &pool_info.owner_key, + &new_owner_key, + &new_owner_fee.key, + ) + .unwrap(), + vec![ + &mut pool_info.pool_account, + &mut pool_info.owner_account, + &mut new_owner_account, + &mut new_owner_fee.account, + ], + ); + + assert_eq!(result, Err(Error::InvalidInput.into())); + } } From 7db4ac2a4d20bc5f704f4d1c4f2048468db1742a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 2 Dec 2020 12:54:42 +0000 Subject: [PATCH 0027/1076] Bump solana-program from 1.4.9 to 1.4.13 (#916) Bumps [solana-program](https://github.com/solana-labs/solana) from 1.4.9 to 1.4.13. - [Release notes](https://github.com/solana-labs/solana/releases) - [Changelog](https://github.com/solana-labs/solana/blob/master/RELEASE.md) - [Commits](https://github.com/solana-labs/solana/compare/v1.4.9...v1.4.13) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index dc55f709..a19c607b 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -17,7 +17,7 @@ solana-cli-config = "1.4.9" solana-client = "1.4.9" solana-logger = "1.4.9" solana-sdk = "1.4.9" -solana-program = "1.4.9" +solana-program = "1.4.13" spl-stake-pool = { path="../program", features = [ "no-entrypoint" ] } spl-token = { path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" diff --git a/program/Cargo.toml b/program/Cargo.toml index bf6219c1..189d0f80 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,7 +17,7 @@ num-traits = "0.2" num_enum = "0.5.1" serde = "1.0.117" serde_derive = "1.0.103" -solana-program = "1.4.9" +solana-program = "1.4.13" spl-token = { path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" From 49329f959d64ad88bd703e7b6c0aa80ab6bda981 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Wed, 25 Nov 2020 11:26:08 -0800 Subject: [PATCH 0028/1076] program-test now adds SPL Token automatically --- program/tests/functional.rs | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/program/tests/functional.rs b/program/tests/functional.rs index 3e5d2286..5833dfac 100644 --- a/program/tests/functional.rs +++ b/program/tests/functional.rs @@ -13,20 +13,11 @@ use bincode::deserialize; const TEST_STAKE_AMOUNT: u64 = 100; fn program_test() -> ProgramTest { - let mut pc = ProgramTest::new( + ProgramTest::new( "spl_stake_pool", id(), processor!(processor::Processor::process), - ); - - // Add SPL Token program - pc.add_program( - "spl_token", - spl_token::id(), - processor!(spl_token::processor::Processor::process), - ); - - pc + ) } async fn create_mint( From 55416c4e3906d9e0f2b1b2700738f54f11fa508f Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Wed, 2 Dec 2020 18:37:53 -0800 Subject: [PATCH 0029/1076] Upgrade to Solana v1.4.14 --- clients/cli/Cargo.toml | 14 +++++++------- program/Cargo.toml | 6 +++--- program/src/processor.rs | 42 ++++++++++++++++++++-------------------- 3 files changed, 31 insertions(+), 31 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index a19c607b..0faea543 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,13 +11,13 @@ version = "2.0.1" [dependencies] clap = "2.33.3" serde_json = "1.0.57" -solana-account-decoder = "1.4.9" -solana-clap-utils = "1.4.9" -solana-cli-config = "1.4.9" -solana-client = "1.4.9" -solana-logger = "1.4.9" -solana-sdk = "1.4.9" -solana-program = "1.4.13" +solana-account-decoder = "1.4.14" +solana-clap-utils = "1.4.14" +solana-cli-config = "1.4.14" +solana-client = "1.4.14" +solana-logger = "1.4.14" +solana-sdk = "1.4.14" +solana-program = "1.4.14" spl-stake-pool = { path="../program", features = [ "no-entrypoint" ] } spl-token = { path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" diff --git a/program/Cargo.toml b/program/Cargo.toml index 189d0f80..09a2d24d 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,14 +17,14 @@ num-traits = "0.2" num_enum = "0.5.1" serde = "1.0.117" serde_derive = "1.0.103" -solana-program = "1.4.13" +solana-program = "1.4.14" spl-token = { path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" [dev-dependencies] bincode = "1.3.1" -solana-program-test = "1.4.9" -solana-sdk = "1.4.9" +solana-program-test = "1.4.14" +solana-sdk = "1.4.14" tokio = { version = "0.3", features = ["macros"]} [lib] diff --git a/program/src/processor.rs b/program/src/processor.rs index e301bb24..966029cc 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -9,7 +9,7 @@ use crate::{ use num_traits::FromPrimitive; use solana_program::{ account_info::next_account_info, account_info::AccountInfo, decode_error::DecodeError, - entrypoint::ProgramResult, info, program::invoke_signed, program_error::PrintProgramError, + entrypoint::ProgramResult, msg, program::invoke_signed, program_error::PrintProgramError, program_error::ProgramError, program_pack::Pack, pubkey::Pubkey, }; use std::convert::TryFrom; @@ -582,27 +582,27 @@ impl Processor { let instruction = StakePoolInstruction::deserialize(input)?; match instruction { StakePoolInstruction::Initialize(init) => { - info!("Instruction: Init"); + msg!("Instruction: Init"); Self::process_initialize(program_id, init, accounts) } StakePoolInstruction::Deposit => { - info!("Instruction: Deposit"); + msg!("Instruction: Deposit"); Self::process_deposit(program_id, accounts) } StakePoolInstruction::Withdraw(amount) => { - info!("Instruction: Withdraw"); + msg!("Instruction: Withdraw"); Self::process_withdraw(program_id, amount, accounts) } StakePoolInstruction::Claim => { - info!("Instruction: Claim"); + msg!("Instruction: Claim"); Self::process_claim(program_id, accounts) } StakePoolInstruction::SetStakingAuthority => { - info!("Instruction: SetStakingAuthority"); + msg!("Instruction: SetStakingAuthority"); Self::process_set_staking_auth(program_id, accounts) } StakePoolInstruction::SetOwner => { - info!("Instruction: SetOwner"); + msg!("Instruction: SetOwner"); Self::process_set_owner(program_id, accounts) } } @@ -615,19 +615,19 @@ impl PrintProgramError for Error { E: 'static + std::error::Error + DecodeError + PrintProgramError + FromPrimitive, { match self { - Error::AlreadyInUse => info!("Error: AlreadyInUse"), - Error::InvalidProgramAddress => info!("Error: InvalidProgramAddress"), - Error::InvalidOwner => info!("Error: InvalidOwner"), - Error::ExpectedToken => info!("Error: ExpectedToken"), - Error::ExpectedAccount => info!("Error: ExpectedAccount"), - Error::InvalidSupply => info!("Error: InvalidSupply"), - Error::InvalidDelegate => info!("Error: InvalidDelegate"), - Error::InvalidState => info!("Error: InvalidState"), - Error::InvalidInput => info!("Error: InvalidInput"), - Error::InvalidOutput => info!("Error: InvalidOutput"), - Error::CalculationFailure => info!("Error: CalculationFailure"), - Error::FeeTooHigh => info!("Error: FeeTooHigh"), - Error::WrongAccountMint => info!("Error: WrongAccountMint"), + Error::AlreadyInUse => msg!("Error: AlreadyInUse"), + Error::InvalidProgramAddress => msg!("Error: InvalidProgramAddress"), + Error::InvalidOwner => msg!("Error: InvalidOwner"), + Error::ExpectedToken => msg!("Error: ExpectedToken"), + Error::ExpectedAccount => msg!("Error: ExpectedAccount"), + Error::InvalidSupply => msg!("Error: InvalidSupply"), + Error::InvalidDelegate => msg!("Error: InvalidDelegate"), + Error::InvalidState => msg!("Error: InvalidState"), + Error::InvalidInput => msg!("Error: InvalidInput"), + Error::InvalidOutput => msg!("Error: InvalidOutput"), + Error::CalculationFailure => msg!("Error: CalculationFailure"), + Error::FeeTooHigh => msg!("Error: FeeTooHigh"), + Error::WrongAccountMint => msg!("Error: WrongAccountMint"), } } } @@ -671,7 +671,7 @@ mod tests { account_infos: &[AccountInfo], signers_seeds: &[&[&[u8]]], ) -> ProgramResult { - info!("TestSyscallStubs::sol_invoke_signed()"); + msg!("TestSyscallStubs::sol_invoke_signed()"); let mut new_account_infos = vec![]; for meta in instruction.accounts.iter() { From b56add9ef8ecf5c9ad76c48b5f776cc65309c427 Mon Sep 17 00:00:00 2001 From: Yuriy Savchenko Date: Thu, 3 Dec 2020 12:11:56 +0200 Subject: [PATCH 0030/1076] Multi-account withdraw added the stake-pool CLI (#895) * Multi-account withdraw added the stake-pool CLI * Multi-account withdraw refactoring in stake-pool cli, added merge of multiple claim accounts * Fixed formatting * Added tests to stake pool CLI withdraw accounts selection * Formatting fixed * Clippy warnings fixed --- clients/cli/src/main.rs | 370 +++++++++++++++++++++++++++++---------- program/src/lib.rs | 2 +- program/src/processor.rs | 24 +++ 3 files changed, 300 insertions(+), 96 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index f06d9fb6..d79502a8 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -391,12 +391,100 @@ fn pool_tokens_to_stake_amount(pool_data: &StakePool, tokens: u64) -> u64 { .unwrap() as u64 } +#[derive(PartialEq, Debug)] +struct WithdrawAccount { + pubkey: Pubkey, + account: Account, + amount: u64, +} + +fn prepare_withdraw_accounts( + config: &Config, + pool_withdraw_authority: &Pubkey, + amount: u64, +) -> Result, Error> { + let mut accounts = get_authority_accounts(config, &pool_withdraw_authority); + if accounts.is_empty() { + return Err("No accounts found.".to_string().into()); + } + pick_withdraw_accounts(&mut accounts, amount) +} + +fn pick_withdraw_accounts( + accounts: &mut Vec<(Pubkey, Account)>, + amount: u64, +) -> Result, Error> { + // Sort from highest to lowest balance + accounts.sort_by(|a, b| b.1.lamports.cmp(&a.1.lamports)); + + // Prepare the list of accounts to withdraw from + let mut withdraw_from: Vec = vec![]; + let mut remaining_amount = amount; + + let mut split_candidate: Option = None; + + // If amount to withdraw is more than the largest account + // then use up all the large accounts first + // Then either find the smallest account with balance more than remaining + // or find account to claim with exactly the same balance as remaining + for (pubkey, account) in accounts { + if account.lamports <= remaining_amount { + if split_candidate.is_some() { + // If there is an active split candidate and current account is smaller than remaining + // then break to use split candidate + if account.lamports < remaining_amount { + break; + } + // Otherwise (account balance == remaining) procede with `claim` + } + // Those accounts will be withdrawn completely with `claim` instruction + withdraw_from.push(WithdrawAccount { + pubkey: *pubkey, + account: account.clone(), + amount: account.lamports, + }); + remaining_amount -= account.lamports; + if remaining_amount == 0 { + // We filled all the balance, ignore split candidate + split_candidate = None; + break; + } + } else { + // Save the last account with balance more than remaining as a candidate for split + split_candidate = Some(WithdrawAccount { + pubkey: *pubkey, + account: account.clone(), + amount: remaining_amount, + }); + } + } + + // If there is a pending account to split, add it to the list + if let Some(withdraw) = split_candidate { + remaining_amount -= withdraw.amount; + + // This account will be withdrawn partially (if remaining_amount < account.lamports), so we put it first + withdraw_from.insert(0, withdraw); + } + + // Not enough stake to withdraw the specified amount + if remaining_amount > 0 { + return Err(format!( + "No stake accounts found in this pool with enough balance to withdraw {} SOL.", + lamports_to_sol(amount) + ) + .into()); + } + + Ok(withdraw_from) +} + fn command_withdraw( config: &Config, pool: &Pubkey, amount: u64, burn_from: &Pubkey, - stake_receiver: &Option, + stake_receiver_param: &Option, ) -> CommandResult { // Get stake pool state let pool_data = config.rpc_client.get_account_data(&pool)?; @@ -433,131 +521,130 @@ fn command_withdraw( .into()); } - let mut accounts = get_authority_accounts(config, &pool_withdraw_authority); - if accounts.is_empty() { - return Err("No accounts found.".to_string().into()); - } - // Sort from lowest to highest balance - accounts.sort_by(|a, b| a.1.lamports.cmp(&b.1.lamports)); + // Get the list of accounts to withdraw from + let withdraw_from: Vec = + prepare_withdraw_accounts(config, &pool_withdraw_authority, amount)?; - for (stake_pubkey, account) in accounts { - if account.lamports < amount { - continue; - } - // Account found to claim or withdraw - println!("Withdrawing from account {}", stake_pubkey); + // Construct transaction to withdraw from withdraw_from account list + let mut instructions: Vec = vec![]; + let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()]; + let stake_receiver_account = Keypair::new(); // Will be added to signers if creating new account - let mut instructions: Vec = vec![]; - let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()]; + let mut total_rent_free_balances: u64 = 0; - let stake_receiver_account = Keypair::new(); + // Calculate amount of tokens to burn + let tokens_to_burn = stake_amount_to_pool_tokens(&pool_data, amount); - let mut total_rent_free_balances: u64 = 0; + instructions.push( + // Approve spending token + approve_token( + &spl_token::id(), + &burn_from, + &pool_withdraw_authority, + &config.owner.pubkey(), + &[], + tokens_to_burn, + )?, + ); - // Calculate amount of tokens to burn - let tokens_to_burn = stake_amount_to_pool_tokens(&pool_data, amount); + // Use separate mutable variable because withdraw might create a new account + let mut stake_receiver: Option = *stake_receiver_param; - instructions.push( - // Approve spending token - approve_token( - &spl_token::id(), - &burn_from, - &pool_withdraw_authority, - &config.owner.pubkey(), - &[], - tokens_to_burn, - )?, + // Go through prepared accounts and withdraw/claim them + for withdraw_stake in withdraw_from { + println!( + "Withdrawing from account {}, amount {} SOL", + withdraw_stake.pubkey, + lamports_to_sol(withdraw_stake.amount) ); - if amount == account.lamports { - // Claim to get whole account - instructions.push(claim( + if withdraw_stake.amount < withdraw_stake.account.lamports { + // Withdraw to split account + if stake_receiver.is_none() { + // Account for tokens not specified, creating one + println!( + "Creating account to receive stake {}", + stake_receiver_account.pubkey() + ); + + let stake_receiver_account_balance = config + .rpc_client + .get_minimum_balance_for_rent_exemption(STAKE_STATE_LEN)?; + + instructions.push( + // Creating new account + system_instruction::create_account( + &config.fee_payer.pubkey(), + &stake_receiver_account.pubkey(), + stake_receiver_account_balance, + STAKE_STATE_LEN as u64, + &stake_program_id(), + ), + ); + + signers.push(&stake_receiver_account); + + total_rent_free_balances += stake_receiver_account_balance; + + stake_receiver = Some(stake_receiver_account.pubkey()); + } + + instructions.push(withdraw( &spl_stake_pool::id(), &pool, &pool_withdraw_authority, - &stake_pubkey, + &withdraw_stake.pubkey, + &stake_receiver.unwrap(), // Cannot be none at this point &config.owner.pubkey(), &burn_from, &pool_data.pool_mint, &spl_token::id(), &stake_program_id(), + withdraw_stake.amount, )?); - // Merge into stake_receiver (if present) - if let Some(merge_into) = stake_receiver { - instructions.push(merge_stake( - &merge_into, - &stake_pubkey, - &config.owner.pubkey(), - )); - } } else { - // Withdraw to split account - let stake_receiver: Pubkey = match stake_receiver { - Some(value) => *value, - None => { - // Account for tokens not specified, creating one - println!( - "Creating account to receive stake {}", - stake_receiver_account.pubkey() - ); - - let stake_receiver_account_balance = config - .rpc_client - .get_minimum_balance_for_rent_exemption(STAKE_STATE_LEN)?; - - instructions.push( - // Creating new account - system_instruction::create_account( - &config.fee_payer.pubkey(), - &stake_receiver_account.pubkey(), - stake_receiver_account_balance, - STAKE_STATE_LEN as u64, - &stake_program_id(), - ), - ); - - signers.push(&stake_receiver_account); - - total_rent_free_balances += stake_receiver_account_balance; - - stake_receiver_account.pubkey() - } - }; - - instructions.push(withdraw( + // Claim to get whole account + instructions.push(claim( &spl_stake_pool::id(), &pool, &pool_withdraw_authority, - &stake_pubkey, - &stake_receiver, + &withdraw_stake.pubkey, &config.owner.pubkey(), &burn_from, &pool_data.pool_mint, &spl_token::id(), &stake_program_id(), - amount, )?); - } - let mut transaction = - Transaction::new_with_payer(&instructions, Some(&config.fee_payer.pubkey())); + match stake_receiver { + Some(merge_into) => { + // Merge into stake_receiver + instructions.push(merge_stake( + &merge_into, + &withdraw_stake.pubkey, + &config.owner.pubkey(), + )); + } + None => { + // Save last account to merge into for the next claim + stake_receiver = Some(withdraw_stake.pubkey); + } + } + } + } - let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_fee_payer_balance( - config, - total_rent_free_balances + fee_calculator.calculate_fee(&transaction.message()), - )?; - unique_signers!(signers); - transaction.sign(&signers, recent_blockhash); + let mut transaction = + Transaction::new_with_payer(&instructions, Some(&config.fee_payer.pubkey())); - return Ok(Some(transaction)); - } + let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + check_fee_payer_balance( + config, + total_rent_free_balances + fee_calculator.calculate_fee(&transaction.message()), + )?; + unique_signers!(signers); + transaction.sign(&signers, recent_blockhash); - Err(format!( - "No stake accounts found in this pool with enough balance to withdraw {} SOL.", - lamports_to_sol(amount) - ) - .into()) + Ok(Some(transaction)) } fn command_set_staking_auth( @@ -985,3 +1072,96 @@ fn main() { exit(1); }); } + +#[cfg(test)] +mod tests { + use super::*; + + const PK_OWNER: Pubkey = Pubkey::new_from_array([0xff; 32]); + + fn lamports_to_accounts(lamports: &[u64]) -> Vec<(Pubkey, Account)> { + let mut result: Vec<(Pubkey, Account)> = Vec::with_capacity(lamports.len()); + + for (index, balance) in lamports.iter().enumerate() { + result.push(( + Pubkey::new_from_array([index as u8; 32]), + Account::new(*balance, 0, &PK_OWNER), + )); + } + result + } + + fn pick_with_balance( + test_list: &[(Pubkey, Account)], + balance: u64, + withdraw: u64, + ) -> WithdrawAccount { + for (pubkey, account) in test_list { + if account.lamports == balance { + return WithdrawAccount { + pubkey: *pubkey, + account: account.clone(), + amount: withdraw, + }; + } + } + + panic!(); + } + + #[test] + fn test_pick_withdraw_accounts() { + let mut test_list = lamports_to_accounts(&[2, 7, 8, 5, 3, 10]); + assert_eq!( + pick_withdraw_accounts(&mut test_list, 5).unwrap(), + vec![pick_with_balance(&test_list, 5, 5),] + ); + + let mut test_list = lamports_to_accounts(&[2, 7, 8, 5, 3, 10]); + assert_eq!( + pick_withdraw_accounts(&mut test_list, 13).unwrap(), + vec![ + pick_with_balance(&test_list, 10, 10), + pick_with_balance(&test_list, 3, 3), + ] + ); + + let mut test_list = lamports_to_accounts(&[2, 7, 8, 5, 3, 10]); + assert_eq!( + pick_withdraw_accounts(&mut test_list, 14).unwrap(), + vec![ + pick_with_balance(&test_list, 5, 4), // Partial should always be the first + pick_with_balance(&test_list, 10, 10), + ] + ); + + let mut test_list = lamports_to_accounts(&[2, 7, 8, 5, 3, 10]); + assert_eq!( + pick_withdraw_accounts(&mut test_list, 19).unwrap(), + vec![ + pick_with_balance(&test_list, 2, 1), // Partial should always be the first + pick_with_balance(&test_list, 10, 10), + pick_with_balance(&test_list, 8, 8), + ] + ); + + let mut test_list = lamports_to_accounts(&[5, 4, 3]); + assert_eq!( + pick_withdraw_accounts(&mut test_list, 1).unwrap(), + vec![pick_with_balance(&test_list, 3, 1),] + ); + + let mut test_list = lamports_to_accounts(&[5, 3, 4]); + assert_eq!( + pick_withdraw_accounts(&mut test_list, 12).unwrap(), + vec![ + pick_with_balance(&test_list, 5, 5), + pick_with_balance(&test_list, 4, 4), + pick_with_balance(&test_list, 3, 3), + ] + ); + + let mut test_list = lamports_to_accounts(&[5, 3, 4]); + assert!(pick_withdraw_accounts(&mut test_list, 13).err().is_some()); + } +} diff --git a/program/src/lib.rs b/program/src/lib.rs index b1233b96..c97b7018 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -14,4 +14,4 @@ pub mod entrypoint; // Export current sdk types for downstream users building with a different sdk version pub use solana_program; -solana_program::declare_id!("AYyuDZeEKcDDyqRHgM6iba7ui2Dkc9ENUpUhfMd58N8e"); +solana_program::declare_id!("3T92SNpyV3ipDm1VeR4SZxsUVtRT3sBJMhynJ8hwLc8G"); diff --git a/program/src/processor.rs b/program/src/processor.rs index 966029cc..05581b47 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -410,6 +410,18 @@ impl Processor { stake_program_info.clone(), )?; + Self::stake_authorize( + stake_pool_info.key, + stake_split_to.clone(), + withdraw_info.clone(), + Self::AUTHORITY_WITHDRAW, + stake_pool.withdraw_bump_seed, + user_stake_authority.key, + stake::StakeAuthorize::Staker, + reserved.clone(), + stake_program_info.clone(), + )?; + Self::token_burn( stake_pool_info.key, token_program_info.clone(), @@ -482,6 +494,18 @@ impl Processor { stake_program_info.clone(), )?; + Self::stake_authorize( + stake_pool_info.key, + stake_to_claim.clone(), + withdraw_info.clone(), + Self::AUTHORITY_WITHDRAW, + stake_pool.withdraw_bump_seed, + user_stake_authority.key, + stake::StakeAuthorize::Staker, + reserved.clone(), + stake_program_info.clone(), + )?; + Self::token_burn( stake_pool_info.key, token_program_info.clone(), From bd8aff0ee198aae934fc802840e30ed08f938b2e Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Thu, 17 Dec 2020 16:11:56 -0800 Subject: [PATCH 0031/1076] Update to Solana 1.5.0 --- clients/cli/Cargo.toml | 14 +++++++------- program/Cargo.toml | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 0faea543..b22a6157 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,13 +11,13 @@ version = "2.0.1" [dependencies] clap = "2.33.3" serde_json = "1.0.57" -solana-account-decoder = "1.4.14" -solana-clap-utils = "1.4.14" -solana-cli-config = "1.4.14" -solana-client = "1.4.14" -solana-logger = "1.4.14" -solana-sdk = "1.4.14" -solana-program = "1.4.14" +solana-account-decoder = "1.5.0" +solana-clap-utils = "1.5.0" +solana-cli-config = "1.5.0" +solana-client = "1.5.0" +solana-logger = "1.5.0" +solana-sdk = "1.5.0" +solana-program = "1.5.0" spl-stake-pool = { path="../program", features = [ "no-entrypoint" ] } spl-token = { path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" diff --git a/program/Cargo.toml b/program/Cargo.toml index 09a2d24d..999d4f5f 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,14 +17,14 @@ num-traits = "0.2" num_enum = "0.5.1" serde = "1.0.117" serde_derive = "1.0.103" -solana-program = "1.4.14" +solana-program = "1.5.0" spl-token = { path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" [dev-dependencies] bincode = "1.3.1" -solana-program-test = "1.4.14" -solana-sdk = "1.4.14" +solana-program-test = "1.5.0" +solana-sdk = "1.5.0" tokio = { version = "0.3", features = ["macros"]} [lib] From 6e377d7e444dad7c1a67b846e1a100cef45a4cf1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Jan 2021 01:33:47 +0000 Subject: [PATCH 0032/1076] Bump serde_json from 1.0.59 to 1.0.61 (#983) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.59 to 1.0.61. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.59...v1.0.61) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index b22a6157..4ce3162a 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -10,7 +10,7 @@ version = "2.0.1" [dependencies] clap = "2.33.3" -serde_json = "1.0.57" +serde_json = "1.0.61" solana-account-decoder = "1.5.0" solana-clap-utils = "1.5.0" solana-cli-config = "1.5.0" From 112c86c4011d9d8ca9cc4a26ababae53ea15a48b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Jan 2021 12:39:08 +0000 Subject: [PATCH 0033/1076] build(deps): bump solana-cli-config from 1.5.0 to 1.5.1 (#1023) Bumps [solana-cli-config](https://github.com/solana-labs/solana) from 1.5.0 to 1.5.1. - [Release notes](https://github.com/solana-labs/solana/releases) - [Changelog](https://github.com/solana-labs/solana/blob/master/RELEASE.md) - [Commits](https://github.com/solana-labs/solana/compare/v1.5.0...v1.5.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 4ce3162a..80d449b6 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ clap = "2.33.3" serde_json = "1.0.61" solana-account-decoder = "1.5.0" solana-clap-utils = "1.5.0" -solana-cli-config = "1.5.0" +solana-cli-config = "1.5.1" solana-client = "1.5.0" solana-logger = "1.5.0" solana-sdk = "1.5.0" From 58c3fe148f5220851656785f79ba2402119a8c88 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Jan 2021 13:51:29 +0000 Subject: [PATCH 0034/1076] build(deps): bump solana-program from 1.5.0 to 1.5.1 (#1025) Bumps [solana-program](https://github.com/solana-labs/solana) from 1.5.0 to 1.5.1. - [Release notes](https://github.com/solana-labs/solana/releases) - [Changelog](https://github.com/solana-labs/solana/blob/master/RELEASE.md) - [Commits](https://github.com/solana-labs/solana/compare/v1.5.0...v1.5.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 80d449b6..48910116 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -17,7 +17,7 @@ solana-cli-config = "1.5.1" solana-client = "1.5.0" solana-logger = "1.5.0" solana-sdk = "1.5.0" -solana-program = "1.5.0" +solana-program = "1.5.1" spl-stake-pool = { path="../program", features = [ "no-entrypoint" ] } spl-token = { path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" diff --git a/program/Cargo.toml b/program/Cargo.toml index 999d4f5f..95a5c391 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,7 +17,7 @@ num-traits = "0.2" num_enum = "0.5.1" serde = "1.0.117" serde_derive = "1.0.103" -solana-program = "1.5.0" +solana-program = "1.5.1" spl-token = { path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" From 6f5dbdbd1c75be60edb8c70a81573083bee59f0d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Jan 2021 08:55:02 +0800 Subject: [PATCH 0035/1076] Bump serde from 1.0.117 to 1.0.118 (#1004) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.117 to 1.0.118. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.117...v1.0.118) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 95a5c391..f97c0469 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -15,7 +15,7 @@ arrayref = "0.3.6" num-derive = "0.3" num-traits = "0.2" num_enum = "0.5.1" -serde = "1.0.117" +serde = "1.0.118" serde_derive = "1.0.103" solana-program = "1.5.1" spl-token = { path = "../../token/program", features = [ "no-entrypoint" ] } From 88faaf387ad87baf5d0672ec4dce86e3e76a39e6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Jan 2021 01:32:56 +0000 Subject: [PATCH 0036/1076] build(deps): bump solana-cli-config from 1.5.1 to 1.5.2 (#1051) Bumps [solana-cli-config](https://github.com/solana-labs/solana) from 1.5.1 to 1.5.2. - [Release notes](https://github.com/solana-labs/solana/releases) - [Changelog](https://github.com/solana-labs/solana/blob/master/RELEASE.md) - [Commits](https://github.com/solana-labs/solana/compare/v1.5.1...v1.5.2) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 48910116..51df993b 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ clap = "2.33.3" serde_json = "1.0.61" solana-account-decoder = "1.5.0" solana-clap-utils = "1.5.0" -solana-cli-config = "1.5.1" +solana-cli-config = "1.5.2" solana-client = "1.5.0" solana-logger = "1.5.0" solana-sdk = "1.5.0" From 46d6844cf5884db6f26d830d36aa6d9c48f5c82f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Jan 2021 12:36:43 +0000 Subject: [PATCH 0037/1076] build(deps): bump solana-logger from 1.5.1 to 1.5.3 (#1066) Bumps [solana-logger](https://github.com/solana-labs/solana) from 1.5.1 to 1.5.3. - [Release notes](https://github.com/solana-labs/solana/releases) - [Changelog](https://github.com/solana-labs/solana/blob/master/RELEASE.md) - [Commits](https://github.com/solana-labs/solana/compare/v1.5.1...v1.5.3) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 51df993b..0656331d 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -15,7 +15,7 @@ solana-account-decoder = "1.5.0" solana-clap-utils = "1.5.0" solana-cli-config = "1.5.2" solana-client = "1.5.0" -solana-logger = "1.5.0" +solana-logger = "1.5.3" solana-sdk = "1.5.0" solana-program = "1.5.1" spl-stake-pool = { path="../program", features = [ "no-entrypoint" ] } From b0520f6fd20f23ca56a9d3aaf1781b4157f4b3be Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 21 Jan 2021 14:48:46 +0100 Subject: [PATCH 0038/1076] Stake pool: adding pool balance confirmation (Redo of #960) (#1116) * Added validator stake account list storage, deprecated old tests * Added join and leave stake pool instructions, error messages refactoring * Stake pool tests refactoring, tests for join and leave pool added * Added validator stake account creation instruction, join/leave pool instructions renamed, version field added * Formatting fixes * Added update list/pool instructions (no tests yet), updated deposit instruction logic, claim instruction removed, refactoring * Updated deposit logic and tests, updated withdraw logic and added tests, refactoring * Stake pool CLI updated to work with new deposit/withdraw instructions, claim usage removed * Added validator stake account management and balance update commands to the stake pool CLI, updated dependency versions, updated devnet program address * Merge conflicts fixed * Removed deprecated tests * Fixes for review comments * Additional program id checks across the code * Formatting errors fixed * Changed minimum stake balance in CLI, removed deprecated tests, removed check for stake history id * Added TODO for stake account warmup status check * Cargo.lock conflict fix * Formatting fixed * Update Cargo lock file for CI * Pin themis version of subtle Co-authored-by: Yuriy Savchenko --- clients/cli/Cargo.toml | 10 +- clients/cli/src/main.rs | 769 +++++++--- program/Cargo.toml | 6 +- program/src/entrypoint.rs | 4 +- program/src/error.rs | 68 +- program/src/instruction.rs | 321 +++- program/src/lib.rs | 5 +- program/src/processor.rs | 2102 ++++++++++---------------- program/src/stake.rs | 22 +- program/src/state.rs | 280 +++- program/tests/deposit.rs | 145 ++ program/tests/functional.rs | 347 ----- program/tests/helpers/mod.rs | 732 +++++++++ program/tests/initialize.rs | 31 + program/tests/update_list_balance.rs | 79 + program/tests/update_pool_balance.rs | 16 + program/tests/vsa_add.rs | 104 ++ program/tests/vsa_create.rs | 62 + program/tests/vsa_remove.rs | 106 ++ program/tests/withdraw.rs | 153 ++ 20 files changed, 3378 insertions(+), 1984 deletions(-) create mode 100644 program/tests/deposit.rs delete mode 100644 program/tests/functional.rs create mode 100644 program/tests/helpers/mod.rs create mode 100644 program/tests/initialize.rs create mode 100644 program/tests/update_list_balance.rs create mode 100644 program/tests/update_pool_balance.rs create mode 100644 program/tests/vsa_add.rs create mode 100644 program/tests/vsa_create.rs create mode 100644 program/tests/vsa_remove.rs create mode 100644 program/tests/withdraw.rs diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 0656331d..3b97bae2 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,16 +11,18 @@ version = "2.0.1" [dependencies] clap = "2.33.3" serde_json = "1.0.61" -solana-account-decoder = "1.5.0" -solana-clap-utils = "1.5.0" -solana-cli-config = "1.5.2" -solana-client = "1.5.0" +solana-account-decoder = "1.5.3" +solana-clap-utils = "1.5.3" +solana-cli-config = "1.5.3" +solana-client = "1.5.3" solana-logger = "1.5.3" solana-sdk = "1.5.0" solana-program = "1.5.1" spl-stake-pool = { path="../program", features = [ "no-entrypoint" ] } spl-token = { path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" +bincode = "1.3.1" +lazy_static = "1.4.0" [[bin]] name = "spl-stake-pool" diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index d79502a8..f394ac58 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -1,3 +1,6 @@ +#[macro_use] +extern crate lazy_static; +use bincode::deserialize; use clap::{ crate_description, crate_name, crate_version, value_t, value_t_or_exit, App, AppSettings, Arg, ArgGroup, SubCommand, @@ -25,16 +28,19 @@ use solana_sdk::{ }; use spl_stake_pool::{ instruction::{ - claim, deposit, initialize as initialize_pool, set_owner, set_staking_authority, withdraw, - Fee as PoolFee, InitArgs as PoolInitArgs, + add_validator_stake_account, create_validator_stake_account, deposit, + initialize as initialize_pool, remove_validator_stake_account, set_owner, + set_staking_authority, update_list_balance, update_pool_balance, withdraw, Fee as PoolFee, + InitArgs as PoolInitArgs, }, processor::Processor as PoolProcessor, stake::authorize as authorize_stake, stake::id as stake_program_id, - stake::merge as merge_stake, stake::StakeAuthorize, + stake::StakeState, state::StakePool, state::State as PoolState, + state::ValidatorStakeList, }; use spl_token::{ self, instruction::approve as approve_token, instruction::initialize_account, @@ -55,6 +61,10 @@ type Error = Box; type CommandResult = Result, Error>; const STAKE_STATE_LEN: usize = 200; +const MAX_ACCOUNTS_TO_UPDATE: usize = 10; +lazy_static! { + static ref MIN_STAKE_BALANCE: u64 = sol_to_lamports(1.0); +} macro_rules! unique_signers { ($vec:ident) => { @@ -128,6 +138,8 @@ fn command_create_pool(config: &Config, fee: PoolFee) -> CommandResult { let pool_account = Keypair::new(); println!("Creating stake pool {}", pool_account.pubkey()); + let validator_stake_list = Keypair::new(); + let mint_account_balance = config .rpc_client .get_minimum_balance_for_rent_exemption(TokenMint::LEN)?; @@ -137,8 +149,13 @@ fn command_create_pool(config: &Config, fee: PoolFee) -> CommandResult { let pool_account_balance = config .rpc_client .get_minimum_balance_for_rent_exemption(PoolState::LEN)?; - let total_rent_free_balances = - mint_account_balance + pool_fee_account_balance + pool_account_balance; + let validator_stake_list_balance = config + .rpc_client + .get_minimum_balance_for_rent_exemption(ValidatorStakeList::LEN)?; + let total_rent_free_balances = mint_account_balance + + pool_fee_account_balance + + pool_account_balance + + validator_stake_list_balance; let default_decimals = native_mint::DECIMALS; @@ -179,6 +196,14 @@ fn command_create_pool(config: &Config, fee: PoolFee) -> CommandResult { PoolState::LEN as u64, &spl_stake_pool::id(), ), + // Validator stake account list storage + system_instruction::create_account( + &config.fee_payer.pubkey(), + &validator_stake_list.pubkey(), + validator_stake_list_balance, + ValidatorStakeList::LEN as u64, + &spl_stake_pool::id(), + ), // Initialize pool token mint account initialize_mint( &spl_token::id(), @@ -199,6 +224,7 @@ fn command_create_pool(config: &Config, fee: PoolFee) -> CommandResult { &spl_stake_pool::id(), &pool_account.pubkey(), &config.owner.pubkey(), + &validator_stake_list.pubkey(), &mint_account.pubkey(), &pool_fee_account.pubkey(), &spl_token::id(), @@ -216,6 +242,7 @@ fn command_create_pool(config: &Config, fee: PoolFee) -> CommandResult { let mut signers = vec![ config.fee_payer.as_ref(), &pool_account, + &validator_stake_list, &mint_account, &pool_fee_account, ]; @@ -224,7 +251,37 @@ fn command_create_pool(config: &Config, fee: PoolFee) -> CommandResult { Ok(Some(transaction)) } -fn command_deposit( +fn command_vsa_create(config: &Config, pool: &Pubkey, validator: &Pubkey) -> CommandResult { + let (stake_account, _) = + PoolProcessor::find_stake_address_for_validator(&spl_stake_pool::id(), &validator, &pool); + + println!("Creating stake account {}", stake_account); + + let mut transaction = Transaction::new_with_payer( + &[ + // Create new validator stake account address + create_validator_stake_account( + &spl_stake_pool::id(), + &pool, + &config.fee_payer.pubkey(), + &stake_account, + &validator, + &config.owner.pubkey(), + &config.owner.pubkey(), + &solana_program::system_program::id(), + &stake_program_id(), + )?, + ], + Some(&config.fee_payer.pubkey()), + ); + + let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; + transaction.sign(&[config.fee_payer.as_ref()], recent_blockhash); + Ok(Some(transaction)) +} + +fn command_vsa_add( config: &Config, pool: &Pubkey, stake: &Pubkey, @@ -237,23 +294,187 @@ fn command_deposit( .stake_pool() .unwrap(); + let mut total_rent_free_balances: u64 = 0; + + let token_receiver_account = Keypair::new(); + let mut instructions: Vec = vec![]; let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()]; - let mut total_rent_free_balances: u64 = 0; + // Create token account if not specified + let token_receiver = unwrap_create_token_account( + &config, + &token_receiver, + &token_receiver_account, + &pool_data.pool_mint, + &mut instructions, + |balance| { + signers.push(&token_receiver_account); + total_rent_free_balances += balance; + }, + )?; - let token_receiver_account = Keypair::new(); + // Calculate Deposit and Withdraw stake pool authorities + let pool_deposit_authority: Pubkey = PoolProcessor::authority_id( + &spl_stake_pool::id(), + pool, + PoolProcessor::AUTHORITY_DEPOSIT, + pool_data.deposit_bump_seed, + ) + .unwrap(); + let pool_withdraw_authority: Pubkey = PoolProcessor::authority_id( + &spl_stake_pool::id(), + pool, + PoolProcessor::AUTHORITY_WITHDRAW, + pool_data.withdraw_bump_seed, + ) + .unwrap(); + + instructions.extend(vec![ + // Set Withdrawer on stake account to Deposit authority of the stake pool + authorize_stake( + &stake, + &config.owner.pubkey(), + &pool_deposit_authority, + StakeAuthorize::Withdrawer, + ), + // Set Staker on stake account to Deposit authority of the stake pool + authorize_stake( + &stake, + &config.owner.pubkey(), + &pool_deposit_authority, + StakeAuthorize::Staker, + ), + // Add validator stake account to the pool + add_validator_stake_account( + &spl_stake_pool::id(), + &pool, + &config.owner.pubkey(), + &pool_deposit_authority, + &pool_withdraw_authority, + &pool_data.validator_stake_list, + &stake, + &token_receiver, + &pool_data.pool_mint, + &spl_token::id(), + &stake_program_id(), + )?, + ]); + + let mut transaction = + Transaction::new_with_payer(&instructions, Some(&config.fee_payer.pubkey())); + + let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + check_fee_payer_balance( + config, + total_rent_free_balances + fee_calculator.calculate_fee(&transaction.message()), + )?; + unique_signers!(signers); + transaction.sign(&signers, recent_blockhash); + Ok(Some(transaction)) +} + +fn command_vsa_remove( + config: &Config, + pool: &Pubkey, + stake: &Pubkey, + burn_from: &Pubkey, + new_authority: &Option, +) -> CommandResult { + // Get stake pool state + let pool_data = config.rpc_client.get_account_data(&pool)?; + let pool_data: StakePool = PoolState::deserialize(pool_data.as_slice()) + .unwrap() + .stake_pool() + .unwrap(); + + let pool_withdraw_authority: Pubkey = PoolProcessor::authority_id( + &spl_stake_pool::id(), + pool, + PoolProcessor::AUTHORITY_WITHDRAW, + pool_data.withdraw_bump_seed, + ) + .unwrap(); + + let owner_pubkey = config.owner.pubkey(); + let new_authority = new_authority.as_ref().unwrap_or(&owner_pubkey); + + // Calculate amount of tokens to burn + let stake_account = config.rpc_client.get_account(&stake)?; + let tokens_to_burn = stake_amount_to_pool_tokens(&pool_data, stake_account.lamports); + + // Check balance and mint + let account_data = config.rpc_client.get_account_data(&burn_from)?; + let account_data: TokenAccount = + TokenAccount::unpack_from_slice(account_data.as_slice()).unwrap(); - let token_receiver: Pubkey = match token_receiver { + if account_data.mint != pool_data.pool_mint { + return Err("Wrong token account.".into()); + } + + if account_data.amount < tokens_to_burn { + return Err(format!( + "Not enough balance to burn to remove validator stake account from the pool. {} pool tokens needed.", + lamports_to_sol(tokens_to_burn) + ).into()); + } + + let mut transaction = Transaction::new_with_payer( + &[ + // Approve spending token + approve_token( + &spl_token::id(), + &burn_from, + &pool_withdraw_authority, + &config.owner.pubkey(), + &[], + tokens_to_burn, + )?, + // Create new validator stake account address + remove_validator_stake_account( + &spl_stake_pool::id(), + &pool, + &config.owner.pubkey(), + &pool_withdraw_authority, + &new_authority, + &pool_data.validator_stake_list, + &stake, + &burn_from, + &pool_data.pool_mint, + &spl_token::id(), + &stake_program_id(), + )?, + ], + Some(&config.fee_payer.pubkey()), + ); + + let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; + transaction.sign( + &[config.fee_payer.as_ref(), config.owner.as_ref()], + recent_blockhash, + ); + Ok(Some(transaction)) +} + +fn unwrap_create_token_account( + config: &Config, + token_optional: &Option, + keypair: &Keypair, + mint: &Pubkey, + instructions: &mut Vec, + handler: F, +) -> Result +where + F: FnOnce(u64), +{ + let result = match token_optional { Some(value) => *value, None => { // Account for tokens not specified, creating one - println!( - "Creating account to receive tokens {}", - token_receiver_account.pubkey() - ); + println!("Creating account to receive tokens {}", keypair.pubkey()); - let token_receiver_account_balance = config + let min_account_balance = config .rpc_client .get_minimum_balance_for_rent_exemption(TokenAccount::LEN)?; @@ -261,27 +482,83 @@ fn command_deposit( // Creating new account system_instruction::create_account( &config.fee_payer.pubkey(), - &token_receiver_account.pubkey(), - token_receiver_account_balance, + &keypair.pubkey(), + min_account_balance, TokenAccount::LEN as u64, &spl_token::id(), ), // Initialize token receiver account initialize_account( &spl_token::id(), - &token_receiver_account.pubkey(), - &pool_data.pool_mint, + &keypair.pubkey(), + mint, &config.owner.pubkey(), )?, ]); - signers.push(&token_receiver_account); - - total_rent_free_balances += token_receiver_account_balance; + handler(min_account_balance); - token_receiver_account.pubkey() + keypair.pubkey() } }; + Ok(result) +} + +fn command_deposit( + config: &Config, + pool: &Pubkey, + stake: &Pubkey, + token_receiver: &Option, +) -> CommandResult { + // Get stake pool state + let pool_data = config.rpc_client.get_account_data(&pool)?; + let pool_data: StakePool = PoolState::deserialize(pool_data.as_slice()) + .unwrap() + .stake_pool() + .unwrap(); + + // Get stake account data + let stake_data = config.rpc_client.get_account_data(&stake)?; + let stake_data: StakeState = + deserialize(stake_data.as_slice()).or(Err("Invalid stake account data"))?; + let validator: Pubkey = match stake_data { + StakeState::Stake(_, stake) => Ok(stake.delegation.voter_pubkey), + _ => Err("Wrong stake account state, must be delegated to validator"), + }?; + + // Check if this validator has staking account in the pool + let validator_stake_list_data = config + .rpc_client + .get_account_data(&pool_data.validator_stake_list)?; + let validator_stake_list_data = + ValidatorStakeList::deserialize(&validator_stake_list_data.as_slice())?; + if !validator_stake_list_data.contains(&validator) { + return Err("Stake account for this validator does not exist in the pool.".into()); + } + + // Calculate validator stake account address linked to the pool + let (validator_stake_account, _) = + PoolProcessor::find_stake_address_for_validator(&spl_stake_pool::id(), &validator, pool); + + let mut instructions: Vec = vec![]; + let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()]; + + let mut total_rent_free_balances: u64 = 0; + + let token_receiver_account = Keypair::new(); + + // Create token account if not specified + let token_receiver = unwrap_create_token_account( + &config, + &token_receiver, + &token_receiver_account, + &pool_data.pool_mint, + &mut instructions, + |balance| { + signers.push(&token_receiver_account); + total_rent_free_balances += balance; + }, + )?; // Calculate Deposit and Withdraw stake pool authorities let pool_deposit_authority: Pubkey = PoolProcessor::authority_id( @@ -318,9 +595,11 @@ fn command_deposit( deposit( &spl_stake_pool::id(), &pool, + &pool_data.validator_stake_list, &pool_deposit_authority, &pool_withdraw_authority, &stake, + &validator_stake_account, &token_receiver, &pool_data.owner_fee_account, &pool_data.pool_mint, @@ -375,6 +654,63 @@ fn command_list(config: &Config, pool: &Pubkey) -> CommandResult { Ok(None) } +fn command_update(config: &Config, pool: &Pubkey) -> CommandResult { + // Get stake pool state + let pool_data = config.rpc_client.get_account_data(&pool)?; + let pool_data: StakePool = PoolState::deserialize(pool_data.as_slice()) + .unwrap() + .stake_pool() + .unwrap(); + let validator_stake_list_data = config + .rpc_client + .get_account_data(&pool_data.validator_stake_list)?; + let validator_stake_list_data = + ValidatorStakeList::deserialize(&validator_stake_list_data.as_slice())?; + + let epoch_info = config.rpc_client.get_epoch_info()?; + + let accounts_to_update: Vec<&Pubkey> = validator_stake_list_data + .validators + .iter() + .filter_map(|item| { + if item.last_update_epoch >= epoch_info.epoch { + None + } else { + Some(&item.validator_account) + } + }) + .collect(); + + let mut instructions: Vec = vec![]; + + for chunk in accounts_to_update.chunks(MAX_ACCOUNTS_TO_UPDATE) { + instructions.push(update_list_balance( + &spl_stake_pool::id(), + &pool_data.validator_stake_list, + &chunk, + )?); + } + + if instructions.is_empty() { + println!("Stake pool balances are up to date, no update required."); + Ok(None) + } else { + instructions.push(update_pool_balance( + &spl_stake_pool::id(), + pool, + &pool_data.validator_stake_list, + )?); + + let mut transaction = + Transaction::new_with_payer(&instructions, Some(&config.fee_payer.pubkey())); + + let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; + transaction.sign(&[config.fee_payer.as_ref()], recent_blockhash); + Ok(Some(transaction)) + } +} + fn stake_amount_to_pool_tokens(pool_data: &StakePool, amount: u64) -> u64 { (amount as u128) .checked_mul(pool_data.pool_total as u128) @@ -407,12 +743,17 @@ fn prepare_withdraw_accounts( if accounts.is_empty() { return Err("No accounts found.".to_string().into()); } - pick_withdraw_accounts(&mut accounts, amount) + let min_balance = config + .rpc_client + .get_minimum_balance_for_rent_exemption(STAKE_STATE_LEN)? + + 1; + pick_withdraw_accounts(&mut accounts, amount, min_balance) } fn pick_withdraw_accounts( accounts: &mut Vec<(Pubkey, Account)>, amount: u64, + min_balance: u64, ) -> Result, Error> { // Sort from highest to lowest balance accounts.sort_by(|a, b| b.1.lamports.cmp(&a.1.lamports)); @@ -421,50 +762,25 @@ fn pick_withdraw_accounts( let mut withdraw_from: Vec = vec![]; let mut remaining_amount = amount; - let mut split_candidate: Option = None; - - // If amount to withdraw is more than the largest account - // then use up all the large accounts first - // Then either find the smallest account with balance more than remaining - // or find account to claim with exactly the same balance as remaining + // Go through available accounts and withdraw from largest to smallest for (pubkey, account) in accounts { - if account.lamports <= remaining_amount { - if split_candidate.is_some() { - // If there is an active split candidate and current account is smaller than remaining - // then break to use split candidate - if account.lamports < remaining_amount { - break; - } - // Otherwise (account balance == remaining) procede with `claim` - } - // Those accounts will be withdrawn completely with `claim` instruction - withdraw_from.push(WithdrawAccount { - pubkey: *pubkey, - account: account.clone(), - amount: account.lamports, - }); - remaining_amount -= account.lamports; - if remaining_amount == 0 { - // We filled all the balance, ignore split candidate - split_candidate = None; - break; - } - } else { - // Save the last account with balance more than remaining as a candidate for split - split_candidate = Some(WithdrawAccount { - pubkey: *pubkey, - account: account.clone(), - amount: remaining_amount, - }); + if account.lamports <= min_balance { + continue; } - } - - // If there is a pending account to split, add it to the list - if let Some(withdraw) = split_candidate { - remaining_amount -= withdraw.amount; + let available_for_withdrawal = account.lamports - *MIN_STAKE_BALANCE; + let withdraw_amount = u64::min(available_for_withdrawal, remaining_amount); + + // Those accounts will be withdrawn completely with `claim` instruction + withdraw_from.push(WithdrawAccount { + pubkey: *pubkey, + account: account.clone(), + amount: withdraw_amount, + }); + remaining_amount -= withdraw_amount; - // This account will be withdrawn partially (if remaining_amount < account.lamports), so we put it first - withdraw_from.insert(0, withdraw); + if remaining_amount == 0 { + break; + } } // Not enough stake to withdraw the specified amount @@ -507,7 +823,7 @@ fn command_withdraw( TokenAccount::unpack_from_slice(account_data.as_slice()).unwrap(); if account_data.mint != pool_data.pool_mint { - return Err("Wrong token account.".to_string().into()); + return Err("Wrong token account.".into()); } // Check burn_from balance @@ -558,79 +874,49 @@ fn command_withdraw( lamports_to_sol(withdraw_stake.amount) ); - if withdraw_stake.amount < withdraw_stake.account.lamports { - // Withdraw to split account - if stake_receiver.is_none() { - // Account for tokens not specified, creating one - println!( - "Creating account to receive stake {}", - stake_receiver_account.pubkey() - ); - - let stake_receiver_account_balance = config - .rpc_client - .get_minimum_balance_for_rent_exemption(STAKE_STATE_LEN)?; - - instructions.push( - // Creating new account - system_instruction::create_account( - &config.fee_payer.pubkey(), - &stake_receiver_account.pubkey(), - stake_receiver_account_balance, - STAKE_STATE_LEN as u64, - &stake_program_id(), - ), - ); + if stake_receiver.is_none() { + // Account for tokens not specified, creating one + println!( + "Creating account to receive stake {}", + stake_receiver_account.pubkey() + ); - signers.push(&stake_receiver_account); + let stake_receiver_account_balance = config + .rpc_client + .get_minimum_balance_for_rent_exemption(STAKE_STATE_LEN)?; - total_rent_free_balances += stake_receiver_account_balance; + instructions.push( + // Creating new account + system_instruction::create_account( + &config.fee_payer.pubkey(), + &stake_receiver_account.pubkey(), + stake_receiver_account_balance, + STAKE_STATE_LEN as u64, + &stake_program_id(), + ), + ); - stake_receiver = Some(stake_receiver_account.pubkey()); - } + signers.push(&stake_receiver_account); - instructions.push(withdraw( - &spl_stake_pool::id(), - &pool, - &pool_withdraw_authority, - &withdraw_stake.pubkey, - &stake_receiver.unwrap(), // Cannot be none at this point - &config.owner.pubkey(), - &burn_from, - &pool_data.pool_mint, - &spl_token::id(), - &stake_program_id(), - withdraw_stake.amount, - )?); - } else { - // Claim to get whole account - instructions.push(claim( - &spl_stake_pool::id(), - &pool, - &pool_withdraw_authority, - &withdraw_stake.pubkey, - &config.owner.pubkey(), - &burn_from, - &pool_data.pool_mint, - &spl_token::id(), - &stake_program_id(), - )?); - - match stake_receiver { - Some(merge_into) => { - // Merge into stake_receiver - instructions.push(merge_stake( - &merge_into, - &withdraw_stake.pubkey, - &config.owner.pubkey(), - )); - } - None => { - // Save last account to merge into for the next claim - stake_receiver = Some(withdraw_stake.pubkey); - } - } + total_rent_free_balances += stake_receiver_account_balance; + + stake_receiver = Some(stake_receiver_account.pubkey()); } + + instructions.push(withdraw( + &spl_stake_pool::id(), + &pool, + &pool_data.validator_stake_list, + &pool_withdraw_authority, + &withdraw_stake.pubkey, + &stake_receiver.unwrap(), // Cannot be none at this point + &config.owner.pubkey(), + &burn_from, + &pool_data.pool_mint, + &spl_token::id(), + &stake_program_id(), + withdraw_stake.amount, + )?); } let mut transaction = @@ -826,6 +1112,91 @@ fn main() { .help("Fee denominator, fee amount is numerator divided by denominator."), ) ) + .subcommand(SubCommand::with_name("create-validator-stake").about("Create a new validator stake account to use with the pool") + .arg( + Arg::with_name("pool") + .long("pool") + .validator(is_pubkey) + .value_name("ADDRESS") + .takes_value(true) + .required(true) + .help("Stake pool address"), + ) + .arg( + Arg::with_name("validator") + .long("validator") + .validator(is_pubkey) + .value_name("ADDRESS") + .takes_value(true) + .required(true) + .help("Validator this stake account will vote for"), + ) + ) + .subcommand(SubCommand::with_name("add-validator-stake").about("Add validator stake account to the stake pool. Must be signed by the pool owner.") + .arg( + Arg::with_name("pool") + .long("pool") + .validator(is_pubkey) + .value_name("ADDRESS") + .takes_value(true) + .required(true) + .help("Stake pool address"), + ) + .arg( + Arg::with_name("stake") + .long("stake") + .validator(is_pubkey) + .value_name("ADDRESS") + .takes_value(true) + .required(true) + .help("Stake account to add to the pool"), + ) + .arg( + Arg::with_name("token_receiver") + .long("token-receiver") + .validator(is_pubkey) + .value_name("ADDRESS") + .takes_value(true) + .help("Account to receive pool token. Must be initialized account of the stake pool token. Defaults to the new pool token account."), + ) + ) + .subcommand(SubCommand::with_name("remove-validator-stake").about("Add validator stake account to the stake pool. Must be signed by the pool owner.") + .arg( + Arg::with_name("pool") + .long("pool") + .validator(is_pubkey) + .value_name("ADDRESS") + .takes_value(true) + .required(true) + .help("Stake pool address"), + ) + .arg( + Arg::with_name("stake") + .long("stake") + .validator(is_pubkey) + .value_name("ADDRESS") + .takes_value(true) + .required(true) + .help("Stake account to remove from the pool"), + ) + .arg( + Arg::with_name("burn_from") + .long("burn-from") + .validator(is_pubkey) + .value_name("ADDRESS") + .takes_value(true) + .required(true) + .help("Token account to burn pool token from. Must have enough tokens to burn for the full stake address balance."), + ) + .arg( + Arg::with_name("new_authority") + .long("new-authority") + .validator(is_pubkey) + .value_name("ADDRESS") + .takes_value(true) + .help("New authority to set as Staker and Withdrawer in the stake account removed from the pool. Defaults to the wallet owner pubkey."), + ) + ) .subcommand(SubCommand::with_name("deposit").about("Add stake account to the stake pool") .arg( Arg::with_name("pool") @@ -865,6 +1236,17 @@ fn main() { .help("Stake pool address."), ) ) + .subcommand(SubCommand::with_name("update").about("Updates all balances in the pool after validator stake accounts receive rewards.") + .arg( + Arg::with_name("pool") + .long("pool") + .validator(is_pubkey) + .value_name("ADDRESS") + .takes_value(true) + .required(true) + .help("Stake pool address."), + ) + ) .subcommand(SubCommand::with_name("withdraw").about("Withdraw amount from the stake pool") .arg( Arg::with_name("pool") @@ -1021,6 +1403,30 @@ fn main() { }, ) } + ("create-validator-stake", Some(arg_matches)) => { + let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); + let validator_account: Pubkey = pubkey_of(arg_matches, "validator").unwrap(); + command_vsa_create(&config, &pool_account, &validator_account) + } + ("add-validator-stake", Some(arg_matches)) => { + let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); + let stake_account: Pubkey = pubkey_of(arg_matches, "stake").unwrap(); + let token_receiver: Option = pubkey_of(arg_matches, "token_receiver"); + command_vsa_add(&config, &pool_account, &stake_account, &token_receiver) + } + ("remove-validator-stake", Some(arg_matches)) => { + let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); + let stake_account: Pubkey = pubkey_of(arg_matches, "stake").unwrap(); + let burn_from: Pubkey = pubkey_of(arg_matches, "burn_from").unwrap(); + let new_authority: Option = pubkey_of(arg_matches, "new_authority"); + command_vsa_remove( + &config, + &pool_account, + &stake_account, + &burn_from, + &new_authority, + ) + } ("deposit", Some(arg_matches)) => { let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); let stake_account: Pubkey = pubkey_of(arg_matches, "stake").unwrap(); @@ -1031,6 +1437,10 @@ fn main() { let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); command_list(&config, &pool_account) } + ("update", Some(arg_matches)) => { + let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); + command_update(&config, &pool_account) + } ("withdraw", Some(arg_matches)) => { let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); let burn_from: Pubkey = pubkey_of(arg_matches, "burn_from").unwrap(); @@ -1072,96 +1482,3 @@ fn main() { exit(1); }); } - -#[cfg(test)] -mod tests { - use super::*; - - const PK_OWNER: Pubkey = Pubkey::new_from_array([0xff; 32]); - - fn lamports_to_accounts(lamports: &[u64]) -> Vec<(Pubkey, Account)> { - let mut result: Vec<(Pubkey, Account)> = Vec::with_capacity(lamports.len()); - - for (index, balance) in lamports.iter().enumerate() { - result.push(( - Pubkey::new_from_array([index as u8; 32]), - Account::new(*balance, 0, &PK_OWNER), - )); - } - result - } - - fn pick_with_balance( - test_list: &[(Pubkey, Account)], - balance: u64, - withdraw: u64, - ) -> WithdrawAccount { - for (pubkey, account) in test_list { - if account.lamports == balance { - return WithdrawAccount { - pubkey: *pubkey, - account: account.clone(), - amount: withdraw, - }; - } - } - - panic!(); - } - - #[test] - fn test_pick_withdraw_accounts() { - let mut test_list = lamports_to_accounts(&[2, 7, 8, 5, 3, 10]); - assert_eq!( - pick_withdraw_accounts(&mut test_list, 5).unwrap(), - vec![pick_with_balance(&test_list, 5, 5),] - ); - - let mut test_list = lamports_to_accounts(&[2, 7, 8, 5, 3, 10]); - assert_eq!( - pick_withdraw_accounts(&mut test_list, 13).unwrap(), - vec![ - pick_with_balance(&test_list, 10, 10), - pick_with_balance(&test_list, 3, 3), - ] - ); - - let mut test_list = lamports_to_accounts(&[2, 7, 8, 5, 3, 10]); - assert_eq!( - pick_withdraw_accounts(&mut test_list, 14).unwrap(), - vec![ - pick_with_balance(&test_list, 5, 4), // Partial should always be the first - pick_with_balance(&test_list, 10, 10), - ] - ); - - let mut test_list = lamports_to_accounts(&[2, 7, 8, 5, 3, 10]); - assert_eq!( - pick_withdraw_accounts(&mut test_list, 19).unwrap(), - vec![ - pick_with_balance(&test_list, 2, 1), // Partial should always be the first - pick_with_balance(&test_list, 10, 10), - pick_with_balance(&test_list, 8, 8), - ] - ); - - let mut test_list = lamports_to_accounts(&[5, 4, 3]); - assert_eq!( - pick_withdraw_accounts(&mut test_list, 1).unwrap(), - vec![pick_with_balance(&test_list, 3, 1),] - ); - - let mut test_list = lamports_to_accounts(&[5, 3, 4]); - assert_eq!( - pick_withdraw_accounts(&mut test_list, 12).unwrap(), - vec![ - pick_with_balance(&test_list, 5, 5), - pick_with_balance(&test_list, 4, 4), - pick_with_balance(&test_list, 3, 3), - ] - ); - - let mut test_list = lamports_to_accounts(&[5, 3, 4]); - assert!(pick_withdraw_accounts(&mut test_list, 13).err().is_some()); - } -} diff --git a/program/Cargo.toml b/program/Cargo.toml index f97c0469..ecaab20d 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -9,6 +9,7 @@ edition = "2018" [features] no-entrypoint = [] +test-bpf = [] [dependencies] arrayref = "0.3.6" @@ -20,11 +21,12 @@ serde_derive = "1.0.103" solana-program = "1.5.1" spl-token = { path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" +bincode = "1.3.1" [dev-dependencies] -bincode = "1.3.1" -solana-program-test = "1.5.0" +solana-program-test = "1.5.3" solana-sdk = "1.5.0" +solana-vote-program = "1.5.3" tokio = { version = "0.3", features = ["macros"]} [lib] diff --git a/program/src/entrypoint.rs b/program/src/entrypoint.rs index ee0cb497..6a3262b2 100644 --- a/program/src/entrypoint.rs +++ b/program/src/entrypoint.rs @@ -2,7 +2,7 @@ #![cfg(all(target_arch = "bpf", not(feature = "no-entrypoint")))] -use crate::{error::Error, processor::Processor}; +use crate::{error::StakePoolError, processor::Processor}; use solana_program::{ account_info::AccountInfo, entrypoint, entrypoint::ProgramResult, program_error::PrintProgramError, pubkey::Pubkey, @@ -16,7 +16,7 @@ fn process_instruction( ) -> ProgramResult { if let Err(error) = Processor::process(program_id, accounts, instruction_data) { // catch the error so we can print it - error.print::(); + error.print::(); return Err(error); } Ok(()) diff --git a/program/src/error.rs b/program/src/error.rs index edb6ca8c..d39a73a3 100644 --- a/program/src/error.rs +++ b/program/src/error.rs @@ -6,37 +6,16 @@ use thiserror::Error; /// Errors that may be returned by the StakePool program. #[derive(Clone, Debug, Eq, Error, FromPrimitive, PartialEq)] -pub enum Error { +pub enum StakePoolError { /// The account cannot be initialized because it is already being used. #[error("AlreadyInUse")] AlreadyInUse, /// The program address provided doesn't match the value generated by the program. #[error("InvalidProgramAddress")] InvalidProgramAddress, - /// The owner of the input isn't set to the program address generated by the program. - #[error("InvalidOwner")] - InvalidOwner, - /// The deserialization of the Token state returned something besides State::Token. - #[error("ExpectedToken")] - ExpectedToken, - /// The deserialization of the Token state returned something besides State::Account. - #[error("ExpectedAccount")] - ExpectedAccount, - /// The initialized pool had a non zero supply. - #[error("InvalidSupply")] - InvalidSupply, - /// The initialized token has a delegate. - #[error("InvalidDelegate")] - InvalidDelegate, /// The token swap state is invalid. #[error("InvalidState")] InvalidState, - /// The input token is invalid for swap. - #[error("InvalidInput")] - InvalidInput, - /// The output token is invalid for swap. - #[error("InvalidOutput")] - InvalidOutput, /// The calculation failed. #[error("CalculationFailure")] CalculationFailure, @@ -46,13 +25,52 @@ pub enum Error { /// Token account is associated with the wrong mint. #[error("WrongAccountMint")] WrongAccountMint, + /// Account balance should be zero. + #[error("NonZeroBalance")] + NonZeroBalance, + /// Wrong pool owner account. + #[error("WrongOwner")] + WrongOwner, + /// Required signature is missing. + #[error("SignatureMissing")] + SignatureMissing, + /// Invalid validator stake list account. + #[error("InvalidValidatorStakeList")] + InvalidValidatorStakeList, + /// Invalid owner fee account. + #[error("InvalidFeeAccount")] + InvalidFeeAccount, + /// Specified pool mint account is wrong. + #[error("WrongPoolMint")] + WrongPoolMint, + /// Stake account is not in the state expected by the program. + #[error("WrongStakeState")] + WrongStakeState, + /// Stake account voting for this validator already exists in the pool. + #[error("ValidatorAlreadyAdded")] + ValidatorAlreadyAdded, + /// Stake account for this validator not found in the pool. + #[error("ValidatorNotFound")] + ValidatorNotFound, + /// Stake account address not properly derived from the validator address. + #[error("InvalidStakeAccountAddress")] + InvalidStakeAccountAddress, + /// Identify validator stake accounts with old balances and update them. + #[error("StakeListOutOfDate")] + StakeListOutOfDate, + /// First udpate old validator stake account balances and then pool stake balance. + #[error("StakeListAndPoolOutOfDate")] + StakeListAndPoolOutOfDate, + /// Validator stake account is not found in the list storage. + #[error("UnknownValidatorStakeAccount")] + UnknownValidatorStakeAccount, } -impl From for ProgramError { - fn from(e: Error) -> Self { +impl From for ProgramError { + fn from(e: StakePoolError) -> Self { ProgramError::Custom(e as u32) } } -impl DecodeError for Error { +impl DecodeError for StakePoolError { fn type_of() -> &'static str { "Stake Pool Error" } diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 591a7225..abbe1c4c 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -36,56 +36,104 @@ pub enum StakePoolInstruction { /// /// 0. `[w]` New StakePool to create. /// 1. `[]` Owner - /// 2. `[]` pool token Mint. Must be non zero, owned by withdraw authority. - /// 3. `[]` Pool Account to deposit the generated fee for owner. - /// 4. `[]` Token program id + /// 2. `[w]` Uninitialized validator stake list storage account + /// 3. `[]` pool token Mint. Must be non zero, owned by withdraw authority. + /// 4. `[]` Pool Account to deposit the generated fee for owner. + /// 5. `[]` Token program id Initialize(InitArgs), + /// Creates new program account for accumulating stakes for a particular validator + /// + /// 0. `[]` Stake pool account this stake will belong to + /// 1. `[ws]` Funding account (must be a system account) + /// 2. `[w]` Stake account to be created + /// 3. `[]` Validator this stake account will vote for + /// 4. `[]` Stake authority for the new stake account + /// 5. `[]` Withdraw authority for the new stake account + /// 6. `[]` Rent sysvar + /// 7. `[]` System program + /// 8. `[]` Stake program + CreateValidatorStakeAccount, + + /// Adds validator stake account to the pool + /// + /// 0. `[w]` Stake pool + /// 1. `[s]` Owner + /// 2. `[]` Stake pool deposit authority + /// 3. `[]` Stake pool withdraw authority + /// 4. `[w]` Validator stake list storage account + /// 5. `[w]` Stake account to add to the pool, its withdraw authority should be set to stake pool deposit + /// 6. `[w]` User account to receive pool tokens + /// 7. `[w]` Pool token mint account + /// 8. `[]` Clock sysvar (required) + /// 9. `[]` Pool token program id, + /// 10. `[]` Stake program id, + AddValidatorStakeAccount, + + /// Removes validator stake account from the pool + /// + /// 0. `[w]` Stake pool + /// 1. `[s]` Owner + /// 2. `[]` Stake pool withdraw authority + /// 3. `[]` New withdraw/staker authority to set in the stake account + /// 4. `[w]` Validator stake list storage account + /// 5. `[w]` Stake account to remove from the pool + /// 6. `[w]` User account with pool tokens to burn from + /// 7. `[w]` Pool token mint account + /// 8. '[]' Sysvar clock account (required) + /// 9. `[]` Pool token program id + /// 10. `[]` Stake program id, + RemoveValidatorStakeAccount, + + /// Updates balances of validator stake accounts in the pool + /// + /// 0. `[w]` Validator stake list storage account + /// 1. `[]` Sysvar clock account + /// 2. ..2+N ` [] N validator stake accounts to update balances + UpdateListBalance, + + /// Updates total pool balance based on balances in validator stake account list storage + /// + /// 0. `[w]` Stake pool + /// 1. `[]` Validator stake list storage account + /// 2. `[]` Sysvar clock account + UpdatePoolBalance, + /// Deposit some stake into the pool. The output is a "pool" token representing ownership /// into the pool. Inputs are converted to the current ratio. /// /// 0. `[w]` Stake pool - /// 1. `[]` Stake pool deposit authority - /// 2. `[]` Stake pool withdraw authority - /// 3. `[w]` Stake account to join the pool (withdraw should be set to stake pool deposit) - /// 4. `[w]` User account to receive pool tokens - /// 5. `[w]` Account to receive pool fee tokens - /// 6. `[w]` Pool token mint account - /// 7. '[]' Sysvar clock account (reserved for future use) - /// 8. `[]` Pool token program id, - /// 9. `[]` Stake program id, + /// 1. `[w]` Validator stake list storage account + /// 2. `[]` Stake pool deposit authority + /// 3. `[]` Stake pool withdraw authority + /// 4. `[w]` Stake account to join the pool (withdraw should be set to stake pool deposit) + /// 5. `[w]` Validator stake account for the stake account to be merged with + /// 6. `[w]` User account to receive pool tokens + /// 7. `[w]` Account to receive pool fee tokens + /// 8. `[w]` Pool token mint account + /// 9. '[]' Sysvar clock account (required) + /// 10. '[]' Sysvar stake history account + /// 11. `[]` Pool token program id, + /// 12. `[]` Stake program id, Deposit, /// Withdraw the token from the pool at the current ratio. /// The amount withdrawn is the MIN(u64, stake size) /// /// 0. `[w]` Stake pool - /// 1. `[]` Stake pool withdraw authority - /// 2. `[w]` Stake account to split - /// 3. `[w]` Unitialized stake account to receive withdrawal - /// 4. `[]` User account to set as a new withdraw authority - /// 5. `[w]` User account with pool tokens to burn from - /// 6. `[w]` Pool token mint account - /// 7. '[]' Sysvar clock account (reserved for future use) - /// 8. `[]` Pool token program id - /// 9. `[]` Stake program id, + /// 1. `[w]` Validator stake list storage account + /// 2. `[]` Stake pool withdraw authority + /// 3. `[w]` Validator stake account to split + /// 4. `[w]` Unitialized stake account to receive withdrawal + /// 5. `[]` User account to set as a new withdraw authority + /// 6. `[w]` User account with pool tokens to burn from + /// 7. `[w]` Pool token mint account + /// 8. '[]' Sysvar clock account (required) + /// 9. `[]` Pool token program id + /// 10. `[]` Stake program id, /// userdata: amount to withdraw Withdraw(u64), - /// Claim ownership of a whole stake account. - /// Also burns enough tokens to make up for the stake account balance - /// - /// 0. `[w]` Stake pool - /// 1. `[]` Stake pool withdraw authority - /// 2. `[w]` Stake account to claim - /// 3. `[]` User account to set as a new withdraw authority - /// 4. `[w]` User account with pool tokens to burn from - /// 5. `[w]` Pool token mint account - /// 6. '[]' Sysvar clock account (reserved for future use) - /// 7. `[]` Pool token program id - /// 8. `[]` Stake program id, - Claim, - /// Update the staking pubkey for a stake /// /// 0. `[w]` StakePool @@ -118,14 +166,18 @@ impl StakePoolInstruction { let val: &InitArgs = unpack(input)?; Self::Initialize(*val) } - 1 => Self::Deposit, - 2 => { + 1 => Self::CreateValidatorStakeAccount, + 2 => Self::AddValidatorStakeAccount, + 3 => Self::RemoveValidatorStakeAccount, + 4 => Self::UpdateListBalance, + 5 => Self::UpdatePoolBalance, + 6 => Self::Deposit, + 7 => { let val: &u64 = unpack(input)?; Self::Withdraw(*val) } - 3 => Self::Claim, - 4 => Self::SetStakingAuthority, - 5 => Self::SetOwner, + 8 => Self::SetStakingAuthority, + 9 => Self::SetOwner, _ => return Err(ProgramError::InvalidAccountData), }) } @@ -141,23 +193,35 @@ impl StakePoolInstruction { let value = unsafe { &mut *(&mut output[1] as *mut u8 as *mut InitArgs) }; *value = *init; } - Self::Deposit => { + Self::CreateValidatorStakeAccount => { output[0] = 1; } - Self::Withdraw(val) => { + Self::AddValidatorStakeAccount => { output[0] = 2; + } + Self::RemoveValidatorStakeAccount => { + output[0] = 3; + } + Self::UpdateListBalance => { + output[0] = 4; + } + Self::UpdatePoolBalance => { + output[0] = 5; + } + Self::Deposit => { + output[0] = 6; + } + Self::Withdraw(val) => { + output[0] = 7; #[allow(clippy::cast_ptr_alignment)] let value = unsafe { &mut *(&mut output[1] as *mut u8 as *mut u64) }; *value = *val; } - Self::Claim => { - output[0] = 3; - } Self::SetStakingAuthority => { - output[0] = 4; + output[0] = 8; } Self::SetOwner => { - output[0] = 5; + output[0] = 9; } } Ok(output) @@ -179,6 +243,7 @@ pub fn initialize( program_id: &Pubkey, stake_pool: &Pubkey, owner: &Pubkey, + validator_stake_list: &Pubkey, pool_mint: &Pubkey, owner_pool_account: &Pubkey, token_program_id: &Pubkey, @@ -189,8 +254,10 @@ pub fn initialize( let accounts = vec![ AccountMeta::new(*stake_pool, true), AccountMeta::new_readonly(*owner, false), + AccountMeta::new(*validator_stake_list, false), AccountMeta::new_readonly(*pool_mint, false), AccountMeta::new_readonly(*owner_pool_account, false), + AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(*token_program_id, false), ]; Ok(Instruction { @@ -200,28 +267,58 @@ pub fn initialize( }) } -/// Creates a 'deposit' instruction. -pub fn deposit( +/// Creates `CreateValidatorStakeAccount` instruction (create new stake account for the validator) +pub fn create_validator_stake_account( program_id: &Pubkey, stake_pool: &Pubkey, + funder: &Pubkey, + stake_account: &Pubkey, + validator: &Pubkey, + stake_authority: &Pubkey, + withdraw_authority: &Pubkey, + system_program_id: &Pubkey, + stake_program_id: &Pubkey, +) -> Result { + let accounts = vec![ + AccountMeta::new_readonly(*stake_pool, false), + AccountMeta::new(*funder, true), + AccountMeta::new(*stake_account, false), + AccountMeta::new_readonly(*validator, false), + AccountMeta::new_readonly(*stake_authority, false), + AccountMeta::new_readonly(*withdraw_authority, false), + AccountMeta::new_readonly(sysvar::rent::id(), false), + AccountMeta::new_readonly(*system_program_id, false), + AccountMeta::new_readonly(*stake_program_id, false), + ]; + Ok(Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::CreateValidatorStakeAccount.serialize()?, + }) +} + +/// Creates `AddValidatorStakeAccount` instruction (add new validator stake account to the pool) +pub fn add_validator_stake_account( + program_id: &Pubkey, + stake_pool: &Pubkey, + owner: &Pubkey, stake_pool_deposit: &Pubkey, stake_pool_withdraw: &Pubkey, - stake_to_join: &Pubkey, + validator_stake_list: &Pubkey, + stake_account: &Pubkey, pool_tokens_to: &Pubkey, - pool_fee_to: &Pubkey, pool_mint: &Pubkey, token_program_id: &Pubkey, stake_program_id: &Pubkey, ) -> Result { - let args = StakePoolInstruction::Deposit; - let data = args.serialize()?; let accounts = vec![ AccountMeta::new(*stake_pool, false), + AccountMeta::new_readonly(*owner, true), AccountMeta::new_readonly(*stake_pool_deposit, false), AccountMeta::new_readonly(*stake_pool_withdraw, false), - AccountMeta::new(*stake_to_join, false), + AccountMeta::new(*validator_stake_list, false), + AccountMeta::new(*stake_account, false), AccountMeta::new(*pool_tokens_to, false), - AccountMeta::new(*pool_fee_to, false), AccountMeta::new(*pool_mint, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(*token_program_id, false), @@ -230,38 +327,113 @@ pub fn deposit( Ok(Instruction { program_id: *program_id, accounts, - data, + data: StakePoolInstruction::AddValidatorStakeAccount.serialize()?, }) } -/// Creates a 'withdraw' instruction. -pub fn withdraw( +/// Creates `RemoveValidatorStakeAccount` instruction (remove validator stake account from the pool) +pub fn remove_validator_stake_account( program_id: &Pubkey, stake_pool: &Pubkey, + owner: &Pubkey, stake_pool_withdraw: &Pubkey, - stake_to_split: &Pubkey, - stake_to_receive: &Pubkey, - user_withdrawer: &Pubkey, + new_stake_authority: &Pubkey, + validator_stake_list: &Pubkey, + stake_account: &Pubkey, burn_from: &Pubkey, pool_mint: &Pubkey, token_program_id: &Pubkey, stake_program_id: &Pubkey, - amount: u64, ) -> Result { - let args = StakePoolInstruction::Withdraw(amount); - let data = args.serialize()?; let accounts = vec![ AccountMeta::new(*stake_pool, false), + AccountMeta::new_readonly(*owner, true), AccountMeta::new_readonly(*stake_pool_withdraw, false), - AccountMeta::new(*stake_to_split, false), - AccountMeta::new(*stake_to_receive, false), - AccountMeta::new_readonly(*user_withdrawer, false), + AccountMeta::new_readonly(*new_stake_authority, false), + AccountMeta::new(*validator_stake_list, false), + AccountMeta::new(*stake_account, false), AccountMeta::new(*burn_from, false), AccountMeta::new(*pool_mint, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(*token_program_id, false), AccountMeta::new_readonly(*stake_program_id, false), ]; + Ok(Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::RemoveValidatorStakeAccount.serialize()?, + }) +} + +/// Creates `UpdateListBalance` instruction (update validator stake account balances) +pub fn update_list_balance( + program_id: &Pubkey, + validator_stake_list_storage: &Pubkey, + validator_stake_list: &[&Pubkey], +) -> Result { + let mut accounts: Vec = validator_stake_list + .iter() + .map(|pubkey| AccountMeta::new_readonly(**pubkey, false)) + .collect(); + accounts.insert(0, AccountMeta::new(*validator_stake_list_storage, false)); + accounts.insert(1, AccountMeta::new_readonly(sysvar::clock::id(), false)); + Ok(Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::UpdateListBalance.serialize()?, + }) +} + +/// Creates `UpdatePoolBalance` instruction (pool balance from the stake account list balances) +pub fn update_pool_balance( + program_id: &Pubkey, + stake_pool: &Pubkey, + validator_stake_list_storage: &Pubkey, +) -> Result { + let accounts = vec![ + AccountMeta::new(*stake_pool, false), + AccountMeta::new(*validator_stake_list_storage, false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + ]; + Ok(Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::UpdatePoolBalance.serialize()?, + }) +} + +/// Creates a 'Deposit' instruction. +pub fn deposit( + program_id: &Pubkey, + stake_pool: &Pubkey, + validator_stake_list_storage: &Pubkey, + stake_pool_deposit: &Pubkey, + stake_pool_withdraw: &Pubkey, + stake_to_join: &Pubkey, + validator_stake_accont: &Pubkey, + pool_tokens_to: &Pubkey, + pool_fee_to: &Pubkey, + pool_mint: &Pubkey, + token_program_id: &Pubkey, + stake_program_id: &Pubkey, +) -> Result { + let args = StakePoolInstruction::Deposit; + let data = args.serialize()?; + let accounts = vec![ + AccountMeta::new(*stake_pool, false), + AccountMeta::new(*validator_stake_list_storage, false), + AccountMeta::new_readonly(*stake_pool_deposit, false), + AccountMeta::new_readonly(*stake_pool_withdraw, false), + AccountMeta::new(*stake_to_join, false), + AccountMeta::new(*validator_stake_accont, false), + AccountMeta::new(*pool_tokens_to, false), + AccountMeta::new(*pool_fee_to, false), + AccountMeta::new(*pool_mint, false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(sysvar::stake_history::id(), false), + AccountMeta::new_readonly(*token_program_id, false), + AccountMeta::new_readonly(*stake_program_id, false), + ]; Ok(Instruction { program_id: *program_id, accounts, @@ -269,24 +441,29 @@ pub fn withdraw( }) } -/// Creates a 'claim' instruction. -pub fn claim( +/// Creates a 'withdraw' instruction. +pub fn withdraw( program_id: &Pubkey, stake_pool: &Pubkey, + validator_stake_list_storage: &Pubkey, stake_pool_withdraw: &Pubkey, - stake_to_claim: &Pubkey, + stake_to_split: &Pubkey, + stake_to_receive: &Pubkey, user_withdrawer: &Pubkey, burn_from: &Pubkey, pool_mint: &Pubkey, token_program_id: &Pubkey, stake_program_id: &Pubkey, + amount: u64, ) -> Result { - let args = StakePoolInstruction::Claim; + let args = StakePoolInstruction::Withdraw(amount); let data = args.serialize()?; let accounts = vec![ AccountMeta::new(*stake_pool, false), + AccountMeta::new(*validator_stake_list_storage, false), AccountMeta::new_readonly(*stake_pool_withdraw, false), - AccountMeta::new(*stake_to_claim, false), + AccountMeta::new(*stake_to_split, false), + AccountMeta::new(*stake_to_receive, false), AccountMeta::new_readonly(*user_withdrawer, false), AccountMeta::new(*burn_from, false), AccountMeta::new(*pool_mint, false), diff --git a/program/src/lib.rs b/program/src/lib.rs index c97b7018..6f48ebb5 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -8,10 +8,13 @@ pub mod processor; pub mod stake; pub mod state; +/// Current program version +pub const PROGRAM_VERSION: u8 = 1; + #[cfg(not(feature = "no-entrypoint"))] pub mod entrypoint; // Export current sdk types for downstream users building with a different sdk version pub use solana_program; -solana_program::declare_id!("3T92SNpyV3ipDm1VeR4SZxsUVtRT3sBJMhynJ8hwLc8G"); +solana_program::declare_id!("5QuBzCtUC6pHgFEQJ5d2qX7ktyyHba9HVXLQVUEiAf7d"); diff --git a/program/src/processor.rs b/program/src/processor.rs index 05581b47..a5366467 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1,18 +1,30 @@ //! Program state processor use crate::{ - error::Error, + error::StakePoolError, instruction::{InitArgs, StakePoolInstruction}, stake, - state::{StakePool, State}, + state::{StakePool, State, ValidatorStakeInfo, ValidatorStakeList}, + PROGRAM_VERSION, }; +use bincode::deserialize; use num_traits::FromPrimitive; use solana_program::{ - account_info::next_account_info, account_info::AccountInfo, decode_error::DecodeError, - entrypoint::ProgramResult, msg, program::invoke_signed, program_error::PrintProgramError, - program_error::ProgramError, program_pack::Pack, pubkey::Pubkey, + account_info::next_account_info, + account_info::AccountInfo, + clock::Clock, + decode_error::DecodeError, + entrypoint::ProgramResult, + msg, + program::{invoke, invoke_signed}, + program_error::PrintProgramError, + program_error::ProgramError, + program_pack::Pack, + pubkey::Pubkey, + rent::Rent, + system_instruction, + sysvar::Sysvar, }; -use std::convert::TryFrom; /// Program state handler. pub struct Processor {} @@ -24,23 +36,95 @@ impl Processor { /// Calculates the authority id by generating a program address. pub fn authority_id( program_id: &Pubkey, - my_info: &Pubkey, + stake_pool: &Pubkey, authority_type: &[u8], bump_seed: u8, - ) -> Result { + ) -> Result { Pubkey::create_program_address( - &[&my_info.to_bytes()[..32], authority_type, &[bump_seed]], + &[&stake_pool.to_bytes()[..32], authority_type, &[bump_seed]], program_id, ) - .or(Err(Error::InvalidProgramAddress)) + .map_err(|_| StakePoolError::InvalidProgramAddress.into()) } /// Generates seed bump for stake pool authorities pub fn find_authority_bump_seed( program_id: &Pubkey, - my_info: &Pubkey, + stake_pool: &Pubkey, authority_type: &[u8], ) -> (Pubkey, u8) { - Pubkey::find_program_address(&[&my_info.to_bytes()[..32], authority_type], program_id) + Pubkey::find_program_address(&[&stake_pool.to_bytes()[..32], authority_type], program_id) + } + /// Generates stake account address for the validator + pub fn find_stake_address_for_validator( + program_id: &Pubkey, + validator: &Pubkey, + stake_pool: &Pubkey, + ) -> (Pubkey, u8) { + Pubkey::find_program_address( + &[&validator.to_bytes()[..32], &stake_pool.to_bytes()[..32]], + program_id, + ) + } + + /// Checks withdraw or deposit authority + pub fn check_authority( + authority_to_check: &Pubkey, + program_id: &Pubkey, + stake_pool_key: &Pubkey, + authority_type: &[u8], + bump_seed: u8, + ) -> Result<(), ProgramError> { + if *authority_to_check + != Self::authority_id(program_id, stake_pool_key, authority_type, bump_seed)? + { + return Err(StakePoolError::InvalidProgramAddress.into()); + } + Ok(()) + } + + /// Returns validator address for a particular stake account + pub fn get_validator(stake_account_info: &AccountInfo) -> Result { + let stake_state: stake::StakeState = deserialize(&stake_account_info.data.borrow()) + .or(Err(ProgramError::InvalidAccountData))?; + match stake_state { + stake::StakeState::Stake(_, stake) => Ok(stake.delegation.voter_pubkey), + _ => Err(StakePoolError::WrongStakeState.into()), + } + } + + /// Checks if validator stake account is a proper program address + pub fn is_validator_stake_address( + validator_account: &Pubkey, + program_id: &Pubkey, + stake_pool_info: &AccountInfo, + stake_account_info: &AccountInfo, + ) -> bool { + // Check stake account address validity + let (stake_address, _) = Self::find_stake_address_for_validator( + &program_id, + &validator_account, + &stake_pool_info.key, + ); + stake_address == *stake_account_info.key + } + + /// Returns validator address for a particular stake account and checks its validity + pub fn get_validator_checked( + program_id: &Pubkey, + stake_pool_info: &AccountInfo, + stake_account_info: &AccountInfo, + ) -> Result { + let validator_account = Self::get_validator(stake_account_info)?; + + if !Self::is_validator_stake_address( + &validator_account, + program_id, + stake_pool_info, + stake_account_info, + ) { + return Err(StakePoolError::InvalidStakeAccountAddress.into()); + } + Ok(validator_account) } /// Issue a stake_split instruction. @@ -75,6 +159,39 @@ impl Processor { ) } + /// Issue a stake_merge instruction. + #[allow(clippy::too_many_arguments)] + pub fn stake_merge<'a>( + stake_pool: &Pubkey, + stake_account: AccountInfo<'a>, + authority: AccountInfo<'a>, + authority_type: &[u8], + bump_seed: u8, + merge_with: AccountInfo<'a>, + clock: AccountInfo<'a>, + stake_history: AccountInfo<'a>, + stake_program_info: AccountInfo<'a>, + ) -> Result<(), ProgramError> { + let me_bytes = stake_pool.to_bytes(); + let authority_signature_seeds = [&me_bytes[..32], authority_type, &[bump_seed]]; + let signers = &[&authority_signature_seeds[..]]; + + let ix = stake::merge(merge_with.key, stake_account.key, authority.key); + + invoke_signed( + &ix, + &[ + merge_with, + stake_account, + clock, + stake_history, + authority, + stake_program_info, + ], + signers, + ) + } + /// Issue a stake_set_owner instruction. #[allow(clippy::too_many_arguments)] pub fn stake_authorize<'a>( @@ -161,7 +278,7 @@ impl Processor { invoke_signed(&ix, &[mint, destination, authority, token_program], signers) } - /// Processes an [Initialize](enum.Instruction.html). + /// Processes `Initialize` instruction. pub fn process_initialize( program_id: &Pubkey, init: InitArgs, @@ -170,25 +287,44 @@ impl Processor { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; let owner_info = next_account_info(account_info_iter)?; + let validator_stake_list_info = next_account_info(account_info_iter)?; let pool_mint_info = next_account_info(account_info_iter)?; let owner_fee_info = next_account_info(account_info_iter)?; + // Clock sysvar account + let clock_info = next_account_info(account_info_iter)?; + let clock = &Clock::from_account_info(clock_info)?; + // Token program ID let token_program_info = next_account_info(account_info_iter)?; // Stake pool account should not be already initialized if State::Unallocated != State::deserialize(&stake_pool_info.data.borrow())? { - return Err(Error::AlreadyInUse.into()); + return Err(StakePoolError::AlreadyInUse.into()); + } + + // Check if validator stake list storage is unitialized + let mut validator_stake_list = + ValidatorStakeList::deserialize(&validator_stake_list_info.data.borrow())?; + if validator_stake_list.is_initialized { + return Err(StakePoolError::AlreadyInUse.into()); } + validator_stake_list.is_initialized = true; + validator_stake_list.validators.clear(); // Numerator should be smaller than or equal to denominator (fee <= 1) if init.fee.numerator > init.fee.denominator { - return Err(Error::FeeTooHigh.into()); + return Err(StakePoolError::FeeTooHigh.into()); } // Check for owner fee account to have proper mint assigned if *pool_mint_info.key != spl_token::state::Account::unpack_from_slice(&owner_fee_info.data.borrow())?.mint { - return Err(Error::WrongAccountMint.into()); + return Err(StakePoolError::WrongAccountMint.into()); + } + + // Check pool mint program ID + if pool_mint_info.owner != token_program_info.key { + return Err(ProgramError::IncorrectProgramId); } let (_, deposit_bump_seed) = Self::find_authority_bump_seed( @@ -201,113 +337,226 @@ impl Processor { stake_pool_info.key, Self::AUTHORITY_WITHDRAW, ); + + validator_stake_list.serialize(&mut validator_stake_list_info.data.borrow_mut())?; + + msg!("Clock data: {:?}", clock_info.data.borrow()); + msg!("Epoch: {}", clock.epoch); + let stake_pool = State::Init(StakePool { + version: PROGRAM_VERSION, owner: *owner_info.key, deposit_bump_seed, withdraw_bump_seed, + validator_stake_list: *validator_stake_list_info.key, pool_mint: *pool_mint_info.key, owner_fee_account: *owner_fee_info.key, token_program_id: *token_program_info.key, stake_total: 0, pool_total: 0, + last_update_epoch: clock.epoch, fee: init.fee, }); stake_pool.serialize(&mut stake_pool_info.data.borrow_mut()) } - /// Processes [Deposit](enum.Instruction.html). - pub fn process_deposit(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { + /// Processes `CreateValidatorStakeAccount` instruction. + pub fn process_create_validator_stake_account( + program_id: &Pubkey, + accounts: &[AccountInfo], + ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); - // Stake pool + // Stake pool account + let stake_pool_info = next_account_info(account_info_iter)?; + // Account creation funder account + let funder_info = next_account_info(account_info_iter)?; + // Stake account to be created + let stake_account_info = next_account_info(account_info_iter)?; + // Validator this stake account will vote for + let validator_info = next_account_info(account_info_iter)?; + // Stake authority for the new stake account + let stake_authority_info = next_account_info(account_info_iter)?; + // Withdraw authority for the new stake account + let withdraw_authority_info = next_account_info(account_info_iter)?; + // Rent sysvar account + let rent_info = next_account_info(account_info_iter)?; + let rent = &Rent::from_account_info(rent_info)?; + // System program id + let system_program_info = next_account_info(account_info_iter)?; + // Staking program id + let stake_program_info = next_account_info(account_info_iter)?; + + // Check program ids + if *system_program_info.key != solana_program::system_program::id() { + return Err(ProgramError::IncorrectProgramId); + } + if *stake_program_info.key != stake::id() { + return Err(ProgramError::IncorrectProgramId); + } + + // Check stake account address validity + let (stake_address, bump_seed) = Self::find_stake_address_for_validator( + &program_id, + &validator_info.key, + &stake_pool_info.key, + ); + if stake_address != *stake_account_info.key { + return Err(StakePoolError::InvalidStakeAccountAddress.into()); + } + + let stake_account_signer_seeds: &[&[_]] = &[ + &validator_info.key.to_bytes()[..32], + &stake_pool_info.key.to_bytes()[..32], + &[bump_seed], + ]; + + // Fund the associated token account with the minimum balance to be rent exempt + let required_lamports = 1 + rent.minimum_balance(std::mem::size_of::()); + // Fund new account + invoke( + &system_instruction::transfer( + &funder_info.key, + stake_account_info.key, + required_lamports, + ), + &[ + funder_info.clone(), + stake_account_info.clone(), + system_program_info.clone(), + ], + )?; + // Allocate account space + invoke_signed( + &system_instruction::allocate( + stake_account_info.key, + std::mem::size_of::() as u64, + ), + &[stake_account_info.clone(), system_program_info.clone()], + &[&stake_account_signer_seeds], + )?; + // Assign account to the stake program + invoke_signed( + &system_instruction::assign(stake_account_info.key, &stake::id()), + &[stake_account_info.clone(), system_program_info.clone()], + &[&stake_account_signer_seeds], + )?; + // Initialize stake account + invoke( + &stake::initialize( + &stake_account_info.key, + &stake::Authorized { + staker: *stake_authority_info.key, + withdrawer: *withdraw_authority_info.key, + }, + &stake::Lockup::default(), + ), + &[ + stake_account_info.clone(), + rent_info.clone(), + stake_program_info.clone(), + ], + ) + } + + /// Processes `AddValidatorStakeAccount` instruction. + pub fn process_add_validator_stake_account( + program_id: &Pubkey, + accounts: &[AccountInfo], + ) -> ProgramResult { + let account_info_iter = &mut accounts.iter(); + // Stake pool account let stake_pool_info = next_account_info(account_info_iter)?; + // Pool owner account + let owner_info = next_account_info(account_info_iter)?; // Stake pool deposit authority let deposit_info = next_account_info(account_info_iter)?; // Stake pool withdraw authority let withdraw_info = next_account_info(account_info_iter)?; - // Stake account to join the pool (withdraw should be set to stake pool deposit) - let stake_info = next_account_info(account_info_iter)?; + // Account storing validator stake list + let validator_stake_list_info = next_account_info(account_info_iter)?; + // Stake account to add to the pool + let stake_account_info = next_account_info(account_info_iter)?; // User account to receive pool tokens let dest_user_info = next_account_info(account_info_iter)?; - // Account to receive pool fee tokens - let owner_fee_info = next_account_info(account_info_iter)?; // Pool token mint account let pool_mint_info = next_account_info(account_info_iter)?; - // (Reserved) - let reserved = next_account_info(account_info_iter)?; + // Clock sysvar account + let clock_info = next_account_info(account_info_iter)?; + let clock = &Clock::from_account_info(clock_info)?; // Pool token program id let token_program_info = next_account_info(account_info_iter)?; - // Stake program id + // Staking program id let stake_program_info = next_account_info(account_info_iter)?; + // Check program ids + if *stake_program_info.key != stake::id() { + return Err(ProgramError::IncorrectProgramId); + } + + // Get stake pool stake (and check if it is iniaialized) let mut stake_pool = State::deserialize(&stake_pool_info.data.borrow())?.stake_pool()?; - if *withdraw_info.key - != Self::authority_id( - program_id, - stake_pool_info.key, - Self::AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, - )? - { - return Err(Error::InvalidProgramAddress.into()); - } + // Check authority accounts + stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?; + stake_pool.check_authority_deposit(deposit_info.key, program_id, stake_pool_info.key)?; - if *deposit_info.key - != Self::authority_id( - program_id, - stake_pool_info.key, - Self::AUTHORITY_DEPOSIT, - stake_pool.deposit_bump_seed, - )? - { - return Err(Error::InvalidProgramAddress.into()); - } + // Check owner validity and signature + stake_pool.check_owner(owner_info)?; - if stake_pool.owner_fee_account != *owner_fee_info.key { - return Err(Error::InvalidInput.into()); + // Check stake pool last update epoch + if stake_pool.last_update_epoch < clock.epoch { + return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); } + if stake_pool.token_program_id != *token_program_info.key { - return Err(Error::InvalidInput.into()); + return Err(StakePoolError::InvalidProgramAddress.into()); + } + if stake_pool.pool_mint != *pool_mint_info.key { + return Err(StakePoolError::WrongPoolMint.into()); } - let stake_lamports = **stake_info.lamports.borrow(); - let pool_amount = stake_pool - .calc_pool_deposit_amount(stake_lamports) - .ok_or(Error::CalculationFailure)?; + // Check validator stake account list storage + if *validator_stake_list_info.key != stake_pool.validator_stake_list { + return Err(StakePoolError::InvalidValidatorStakeList.into()); + } - let fee_amount = stake_pool - .calc_fee_amount(pool_amount) - .ok_or(Error::CalculationFailure)?; + // Read validator stake list account and check if it is valid + let mut validator_stake_list = + ValidatorStakeList::deserialize(&validator_stake_list_info.data.borrow())?; + if !validator_stake_list.is_initialized { + return Err(StakePoolError::InvalidState.into()); + } - let user_amount = pool_amount - .checked_sub(fee_amount) - .ok_or(Error::CalculationFailure)?; + let validator_account = + Self::get_validator_checked(program_id, stake_pool_info, stake_account_info)?; - Self::stake_authorize( - stake_pool_info.key, - stake_info.clone(), - deposit_info.clone(), - Self::AUTHORITY_DEPOSIT, - stake_pool.deposit_bump_seed, - withdraw_info.key, - stake::StakeAuthorize::Withdrawer, - reserved.clone(), - stake_program_info.clone(), - )?; + if validator_stake_list.contains(&validator_account) { + return Err(StakePoolError::ValidatorAlreadyAdded.into()); + } - Self::stake_authorize( - stake_pool_info.key, - stake_info.clone(), - deposit_info.clone(), - Self::AUTHORITY_DEPOSIT, - stake_pool.deposit_bump_seed, - withdraw_info.key, + // Update Withdrawer and Staker authority to the program withdraw authority + for authority in &[ + stake::StakeAuthorize::Withdrawer, stake::StakeAuthorize::Staker, - reserved.clone(), - stake_program_info.clone(), - )?; + ] { + Self::stake_authorize( + stake_pool_info.key, + stake_account_info.clone(), + deposit_info.clone(), + Self::AUTHORITY_DEPOSIT, + stake_pool.deposit_bump_seed, + withdraw_info.key, + *authority, + clock_info.clone(), + stake_program_info.clone(), + )?; + } - let user_amount = ::try_from(user_amount).or(Err(Error::CalculationFailure))?; + // Calculate and mint tokens + let stake_lamports = **stake_account_info.lamports.borrow(); + let token_amount = stake_pool + .calc_pool_deposit_amount(stake_lamports) + .ok_or(StakePoolError::CalculationFailure)?; Self::token_mint_to( stake_pool_info.key, token_program_info.clone(), @@ -316,112 +565,126 @@ impl Processor { withdraw_info.clone(), Self::AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, - user_amount, + token_amount, )?; - let fee_amount = ::try_from(fee_amount).or(Err(Error::CalculationFailure))?; - Self::token_mint_to( - stake_pool_info.key, - token_program_info.clone(), - pool_mint_info.clone(), - owner_fee_info.clone(), - withdraw_info.clone(), - Self::AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, - fee_amount as u64, - )?; - let pool_amount = ::try_from(pool_amount).or(Err(Error::CalculationFailure))?; - stake_pool.pool_total += pool_amount; + // TODO: Check if stake is warmed up + + // Add validator to the list and save + validator_stake_list.validators.push(ValidatorStakeInfo { + validator_account, + balance: stake_lamports, + last_update_epoch: clock.epoch, + }); + validator_stake_list.serialize(&mut validator_stake_list_info.data.borrow_mut())?; + + // Save amounts to the stake pool state + stake_pool.pool_total += token_amount; + // Only update stake total if the last state update epoch is current stake_pool.stake_total += stake_lamports; State::Init(stake_pool).serialize(&mut stake_pool_info.data.borrow_mut())?; + Ok(()) } - /// Processes [Withdraw](enum.Instruction.html). - pub fn process_withdraw( + /// Processes `RemoveValidatorStakeAccount` instruction. + pub fn process_remove_validator_stake_account( program_id: &Pubkey, - stake_amount: u64, accounts: &[AccountInfo], ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); - // Stake pool + // Stake pool account let stake_pool_info = next_account_info(account_info_iter)?; + // Pool owner account + let owner_info = next_account_info(account_info_iter)?; // Stake pool withdraw authority let withdraw_info = next_account_info(account_info_iter)?; - // Stake account to split - let stake_split_from = next_account_info(account_info_iter)?; - // Unitialized stake account to receive withdrawal - let stake_split_to = next_account_info(account_info_iter)?; - // User account to set as a new withdraw authority - let user_stake_authority = next_account_info(account_info_iter)?; + // New stake authority + let new_stake_authority_info = next_account_info(account_info_iter)?; + // Account storing validator stake list + let validator_stake_list_info = next_account_info(account_info_iter)?; + // Stake account to remove from the pool + let stake_account_info = next_account_info(account_info_iter)?; // User account with pool tokens to burn from let burn_from_info = next_account_info(account_info_iter)?; // Pool token mint account let pool_mint_info = next_account_info(account_info_iter)?; - // (Reserved) - let reserved = next_account_info(account_info_iter)?; + // Clock sysvar account + let clock_info = next_account_info(account_info_iter)?; + let clock = &Clock::from_account_info(clock_info)?; // Pool token program id let token_program_info = next_account_info(account_info_iter)?; - // Stake program id + // Staking program id let stake_program_info = next_account_info(account_info_iter)?; + // Check program ids + if *stake_program_info.key != stake::id() { + return Err(ProgramError::IncorrectProgramId); + } + + // Get stake pool stake (and check if it is iniaialized) let mut stake_pool = State::deserialize(&stake_pool_info.data.borrow())?.stake_pool()?; - if *withdraw_info.key - != Self::authority_id( - program_id, - stake_pool_info.key, - Self::AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, - )? - { - return Err(Error::InvalidProgramAddress.into()); + // Check authority account + stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?; + + // Check owner validity and signature + stake_pool.check_owner(owner_info)?; + + // Check stake pool last update epoch + if stake_pool.last_update_epoch < clock.epoch { + return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); } + if stake_pool.token_program_id != *token_program_info.key { - return Err(Error::InvalidInput.into()); + return Err(StakePoolError::InvalidProgramAddress.into()); + } + if stake_pool.pool_mint != *pool_mint_info.key { + return Err(StakePoolError::WrongPoolMint.into()); } - let pool_amount = stake_pool - .calc_pool_withdraw_amount(stake_amount) - .ok_or(Error::CalculationFailure)?; - let pool_amount = ::try_from(pool_amount).or(Err(Error::CalculationFailure))?; + // Check validator stake account list storage + if *validator_stake_list_info.key != stake_pool.validator_stake_list { + return Err(StakePoolError::InvalidValidatorStakeList.into()); + } - Self::stake_split( - stake_pool_info.key, - stake_split_from.clone(), - withdraw_info.clone(), - Self::AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, - stake_amount, - stake_split_to.clone(), - reserved.clone(), - stake_program_info.clone(), - )?; + // Read validator stake list account and check if it is valid + let mut validator_stake_list = + ValidatorStakeList::deserialize(&validator_stake_list_info.data.borrow())?; + if !validator_stake_list.is_initialized { + return Err(StakePoolError::InvalidState.into()); + } - Self::stake_authorize( - stake_pool_info.key, - stake_split_to.clone(), - withdraw_info.clone(), - Self::AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, - user_stake_authority.key, - stake::StakeAuthorize::Withdrawer, - reserved.clone(), - stake_program_info.clone(), - )?; + let validator_account = + Self::get_validator_checked(program_id, stake_pool_info, stake_account_info)?; - Self::stake_authorize( - stake_pool_info.key, - stake_split_to.clone(), - withdraw_info.clone(), - Self::AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, - user_stake_authority.key, + if !validator_stake_list.contains(&validator_account) { + return Err(StakePoolError::ValidatorNotFound.into()); + } + + // Update Withdrawer and Staker authority to the provided authority + for authority in &[ + stake::StakeAuthorize::Withdrawer, stake::StakeAuthorize::Staker, - reserved.clone(), - stake_program_info.clone(), - )?; + ] { + Self::stake_authorize( + stake_pool_info.key, + stake_account_info.clone(), + withdraw_info.clone(), + Self::AUTHORITY_WITHDRAW, + stake_pool.withdraw_bump_seed, + new_stake_authority_info.key, + *authority, + clock_info.clone(), + stake_program_info.clone(), + )?; + } + // Calculate and burn tokens + let stake_lamports = **stake_account_info.lamports.borrow(); + let token_amount = stake_pool + .calc_pool_withdraw_amount(stake_lamports) + .ok_or(StakePoolError::CalculationFailure)?; Self::token_burn( stake_pool_info.key, token_program_info.clone(), @@ -430,79 +693,381 @@ impl Processor { withdraw_info.clone(), Self::AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, - pool_amount, + token_amount, )?; - stake_pool.pool_total -= pool_amount; - stake_pool.stake_total -= stake_amount; + // Remove validator from the list and save + validator_stake_list + .validators + .retain(|item| item.validator_account != validator_account); + validator_stake_list.serialize(&mut validator_stake_list_info.data.borrow_mut())?; + + // Save amounts to the stake pool state + stake_pool.pool_total -= token_amount; + // Only update stake total if the last state update epoch is current + stake_pool.stake_total -= stake_lamports; State::Init(stake_pool).serialize(&mut stake_pool_info.data.borrow_mut())?; + Ok(()) } - /// Processes [Claim](enum.Instruction.html). - pub fn process_claim(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { + + /// Processes `UpdateListBalance` instruction. + pub fn process_update_list_balance( + _program_id: &Pubkey, + accounts: &[AccountInfo], + ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); - // Stake pool - let stake_pool_info = next_account_info(account_info_iter)?; - // Stake pool withdraw authority - let withdraw_info = next_account_info(account_info_iter)?; - // Stake account to claim - let stake_to_claim = next_account_info(account_info_iter)?; - // User account to set as a new withdraw authority - let user_stake_authority = next_account_info(account_info_iter)?; - // User account with pool tokens to burn from - let burn_from_info = next_account_info(account_info_iter)?; - // Pool token account + // Account storing validator stake list + let validator_stake_list_info = next_account_info(account_info_iter)?; + // Clock sysvar account + let clock_info = next_account_info(account_info_iter)?; + let clock = &Clock::from_account_info(clock_info)?; + // Validator stake accounts + let validator_stake_accounts = account_info_iter.as_slice(); + + // Read validator stake list account and check if it is valid + let mut validator_stake_list = + ValidatorStakeList::deserialize(&validator_stake_list_info.data.borrow())?; + if !validator_stake_list.is_initialized { + return Err(StakePoolError::InvalidState.into()); + } + + let validator_accounts: Vec> = validator_stake_accounts + .iter() + .map(|stake| Self::get_validator(stake).ok()) + .collect(); + + let mut changes = false; + // Do a brute iteration through the list, optimize if necessary + for validator_stake_record in &mut validator_stake_list.validators { + if validator_stake_record.last_update_epoch >= clock.epoch { + continue; + } + for (validator_stake_account, validator_account) in validator_stake_accounts + .iter() + .zip(validator_accounts.iter()) + { + if validator_stake_record.validator_account + != validator_account.ok_or(StakePoolError::WrongStakeState)? + { + continue; + } + validator_stake_record.last_update_epoch = clock.epoch; + validator_stake_record.balance = **validator_stake_account.lamports.borrow(); + changes = true; + } + } + + if changes { + validator_stake_list.serialize(&mut validator_stake_list_info.data.borrow_mut())?; + } + + Ok(()) + } + + /// Processes `UpdatePoolBalance` instruction. + pub fn process_update_pool_balance( + _program_id: &Pubkey, + accounts: &[AccountInfo], + ) -> ProgramResult { + let account_info_iter = &mut accounts.iter(); + // Stake pool account + let stake_pool_info = next_account_info(account_info_iter)?; + // Account storing validator stake list + let validator_stake_list_info = next_account_info(account_info_iter)?; + // Clock sysvar account + let clock_info = next_account_info(account_info_iter)?; + let clock = &Clock::from_account_info(clock_info)?; + + // Get stake pool stake (and check if it is iniaialized) + let mut stake_pool = State::deserialize(&stake_pool_info.data.borrow())?.stake_pool()?; + + // Check validator stake account list storage + if *validator_stake_list_info.key != stake_pool.validator_stake_list { + return Err(StakePoolError::InvalidValidatorStakeList.into()); + } + + // Read validator stake list account and check if it is valid + let validator_stake_list = + ValidatorStakeList::deserialize(&validator_stake_list_info.data.borrow())?; + if !validator_stake_list.is_initialized { + return Err(StakePoolError::InvalidState.into()); + } + + let mut total_balance: u64 = 0; + for validator_stake_record in validator_stake_list.validators { + if validator_stake_record.last_update_epoch < clock.epoch { + return Err(StakePoolError::StakeListOutOfDate.into()); + } + total_balance += validator_stake_record.balance; + } + + stake_pool.stake_total = total_balance; + stake_pool.last_update_epoch = clock.epoch; + State::Init(stake_pool).serialize(&mut stake_pool_info.data.borrow_mut())?; + + Ok(()) + } + + /// Processes [Deposit](enum.Instruction.html). + pub fn process_deposit(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { + let account_info_iter = &mut accounts.iter(); + // Stake pool + let stake_pool_info = next_account_info(account_info_iter)?; + // Account storing validator stake list + let validator_stake_list_info = next_account_info(account_info_iter)?; + // Stake pool deposit authority + let deposit_info = next_account_info(account_info_iter)?; + // Stake pool withdraw authority + let withdraw_info = next_account_info(account_info_iter)?; + // Stake account to join the pool (withdraw should be set to stake pool deposit) + let stake_info = next_account_info(account_info_iter)?; + // Valdidator stake account to merge with + let validator_stake_account_info = next_account_info(account_info_iter)?; + // User account to receive pool tokens + let dest_user_info = next_account_info(account_info_iter)?; + // Account to receive pool fee tokens + let owner_fee_info = next_account_info(account_info_iter)?; + // Pool token mint account let pool_mint_info = next_account_info(account_info_iter)?; - // (Reserved) - let reserved = next_account_info(account_info_iter)?; + // Clock sysvar account + let clock_info = next_account_info(account_info_iter)?; + let clock = &Clock::from_account_info(clock_info)?; + // Stake history sysvar account + let stake_history_info = next_account_info(account_info_iter)?; // Pool token program id let token_program_info = next_account_info(account_info_iter)?; // Stake program id let stake_program_info = next_account_info(account_info_iter)?; + // Check program ids + if *stake_program_info.key != stake::id() { + return Err(ProgramError::IncorrectProgramId); + } + let mut stake_pool = State::deserialize(&stake_pool_info.data.borrow())?.stake_pool()?; - if *withdraw_info.key - != Self::authority_id( - program_id, - stake_pool_info.key, - Self::AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, - )? - { - return Err(Error::InvalidProgramAddress.into()); + // Check authority accounts + stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?; + stake_pool.check_authority_deposit(deposit_info.key, program_id, stake_pool_info.key)?; + + if stake_pool.owner_fee_account != *owner_fee_info.key { + return Err(StakePoolError::InvalidFeeAccount.into()); + } + if stake_pool.token_program_id != *token_program_info.key { + return Err(StakePoolError::InvalidProgramAddress.into()); + } + + // Check validator stake account list storage + if *validator_stake_list_info.key != stake_pool.validator_stake_list { + return Err(StakePoolError::InvalidValidatorStakeList.into()); + } + + // Check stake pool last update epoch + if stake_pool.last_update_epoch < clock.epoch { + return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); + } + + // Read validator stake list account and check if it is valid + let mut validator_stake_list = + ValidatorStakeList::deserialize(&validator_stake_list_info.data.borrow())?; + if !validator_stake_list.is_initialized { + return Err(StakePoolError::InvalidState.into()); + } + + let validator_account = + Self::get_validator_checked(program_id, stake_pool_info, validator_stake_account_info)?; + + let validator_list_item = validator_stake_list + .find_mut(&validator_account) + .ok_or(StakePoolError::ValidatorNotFound)?; + + let stake_lamports = **stake_info.lamports.borrow(); + let pool_amount = stake_pool + .calc_pool_deposit_amount(stake_lamports) + .ok_or(StakePoolError::CalculationFailure)?; + + let fee_amount = stake_pool + .calc_fee_amount(pool_amount) + .ok_or(StakePoolError::CalculationFailure)?; + + let user_amount = pool_amount + .checked_sub(fee_amount) + .ok_or(StakePoolError::CalculationFailure)?; + + Self::stake_authorize( + stake_pool_info.key, + stake_info.clone(), + deposit_info.clone(), + Self::AUTHORITY_DEPOSIT, + stake_pool.deposit_bump_seed, + withdraw_info.key, + stake::StakeAuthorize::Withdrawer, + clock_info.clone(), + stake_program_info.clone(), + )?; + + Self::stake_authorize( + stake_pool_info.key, + stake_info.clone(), + deposit_info.clone(), + Self::AUTHORITY_DEPOSIT, + stake_pool.deposit_bump_seed, + withdraw_info.key, + stake::StakeAuthorize::Staker, + clock_info.clone(), + stake_program_info.clone(), + )?; + + Self::stake_merge( + stake_pool_info.key, + stake_info.clone(), + withdraw_info.clone(), + Self::AUTHORITY_WITHDRAW, + stake_pool.withdraw_bump_seed, + validator_stake_account_info.clone(), + clock_info.clone(), + stake_history_info.clone(), + stake_program_info.clone(), + )?; + + Self::token_mint_to( + stake_pool_info.key, + token_program_info.clone(), + pool_mint_info.clone(), + dest_user_info.clone(), + withdraw_info.clone(), + Self::AUTHORITY_WITHDRAW, + stake_pool.withdraw_bump_seed, + user_amount, + )?; + + Self::token_mint_to( + stake_pool_info.key, + token_program_info.clone(), + pool_mint_info.clone(), + owner_fee_info.clone(), + withdraw_info.clone(), + Self::AUTHORITY_WITHDRAW, + stake_pool.withdraw_bump_seed, + fee_amount, + )?; + stake_pool.pool_total += pool_amount; + stake_pool.stake_total += stake_lamports; + State::Init(stake_pool).serialize(&mut stake_pool_info.data.borrow_mut())?; + + validator_list_item.balance = **validator_stake_account_info.lamports.borrow(); + validator_stake_list.serialize(&mut validator_stake_list_info.data.borrow_mut())?; + + Ok(()) + } + + /// Processes [Withdraw](enum.Instruction.html). + pub fn process_withdraw( + program_id: &Pubkey, + stake_amount: u64, + accounts: &[AccountInfo], + ) -> ProgramResult { + let account_info_iter = &mut accounts.iter(); + // Stake pool + let stake_pool_info = next_account_info(account_info_iter)?; + // Account storing validator stake list + let validator_stake_list_info = next_account_info(account_info_iter)?; + // Stake pool withdraw authority + let withdraw_info = next_account_info(account_info_iter)?; + // Stake account to split + let stake_split_from = next_account_info(account_info_iter)?; + // Unitialized stake account to receive withdrawal + let stake_split_to = next_account_info(account_info_iter)?; + // User account to set as a new withdraw authority + let user_stake_authority = next_account_info(account_info_iter)?; + // User account with pool tokens to burn from + let burn_from_info = next_account_info(account_info_iter)?; + // Pool token mint account + let pool_mint_info = next_account_info(account_info_iter)?; + // Clock sysvar account + let clock_info = next_account_info(account_info_iter)?; + let clock = &Clock::from_account_info(clock_info)?; + // Pool token program id + let token_program_info = next_account_info(account_info_iter)?; + // Stake program id + let stake_program_info = next_account_info(account_info_iter)?; + + // Check program ids + if *stake_program_info.key != stake::id() { + return Err(ProgramError::IncorrectProgramId); } + + let mut stake_pool = State::deserialize(&stake_pool_info.data.borrow())?.stake_pool()?; + + // Check authority account + stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?; + if stake_pool.token_program_id != *token_program_info.key { - return Err(Error::InvalidInput.into()); + return Err(StakePoolError::InvalidProgramAddress.into()); + } + + // Check validator stake account list storage + if *validator_stake_list_info.key != stake_pool.validator_stake_list { + return Err(StakePoolError::InvalidValidatorStakeList.into()); + } + + // Check stake pool last update epoch + if stake_pool.last_update_epoch < clock.epoch { + return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); } - let stake_amount = **stake_to_claim.lamports.borrow(); + // Read validator stake list account and check if it is valid + let mut validator_stake_list = + ValidatorStakeList::deserialize(&validator_stake_list_info.data.borrow())?; + if !validator_stake_list.is_initialized { + return Err(StakePoolError::InvalidState.into()); + } + + let validator_account = + Self::get_validator_checked(program_id, stake_pool_info, stake_split_from)?; + + let validator_list_item = validator_stake_list + .find_mut(&validator_account) + .ok_or(StakePoolError::ValidatorNotFound)?; + let pool_amount = stake_pool .calc_pool_withdraw_amount(stake_amount) - .ok_or(Error::CalculationFailure)?; - let pool_amount = ::try_from(pool_amount).or(Err(Error::CalculationFailure))?; + .ok_or(StakePoolError::CalculationFailure)?; + + Self::stake_split( + stake_pool_info.key, + stake_split_from.clone(), + withdraw_info.clone(), + Self::AUTHORITY_WITHDRAW, + stake_pool.withdraw_bump_seed, + stake_amount, + stake_split_to.clone(), + clock_info.clone(), + stake_program_info.clone(), + )?; Self::stake_authorize( stake_pool_info.key, - stake_to_claim.clone(), + stake_split_to.clone(), withdraw_info.clone(), Self::AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, user_stake_authority.key, stake::StakeAuthorize::Withdrawer, - reserved.clone(), + clock_info.clone(), stake_program_info.clone(), )?; Self::stake_authorize( stake_pool_info.key, - stake_to_claim.clone(), + stake_split_to.clone(), withdraw_info.clone(), Self::AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, user_stake_authority.key, stake::StakeAuthorize::Staker, - reserved.clone(), + clock_info.clone(), stake_program_info.clone(), )?; @@ -520,6 +1085,10 @@ impl Processor { stake_pool.pool_total -= pool_amount; stake_pool.stake_total -= stake_amount; State::Init(stake_pool).serialize(&mut stake_pool_info.data.borrow_mut())?; + + validator_list_item.balance = **stake_split_from.lamports.borrow(); + validator_stake_list.serialize(&mut validator_stake_list_info.data.borrow_mut())?; + Ok(()) } /// Processes [SetStakeAuthority](enum.Instruction.html). @@ -538,25 +1107,18 @@ impl Processor { // Stake program id let stake_program_info = next_account_info(account_info_iter)?; + // Check program ids + if *stake_program_info.key != stake::id() { + return Err(ProgramError::IncorrectProgramId); + } + let stake_pool = State::deserialize(&stake_pool_info.data.borrow())?.stake_pool()?; - if *owner_info.key != stake_pool.owner { - return Err(Error::InvalidInput.into()); - } - if !owner_info.is_signer { - return Err(Error::InvalidInput.into()); - } + // Check authority account + stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?; - if *withdraw_info.key - != Self::authority_id( - program_id, - stake_pool_info.key, - Self::AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, - )? - { - return Err(Error::InvalidProgramAddress.into()); - } + // Check owner validity and signature + stake_pool.check_owner(owner_info)?; Self::stake_authorize( stake_pool_info.key, @@ -582,18 +1144,14 @@ impl Processor { let mut stake_pool = State::deserialize(&stake_pool_info.data.borrow())?.stake_pool()?; - if *owner_info.key != stake_pool.owner { - return Err(Error::InvalidInput.into()); - } - if !owner_info.is_signer { - return Err(Error::InvalidInput.into()); - } + // Check owner validity and signature + stake_pool.check_owner(owner_info)?; // Check for owner fee account to have proper mint assigned if stake_pool.pool_mint != spl_token::state::Account::unpack_from_slice(&new_owner_fee_info.data.borrow())?.mint { - return Err(Error::WrongAccountMint.into()); + return Err(StakePoolError::WrongAccountMint.into()); } stake_pool.owner = *new_owner_info.key; @@ -609,6 +1167,26 @@ impl Processor { msg!("Instruction: Init"); Self::process_initialize(program_id, init, accounts) } + StakePoolInstruction::CreateValidatorStakeAccount => { + msg!("Instruction: CreateValidatorStakeAccount"); + Self::process_create_validator_stake_account(program_id, accounts) + } + StakePoolInstruction::AddValidatorStakeAccount => { + msg!("Instruction: AddValidatorStakeAccount"); + Self::process_add_validator_stake_account(program_id, accounts) + } + StakePoolInstruction::RemoveValidatorStakeAccount => { + msg!("Instruction: RemoveValidatorStakeAccount"); + Self::process_remove_validator_stake_account(program_id, accounts) + } + StakePoolInstruction::UpdateListBalance => { + msg!("Instruction: UpdateListBalance"); + Self::process_update_list_balance(program_id, accounts) + } + StakePoolInstruction::UpdatePoolBalance => { + msg!("Instruction: UpdatePoolBalance"); + Self::process_update_pool_balance(program_id, accounts) + } StakePoolInstruction::Deposit => { msg!("Instruction: Deposit"); Self::process_deposit(program_id, accounts) @@ -617,10 +1195,6 @@ impl Processor { msg!("Instruction: Withdraw"); Self::process_withdraw(program_id, amount, accounts) } - StakePoolInstruction::Claim => { - msg!("Instruction: Claim"); - Self::process_claim(program_id, accounts) - } StakePoolInstruction::SetStakingAuthority => { msg!("Instruction: SetStakingAuthority"); Self::process_set_staking_auth(program_id, accounts) @@ -633,1087 +1207,33 @@ impl Processor { } } -impl PrintProgramError for Error { +impl PrintProgramError for StakePoolError { fn print(&self) where E: 'static + std::error::Error + DecodeError + PrintProgramError + FromPrimitive, { match self { - Error::AlreadyInUse => msg!("Error: AlreadyInUse"), - Error::InvalidProgramAddress => msg!("Error: InvalidProgramAddress"), - Error::InvalidOwner => msg!("Error: InvalidOwner"), - Error::ExpectedToken => msg!("Error: ExpectedToken"), - Error::ExpectedAccount => msg!("Error: ExpectedAccount"), - Error::InvalidSupply => msg!("Error: InvalidSupply"), - Error::InvalidDelegate => msg!("Error: InvalidDelegate"), - Error::InvalidState => msg!("Error: InvalidState"), - Error::InvalidInput => msg!("Error: InvalidInput"), - Error::InvalidOutput => msg!("Error: InvalidOutput"), - Error::CalculationFailure => msg!("Error: CalculationFailure"), - Error::FeeTooHigh => msg!("Error: FeeTooHigh"), - Error::WrongAccountMint => msg!("Error: WrongAccountMint"), - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::instruction::*; - use solana_program::{ - instruction::AccountMeta, instruction::Instruction, native_token::sol_to_lamports, - program_pack::Pack, program_stubs, rent::Rent, sysvar, - }; - use solana_sdk::account::{create_account, create_is_signer_account_infos, Account}; - use spl_token::{ - error::TokenError, - instruction::{initialize_account, initialize_mint}, - processor::Processor as TokenProcessor, - state::{Account as SplAccount, Mint as SplMint}, - }; - - /// Test program id for the stake-pool program. - const STAKE_POOL_PROGRAM_ID: Pubkey = Pubkey::new_from_array([2u8; 32]); - - /// Test program id for the token program. - const TOKEN_PROGRAM_ID: Pubkey = Pubkey::new_from_array([1u8; 32]); - - /// Actual stake account program id, used for tests - fn stake_program_id() -> Pubkey { - "Stake11111111111111111111111111111111111111" - .parse::() - .unwrap() - } - - const STAKE_ACCOUNT_LEN: usize = 100; - - struct TestSyscallStubs {} - impl program_stubs::SyscallStubs for TestSyscallStubs { - fn sol_invoke_signed( - &self, - instruction: &Instruction, - account_infos: &[AccountInfo], - signers_seeds: &[&[&[u8]]], - ) -> ProgramResult { - msg!("TestSyscallStubs::sol_invoke_signed()"); - - let mut new_account_infos = vec![]; - for meta in instruction.accounts.iter() { - for account_info in account_infos.iter() { - if meta.pubkey == *account_info.key { - let mut new_account_info = account_info.clone(); - for seeds in signers_seeds.iter() { - let signer = - Pubkey::create_program_address(seeds, &STAKE_POOL_PROGRAM_ID) - .unwrap(); - if *account_info.key == signer { - new_account_info.is_signer = true; - } - } - new_account_infos.push(new_account_info); - } - } - } - - match instruction.program_id { - TOKEN_PROGRAM_ID => invoke_token(&new_account_infos, &instruction.data), - pubkey => { - if pubkey == stake_program_id() { - invoke_stake(&new_account_infos, &instruction.data) - } else { - Err(ProgramError::IncorrectProgramId) - } - } - } - } - } - - /// Mocks token instruction invocation - pub fn invoke_token<'a>(account_infos: &[AccountInfo<'a>], input: &[u8]) -> ProgramResult { - spl_token::processor::Processor::process(&TOKEN_PROGRAM_ID, &account_infos, &input) - } - - /// Mocks stake account instruction invocation - pub fn invoke_stake<'a>(_account_infos: &[AccountInfo<'a>], _input: &[u8]) -> ProgramResult { - // For now always return ok - Ok(()) - } - - fn test_syscall_stubs() { - use std::sync::Once; - static ONCE: Once = Once::new(); - - ONCE.call_once(|| { - program_stubs::set_syscall_stubs(Box::new(TestSyscallStubs {})); - }); - } - - struct StakePoolInfo { - pub pool_key: Pubkey, - pub pool_account: Account, - pub deposit_bump_seed: u8, - pub withdraw_bump_seed: u8, - pub deposit_authority_key: Pubkey, - pub withdraw_authority_key: Pubkey, - pub fee: Fee, - pub owner_key: Pubkey, - pub owner_account: Account, - pub owner_fee_key: Pubkey, - pub owner_fee_account: Account, - pub mint_key: Pubkey, - pub mint_account: Account, - } - - struct DepositInfo { - result: ProgramResult, - stake_account_key: Pubkey, - stake_account_account: Account, - } - - struct Deposit { - stake_balance: u64, - tokens_to_issue: u64, - user_token_balance: u64, - fee_token_balance: u64, - pool_info: StakePoolInfo, - pool_token_receiver: TokenInfo, - } - - struct WithdrawInfo { - result: ProgramResult, - } - - struct Withdraw { - stake_balance: u64, - tokens_to_issue: u64, - withdraw_amount: u64, - tokens_to_burn: u64, - pool_info: StakePoolInfo, - user_withdrawer_key: Pubkey, - pool_token_receiver: TokenInfo, - deposit_info: DepositInfo, - } - - struct ClaimInfo { - result: ProgramResult, - } - - struct Claim { - tokens_to_issue: u64, - pool_info: StakePoolInfo, - user_withdrawer_key: Pubkey, - pool_token_receiver: TokenInfo, - deposit_info: DepositInfo, - allow_burn_to: Pubkey, - } - - fn do_process_instruction( - instruction: Instruction, - accounts: Vec<&mut Account>, - ) -> ProgramResult { - test_syscall_stubs(); - - // approximate the logic in the actual runtime which runs the instruction - // and only updates accounts if the instruction is successful - let mut account_clones = accounts.iter().map(|x| (*x).clone()).collect::>(); - let mut meta = instruction - .accounts - .iter() - .zip(account_clones.iter_mut()) - .map(|(account_meta, account)| (&account_meta.pubkey, account_meta.is_signer, account)) - .collect::>(); - let mut account_infos = create_is_signer_account_infos(&mut meta); - let res = if instruction.program_id == STAKE_POOL_PROGRAM_ID { - Processor::process(&instruction.program_id, &account_infos, &instruction.data) - } else { - TokenProcessor::process(&instruction.program_id, &account_infos, &instruction.data) - }; - - if res.is_ok() { - let mut account_metas = instruction - .accounts - .iter() - .zip(accounts) - .map(|(account_meta, account)| (&account_meta.pubkey, account)) - .collect::>(); - for account_info in account_infos.iter_mut() { - for account_meta in account_metas.iter_mut() { - if account_info.key == account_meta.0 { - let account = &mut account_meta.1; - account.owner = *account_info.owner; - account.lamports = **account_info.lamports.borrow(); - account.data = account_info.data.borrow().to_vec(); - } - } - } - } - res - } - - fn account_minimum_balance() -> u64 { - Rent::default().minimum_balance(SplAccount::get_packed_len()) - } - - fn mint_minimum_balance() -> u64 { - Rent::default().minimum_balance(SplMint::get_packed_len()) - } - - struct TokenInfo { - key: Pubkey, - account: Account, - owner: Pubkey, - } - - fn create_token_account( - program_id: &Pubkey, - mint_key: &Pubkey, - mint_account: &mut Account, - ) -> TokenInfo { - let mut token = TokenInfo { - key: Pubkey::new_unique(), - account: Account::new( - account_minimum_balance(), - SplAccount::get_packed_len(), - &program_id, - ), - owner: Pubkey::new_unique(), - }; - let mut rent_sysvar_account = create_account(&Rent::free(), 1); - let mut owner_account = Account::default(); - - // create account - do_process_instruction( - initialize_account(&program_id, &token.key, &mint_key, &token.owner).unwrap(), - vec![ - &mut token.account, - mint_account, - &mut owner_account, - &mut rent_sysvar_account, - ], - ) - .unwrap(); - - token - } - - fn create_mint(program_id: &Pubkey, authority_key: &Pubkey) -> (Pubkey, Account) { - let mint_key = Pubkey::new_unique(); - let mut mint_account = Account::new( - mint_minimum_balance(), - SplMint::get_packed_len(), - &program_id, - ); - let mut rent_sysvar_account = create_account(&Rent::free(), 1); - - // create token mint - do_process_instruction( - initialize_mint(&program_id, &mint_key, authority_key, None, 2).unwrap(), - vec![&mut mint_account, &mut rent_sysvar_account], - ) - .unwrap(); - - (mint_key, mint_account) - } - - fn approve_token( - program_id: &Pubkey, - token_account_pubkey: &Pubkey, - mut token_account_account: &mut Account, - delegate_pubkey: &Pubkey, - owner_pubkey: &Pubkey, - amount: u64, - ) { - do_process_instruction( - spl_token::instruction::approve( - &program_id, - token_account_pubkey, - delegate_pubkey, - owner_pubkey, - &[], - amount, - ) - .unwrap(), - vec![ - &mut token_account_account, - &mut Account::default(), - &mut Account::default(), - ], - ) - .unwrap(); - } - - const FEE_DEFAULT: Fee = Fee { - denominator: 100, - numerator: 5, - }; - - fn create_stake_pool_default() -> StakePoolInfo { - create_stake_pool(FEE_DEFAULT) - } - - fn create_stake_pool(fee: Fee) -> StakePoolInfo { - let stake_pool_key = Pubkey::new_unique(); - let owner_key = Pubkey::new_unique(); - - let mut stake_pool_account = Account::new(0, State::LEN, &STAKE_POOL_PROGRAM_ID); - let mut owner_account = Account::default(); - - // Calculate authority addresses - let (deposit_authority_key, deposit_bump_seed) = Pubkey::find_program_address( - &[&stake_pool_key.to_bytes()[..32], b"deposit"], - &STAKE_POOL_PROGRAM_ID, - ); - let (withdraw_authority_key, withdraw_bump_seed) = Pubkey::find_program_address( - &[&stake_pool_key.to_bytes()[..32], b"withdraw"], - &STAKE_POOL_PROGRAM_ID, - ); - - let (mint_key, mut mint_account) = create_mint(&TOKEN_PROGRAM_ID, &withdraw_authority_key); - let mut token = create_token_account(&TOKEN_PROGRAM_ID, &mint_key, &mut mint_account); - - // StakePool Init - let _result = do_process_instruction( - initialize( - &STAKE_POOL_PROGRAM_ID, - &stake_pool_key, - &owner_key, - &mint_key, - &token.key, - &TOKEN_PROGRAM_ID, - InitArgs { fee }, - ) - .unwrap(), - vec![ - &mut stake_pool_account, - &mut owner_account, - &mut mint_account, - &mut token.account, - &mut Account::default(), - ], - ) - .expect("Error on stake pool initialize"); - - StakePoolInfo { - pool_key: stake_pool_key, - pool_account: stake_pool_account, - deposit_bump_seed, - withdraw_bump_seed, - deposit_authority_key, - withdraw_authority_key, - fee, - owner_key, - owner_account, - owner_fee_key: token.key, - owner_fee_account: token.account, - mint_key, - mint_account, - } - } - - fn do_deposit( - pool_info: &mut StakePoolInfo, - stake_balance: u64, - token: &mut TokenInfo, - ) -> DepositInfo { - let stake_account_key = Pubkey::new_unique(); - let mut stake_account_account = - Account::new(stake_balance, STAKE_ACCOUNT_LEN, &stake_program_id()); - // TODO: Set stake account Withdrawer authority to pool_info.deposit_authority_key - - // Call deposit - let result = do_process_instruction( - deposit( - &STAKE_POOL_PROGRAM_ID, - &pool_info.pool_key, - &pool_info.deposit_authority_key, - &pool_info.withdraw_authority_key, - &stake_account_key, - &token.key, - &pool_info.owner_fee_key, - &pool_info.mint_key, - &TOKEN_PROGRAM_ID, - &stake_program_id(), - ) - .unwrap(), - vec![ - &mut pool_info.pool_account, - &mut Account::default(), - &mut Account::default(), - &mut stake_account_account, - &mut token.account, - &mut pool_info.owner_fee_account, - &mut pool_info.mint_account, - &mut Account::default(), - &mut Account::default(), - &mut Account::default(), - ], - ); - - DepositInfo { - result, - stake_account_key, - stake_account_account, - } - } - - fn do_withdraw(test_data: &mut Withdraw) -> WithdrawInfo { - approve_token( - &TOKEN_PROGRAM_ID, - &test_data.pool_token_receiver.key, - &mut test_data.pool_token_receiver.account, - &test_data.pool_info.withdraw_authority_key, - &test_data.pool_token_receiver.owner, - test_data.tokens_to_burn, - ); - - let stake_to_receive_key = Pubkey::new_unique(); - let mut stake_to_receive_account = Account::new( - test_data.stake_balance, - STAKE_ACCOUNT_LEN, - &stake_program_id(), - ); - - let result = do_process_instruction( - withdraw( - &STAKE_POOL_PROGRAM_ID, - &test_data.pool_info.pool_key, - &test_data.pool_info.withdraw_authority_key, - &test_data.deposit_info.stake_account_key, - &stake_to_receive_key, - &test_data.user_withdrawer_key, - &test_data.pool_token_receiver.key, - &test_data.pool_info.mint_key, - &TOKEN_PROGRAM_ID, - &stake_program_id(), - test_data.withdraw_amount, - ) - .unwrap(), - vec![ - &mut test_data.pool_info.pool_account, - &mut Account::default(), - &mut test_data.deposit_info.stake_account_account, - &mut stake_to_receive_account, - &mut Account::default(), - &mut test_data.pool_token_receiver.account, - &mut test_data.pool_info.mint_account, - &mut Account::default(), - &mut Account::default(), - &mut Account::default(), - ], - ); - - WithdrawInfo { result } - } - - fn do_claim(test_data: &mut Claim) -> ClaimInfo { - approve_token( - &TOKEN_PROGRAM_ID, - &test_data.pool_token_receiver.key, - &mut test_data.pool_token_receiver.account, - &test_data.allow_burn_to, - &test_data.pool_token_receiver.owner, - test_data.tokens_to_issue, - ); - - let result = do_process_instruction( - claim( - &STAKE_POOL_PROGRAM_ID, - &test_data.pool_info.pool_key, - &test_data.pool_info.withdraw_authority_key, - &test_data.deposit_info.stake_account_key, - &test_data.user_withdrawer_key, - &test_data.pool_token_receiver.key, - &test_data.pool_info.mint_key, - &TOKEN_PROGRAM_ID, - &stake_program_id(), - ) - .unwrap(), - vec![ - &mut test_data.pool_info.pool_account, - &mut Account::default(), - &mut test_data.deposit_info.stake_account_account, - &mut Account::default(), - &mut test_data.pool_token_receiver.account, - &mut test_data.pool_info.mint_account, - &mut Account::default(), - &mut Account::default(), - &mut Account::default(), - ], - ); - ClaimInfo { result } - } - - fn set_staking_authority_without_signer( - program_id: &Pubkey, - stake_pool: &Pubkey, - stake_pool_owner: &Pubkey, - stake_pool_withdraw: &Pubkey, - stake_account_to_update: &Pubkey, - stake_account_new_authority: &Pubkey, - stake_program_id: &Pubkey, - ) -> Result { - let args = StakePoolInstruction::SetStakingAuthority; - let data = args.serialize()?; - let accounts = vec![ - AccountMeta::new(*stake_pool, false), - AccountMeta::new_readonly(*stake_pool_owner, false), - AccountMeta::new_readonly(*stake_pool_withdraw, false), - AccountMeta::new(*stake_account_to_update, false), - AccountMeta::new_readonly(*stake_account_new_authority, false), - AccountMeta::new_readonly(sysvar::clock::id(), false), - AccountMeta::new_readonly(*stake_program_id, false), - ]; - Ok(Instruction { - program_id: *program_id, - accounts, - data, - }) - } - - fn set_owner_without_signer( - program_id: &Pubkey, - stake_pool: &Pubkey, - stake_pool_owner: &Pubkey, - stake_pool_new_owner: &Pubkey, - stake_pool_new_fee_receiver: &Pubkey, - ) -> Result { - let args = StakePoolInstruction::SetOwner; - let data = args.serialize()?; - let accounts = vec![ - AccountMeta::new(*stake_pool, false), - AccountMeta::new_readonly(*stake_pool_owner, false), - AccountMeta::new_readonly(*stake_pool_new_owner, false), - AccountMeta::new_readonly(*stake_pool_new_fee_receiver, false), - ]; - Ok(Instruction { - program_id: *program_id, - accounts, - data, - }) - } - - #[test] - fn test_initialize() { - let pool_info = create_stake_pool_default(); - // Read account data - let state = State::deserialize(&pool_info.pool_account.data).unwrap(); - match state { - State::Unallocated => panic!("Stake pool state is not initialized after init"), - State::Init(stake_pool) => { - assert_eq!(stake_pool.deposit_bump_seed, pool_info.deposit_bump_seed); - assert_eq!(stake_pool.withdraw_bump_seed, pool_info.withdraw_bump_seed); - assert_eq!(stake_pool.fee.numerator, FEE_DEFAULT.numerator); - assert_eq!(stake_pool.fee.denominator, FEE_DEFAULT.denominator); - - assert_eq!(stake_pool.owner, pool_info.owner_key); - assert_eq!(stake_pool.pool_mint, pool_info.mint_key); - assert_eq!(stake_pool.owner_fee_account, pool_info.owner_fee_key); - assert_eq!(stake_pool.token_program_id, TOKEN_PROGRAM_ID); - - assert_eq!(stake_pool.stake_total, 0); - assert_eq!(stake_pool.pool_total, 0); + StakePoolError::AlreadyInUse => msg!("Error: AlreadyInUse"), + StakePoolError::InvalidProgramAddress => msg!("Error: InvalidProgramAddress"), + StakePoolError::InvalidState => msg!("Error: InvalidState"), + StakePoolError::CalculationFailure => msg!("Error: CalculationFailure"), + StakePoolError::FeeTooHigh => msg!("Error: FeeTooHigh"), + StakePoolError::WrongAccountMint => msg!("Error: WrongAccountMint"), + StakePoolError::NonZeroBalance => msg!("Error: NonZeroBalance"), + StakePoolError::WrongOwner => msg!("Error: WrongOwner"), + StakePoolError::SignatureMissing => msg!("Error: SignatureMissing"), + StakePoolError::InvalidValidatorStakeList => msg!("Error: InvalidValidatorStakeList"), + StakePoolError::InvalidFeeAccount => msg!("Error: InvalidFeeAccount"), + StakePoolError::WrongPoolMint => msg!("Error: WrongPoolMint"), + StakePoolError::WrongStakeState => msg!("Error: WrongStakeState"), + StakePoolError::ValidatorAlreadyAdded => msg!("Error: ValidatorAlreadyAdded"), + StakePoolError::ValidatorNotFound => msg!("Error: ValidatorNotFound"), + StakePoolError::InvalidStakeAccountAddress => msg!("Error: InvalidStakeAccountAddress"), + StakePoolError::StakeListOutOfDate => msg!("Error: StakeListOutOfDate"), + StakePoolError::StakeListAndPoolOutOfDate => msg!("Error: StakeListAndPoolOutOfDate"), + StakePoolError::UnknownValidatorStakeAccount => { + msg!("Error: UnknownValidatorStakeAccount") } } } - - fn initialize_deposit_test() -> Deposit { - let stake_balance: u64 = sol_to_lamports(10.0); - let tokens_to_issue: u64 = 10_000_000_000; - let user_token_balance: u64 = 9_800_000_000; - let fee_token_balance: u64 = 200_000_000; - assert_eq!(tokens_to_issue, user_token_balance + fee_token_balance); - - // Create stake account - let mut pool_info = create_stake_pool(Fee { - denominator: 100, - numerator: 2, - }); - - let pool_token_receiver = create_token_account( - &TOKEN_PROGRAM_ID, - &pool_info.mint_key, - &mut pool_info.mint_account, - ); - - Deposit { - stake_balance, - tokens_to_issue, - user_token_balance, - fee_token_balance, - pool_info, - pool_token_receiver, - } - } - #[test] - fn test_deposit() { - let mut test_data = initialize_deposit_test(); - - let deposit_info = do_deposit( - &mut test_data.pool_info, - test_data.stake_balance, - &mut test_data.pool_token_receiver, - ); - - deposit_info.result.expect("Fail on deposit"); - // Test stake pool balance - let state = State::deserialize(&test_data.pool_info.pool_account.data).unwrap(); - assert!( - matches!(state, State::Init(stake_pool) if stake_pool.stake_total == test_data.stake_balance && stake_pool.pool_total == test_data.tokens_to_issue) - ); - - // Test token balances - let user_token_state = - SplAccount::unpack_from_slice(&test_data.pool_token_receiver.account.data) - .expect("User token account is not initialized after deposit"); - assert_eq!(user_token_state.amount, test_data.user_token_balance); - let fee_token_state = - SplAccount::unpack_from_slice(&test_data.pool_info.owner_fee_account.data) - .expect("Fee token account is not initialized after deposit"); - assert_eq!(fee_token_state.amount, test_data.fee_token_balance); - - // Test mint total issued tokens - let mint_state = SplMint::unpack_from_slice(&test_data.pool_info.mint_account.data) - .expect("Mint account is not initialized after deposit"); - assert_eq!(mint_state.supply, test_data.stake_balance); - - // TODO: Check stake account Withdrawer to match stake pool withdraw authority - } - #[test] - fn negative_test_deposit_wrong_withdraw_authority() { - let mut test_data = initialize_deposit_test(); - test_data.pool_info.withdraw_authority_key = Pubkey::new_unique(); - - let deposit_info = do_deposit( - &mut test_data.pool_info, - test_data.stake_balance, - &mut test_data.pool_token_receiver, - ); - assert_eq!( - deposit_info.result, - Err(Error::InvalidProgramAddress.into()) - ); - } - #[test] - fn negative_test_deposit_wrong_deposit_authority() { - let mut test_data = initialize_deposit_test(); - test_data.pool_info.deposit_authority_key = Pubkey::new_unique(); - - let deposit_info = do_deposit( - &mut test_data.pool_info, - test_data.stake_balance, - &mut test_data.pool_token_receiver, - ); - - assert_eq!( - deposit_info.result, - Err(Error::InvalidProgramAddress.into()) - ); - } - #[test] - fn negative_test_deposit_wrong_owner_fee_account() { - let mut test_data = initialize_deposit_test(); - test_data.pool_info.owner_fee_account = Account::default(); - - let deposit_info = do_deposit( - &mut test_data.pool_info, - test_data.stake_balance, - &mut test_data.pool_token_receiver, - ); - - assert_eq!(deposit_info.result, Err(ProgramError::InvalidAccountData)); - } - - fn initialize_withdraw_test() -> Withdraw { - let stake_balance = sol_to_lamports(20.0); - let tokens_to_issue = 20_000_000_000; - let withdraw_amount = sol_to_lamports(5.0); - let tokens_to_burn = 5_000_000_000; - - let mut pool_info = create_stake_pool_default(); - - let user_withdrawer_key = Pubkey::new_unique(); - - let mut pool_token_receiver = create_token_account( - &TOKEN_PROGRAM_ID, - &pool_info.mint_key, - &mut pool_info.mint_account, - ); - let deposit_info = do_deposit(&mut pool_info, stake_balance, &mut pool_token_receiver); - - Withdraw { - stake_balance, - tokens_to_issue, - withdraw_amount, - tokens_to_burn, - pool_info, - user_withdrawer_key, - pool_token_receiver, - deposit_info, - } - } - #[test] - fn test_withdraw() { - let mut test_data = initialize_withdraw_test(); - let withdraw_info = do_withdraw(&mut test_data); - - withdraw_info.result.expect("Fail on deposit"); - let fee_amount = test_data.stake_balance * FEE_DEFAULT.numerator / FEE_DEFAULT.denominator; - - let user_token_state = - SplAccount::unpack_from_slice(&test_data.pool_token_receiver.account.data) - .expect("User token account is not initialized after withdraw"); - assert_eq!( - user_token_state.amount, - test_data.stake_balance - fee_amount - test_data.withdraw_amount - ); - - // Check stake pool token amounts - let state = State::deserialize(&test_data.pool_info.pool_account.data).unwrap(); - assert!( - matches!(state, State::Init(stake_pool) if stake_pool.stake_total == test_data.stake_balance - test_data.withdraw_amount && stake_pool.pool_total == test_data.tokens_to_issue - test_data.tokens_to_burn) - ); - } - #[test] - fn negative_test_withdraw_wrong_withdraw_authority() { - let mut test_data = initialize_withdraw_test(); - - test_data.pool_info.withdraw_authority_key = Pubkey::new_unique(); - - let withdraw_info = do_withdraw(&mut test_data); - - assert_eq!( - withdraw_info.result, - Err(Error::InvalidProgramAddress.into()) - ); - } - #[test] - fn negative_test_withdraw_all() { - let mut test_data = initialize_withdraw_test(); - - test_data.withdraw_amount = test_data.stake_balance; - - let withdraw_info = do_withdraw(&mut test_data); - - assert_eq!( - withdraw_info.result, - Err(Error::InvalidProgramAddress.into()) - ); - } - #[test] - fn negative_test_withdraw_excess_amount() { - let mut test_data = initialize_withdraw_test(); - - test_data.withdraw_amount *= 2; - - let withdraw_info = do_withdraw(&mut test_data); - - assert_eq!( - withdraw_info.result, - Err(Error::InvalidProgramAddress.into()) - ); - } - - fn initialize_claim_test() -> Claim { - let mut pool_info = create_stake_pool_default(); - - let user_withdrawer_key = Pubkey::new_unique(); - - let stake_balance = sol_to_lamports(20.0); - let tokens_to_issue = 20_000_000_000; - - let mut pool_token_receiver = create_token_account( - &TOKEN_PROGRAM_ID, - &pool_info.mint_key, - &mut pool_info.mint_account, - ); - let deposit_info = do_deposit(&mut pool_info, stake_balance, &mut pool_token_receiver); - - // Need to deposit more to cover deposit fee - let fee_amount = stake_balance * FEE_DEFAULT.numerator / FEE_DEFAULT.denominator; - let extra_deposit = (fee_amount * FEE_DEFAULT.denominator) - / (FEE_DEFAULT.denominator - FEE_DEFAULT.numerator); - - let _extra_deposit_info = - do_deposit(&mut pool_info, extra_deposit, &mut pool_token_receiver); - - Claim { - tokens_to_issue, - allow_burn_to: pool_info.withdraw_authority_key, - pool_info, - user_withdrawer_key, - pool_token_receiver, - deposit_info, - } - } - - #[test] - fn test_claim() { - let mut test_data = initialize_claim_test(); - let claim_info = do_claim(&mut test_data); - - assert_eq!(claim_info.result, Ok(())); - - let user_token_state = - SplAccount::unpack_from_slice(&test_data.pool_token_receiver.account.data) - .expect("User token account is not initialized after withdraw"); - assert_eq!(user_token_state.amount, 0); - - // TODO: Check deposit_info.stake_account_account Withdrawer to change to user_withdrawer_key - } - #[test] - fn negative_test_claim_not_enough_approved() { - let mut test_data = initialize_claim_test(); - test_data.tokens_to_issue /= 2; // Approve less tokens for burning than required - let claim_info = do_claim(&mut test_data); - - assert_eq!(claim_info.result, Err(TokenError::InsufficientFunds.into())); - } - #[test] - fn negative_test_claim_approve_to_wrong_account() { - let mut test_data = initialize_claim_test(); - test_data.allow_burn_to = test_data.pool_info.deposit_authority_key; // Change token burn authority - let claim_info = do_claim(&mut test_data); - - assert_eq!(claim_info.result, Err(TokenError::OwnerMismatch.into())); - } - #[test] - fn negative_test_claim_twice() { - let mut test_data = initialize_claim_test(); - let claim_info = do_claim(&mut test_data); - - assert_eq!(claim_info.result, Ok(())); - - let result = do_process_instruction( - claim( - &STAKE_POOL_PROGRAM_ID, - &test_data.pool_info.pool_key, - &test_data.pool_info.withdraw_authority_key, - &test_data.deposit_info.stake_account_key, - &test_data.user_withdrawer_key, - &test_data.pool_token_receiver.key, - &test_data.pool_info.mint_key, - &TOKEN_PROGRAM_ID, - &stake_program_id(), - ) - .unwrap(), - vec![ - &mut test_data.pool_info.pool_account, - &mut Account::default(), - &mut test_data.deposit_info.stake_account_account, - &mut Account::default(), - &mut test_data.pool_token_receiver.account, - &mut test_data.pool_info.mint_account, - &mut Account::default(), - &mut Account::default(), - &mut Account::default(), - ], - ); - - assert_eq!(result, Err(Error::InvalidProgramAddress.into())); - } - - #[test] - fn test_set_staking_authority() { - let mut pool_info = create_stake_pool_default(); - let stake_balance = sol_to_lamports(10.0); - - let stake_key = Pubkey::new_unique(); - let mut stake_account = Account::new(stake_balance, STAKE_ACCOUNT_LEN, &stake_program_id()); - let new_authority_key = Pubkey::new_unique(); - let mut new_authority_account = - Account::new(stake_balance, STAKE_ACCOUNT_LEN, &stake_program_id()); - - let _result = do_process_instruction( - set_staking_authority( - &STAKE_POOL_PROGRAM_ID, - &pool_info.pool_key, - &pool_info.owner_key, - &pool_info.withdraw_authority_key, - &stake_key, - &new_authority_key, - &stake_program_id(), - ) - .unwrap(), - vec![ - &mut pool_info.pool_account, - &mut pool_info.owner_fee_account, - &mut Account::default(), - &mut stake_account, - &mut new_authority_account, - &mut Account::default(), - &mut Account::default(), - ], - ) - .expect("Error on set_owner"); - } - #[test] - fn negative_test_set_staking_authority_owner() { - let mut pool_info = create_stake_pool_default(); - let stake_balance = sol_to_lamports(10.0); - - let stake_key = Pubkey::new_unique(); - let mut stake_account = Account::new(stake_balance, STAKE_ACCOUNT_LEN, &stake_program_id()); - let new_authority_key = Pubkey::new_unique(); - let mut new_authority_account = - Account::new(stake_balance, STAKE_ACCOUNT_LEN, &stake_program_id()); - - let result = do_process_instruction( - set_staking_authority( - &STAKE_POOL_PROGRAM_ID, - &pool_info.pool_key, - &Pubkey::new_unique(), - &pool_info.withdraw_authority_key, - &stake_key, - &new_authority_key, - &stake_program_id(), - ) - .unwrap(), - vec![ - &mut pool_info.pool_account, - &mut Account::default(), - &mut Account::default(), - &mut stake_account, - &mut new_authority_account, - &mut Account::default(), - &mut Account::default(), - ], - ); - - assert_eq!(result, Err(Error::InvalidInput.into())); - } - #[test] - fn negative_test_set_staking_authority_signer() { - let mut pool_info = create_stake_pool_default(); - let stake_balance = sol_to_lamports(10.0); - - let stake_key = Pubkey::new_unique(); - let mut stake_account = Account::new(stake_balance, STAKE_ACCOUNT_LEN, &stake_program_id()); - let new_authority_key = Pubkey::new_unique(); - let mut new_authority_account = - Account::new(stake_balance, STAKE_ACCOUNT_LEN, &stake_program_id()); - - let result = do_process_instruction( - set_staking_authority_without_signer( - &STAKE_POOL_PROGRAM_ID, - &pool_info.pool_key, - &Pubkey::new_unique(), - &pool_info.withdraw_authority_key, - &stake_key, - &new_authority_key, - &stake_program_id(), - ) - .unwrap(), - vec![ - &mut pool_info.pool_account, - &mut pool_info.owner_fee_account, - &mut Account::default(), - &mut stake_account, - &mut new_authority_account, - &mut Account::default(), - &mut Account::default(), - ], - ); - assert_eq!(result, Err(Error::InvalidInput.into())); - } - - #[test] - fn test_set_owner() { - let mut pool_info = create_stake_pool_default(); - - let new_owner_key = Pubkey::new_unique(); - let mut new_owner_account = Account::default(); - - let mut new_owner_fee = create_token_account( - &TOKEN_PROGRAM_ID, - &pool_info.mint_key, - &mut pool_info.mint_account, - ); - - let _result = do_process_instruction( - set_owner( - &STAKE_POOL_PROGRAM_ID, - &pool_info.pool_key, - &pool_info.owner_key, - &new_owner_key, - &new_owner_fee.key, - ) - .unwrap(), - vec![ - &mut pool_info.pool_account, - &mut pool_info.owner_account, - &mut new_owner_account, - &mut new_owner_fee.account, - ], - ) - .expect("Error on set_owner"); - - let state = State::deserialize(&pool_info.pool_account.data).unwrap(); - assert!( - matches!(state, State::Init(stake_pool) if stake_pool.owner == new_owner_key && stake_pool.owner_fee_account == new_owner_fee.key) - ); - } - #[test] - fn negative_test_set_owner_owner() { - let mut pool_info = create_stake_pool_default(); - - let new_owner_key = Pubkey::new_unique(); - let mut new_owner_account = Account::default(); - - let mut new_owner_fee = create_token_account( - &TOKEN_PROGRAM_ID, - &pool_info.mint_key, - &mut pool_info.mint_account, - ); - - let result = do_process_instruction( - set_owner( - &STAKE_POOL_PROGRAM_ID, - &pool_info.pool_key, - &Pubkey::new_unique(), - &new_owner_key, - &new_owner_fee.key, - ) - .unwrap(), - vec![ - &mut pool_info.pool_account, - &mut Account::default(), - &mut new_owner_account, - &mut new_owner_fee.account, - ], - ); - - assert_eq!(result, Err(Error::InvalidInput.into())); - } - #[test] - fn negative_test_set_owner_signer() { - let mut pool_info = create_stake_pool_default(); - - let new_owner_key = Pubkey::new_unique(); - let mut new_owner_account = Account::default(); - - let mut new_owner_fee = create_token_account( - &TOKEN_PROGRAM_ID, - &pool_info.mint_key, - &mut pool_info.mint_account, - ); - - let result = do_process_instruction( - set_owner_without_signer( - &STAKE_POOL_PROGRAM_ID, - &pool_info.pool_key, - &pool_info.owner_key, - &new_owner_key, - &new_owner_fee.key, - ) - .unwrap(), - vec![ - &mut pool_info.pool_account, - &mut pool_info.owner_account, - &mut new_owner_account, - &mut new_owner_fee.account, - ], - ); - - assert_eq!(result, Err(Error::InvalidInput.into())); - } } diff --git a/program/src/stake.rs b/program/src/stake.rs index 61bc63c4..0a49cc22 100644 --- a/program/src/stake.rs +++ b/program/src/stake.rs @@ -7,9 +7,12 @@ use solana_program::{ pubkey::Pubkey, system_instruction, sysvar, }; +use std::str::FromStr; solana_program::declare_id!("Stake11111111111111111111111111111111111111"); +const STAKE_CONFIG: &str = "StakeConfig11111111111111111111111111111111"; + /// FIXME copied from solana stake program #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] pub enum StakeInstruction { @@ -257,7 +260,7 @@ pub fn create_account( } /// FIXME copied from the stake program -fn initialize(stake_pubkey: &Pubkey, authorized: &Authorized, lockup: &Lockup) -> Instruction { +pub fn initialize(stake_pubkey: &Pubkey, authorized: &Authorized, lockup: &Lockup) -> Instruction { Instruction::new( id(), &StakeInstruction::Initialize(*authorized, *lockup), @@ -267,3 +270,20 @@ fn initialize(stake_pubkey: &Pubkey, authorized: &Authorized, lockup: &Lockup) - ], ) } + +/// FIXME copied from the stake program +pub fn delegate_stake( + stake_pubkey: &Pubkey, + authorized_pubkey: &Pubkey, + vote_pubkey: &Pubkey, +) -> Instruction { + let account_metas = vec![ + AccountMeta::new(*stake_pubkey, false), + AccountMeta::new_readonly(*vote_pubkey, false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(sysvar::stake_history::id(), false), + AccountMeta::new_readonly(Pubkey::from_str(STAKE_CONFIG).unwrap(), false), + AccountMeta::new_readonly(*authorized_pubkey, true), + ]; + Instruction::new(id(), &StakeInstruction::DelegateStake, account_metas) +} diff --git a/program/src/state.rs b/program/src/state.rs index 1bae9a7d..02bad925 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -1,14 +1,22 @@ //! State transition types -use crate::error::Error; +use crate::error::StakePoolError; use crate::instruction::{unpack, Fee}; -use solana_program::{entrypoint::ProgramResult, program_error::ProgramError, pubkey::Pubkey}; +use crate::processor::Processor; +use core::convert::TryInto; +use solana_program::{ + account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, + pubkey::Pubkey, +}; +use std::convert::TryFrom; use std::mem::size_of; /// Initialized program details. #[repr(C)] #[derive(Clone, Copy, Debug, Default, PartialEq)] pub struct StakePool { + /// Pool version + pub version: u8, /// Owner authority /// allows for updating the staking authority pub owner: Pubkey, @@ -18,6 +26,8 @@ pub struct StakePool { /// Withdrawal authority bump seed /// for `create_program_address(&[state::StakePool account, "withdrawal"])` pub withdraw_bump_seed: u8, + /// Validator stake list storage account + pub validator_stake_list: Pubkey, /// Pool Mint pub pool_mint: Pubkey, /// Owner fee account @@ -28,37 +38,88 @@ pub struct StakePool { pub stake_total: u64, /// total pool pub pool_total: u64, + /// Last epoch stake_total field was updated + pub last_update_epoch: u64, /// Fee applied to deposits pub fee: Fee, } impl StakePool { /// calculate the pool tokens that should be minted - pub fn calc_pool_deposit_amount(&self, stake_lamports: u64) -> Option { + pub fn calc_pool_deposit_amount(&self, stake_lamports: u64) -> Option { if self.stake_total == 0 { - return Some(stake_lamports as u128); + return Some(stake_lamports); } self.calc_pool_withdraw_amount(stake_lamports) } /// calculate the pool tokens that should be withdrawn - pub fn calc_pool_withdraw_amount(&self, stake_lamports: u64) -> Option { - (stake_lamports as u128) - .checked_mul(self.pool_total as u128)? - .checked_div(self.stake_total as u128) + pub fn calc_pool_withdraw_amount(&self, stake_lamports: u64) -> Option { + u64::try_from( + (stake_lamports as u128) + .checked_mul(self.pool_total as u128)? + .checked_div(self.stake_total as u128)?, + ) + .ok() } /// calculate the fee in pool tokens that goes to the owner - pub fn calc_fee_amount(&self, pool_amount: u128) -> Option { + pub fn calc_fee_amount(&self, pool_amount: u64) -> Option { if self.fee.denominator == 0 { return Some(0); } - pool_amount - .checked_mul(self.fee.numerator as u128)? - .checked_div(self.fee.denominator as u128) + u64::try_from( + (pool_amount as u128) + .checked_mul(self.fee.numerator as u128)? + .checked_div(self.fee.denominator as u128)?, + ) + .ok() + } + + /// Checks withdraw authority + pub fn check_authority_withdraw( + &self, + authority_to_check: &Pubkey, + program_id: &Pubkey, + stake_pool_key: &Pubkey, + ) -> Result<(), ProgramError> { + Processor::check_authority( + authority_to_check, + program_id, + stake_pool_key, + Processor::AUTHORITY_WITHDRAW, + self.withdraw_bump_seed, + ) + } + /// Checks deposit authority + pub fn check_authority_deposit( + &self, + authority_to_check: &Pubkey, + program_id: &Pubkey, + stake_pool_key: &Pubkey, + ) -> Result<(), ProgramError> { + Processor::check_authority( + authority_to_check, + program_id, + stake_pool_key, + Processor::AUTHORITY_DEPOSIT, + self.deposit_bump_seed, + ) + } + + /// Check owner validity and signature + pub fn check_owner(&self, owner_info: &AccountInfo) -> Result<(), ProgramError> { + if *owner_info.key != self.owner { + return Err(StakePoolError::WrongOwner.into()); + } + if !owner_info.is_signer { + return Err(StakePoolError::SignatureMissing.into()); + } + Ok(()) } } /// Program states. #[repr(C)] #[derive(Clone, Copy, Debug, PartialEq)] +#[allow(clippy::large_enum_variant)] pub enum State { /// Unallocated state, may be initialized into another state. Unallocated, @@ -111,7 +172,200 @@ impl State { if let State::Init(swap) = &self { Ok(*swap) } else { - Err(Error::InvalidState.into()) + Err(StakePoolError::InvalidState.into()) + } + } +} + +const MAX_VALIDATOR_STAKE_ACCOUNTS: usize = 1000; + +/// Storage list for all validator stake accounts in the pool. +#[repr(C)] +#[derive(Clone, Debug, Default, PartialEq)] +pub struct ValidatorStakeList { + /// False if not yet initialized + pub is_initialized: bool, + /// List of all validator stake accounts and their info + pub validators: Vec, +} + +/// Information about the singe validator stake account +#[repr(C)] +#[derive(Clone, Copy, Debug, Default, PartialEq)] +pub struct ValidatorStakeInfo { + /// Validator account pubkey + pub validator_account: Pubkey, + + /// Account balance in lamports + pub balance: u64, + + /// Last epoch balance field was updated + pub last_update_epoch: u64, +} + +impl ValidatorStakeList { + /// Length of ValidatorStakeList data when serialized + pub const LEN: usize = + Self::HEADER_LEN + ValidatorStakeInfo::LEN * MAX_VALIDATOR_STAKE_ACCOUNTS; + + /// Header length + pub const HEADER_LEN: usize = size_of::() + size_of::(); + + /// Check if contains validator with particular pubkey + pub fn contains(&self, validator: &Pubkey) -> bool { + self.validators + .iter() + .any(|x| x.validator_account == *validator) + } + + /// Check if contains validator with particular pubkey (mutable) + pub fn find_mut(&mut self, validator: &Pubkey) -> Option<&mut ValidatorStakeInfo> { + self.validators + .iter_mut() + .find(|x| x.validator_account == *validator) + } + /// Check if contains validator with particular pubkey (immutable) + pub fn find(&self, validator: &Pubkey) -> Option<&ValidatorStakeInfo> { + self.validators + .iter() + .find(|x| x.validator_account == *validator) + } + + /// Deserializes a byte buffer into a ValidatorStakeList. + pub fn deserialize(input: &[u8]) -> Result { + if input.len() < Self::LEN { + return Err(ProgramError::InvalidAccountData); + } + + if input[0] == 0 { + return Ok(ValidatorStakeList { + is_initialized: false, + validators: vec![], + }); + } + + let number_of_validators: usize = u16::from_le_bytes( + input[1..3] + .try_into() + .or(Err(ProgramError::InvalidAccountData))?, + ) as usize; + if number_of_validators > MAX_VALIDATOR_STAKE_ACCOUNTS { + return Err(ProgramError::InvalidAccountData); } + let mut validators: Vec = Vec::with_capacity(number_of_validators); + + let mut from = Self::HEADER_LEN; + let mut to = from + ValidatorStakeInfo::LEN; + for _ in 0..number_of_validators { + validators.push(ValidatorStakeInfo::deserialize(&input[from..to])?); + from += ValidatorStakeInfo::LEN; + to += ValidatorStakeInfo::LEN; + } + Ok(ValidatorStakeList { + is_initialized: true, + validators, + }) + } + + /// Serializes ValidatorStakeList into a byte buffer. + pub fn serialize(&self, output: &mut [u8]) -> ProgramResult { + if output.len() < Self::LEN { + return Err(ProgramError::InvalidAccountData); + } + if self.validators.len() > MAX_VALIDATOR_STAKE_ACCOUNTS { + return Err(ProgramError::InvalidAccountData); + } + output[0] = if self.is_initialized { 1 } else { 0 }; + output[1..3].copy_from_slice(&u16::to_le_bytes(self.validators.len() as u16)); + let mut from = Self::HEADER_LEN; + let mut to = from + ValidatorStakeInfo::LEN; + for validator in &self.validators { + validator.serialize(&mut output[from..to])?; + from += ValidatorStakeInfo::LEN; + to += ValidatorStakeInfo::LEN; + } + Ok(()) + } +} + +impl ValidatorStakeInfo { + /// Length of ValidatorStakeInfo data when serialized + pub const LEN: usize = size_of::(); + + /// Deserializes a byte buffer into a ValidatorStakeInfo. + pub fn deserialize(input: &[u8]) -> Result { + if input.len() < Self::LEN { + return Err(ProgramError::InvalidAccountData); + } + #[allow(clippy::cast_ptr_alignment)] + let stake_info: &ValidatorStakeInfo = + unsafe { &*(&input[0] as *const u8 as *const ValidatorStakeInfo) }; + Ok(*stake_info) + } + + /// Serializes ValidatorStakeInfo into a byte buffer. + pub fn serialize(&self, output: &mut [u8]) -> ProgramResult { + if output.len() < Self::LEN { + return Err(ProgramError::InvalidAccountData); + } + + #[allow(clippy::cast_ptr_alignment)] + let value = unsafe { &mut *(&mut output[0] as *mut u8 as *mut ValidatorStakeInfo) }; + *value = *self; + Ok(()) + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_state_packing() { + // Not initialized + let stake_list = ValidatorStakeList { + is_initialized: false, + validators: vec![], + }; + let mut bytes: [u8; ValidatorStakeList::LEN] = [0; ValidatorStakeList::LEN]; + stake_list.serialize(&mut bytes).unwrap(); + let stake_list_unpacked = ValidatorStakeList::deserialize(&bytes).unwrap(); + assert_eq!(stake_list_unpacked, stake_list); + + // Empty + let stake_list = ValidatorStakeList { + is_initialized: true, + validators: vec![], + }; + let mut bytes: [u8; ValidatorStakeList::LEN] = [0; ValidatorStakeList::LEN]; + stake_list.serialize(&mut bytes).unwrap(); + let stake_list_unpacked = ValidatorStakeList::deserialize(&bytes).unwrap(); + assert_eq!(stake_list_unpacked, stake_list); + + // With several accounts + let stake_list = ValidatorStakeList { + is_initialized: true, + validators: vec![ + ValidatorStakeInfo { + validator_account: Pubkey::new_from_array([1; 32]), + balance: 123456789, + last_update_epoch: 987654321, + }, + ValidatorStakeInfo { + validator_account: Pubkey::new_from_array([2; 32]), + balance: 998877665544, + last_update_epoch: 11223445566, + }, + ValidatorStakeInfo { + validator_account: Pubkey::new_from_array([3; 32]), + balance: 0, + last_update_epoch: 999999999999999, + }, + ], + }; + let mut bytes: [u8; ValidatorStakeList::LEN] = [0; ValidatorStakeList::LEN]; + stake_list.serialize(&mut bytes).unwrap(); + let stake_list_unpacked = ValidatorStakeList::deserialize(&bytes).unwrap(); + assert_eq!(stake_list_unpacked, stake_list); } } diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs new file mode 100644 index 00000000..fbb1f866 --- /dev/null +++ b/program/tests/deposit.rs @@ -0,0 +1,145 @@ +#![cfg(feature = "test-bpf")] + +mod helpers; + +use helpers::*; + +use solana_sdk::signature::{Keypair, Signer}; +use spl_stake_pool::*; + +#[tokio::test] +async fn test_stake_pool_deposit() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await; + + let validator_stake_account: StakeAccount = simple_add_validator_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + ) + .await; + + let user = Keypair::new(); + // make stake account + let user_stake = Keypair::new(); + let lockup = stake::Lockup::default(); + let authorized = stake::Authorized { + staker: stake_pool_accounts.deposit_authority, + withdrawer: stake_pool_accounts.deposit_authority, + }; + let stake_lamports = create_independent_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake, + &authorized, + &lockup, + ) + .await; + // make pool token account + let user_pool_account = Keypair::new(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user.pubkey(), + ) + .await; + + // Save stake pool state before depositing + let stake_pool_before = + get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; + let stake_pool_before = state::State::deserialize(&stake_pool_before.data.as_slice()) + .unwrap() + .stake_pool() + .unwrap(); + + // Save validator stake account record before depositing + let validator_stake_list = get_account( + &mut banks_client, + &stake_pool_accounts.validator_stake_list.pubkey(), + ) + .await; + let validator_stake_list = + state::ValidatorStakeList::deserialize(validator_stake_list.data.as_slice()).unwrap(); + let validator_stake_item_before = validator_stake_list + .find(&validator_stake_account.vote.pubkey()) + .unwrap(); + + stake_pool_accounts + .deposit_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.pubkey(), + &user_pool_account.pubkey(), + &validator_stake_account.stake_account, + ) + .await; + + // Original stake account should be drained + assert!(banks_client + .get_account(user_stake.pubkey()) + .await + .expect("get_account") + .is_none()); + + let tokens_issued = stake_lamports; // For now tokens are 1:1 to stake + let fee = stake_pool_accounts.calculate_fee(tokens_issued); + + // Stake pool should add its balance to the pool balance + let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; + let stake_pool = state::State::deserialize(&stake_pool.data.as_slice()) + .unwrap() + .stake_pool() + .unwrap(); + assert_eq!( + stake_pool.stake_total, + stake_pool_before.stake_total + stake_lamports + ); + assert_eq!( + stake_pool.pool_total, + stake_pool_before.pool_total + tokens_issued + ); + + // Check minted tokens + let user_token_balance = + get_token_balance(&mut banks_client, &user_pool_account.pubkey()).await; + assert_eq!(user_token_balance, tokens_issued - fee); + let pool_fee_token_balance = get_token_balance( + &mut banks_client, + &stake_pool_accounts.pool_fee_account.pubkey(), + ) + .await; + assert_eq!(pool_fee_token_balance, fee); + + // Check balances in validator stake account list storage + let validator_stake_list = get_account( + &mut banks_client, + &stake_pool_accounts.validator_stake_list.pubkey(), + ) + .await; + let validator_stake_list = + state::ValidatorStakeList::deserialize(validator_stake_list.data.as_slice()).unwrap(); + let validator_stake_item = validator_stake_list + .find(&validator_stake_account.vote.pubkey()) + .unwrap(); + assert_eq!( + validator_stake_item.balance, + validator_stake_item_before.balance + stake_lamports + ); + + // Check validator stake account actual SOL balance + let validator_stake_account = + get_account(&mut banks_client, &validator_stake_account.stake_account).await; + assert_eq!( + validator_stake_account.lamports, + validator_stake_item.balance + ); +} diff --git a/program/tests/functional.rs b/program/tests/functional.rs deleted file mode 100644 index 5833dfac..00000000 --- a/program/tests/functional.rs +++ /dev/null @@ -1,347 +0,0 @@ -#![cfg(feature = "test-bpf")] - -use solana_program::{hash::Hash, program_pack::Pack, pubkey::Pubkey, system_instruction}; -use solana_program_test::*; -use solana_sdk::{ - signature::{Keypair, Signer}, - transaction::Transaction, -}; -use spl_stake_pool::*; - -use bincode::deserialize; - -const TEST_STAKE_AMOUNT: u64 = 100; - -fn program_test() -> ProgramTest { - ProgramTest::new( - "spl_stake_pool", - id(), - processor!(processor::Processor::process), - ) -} - -async fn create_mint( - banks_client: &mut BanksClient, - payer: &Keypair, - recent_blockhash: &Hash, - pool_mint: &Keypair, - owner: &Pubkey, -) { - let rent = banks_client.get_rent().await.unwrap(); - let mint_rent = rent.minimum_balance(spl_token::state::Mint::LEN); - - let mut transaction = Transaction::new_with_payer( - &[ - system_instruction::create_account( - &payer.pubkey(), - &pool_mint.pubkey(), - mint_rent, - spl_token::state::Mint::LEN as u64, - &spl_token::id(), - ), - spl_token::instruction::initialize_mint( - &spl_token::id(), - &pool_mint.pubkey(), - &owner, - None, - 0, - ) - .unwrap(), - ], - Some(&payer.pubkey()), - ); - transaction.sign(&[payer, pool_mint], *recent_blockhash); - banks_client.process_transaction(transaction).await.unwrap(); -} - -async fn create_token_account( - banks_client: &mut BanksClient, - payer: &Keypair, - recent_blockhash: &Hash, - account: &Keypair, - pool_mint: &Pubkey, - owner: &Pubkey, -) { - let rent = banks_client.get_rent().await.unwrap(); - let account_rent = rent.minimum_balance(spl_token::state::Account::LEN); - - let mut transaction = Transaction::new_with_payer( - &[ - system_instruction::create_account( - &payer.pubkey(), - &account.pubkey(), - account_rent, - spl_token::state::Account::LEN as u64, - &spl_token::id(), - ), - spl_token::instruction::initialize_account( - &spl_token::id(), - &account.pubkey(), - pool_mint, - owner, - ) - .unwrap(), - ], - Some(&payer.pubkey()), - ); - transaction.sign(&[payer, account], *recent_blockhash); - banks_client.process_transaction(transaction).await.unwrap(); -} - -async fn create_stake_pool( - banks_client: &mut BanksClient, - payer: &Keypair, - recent_blockhash: &Hash, - stake_pool: &Keypair, - pool_mint: &Pubkey, - pool_token_account: &Pubkey, - owner: &Pubkey, -) { - let rent = banks_client.get_rent().await.unwrap(); - let rent = rent.minimum_balance(state::State::LEN); - let numerator = 1; - let denominator = 100; - let fee = instruction::Fee { - numerator, - denominator, - }; - let init_args = instruction::InitArgs { fee }; - - let mut transaction = Transaction::new_with_payer( - &[ - system_instruction::create_account( - &payer.pubkey(), - &stake_pool.pubkey(), - rent, - state::State::LEN as u64, - &id(), - ), - instruction::initialize( - &id(), - &stake_pool.pubkey(), - owner, - pool_mint, - pool_token_account, - &spl_token::id(), - init_args, - ) - .unwrap(), - ], - Some(&payer.pubkey()), - ); - transaction.sign(&[payer, stake_pool], *recent_blockhash); - banks_client.process_transaction(transaction).await.unwrap(); -} - -async fn create_stake_account( - banks_client: &mut BanksClient, - payer: &Keypair, - recent_blockhash: &Hash, - stake: &Keypair, - authorized: &stake::Authorized, - lockup: &stake::Lockup, -) { - let rent = banks_client.get_rent().await.unwrap(); - let lamports = - rent.minimum_balance(std::mem::size_of::()) + TEST_STAKE_AMOUNT; - - let mut transaction = Transaction::new_with_payer( - &stake::create_account( - &payer.pubkey(), - &stake.pubkey(), - authorized, - lockup, - lamports, - ), - Some(&payer.pubkey()), - ); - transaction.sign(&[payer, stake], *recent_blockhash); - banks_client.process_transaction(transaction).await.unwrap(); -} - -struct StakePoolAccounts { - pub stake_pool: Keypair, - pub pool_mint: Keypair, - pub pool_fee_account: Keypair, - pub owner: Pubkey, - pub withdraw_authority: Pubkey, - pub deposit_authority: Pubkey, -} - -impl StakePoolAccounts { - pub fn new() -> Self { - let stake_pool = Keypair::new(); - let stake_pool_address = &stake_pool.pubkey(); - let (withdraw_authority, _) = Pubkey::find_program_address( - &[&stake_pool_address.to_bytes()[..32], b"withdraw"], - &id(), - ); - let (deposit_authority, _) = Pubkey::find_program_address( - &[&stake_pool_address.to_bytes()[..32], b"deposit"], - &id(), - ); - let pool_mint = Keypair::new(); - let pool_fee_account = Keypair::new(); - let owner = Pubkey::new_unique(); - - Self { - stake_pool, - pool_mint, - pool_fee_account, - owner, - withdraw_authority, - deposit_authority, - } - } - - pub async fn initialize_stake_pool( - &self, - mut banks_client: &mut BanksClient, - payer: &Keypair, - recent_blockhash: &Hash, - ) { - create_mint( - &mut banks_client, - &payer, - &recent_blockhash, - &self.pool_mint, - &self.withdraw_authority, - ) - .await; - create_token_account( - &mut banks_client, - &payer, - &recent_blockhash, - &self.pool_fee_account, - &self.pool_mint.pubkey(), - &self.owner, - ) - .await; - create_stake_pool( - &mut banks_client, - &payer, - &recent_blockhash, - &self.stake_pool, - &self.pool_mint.pubkey(), - &self.pool_fee_account.pubkey(), - &self.owner, - ) - .await; - } - - pub async fn deposit_stake( - &self, - stake: &Pubkey, - pool_account: &Pubkey, - banks_client: &mut BanksClient, - payer: &Keypair, - recent_blockhash: &Hash, - ) { - let mut transaction = Transaction::new_with_payer( - &[instruction::deposit( - &id(), - &self.stake_pool.pubkey(), - &self.deposit_authority, - &self.withdraw_authority, - stake, - pool_account, - &self.pool_fee_account.pubkey(), - &self.pool_mint.pubkey(), - &spl_token::id(), - &stake::id(), - ) - .unwrap()], - Some(&payer.pubkey()), - ); - transaction.sign(&[payer], *recent_blockhash); - banks_client.process_transaction(transaction).await.unwrap(); - } -} - -#[tokio::test] -async fn test_stake_pool_initialize() { - let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); - stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) - .await; - - // Stake pool now exists - let stake_pool = banks_client - .get_account(stake_pool_accounts.stake_pool.pubkey()) - .await - .expect("get_account") - .expect("stake pool not none"); - assert_eq!(stake_pool.data.len(), state::State::LEN); - assert_eq!(stake_pool.owner, id()); -} - -#[tokio::test] -async fn test_stake_pool_deposit() { - let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); - stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) - .await; - - let user = Keypair::new(); - // make stake account - let user_stake = Keypair::new(); - let lockup = stake::Lockup::default(); - let authorized = stake::Authorized { - staker: stake_pool_accounts.deposit_authority.clone(), - withdrawer: stake_pool_accounts.deposit_authority.clone(), - }; - create_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake, - &authorized, - &lockup, - ) - .await; - // make pool token account - let user_pool_account = Keypair::new(); - create_token_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_pool_account, - &stake_pool_accounts.pool_mint.pubkey(), - &user.pubkey(), - ) - .await; - stake_pool_accounts - .deposit_stake( - &user_stake.pubkey(), - &user_pool_account.pubkey(), - &mut banks_client, - &payer, - &recent_blockhash, - ) - .await; - - let stake = banks_client - .get_account(user_stake.pubkey()) - .await - .expect("get_account") - .expect("stake not none"); - assert_eq!(stake.data.len(), std::mem::size_of::()); - assert_eq!(stake.owner, stake::id()); - - let stake_state = deserialize::(&stake.data).unwrap(); - match stake_state { - stake::StakeState::Initialized(meta) => { - assert_eq!( - &meta.authorized.staker, - &stake_pool_accounts.withdraw_authority - ); - assert_eq!( - &meta.authorized.withdrawer, - &stake_pool_accounts.withdraw_authority - ); - } - _ => assert!(false), - } -} diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs new file mode 100644 index 00000000..6de4df35 --- /dev/null +++ b/program/tests/helpers/mod.rs @@ -0,0 +1,732 @@ +#![allow(dead_code)] + +use solana_program::{hash::Hash, program_pack::Pack, pubkey::Pubkey, system_instruction}; +use solana_program_test::*; +use solana_sdk::{ + account::Account, + signature::{Keypair, Signer}, + transaction::Transaction, + transport::TransportError, +}; +use solana_vote_program::{self, vote_state::VoteState}; +use spl_stake_pool::*; + +pub const TEST_STAKE_AMOUNT: u64 = 100; + +pub fn program_test() -> ProgramTest { + ProgramTest::new( + "spl_stake_pool", + id(), + processor!(processor::Processor::process), + ) +} + +pub async fn get_account(banks_client: &mut BanksClient, pubkey: &Pubkey) -> Account { + banks_client + .get_account(*pubkey) + .await + .expect("account not found") + .expect("account empty") +} + +async fn create_mint( + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + pool_mint: &Keypair, + owner: &Pubkey, +) { + let rent = banks_client.get_rent().await.unwrap(); + let mint_rent = rent.minimum_balance(spl_token::state::Mint::LEN); + + let mut transaction = Transaction::new_with_payer( + &[ + system_instruction::create_account( + &payer.pubkey(), + &pool_mint.pubkey(), + mint_rent, + spl_token::state::Mint::LEN as u64, + &spl_token::id(), + ), + spl_token::instruction::initialize_mint( + &spl_token::id(), + &pool_mint.pubkey(), + &owner, + None, + 0, + ) + .unwrap(), + ], + Some(&payer.pubkey()), + ); + transaction.sign(&[payer, pool_mint], *recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); +} + +pub async fn transfer( + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + recipient: &Pubkey, + amount: u64, +) { + let mut transaction = Transaction::new_with_payer( + &[system_instruction::transfer( + &payer.pubkey(), + recipient, + amount, + )], + Some(&payer.pubkey()), + ); + transaction.sign(&[payer], *recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); +} + +pub async fn create_token_account( + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + account: &Keypair, + pool_mint: &Pubkey, + owner: &Pubkey, +) { + let rent = banks_client.get_rent().await.unwrap(); + let account_rent = rent.minimum_balance(spl_token::state::Account::LEN); + + let mut transaction = Transaction::new_with_payer( + &[ + system_instruction::create_account( + &payer.pubkey(), + &account.pubkey(), + account_rent, + spl_token::state::Account::LEN as u64, + &spl_token::id(), + ), + spl_token::instruction::initialize_account( + &spl_token::id(), + &account.pubkey(), + pool_mint, + owner, + ) + .unwrap(), + ], + Some(&payer.pubkey()), + ); + transaction.sign(&[payer, account], *recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); +} + +pub async fn get_token_balance(banks_client: &mut BanksClient, token: &Pubkey) -> u64 { + let token_account = banks_client + .get_account(token.clone()) + .await + .unwrap() + .unwrap(); + let account_info: spl_token::state::Account = + spl_token::state::Account::unpack_from_slice(token_account.data.as_slice()).unwrap(); + account_info.amount +} + +pub async fn delegate_tokens( + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + account: &Pubkey, + owner: &Keypair, + delegate: &Pubkey, + amount: u64, +) { + let mut transaction = Transaction::new_with_payer( + &[spl_token::instruction::approve( + &spl_token::id(), + &account, + &delegate, + &owner.pubkey(), + &[], + amount, + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[payer, owner], *recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); +} + +#[allow(clippy::too_many_arguments)] +async fn create_stake_pool( + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + stake_pool: &Keypair, + validator_stake_list: &Keypair, + pool_mint: &Pubkey, + pool_token_account: &Pubkey, + owner: &Pubkey, + fee: &instruction::Fee, +) { + let rent = banks_client.get_rent().await.unwrap(); + let rent_stake_pool = rent.minimum_balance(state::State::LEN); + let rent_validator_stake_list = rent.minimum_balance(state::ValidatorStakeList::LEN); + let init_args = instruction::InitArgs { fee: *fee }; + + let mut transaction = Transaction::new_with_payer( + &[ + system_instruction::create_account( + &payer.pubkey(), + &stake_pool.pubkey(), + rent_stake_pool, + state::State::LEN as u64, + &id(), + ), + system_instruction::create_account( + &payer.pubkey(), + &validator_stake_list.pubkey(), + rent_validator_stake_list, + state::ValidatorStakeList::LEN as u64, + &id(), + ), + instruction::initialize( + &id(), + &stake_pool.pubkey(), + owner, + &validator_stake_list.pubkey(), + pool_mint, + pool_token_account, + &spl_token::id(), + init_args, + ) + .unwrap(), + ], + Some(&payer.pubkey()), + ); + transaction.sign( + &[payer, stake_pool, validator_stake_list], + *recent_blockhash, + ); + banks_client.process_transaction(transaction).await.unwrap(); +} + +pub async fn create_vote( + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + vote: &Keypair, +) { + let rent = banks_client.get_rent().await.unwrap(); + let rent_voter = rent.minimum_balance(VoteState::size_of()); + + let mut transaction = Transaction::new_with_payer( + &[system_instruction::create_account( + &payer.pubkey(), + &vote.pubkey(), + rent_voter, + VoteState::size_of() as u64, + &solana_vote_program::id(), + )], + Some(&payer.pubkey()), + ); + transaction.sign(&[&vote, payer], *recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); +} + +pub async fn create_independent_stake_account( + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + stake: &Keypair, + authorized: &stake::Authorized, + lockup: &stake::Lockup, +) -> u64 { + let rent = banks_client.get_rent().await.unwrap(); + let lamports = + rent.minimum_balance(std::mem::size_of::()) + TEST_STAKE_AMOUNT; + + let mut transaction = Transaction::new_with_payer( + &stake::create_account( + &payer.pubkey(), + &stake.pubkey(), + authorized, + lockup, + lamports, + ), + Some(&payer.pubkey()), + ); + transaction.sign(&[payer, stake], *recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); + + lamports +} + +pub async fn create_blank_stake_account( + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + stake: &Keypair, +) -> u64 { + let rent = banks_client.get_rent().await.unwrap(); + let lamports = rent.minimum_balance(std::mem::size_of::()) + 1; + + let mut transaction = Transaction::new_with_payer( + &[system_instruction::create_account( + &payer.pubkey(), + &stake.pubkey(), + lamports, + std::mem::size_of::() as u64, + &stake::id(), + )], + Some(&payer.pubkey()), + ); + transaction.sign(&[payer, stake], *recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); + + lamports +} + +pub async fn create_stake_account( + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + stake_pool: &Pubkey, + stake_account: &Pubkey, + validator: &Pubkey, + stake_authority: &Pubkey, + withdraw_authority: &Pubkey, +) { + let mut transaction = Transaction::new_with_payer( + &[ + instruction::create_validator_stake_account( + &id(), + &stake_pool, + &payer.pubkey(), + &stake_account, + &validator, + &stake_authority, + &withdraw_authority, + &solana_program::system_program::id(), + &stake::id(), + ) + .unwrap(), + system_instruction::transfer(&payer.pubkey(), &stake_account, TEST_STAKE_AMOUNT), + ], + Some(&payer.pubkey()), + ); + transaction.sign(&[payer], *recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); +} + +pub async fn delegate_stake_account( + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + stake: &Pubkey, + authorized: &Keypair, + vote: &Pubkey, +) { + let mut transaction = Transaction::new_with_payer( + &[stake::delegate_stake(&stake, &authorized.pubkey(), &vote)], + Some(&payer.pubkey()), + ); + transaction.sign(&[payer, authorized], *recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); +} + +pub async fn authorize_stake_account( + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + stake: &Pubkey, + authorized: &Keypair, + new_authorized: &Pubkey, + stake_authorize: stake::StakeAuthorize, +) { + let mut transaction = Transaction::new_with_payer( + &[stake::authorize( + &stake, + &authorized.pubkey(), + &new_authorized, + stake_authorize, + )], + Some(&payer.pubkey()), + ); + transaction.sign(&[payer, authorized], *recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); +} + +pub struct StakeAccount { + pub stake_account: Pubkey, + pub target_authority: Pubkey, + pub vote: Keypair, + pub stake_pool: Pubkey, +} + +impl StakeAccount { + pub fn new_with_target_authority(authority: &Pubkey, stake_pool: &Pubkey) -> Self { + let validator = Keypair::new(); + let (stake_account, _) = processor::Processor::find_stake_address_for_validator( + &id(), + &validator.pubkey(), + stake_pool, + ); + StakeAccount { + stake_account, + target_authority: *authority, + vote: validator, + stake_pool: *stake_pool, + } + } + + pub async fn create_and_delegate( + &self, + mut banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + ) { + // make stake account + let user_stake_authority = Keypair::new(); + create_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &self.stake_pool, + &self.stake_account, + &self.vote.pubkey(), + &user_stake_authority.pubkey(), + &self.target_authority, + ) + .await; + + create_vote(&mut banks_client, &payer, &recent_blockhash, &self.vote).await; + delegate_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &self.stake_account, + &user_stake_authority, + &self.vote.pubkey(), + ) + .await; + + authorize_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &self.stake_account, + &user_stake_authority, + &self.target_authority, + stake::StakeAuthorize::Staker, + ) + .await; + } +} + +pub struct StakePoolAccounts { + pub stake_pool: Keypair, + pub validator_stake_list: Keypair, + pub pool_mint: Keypair, + pub pool_fee_account: Keypair, + pub owner: Keypair, + pub withdraw_authority: Pubkey, + pub deposit_authority: Pubkey, + pub fee: instruction::Fee, +} + +impl StakePoolAccounts { + pub fn new() -> Self { + let stake_pool = Keypair::new(); + let validator_stake_list = Keypair::new(); + let stake_pool_address = &stake_pool.pubkey(); + let (withdraw_authority, _) = Pubkey::find_program_address( + &[&stake_pool_address.to_bytes()[..32], b"withdraw"], + &id(), + ); + let (deposit_authority, _) = Pubkey::find_program_address( + &[&stake_pool_address.to_bytes()[..32], b"deposit"], + &id(), + ); + let pool_mint = Keypair::new(); + let pool_fee_account = Keypair::new(); + let owner = Keypair::new(); + + Self { + stake_pool, + validator_stake_list, + pool_mint, + pool_fee_account, + owner, + withdraw_authority, + deposit_authority, + fee: instruction::Fee { + numerator: 1, + denominator: 100, + }, + } + } + + pub fn calculate_fee(&self, amount: u64) -> u64 { + amount * self.fee.numerator / self.fee.denominator + } + + pub async fn initialize_stake_pool( + &self, + mut banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + ) { + create_mint( + &mut banks_client, + &payer, + &recent_blockhash, + &self.pool_mint, + &self.withdraw_authority, + ) + .await; + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &self.pool_fee_account, + &self.pool_mint.pubkey(), + &self.owner.pubkey(), + ) + .await; + create_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &self.stake_pool, + &self.validator_stake_list, + &self.pool_mint.pubkey(), + &self.pool_fee_account.pubkey(), + &self.owner.pubkey(), + &self.fee, + ) + .await; + } + + pub async fn deposit_stake( + &self, + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + stake: &Pubkey, + pool_account: &Pubkey, + validator_stake_account: &Pubkey, + ) { + let mut transaction = Transaction::new_with_payer( + &[instruction::deposit( + &id(), + &self.stake_pool.pubkey(), + &self.validator_stake_list.pubkey(), + &self.deposit_authority, + &self.withdraw_authority, + stake, + validator_stake_account, + pool_account, + &self.pool_fee_account.pubkey(), + &self.pool_mint.pubkey(), + &spl_token::id(), + &stake::id(), + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[payer], *recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); + } + + pub async fn withdraw_stake( + &self, + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + stake_recipient: &Pubkey, + pool_account: &Pubkey, + validator_stake_account: &Pubkey, + recipient_new_authority: &Pubkey, + amount: u64, + ) { + let mut transaction = Transaction::new_with_payer( + &[instruction::withdraw( + &id(), + &self.stake_pool.pubkey(), + &self.validator_stake_list.pubkey(), + &self.withdraw_authority, + validator_stake_account, + stake_recipient, + recipient_new_authority, + pool_account, + &self.pool_mint.pubkey(), + &spl_token::id(), + &stake::id(), + amount, + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[payer], *recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); + } + + pub async fn add_validator_stake_account( + &self, + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + stake: &Pubkey, + pool_account: &Pubkey, + ) -> Option { + let mut transaction = Transaction::new_with_payer( + &[instruction::add_validator_stake_account( + &id(), + &self.stake_pool.pubkey(), + &self.owner.pubkey(), + &self.deposit_authority, + &self.withdraw_authority, + &self.validator_stake_list.pubkey(), + stake, + pool_account, + &self.pool_mint.pubkey(), + &spl_token::id(), + &stake::id(), + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[payer, &self.owner], *recent_blockhash); + banks_client.process_transaction(transaction).await.err() + } + + pub async fn remove_validator_stake_account( + &self, + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + stake: &Pubkey, + pool_account: &Pubkey, + new_authority: &Pubkey, + ) -> Option { + let mut transaction = Transaction::new_with_payer( + &[instruction::remove_validator_stake_account( + &id(), + &self.stake_pool.pubkey(), + &self.owner.pubkey(), + &self.withdraw_authority, + &new_authority, + &self.validator_stake_list.pubkey(), + stake, + pool_account, + &self.pool_mint.pubkey(), + &spl_token::id(), + &stake::id(), + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[payer, &self.owner], *recent_blockhash); + banks_client.process_transaction(transaction).await.err() + } +} + +pub async fn simple_add_validator_stake_account( + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + stake_pool_accounts: &StakePoolAccounts, +) -> StakeAccount { + let user_stake = StakeAccount::new_with_target_authority( + &stake_pool_accounts.deposit_authority, + &stake_pool_accounts.stake_pool.pubkey(), + ); + user_stake + .create_and_delegate(banks_client, &payer, &recent_blockhash) + .await; + + let user_pool_account = Keypair::new(); + let user = Keypair::new(); + create_token_account( + banks_client, + &payer, + &recent_blockhash, + &user_pool_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user.pubkey(), + ) + .await; + let error = stake_pool_accounts + .add_validator_stake_account( + banks_client, + &payer, + &recent_blockhash, + &user_stake.stake_account, + &user_pool_account.pubkey(), + ) + .await; + assert!(error.is_none()); + + user_stake +} + +pub struct DepositInfo { + pub user: Keypair, + pub user_pool_account: Pubkey, + pub stake_lamports: u64, + pub pool_tokens: u64, +} + +pub async fn simple_deposit( + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + stake_pool_accounts: &StakePoolAccounts, + validator_stake_account: &StakeAccount, +) -> DepositInfo { + let user = Keypair::new(); + // make stake account + let user_stake = Keypair::new(); + let lockup = stake::Lockup::default(); + let authorized = stake::Authorized { + staker: stake_pool_accounts.deposit_authority, + withdrawer: stake_pool_accounts.deposit_authority, + }; + let stake_lamports = create_independent_stake_account( + banks_client, + payer, + recent_blockhash, + &user_stake, + &authorized, + &lockup, + ) + .await; + // make pool token account + let user_pool_account = Keypair::new(); + create_token_account( + banks_client, + payer, + recent_blockhash, + &user_pool_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user.pubkey(), + ) + .await; + + stake_pool_accounts + .deposit_stake( + banks_client, + payer, + recent_blockhash, + &user_stake.pubkey(), + &user_pool_account.pubkey(), + &validator_stake_account.stake_account, + ) + .await; + + let user_pool_account = user_pool_account.pubkey(); + let pool_tokens = get_token_balance(banks_client, &user_pool_account).await; + + DepositInfo { + user, + user_pool_account, + stake_lamports, + pool_tokens, + } +} diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs new file mode 100644 index 00000000..03ceba1c --- /dev/null +++ b/program/tests/initialize.rs @@ -0,0 +1,31 @@ +#![cfg(feature = "test-bpf")] + +mod helpers; + +use helpers::*; +use solana_sdk::signature::Signer; +use spl_stake_pool::*; + +#[tokio::test] +async fn test_stake_pool_initialize() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await; + + // Stake pool now exists + let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; + assert_eq!(stake_pool.data.len(), state::State::LEN); + assert_eq!(stake_pool.owner, id()); + + // Validator stake list storage initialized + let validator_stake_list = get_account( + &mut banks_client, + &stake_pool_accounts.validator_stake_list.pubkey(), + ) + .await; + let validator_stake_list = + state::ValidatorStakeList::deserialize(validator_stake_list.data.as_slice()).unwrap(); + assert_eq!(validator_stake_list.is_initialized, true); +} diff --git a/program/tests/update_list_balance.rs b/program/tests/update_list_balance.rs new file mode 100644 index 00000000..12d0afff --- /dev/null +++ b/program/tests/update_list_balance.rs @@ -0,0 +1,79 @@ +#![cfg(feature = "test-bpf")] + +mod helpers; + +use crate::helpers::TEST_STAKE_AMOUNT; +use helpers::*; +use solana_program::pubkey::Pubkey; +use solana_program_test::BanksClient; +use solana_sdk::signature::Signer; +use spl_stake_pool::*; + +async fn get_list_sum(banks_client: &mut BanksClient, validator_stake_list_key: &Pubkey) -> u64 { + let validator_stake_list = banks_client + .get_account(*validator_stake_list_key) + .await + .expect("get_account") + .expect("validator stake list not none"); + let validator_stake_list = + state::ValidatorStakeList::deserialize(validator_stake_list.data.as_slice()).unwrap(); + + validator_stake_list + .validators + .iter() + .map(|info| info.balance) + .sum() +} + +#[tokio::test] +async fn test_update_list_balance() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await; + + // Add several accounts + let mut stake_accounts: Vec = vec![]; + const STAKE_ACCOUNTS: u64 = 3; + for _ in 0..STAKE_ACCOUNTS { + stake_accounts.push( + simple_add_validator_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + ) + .await, + ); + } + + // Add stake extra funds + const EXTRA_STAKE: u64 = 1_000_000; + + for stake_account in stake_accounts { + transfer( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_account.stake_account, + EXTRA_STAKE, + ) + .await; + } + + let rent = banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()) + 1; + + // Check current balance in the list + assert_eq!( + get_list_sum( + &mut banks_client, + &stake_pool_accounts.validator_stake_list.pubkey() + ) + .await, + STAKE_ACCOUNTS * (stake_rent + TEST_STAKE_AMOUNT) + ); + + // TODO: Execute update list with updated clock +} diff --git a/program/tests/update_pool_balance.rs b/program/tests/update_pool_balance.rs new file mode 100644 index 00000000..049002e8 --- /dev/null +++ b/program/tests/update_pool_balance.rs @@ -0,0 +1,16 @@ +#![cfg(feature = "test-bpf")] + +mod helpers; + +use helpers::*; + +#[tokio::test] +async fn test_update_pool_balance() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await; + + // TODO: Waiting for the ability to advance clock (or modify account data) to finish the tests +} diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs new file mode 100644 index 00000000..0dcaccb1 --- /dev/null +++ b/program/tests/vsa_add.rs @@ -0,0 +1,104 @@ +#![cfg(feature = "test-bpf")] + +mod helpers; + +use helpers::*; + +use bincode::deserialize; +use solana_sdk::signature::{Keypair, Signer}; +use spl_stake_pool::*; + +#[tokio::test] +async fn test_add_validator_stake_account() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await; + + let user = Keypair::new(); + + let user_stake = StakeAccount::new_with_target_authority( + &stake_pool_accounts.deposit_authority, + &stake_pool_accounts.stake_pool.pubkey(), + ); + user_stake + .create_and_delegate(&mut banks_client, &payer, &recent_blockhash) + .await; + + // make pool token account + let user_pool_account = Keypair::new(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user.pubkey(), + ) + .await; + let error = stake_pool_accounts + .add_validator_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.stake_account, + &user_pool_account.pubkey(), + ) + .await; + assert!(error.is_none()); + + let stake_account_balance = banks_client + .get_account(user_stake.stake_account) + .await + .unwrap() + .unwrap() + .lamports; + let deposit_tokens = stake_account_balance; // For now 1:1 math + // Check token account balance + let token_balance = get_token_balance(&mut banks_client, &user_pool_account.pubkey()).await; + assert_eq!(token_balance, deposit_tokens); + let pool_fee_token_balance = get_token_balance( + &mut banks_client, + &stake_pool_accounts.pool_fee_account.pubkey(), + ) + .await; + assert_eq!(pool_fee_token_balance, 0); // No fee when adding validator stake accounts + + // Check if validator account was added to the list + let validator_stake_list = get_account( + &mut banks_client, + &stake_pool_accounts.validator_stake_list.pubkey(), + ) + .await; + let validator_stake_list = + state::ValidatorStakeList::deserialize(validator_stake_list.data.as_slice()).unwrap(); + assert_eq!( + validator_stake_list, + state::ValidatorStakeList { + is_initialized: true, + validators: vec![state::ValidatorStakeInfo { + validator_account: user_stake.vote.pubkey(), + last_update_epoch: 0, + balance: stake_account_balance, + }] + } + ); + + // Check of stake account authority has changed + let stake = get_account(&mut banks_client, &user_stake.stake_account).await; + let stake_state = deserialize::(&stake.data).unwrap(); + match stake_state { + stake::StakeState::Stake(meta, _) => { + assert_eq!( + &meta.authorized.staker, + &stake_pool_accounts.withdraw_authority + ); + assert_eq!( + &meta.authorized.withdrawer, + &stake_pool_accounts.withdraw_authority + ); + } + _ => panic!(), + } +} diff --git a/program/tests/vsa_create.rs b/program/tests/vsa_create.rs new file mode 100644 index 00000000..6f08f13d --- /dev/null +++ b/program/tests/vsa_create.rs @@ -0,0 +1,62 @@ +#![cfg(feature = "test-bpf")] + +mod helpers; + +use crate::solana_program::pubkey::Pubkey; +use helpers::*; + +use bincode::deserialize; +use solana_sdk::signature::{Keypair, Signer}; +use solana_sdk::transaction::Transaction; +use spl_stake_pool::*; + +#[tokio::test] +async fn test_create_validator_stake_account() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await; + + let validator = Pubkey::new_unique(); + let user_stake_authority = Keypair::new(); + let user_withdraw_authority = Keypair::new(); + + let (stake_account, _) = processor::Processor::find_stake_address_for_validator( + &id(), + &validator, + &stake_pool_accounts.stake_pool.pubkey(), + ); + + let mut transaction = Transaction::new_with_payer( + &[instruction::create_validator_stake_account( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &payer.pubkey(), + &stake_account, + &validator, + &user_stake_authority.pubkey(), + &user_withdraw_authority.pubkey(), + &solana_program::system_program::id(), + &stake::id(), + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer], recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); + + // Check authorities + let stake = get_account(&mut banks_client, &stake_account).await; + let stake_state = deserialize::(&stake.data).unwrap(); + match stake_state { + stake::StakeState::Initialized(meta) => { + assert_eq!(&meta.authorized.staker, &user_stake_authority.pubkey()); + assert_eq!( + &meta.authorized.withdrawer, + &user_withdraw_authority.pubkey() + ); + } + _ => panic!(), + } +} diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs new file mode 100644 index 00000000..9ada8989 --- /dev/null +++ b/program/tests/vsa_remove.rs @@ -0,0 +1,106 @@ +#![cfg(feature = "test-bpf")] + +mod helpers; + +use bincode::deserialize; +use helpers::*; +use solana_program::pubkey::Pubkey; +use solana_sdk::signature::{Keypair, Signer}; +use spl_stake_pool::*; + +#[tokio::test] +async fn test_remove_validator_stake_account() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await; + + let user = Keypair::new(); + + let user_stake = StakeAccount::new_with_target_authority( + &stake_pool_accounts.deposit_authority, + &stake_pool_accounts.stake_pool.pubkey(), + ); + user_stake + .create_and_delegate(&mut banks_client, &payer, &recent_blockhash) + .await; + + // make pool token account + let user_pool_account = Keypair::new(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user.pubkey(), + ) + .await; + let error = stake_pool_accounts + .add_validator_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.stake_account, + &user_pool_account.pubkey(), + ) + .await; + assert!(error.is_none()); + + let tokens_to_burn = get_token_balance(&mut banks_client, &user_pool_account.pubkey()).await; + delegate_tokens( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account.pubkey(), + &user, + &stake_pool_accounts.withdraw_authority, + tokens_to_burn, + ) + .await; + + let new_authority = Pubkey::new_unique(); + let error = stake_pool_accounts + .remove_validator_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.stake_account, + &user_pool_account.pubkey(), + &new_authority, + ) + .await; + assert!(error.is_none()); + + // Check if all tokens were burned + let tokens_left = get_token_balance(&mut banks_client, &user_pool_account.pubkey()).await; + assert_eq!(tokens_left, 0); + + // Check if account was removed from the list of stake accounts + let validator_stake_list = get_account( + &mut banks_client, + &stake_pool_accounts.validator_stake_list.pubkey(), + ) + .await; + let validator_stake_list = + state::ValidatorStakeList::deserialize(validator_stake_list.data.as_slice()).unwrap(); + assert_eq!( + validator_stake_list, + state::ValidatorStakeList { + is_initialized: true, + validators: vec![] + } + ); + + // Check of stake account authority has changed + let stake = get_account(&mut banks_client, &user_stake.stake_account).await; + let stake_state = deserialize::(&stake.data).unwrap(); + match stake_state { + stake::StakeState::Stake(meta, _) => { + assert_eq!(&meta.authorized.staker, &new_authority); + assert_eq!(&meta.authorized.withdrawer, &new_authority); + } + _ => panic!(), + } +} diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs new file mode 100644 index 00000000..46059399 --- /dev/null +++ b/program/tests/withdraw.rs @@ -0,0 +1,153 @@ +#![cfg(feature = "test-bpf")] + +mod helpers; + +use helpers::*; +use solana_program::pubkey::Pubkey; + +use solana_sdk::signature::{Keypair, Signer}; +use spl_stake_pool::*; + +#[tokio::test] +async fn test_stake_pool_withdraw() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await; + + let validator_stake_account: StakeAccount = simple_add_validator_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + ) + .await; + + let deposit_info: DepositInfo = simple_deposit( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + &validator_stake_account, + ) + .await; + + let tokens_to_burn = deposit_info.pool_tokens / 4; + let lamports_to_withdraw = tokens_to_burn; // For now math is 1:1 + + // Delegate tokens for burning + delegate_tokens( + &mut banks_client, + &payer, + &recent_blockhash, + &deposit_info.user_pool_account, + &deposit_info.user, + &stake_pool_accounts.withdraw_authority, + tokens_to_burn, + ) + .await; + + // Create stake account to withdraw to + let user_stake_recipient = Keypair::new(); + let initial_stake_lamports = create_blank_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake_recipient, + ) + .await; + + // Save stake pool state before withdrawal + let stake_pool_before = + get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; + let stake_pool_before = state::State::deserialize(&stake_pool_before.data.as_slice()) + .unwrap() + .stake_pool() + .unwrap(); + + // Save validator stake account record before withdrawal + let validator_stake_list = get_account( + &mut banks_client, + &stake_pool_accounts.validator_stake_list.pubkey(), + ) + .await; + let validator_stake_list = + state::ValidatorStakeList::deserialize(validator_stake_list.data.as_slice()).unwrap(); + let validator_stake_item_before = validator_stake_list + .find(&validator_stake_account.vote.pubkey()) + .unwrap(); + + // Save user token balance + let user_token_balance_before = + get_token_balance(&mut banks_client, &deposit_info.user_pool_account).await; + + let new_authority = Pubkey::new_unique(); + stake_pool_accounts + .withdraw_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake_recipient.pubkey(), + &deposit_info.user_pool_account, + &validator_stake_account.stake_account, + &new_authority, + lamports_to_withdraw, + ) + .await; + + // Check pool stats + let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; + let stake_pool = state::State::deserialize(&stake_pool.data.as_slice()) + .unwrap() + .stake_pool() + .unwrap(); + assert_eq!( + stake_pool.stake_total, + stake_pool_before.stake_total - lamports_to_withdraw + ); + assert_eq!( + stake_pool.pool_total, + stake_pool_before.pool_total - tokens_to_burn + ); + + // Check validator stake list storage + let validator_stake_list = get_account( + &mut banks_client, + &stake_pool_accounts.validator_stake_list.pubkey(), + ) + .await; + let validator_stake_list = + state::ValidatorStakeList::deserialize(validator_stake_list.data.as_slice()).unwrap(); + let validator_stake_item = validator_stake_list + .find(&validator_stake_account.vote.pubkey()) + .unwrap(); + assert_eq!( + validator_stake_item.balance, + validator_stake_item_before.balance - lamports_to_withdraw + ); + + // Check tokens burned + let user_token_balance = + get_token_balance(&mut banks_client, &deposit_info.user_pool_account).await; + assert_eq!( + user_token_balance, + user_token_balance_before - tokens_to_burn + ); + + // Check validator stake account balance + let validator_stake_account = + get_account(&mut banks_client, &validator_stake_account.stake_account).await; + assert_eq!( + validator_stake_account.lamports, + validator_stake_item.balance + ); + + // Check user recipient stake account balance + let user_stake_recipient_account = + get_account(&mut banks_client, &user_stake_recipient.pubkey()).await; + assert_eq!( + user_stake_recipient_account.lamports, + initial_stake_lamports + lamports_to_withdraw + ); +} From 9be4f8d5ffb0e7c5b0153a6ef0c73d79f374792c Mon Sep 17 00:00:00 2001 From: Yuriy Savchenko Date: Thu, 28 Jan 2021 00:35:25 +0200 Subject: [PATCH 0039/1076] Stake pool: test coverage for most of the program errors (#1134) * Stake pool: test coverage for most of the program errors * Fixes to stake pool tests PR comments --- program/src/processor.rs | 8 +- program/tests/deposit.rs | 648 ++++++++++++++++++++++- program/tests/helpers/mod.rs | 47 +- program/tests/initialize.rs | 239 ++++++++- program/tests/set_owner.rs | 218 ++++++++ program/tests/set_staking_authority.rs | 267 ++++++++++ program/tests/update_list_balance.rs | 9 +- program/tests/update_pool_balance.rs | 53 +- program/tests/vsa_add.rs | 455 +++++++++++++++- program/tests/vsa_create.rs | 168 +++++- program/tests/vsa_remove.rs | 496 +++++++++++++++++- program/tests/withdraw.rs | 690 ++++++++++++++++++++++++- 12 files changed, 3247 insertions(+), 51 deletions(-) create mode 100644 program/tests/set_owner.rs create mode 100644 program/tests/set_staking_authority.rs diff --git a/program/src/processor.rs b/program/src/processor.rs index a5366467..2203c8fa 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -509,7 +509,7 @@ impl Processor { } if stake_pool.token_program_id != *token_program_info.key { - return Err(StakePoolError::InvalidProgramAddress.into()); + return Err(ProgramError::IncorrectProgramId); } if stake_pool.pool_mint != *pool_mint_info.key { return Err(StakePoolError::WrongPoolMint.into()); @@ -637,7 +637,7 @@ impl Processor { } if stake_pool.token_program_id != *token_program_info.key { - return Err(StakePoolError::InvalidProgramAddress.into()); + return Err(ProgramError::IncorrectProgramId); } if stake_pool.pool_mint != *pool_mint_info.key { return Err(StakePoolError::WrongPoolMint.into()); @@ -855,7 +855,7 @@ impl Processor { return Err(StakePoolError::InvalidFeeAccount.into()); } if stake_pool.token_program_id != *token_program_info.key { - return Err(StakePoolError::InvalidProgramAddress.into()); + return Err(ProgramError::IncorrectProgramId); } // Check validator stake account list storage @@ -1004,7 +1004,7 @@ impl Processor { stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?; if stake_pool.token_program_id != *token_program_info.key { - return Err(StakePoolError::InvalidProgramAddress.into()); + return Err(ProgramError::IncorrectProgramId); } // Check validator stake account list storage diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index fbb1f866..8f92e56c 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -4,16 +4,25 @@ mod helpers; use helpers::*; -use solana_sdk::signature::{Keypair, Signer}; +use solana_program::hash::Hash; +use solana_program_test::BanksClient; +use solana_sdk::{ + instruction::InstructionError, + signature::{Keypair, Signer}, + transaction::Transaction, + transaction::TransactionError, + transport::TransportError, +}; use spl_stake_pool::*; +use spl_token::error as token_error; -#[tokio::test] -async fn test_stake_pool_deposit() { +async fn setup() -> (BanksClient, Keypair, Hash, StakePoolAccounts, StakeAccount) { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) - .await; + .await + .unwrap(); let validator_stake_account: StakeAccount = simple_add_validator_stake_account( &mut banks_client, @@ -23,6 +32,20 @@ async fn test_stake_pool_deposit() { ) .await; + ( + banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + validator_stake_account, + ) +} + +#[tokio::test] +async fn test_stake_pool_deposit() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake_account) = + setup().await; + let user = Keypair::new(); // make stake account let user_stake = Keypair::new(); @@ -50,7 +73,8 @@ async fn test_stake_pool_deposit() { &stake_pool_accounts.pool_mint.pubkey(), &user.pubkey(), ) - .await; + .await + .unwrap(); // Save stake pool state before depositing let stake_pool_before = @@ -81,7 +105,8 @@ async fn test_stake_pool_deposit() { &user_pool_account.pubkey(), &validator_stake_account.stake_account, ) - .await; + .await + .unwrap(); // Original stake account should be drained assert!(banks_client @@ -143,3 +168,614 @@ async fn test_stake_pool_deposit() { validator_stake_item.balance ); } + +#[tokio::test] +async fn test_stake_pool_deposit_with_wrong_stake_program_id() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake_account) = + setup().await; + + let user = Keypair::new(); + // make stake account + let user_stake = Keypair::new(); + + // make pool token account + let user_pool_account = Keypair::new(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user.pubkey(), + ) + .await + .unwrap(); + + let wrong_stake_program = Keypair::new(); + + let mut transaction = Transaction::new_with_payer( + &[instruction::deposit( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.validator_stake_list.pubkey(), + &stake_pool_accounts.deposit_authority, + &stake_pool_accounts.withdraw_authority, + &user_stake.pubkey(), + &validator_stake_account.stake_account, + &user_pool_account.pubkey(), + &stake_pool_accounts.pool_fee_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &spl_token::id(), + &wrong_stake_program.pubkey(), + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { + assert_eq!(error, InstructionError::IncorrectProgramId); + } + _ => panic!("Wrong error occurs while try to make a deposit with wrong stake program ID"), + } +} + +#[tokio::test] +async fn test_stake_pool_deposit_with_wrong_pool_fee_account() { + let ( + mut banks_client, + payer, + recent_blockhash, + mut stake_pool_accounts, + validator_stake_account, + ) = setup().await; + + let user = Keypair::new(); + // make stake account + let user_stake = Keypair::new(); + + // make pool token account + let user_pool_account = Keypair::new(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user.pubkey(), + ) + .await + .unwrap(); + + let wrong_pool_fee_acc = Keypair::new(); + stake_pool_accounts.pool_fee_account = wrong_pool_fee_acc; + + let transaction_error = stake_pool_accounts + .deposit_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.pubkey(), + &user_pool_account.pubkey(), + &validator_stake_account.stake_account, + ) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::InvalidFeeAccount as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while try to make a deposit with wrong pool fee account"), + } +} + +#[tokio::test] +async fn test_stake_pool_deposit_with_wrong_token_program_id() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake_account) = + setup().await; + + let user = Keypair::new(); + // make stake account + let user_stake = Keypair::new(); + + // make pool token account + let user_pool_account = Keypair::new(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user.pubkey(), + ) + .await + .unwrap(); + + let wrong_token_program = Keypair::new(); + + let mut transaction = Transaction::new_with_payer( + &[instruction::deposit( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.validator_stake_list.pubkey(), + &stake_pool_accounts.deposit_authority, + &stake_pool_accounts.withdraw_authority, + &user_stake.pubkey(), + &validator_stake_account.stake_account, + &user_pool_account.pubkey(), + &stake_pool_accounts.pool_fee_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &wrong_token_program.pubkey(), + &stake::id(), + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { + assert_eq!(error, InstructionError::IncorrectProgramId); + } + _ => panic!("Wrong error occurs while try to make a deposit with wrong token program ID"), + } +} + +#[tokio::test] +async fn test_stake_pool_deposit_with_wrong_validator_stake_list_account() { + let ( + mut banks_client, + payer, + recent_blockhash, + mut stake_pool_accounts, + validator_stake_account, + ) = setup().await; + + let user = Keypair::new(); + // make stake account + let user_stake = Keypair::new(); + + // make pool token account + let user_pool_account = Keypair::new(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user.pubkey(), + ) + .await + .unwrap(); + + let wrong_validator_stake_list = Keypair::new(); + stake_pool_accounts.validator_stake_list = wrong_validator_stake_list; + + let transaction_error = stake_pool_accounts + .deposit_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.pubkey(), + &user_pool_account.pubkey(), + &validator_stake_account.stake_account, + ) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::InvalidValidatorStakeList as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while try to make a deposit with wrong validator stake list account"), + } +} + +#[tokio::test] +async fn test_stake_pool_deposit_where_stake_acc_not_in_stake_state() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await + .unwrap(); + + let validator_stake_account = StakeAccount::new_with_target_authority( + &stake_pool_accounts.deposit_authority, + &stake_pool_accounts.stake_pool.pubkey(), + ); + + let user_stake_authority = Keypair::new(); + create_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &validator_stake_account.stake_pool, + &validator_stake_account.stake_account, + &validator_stake_account.vote.pubkey(), + &user_stake_authority.pubkey(), + &validator_stake_account.target_authority, + ) + .await; + + let user_pool_account = Keypair::new(); + let user = Keypair::new(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user.pubkey(), + ) + .await + .unwrap(); + + let user_stake_acc = Keypair::new(); + let transaction_error = stake_pool_accounts + .deposit_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake_acc.pubkey(), + &user_pool_account.pubkey(), + &validator_stake_account.stake_account, + ) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::WrongStakeState as u32; + assert_eq!(error_index, program_error); + } + _ => panic!( + "Wrong error occurs while try to make a deposit when stake acc not in stake state" + ), + } +} + +#[tokio::test] +async fn test_stake_pool_deposit_to_unknown_validator() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await + .unwrap(); + + let validator_stake_account = StakeAccount::new_with_target_authority( + &stake_pool_accounts.deposit_authority, + &stake_pool_accounts.stake_pool.pubkey(), + ); + validator_stake_account + .create_and_delegate(&mut banks_client, &payer, &recent_blockhash) + .await; + + let user_pool_account = Keypair::new(); + let user = Keypair::new(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user.pubkey(), + ) + .await + .unwrap(); + + // make stake account + let user_stake = Keypair::new(); + let lockup = stake::Lockup::default(); + let authorized = stake::Authorized { + staker: stake_pool_accounts.deposit_authority, + withdrawer: stake_pool_accounts.deposit_authority, + }; + create_independent_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake, + &authorized, + &lockup, + ) + .await; + + let transaction_error = stake_pool_accounts + .deposit_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.pubkey(), + &user_pool_account.pubkey(), + &validator_stake_account.stake_account, + ) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::ValidatorNotFound as u32; + assert_eq!(error_index, program_error); + } + _ => { + panic!("Wrong error occurs while try to make a deposit with unknown validator account") + } + } +} + +#[tokio::test] +async fn test_stake_pool_deposit_with_wrong_deposit_authority() { + let ( + mut banks_client, + payer, + recent_blockhash, + mut stake_pool_accounts, + validator_stake_account, + ) = setup().await; + + let user = Keypair::new(); + // make stake account + let user_stake = Keypair::new(); + + // make pool token account + let user_pool_account = Keypair::new(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user.pubkey(), + ) + .await + .unwrap(); + + stake_pool_accounts.deposit_authority = Keypair::new().pubkey(); + + let transaction_error = stake_pool_accounts + .deposit_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.pubkey(), + &user_pool_account.pubkey(), + &validator_stake_account.stake_account, + ) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::InvalidProgramAddress as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while try to make a deposit with wrong deposit authority"), + } +} + +#[tokio::test] +async fn test_stake_pool_deposit_with_wrong_withdraw_authority() { + let ( + mut banks_client, + payer, + recent_blockhash, + mut stake_pool_accounts, + validator_stake_account, + ) = setup().await; + + let user = Keypair::new(); + // make stake account + let user_stake = Keypair::new(); + + // make pool token account + let user_pool_account = Keypair::new(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user.pubkey(), + ) + .await + .unwrap(); + + stake_pool_accounts.withdraw_authority = Keypair::new().pubkey(); + + let transaction_error = stake_pool_accounts + .deposit_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.pubkey(), + &user_pool_account.pubkey(), + &validator_stake_account.stake_account, + ) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::InvalidProgramAddress as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while try to make a deposit with wrong withdraw authority"), + } +} + +#[tokio::test] +async fn test_stake_pool_deposit_with_wrong_set_deposit_authority() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake_account) = + setup().await; + + let user = Keypair::new(); + // make stake account + let user_stake = Keypair::new(); + let lockup = stake::Lockup::default(); + let authorized = stake::Authorized { + staker: Keypair::new().pubkey(), + withdrawer: stake_pool_accounts.deposit_authority, + }; + create_independent_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake, + &authorized, + &lockup, + ) + .await; + // make pool token account + let user_pool_account = Keypair::new(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user.pubkey(), + ) + .await + .unwrap(); + + let transaction_error = stake_pool_accounts + .deposit_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.pubkey(), + &user_pool_account.pubkey(), + &validator_stake_account.stake_account, + ) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { + assert_eq!(error, InstructionError::MissingRequiredSignature); + } + _ => { + panic!("Wrong error occurs while try to make deposit with wrong set deposit authority") + } + } +} + +#[tokio::test] +async fn test_stake_pool_deposit_with_wrong_mint_for_receiver_acc() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake_account) = + setup().await; + + // make stake account + let user_stake = Keypair::new(); + let lockup = stake::Lockup::default(); + let authorized = stake::Authorized { + staker: stake_pool_accounts.deposit_authority, + withdrawer: stake_pool_accounts.deposit_authority, + }; + create_independent_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake, + &authorized, + &lockup, + ) + .await; + + let outside_mint = Keypair::new(); + let outside_withdraw_auth = Keypair::new(); + let outside_owner = Keypair::new(); + let outside_pool_fee_acc = Keypair::new(); + + create_mint( + &mut banks_client, + &payer, + &recent_blockhash, + &outside_mint, + &outside_withdraw_auth.pubkey(), + ) + .await + .unwrap(); + + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &outside_pool_fee_acc, + &outside_mint.pubkey(), + &outside_owner.pubkey(), + ) + .await + .unwrap(); + + let transaction_error = stake_pool_accounts + .deposit_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.pubkey(), + &outside_pool_fee_acc.pubkey(), + &validator_stake_account.stake_account, + ) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = token_error::TokenError::MintMismatch as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while try to deposit with wrong mint fro receiver account"), + } +} + +#[tokio::test] +async fn test_deposit_with_uninitialized_validator_stake_list() {} // TODO + +#[tokio::test] +async fn test_deposit_with_out_of_dated_pool_balances() {} // TODO diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 6de4df35..18cca7f8 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -29,13 +29,13 @@ pub async fn get_account(banks_client: &mut BanksClient, pubkey: &Pubkey) -> Acc .expect("account empty") } -async fn create_mint( +pub async fn create_mint( banks_client: &mut BanksClient, payer: &Keypair, recent_blockhash: &Hash, pool_mint: &Keypair, owner: &Pubkey, -) { +) -> Result<(), TransportError> { let rent = banks_client.get_rent().await.unwrap(); let mint_rent = rent.minimum_balance(spl_token::state::Mint::LEN); @@ -60,7 +60,8 @@ async fn create_mint( Some(&payer.pubkey()), ); transaction.sign(&[payer, pool_mint], *recent_blockhash); - banks_client.process_transaction(transaction).await.unwrap(); + banks_client.process_transaction(transaction).await?; + Ok(()) } pub async fn transfer( @@ -89,7 +90,7 @@ pub async fn create_token_account( account: &Keypair, pool_mint: &Pubkey, owner: &Pubkey, -) { +) -> Result<(), TransportError> { let rent = banks_client.get_rent().await.unwrap(); let account_rent = rent.minimum_balance(spl_token::state::Account::LEN); @@ -113,7 +114,8 @@ pub async fn create_token_account( Some(&payer.pubkey()), ); transaction.sign(&[payer, account], *recent_blockhash); - banks_client.process_transaction(transaction).await.unwrap(); + banks_client.process_transaction(transaction).await?; + Ok(()) } pub async fn get_token_balance(banks_client: &mut BanksClient, token: &Pubkey) -> u64 { @@ -153,7 +155,7 @@ pub async fn delegate_tokens( } #[allow(clippy::too_many_arguments)] -async fn create_stake_pool( +pub async fn create_stake_pool( banks_client: &mut BanksClient, payer: &Keypair, recent_blockhash: &Hash, @@ -163,7 +165,7 @@ async fn create_stake_pool( pool_token_account: &Pubkey, owner: &Pubkey, fee: &instruction::Fee, -) { +) -> Result<(), TransportError> { let rent = banks_client.get_rent().await.unwrap(); let rent_stake_pool = rent.minimum_balance(state::State::LEN); let rent_validator_stake_list = rent.minimum_balance(state::ValidatorStakeList::LEN); @@ -203,7 +205,8 @@ async fn create_stake_pool( &[payer, stake_pool, validator_stake_list], *recent_blockhash, ); - banks_client.process_transaction(transaction).await.unwrap(); + banks_client.process_transaction(transaction).await?; + Ok(()) } pub async fn create_vote( @@ -471,7 +474,7 @@ impl StakePoolAccounts { mut banks_client: &mut BanksClient, payer: &Keypair, recent_blockhash: &Hash, - ) { + ) -> Result<(), TransportError> { create_mint( &mut banks_client, &payer, @@ -479,7 +482,7 @@ impl StakePoolAccounts { &self.pool_mint, &self.withdraw_authority, ) - .await; + .await?; create_token_account( &mut banks_client, &payer, @@ -488,7 +491,7 @@ impl StakePoolAccounts { &self.pool_mint.pubkey(), &self.owner.pubkey(), ) - .await; + .await?; create_stake_pool( &mut banks_client, &payer, @@ -500,7 +503,8 @@ impl StakePoolAccounts { &self.owner.pubkey(), &self.fee, ) - .await; + .await?; + Ok(()) } pub async fn deposit_stake( @@ -511,7 +515,7 @@ impl StakePoolAccounts { stake: &Pubkey, pool_account: &Pubkey, validator_stake_account: &Pubkey, - ) { + ) -> Result<(), TransportError> { let mut transaction = Transaction::new_with_payer( &[instruction::deposit( &id(), @@ -531,7 +535,8 @@ impl StakePoolAccounts { Some(&payer.pubkey()), ); transaction.sign(&[payer], *recent_blockhash); - banks_client.process_transaction(transaction).await.unwrap(); + banks_client.process_transaction(transaction).await?; + Ok(()) } pub async fn withdraw_stake( @@ -544,7 +549,7 @@ impl StakePoolAccounts { validator_stake_account: &Pubkey, recipient_new_authority: &Pubkey, amount: u64, - ) { + ) -> Result<(), TransportError> { let mut transaction = Transaction::new_with_payer( &[instruction::withdraw( &id(), @@ -564,7 +569,8 @@ impl StakePoolAccounts { Some(&payer.pubkey()), ); transaction.sign(&[payer], *recent_blockhash); - banks_client.process_transaction(transaction).await.unwrap(); + banks_client.process_transaction(transaction).await?; + Ok(()) } pub async fn add_validator_stake_account( @@ -651,7 +657,8 @@ pub async fn simple_add_validator_stake_account( &stake_pool_accounts.pool_mint.pubkey(), &user.pubkey(), ) - .await; + .await + .unwrap(); let error = stake_pool_accounts .add_validator_stake_account( banks_client, @@ -707,7 +714,8 @@ pub async fn simple_deposit( &stake_pool_accounts.pool_mint.pubkey(), &user.pubkey(), ) - .await; + .await + .unwrap(); stake_pool_accounts .deposit_stake( @@ -718,7 +726,8 @@ pub async fn simple_deposit( &user_pool_account.pubkey(), &validator_stake_account.stake_account, ) - .await; + .await + .unwrap(); let user_pool_account = user_pool_account.pubkey(); let pool_tokens = get_token_balance(banks_client, &user_pool_account).await; diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index 03ceba1c..c15f2f04 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -3,7 +3,11 @@ mod helpers; use helpers::*; -use solana_sdk::signature::Signer; +use solana_program::system_instruction; +use solana_sdk::{ + instruction::InstructionError, signature::Keypair, signature::Signer, transaction::Transaction, + transaction::TransactionError, transport::TransportError, +}; use spl_stake_pool::*; #[tokio::test] @@ -12,7 +16,8 @@ async fn test_stake_pool_initialize() { let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) - .await; + .await + .unwrap(); // Stake pool now exists let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; @@ -29,3 +34,233 @@ async fn test_stake_pool_initialize() { state::ValidatorStakeList::deserialize(validator_stake_list.data.as_slice()).unwrap(); assert_eq!(validator_stake_list.is_initialized, true); } + +#[tokio::test] +async fn test_initialize_already_initialized_stake_pool() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await + .unwrap(); + + let latest_blockhash = banks_client.get_recent_blockhash().await.unwrap(); + + let mut second_stake_pool_accounts = StakePoolAccounts::new(); + second_stake_pool_accounts.stake_pool = stake_pool_accounts.stake_pool; + + let transaction_error = second_stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &latest_blockhash) + .await + .err() + .unwrap(); + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::AlreadyInUse as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while try to initialize already initialized stake pool"), + } +} + +#[tokio::test] +async fn test_initialize_stake_pool_with_already_initialized_stake_list_storage() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await + .unwrap(); + + let latest_blockhash = banks_client.get_recent_blockhash().await.unwrap(); + + let mut second_stake_pool_accounts = StakePoolAccounts::new(); + second_stake_pool_accounts.validator_stake_list = stake_pool_accounts.validator_stake_list; + + let transaction_error = second_stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &latest_blockhash) + .await + .err() + .unwrap(); + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::AlreadyInUse as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while try to initialize stake pool with already initialized stake list storage"), + } +} + +#[tokio::test] +async fn test_initialize_stake_pool_with_high_fee() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let mut stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts.fee = instruction::Fee { + numerator: 100001, + denominator: 100000, + }; + + let transaction_error = stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await + .err() + .unwrap(); + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::FeeTooHigh as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while try to initialize stake pool with high fee"), + } +} + +#[tokio::test] +async fn test_initialize_stake_pool_with_wrong_mint_authority() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + let wrong_mint = Keypair::new(); + + create_mint( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.pool_mint, + &stake_pool_accounts.withdraw_authority, + ) + .await + .unwrap(); + + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.pool_fee_account, + &stake_pool_accounts.pool_mint.pubkey(), + &stake_pool_accounts.owner.pubkey(), + ) + .await + .unwrap(); + + let transaction_error = create_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.stake_pool, + &stake_pool_accounts.validator_stake_list, + &wrong_mint.pubkey(), + &stake_pool_accounts.pool_fee_account.pubkey(), + &stake_pool_accounts.owner.pubkey(), + &stake_pool_accounts.fee, + ) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::WrongAccountMint as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while try to initialize stake pool with wrong mint authority of pool fee account"), + } +} + +#[tokio::test] +async fn test_initialize_stake_pool_with_wrong_token_program_id() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + + create_mint( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.pool_mint, + &stake_pool_accounts.withdraw_authority, + ) + .await + .unwrap(); + + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.pool_fee_account, + &stake_pool_accounts.pool_mint.pubkey(), + &stake_pool_accounts.owner.pubkey(), + ) + .await + .unwrap(); + + let rent = banks_client.get_rent().await.unwrap(); + let rent_stake_pool = rent.minimum_balance(state::State::LEN); + let rent_validator_stake_list = rent.minimum_balance(state::ValidatorStakeList::LEN); + let init_args = instruction::InitArgs { + fee: stake_pool_accounts.fee, + }; + let wrong_token_program = Keypair::new(); + + let mut transaction = Transaction::new_with_payer( + &[ + system_instruction::create_account( + &payer.pubkey(), + &stake_pool_accounts.stake_pool.pubkey(), + rent_stake_pool, + state::State::LEN as u64, + &id(), + ), + system_instruction::create_account( + &payer.pubkey(), + &stake_pool_accounts.validator_stake_list.pubkey(), + rent_validator_stake_list, + state::ValidatorStakeList::LEN as u64, + &id(), + ), + instruction::initialize( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.owner.pubkey(), + &stake_pool_accounts.validator_stake_list.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &stake_pool_accounts.pool_fee_account.pubkey(), + &wrong_token_program.pubkey(), + init_args, + ) + .unwrap(), + ], + Some(&payer.pubkey()), + ); + transaction.sign( + &[ + &payer, + &stake_pool_accounts.stake_pool, + &stake_pool_accounts.validator_stake_list, + ], + recent_blockhash, + ); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { + assert_eq!(error, InstructionError::IncorrectProgramId); + } + _ => panic!( + "Wrong error occurs while try to initialize stake pool with wrong token program ID" + ), + } +} diff --git a/program/tests/set_owner.rs b/program/tests/set_owner.rs new file mode 100644 index 00000000..8c2321b8 --- /dev/null +++ b/program/tests/set_owner.rs @@ -0,0 +1,218 @@ +#![cfg(feature = "test-bpf")] + +mod helpers; + +use helpers::*; +use solana_program::hash::Hash; +use solana_program::instruction::AccountMeta; +use solana_program::instruction::Instruction; +use solana_program_test::BanksClient; +use solana_sdk::{ + instruction::InstructionError, signature::Keypair, signature::Signer, transaction::Transaction, + transaction::TransactionError, transport::TransportError, +}; +use spl_stake_pool::*; + +async fn setup() -> ( + BanksClient, + Keypair, + Hash, + StakePoolAccounts, + Keypair, + Keypair, +) { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await + .unwrap(); + + let new_pool_fee = Keypair::new(); + let new_owner = Keypair::new(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &new_pool_fee, + &stake_pool_accounts.pool_mint.pubkey(), + &new_owner.pubkey(), + ) + .await + .unwrap(); + + ( + banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + new_pool_fee, + new_owner, + ) +} + +#[tokio::test] +async fn test_set_owner() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_pool_fee, new_owner) = + setup().await; + + let mut transaction = Transaction::new_with_payer( + &[instruction::set_owner( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.owner.pubkey(), + &new_owner.pubkey(), + &new_pool_fee.pubkey(), + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); + + let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; + let stake_pool = state::State::deserialize(&stake_pool.data.as_slice()) + .unwrap() + .stake_pool() + .unwrap(); + + assert_eq!(stake_pool.owner, new_owner.pubkey()); +} + +#[tokio::test] +async fn test_set_owner_by_malicious() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_pool_fee, new_owner) = + setup().await; + + let mut transaction = Transaction::new_with_payer( + &[instruction::set_owner( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &new_owner.pubkey(), + &new_owner.pubkey(), + &new_pool_fee.pubkey(), + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &new_owner], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::WrongOwner as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while malicious try to set owner"), + } +} + +#[tokio::test] +async fn test_set_owner_without_signature() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_pool_fee, new_owner) = + setup().await; + + let args = instruction::StakePoolInstruction::SetOwner; + let data = args.serialize().unwrap(); + let accounts = vec![ + AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), + AccountMeta::new_readonly(stake_pool_accounts.owner.pubkey(), false), + AccountMeta::new_readonly(new_owner.pubkey(), false), + AccountMeta::new_readonly(new_pool_fee.pubkey(), false), + ]; + let instruction = Instruction { + program_id: id(), + accounts, + data, + }; + + let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); + transaction.sign(&[&payer], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::SignatureMissing as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while try to set new owner without signature"), + } +} + +#[tokio::test] +async fn test_set_owner_with_wrong_mint_for_pool_fee_acc() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await + .unwrap(); + + let new_mint = Keypair::new(); + let new_withdraw_auth = Keypair::new(); + let new_pool_fee = Keypair::new(); + let new_owner = Keypair::new(); + + create_mint( + &mut banks_client, + &payer, + &recent_blockhash, + &new_mint, + &new_withdraw_auth.pubkey(), + ) + .await + .unwrap(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &new_pool_fee, + &new_mint.pubkey(), + &new_owner.pubkey(), + ) + .await + .unwrap(); + + let mut transaction = Transaction::new_with_payer( + &[instruction::set_owner( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.owner.pubkey(), + &new_owner.pubkey(), + &new_pool_fee.pubkey(), + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::WrongAccountMint as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while try to set new owner with wrong mint"), + } +} diff --git a/program/tests/set_staking_authority.rs b/program/tests/set_staking_authority.rs new file mode 100644 index 00000000..4972e506 --- /dev/null +++ b/program/tests/set_staking_authority.rs @@ -0,0 +1,267 @@ +#![cfg(feature = "test-bpf")] + +mod helpers; + +use bincode::deserialize; +use helpers::*; +use solana_program::hash::Hash; +use solana_program::instruction::AccountMeta; +use solana_program::instruction::Instruction; +use solana_program::sysvar; +use solana_program_test::BanksClient; +use solana_sdk::{ + instruction::InstructionError, signature::Keypair, signature::Signer, transaction::Transaction, + transaction::TransactionError, transport::TransportError, +}; +use spl_stake_pool::*; + +async fn setup() -> (BanksClient, Keypair, Hash, StakePoolAccounts, StakeAccount) { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await + .unwrap(); + + let user = Keypair::new(); + + let user_stake = StakeAccount::new_with_target_authority( + &stake_pool_accounts.deposit_authority, + &stake_pool_accounts.stake_pool.pubkey(), + ); + user_stake + .create_and_delegate(&mut banks_client, &payer, &recent_blockhash) + .await; + + // make pool token account + let user_pool_account = Keypair::new(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user.pubkey(), + ) + .await + .unwrap(); + + let error = stake_pool_accounts + .add_validator_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.stake_account, + &user_pool_account.pubkey(), + ) + .await; + assert!(error.is_none()); + + ( + banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + user_stake, + ) +} + +#[tokio::test] +async fn test_set_staking_authority() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + setup().await; + + let new_staking_pubkey = Keypair::new().pubkey(); + + let mut transaction = Transaction::new_with_payer( + &[instruction::set_staking_authority( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.owner.pubkey(), + &stake_pool_accounts.withdraw_authority, + &user_stake.stake_account, + &new_staking_pubkey, + &stake::id(), + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); + + // Check of stake account authority has changed + let stake = get_account(&mut banks_client, &user_stake.stake_account).await; + let stake_state = deserialize::(&stake.data).unwrap(); + match stake_state { + stake::StakeState::Stake(meta, _) => { + assert_eq!(&meta.authorized.staker, &new_staking_pubkey); + assert_eq!( + &meta.authorized.withdrawer, + &stake_pool_accounts.withdraw_authority + ); + } + _ => panic!(), + } +} + +#[tokio::test] +async fn test_set_staking_authority_with_wrong_stake_program_id() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + setup().await; + + let new_staking_pubkey = Keypair::new().pubkey(); + + let mut transaction = Transaction::new_with_payer( + &[instruction::set_staking_authority( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.owner.pubkey(), + &stake_pool_accounts.withdraw_authority, + &user_stake.stake_account, + &new_staking_pubkey, + &Keypair::new().pubkey(), + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { + assert_eq!(error, InstructionError::IncorrectProgramId); + } + _ => panic!( + "Wrong error occurs while try to set staking authority with wrong stake program ID" + ), + } +} + +#[tokio::test] +async fn test_set_staking_authority_with_wrong_withdraw_authority() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + setup().await; + + let new_staking_pubkey = Keypair::new().pubkey(); + + let mut transaction = Transaction::new_with_payer( + &[instruction::set_staking_authority( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.owner.pubkey(), + &Keypair::new().pubkey(), + &user_stake.stake_account, + &new_staking_pubkey, + &stake::id(), + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::InvalidProgramAddress as u32; + assert_eq!(error_index, program_error); + } + _ => panic!( + "Wrong error occurs while try to set staking authority with wrong withdraw authority" + ), + } +} + +#[tokio::test] +async fn test_set_staking_authority_with_wrong_owner() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + setup().await; + + let new_staking_pubkey = Keypair::new().pubkey(); + let wrong_owner = Keypair::new(); + + let mut transaction = Transaction::new_with_payer( + &[instruction::set_staking_authority( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &wrong_owner.pubkey(), + &stake_pool_accounts.withdraw_authority, + &user_stake.stake_account, + &new_staking_pubkey, + &stake::id(), + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &wrong_owner], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::WrongOwner as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while try to set staking authority with wrong owner"), + } +} + +#[tokio::test] +async fn test_set_staking_authority_without_signature() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + setup().await; + + let new_staking_pubkey = Keypair::new().pubkey(); + + let args = instruction::StakePoolInstruction::SetStakingAuthority; + let data = args.serialize().unwrap(); + let accounts = vec![ + AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), + AccountMeta::new_readonly(stake_pool_accounts.owner.pubkey(), false), + AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false), + AccountMeta::new(user_stake.stake_account, false), + AccountMeta::new_readonly(new_staking_pubkey, false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(stake::id(), false), + ]; + let instruction = Instruction { + program_id: id(), + accounts, + data, + }; + + let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); + transaction.sign(&[&payer], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::SignatureMissing as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while try to set staking authority without signature"), + } +} diff --git a/program/tests/update_list_balance.rs b/program/tests/update_list_balance.rs index 12d0afff..f834ed64 100644 --- a/program/tests/update_list_balance.rs +++ b/program/tests/update_list_balance.rs @@ -31,7 +31,8 @@ async fn test_update_list_balance() { let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) - .await; + .await + .unwrap(); // Add several accounts let mut stake_accounts: Vec = vec![]; @@ -77,3 +78,9 @@ async fn test_update_list_balance() { // TODO: Execute update list with updated clock } + +#[tokio::test] +async fn test_update_list_balance_with_uninitialized_validator_stake_list() {} // TODO + +#[tokio::test] +async fn test_update_list_balance_with_wrong_stake_state() {} // TODO diff --git a/program/tests/update_pool_balance.rs b/program/tests/update_pool_balance.rs index 049002e8..53bbd4d6 100644 --- a/program/tests/update_pool_balance.rs +++ b/program/tests/update_pool_balance.rs @@ -3,6 +3,11 @@ mod helpers; use helpers::*; +use solana_sdk::{ + instruction::InstructionError, signature::Keypair, signature::Signer, transaction::Transaction, + transaction::TransactionError, transport::TransportError, +}; +use spl_stake_pool::*; #[tokio::test] async fn test_update_pool_balance() { @@ -10,7 +15,53 @@ async fn test_update_pool_balance() { let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) - .await; + .await + .unwrap(); // TODO: Waiting for the ability to advance clock (or modify account data) to finish the tests } + +#[tokio::test] +async fn test_update_pool_balance_with_wrong_validator_stake_list() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await + .unwrap(); + + let wrong_stake_list_storage = Keypair::new(); + let mut transaction = Transaction::new_with_payer( + &[instruction::update_pool_balance( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &wrong_stake_list_storage.pubkey(), + ) + .unwrap()], + Some(&payer.pubkey()), + ); + + transaction.sign(&[&payer], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::InvalidValidatorStakeList as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while try to update pool balance with wrong validator stake list account"), + } +} + +#[tokio::test] +async fn test_update_pool_balance_with_uninitialized_validator_stake_list() {} // TODO + +#[tokio::test] +async fn test_update_pool_balance_with_out_of_dated_validators_balances() {} // TODO diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index 0dcaccb1..da933cb1 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -5,16 +5,34 @@ mod helpers; use helpers::*; use bincode::deserialize; -use solana_sdk::signature::{Keypair, Signer}; +use solana_program::hash::Hash; +use solana_program::instruction::AccountMeta; +use solana_program::instruction::Instruction; +use solana_program::sysvar; +use solana_program_test::BanksClient; +use solana_sdk::{ + instruction::InstructionError, + signature::{Keypair, Signer}, + transaction::Transaction, + transaction::TransactionError, + transport::TransportError, +}; use spl_stake_pool::*; -#[tokio::test] -async fn test_add_validator_stake_account() { +async fn setup() -> ( + BanksClient, + Keypair, + Hash, + StakePoolAccounts, + StakeAccount, + Keypair, +) { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) - .await; + .await + .unwrap(); let user = Keypair::new(); @@ -36,7 +54,30 @@ async fn test_add_validator_stake_account() { &stake_pool_accounts.pool_mint.pubkey(), &user.pubkey(), ) - .await; + .await + .unwrap(); + + ( + banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + user_stake, + user_pool_account, + ) +} + +#[tokio::test] +async fn test_add_validator_stake_account() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + user_stake, + user_pool_account, + ) = setup().await; + let error = stake_pool_accounts .add_validator_stake_account( &mut banks_client, @@ -102,3 +143,407 @@ async fn test_add_validator_stake_account() { _ => panic!(), } } + +#[tokio::test] +async fn test_add_validator_stake_account_with_wrong_token_program_id() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + user_stake, + user_pool_account, + ) = setup().await; + + let mut transaction = Transaction::new_with_payer( + &[instruction::add_validator_stake_account( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.owner.pubkey(), + &stake_pool_accounts.deposit_authority, + &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts.validator_stake_list.pubkey(), + &user_stake.stake_account, + &user_pool_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &stake::id(), + &stake::id(), + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { + assert_eq!(error, InstructionError::IncorrectProgramId); + } + _ => panic!("Wrong error occurs while try to add validator stake address with wrong token program ID"), + } +} + +#[tokio::test] +async fn test_add_validator_stake_account_with_wrong_pool_mint_account() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + user_stake, + user_pool_account, + ) = setup().await; + + let wrong_pool_mint = Keypair::new(); + + let mut transaction = Transaction::new_with_payer( + &[instruction::add_validator_stake_account( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.owner.pubkey(), + &stake_pool_accounts.deposit_authority, + &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts.validator_stake_list.pubkey(), + &user_stake.stake_account, + &user_pool_account.pubkey(), + &wrong_pool_mint.pubkey(), + &spl_token::id(), + &stake::id(), + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::WrongPoolMint as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while try to add validator stake address with wrong pool mint account"), + } +} + +#[tokio::test] +async fn test_add_validator_stake_account_with_wrong_validator_stake_list_account() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + user_stake, + user_pool_account, + ) = setup().await; + + let wrong_validator_stake_list = Keypair::new(); + + let mut transaction = Transaction::new_with_payer( + &[instruction::add_validator_stake_account( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.owner.pubkey(), + &stake_pool_accounts.deposit_authority, + &stake_pool_accounts.withdraw_authority, + &wrong_validator_stake_list.pubkey(), + &user_stake.stake_account, + &user_pool_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &spl_token::id(), + &stake::id(), + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::InvalidValidatorStakeList as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while try to add validator stake address with wrong validator stake list account"), + } +} + +#[tokio::test] +async fn test_try_to_add_already_added_validator_stake_account() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + user_stake, + user_pool_account, + ) = setup().await; + + stake_pool_accounts + .add_validator_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.stake_account, + &user_pool_account.pubkey(), + ) + .await; + + let latest_blockhash = banks_client.get_recent_blockhash().await.unwrap(); + + let transaction_error = stake_pool_accounts + .add_validator_stake_account( + &mut banks_client, + &payer, + &latest_blockhash, + &user_stake.stake_account, + &user_pool_account.pubkey(), + ) + .await + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::ValidatorAlreadyAdded as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while try to add already added validator stake account"), + } +} + +#[tokio::test] +async fn test_not_owner_try_to_add_validator_stake_account() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + user_stake, + user_pool_account, + ) = setup().await; + + let malicious = Keypair::new(); + + let mut transaction = Transaction::new_with_payer( + &[instruction::add_validator_stake_account( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &malicious.pubkey(), + &stake_pool_accounts.deposit_authority, + &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts.validator_stake_list.pubkey(), + &user_stake.stake_account, + &user_pool_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &spl_token::id(), + &stake::id(), + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &malicious], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::WrongOwner as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while malicious try to add validator stake account"), + } +} + +#[tokio::test] +async fn test_not_owner_try_to_add_validator_stake_account_without_signature() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + user_stake, + user_pool_account, + ) = setup().await; + + let accounts = vec![ + AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), + AccountMeta::new_readonly(stake_pool_accounts.owner.pubkey(), false), + AccountMeta::new_readonly(stake_pool_accounts.deposit_authority, false), + AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false), + AccountMeta::new(stake_pool_accounts.validator_stake_list.pubkey(), false), + AccountMeta::new(user_stake.stake_account, false), + AccountMeta::new(user_pool_account.pubkey(), false), + AccountMeta::new(stake_pool_accounts.pool_mint.pubkey(), false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(spl_token::id(), false), + AccountMeta::new_readonly(stake::id(), false), + ]; + let instruction = Instruction { + program_id: id(), + accounts, + data: instruction::StakePoolInstruction::AddValidatorStakeAccount + .serialize() + .unwrap(), + }; + + let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); + transaction.sign(&[&payer], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::SignatureMissing as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while malicious try to add validator stake account without signing transaction"), + } +} + +#[tokio::test] +async fn test_add_validator_stake_account_when_stake_acc_not_in_stake_state() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await + .unwrap(); + + let user = Keypair::new(); + + let user_stake = StakeAccount::new_with_target_authority( + &stake_pool_accounts.deposit_authority, + &stake_pool_accounts.stake_pool.pubkey(), + ); + let user_stake_authority = Keypair::new(); + create_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.stake_pool, + &user_stake.stake_account, + &user_stake.vote.pubkey(), + &user_stake_authority.pubkey(), + &user_stake.target_authority, + ) + .await; + + let user_pool_account = Keypair::new(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user.pubkey(), + ) + .await + .unwrap(); + + let transaction_error = stake_pool_accounts + .add_validator_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.stake_account, + &user_pool_account.pubkey(), + ) + .await + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::WrongStakeState as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while try to add validator stake account when it isn't in stake state"), + } +} + +#[tokio::test] +async fn test_add_validator_stake_account_with_wrong_stake_program_id() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + user_stake, + user_pool_account, + ) = setup().await; + + let wrong_stake_program = Keypair::new(); + + let mut transaction = Transaction::new_with_payer( + &[instruction::add_validator_stake_account( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.owner.pubkey(), + &stake_pool_accounts.deposit_authority, + &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts.validator_stake_list.pubkey(), + &user_stake.stake_account, + &user_pool_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &spl_token::id(), + &wrong_stake_program.pubkey(), + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { + assert_eq!(error, InstructionError::IncorrectProgramId); + } + _ => panic!( + "Wrong error occurs while try to add validator stake account with wrong stake program ID" + ), + } +} + +#[tokio::test] +async fn test_add_validator_stake_account_to_unupdated_stake_pool() {} // TODO + +#[tokio::test] +async fn test_add_validator_stake_account_with_uninitialized_validator_stake_list_account() {} // TODO diff --git a/program/tests/vsa_create.rs b/program/tests/vsa_create.rs index 6f08f13d..ab48b56e 100644 --- a/program/tests/vsa_create.rs +++ b/program/tests/vsa_create.rs @@ -6,8 +6,13 @@ use crate::solana_program::pubkey::Pubkey; use helpers::*; use bincode::deserialize; -use solana_sdk::signature::{Keypair, Signer}; -use solana_sdk::transaction::Transaction; +use solana_sdk::{ + instruction::InstructionError, + signature::{Keypair, Signer}, + transaction::Transaction, + transaction::TransactionError, + transport::TransportError, +}; use spl_stake_pool::*; #[tokio::test] @@ -16,7 +21,8 @@ async fn test_create_validator_stake_account() { let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) - .await; + .await + .unwrap(); let validator = Pubkey::new_unique(); let user_stake_authority = Keypair::new(); @@ -60,3 +66,159 @@ async fn test_create_validator_stake_account() { _ => panic!(), } } + +#[tokio::test] +async fn test_create_validator_stake_account_with_incorrect_address() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await + .unwrap(); + + let validator = Pubkey::new_unique(); + let user_stake_authority = Keypair::new(); + let user_withdraw_authority = Keypair::new(); + let stake_account = Keypair::new(); + + let mut transaction = Transaction::new_with_payer( + &[instruction::create_validator_stake_account( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &payer.pubkey(), + &stake_account.pubkey(), + &validator, + &user_stake_authority.pubkey(), + &user_withdraw_authority.pubkey(), + &solana_program::system_program::id(), + &stake::id(), + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::InvalidStakeAccountAddress as u32; + assert_eq!(error_index, program_error); + } + _ => panic!( + "Wrong error occurs while try to create validator stake account with incorrect address" + ), + } +} + +#[tokio::test] +async fn test_create_validator_stake_account_with_wrong_system_program() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await + .unwrap(); + + let validator = Pubkey::new_unique(); + let user_stake_authority = Keypair::new(); + let user_withdraw_authority = Keypair::new(); + + let (stake_account, _) = processor::Processor::find_stake_address_for_validator( + &id(), + &validator, + &stake_pool_accounts.stake_pool.pubkey(), + ); + + let wrong_system_program = Keypair::new(); + + let mut transaction = Transaction::new_with_payer( + &[instruction::create_validator_stake_account( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &payer.pubkey(), + &stake_account, + &validator, + &user_stake_authority.pubkey(), + &user_withdraw_authority.pubkey(), + &wrong_system_program.pubkey(), + &stake::id(), + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { + assert_eq!(error, InstructionError::IncorrectProgramId); + } + _ => panic!( + "Wrong error occurs while try to create validator stake account with wrong token program ID" + ), + } +} + +#[tokio::test] +async fn test_create_validator_stake_account_with_wrong_stake_program() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await + .unwrap(); + + let validator = Pubkey::new_unique(); + let user_stake_authority = Keypair::new(); + let user_withdraw_authority = Keypair::new(); + + let (stake_account, _) = processor::Processor::find_stake_address_for_validator( + &id(), + &validator, + &stake_pool_accounts.stake_pool.pubkey(), + ); + + let wrong_stake_program = Keypair::new(); + + let mut transaction = Transaction::new_with_payer( + &[instruction::create_validator_stake_account( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &payer.pubkey(), + &stake_account, + &validator, + &user_stake_authority.pubkey(), + &user_withdraw_authority.pubkey(), + &solana_program::system_program::id(), + &wrong_stake_program.pubkey(), + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { + assert_eq!(error, InstructionError::IncorrectProgramId); + } + _ => panic!( + "Wrong error occurs while try to create validator stake account with wrong stake program ID" + ), + } +} diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 9ada8989..99aaeee1 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -4,17 +4,36 @@ mod helpers; use bincode::deserialize; use helpers::*; +use solana_program::hash::Hash; +use solana_program::instruction::AccountMeta; +use solana_program::instruction::Instruction; use solana_program::pubkey::Pubkey; -use solana_sdk::signature::{Keypair, Signer}; +use solana_program::sysvar; +use solana_program_test::BanksClient; +use solana_sdk::{ + instruction::InstructionError, + signature::{Keypair, Signer}, + transaction::Transaction, + transaction::TransactionError, + transport::TransportError, +}; use spl_stake_pool::*; -#[tokio::test] -async fn test_remove_validator_stake_account() { +async fn setup() -> ( + BanksClient, + Keypair, + Hash, + StakePoolAccounts, + StakeAccount, + Keypair, + Keypair, +) { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) - .await; + .await + .unwrap(); let user = Keypair::new(); @@ -36,7 +55,9 @@ async fn test_remove_validator_stake_account() { &stake_pool_accounts.pool_mint.pubkey(), &user.pubkey(), ) - .await; + .await + .unwrap(); + let error = stake_pool_accounts .add_validator_stake_account( &mut banks_client, @@ -48,6 +69,29 @@ async fn test_remove_validator_stake_account() { .await; assert!(error.is_none()); + ( + banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + user_stake, + user_pool_account, + user, + ) +} + +#[tokio::test] +async fn test_remove_validator_stake_account() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + user_stake, + user_pool_account, + user, + ) = setup().await; + let tokens_to_burn = get_token_balance(&mut banks_client, &user_pool_account.pubkey()).await; delegate_tokens( &mut banks_client, @@ -104,3 +148,445 @@ async fn test_remove_validator_stake_account() { _ => panic!(), } } + +#[tokio::test] +async fn test_remove_validator_stake_account_with_wrong_stake_program_id() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + user_stake, + user_pool_account, + _, + ) = setup().await; + + let wrong_stake_program = Keypair::new(); + + let new_authority = Pubkey::new_unique(); + let mut transaction = Transaction::new_with_payer( + &[instruction::remove_validator_stake_account( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.owner.pubkey(), + &stake_pool_accounts.withdraw_authority, + &new_authority, + &stake_pool_accounts.validator_stake_list.pubkey(), + &user_stake.stake_account, + &user_pool_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &spl_token::id(), + &wrong_stake_program.pubkey(), + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + error, + )) => { + assert_eq!(error, InstructionError::IncorrectProgramId); + } + _ => panic!("Wrong error occurs while try to remove validator stake address with wrong stake program ID"), + } +} + +#[tokio::test] +async fn test_remove_validator_stake_account_with_wrong_token_program_id() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + user_stake, + user_pool_account, + _, + ) = setup().await; + + let wrong_token_program = Keypair::new(); + + let new_authority = Pubkey::new_unique(); + let mut transaction = Transaction::new_with_payer( + &[instruction::remove_validator_stake_account( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.owner.pubkey(), + &stake_pool_accounts.withdraw_authority, + &new_authority, + &stake_pool_accounts.validator_stake_list.pubkey(), + &user_stake.stake_account, + &user_pool_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &wrong_token_program.pubkey(), + &stake::id(), + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { + assert_eq!(error, InstructionError::IncorrectProgramId); + } + _ => panic!("Wrong error occurs while try to remove validator stake address with wrong token program ID"), + } +} + +#[tokio::test] +async fn test_remove_validator_stake_account_with_wrong_pool_mint_account() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + user_stake, + user_pool_account, + _, + ) = setup().await; + + let wrong_pool_mint = Keypair::new(); + + let new_authority = Pubkey::new_unique(); + let mut transaction = Transaction::new_with_payer( + &[instruction::remove_validator_stake_account( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.owner.pubkey(), + &stake_pool_accounts.withdraw_authority, + &new_authority, + &stake_pool_accounts.validator_stake_list.pubkey(), + &user_stake.stake_account, + &user_pool_account.pubkey(), + &wrong_pool_mint.pubkey(), + &spl_token::id(), + &stake::id(), + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::WrongPoolMint as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while try to remove validator stake address with wrong pool mint account"), + } +} + +#[tokio::test] +async fn test_remove_validator_stake_account_with_wrong_validator_stake_list_account() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + user_stake, + user_pool_account, + _, + ) = setup().await; + + let wrong_validator_stake_list = Keypair::new(); + + let new_authority = Pubkey::new_unique(); + let mut transaction = Transaction::new_with_payer( + &[instruction::remove_validator_stake_account( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.owner.pubkey(), + &stake_pool_accounts.withdraw_authority, + &new_authority, + &wrong_validator_stake_list.pubkey(), + &user_stake.stake_account, + &user_pool_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &spl_token::id(), + &stake::id(), + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::InvalidValidatorStakeList as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while try to remove validator stake address with wrong validator stake list account"), + } +} + +#[tokio::test] +async fn test_remove_already_removed_validator_stake_account() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + user_stake, + user_pool_account, + user, + ) = setup().await; + + let tokens_to_burn = get_token_balance(&mut banks_client, &user_pool_account.pubkey()).await; + delegate_tokens( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account.pubkey(), + &user, + &stake_pool_accounts.withdraw_authority, + tokens_to_burn, + ) + .await; + + let new_authority = Pubkey::new_unique(); + let error = stake_pool_accounts + .remove_validator_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.stake_account, + &user_pool_account.pubkey(), + &new_authority, + ) + .await; + assert!(error.is_none()); + + let latest_blockhash = banks_client.get_recent_blockhash().await.unwrap(); + + let transaction_error = stake_pool_accounts + .remove_validator_stake_account( + &mut banks_client, + &payer, + &latest_blockhash, + &user_stake.stake_account, + &user_pool_account.pubkey(), + &new_authority, + ) + .await + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::ValidatorNotFound as u32; + assert_eq!(error_index, program_error); + } + _ => { + panic!("Wrong error occurs while try to remove already removed validator stake address") + } + } +} + +#[tokio::test] +async fn test_not_owner_try_to_remove_validator_stake_account() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + user_stake, + user_pool_account, + _, + ) = setup().await; + + let malicious = Keypair::new(); + + let new_authority = Pubkey::new_unique(); + let mut transaction = Transaction::new_with_payer( + &[instruction::remove_validator_stake_account( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &malicious.pubkey(), + &stake_pool_accounts.withdraw_authority, + &new_authority, + &stake_pool_accounts.validator_stake_list.pubkey(), + &user_stake.stake_account, + &user_pool_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &spl_token::id(), + &stake::id(), + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &malicious], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::WrongOwner as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while not an owner try to remove validator stake address"), + } +} + +#[tokio::test] +async fn test_not_owner_try_to_remove_validator_stake_account_without_signature() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + user_stake, + user_pool_account, + _, + ) = setup().await; + + let new_authority = Pubkey::new_unique(); + + let accounts = vec![ + AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), + AccountMeta::new_readonly(stake_pool_accounts.owner.pubkey(), false), + AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false), + AccountMeta::new_readonly(new_authority, false), + AccountMeta::new(stake_pool_accounts.validator_stake_list.pubkey(), false), + AccountMeta::new(user_stake.stake_account, false), + AccountMeta::new(user_pool_account.pubkey(), false), + AccountMeta::new(stake_pool_accounts.pool_mint.pubkey(), false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(spl_token::id(), false), + AccountMeta::new_readonly(stake::id(), false), + ]; + let instruction = Instruction { + program_id: id(), + accounts, + data: instruction::StakePoolInstruction::RemoveValidatorStakeAccount + .serialize() + .unwrap(), + }; + + let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); + transaction.sign(&[&payer], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::SignatureMissing as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while malicious try to remove validator stake account without signing transaction"), + } +} + +#[tokio::test] +async fn test_remove_validator_stake_account_when_stake_acc_not_in_stake_state() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await + .unwrap(); + + let user = Keypair::new(); + + let user_stake = StakeAccount::new_with_target_authority( + &stake_pool_accounts.deposit_authority, + &stake_pool_accounts.stake_pool.pubkey(), + ); + let user_stake_authority = Keypair::new(); + create_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.stake_pool, + &user_stake.stake_account, + &user_stake.vote.pubkey(), + &user_stake_authority.pubkey(), + &user_stake.target_authority, + ) + .await; + + let user_pool_account = Keypair::new(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user.pubkey(), + ) + .await + .unwrap(); + + let new_authority = Pubkey::new_unique(); + + let transaction_error = stake_pool_accounts + .remove_validator_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.stake_account, + &user_pool_account.pubkey(), + &new_authority, + ) + .await + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::WrongStakeState as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while try to add validator stake account when it isn't in stake state"), + } +} + +#[tokio::test] +async fn test_remove_validator_stake_account_from_unupdated_stake_pool() {} // TODO + +#[tokio::test] +async fn test_remove_validator_stake_account_with_uninitialized_validator_stake_list_account() {} // TODO diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 46059399..ed805da1 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -5,16 +5,34 @@ mod helpers; use helpers::*; use solana_program::pubkey::Pubkey; -use solana_sdk::signature::{Keypair, Signer}; +use solana_program::hash::Hash; +use solana_program_test::BanksClient; +use solana_sdk::{ + instruction::InstructionError, + signature::{Keypair, Signer}, + transaction::Transaction, + transaction::TransactionError, + transport::TransportError, +}; use spl_stake_pool::*; +use spl_token::error::TokenError; -#[tokio::test] -async fn test_stake_pool_withdraw() { +async fn setup() -> ( + BanksClient, + Keypair, + Hash, + StakePoolAccounts, + StakeAccount, + DepositInfo, + u64, + u64, +) { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) - .await; + .await + .unwrap(); let validator_stake_account: StakeAccount = simple_add_validator_stake_account( &mut banks_client, @@ -48,6 +66,31 @@ async fn test_stake_pool_withdraw() { ) .await; + ( + banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + validator_stake_account, + deposit_info, + tokens_to_burn, + lamports_to_withdraw, + ) +} + +#[tokio::test] +async fn test_stake_pool_withdraw() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + validator_stake_account, + deposit_info, + tokens_to_burn, + lamports_to_withdraw, + ) = setup().await; + // Create stake account to withdraw to let user_stake_recipient = Keypair::new(); let initial_stake_lamports = create_blank_stake_account( @@ -94,7 +137,8 @@ async fn test_stake_pool_withdraw() { &new_authority, lamports_to_withdraw, ) - .await; + .await + .unwrap(); // Check pool stats let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; @@ -151,3 +195,639 @@ async fn test_stake_pool_withdraw() { initial_stake_lamports + lamports_to_withdraw ); } + +#[tokio::test] +async fn test_stake_pool_withdraw_with_wrong_stake_program() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + validator_stake_account, + deposit_info, + _, + lamports_to_withdraw, + ) = setup().await; + + // Create stake account to withdraw to + let user_stake_recipient = Keypair::new(); + + let new_authority = Pubkey::new_unique(); + let wrong_stake_program = Keypair::new(); + + let mut transaction = Transaction::new_with_payer( + &[instruction::withdraw( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.validator_stake_list.pubkey(), + &stake_pool_accounts.withdraw_authority, + &validator_stake_account.stake_account, + &user_stake_recipient.pubkey(), + &new_authority, + &deposit_info.user_pool_account, + &stake_pool_accounts.pool_mint.pubkey(), + &spl_token::id(), + &wrong_stake_program.pubkey(), + lamports_to_withdraw, + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { + assert_eq!(error, InstructionError::IncorrectProgramId); + } + _ => panic!("Wrong error occurs while try to withdraw with wrong stake program ID"), + } +} + +#[tokio::test] +async fn test_stake_pool_withdraw_with_wrong_withdraw_authority() { + let ( + mut banks_client, + payer, + recent_blockhash, + mut stake_pool_accounts, + validator_stake_account, + deposit_info, + _, + lamports_to_withdraw, + ) = setup().await; + + // Create stake account to withdraw to + let user_stake_recipient = Keypair::new(); + + let new_authority = Pubkey::new_unique(); + stake_pool_accounts.withdraw_authority = Keypair::new().pubkey(); + + let transaction_error = stake_pool_accounts + .withdraw_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake_recipient.pubkey(), + &deposit_info.user_pool_account, + &validator_stake_account.stake_account, + &new_authority, + lamports_to_withdraw, + ) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::InvalidProgramAddress as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while try to withdraw with wrong withdraw authority"), + } +} + +#[tokio::test] +async fn test_stake_pool_withdraw_with_wrong_token_program_id() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + validator_stake_account, + deposit_info, + _, + lamports_to_withdraw, + ) = setup().await; + + // Create stake account to withdraw to + let user_stake_recipient = Keypair::new(); + + let new_authority = Pubkey::new_unique(); + let wrong_token_program = Keypair::new(); + + let mut transaction = Transaction::new_with_payer( + &[instruction::withdraw( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.validator_stake_list.pubkey(), + &stake_pool_accounts.withdraw_authority, + &validator_stake_account.stake_account, + &user_stake_recipient.pubkey(), + &new_authority, + &deposit_info.user_pool_account, + &stake_pool_accounts.pool_mint.pubkey(), + &wrong_token_program.pubkey(), + &stake::id(), + lamports_to_withdraw, + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { + assert_eq!(error, InstructionError::IncorrectProgramId); + } + _ => panic!("Wrong error occurs while try to withdraw with wrong token program ID"), + } +} + +#[tokio::test] +async fn test_stake_pool_withdraw_with_wrong_validator_stake_list() { + let ( + mut banks_client, + payer, + recent_blockhash, + mut stake_pool_accounts, + validator_stake_account, + deposit_info, + _, + lamports_to_withdraw, + ) = setup().await; + + // Create stake account to withdraw to + let user_stake_recipient = Keypair::new(); + + let new_authority = Pubkey::new_unique(); + stake_pool_accounts.validator_stake_list = Keypair::new(); + + let transaction_error = stake_pool_accounts + .withdraw_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake_recipient.pubkey(), + &deposit_info.user_pool_account, + &validator_stake_account.stake_account, + &new_authority, + lamports_to_withdraw, + ) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::InvalidValidatorStakeList as u32; + assert_eq!(error_index, program_error); + } + _ => panic!( + "Wrong error occurs while try to withdraw with wrong validator stake list account" + ), + } +} + +#[tokio::test] +async fn test_stake_pool_withdraw_when_stake_acc_not_in_stake_state() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await + .unwrap(); + + let validator_stake_account = StakeAccount::new_with_target_authority( + &stake_pool_accounts.deposit_authority, + &stake_pool_accounts.stake_pool.pubkey(), + ); + + let user_stake_authority = Keypair::new(); + create_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &validator_stake_account.stake_pool, + &validator_stake_account.stake_account, + &validator_stake_account.vote.pubkey(), + &user_stake_authority.pubkey(), + &validator_stake_account.target_authority, + ) + .await; + + let user = Keypair::new(); + // make stake account + let user_stake = Keypair::new(); + let lockup = stake::Lockup::default(); + let authorized = stake::Authorized { + staker: stake_pool_accounts.deposit_authority, + withdrawer: stake_pool_accounts.deposit_authority, + }; + create_independent_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake, + &authorized, + &lockup, + ) + .await; + // make pool token account + let user_pool_account = Keypair::new(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user.pubkey(), + ) + .await + .unwrap(); + + let user_pool_account = user_pool_account.pubkey(); + let pool_tokens = get_token_balance(&mut banks_client, &user_pool_account).await; + + let tokens_to_burn = pool_tokens / 4; + let lamports_to_withdraw = tokens_to_burn; // For now math is 1:1 + + // Delegate tokens for burning + delegate_tokens( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account, + &user, + &stake_pool_accounts.withdraw_authority, + tokens_to_burn, + ) + .await; + + // Create stake account to withdraw to + let user_stake_recipient = Keypair::new(); + + let new_authority = Pubkey::new_unique(); + + let transaction_error = stake_pool_accounts + .withdraw_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake_recipient.pubkey(), + &user_pool_account, + &validator_stake_account.stake_account, + &new_authority, + lamports_to_withdraw, + ) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::WrongStakeState as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while try to withdraw when stake acc not in stake state"), + } +} + +#[tokio::test] +async fn test_stake_pool_withdraw_from_unknown_validator() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await + .unwrap(); + + let validator_stake_account = StakeAccount::new_with_target_authority( + &stake_pool_accounts.deposit_authority, + &stake_pool_accounts.stake_pool.pubkey(), + ); + validator_stake_account + .create_and_delegate(&mut banks_client, &payer, &recent_blockhash) + .await; + + let user_stake = StakeAccount::new_with_target_authority( + &stake_pool_accounts.deposit_authority, + &stake_pool_accounts.stake_pool.pubkey(), + ); + user_stake + .create_and_delegate(&mut banks_client, &payer, &recent_blockhash) + .await; + + let user_pool_account = Keypair::new(); + let user = Keypair::new(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user.pubkey(), + ) + .await + .unwrap(); + + let user = Keypair::new(); + // make stake account + let user_stake = Keypair::new(); + let lockup = stake::Lockup::default(); + let authorized = stake::Authorized { + staker: stake_pool_accounts.deposit_authority, + withdrawer: stake_pool_accounts.deposit_authority, + }; + create_independent_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake, + &authorized, + &lockup, + ) + .await; + // make pool token account + let user_pool_account = Keypair::new(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user.pubkey(), + ) + .await + .unwrap(); + + let user_pool_account = user_pool_account.pubkey(); + let pool_tokens = get_token_balance(&mut banks_client, &user_pool_account).await; + + let tokens_to_burn = pool_tokens / 4; + let lamports_to_withdraw = tokens_to_burn; // For now math is 1:1 + + // Delegate tokens for burning + delegate_tokens( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account, + &user, + &stake_pool_accounts.withdraw_authority, + tokens_to_burn, + ) + .await; + + // Create stake account to withdraw to + let user_stake_recipient = Keypair::new(); + + let new_authority = Pubkey::new_unique(); + + let transaction_error = stake_pool_accounts + .withdraw_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake_recipient.pubkey(), + &user_pool_account, + &validator_stake_account.stake_account, + &new_authority, + lamports_to_withdraw, + ) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::ValidatorNotFound as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while try to do withdraw from unknown validator"), + } +} + +#[tokio::test] +async fn test_stake_pool_double_withdraw_to_the_same_account() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + validator_stake_account, + deposit_info, + _, + lamports_to_withdraw, + ) = setup().await; + + // Create stake account to withdraw to + let user_stake_recipient = Keypair::new(); + create_blank_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake_recipient, + ) + .await; + + let new_authority = Pubkey::new_unique(); + stake_pool_accounts + .withdraw_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake_recipient.pubkey(), + &deposit_info.user_pool_account, + &validator_stake_account.stake_account, + &new_authority, + lamports_to_withdraw, + ) + .await + .unwrap(); + + let latest_blockhash = banks_client.get_recent_blockhash().await.unwrap(); + + let transaction_error = stake_pool_accounts + .withdraw_stake( + &mut banks_client, + &payer, + &latest_blockhash, + &user_stake_recipient.pubkey(), + &deposit_info.user_pool_account, + &validator_stake_account.stake_account, + &new_authority, + lamports_to_withdraw, + ) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { + assert_eq!(error, InstructionError::InvalidAccountData); + } + _ => panic!("Wrong error occurs while try to do double withdraw"), + } +} + +#[tokio::test] +async fn test_stake_pool_withdraw_token_delegate_was_not_setup() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await + .unwrap(); + + let validator_stake_account: StakeAccount = simple_add_validator_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + ) + .await; + + let deposit_info: DepositInfo = simple_deposit( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + &validator_stake_account, + ) + .await; + + let tokens_to_burn = deposit_info.pool_tokens / 4; + let lamports_to_withdraw = tokens_to_burn; // For now math is 1:1 + + // Create stake account to withdraw to + let user_stake_recipient = Keypair::new(); + create_blank_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake_recipient, + ) + .await; + + let new_authority = Pubkey::new_unique(); + let transaction_error = stake_pool_accounts + .withdraw_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake_recipient.pubkey(), + &deposit_info.user_pool_account, + &validator_stake_account.stake_account, + &new_authority, + lamports_to_withdraw, + ) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = TokenError::OwnerMismatch as u32; + assert_eq!(error_index, program_error); + } + _ => panic!( + "Wrong error occurs while try to do withdraw without token delegation for burn before" + ), + } +} + +#[tokio::test] +async fn test_stake_pool_withdraw_with_low_delegation() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await + .unwrap(); + + let validator_stake_account: StakeAccount = simple_add_validator_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + ) + .await; + + let deposit_info: DepositInfo = simple_deposit( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + &validator_stake_account, + ) + .await; + + let tokens_to_burn = deposit_info.pool_tokens / 4; + let lamports_to_withdraw = tokens_to_burn; // For now math is 1:1 + + // Delegate tokens for burning + delegate_tokens( + &mut banks_client, + &payer, + &recent_blockhash, + &deposit_info.user_pool_account, + &deposit_info.user, + &stake_pool_accounts.withdraw_authority, + 1, + ) + .await; + + // Create stake account to withdraw to + let user_stake_recipient = Keypair::new(); + create_blank_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake_recipient, + ) + .await; + + let new_authority = Pubkey::new_unique(); + let transaction_error = stake_pool_accounts + .withdraw_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake_recipient.pubkey(), + &deposit_info.user_pool_account, + &validator_stake_account.stake_account, + &new_authority, + lamports_to_withdraw, + ) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = TokenError::InsufficientFunds as u32; + assert_eq!(error_index, program_error); + } + _ => panic!( + "Wrong error occurs while try to do withdraw with not enough delegated tokens to burn" + ), + } +} From 181b316a0bbf6606e544d36fb16548654cc6c71e Mon Sep 17 00:00:00 2001 From: Atticlab LLC Date: Wed, 10 Feb 2021 18:42:28 +0200 Subject: [PATCH 0040/1076] Various postponed fixes and changes to the stake pool program (#1200) * Various postponed fixes and changes to the stake pool program * Fixed PR comments * Fixed no-signature validator stake account add test Co-authored-by: Yuriy Savchenko --- clients/cli/src/main.rs | 66 ++-- program/src/error.rs | 13 +- program/src/instruction.rs | 15 +- program/src/processor.rs | 264 ++++++++++------ program/src/stake.rs | 209 +++++++++++- program/src/state.rs | 104 +++--- program/tests/deposit.rs | 158 +++++++++- program/tests/helpers/mod.rs | 28 +- program/tests/initialize.rs | 419 +++++++++++++++++++++++-- program/tests/set_owner.rs | 5 +- program/tests/set_staking_authority.rs | 10 +- program/tests/update_list_balance.rs | 2 +- program/tests/vsa_add.rs | 11 +- program/tests/vsa_remove.rs | 10 +- program/tests/withdraw.rs | 78 ++--- 15 files changed, 1069 insertions(+), 323 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index f394ac58..02bf8bb3 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -39,7 +39,6 @@ use spl_stake_pool::{ stake::StakeAuthorize, stake::StakeState, state::StakePool, - state::State as PoolState, state::ValidatorStakeList, }; use spl_token::{ @@ -148,7 +147,7 @@ fn command_create_pool(config: &Config, fee: PoolFee) -> CommandResult { .get_minimum_balance_for_rent_exemption(TokenAccount::LEN)?; let pool_account_balance = config .rpc_client - .get_minimum_balance_for_rent_exemption(PoolState::LEN)?; + .get_minimum_balance_for_rent_exemption(StakePool::LEN)?; let validator_stake_list_balance = config .rpc_client .get_minimum_balance_for_rent_exemption(ValidatorStakeList::LEN)?; @@ -193,7 +192,7 @@ fn command_create_pool(config: &Config, fee: PoolFee) -> CommandResult { &config.fee_payer.pubkey(), &pool_account.pubkey(), pool_account_balance, - PoolState::LEN as u64, + StakePool::LEN as u64, &spl_stake_pool::id(), ), // Validator stake account list storage @@ -245,6 +244,7 @@ fn command_create_pool(config: &Config, fee: PoolFee) -> CommandResult { &validator_stake_list, &mint_account, &pool_fee_account, + config.owner.as_ref(), ]; unique_signers!(signers); transaction.sign(&signers, recent_blockhash); @@ -289,10 +289,7 @@ fn command_vsa_add( ) -> CommandResult { // Get stake pool state let pool_data = config.rpc_client.get_account_data(&pool)?; - let pool_data: StakePool = PoolState::deserialize(pool_data.as_slice()) - .unwrap() - .stake_pool() - .unwrap(); + let pool_data: StakePool = StakePool::deserialize(pool_data.as_slice()).unwrap(); let mut total_rent_free_balances: u64 = 0; @@ -383,10 +380,7 @@ fn command_vsa_remove( ) -> CommandResult { // Get stake pool state let pool_data = config.rpc_client.get_account_data(&pool)?; - let pool_data: StakePool = PoolState::deserialize(pool_data.as_slice()) - .unwrap() - .stake_pool() - .unwrap(); + let pool_data: StakePool = StakePool::deserialize(pool_data.as_slice()).unwrap(); let pool_withdraw_authority: Pubkey = PoolProcessor::authority_id( &spl_stake_pool::id(), @@ -512,10 +506,7 @@ fn command_deposit( ) -> CommandResult { // Get stake pool state let pool_data = config.rpc_client.get_account_data(&pool)?; - let pool_data: StakePool = PoolState::deserialize(pool_data.as_slice()) - .unwrap() - .stake_pool() - .unwrap(); + let pool_data: StakePool = StakePool::deserialize(pool_data.as_slice()).unwrap(); // Get stake account data let stake_data = config.rpc_client.get_account_data(&stake)?; @@ -624,10 +615,7 @@ fn command_deposit( fn command_list(config: &Config, pool: &Pubkey) -> CommandResult { // Get stake pool state let pool_data = config.rpc_client.get_account_data(&pool)?; - let pool_data: StakePool = PoolState::deserialize(pool_data.as_slice()) - .unwrap() - .stake_pool() - .unwrap(); + let pool_data: StakePool = StakePool::deserialize(pool_data.as_slice()).unwrap(); let pool_withdraw_authority: Pubkey = PoolProcessor::authority_id( &spl_stake_pool::id(), @@ -657,10 +645,7 @@ fn command_list(config: &Config, pool: &Pubkey) -> CommandResult { fn command_update(config: &Config, pool: &Pubkey) -> CommandResult { // Get stake pool state let pool_data = config.rpc_client.get_account_data(&pool)?; - let pool_data: StakePool = PoolState::deserialize(pool_data.as_slice()) - .unwrap() - .stake_pool() - .unwrap(); + let pool_data: StakePool = StakePool::deserialize(pool_data.as_slice()).unwrap(); let validator_stake_list_data = config .rpc_client .get_account_data(&pool_data.validator_stake_list)?; @@ -804,10 +789,7 @@ fn command_withdraw( ) -> CommandResult { // Get stake pool state let pool_data = config.rpc_client.get_account_data(&pool)?; - let pool_data: StakePool = PoolState::deserialize(pool_data.as_slice()) - .unwrap() - .stake_pool() - .unwrap(); + let pool_data: StakePool = StakePool::deserialize(pool_data.as_slice()).unwrap(); let pool_withdraw_authority: Pubkey = PoolProcessor::authority_id( &spl_stake_pool::id(), @@ -827,19 +809,21 @@ fn command_withdraw( } // Check burn_from balance - let max_withdraw_amount = pool_tokens_to_stake_amount(&pool_data, account_data.amount); - if max_withdraw_amount < amount { + if account_data.amount < amount { return Err(format!( - "Not enough token balance to withdraw {} SOL.\nMaximum withdraw amount is {} SOL.", + "Not enough token balance to withdraw {} pool tokens.\nMaximum withdraw amount is {} pool tokens.", lamports_to_sol(amount), - lamports_to_sol(max_withdraw_amount) + lamports_to_sol(account_data.amount) ) .into()); } + // Convert pool tokens amount to lamports + let sol_withdraw_amount = pool_tokens_to_stake_amount(&pool_data, amount); + // Get the list of accounts to withdraw from let withdraw_from: Vec = - prepare_withdraw_accounts(config, &pool_withdraw_authority, amount)?; + prepare_withdraw_accounts(config, &pool_withdraw_authority, sol_withdraw_amount)?; // Construct transaction to withdraw from withdraw_from account list let mut instructions: Vec = vec![]; @@ -848,9 +832,6 @@ fn command_withdraw( let mut total_rent_free_balances: u64 = 0; - // Calculate amount of tokens to burn - let tokens_to_burn = stake_amount_to_pool_tokens(&pool_data, amount); - instructions.push( // Approve spending token approve_token( @@ -859,7 +840,7 @@ fn command_withdraw( &pool_withdraw_authority, &config.owner.pubkey(), &[], - tokens_to_burn, + amount, )?, ); @@ -940,10 +921,7 @@ fn command_set_staking_auth( new_staker: &Pubkey, ) -> CommandResult { let pool_data = config.rpc_client.get_account_data(&pool)?; - let pool_data: StakePool = PoolState::deserialize(pool_data.as_slice()) - .unwrap() - .stake_pool() - .unwrap(); + let pool_data: StakePool = StakePool::deserialize(pool_data.as_slice()).unwrap(); let pool_withdraw_authority: Pubkey = PoolProcessor::authority_id( &spl_stake_pool::id(), @@ -981,10 +959,7 @@ fn command_set_owner( new_fee_receiver: &Option, ) -> CommandResult { let pool_data = config.rpc_client.get_account_data(&pool)?; - let pool_data: StakePool = PoolState::deserialize(pool_data.as_slice()) - .unwrap() - .stake_pool() - .unwrap(); + let pool_data: StakePool = StakePool::deserialize(pool_data.as_slice()).unwrap(); // If new accounts are missing in the arguments use the old ones let new_owner: Pubkey = match new_owner { @@ -1264,7 +1239,7 @@ fn main() { .value_name("AMOUNT") .takes_value(true) .required(true) - .help("Amount in SOL to withdraw from the pool."), + .help("Amount of pool tokens to burn and get rewards."), ) .arg( Arg::with_name("burn_from") @@ -1444,6 +1419,7 @@ fn main() { ("withdraw", Some(arg_matches)) => { let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); let burn_from: Pubkey = pubkey_of(arg_matches, "burn_from").unwrap(); + // convert from float to int, using sol_to_lamports because they have the same precision as SOL let amount: u64 = sol_to_lamports(value_t_or_exit!(arg_matches, "amount", f64)); let stake_receiver: Option = pubkey_of(arg_matches, "stake_receiver"); command_withdraw(&config, &pool_account, amount, &burn_from, &stake_receiver) diff --git a/program/src/error.rs b/program/src/error.rs index d39a73a3..d2a34451 100644 --- a/program/src/error.rs +++ b/program/src/error.rs @@ -13,7 +13,7 @@ pub enum StakePoolError { /// The program address provided doesn't match the value generated by the program. #[error("InvalidProgramAddress")] InvalidProgramAddress, - /// The token swap state is invalid. + /// The stake pool state is invalid. #[error("InvalidState")] InvalidState, /// The calculation failed. @@ -46,6 +46,9 @@ pub enum StakePoolError { /// Stake account is not in the state expected by the program. #[error("WrongStakeState")] WrongStakeState, + /// User stake is not active + #[error("UserStakeNotActive")] + UserStakeNotActive, /// Stake account voting for this validator already exists in the pool. #[error("ValidatorAlreadyAdded")] ValidatorAlreadyAdded, @@ -58,12 +61,18 @@ pub enum StakePoolError { /// Identify validator stake accounts with old balances and update them. #[error("StakeListOutOfDate")] StakeListOutOfDate, - /// First udpate old validator stake account balances and then pool stake balance. + /// First update old validator stake account balances and then pool stake balance. #[error("StakeListAndPoolOutOfDate")] StakeListAndPoolOutOfDate, /// Validator stake account is not found in the list storage. #[error("UnknownValidatorStakeAccount")] UnknownValidatorStakeAccount, + /// Wrong minting authority set for mint pool account + #[error("WrongMintingAuthority")] + WrongMintingAuthority, + /// Account is not rent-exempt + #[error("AccountNotRentExempt")] + AccountNotRentExempt, } impl From for ProgramError { fn from(e: StakePoolError) -> Self { diff --git a/program/src/instruction.rs b/program/src/instruction.rs index abbe1c4c..00c85ccf 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -35,11 +35,13 @@ pub enum StakePoolInstruction { /// Initializes a new StakePool. /// /// 0. `[w]` New StakePool to create. - /// 1. `[]` Owner + /// 1. `[s]` Owner /// 2. `[w]` Uninitialized validator stake list storage account /// 3. `[]` pool token Mint. Must be non zero, owned by withdraw authority. /// 4. `[]` Pool Account to deposit the generated fee for owner. - /// 5. `[]` Token program id + /// 5. `[]` Clock sysvar + /// 6. `[]` Rent sysvar + /// 7. `[]` Token program id Initialize(InitArgs), /// Creates new program account for accumulating stakes for a particular validator @@ -66,8 +68,9 @@ pub enum StakePoolInstruction { /// 6. `[w]` User account to receive pool tokens /// 7. `[w]` Pool token mint account /// 8. `[]` Clock sysvar (required) - /// 9. `[]` Pool token program id, - /// 10. `[]` Stake program id, + /// 9. '[]' Sysvar stake history account + /// 10. `[]` Pool token program id, + /// 11. `[]` Stake program id, AddValidatorStakeAccount, /// Removes validator stake account from the pool @@ -253,11 +256,12 @@ pub fn initialize( let data = init_data.serialize()?; let accounts = vec![ AccountMeta::new(*stake_pool, true), - AccountMeta::new_readonly(*owner, false), + AccountMeta::new_readonly(*owner, true), AccountMeta::new(*validator_stake_list, false), AccountMeta::new_readonly(*pool_mint, false), AccountMeta::new_readonly(*owner_pool_account, false), AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(sysvar::rent::id(), false), AccountMeta::new_readonly(*token_program_id, false), ]; Ok(Instruction { @@ -321,6 +325,7 @@ pub fn add_validator_stake_account( AccountMeta::new(*pool_tokens_to, false), AccountMeta::new(*pool_mint, false), AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(sysvar::stake_history::id(), false), AccountMeta::new_readonly(*token_program_id, false), AccountMeta::new_readonly(*stake_program_id, false), ]; diff --git a/program/src/processor.rs b/program/src/processor.rs index 2203c8fa..73bf4b82 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -4,7 +4,7 @@ use crate::{ error::StakePoolError, instruction::{InitArgs, StakePoolInstruction}, stake, - state::{StakePool, State, ValidatorStakeInfo, ValidatorStakeList}, + state::{StakePool, ValidatorStakeInfo, ValidatorStakeList}, PROGRAM_VERSION, }; use bincode::deserialize; @@ -22,9 +22,11 @@ use solana_program::{ program_pack::Pack, pubkey::Pubkey, rent::Rent, + stake_history::StakeHistory, system_instruction, sysvar::Sysvar, }; +use spl_token::state::Mint; /// Program state handler. pub struct Processor {} @@ -293,33 +295,53 @@ impl Processor { // Clock sysvar account let clock_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(clock_info)?; + // Rent sysvar account + let rent_info = next_account_info(account_info_iter)?; + let rent = &Rent::from_account_info(rent_info)?; // Token program ID let token_program_info = next_account_info(account_info_iter)?; + // Check if transaction was signed by owner + if !owner_info.is_signer { + return Err(StakePoolError::SignatureMissing.into()); + } + + let mut stake_pool = StakePool::deserialize(&stake_pool_info.data.borrow())?; // Stake pool account should not be already initialized - if State::Unallocated != State::deserialize(&stake_pool_info.data.borrow())? { + if stake_pool.is_initialized() { return Err(StakePoolError::AlreadyInUse.into()); } // Check if validator stake list storage is unitialized let mut validator_stake_list = ValidatorStakeList::deserialize(&validator_stake_list_info.data.borrow())?; - if validator_stake_list.is_initialized { + if validator_stake_list.is_initialized() { return Err(StakePoolError::AlreadyInUse.into()); } - validator_stake_list.is_initialized = true; + validator_stake_list.version = ValidatorStakeList::VALIDATOR_STAKE_LIST_VERSION; validator_stake_list.validators.clear(); + // Check if stake pool account is rent-exempt + if !rent.is_exempt(stake_pool_info.lamports(), stake_pool_info.data_len()) { + return Err(StakePoolError::AccountNotRentExempt.into()); + } + + // Check if validator stake list account is rent-exempt + if !rent.is_exempt( + validator_stake_list_info.lamports(), + validator_stake_list_info.data_len(), + ) { + return Err(StakePoolError::AccountNotRentExempt.into()); + } + // Numerator should be smaller than or equal to denominator (fee <= 1) if init.fee.numerator > init.fee.denominator { return Err(StakePoolError::FeeTooHigh.into()); } - // Check for owner fee account to have proper mint assigned - if *pool_mint_info.key - != spl_token::state::Account::unpack_from_slice(&owner_fee_info.data.borrow())?.mint - { - return Err(StakePoolError::WrongAccountMint.into()); + // Check if fee account's owner the same as token program id + if owner_fee_info.owner != token_program_info.key { + return Err(StakePoolError::InvalidFeeAccount.into()); } // Check pool mint program ID @@ -327,36 +349,46 @@ impl Processor { return Err(ProgramError::IncorrectProgramId); } + // Check for owner fee account to have proper mint assigned + if *pool_mint_info.key + != spl_token::state::Account::unpack_from_slice(&owner_fee_info.data.borrow())?.mint + { + return Err(StakePoolError::WrongAccountMint.into()); + } + let (_, deposit_bump_seed) = Self::find_authority_bump_seed( program_id, stake_pool_info.key, Self::AUTHORITY_DEPOSIT, ); - let (_, withdraw_bump_seed) = Self::find_authority_bump_seed( + let (withdraw_authority_key, withdraw_bump_seed) = Self::find_authority_bump_seed( program_id, stake_pool_info.key, Self::AUTHORITY_WITHDRAW, ); + let pool_mint = Mint::unpack_from_slice(&pool_mint_info.data.borrow())?; + + if !pool_mint.mint_authority.contains(&withdraw_authority_key) { + return Err(StakePoolError::WrongMintingAuthority.into()); + } + validator_stake_list.serialize(&mut validator_stake_list_info.data.borrow_mut())?; msg!("Clock data: {:?}", clock_info.data.borrow()); msg!("Epoch: {}", clock.epoch); - let stake_pool = State::Init(StakePool { - version: PROGRAM_VERSION, - owner: *owner_info.key, - deposit_bump_seed, - withdraw_bump_seed, - validator_stake_list: *validator_stake_list_info.key, - pool_mint: *pool_mint_info.key, - owner_fee_account: *owner_fee_info.key, - token_program_id: *token_program_info.key, - stake_total: 0, - pool_total: 0, - last_update_epoch: clock.epoch, - fee: init.fee, - }); + stake_pool.version = PROGRAM_VERSION; + stake_pool.owner = *owner_info.key; + stake_pool.deposit_bump_seed = deposit_bump_seed; + stake_pool.withdraw_bump_seed = withdraw_bump_seed; + stake_pool.validator_stake_list = *validator_stake_list_info.key; + stake_pool.pool_mint = *pool_mint_info.key; + stake_pool.owner_fee_account = *owner_fee_info.key; + stake_pool.token_program_id = *token_program_info.key; + stake_pool.last_update_epoch = clock.epoch; + stake_pool.fee = init.fee; + stake_pool.serialize(&mut stake_pool_info.data.borrow_mut()) } @@ -412,35 +444,20 @@ impl Processor { // Fund the associated token account with the minimum balance to be rent exempt let required_lamports = 1 + rent.minimum_balance(std::mem::size_of::()); - // Fund new account - invoke( - &system_instruction::transfer( + + // Create new stake account + invoke_signed( + &system_instruction::create_account( &funder_info.key, - stake_account_info.key, + &stake_account_info.key, required_lamports, - ), - &[ - funder_info.clone(), - stake_account_info.clone(), - system_program_info.clone(), - ], - )?; - // Allocate account space - invoke_signed( - &system_instruction::allocate( - stake_account_info.key, std::mem::size_of::() as u64, + &stake::id(), ), - &[stake_account_info.clone(), system_program_info.clone()], - &[&stake_account_signer_seeds], - )?; - // Assign account to the stake program - invoke_signed( - &system_instruction::assign(stake_account_info.key, &stake::id()), - &[stake_account_info.clone(), system_program_info.clone()], + &[funder_info.clone(), stake_account_info.clone()], &[&stake_account_signer_seeds], )?; - // Initialize stake account + invoke( &stake::initialize( &stake_account_info.key, @@ -483,6 +500,9 @@ impl Processor { // Clock sysvar account let clock_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(clock_info)?; + // Stake history sysvar account + let stake_history_info = next_account_info(account_info_iter)?; + let stake_history = &StakeHistory::from_account_info(stake_history_info)?; // Pool token program id let token_program_info = next_account_info(account_info_iter)?; // Staking program id @@ -493,8 +513,11 @@ impl Processor { return Err(ProgramError::IncorrectProgramId); } - // Get stake pool stake (and check if it is iniaialized) - let mut stake_pool = State::deserialize(&stake_pool_info.data.borrow())?.stake_pool()?; + // Get stake pool stake (and check if it is initialized) + let mut stake_pool = StakePool::deserialize(&stake_pool_info.data.borrow())?; + if !stake_pool.is_initialized() { + return Err(StakePoolError::InvalidState.into()); + } // Check authority accounts stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?; @@ -523,7 +546,7 @@ impl Processor { // Read validator stake list account and check if it is valid let mut validator_stake_list = ValidatorStakeList::deserialize(&validator_stake_list_info.data.borrow())?; - if !validator_stake_list.is_initialized { + if !validator_stake_list.is_initialized() { return Err(StakePoolError::InvalidState.into()); } @@ -568,7 +591,8 @@ impl Processor { token_amount, )?; - // TODO: Check if stake is warmed up + // Check if stake is warmed up + Self::check_stake_activation(stake_account_info, clock, stake_history)?; // Add validator to the list and save validator_stake_list.validators.push(ValidatorStakeInfo { @@ -582,7 +606,7 @@ impl Processor { stake_pool.pool_total += token_amount; // Only update stake total if the last state update epoch is current stake_pool.stake_total += stake_lamports; - State::Init(stake_pool).serialize(&mut stake_pool_info.data.borrow_mut())?; + stake_pool.serialize(&mut stake_pool_info.data.borrow_mut())?; Ok(()) } @@ -622,8 +646,11 @@ impl Processor { return Err(ProgramError::IncorrectProgramId); } - // Get stake pool stake (and check if it is iniaialized) - let mut stake_pool = State::deserialize(&stake_pool_info.data.borrow())?.stake_pool()?; + // Get stake pool stake (and check if it is initialized) + let mut stake_pool = StakePool::deserialize(&stake_pool_info.data.borrow())?; + if !stake_pool.is_initialized() { + return Err(StakePoolError::InvalidState.into()); + } // Check authority account stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?; @@ -651,7 +678,7 @@ impl Processor { // Read validator stake list account and check if it is valid let mut validator_stake_list = ValidatorStakeList::deserialize(&validator_stake_list_info.data.borrow())?; - if !validator_stake_list.is_initialized { + if !validator_stake_list.is_initialized() { return Err(StakePoolError::InvalidState.into()); } @@ -706,7 +733,7 @@ impl Processor { stake_pool.pool_total -= token_amount; // Only update stake total if the last state update epoch is current stake_pool.stake_total -= stake_lamports; - State::Init(stake_pool).serialize(&mut stake_pool_info.data.borrow_mut())?; + stake_pool.serialize(&mut stake_pool_info.data.borrow_mut())?; Ok(()) } @@ -728,7 +755,7 @@ impl Processor { // Read validator stake list account and check if it is valid let mut validator_stake_list = ValidatorStakeList::deserialize(&validator_stake_list_info.data.borrow())?; - if !validator_stake_list.is_initialized { + if !validator_stake_list.is_initialized() { return Err(StakePoolError::InvalidState.into()); } @@ -779,8 +806,11 @@ impl Processor { let clock_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(clock_info)?; - // Get stake pool stake (and check if it is iniaialized) - let mut stake_pool = State::deserialize(&stake_pool_info.data.borrow())?.stake_pool()?; + // Get stake pool stake (and check if it is initialized) + let mut stake_pool = StakePool::deserialize(&stake_pool_info.data.borrow())?; + if !stake_pool.is_initialized() { + return Err(StakePoolError::InvalidState.into()); + } // Check validator stake account list storage if *validator_stake_list_info.key != stake_pool.validator_stake_list { @@ -790,7 +820,7 @@ impl Processor { // Read validator stake list account and check if it is valid let validator_stake_list = ValidatorStakeList::deserialize(&validator_stake_list_info.data.borrow())?; - if !validator_stake_list.is_initialized { + if !validator_stake_list.is_initialized() { return Err(StakePoolError::InvalidState.into()); } @@ -804,11 +834,40 @@ impl Processor { stake_pool.stake_total = total_balance; stake_pool.last_update_epoch = clock.epoch; - State::Init(stake_pool).serialize(&mut stake_pool_info.data.borrow_mut())?; + stake_pool.serialize(&mut stake_pool_info.data.borrow_mut())?; Ok(()) } + /// Check stake activation status + pub fn check_stake_activation( + _stake_info: &AccountInfo, + _clock: &Clock, + _stake_history: &StakeHistory, + ) -> ProgramResult { + // TODO: remove conditional compilation when time travel in tests is possible + //#[cfg(not(feature = "test-bpf"))] + // This check is commented to make tests run without special command line arguments + /*{ + let stake_acc_state: stake::StakeState = + deserialize(&stake_info.data.borrow()).unwrap(); + let delegation = stake_acc_state.delegation(); + if let Some(delegation) = delegation { + let target_epoch = clock.epoch; + let history = Some(stake_history); + let fix_stake_deactivate = true; + let (effective, activating, deactivating) = delegation + .stake_activating_and_deactivating(target_epoch, history, fix_stake_deactivate); + if activating != 0 || deactivating != 0 || effective == 0 { + return Err(StakePoolError::UserStakeNotActive.into()); + } + } else { + return Err(StakePoolError::WrongStakeState.into()); + } + }*/ + Ok(()) + } + /// Processes [Deposit](enum.Instruction.html). pub fn process_deposit(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { let account_info_iter = &mut accounts.iter(); @@ -822,7 +881,7 @@ impl Processor { let withdraw_info = next_account_info(account_info_iter)?; // Stake account to join the pool (withdraw should be set to stake pool deposit) let stake_info = next_account_info(account_info_iter)?; - // Valdidator stake account to merge with + // Validator stake account to merge with let validator_stake_account_info = next_account_info(account_info_iter)?; // User account to receive pool tokens let dest_user_info = next_account_info(account_info_iter)?; @@ -835,6 +894,7 @@ impl Processor { let clock = &Clock::from_account_info(clock_info)?; // Stake history sysvar account let stake_history_info = next_account_info(account_info_iter)?; + let stake_history = &StakeHistory::from_account_info(stake_history_info)?; // Pool token program id let token_program_info = next_account_info(account_info_iter)?; // Stake program id @@ -845,7 +905,13 @@ impl Processor { return Err(ProgramError::IncorrectProgramId); } - let mut stake_pool = State::deserialize(&stake_pool_info.data.borrow())?.stake_pool()?; + let mut stake_pool = StakePool::deserialize(&stake_pool_info.data.borrow())?; + if !stake_pool.is_initialized() { + return Err(StakePoolError::InvalidState.into()); + } + + // Check if stake is active + Self::check_stake_activation(stake_info, clock, stake_history)?; // Check authority accounts stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?; @@ -871,7 +937,7 @@ impl Processor { // Read validator stake list account and check if it is valid let mut validator_stake_list = ValidatorStakeList::deserialize(&validator_stake_list_info.data.borrow())?; - if !validator_stake_list.is_initialized { + if !validator_stake_list.is_initialized() { return Err(StakePoolError::InvalidState.into()); } @@ -954,7 +1020,7 @@ impl Processor { )?; stake_pool.pool_total += pool_amount; stake_pool.stake_total += stake_lamports; - State::Init(stake_pool).serialize(&mut stake_pool_info.data.borrow_mut())?; + stake_pool.serialize(&mut stake_pool_info.data.borrow_mut())?; validator_list_item.balance = **validator_stake_account_info.lamports.borrow(); validator_stake_list.serialize(&mut validator_stake_list_info.data.borrow_mut())?; @@ -965,7 +1031,7 @@ impl Processor { /// Processes [Withdraw](enum.Instruction.html). pub fn process_withdraw( program_id: &Pubkey, - stake_amount: u64, + pool_amount: u64, accounts: &[AccountInfo], ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); @@ -998,7 +1064,10 @@ impl Processor { return Err(ProgramError::IncorrectProgramId); } - let mut stake_pool = State::deserialize(&stake_pool_info.data.borrow())?.stake_pool()?; + let mut stake_pool = StakePool::deserialize(&stake_pool_info.data.borrow())?; + if !stake_pool.is_initialized() { + return Err(StakePoolError::InvalidState.into()); + } // Check authority account stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?; @@ -1020,7 +1089,7 @@ impl Processor { // Read validator stake list account and check if it is valid let mut validator_stake_list = ValidatorStakeList::deserialize(&validator_stake_list_info.data.borrow())?; - if !validator_stake_list.is_initialized { + if !validator_stake_list.is_initialized() { return Err(StakePoolError::InvalidState.into()); } @@ -1031,8 +1100,8 @@ impl Processor { .find_mut(&validator_account) .ok_or(StakePoolError::ValidatorNotFound)?; - let pool_amount = stake_pool - .calc_pool_withdraw_amount(stake_amount) + let stake_amount = stake_pool + .calc_lamports_amount(pool_amount) .ok_or(StakePoolError::CalculationFailure)?; Self::stake_split( @@ -1084,7 +1153,7 @@ impl Processor { stake_pool.pool_total -= pool_amount; stake_pool.stake_total -= stake_amount; - State::Init(stake_pool).serialize(&mut stake_pool_info.data.borrow_mut())?; + stake_pool.serialize(&mut stake_pool_info.data.borrow_mut())?; validator_list_item.balance = **stake_split_from.lamports.borrow(); validator_stake_list.serialize(&mut validator_stake_list_info.data.borrow_mut())?; @@ -1112,7 +1181,10 @@ impl Processor { return Err(ProgramError::IncorrectProgramId); } - let stake_pool = State::deserialize(&stake_pool_info.data.borrow())?.stake_pool()?; + let stake_pool = StakePool::deserialize(&stake_pool_info.data.borrow())?; + if !stake_pool.is_initialized() { + return Err(StakePoolError::InvalidState.into()); + } // Check authority account stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?; @@ -1142,7 +1214,10 @@ impl Processor { let new_owner_info = next_account_info(account_info_iter)?; let new_owner_fee_info = next_account_info(account_info_iter)?; - let mut stake_pool = State::deserialize(&stake_pool_info.data.borrow())?.stake_pool()?; + let mut stake_pool = StakePool::deserialize(&stake_pool_info.data.borrow())?; + if !stake_pool.is_initialized() { + return Err(StakePoolError::InvalidState.into()); + } // Check owner validity and signature stake_pool.check_owner(owner_info)?; @@ -1156,7 +1231,7 @@ impl Processor { stake_pool.owner = *new_owner_info.key; stake_pool.owner_fee_account = *new_owner_fee_info.key; - State::Init(stake_pool).serialize(&mut stake_pool_info.data.borrow_mut())?; + stake_pool.serialize(&mut stake_pool_info.data.borrow_mut())?; Ok(()) } /// Processes [Instruction](enum.Instruction.html). @@ -1213,27 +1288,30 @@ impl PrintProgramError for StakePoolError { E: 'static + std::error::Error + DecodeError + PrintProgramError + FromPrimitive, { match self { - StakePoolError::AlreadyInUse => msg!("Error: AlreadyInUse"), - StakePoolError::InvalidProgramAddress => msg!("Error: InvalidProgramAddress"), - StakePoolError::InvalidState => msg!("Error: InvalidState"), - StakePoolError::CalculationFailure => msg!("Error: CalculationFailure"), - StakePoolError::FeeTooHigh => msg!("Error: FeeTooHigh"), - StakePoolError::WrongAccountMint => msg!("Error: WrongAccountMint"), - StakePoolError::NonZeroBalance => msg!("Error: NonZeroBalance"), - StakePoolError::WrongOwner => msg!("Error: WrongOwner"), - StakePoolError::SignatureMissing => msg!("Error: SignatureMissing"), - StakePoolError::InvalidValidatorStakeList => msg!("Error: InvalidValidatorStakeList"), - StakePoolError::InvalidFeeAccount => msg!("Error: InvalidFeeAccount"), - StakePoolError::WrongPoolMint => msg!("Error: WrongPoolMint"), - StakePoolError::WrongStakeState => msg!("Error: WrongStakeState"), - StakePoolError::ValidatorAlreadyAdded => msg!("Error: ValidatorAlreadyAdded"), - StakePoolError::ValidatorNotFound => msg!("Error: ValidatorNotFound"), - StakePoolError::InvalidStakeAccountAddress => msg!("Error: InvalidStakeAccountAddress"), - StakePoolError::StakeListOutOfDate => msg!("Error: StakeListOutOfDate"), - StakePoolError::StakeListAndPoolOutOfDate => msg!("Error: StakeListAndPoolOutOfDate"), + StakePoolError::AlreadyInUse => msg!("Error: The account cannot be initialized because it is already being used"), + StakePoolError::InvalidProgramAddress => msg!("Error: The program address provided doesn't match the value generated by the program"), + StakePoolError::InvalidState => msg!("Error: The stake pool state is invalid"), + StakePoolError::CalculationFailure => msg!("Error: The calculation failed"), + StakePoolError::FeeTooHigh => msg!("Error: Stake pool fee > 1"), + StakePoolError::WrongAccountMint => msg!("Error: Token account is associated with the wrong mint"), + StakePoolError::NonZeroBalance => msg!("Error: Account balance should be zero"), + StakePoolError::WrongOwner => msg!("Error: Wrong pool owner account"), + StakePoolError::SignatureMissing => msg!("Error: Required signature is missing"), + StakePoolError::InvalidValidatorStakeList => msg!("Error: Invalid validator stake list account"), + StakePoolError::InvalidFeeAccount => msg!("Error: Invalid owner fee account"), + StakePoolError::WrongPoolMint => msg!("Error: Specified pool mint account is wrong"), + StakePoolError::WrongStakeState => msg!("Error: Stake account is not in the state expected by the program"), + StakePoolError::UserStakeNotActive => msg!("Error: User stake is not active"), + StakePoolError::ValidatorAlreadyAdded => msg!("Error: Stake account voting for this validator already exists in the pool"), + StakePoolError::ValidatorNotFound => msg!("Error: Stake account for this validator not found in the pool"), + StakePoolError::InvalidStakeAccountAddress => msg!("Error: Stake account address not properly derived from the validator address"), + StakePoolError::StakeListOutOfDate => msg!("Error: Identify validator stake accounts with old balances and update them"), + StakePoolError::StakeListAndPoolOutOfDate => msg!("Error: First update old validator stake account balances and then pool stake balance"), StakePoolError::UnknownValidatorStakeAccount => { - msg!("Error: UnknownValidatorStakeAccount") + msg!("Error: Validator stake account is not found in the list storage") } + StakePoolError::WrongMintingAuthority => msg!("Error: Wrong minting authority set for mint pool account"), + StakePoolError::AccountNotRentExempt => msg!("Error: Account is not rent-exempt"), } } } diff --git a/program/src/stake.rs b/program/src/stake.rs index 0a49cc22..47351ff2 100644 --- a/program/src/stake.rs +++ b/program/src/stake.rs @@ -5,6 +5,7 @@ use solana_program::{ clock::{Epoch, UnixTimestamp}, instruction::{AccountMeta, Instruction}, pubkey::Pubkey, + stake_history::StakeHistory, system_instruction, sysvar, }; use std::str::FromStr; @@ -69,7 +70,7 @@ pub enum StakeInstruction { /// 5. Optional: [SIGNER] Lockup authority, if before lockup expiration /// /// The u64 is the portion of the stake account balance to be withdrawn, - /// must be `<= StakeAccount.lamports - staked_lamports`. + /// must be `<= ValidatorStakeAccount.lamports - staked_lamports`. Withdraw(u64), /// Deactivates the stake in the account @@ -186,6 +187,212 @@ pub struct Lockup { pub custodian: Pubkey, } +/// FIXME copied from the stake program +impl StakeState { + /// Get Delegation + pub fn delegation(&self) -> Option { + match self { + StakeState::Stake(_meta, stake) => Some(stake.delegation), + _ => None, + } + } +} + +/// FIXME copied from the stake program +impl Delegation { + /// Create new Delegation + pub fn new( + voter_pubkey: &Pubkey, + stake: u64, + activation_epoch: Epoch, + warmup_cooldown_rate: f64, + ) -> Self { + Self { + voter_pubkey: *voter_pubkey, + stake, + activation_epoch, + warmup_cooldown_rate, + ..Delegation::default() + } + } + /// Check if it bootstrap + pub fn is_bootstrap(&self) -> bool { + self.activation_epoch == std::u64::MAX + } + + /// Return tuple (effective, activating, deactivating) stake + #[allow(clippy::comparison_chain)] + pub fn stake_activating_and_deactivating( + &self, + target_epoch: Epoch, + history: Option<&StakeHistory>, + fix_stake_deactivate: bool, + ) -> (u64, u64, u64) { + let delegated_stake = self.stake; + + // first, calculate an effective and activating stake + let (effective_stake, activating_stake) = + self.stake_and_activating(target_epoch, history, fix_stake_deactivate); + + // then de-activate some portion if necessary + if target_epoch < self.deactivation_epoch { + // not deactivated + (effective_stake, activating_stake, 0) + } else if target_epoch == self.deactivation_epoch { + // can only deactivate what's activated + (effective_stake, 0, effective_stake.min(delegated_stake)) + } else if let Some((history, mut prev_epoch, mut prev_cluster_stake)) = + history.and_then(|history| { + history + .get(&self.deactivation_epoch) + .map(|cluster_stake_at_deactivation_epoch| { + ( + history, + self.deactivation_epoch, + cluster_stake_at_deactivation_epoch, + ) + }) + }) + { + // target_epoch > self.deactivation_epoch + + // loop from my deactivation epoch until the target epoch + // current effective stake is updated using its previous epoch's cluster stake + let mut current_epoch; + let mut current_effective_stake = effective_stake; + loop { + current_epoch = prev_epoch + 1; + // if there is no deactivating stake at prev epoch, we should have been + // fully undelegated at this moment + if prev_cluster_stake.deactivating == 0 { + break; + } + + // I'm trying to get to zero, how much of the deactivation in stake + // this account is entitled to take + let weight = + current_effective_stake as f64 / prev_cluster_stake.deactivating as f64; + + // portion of newly not-effective cluster stake I'm entitled to at current epoch + let newly_not_effective_cluster_stake = + prev_cluster_stake.effective as f64 * self.warmup_cooldown_rate; + let newly_not_effective_stake = + ((weight * newly_not_effective_cluster_stake) as u64).max(1); + + current_effective_stake = + current_effective_stake.saturating_sub(newly_not_effective_stake); + if current_effective_stake == 0 { + break; + } + + if current_epoch >= target_epoch { + break; + } + if let Some(current_cluster_stake) = history.get(¤t_epoch) { + prev_epoch = current_epoch; + prev_cluster_stake = current_cluster_stake; + } else { + break; + } + } + + // deactivating stake should equal to all of currently remaining effective stake + (current_effective_stake, 0, current_effective_stake) + } else { + // no history or I've dropped out of history, so assume fully deactivated + (0, 0, 0) + } + } + + // returned tuple is (effective, activating) stake + fn stake_and_activating( + &self, + target_epoch: Epoch, + history: Option<&StakeHistory>, + fix_stake_deactivate: bool, + ) -> (u64, u64) { + let delegated_stake = self.stake; + + if self.is_bootstrap() { + // fully effective immediately + (delegated_stake, 0) + } else if fix_stake_deactivate && self.activation_epoch == self.deactivation_epoch { + // activated but instantly deactivated; no stake at all regardless of target_epoch + // this must be after the bootstrap check and before all-is-activating check + (0, 0) + } else if target_epoch == self.activation_epoch { + // all is activating + (0, delegated_stake) + } else if target_epoch < self.activation_epoch { + // not yet enabled + (0, 0) + } else if let Some((history, mut prev_epoch, mut prev_cluster_stake)) = + history.and_then(|history| { + history + .get(&self.activation_epoch) + .map(|cluster_stake_at_activation_epoch| { + ( + history, + self.activation_epoch, + cluster_stake_at_activation_epoch, + ) + }) + }) + { + // target_epoch > self.activation_epoch + + // loop from my activation epoch until the target epoch summing up my entitlement + // current effective stake is updated using its previous epoch's cluster stake + let mut current_epoch; + let mut current_effective_stake = 0; + loop { + current_epoch = prev_epoch + 1; + // if there is no activating stake at prev epoch, we should have been + // fully effective at this moment + if prev_cluster_stake.activating == 0 { + break; + } + + // how much of the growth in stake this account is + // entitled to take + let remaining_activating_stake = delegated_stake - current_effective_stake; + let weight = + remaining_activating_stake as f64 / prev_cluster_stake.activating as f64; + + // portion of newly effective cluster stake I'm entitled to at current epoch + let newly_effective_cluster_stake = + prev_cluster_stake.effective as f64 * self.warmup_cooldown_rate; + let newly_effective_stake = + ((weight * newly_effective_cluster_stake) as u64).max(1); + + current_effective_stake += newly_effective_stake; + if current_effective_stake >= delegated_stake { + current_effective_stake = delegated_stake; + break; + } + + if current_epoch >= target_epoch || current_epoch >= self.deactivation_epoch { + break; + } + if let Some(current_cluster_stake) = history.get(¤t_epoch) { + prev_epoch = current_epoch; + prev_cluster_stake = current_cluster_stake; + } else { + break; + } + } + + ( + current_effective_stake, + delegated_stake - current_effective_stake, + ) + } else { + // no history or I've dropped out of history, so assume fully effective + (delegated_stake, 0) + } + } +} + /// FIXME copied from the stake program pub fn split_only( stake_pubkey: &Pubkey, diff --git a/program/src/state.rs b/program/src/state.rs index 02bad925..3c945223 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -1,7 +1,7 @@ //! State transition types use crate::error::StakePoolError; -use crate::instruction::{unpack, Fee}; +use crate::instruction::Fee; use crate::processor::Processor; use core::convert::TryInto; use solana_program::{ @@ -44,6 +44,8 @@ pub struct StakePool { pub fee: Fee, } impl StakePool { + /// Length of state data when serialized + pub const LEN: usize = size_of::(); /// calculate the pool tokens that should be minted pub fn calc_pool_deposit_amount(&self, stake_lamports: u64) -> Option { if self.stake_total == 0 { @@ -60,6 +62,15 @@ impl StakePool { ) .ok() } + /// calculate lamports amount + pub fn calc_lamports_amount(&self, pool_tokens: u64) -> Option { + u64::try_from( + (pool_tokens as u128) + .checked_mul(self.stake_total as u128)? + .checked_div(self.pool_total as u128)?, + ) + .ok() + } /// calculate the fee in pool tokens that goes to the owner pub fn calc_fee_amount(&self, pool_amount: u64) -> Option { if self.fee.denominator == 0 { @@ -114,67 +125,34 @@ impl StakePool { } Ok(()) } -} -/// Program states. -#[repr(C)] -#[derive(Clone, Copy, Debug, PartialEq)] -#[allow(clippy::large_enum_variant)] -pub enum State { - /// Unallocated state, may be initialized into another state. - Unallocated, - /// Initialized state. - Init(StakePool), -} + /// Check if StakePool is initialized + pub fn is_initialized(&self) -> bool { + self.version > 0 + } -impl State { - /// Length of state data when serialized - pub const LEN: usize = size_of::() + size_of::(); - /// Deserializes a byte buffer into a [State](struct.State.html). - /// TODO efficient unpacking here - pub fn deserialize(input: &[u8]) -> Result { - if input.len() < size_of::() { + /// Deserializes a byte buffer into a [StakePool](struct.StakePool.html). + pub fn deserialize(input: &[u8]) -> Result { + if input.len() < size_of::() { return Err(ProgramError::InvalidAccountData); } - Ok(match input[0] { - 0 => State::Unallocated, - 1 => { - // We send whole input here, because unpack skips the first byte - let swap: &StakePool = unpack(&input)?; - State::Init(*swap) - } - _ => return Err(ProgramError::InvalidAccountData), - }) + + let stake_pool: &StakePool = unsafe { &*(&input[0] as *const u8 as *const StakePool) }; + + Ok(*stake_pool) } - /// Serializes [State](struct.State.html) into a byte buffer. - /// TODO efficient packing here + /// Serializes [StakePool](struct.StakePool.html) into a byte buffer. pub fn serialize(&self, output: &mut [u8]) -> ProgramResult { - if output.len() < size_of::() { + if output.len() < size_of::() { return Err(ProgramError::InvalidAccountData); } - match self { - Self::Unallocated => output[0] = 0, - Self::Init(swap) => { - if output.len() < size_of::() + size_of::() { - return Err(ProgramError::InvalidAccountData); - } - output[0] = 1; - #[allow(clippy::cast_ptr_alignment)] - let value = unsafe { &mut *(&mut output[1] as *mut u8 as *mut StakePool) }; - *value = *swap; - } - } + #[allow(clippy::cast_ptr_alignment)] + let value = unsafe { &mut *(&mut output[0] as *mut u8 as *mut StakePool) }; + *value = *self; + Ok(()) } - /// Gets the `StakePool` from `State` - pub fn stake_pool(&self) -> Result { - if let State::Init(swap) = &self { - Ok(*swap) - } else { - Err(StakePoolError::InvalidState.into()) - } - } } const MAX_VALIDATOR_STAKE_ACCOUNTS: usize = 1000; @@ -183,8 +161,8 @@ const MAX_VALIDATOR_STAKE_ACCOUNTS: usize = 1000; #[repr(C)] #[derive(Clone, Debug, Default, PartialEq)] pub struct ValidatorStakeList { - /// False if not yet initialized - pub is_initialized: bool, + /// Validator stake list version + pub version: u8, /// List of all validator stake accounts and their info pub validators: Vec, } @@ -211,6 +189,9 @@ impl ValidatorStakeList { /// Header length pub const HEADER_LEN: usize = size_of::() + size_of::(); + /// Version of validator stake list + pub const VALIDATOR_STAKE_LIST_VERSION: u8 = 1; + /// Check if contains validator with particular pubkey pub fn contains(&self, validator: &Pubkey) -> bool { self.validators @@ -231,6 +212,11 @@ impl ValidatorStakeList { .find(|x| x.validator_account == *validator) } + /// Check if validator stake list is initialized + pub fn is_initialized(&self) -> bool { + self.version > 0 + } + /// Deserializes a byte buffer into a ValidatorStakeList. pub fn deserialize(input: &[u8]) -> Result { if input.len() < Self::LEN { @@ -239,7 +225,7 @@ impl ValidatorStakeList { if input[0] == 0 { return Ok(ValidatorStakeList { - is_initialized: false, + version: 0, validators: vec![], }); } @@ -262,7 +248,7 @@ impl ValidatorStakeList { to += ValidatorStakeInfo::LEN; } Ok(ValidatorStakeList { - is_initialized: true, + version: input[0], validators, }) } @@ -275,7 +261,7 @@ impl ValidatorStakeList { if self.validators.len() > MAX_VALIDATOR_STAKE_ACCOUNTS { return Err(ProgramError::InvalidAccountData); } - output[0] = if self.is_initialized { 1 } else { 0 }; + output[0] = self.version; output[1..3].copy_from_slice(&u16::to_le_bytes(self.validators.len() as u16)); let mut from = Self::HEADER_LEN; let mut to = from + ValidatorStakeInfo::LEN; @@ -324,7 +310,7 @@ mod test { fn test_state_packing() { // Not initialized let stake_list = ValidatorStakeList { - is_initialized: false, + version: 0, validators: vec![], }; let mut bytes: [u8; ValidatorStakeList::LEN] = [0; ValidatorStakeList::LEN]; @@ -334,7 +320,7 @@ mod test { // Empty let stake_list = ValidatorStakeList { - is_initialized: true, + version: ValidatorStakeList::VALIDATOR_STAKE_LIST_VERSION, validators: vec![], }; let mut bytes: [u8; ValidatorStakeList::LEN] = [0; ValidatorStakeList::LEN]; @@ -344,7 +330,7 @@ mod test { // With several accounts let stake_list = ValidatorStakeList { - is_initialized: true, + version: ValidatorStakeList::VALIDATOR_STAKE_LIST_VERSION, validators: vec![ ValidatorStakeInfo { validator_account: Pubkey::new_from_array([1; 32]), diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 8f92e56c..b1dce30b 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -16,7 +16,13 @@ use solana_sdk::{ use spl_stake_pool::*; use spl_token::error as token_error; -async fn setup() -> (BanksClient, Keypair, Hash, StakePoolAccounts, StakeAccount) { +async fn setup() -> ( + BanksClient, + Keypair, + Hash, + StakePoolAccounts, + ValidatorStakeAccount, +) { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts @@ -24,7 +30,7 @@ async fn setup() -> (BanksClient, Keypair, Hash, StakePoolAccounts, StakeAccount .await .unwrap(); - let validator_stake_account: StakeAccount = simple_add_validator_stake_account( + let validator_stake_account: ValidatorStakeAccount = simple_add_validator_stake_account( &mut banks_client, &payer, &recent_blockhash, @@ -50,10 +56,13 @@ async fn test_stake_pool_deposit() { // make stake account let user_stake = Keypair::new(); let lockup = stake::Lockup::default(); + + let stake_authority = Keypair::new(); let authorized = stake::Authorized { - staker: stake_pool_accounts.deposit_authority, - withdrawer: stake_pool_accounts.deposit_authority, + staker: stake_authority.pubkey(), + withdrawer: stake_authority.pubkey(), }; + let stake_lamports = create_independent_stake_account( &mut banks_client, &payer, @@ -63,6 +72,46 @@ async fn test_stake_pool_deposit() { &lockup, ) .await; + + create_vote( + &mut banks_client, + &payer, + &recent_blockhash, + &validator_stake_account.vote, + ) + .await; + delegate_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.pubkey(), + &stake_authority, + &validator_stake_account.vote.pubkey(), + ) + .await; + + // Change authority to the stake pool's deposit + authorize_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.pubkey(), + &stake_authority, + &stake_pool_accounts.deposit_authority, + stake::StakeAuthorize::Withdrawer, + ) + .await; + authorize_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.pubkey(), + &stake_authority, + &stake_pool_accounts.deposit_authority, + stake::StakeAuthorize::Staker, + ) + .await; + // make pool token account let user_pool_account = Keypair::new(); create_token_account( @@ -79,10 +128,8 @@ async fn test_stake_pool_deposit() { // Save stake pool state before depositing let stake_pool_before = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; - let stake_pool_before = state::State::deserialize(&stake_pool_before.data.as_slice()) - .unwrap() - .stake_pool() - .unwrap(); + let stake_pool_before = + state::StakePool::deserialize(&stake_pool_before.data.as_slice()).unwrap(); // Save validator stake account record before depositing let validator_stake_list = get_account( @@ -120,10 +167,7 @@ async fn test_stake_pool_deposit() { // Stake pool should add its balance to the pool balance let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; - let stake_pool = state::State::deserialize(&stake_pool.data.as_slice()) - .unwrap() - .stake_pool() - .unwrap(); + let stake_pool = state::StakePool::deserialize(&stake_pool.data.as_slice()).unwrap(); assert_eq!( stake_pool.stake_total, stake_pool_before.stake_total + stake_lamports @@ -239,6 +283,20 @@ async fn test_stake_pool_deposit_with_wrong_pool_fee_account() { let user = Keypair::new(); // make stake account let user_stake = Keypair::new(); + let lockup = stake::Lockup::default(); + let authorized = stake::Authorized { + staker: stake_pool_accounts.deposit_authority, + withdrawer: stake_pool_accounts.deposit_authority, + }; + create_independent_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake, + &authorized, + &lockup, + ) + .await; // make pool token account let user_pool_account = Keypair::new(); @@ -289,6 +347,20 @@ async fn test_stake_pool_deposit_with_wrong_token_program_id() { let user = Keypair::new(); // make stake account let user_stake = Keypair::new(); + let lockup = stake::Lockup::default(); + let authorized = stake::Authorized { + staker: stake_pool_accounts.deposit_authority, + withdrawer: stake_pool_accounts.deposit_authority, + }; + create_independent_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake, + &authorized, + &lockup, + ) + .await; // make pool token account let user_pool_account = Keypair::new(); @@ -351,6 +423,20 @@ async fn test_stake_pool_deposit_with_wrong_validator_stake_list_account() { let user = Keypair::new(); // make stake account let user_stake = Keypair::new(); + let lockup = stake::Lockup::default(); + let authorized = stake::Authorized { + staker: stake_pool_accounts.deposit_authority, + withdrawer: stake_pool_accounts.deposit_authority, + }; + create_independent_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake, + &authorized, + &lockup, + ) + .await; // make pool token account let user_pool_account = Keypair::new(); @@ -402,13 +488,13 @@ async fn test_stake_pool_deposit_where_stake_acc_not_in_stake_state() { .await .unwrap(); - let validator_stake_account = StakeAccount::new_with_target_authority( + let validator_stake_account = ValidatorStakeAccount::new_with_target_authority( &stake_pool_accounts.deposit_authority, &stake_pool_accounts.stake_pool.pubkey(), ); let user_stake_authority = Keypair::new(); - create_stake_account( + create_validator_stake_account( &mut banks_client, &payer, &recent_blockhash, @@ -434,6 +520,20 @@ async fn test_stake_pool_deposit_where_stake_acc_not_in_stake_state() { .unwrap(); let user_stake_acc = Keypair::new(); + let lockup = stake::Lockup::default(); + let authorized = stake::Authorized { + staker: stake_pool_accounts.deposit_authority, + withdrawer: stake_pool_accounts.deposit_authority, + }; + create_independent_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake_acc, + &authorized, + &lockup, + ) + .await; let transaction_error = stake_pool_accounts .deposit_stake( &mut banks_client, @@ -470,7 +570,7 @@ async fn test_stake_pool_deposit_to_unknown_validator() { .await .unwrap(); - let validator_stake_account = StakeAccount::new_with_target_authority( + let validator_stake_account = ValidatorStakeAccount::new_with_target_authority( &stake_pool_accounts.deposit_authority, &stake_pool_accounts.stake_pool.pubkey(), ); @@ -548,6 +648,20 @@ async fn test_stake_pool_deposit_with_wrong_deposit_authority() { let user = Keypair::new(); // make stake account let user_stake = Keypair::new(); + let lockup = stake::Lockup::default(); + let authorized = stake::Authorized { + staker: stake_pool_accounts.deposit_authority, + withdrawer: stake_pool_accounts.deposit_authority, + }; + create_independent_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake, + &authorized, + &lockup, + ) + .await; // make pool token account let user_pool_account = Keypair::new(); @@ -602,6 +716,20 @@ async fn test_stake_pool_deposit_with_wrong_withdraw_authority() { let user = Keypair::new(); // make stake account let user_stake = Keypair::new(); + let lockup = stake::Lockup::default(); + let authorized = stake::Authorized { + staker: stake_pool_accounts.deposit_authority, + withdrawer: stake_pool_accounts.deposit_authority, + }; + create_independent_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake, + &authorized, + &lockup, + ) + .await; // make pool token account let user_pool_account = Keypair::new(); diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 18cca7f8..35863756 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -163,11 +163,11 @@ pub async fn create_stake_pool( validator_stake_list: &Keypair, pool_mint: &Pubkey, pool_token_account: &Pubkey, - owner: &Pubkey, + owner: &Keypair, fee: &instruction::Fee, ) -> Result<(), TransportError> { let rent = banks_client.get_rent().await.unwrap(); - let rent_stake_pool = rent.minimum_balance(state::State::LEN); + let rent_stake_pool = rent.minimum_balance(state::StakePool::LEN); let rent_validator_stake_list = rent.minimum_balance(state::ValidatorStakeList::LEN); let init_args = instruction::InitArgs { fee: *fee }; @@ -177,7 +177,7 @@ pub async fn create_stake_pool( &payer.pubkey(), &stake_pool.pubkey(), rent_stake_pool, - state::State::LEN as u64, + state::StakePool::LEN as u64, &id(), ), system_instruction::create_account( @@ -190,7 +190,7 @@ pub async fn create_stake_pool( instruction::initialize( &id(), &stake_pool.pubkey(), - owner, + &owner.pubkey(), &validator_stake_list.pubkey(), pool_mint, pool_token_account, @@ -202,7 +202,7 @@ pub async fn create_stake_pool( Some(&payer.pubkey()), ); transaction.sign( - &[payer, stake_pool, validator_stake_list], + &[payer, stake_pool, validator_stake_list, owner], *recent_blockhash, ); banks_client.process_transaction(transaction).await?; @@ -285,7 +285,7 @@ pub async fn create_blank_stake_account( lamports } -pub async fn create_stake_account( +pub async fn create_validator_stake_account( banks_client: &mut BanksClient, payer: &Keypair, recent_blockhash: &Hash, @@ -355,14 +355,14 @@ pub async fn authorize_stake_account( banks_client.process_transaction(transaction).await.unwrap(); } -pub struct StakeAccount { +pub struct ValidatorStakeAccount { pub stake_account: Pubkey, pub target_authority: Pubkey, pub vote: Keypair, pub stake_pool: Pubkey, } -impl StakeAccount { +impl ValidatorStakeAccount { pub fn new_with_target_authority(authority: &Pubkey, stake_pool: &Pubkey) -> Self { let validator = Keypair::new(); let (stake_account, _) = processor::Processor::find_stake_address_for_validator( @@ -370,7 +370,7 @@ impl StakeAccount { &validator.pubkey(), stake_pool, ); - StakeAccount { + ValidatorStakeAccount { stake_account, target_authority: *authority, vote: validator, @@ -386,7 +386,7 @@ impl StakeAccount { ) { // make stake account let user_stake_authority = Keypair::new(); - create_stake_account( + create_validator_stake_account( &mut banks_client, &payer, &recent_blockhash, @@ -500,7 +500,7 @@ impl StakePoolAccounts { &self.validator_stake_list, &self.pool_mint.pubkey(), &self.pool_fee_account.pubkey(), - &self.owner.pubkey(), + &self.owner, &self.fee, ) .await?; @@ -638,8 +638,8 @@ pub async fn simple_add_validator_stake_account( payer: &Keypair, recent_blockhash: &Hash, stake_pool_accounts: &StakePoolAccounts, -) -> StakeAccount { - let user_stake = StakeAccount::new_with_target_authority( +) -> ValidatorStakeAccount { + let user_stake = ValidatorStakeAccount::new_with_target_authority( &stake_pool_accounts.deposit_authority, &stake_pool_accounts.stake_pool.pubkey(), ); @@ -685,7 +685,7 @@ pub async fn simple_deposit( payer: &Keypair, recent_blockhash: &Hash, stake_pool_accounts: &StakePoolAccounts, - validator_stake_account: &StakeAccount, + validator_stake_account: &ValidatorStakeAccount, ) -> DepositInfo { let user = Keypair::new(); // make stake account diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index c15f2f04..79bcaca3 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -3,13 +3,47 @@ mod helpers; use helpers::*; -use solana_program::system_instruction; +use solana_program::hash::Hash; +use solana_program::{ + instruction::{AccountMeta, Instruction}, + program_pack::Pack, + system_instruction, sysvar, +}; +use solana_program_test::BanksClient; use solana_sdk::{ instruction::InstructionError, signature::Keypair, signature::Signer, transaction::Transaction, transaction::TransactionError, transport::TransportError, }; use spl_stake_pool::*; +async fn create_mint_and_token_account( + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + stake_pool_accounts: &StakePoolAccounts, +) { + create_mint( + banks_client, + payer, + recent_blockhash, + &stake_pool_accounts.pool_mint, + &stake_pool_accounts.withdraw_authority, + ) + .await + .unwrap(); + + create_token_account( + banks_client, + payer, + recent_blockhash, + &stake_pool_accounts.pool_fee_account, + &stake_pool_accounts.pool_mint.pubkey(), + &stake_pool_accounts.owner.pubkey(), + ) + .await + .unwrap(); +} + #[tokio::test] async fn test_stake_pool_initialize() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; @@ -21,7 +55,7 @@ async fn test_stake_pool_initialize() { // Stake pool now exists let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; - assert_eq!(stake_pool.data.len(), state::State::LEN); + assert_eq!(stake_pool.data.len(), state::StakePool::LEN); assert_eq!(stake_pool.owner, id()); // Validator stake list storage initialized @@ -32,7 +66,7 @@ async fn test_stake_pool_initialize() { .await; let validator_stake_list = state::ValidatorStakeList::deserialize(validator_stake_list.data.as_slice()).unwrap(); - assert_eq!(validator_stake_list.is_initialized, true); + assert_eq!(validator_stake_list.is_initialized(), true); } #[tokio::test] @@ -129,23 +163,21 @@ async fn test_initialize_stake_pool_with_wrong_mint_authority() { let stake_pool_accounts = StakePoolAccounts::new(); let wrong_mint = Keypair::new(); - create_mint( + create_mint_and_token_account( &mut banks_client, &payer, &recent_blockhash, - &stake_pool_accounts.pool_mint, - &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts, ) - .await - .unwrap(); + .await; - create_token_account( + // create wrong mint + create_mint( &mut banks_client, &payer, &recent_blockhash, - &stake_pool_accounts.pool_fee_account, - &stake_pool_accounts.pool_mint.pubkey(), - &stake_pool_accounts.owner.pubkey(), + &wrong_mint, + &stake_pool_accounts.withdraw_authority, ) .await .unwrap(); @@ -158,7 +190,7 @@ async fn test_initialize_stake_pool_with_wrong_mint_authority() { &stake_pool_accounts.validator_stake_list, &wrong_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), - &stake_pool_accounts.owner.pubkey(), + &stake_pool_accounts.owner, &stake_pool_accounts.fee, ) .await @@ -182,6 +214,8 @@ async fn test_initialize_stake_pool_with_wrong_token_program_id() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); + let wrong_token_program = Keypair::new(); + create_mint( &mut banks_client, &payer, @@ -192,32 +226,201 @@ async fn test_initialize_stake_pool_with_wrong_token_program_id() { .await .unwrap(); - create_token_account( + let rent = banks_client.get_rent().await.unwrap(); + + let account_rent = rent.minimum_balance(spl_token::state::Account::LEN); + let mut transaction = Transaction::new_with_payer( + &[system_instruction::create_account( + &payer.pubkey(), + &stake_pool_accounts.pool_fee_account.pubkey(), + account_rent, + spl_token::state::Account::LEN as u64, + &wrong_token_program.pubkey(), + )], + Some(&payer.pubkey()), + ); + transaction.sign( + &[&payer, &stake_pool_accounts.pool_fee_account], + recent_blockhash, + ); + banks_client.process_transaction(transaction).await.unwrap(); + + let rent_stake_pool = rent.minimum_balance(state::StakePool::LEN); + let rent_validator_stake_list = rent.minimum_balance(state::ValidatorStakeList::LEN); + let init_args = instruction::InitArgs { + fee: stake_pool_accounts.fee, + }; + + let mut transaction = Transaction::new_with_payer( + &[ + system_instruction::create_account( + &payer.pubkey(), + &stake_pool_accounts.stake_pool.pubkey(), + rent_stake_pool, + state::StakePool::LEN as u64, + &id(), + ), + system_instruction::create_account( + &payer.pubkey(), + &stake_pool_accounts.validator_stake_list.pubkey(), + rent_validator_stake_list, + state::ValidatorStakeList::LEN as u64, + &id(), + ), + instruction::initialize( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.owner.pubkey(), + &stake_pool_accounts.validator_stake_list.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &stake_pool_accounts.pool_fee_account.pubkey(), + &wrong_token_program.pubkey(), + init_args, + ) + .unwrap(), + ], + Some(&payer.pubkey()), + ); + transaction.sign( + &[ + &payer, + &stake_pool_accounts.stake_pool, + &stake_pool_accounts.validator_stake_list, + &stake_pool_accounts.owner, + ], + recent_blockhash, + ); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { + assert_eq!(error, InstructionError::IncorrectProgramId); + } + _ => panic!( + "Wrong error occurs while try to initialize stake pool with wrong token program ID" + ), + } +} + +#[tokio::test] +async fn test_initialize_stake_pool_with_wrong_fee_accounts_owner() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + + create_mint( &mut banks_client, &payer, &recent_blockhash, - &stake_pool_accounts.pool_fee_account, + &stake_pool_accounts.pool_mint, + &stake_pool_accounts.withdraw_authority, + ) + .await + .unwrap(); + let rent = banks_client.get_rent().await.unwrap(); + let account_rent = rent.minimum_balance(spl_token::state::Account::LEN); + + let mut transaction = Transaction::new_with_payer( + &[system_instruction::create_account( + &payer.pubkey(), + &stake_pool_accounts.pool_fee_account.pubkey(), + account_rent, + spl_token::state::Account::LEN as u64, + &Keypair::new().pubkey(), + )], + Some(&payer.pubkey()), + ); + transaction.sign( + &[&payer, &stake_pool_accounts.pool_fee_account], + recent_blockhash, + ); + banks_client.process_transaction(transaction).await.unwrap(); + + let transaction_error = create_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.stake_pool, + &stake_pool_accounts.validator_stake_list, &stake_pool_accounts.pool_mint.pubkey(), - &stake_pool_accounts.owner.pubkey(), + &stake_pool_accounts.pool_fee_account.pubkey(), + &stake_pool_accounts.owner, + &stake_pool_accounts.fee, ) .await + .err() .unwrap(); + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::InvalidFeeAccount as u32; + assert_eq!(error_index, program_error); + } + _ => panic!( + "Wrong error occurs while try to initialize stake pool with wrong fee account's owner" + ), + } +} + +#[tokio::test] +async fn test_initialize_stake_pool_with_wrong_withdraw_authority() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let mut stake_pool_accounts = StakePoolAccounts::new(); + + stake_pool_accounts.withdraw_authority = Keypair::new().pubkey(); + + let transaction_error = stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::WrongMintingAuthority as u32; + assert_eq!(error_index, program_error); + } + _ => panic!( + "Wrong error occurs while try to initialize stake pool with wrong withdraw authority" + ), + } +} + +#[tokio::test] +async fn test_initialize_stake_pool_with_not_rent_exempt_pool() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + + create_mint_and_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + ) + .await; + let rent = banks_client.get_rent().await.unwrap(); - let rent_stake_pool = rent.minimum_balance(state::State::LEN); let rent_validator_stake_list = rent.minimum_balance(state::ValidatorStakeList::LEN); let init_args = instruction::InitArgs { fee: stake_pool_accounts.fee, }; - let wrong_token_program = Keypair::new(); let mut transaction = Transaction::new_with_payer( &[ system_instruction::create_account( &payer.pubkey(), &stake_pool_accounts.stake_pool.pubkey(), - rent_stake_pool, - state::State::LEN as u64, + 1, + state::StakePool::LEN as u64, &id(), ), system_instruction::create_account( @@ -234,7 +437,7 @@ async fn test_initialize_stake_pool_with_wrong_token_program_id() { &stake_pool_accounts.validator_stake_list.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), - &wrong_token_program.pubkey(), + &spl_token::id(), init_args, ) .unwrap(), @@ -246,6 +449,7 @@ async fn test_initialize_stake_pool_with_wrong_token_program_id() { &payer, &stake_pool_accounts.stake_pool, &stake_pool_accounts.validator_stake_list, + &stake_pool_accounts.owner, ], recent_blockhash, ); @@ -256,11 +460,178 @@ async fn test_initialize_stake_pool_with_wrong_token_program_id() { .unwrap(); match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { - assert_eq!(error, InstructionError::IncorrectProgramId); + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::AccountNotRentExempt as u32; + assert_eq!(error_index, program_error); } _ => panic!( - "Wrong error occurs while try to initialize stake pool with wrong token program ID" + "Wrong error occurs while try to initialize stake pool with not rent exempt stake pool account" + ), + } +} + +#[tokio::test] +async fn test_initialize_stake_pool_with_not_rent_exempt_validator_stake_list() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + + create_mint_and_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + ) + .await; + + let rent = banks_client.get_rent().await.unwrap(); + let rent_stake_pool = rent.minimum_balance(state::StakePool::LEN); + let init_args = instruction::InitArgs { + fee: stake_pool_accounts.fee, + }; + + let mut transaction = Transaction::new_with_payer( + &[ + system_instruction::create_account( + &payer.pubkey(), + &stake_pool_accounts.stake_pool.pubkey(), + rent_stake_pool, + state::StakePool::LEN as u64, + &id(), + ), + system_instruction::create_account( + &payer.pubkey(), + &stake_pool_accounts.validator_stake_list.pubkey(), + 1, + state::ValidatorStakeList::LEN as u64, + &id(), + ), + instruction::initialize( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.owner.pubkey(), + &stake_pool_accounts.validator_stake_list.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &stake_pool_accounts.pool_fee_account.pubkey(), + &spl_token::id(), + init_args, + ) + .unwrap(), + ], + Some(&payer.pubkey()), + ); + transaction.sign( + &[ + &payer, + &stake_pool_accounts.stake_pool, + &stake_pool_accounts.validator_stake_list, + &stake_pool_accounts.owner, + ], + recent_blockhash, + ); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::AccountNotRentExempt as u32; + assert_eq!(error_index, program_error); + } + _ => panic!( + "Wrong error occurs while try to initialize stake pool with not rent exempt validator stake list account" + ), + } +} + +#[tokio::test] +async fn test_initialize_stake_pool_without_owner_signature() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + + create_mint_and_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + ) + .await; + + let rent = banks_client.get_rent().await.unwrap(); + let rent_stake_pool = rent.minimum_balance(state::StakePool::LEN); + let init_args = instruction::InitArgs { + fee: stake_pool_accounts.fee, + }; + + let init_data = instruction::StakePoolInstruction::Initialize(init_args); + let data = init_data.serialize().unwrap(); + let accounts = vec![ + AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), true), + AccountMeta::new_readonly(stake_pool_accounts.owner.pubkey(), false), + AccountMeta::new(stake_pool_accounts.validator_stake_list.pubkey(), false), + AccountMeta::new_readonly(stake_pool_accounts.pool_mint.pubkey(), false), + AccountMeta::new_readonly(stake_pool_accounts.pool_fee_account.pubkey(), false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(sysvar::rent::id(), false), + AccountMeta::new_readonly(spl_token::id(), false), + ]; + let stake_pool_init_instruction = Instruction { + program_id: id(), + accounts, + data, + }; + + let mut transaction = Transaction::new_with_payer( + &[ + system_instruction::create_account( + &payer.pubkey(), + &stake_pool_accounts.stake_pool.pubkey(), + rent_stake_pool, + state::StakePool::LEN as u64, + &id(), + ), + system_instruction::create_account( + &payer.pubkey(), + &stake_pool_accounts.validator_stake_list.pubkey(), + state::ValidatorStakeList::LEN as u64, + state::ValidatorStakeList::LEN as u64, + &id(), + ), + stake_pool_init_instruction, + ], + Some(&payer.pubkey()), + ); + transaction.sign( + &[ + &payer, + &stake_pool_accounts.stake_pool, + &stake_pool_accounts.validator_stake_list, + ], + recent_blockhash, + ); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::SignatureMissing as u32; + assert_eq!(error_index, program_error); + } + _ => panic!( + "Wrong error occurs while try to initialize stake pool without owner's signature" ), } } diff --git a/program/tests/set_owner.rs b/program/tests/set_owner.rs index 8c2321b8..f0897e23 100644 --- a/program/tests/set_owner.rs +++ b/program/tests/set_owner.rs @@ -71,10 +71,7 @@ async fn test_set_owner() { banks_client.process_transaction(transaction).await.unwrap(); let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; - let stake_pool = state::State::deserialize(&stake_pool.data.as_slice()) - .unwrap() - .stake_pool() - .unwrap(); + let stake_pool = state::StakePool::deserialize(&stake_pool.data.as_slice()).unwrap(); assert_eq!(stake_pool.owner, new_owner.pubkey()); } diff --git a/program/tests/set_staking_authority.rs b/program/tests/set_staking_authority.rs index 4972e506..ab45a88e 100644 --- a/program/tests/set_staking_authority.rs +++ b/program/tests/set_staking_authority.rs @@ -15,7 +15,13 @@ use solana_sdk::{ }; use spl_stake_pool::*; -async fn setup() -> (BanksClient, Keypair, Hash, StakePoolAccounts, StakeAccount) { +async fn setup() -> ( + BanksClient, + Keypair, + Hash, + StakePoolAccounts, + ValidatorStakeAccount, +) { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts @@ -25,7 +31,7 @@ async fn setup() -> (BanksClient, Keypair, Hash, StakePoolAccounts, StakeAccount let user = Keypair::new(); - let user_stake = StakeAccount::new_with_target_authority( + let user_stake = ValidatorStakeAccount::new_with_target_authority( &stake_pool_accounts.deposit_authority, &stake_pool_accounts.stake_pool.pubkey(), ); diff --git a/program/tests/update_list_balance.rs b/program/tests/update_list_balance.rs index f834ed64..a9a22f31 100644 --- a/program/tests/update_list_balance.rs +++ b/program/tests/update_list_balance.rs @@ -35,7 +35,7 @@ async fn test_update_list_balance() { .unwrap(); // Add several accounts - let mut stake_accounts: Vec = vec![]; + let mut stake_accounts: Vec = vec![]; const STAKE_ACCOUNTS: u64 = 3; for _ in 0..STAKE_ACCOUNTS { stake_accounts.push( diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index da933cb1..bd86a6ca 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -24,7 +24,7 @@ async fn setup() -> ( Keypair, Hash, StakePoolAccounts, - StakeAccount, + ValidatorStakeAccount, Keypair, ) { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; @@ -36,7 +36,7 @@ async fn setup() -> ( let user = Keypair::new(); - let user_stake = StakeAccount::new_with_target_authority( + let user_stake = ValidatorStakeAccount::new_with_target_authority( &stake_pool_accounts.deposit_authority, &stake_pool_accounts.stake_pool.pubkey(), ); @@ -117,7 +117,7 @@ async fn test_add_validator_stake_account() { assert_eq!( validator_stake_list, state::ValidatorStakeList { - is_initialized: true, + version: state::ValidatorStakeList::VALIDATOR_STAKE_LIST_VERSION, validators: vec![state::ValidatorStakeInfo { validator_account: user_stake.vote.pubkey(), last_update_epoch: 0, @@ -401,6 +401,7 @@ async fn test_not_owner_try_to_add_validator_stake_account_without_signature() { AccountMeta::new(user_pool_account.pubkey(), false), AccountMeta::new(stake_pool_accounts.pool_mint.pubkey(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(sysvar::stake_history::id(), false), AccountMeta::new_readonly(spl_token::id(), false), AccountMeta::new_readonly(stake::id(), false), ]; @@ -443,12 +444,12 @@ async fn test_add_validator_stake_account_when_stake_acc_not_in_stake_state() { let user = Keypair::new(); - let user_stake = StakeAccount::new_with_target_authority( + let user_stake = ValidatorStakeAccount::new_with_target_authority( &stake_pool_accounts.deposit_authority, &stake_pool_accounts.stake_pool.pubkey(), ); let user_stake_authority = Keypair::new(); - create_stake_account( + create_validator_stake_account( &mut banks_client, &payer, &recent_blockhash, diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 99aaeee1..61aa3843 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -24,7 +24,7 @@ async fn setup() -> ( Keypair, Hash, StakePoolAccounts, - StakeAccount, + ValidatorStakeAccount, Keypair, Keypair, ) { @@ -37,7 +37,7 @@ async fn setup() -> ( let user = Keypair::new(); - let user_stake = StakeAccount::new_with_target_authority( + let user_stake = ValidatorStakeAccount::new_with_target_authority( &stake_pool_accounts.deposit_authority, &stake_pool_accounts.stake_pool.pubkey(), ); @@ -132,7 +132,7 @@ async fn test_remove_validator_stake_account() { assert_eq!( validator_stake_list, state::ValidatorStakeList { - is_initialized: true, + version: state::ValidatorStakeList::VALIDATOR_STAKE_LIST_VERSION, validators: vec![] } ); @@ -530,12 +530,12 @@ async fn test_remove_validator_stake_account_when_stake_acc_not_in_stake_state() let user = Keypair::new(); - let user_stake = StakeAccount::new_with_target_authority( + let user_stake = ValidatorStakeAccount::new_with_target_authority( &stake_pool_accounts.deposit_authority, &stake_pool_accounts.stake_pool.pubkey(), ); let user_stake_authority = Keypair::new(); - create_stake_account( + create_validator_stake_account( &mut banks_client, &payer, &recent_blockhash, diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index ed805da1..17cc7274 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -22,10 +22,9 @@ async fn setup() -> ( Keypair, Hash, StakePoolAccounts, - StakeAccount, + ValidatorStakeAccount, DepositInfo, u64, - u64, ) { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); @@ -34,7 +33,7 @@ async fn setup() -> ( .await .unwrap(); - let validator_stake_account: StakeAccount = simple_add_validator_stake_account( + let validator_stake_account: ValidatorStakeAccount = simple_add_validator_stake_account( &mut banks_client, &payer, &recent_blockhash, @@ -52,7 +51,6 @@ async fn setup() -> ( .await; let tokens_to_burn = deposit_info.pool_tokens / 4; - let lamports_to_withdraw = tokens_to_burn; // For now math is 1:1 // Delegate tokens for burning delegate_tokens( @@ -74,7 +72,6 @@ async fn setup() -> ( validator_stake_account, deposit_info, tokens_to_burn, - lamports_to_withdraw, ) } @@ -88,7 +85,6 @@ async fn test_stake_pool_withdraw() { validator_stake_account, deposit_info, tokens_to_burn, - lamports_to_withdraw, ) = setup().await; // Create stake account to withdraw to @@ -104,10 +100,8 @@ async fn test_stake_pool_withdraw() { // Save stake pool state before withdrawal let stake_pool_before = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; - let stake_pool_before = state::State::deserialize(&stake_pool_before.data.as_slice()) - .unwrap() - .stake_pool() - .unwrap(); + let stake_pool_before = + state::StakePool::deserialize(&stake_pool_before.data.as_slice()).unwrap(); // Save validator stake account record before withdrawal let validator_stake_list = get_account( @@ -135,20 +129,17 @@ async fn test_stake_pool_withdraw() { &deposit_info.user_pool_account, &validator_stake_account.stake_account, &new_authority, - lamports_to_withdraw, + tokens_to_burn, ) .await .unwrap(); // Check pool stats let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; - let stake_pool = state::State::deserialize(&stake_pool.data.as_slice()) - .unwrap() - .stake_pool() - .unwrap(); + let stake_pool = state::StakePool::deserialize(&stake_pool.data.as_slice()).unwrap(); assert_eq!( stake_pool.stake_total, - stake_pool_before.stake_total - lamports_to_withdraw + stake_pool_before.stake_total - tokens_to_burn ); assert_eq!( stake_pool.pool_total, @@ -168,7 +159,7 @@ async fn test_stake_pool_withdraw() { .unwrap(); assert_eq!( validator_stake_item.balance, - validator_stake_item_before.balance - lamports_to_withdraw + validator_stake_item_before.balance - tokens_to_burn ); // Check tokens burned @@ -192,7 +183,7 @@ async fn test_stake_pool_withdraw() { get_account(&mut banks_client, &user_stake_recipient.pubkey()).await; assert_eq!( user_stake_recipient_account.lamports, - initial_stake_lamports + lamports_to_withdraw + initial_stake_lamports + tokens_to_burn ); } @@ -205,8 +196,7 @@ async fn test_stake_pool_withdraw_with_wrong_stake_program() { stake_pool_accounts, validator_stake_account, deposit_info, - _, - lamports_to_withdraw, + tokens_to_burn, ) = setup().await; // Create stake account to withdraw to @@ -228,7 +218,7 @@ async fn test_stake_pool_withdraw_with_wrong_stake_program() { &stake_pool_accounts.pool_mint.pubkey(), &spl_token::id(), &wrong_stake_program.pubkey(), - lamports_to_withdraw, + tokens_to_burn, ) .unwrap()], Some(&payer.pubkey()), @@ -257,8 +247,7 @@ async fn test_stake_pool_withdraw_with_wrong_withdraw_authority() { mut stake_pool_accounts, validator_stake_account, deposit_info, - _, - lamports_to_withdraw, + tokens_to_burn, ) = setup().await; // Create stake account to withdraw to @@ -276,7 +265,7 @@ async fn test_stake_pool_withdraw_with_wrong_withdraw_authority() { &deposit_info.user_pool_account, &validator_stake_account.stake_account, &new_authority, - lamports_to_withdraw, + tokens_to_burn, ) .await .err() @@ -303,8 +292,7 @@ async fn test_stake_pool_withdraw_with_wrong_token_program_id() { stake_pool_accounts, validator_stake_account, deposit_info, - _, - lamports_to_withdraw, + tokens_to_burn, ) = setup().await; // Create stake account to withdraw to @@ -326,7 +314,7 @@ async fn test_stake_pool_withdraw_with_wrong_token_program_id() { &stake_pool_accounts.pool_mint.pubkey(), &wrong_token_program.pubkey(), &stake::id(), - lamports_to_withdraw, + tokens_to_burn, ) .unwrap()], Some(&payer.pubkey()), @@ -355,8 +343,7 @@ async fn test_stake_pool_withdraw_with_wrong_validator_stake_list() { mut stake_pool_accounts, validator_stake_account, deposit_info, - _, - lamports_to_withdraw, + tokens_to_burn, ) = setup().await; // Create stake account to withdraw to @@ -374,7 +361,7 @@ async fn test_stake_pool_withdraw_with_wrong_validator_stake_list() { &deposit_info.user_pool_account, &validator_stake_account.stake_account, &new_authority, - lamports_to_withdraw, + tokens_to_burn, ) .await .err() @@ -403,13 +390,13 @@ async fn test_stake_pool_withdraw_when_stake_acc_not_in_stake_state() { .await .unwrap(); - let validator_stake_account = StakeAccount::new_with_target_authority( + let validator_stake_account = ValidatorStakeAccount::new_with_target_authority( &stake_pool_accounts.deposit_authority, &stake_pool_accounts.stake_pool.pubkey(), ); let user_stake_authority = Keypair::new(); - create_stake_account( + create_validator_stake_account( &mut banks_client, &payer, &recent_blockhash, @@ -455,7 +442,6 @@ async fn test_stake_pool_withdraw_when_stake_acc_not_in_stake_state() { let pool_tokens = get_token_balance(&mut banks_client, &user_pool_account).await; let tokens_to_burn = pool_tokens / 4; - let lamports_to_withdraw = tokens_to_burn; // For now math is 1:1 // Delegate tokens for burning delegate_tokens( @@ -483,7 +469,7 @@ async fn test_stake_pool_withdraw_when_stake_acc_not_in_stake_state() { &user_pool_account, &validator_stake_account.stake_account, &new_authority, - lamports_to_withdraw, + tokens_to_burn, ) .await .err() @@ -510,7 +496,7 @@ async fn test_stake_pool_withdraw_from_unknown_validator() { .await .unwrap(); - let validator_stake_account = StakeAccount::new_with_target_authority( + let validator_stake_account = ValidatorStakeAccount::new_with_target_authority( &stake_pool_accounts.deposit_authority, &stake_pool_accounts.stake_pool.pubkey(), ); @@ -518,7 +504,7 @@ async fn test_stake_pool_withdraw_from_unknown_validator() { .create_and_delegate(&mut banks_client, &payer, &recent_blockhash) .await; - let user_stake = StakeAccount::new_with_target_authority( + let user_stake = ValidatorStakeAccount::new_with_target_authority( &stake_pool_accounts.deposit_authority, &stake_pool_accounts.stake_pool.pubkey(), ); @@ -573,7 +559,6 @@ async fn test_stake_pool_withdraw_from_unknown_validator() { let pool_tokens = get_token_balance(&mut banks_client, &user_pool_account).await; let tokens_to_burn = pool_tokens / 4; - let lamports_to_withdraw = tokens_to_burn; // For now math is 1:1 // Delegate tokens for burning delegate_tokens( @@ -601,7 +586,7 @@ async fn test_stake_pool_withdraw_from_unknown_validator() { &user_pool_account, &validator_stake_account.stake_account, &new_authority, - lamports_to_withdraw, + tokens_to_burn, ) .await .err() @@ -628,8 +613,7 @@ async fn test_stake_pool_double_withdraw_to_the_same_account() { stake_pool_accounts, validator_stake_account, deposit_info, - _, - lamports_to_withdraw, + tokens_to_burn, ) = setup().await; // Create stake account to withdraw to @@ -652,7 +636,7 @@ async fn test_stake_pool_double_withdraw_to_the_same_account() { &deposit_info.user_pool_account, &validator_stake_account.stake_account, &new_authority, - lamports_to_withdraw, + tokens_to_burn, ) .await .unwrap(); @@ -668,7 +652,7 @@ async fn test_stake_pool_double_withdraw_to_the_same_account() { &deposit_info.user_pool_account, &validator_stake_account.stake_account, &new_authority, - lamports_to_withdraw, + tokens_to_burn, ) .await .err() @@ -691,7 +675,7 @@ async fn test_stake_pool_withdraw_token_delegate_was_not_setup() { .await .unwrap(); - let validator_stake_account: StakeAccount = simple_add_validator_stake_account( + let validator_stake_account: ValidatorStakeAccount = simple_add_validator_stake_account( &mut banks_client, &payer, &recent_blockhash, @@ -709,7 +693,6 @@ async fn test_stake_pool_withdraw_token_delegate_was_not_setup() { .await; let tokens_to_burn = deposit_info.pool_tokens / 4; - let lamports_to_withdraw = tokens_to_burn; // For now math is 1:1 // Create stake account to withdraw to let user_stake_recipient = Keypair::new(); @@ -731,7 +714,7 @@ async fn test_stake_pool_withdraw_token_delegate_was_not_setup() { &deposit_info.user_pool_account, &validator_stake_account.stake_account, &new_authority, - lamports_to_withdraw, + tokens_to_burn, ) .await .err() @@ -760,7 +743,7 @@ async fn test_stake_pool_withdraw_with_low_delegation() { .await .unwrap(); - let validator_stake_account: StakeAccount = simple_add_validator_stake_account( + let validator_stake_account: ValidatorStakeAccount = simple_add_validator_stake_account( &mut banks_client, &payer, &recent_blockhash, @@ -778,7 +761,6 @@ async fn test_stake_pool_withdraw_with_low_delegation() { .await; let tokens_to_burn = deposit_info.pool_tokens / 4; - let lamports_to_withdraw = tokens_to_burn; // For now math is 1:1 // Delegate tokens for burning delegate_tokens( @@ -812,7 +794,7 @@ async fn test_stake_pool_withdraw_with_low_delegation() { &deposit_info.user_pool_account, &validator_stake_account.stake_account, &new_authority, - lamports_to_withdraw, + tokens_to_burn, ) .await .err() From 815b081860a835965d61b3fa8dd9baff38a83305 Mon Sep 17 00:00:00 2001 From: Trent Nelson Date: Thu, 11 Feb 2021 14:18:38 -0700 Subject: [PATCH 0041/1076] chore: bump solana crates to 1.5.6 --- clients/cli/Cargo.toml | 14 +++++++------- clients/cli/src/main.rs | 2 +- program/Cargo.toml | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 3b97bae2..1389f5eb 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,13 +11,13 @@ version = "2.0.1" [dependencies] clap = "2.33.3" serde_json = "1.0.61" -solana-account-decoder = "1.5.3" -solana-clap-utils = "1.5.3" -solana-cli-config = "1.5.3" -solana-client = "1.5.3" -solana-logger = "1.5.3" -solana-sdk = "1.5.0" -solana-program = "1.5.1" +solana-account-decoder = "1.5.6" +solana-clap-utils = "1.5.6" +solana-cli-config = "1.5.6" +solana-client = "1.5.6" +solana-logger = "1.5.6" +solana-sdk = "1.5.6" +solana-program = "1.5.6" spl-stake-pool = { path="../program", features = [ "no-entrypoint" ] } spl-token = { path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 02bf8bb3..7ca9d277 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -1360,7 +1360,7 @@ fn main() { verbose, owner, fee_payer, - commitment_config: CommitmentConfig::single(), + commitment_config: CommitmentConfig::confirmed(), } }; diff --git a/program/Cargo.toml b/program/Cargo.toml index ecaab20d..cd9695b2 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,14 +18,14 @@ num-traits = "0.2" num_enum = "0.5.1" serde = "1.0.118" serde_derive = "1.0.103" -solana-program = "1.5.1" +solana-program = "1.5.6" spl-token = { path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" bincode = "1.3.1" [dev-dependencies] -solana-program-test = "1.5.3" -solana-sdk = "1.5.0" +solana-program-test = "1.5.6" +solana-sdk = "1.5.6" solana-vote-program = "1.5.3" tokio = { version = "0.3", features = ["macros"]} From 415b0f36371033a9d9fc8982c06a391887561267 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Feb 2021 22:17:04 +0000 Subject: [PATCH 0042/1076] build(deps): bump serde from 1.0.120 to 1.0.121 (#1258) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.120 to 1.0.121. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.120...v1.0.121) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index cd9695b2..3e66d5bf 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -16,7 +16,7 @@ arrayref = "0.3.6" num-derive = "0.3" num-traits = "0.2" num_enum = "0.5.1" -serde = "1.0.118" +serde = "1.0.121" serde_derive = "1.0.103" solana-program = "1.5.6" spl-token = { path = "../../token/program", features = [ "no-entrypoint" ] } From 5e80172b56ab23e4d0730c555ddecf9464af4dce Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Feb 2021 23:23:27 +0000 Subject: [PATCH 0043/1076] build(deps): bump solana-cli-config from 1.5.6 to 1.5.8 (#1260) Bumps [solana-cli-config](https://github.com/solana-labs/solana) from 1.5.6 to 1.5.8. - [Release notes](https://github.com/solana-labs/solana/releases) - [Changelog](https://github.com/solana-labs/solana/blob/master/RELEASE.md) - [Commits](https://github.com/solana-labs/solana/compare/v1.5.6...v1.5.8) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 1389f5eb..9a97e25d 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ clap = "2.33.3" serde_json = "1.0.61" solana-account-decoder = "1.5.6" solana-clap-utils = "1.5.6" -solana-cli-config = "1.5.6" +solana-cli-config = "1.5.8" solana-client = "1.5.6" solana-logger = "1.5.6" solana-sdk = "1.5.6" From 7c2aecb0dce978a23f2ae255aaa9afe9cf4a1c5a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Feb 2021 23:56:18 +0000 Subject: [PATCH 0044/1076] build(deps): bump solana-program from 1.5.6 to 1.5.8 (#1261) Bumps [solana-program](https://github.com/solana-labs/solana) from 1.5.6 to 1.5.8. - [Release notes](https://github.com/solana-labs/solana/releases) - [Changelog](https://github.com/solana-labs/solana/blob/master/RELEASE.md) - [Commits](https://github.com/solana-labs/solana/compare/v1.5.6...v1.5.8) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 9a97e25d..075c80b0 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -17,7 +17,7 @@ solana-cli-config = "1.5.8" solana-client = "1.5.6" solana-logger = "1.5.6" solana-sdk = "1.5.6" -solana-program = "1.5.6" +solana-program = "1.5.8" spl-stake-pool = { path="../program", features = [ "no-entrypoint" ] } spl-token = { path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" diff --git a/program/Cargo.toml b/program/Cargo.toml index 3e66d5bf..6783a5e4 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,7 +18,7 @@ num-traits = "0.2" num_enum = "0.5.1" serde = "1.0.121" serde_derive = "1.0.103" -solana-program = "1.5.6" +solana-program = "1.5.8" spl-token = { path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" bincode = "1.3.1" From e707cd60dfcc2c3a2b06121d8234b8b63cf6e60e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Feb 2021 02:07:29 +0000 Subject: [PATCH 0045/1076] build(deps): bump serde_json from 1.0.61 to 1.0.62 (#1265) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.61 to 1.0.62. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.61...v1.0.62) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 075c80b0..976ef846 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -10,7 +10,7 @@ version = "2.0.1" [dependencies] clap = "2.33.3" -serde_json = "1.0.61" +serde_json = "1.0.62" solana-account-decoder = "1.5.6" solana-clap-utils = "1.5.6" solana-cli-config = "1.5.8" From 52c300c7e3e1c3f4d4a22d7869e9acd2e0a2b626 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Mon, 22 Feb 2021 23:50:05 +0100 Subject: [PATCH 0046/1076] stake-pool: Validator stake account initialized with 1 SOL (#1305) * stake-pool: Validator stake account initialized with 1 SOL A validator stake account only has 1 lamport, which means that it will gain very few rewards per epoch. Its credits_observed is not be reset each epoch, which makes it practically impossible to merge into. Get around this by instantiating them with more stake. * Cargo fmt + fix tests --- program/src/processor.rs | 6 ++++-- program/tests/update_list_balance.rs | 17 ++++++++++------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/program/src/processor.rs b/program/src/processor.rs index 73bf4b82..448cc40e 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -16,6 +16,7 @@ use solana_program::{ decode_error::DecodeError, entrypoint::ProgramResult, msg, + native_token::sol_to_lamports, program::{invoke, invoke_signed}, program_error::PrintProgramError, program_error::ProgramError, @@ -442,8 +443,9 @@ impl Processor { &[bump_seed], ]; - // Fund the associated token account with the minimum balance to be rent exempt - let required_lamports = 1 + rent.minimum_balance(std::mem::size_of::()); + // Fund the stake account with 1 SOL + rent-exempt balance + let required_lamports = + sol_to_lamports(1.0) + rent.minimum_balance(std::mem::size_of::()); // Create new stake account invoke_signed( diff --git a/program/tests/update_list_balance.rs b/program/tests/update_list_balance.rs index a9a22f31..259fd497 100644 --- a/program/tests/update_list_balance.rs +++ b/program/tests/update_list_balance.rs @@ -2,12 +2,14 @@ mod helpers; -use crate::helpers::TEST_STAKE_AMOUNT; -use helpers::*; -use solana_program::pubkey::Pubkey; -use solana_program_test::BanksClient; -use solana_sdk::signature::Signer; -use spl_stake_pool::*; +use { + crate::helpers::TEST_STAKE_AMOUNT, + helpers::*, + solana_program::{native_token, pubkey::Pubkey}, + solana_program_test::BanksClient, + solana_sdk::signature::Signer, + spl_stake_pool::*, +}; async fn get_list_sum(banks_client: &mut BanksClient, validator_stake_list_key: &Pubkey) -> u64 { let validator_stake_list = banks_client @@ -64,7 +66,8 @@ async fn test_update_list_balance() { } let rent = banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()) + 1; + let stake_rent = rent.minimum_balance(std::mem::size_of::()) + + native_token::sol_to_lamports(1.0); // Check current balance in the list assert_eq!( From c96fe1338a2d6dd9d485b42105054346d8c9fce8 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Mon, 22 Feb 2021 23:50:17 +0100 Subject: [PATCH 0047/1076] stake-pool-cli: Fix update command for empty list (#1306) --- clients/cli/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 7ca9d277..e537508e 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -676,7 +676,7 @@ fn command_update(config: &Config, pool: &Pubkey) -> CommandResult { )?); } - if instructions.is_empty() { + if instructions.is_empty() && pool_data.last_update_epoch == epoch_info.epoch { println!("Stake pool balances are up to date, no update required."); Ok(None) } else { From a4c171e541c0e0dc44f544b30052f117b48415a8 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 23 Feb 2021 00:28:06 +0100 Subject: [PATCH 0048/1076] stake-pool-cli: Update RPC client per TODO (#1304) * Update deployed stake pool program id * Add validator account takes 1 SOL instead of 1 lamport * Fix "update" command for empty validator list * Update dependencies * Revert consequential changes * Run cargo fmt * Revert sdk * Revert Cargo.lock --- clients/cli/src/main.rs | 17 +++++------------ program/Cargo.toml | 2 +- program/program-id.md | 2 +- program/src/error.rs | 18 +++++++++++++++--- program/src/instruction.rs | 17 ++++++++++------- program/src/lib.rs | 2 +- program/src/processor.rs | 1 - program/src/state.rs | 17 ++++++++--------- 8 files changed, 41 insertions(+), 35 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index e537508e..3c4a3de7 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -53,7 +53,6 @@ struct Config { verbose: bool, owner: Box, fee_payer: Box, - commitment_config: CommitmentConfig, } type Error = Box; @@ -530,6 +529,7 @@ fn command_deposit( // Calculate validator stake account address linked to the pool let (validator_stake_account, _) = PoolProcessor::find_stake_address_for_validator(&spl_stake_pool::id(), &validator, pool); + println!("Depositing into stake account {}", validator_stake_account); let mut instructions: Vec = vec![]; let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()]; @@ -615,7 +615,7 @@ fn command_deposit( fn command_list(config: &Config, pool: &Pubkey) -> CommandResult { // Get stake pool state let pool_data = config.rpc_client.get_account_data(&pool)?; - let pool_data: StakePool = StakePool::deserialize(pool_data.as_slice()).unwrap(); + let pool_data = StakePool::deserialize(pool_data.as_slice()).unwrap(); let pool_withdraw_authority: Pubkey = PoolProcessor::authority_id( &spl_stake_pool::id(), @@ -645,7 +645,7 @@ fn command_list(config: &Config, pool: &Pubkey) -> CommandResult { fn command_update(config: &Config, pool: &Pubkey) -> CommandResult { // Get stake pool state let pool_data = config.rpc_client.get_account_data(&pool)?; - let pool_data: StakePool = StakePool::deserialize(pool_data.as_slice()).unwrap(); + let pool_data = StakePool::deserialize(pool_data.as_slice()).unwrap(); let validator_stake_list_data = config .rpc_client .get_account_data(&pool_data.validator_stake_list)?; @@ -1356,11 +1356,10 @@ fn main() { let verbose = matches.is_present("verbose"); Config { - rpc_client: RpcClient::new(json_rpc_url), + rpc_client: RpcClient::new_with_commitment(json_rpc_url, CommitmentConfig::confirmed()), verbose, owner, fee_payer, - commitment_config: CommitmentConfig::confirmed(), } }; @@ -1440,15 +1439,9 @@ fn main() { } .and_then(|transaction| { if let Some(transaction) = transaction { - // TODO: Upgrade to solana-client 1.3 and - // `send_and_confirm_transaction_with_spinner_and_commitment()` with single - // confirmation by default for better UX let signature = config .rpc_client - .send_and_confirm_transaction_with_spinner_and_commitment( - &transaction, - config.commitment_config, - )?; + .send_and_confirm_transaction_with_spinner(&transaction)?; println!("Signature: {}", signature); } Ok(()) diff --git a/program/Cargo.toml b/program/Cargo.toml index 6783a5e4..a2043751 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -26,7 +26,7 @@ bincode = "1.3.1" [dev-dependencies] solana-program-test = "1.5.6" solana-sdk = "1.5.6" -solana-vote-program = "1.5.3" +solana-vote-program = "1.5.6" tokio = { version = "0.3", features = ["macros"]} [lib] diff --git a/program/program-id.md b/program/program-id.md index eae20664..26d3f434 100644 --- a/program/program-id.md +++ b/program/program-id.md @@ -1 +1 @@ -STAKEPQQL1111111111111111111111111111111111 +poo1B9L9nR3CrcaziKVYVpRX6A9Y1LAXYasjjfCbApj diff --git a/program/src/error.rs b/program/src/error.rs index d2a34451..7acc56a6 100644 --- a/program/src/error.rs +++ b/program/src/error.rs @@ -7,6 +7,7 @@ use thiserror::Error; /// Errors that may be returned by the StakePool program. #[derive(Clone, Debug, Eq, Error, FromPrimitive, PartialEq)] pub enum StakePoolError { + // 0. /// The account cannot be initialized because it is already being used. #[error("AlreadyInUse")] AlreadyInUse, @@ -22,12 +23,11 @@ pub enum StakePoolError { /// Stake pool fee > 1. #[error("FeeTooHigh")] FeeTooHigh, + + // 5. /// Token account is associated with the wrong mint. #[error("WrongAccountMint")] WrongAccountMint, - /// Account balance should be zero. - #[error("NonZeroBalance")] - NonZeroBalance, /// Wrong pool owner account. #[error("WrongOwner")] WrongOwner, @@ -37,9 +37,13 @@ pub enum StakePoolError { /// Invalid validator stake list account. #[error("InvalidValidatorStakeList")] InvalidValidatorStakeList, + + // 10. /// Invalid owner fee account. #[error("InvalidFeeAccount")] InvalidFeeAccount, + + // 10. /// Specified pool mint account is wrong. #[error("WrongPoolMint")] WrongPoolMint, @@ -52,9 +56,13 @@ pub enum StakePoolError { /// Stake account voting for this validator already exists in the pool. #[error("ValidatorAlreadyAdded")] ValidatorAlreadyAdded, + + // 15. /// Stake account for this validator not found in the pool. #[error("ValidatorNotFound")] ValidatorNotFound, + + // 15. /// Stake account address not properly derived from the validator address. #[error("InvalidStakeAccountAddress")] InvalidStakeAccountAddress, @@ -67,9 +75,13 @@ pub enum StakePoolError { /// Validator stake account is not found in the list storage. #[error("UnknownValidatorStakeAccount")] UnknownValidatorStakeAccount, + + // 20. /// Wrong minting authority set for mint pool account #[error("WrongMintingAuthority")] WrongMintingAuthority, + + // 20. /// Account is not rent-exempt #[error("AccountNotRentExempt")] AccountNotRentExempt, diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 00c85ccf..049c8abd 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -2,12 +2,15 @@ #![allow(clippy::too_many_arguments)] -use solana_program::instruction::AccountMeta; -use solana_program::instruction::Instruction; -use solana_program::program_error::ProgramError; -use solana_program::pubkey::Pubkey; -use solana_program::sysvar; -use std::mem::size_of; +use { + solana_program::{ + instruction::{AccountMeta, Instruction}, + program_error::ProgramError, + pubkey::Pubkey, + sysvar, + }, + std::mem::size_of, +}; /// Fee rate as a ratio /// Fee is minted on deposit @@ -89,7 +92,7 @@ pub enum StakePoolInstruction { RemoveValidatorStakeAccount, /// Updates balances of validator stake accounts in the pool - /// + /// /// 0. `[w]` Validator stake list storage account /// 1. `[]` Sysvar clock account /// 2. ..2+N ` [] N validator stake accounts to update balances diff --git a/program/src/lib.rs b/program/src/lib.rs index 6f48ebb5..61a2a883 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -17,4 +17,4 @@ pub mod entrypoint; // Export current sdk types for downstream users building with a different sdk version pub use solana_program; -solana_program::declare_id!("5QuBzCtUC6pHgFEQJ5d2qX7ktyyHba9HVXLQVUEiAf7d"); +solana_program::declare_id!("poo1B9L9nR3CrcaziKVYVpRX6A9Y1LAXYasjjfCbApj"); diff --git a/program/src/processor.rs b/program/src/processor.rs index 448cc40e..38c687ee 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1296,7 +1296,6 @@ impl PrintProgramError for StakePoolError { StakePoolError::CalculationFailure => msg!("Error: The calculation failed"), StakePoolError::FeeTooHigh => msg!("Error: Stake pool fee > 1"), StakePoolError::WrongAccountMint => msg!("Error: Token account is associated with the wrong mint"), - StakePoolError::NonZeroBalance => msg!("Error: Account balance should be zero"), StakePoolError::WrongOwner => msg!("Error: Wrong pool owner account"), StakePoolError::SignatureMissing => msg!("Error: Required signature is missing"), StakePoolError::InvalidValidatorStakeList => msg!("Error: Invalid validator stake list account"), diff --git a/program/src/state.rs b/program/src/state.rs index 3c945223..f96493bf 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -1,15 +1,14 @@ //! State transition types -use crate::error::StakePoolError; -use crate::instruction::Fee; -use crate::processor::Processor; -use core::convert::TryInto; -use solana_program::{ - account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, - pubkey::Pubkey, +use { + crate::{error::StakePoolError, instruction::Fee, processor::Processor}, + solana_program::{ + account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, + pubkey::Pubkey, + }, + std::convert::{TryFrom, TryInto}, + std::mem::size_of, }; -use std::convert::TryFrom; -use std::mem::size_of; /// Initialized program details. #[repr(C)] From e42f2872cef0abfff642e68823d7be7dabae4c44 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Sat, 27 Feb 2021 00:57:38 +0100 Subject: [PATCH 0049/1076] stake-pool-cli: Fix update command, add verbosity (#1345) * stake-pool-cli: Fix update command, add verbosity The update command in the stake pool CLI was passing the validator vote account instead of the associated stake account from the pool, causing it to fail. Additionally, add more verbose logging, and a dry-run mode to get simulate transaction information, useful for debugging CLI failures. * Run cargo fmt --- clients/cli/src/main.rs | 70 +++++++++++++++++++++++++++++++++----- program/src/instruction.rs | 4 +-- 2 files changed, 64 insertions(+), 10 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 3c4a3de7..b1b274d3 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -53,6 +53,7 @@ struct Config { verbose: bool, owner: Box, fee_payer: Box, + dry_run: bool, } type Error = Box; @@ -511,6 +512,9 @@ fn command_deposit( let stake_data = config.rpc_client.get_account_data(&stake)?; let stake_data: StakeState = deserialize(stake_data.as_slice()).or(Err("Invalid stake account data"))?; + if config.verbose { + println!("Depositing stake account {:?}", stake_data); + } let validator: Pubkey = match stake_data { StakeState::Stake(_, stake) => Ok(stake.delegation.voter_pubkey), _ => Err("Wrong stake account state, must be delegated to validator"), @@ -529,7 +533,16 @@ fn command_deposit( // Calculate validator stake account address linked to the pool let (validator_stake_account, _) = PoolProcessor::find_stake_address_for_validator(&spl_stake_pool::id(), &validator, pool); - println!("Depositing into stake account {}", validator_stake_account); + let validator_stake_data = config + .rpc_client + .get_account_data(&validator_stake_account)?; + let validator_stake_data: StakeState = + deserialize(validator_stake_data.as_slice()).or(Err("Invalid stake account data"))?; + if config.verbose { + println!("Depositing into stake account {:?}", validator_stake_data); + } else { + println!("Depositing into stake account {}", validator_stake_account); + } let mut instructions: Vec = vec![]; let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()]; @@ -617,6 +630,21 @@ fn command_list(config: &Config, pool: &Pubkey) -> CommandResult { let pool_data = config.rpc_client.get_account_data(&pool)?; let pool_data = StakePool::deserialize(pool_data.as_slice()).unwrap(); + if config.verbose { + let validator_list = config + .rpc_client + .get_account_data(&pool_data.validator_stake_list)?; + let validator_stake_list_data = + ValidatorStakeList::deserialize(&validator_list.as_slice())?; + println!("Current validator list"); + for validator in validator_stake_list_data.validators { + println!( + "Vote: {}\tBalance: {}\tEpoch: {}", + validator.validator_account, validator.balance, validator.last_update_epoch + ); + } + } + let pool_withdraw_authority: Pubkey = PoolProcessor::authority_id( &spl_stake_pool::id(), pool, @@ -633,9 +661,16 @@ fn command_list(config: &Config, pool: &Pubkey) -> CommandResult { let mut total_balance: u64 = 0; for (pubkey, account) in accounts { + let stake_data: StakeState = + deserialize(account.data.as_slice()).or(Err("Invalid stake account data"))?; let balance = account.lamports; total_balance += balance; - println!("{}\t{} SOL", pubkey, lamports_to_sol(balance)); + println!( + "Pubkey: {}\tVote: {}\t{} SOL", + pubkey, + stake_data.delegation().unwrap().voter_pubkey, + lamports_to_sol(balance) + ); } println!("Total: {} SOL", lamports_to_sol(total_balance)); @@ -654,14 +689,19 @@ fn command_update(config: &Config, pool: &Pubkey) -> CommandResult { let epoch_info = config.rpc_client.get_epoch_info()?; - let accounts_to_update: Vec<&Pubkey> = validator_stake_list_data + let accounts_to_update: Vec = validator_stake_list_data .validators .iter() .filter_map(|item| { if item.last_update_epoch >= epoch_info.epoch { None } else { - Some(&item.validator_account) + let (stake_account, _) = PoolProcessor::find_stake_address_for_validator( + &spl_stake_pool::id(), + &item.validator_account, + &pool, + ); + Some(stake_account) } }) .collect(); @@ -1033,6 +1073,13 @@ fn main() { .global(true) .help("Show additional information"), ) + .arg( + Arg::with_name("dry_run") + .long("dry-run") + .takes_value(false) + .global(true) + .help("Simluate transaction instead of executing"), + ) .arg( Arg::with_name("json_rpc_url") .long("url") @@ -1354,12 +1401,14 @@ fn main() { exit(1); }); let verbose = matches.is_present("verbose"); + let dry_run = matches.is_present("dry_run"); Config { rpc_client: RpcClient::new_with_commitment(json_rpc_url, CommitmentConfig::confirmed()), verbose, owner, fee_payer, + dry_run, } }; @@ -1439,10 +1488,15 @@ fn main() { } .and_then(|transaction| { if let Some(transaction) = transaction { - let signature = config - .rpc_client - .send_and_confirm_transaction_with_spinner(&transaction)?; - println!("Signature: {}", signature); + if config.dry_run { + let result = config.rpc_client.simulate_transaction(&transaction)?; + println!("Simulate result: {:?}", result); + } else { + let signature = config + .rpc_client + .send_and_confirm_transaction_with_spinner(&transaction)?; + println!("Signature: {}", signature); + } } Ok(()) }) diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 049c8abd..427dad21 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -377,11 +377,11 @@ pub fn remove_validator_stake_account( pub fn update_list_balance( program_id: &Pubkey, validator_stake_list_storage: &Pubkey, - validator_stake_list: &[&Pubkey], + validator_stake_list: &[Pubkey], ) -> Result { let mut accounts: Vec = validator_stake_list .iter() - .map(|pubkey| AccountMeta::new_readonly(**pubkey, false)) + .map(|pubkey| AccountMeta::new_readonly(*pubkey, false)) .collect(); accounts.insert(0, AccountMeta::new(*validator_stake_list_storage, false)); accounts.insert(1, AccountMeta::new_readonly(sysvar::clock::id(), false)); From aa15f01b6acb4b0f013ad5ce5b6f0a891a0c478d Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Mon, 1 Mar 2021 22:39:21 +0100 Subject: [PATCH 0050/1076] stake-pool: Fix stake split and withdraw token calculation (#1352) * Fix stake split and withdraw token calculation * Cargo fmt --- clients/cli/src/main.rs | 37 ++++++++++++++----------------------- program/src/processor.rs | 17 +---------------- 2 files changed, 15 insertions(+), 39 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index b1b274d3..f062a0e6 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -395,7 +395,9 @@ fn command_vsa_remove( // Calculate amount of tokens to burn let stake_account = config.rpc_client.get_account(&stake)?; - let tokens_to_burn = stake_amount_to_pool_tokens(&pool_data, stake_account.lamports); + let tokens_to_burn = pool_data + .calc_pool_withdraw_amount(stake_account.lamports) + .unwrap(); // Check balance and mint let account_data = config.rpc_client.get_account_data(&burn_from)?; @@ -736,22 +738,6 @@ fn command_update(config: &Config, pool: &Pubkey) -> CommandResult { } } -fn stake_amount_to_pool_tokens(pool_data: &StakePool, amount: u64) -> u64 { - (amount as u128) - .checked_mul(pool_data.pool_total as u128) - .unwrap() - .checked_div(pool_data.stake_total as u128) - .unwrap() as u64 -} - -fn pool_tokens_to_stake_amount(pool_data: &StakePool, tokens: u64) -> u64 { - (tokens as u128) - .checked_mul(pool_data.stake_total as u128) - .unwrap() - .checked_div(pool_data.pool_total as u128) - .unwrap() as u64 -} - #[derive(PartialEq, Debug)] struct WithdrawAccount { pubkey: Pubkey, @@ -859,7 +845,7 @@ fn command_withdraw( } // Convert pool tokens amount to lamports - let sol_withdraw_amount = pool_tokens_to_stake_amount(&pool_data, amount); + let sol_withdraw_amount = pool_data.calc_lamports_amount(amount).unwrap(); // Get the list of accounts to withdraw from let withdraw_from: Vec = @@ -870,8 +856,6 @@ fn command_withdraw( let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()]; let stake_receiver_account = Keypair::new(); // Will be added to signers if creating new account - let mut total_rent_free_balances: u64 = 0; - instructions.push( // Approve spending token approve_token( @@ -887,12 +871,19 @@ fn command_withdraw( // Use separate mutable variable because withdraw might create a new account let mut stake_receiver: Option = *stake_receiver_param; + let mut total_rent_free_balances = 0; + // Go through prepared accounts and withdraw/claim them for withdraw_stake in withdraw_from { + let withdraw_amount = pool_data + .calc_pool_withdraw_amount(withdraw_stake.amount) + .unwrap() + + 1; println!( - "Withdrawing from account {}, amount {} SOL", + "Withdrawing from account {}, amount {} SOL, {} pool tokens", withdraw_stake.pubkey, - lamports_to_sol(withdraw_stake.amount) + lamports_to_sol(withdraw_stake.amount), + lamports_to_sol(withdraw_amount), ); if stake_receiver.is_none() { @@ -936,7 +927,7 @@ fn command_withdraw( &pool_data.pool_mint, &spl_token::id(), &stake_program_id(), - withdraw_stake.amount, + withdraw_amount, )?); } diff --git a/program/src/processor.rs b/program/src/processor.rs index 38c687ee..7b12d900 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -131,7 +131,6 @@ impl Processor { } /// Issue a stake_split instruction. - #[allow(clippy::too_many_arguments)] pub fn stake_split<'a>( stake_pool: &Pubkey, stake_account: AccountInfo<'a>, @@ -140,8 +139,6 @@ impl Processor { bump_seed: u8, amount: u64, split_stake: AccountInfo<'a>, - reserved: AccountInfo<'a>, - stake_program_info: AccountInfo<'a>, ) -> Result<(), ProgramError> { let me_bytes = stake_pool.to_bytes(); let authority_signature_seeds = [&me_bytes[..32], authority_type, &[bump_seed]]; @@ -149,17 +146,7 @@ impl Processor { let ix = stake::split_only(stake_account.key, authority.key, amount, split_stake.key); - invoke_signed( - &ix, - &[ - stake_account, - reserved, - authority, - split_stake, - stake_program_info, - ], - signers, - ) + invoke_signed(&ix, &[stake_account, split_stake, authority], signers) } /// Issue a stake_merge instruction. @@ -1114,8 +1101,6 @@ impl Processor { stake_pool.withdraw_bump_seed, stake_amount, stake_split_to.clone(), - clock_info.clone(), - stake_program_info.clone(), )?; Self::stake_authorize( From c7c936b13e84297f5e724e376a2699da015c41b3 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 2 Mar 2021 19:19:50 +0100 Subject: [PATCH 0051/1076] Update solana-program to 1.5.11 (#1362) * Update solana-program to 1.5.11 * Update all programs --- clients/cli/Cargo.toml | 14 +++++++------- program/Cargo.toml | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 976ef846..995016b0 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,13 +11,13 @@ version = "2.0.1" [dependencies] clap = "2.33.3" serde_json = "1.0.62" -solana-account-decoder = "1.5.6" -solana-clap-utils = "1.5.6" -solana-cli-config = "1.5.8" -solana-client = "1.5.6" -solana-logger = "1.5.6" -solana-sdk = "1.5.6" -solana-program = "1.5.8" +solana-account-decoder = "1.5.11" +solana-clap-utils = "1.5.11" +solana-cli-config = "1.5.11" +solana-client = "1.5.11" +solana-logger = "1.5.11" +solana-sdk = "1.5.11" +solana-program = "1.5.11" spl-stake-pool = { path="../program", features = [ "no-entrypoint" ] } spl-token = { path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" diff --git a/program/Cargo.toml b/program/Cargo.toml index a2043751..5d1f3d5b 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,15 +18,15 @@ num-traits = "0.2" num_enum = "0.5.1" serde = "1.0.121" serde_derive = "1.0.103" -solana-program = "1.5.8" +solana-program = "1.5.11" spl-token = { path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" bincode = "1.3.1" [dev-dependencies] -solana-program-test = "1.5.6" -solana-sdk = "1.5.6" -solana-vote-program = "1.5.6" +solana-program-test = "1.5.11" +solana-sdk = "1.5.11" +solana-vote-program = "1.5.11" tokio = { version = "0.3", features = ["macros"]} [lib] From dabd4c54b41b7ff555f14a29c242fdcb53236897 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 10 Mar 2021 10:38:44 +0100 Subject: [PATCH 0052/1076] stake-pool-cli: Rename burn -> withdraw (#1423) --- clients/cli/src/main.rs | 66 ++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index f062a0e6..9e73f9a0 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -375,7 +375,7 @@ fn command_vsa_remove( config: &Config, pool: &Pubkey, stake: &Pubkey, - burn_from: &Pubkey, + withdraw_from: &Pubkey, new_authority: &Option, ) -> CommandResult { // Get stake pool state @@ -393,14 +393,14 @@ fn command_vsa_remove( let owner_pubkey = config.owner.pubkey(); let new_authority = new_authority.as_ref().unwrap_or(&owner_pubkey); - // Calculate amount of tokens to burn + // Calculate amount of tokens to withdraw let stake_account = config.rpc_client.get_account(&stake)?; - let tokens_to_burn = pool_data + let tokens_to_withdraw = pool_data .calc_pool_withdraw_amount(stake_account.lamports) .unwrap(); // Check balance and mint - let account_data = config.rpc_client.get_account_data(&burn_from)?; + let account_data = config.rpc_client.get_account_data(&withdraw_from)?; let account_data: TokenAccount = TokenAccount::unpack_from_slice(account_data.as_slice()).unwrap(); @@ -408,10 +408,10 @@ fn command_vsa_remove( return Err("Wrong token account.".into()); } - if account_data.amount < tokens_to_burn { + if account_data.amount < tokens_to_withdraw { return Err(format!( - "Not enough balance to burn to remove validator stake account from the pool. {} pool tokens needed.", - lamports_to_sol(tokens_to_burn) + "Not enough balance to withdraw to remove validator stake account from the pool. {} pool tokens needed.", + lamports_to_sol(tokens_to_withdraw) ).into()); } @@ -420,11 +420,11 @@ fn command_vsa_remove( // Approve spending token approve_token( &spl_token::id(), - &burn_from, + &withdraw_from, &pool_withdraw_authority, &config.owner.pubkey(), &[], - tokens_to_burn, + tokens_to_withdraw, )?, // Create new validator stake account address remove_validator_stake_account( @@ -435,7 +435,7 @@ fn command_vsa_remove( &new_authority, &pool_data.validator_stake_list, &stake, - &burn_from, + &withdraw_from, &pool_data.pool_mint, &spl_token::id(), &stake_program_id(), @@ -810,7 +810,7 @@ fn command_withdraw( config: &Config, pool: &Pubkey, amount: u64, - burn_from: &Pubkey, + withdraw_from: &Pubkey, stake_receiver_param: &Option, ) -> CommandResult { // Get stake pool state @@ -825,8 +825,8 @@ fn command_withdraw( ) .unwrap(); - // Check burn_from account type - let account_data = config.rpc_client.get_account_data(&burn_from)?; + // Check withdraw_from account type + let account_data = config.rpc_client.get_account_data(&withdraw_from)?; let account_data: TokenAccount = TokenAccount::unpack_from_slice(account_data.as_slice()).unwrap(); @@ -834,7 +834,7 @@ fn command_withdraw( return Err("Wrong token account.".into()); } - // Check burn_from balance + // Check withdraw_from balance if account_data.amount < amount { return Err(format!( "Not enough token balance to withdraw {} pool tokens.\nMaximum withdraw amount is {} pool tokens.", @@ -848,10 +848,10 @@ fn command_withdraw( let sol_withdraw_amount = pool_data.calc_lamports_amount(amount).unwrap(); // Get the list of accounts to withdraw from - let withdraw_from: Vec = + let withdraw_accounts: Vec = prepare_withdraw_accounts(config, &pool_withdraw_authority, sol_withdraw_amount)?; - // Construct transaction to withdraw from withdraw_from account list + // Construct transaction to withdraw from withdraw_accounts account list let mut instructions: Vec = vec![]; let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()]; let stake_receiver_account = Keypair::new(); // Will be added to signers if creating new account @@ -860,7 +860,7 @@ fn command_withdraw( // Approve spending token approve_token( &spl_token::id(), - &burn_from, + &withdraw_from, &pool_withdraw_authority, &config.owner.pubkey(), &[], @@ -874,7 +874,7 @@ fn command_withdraw( let mut total_rent_free_balances = 0; // Go through prepared accounts and withdraw/claim them - for withdraw_stake in withdraw_from { + for withdraw_stake in withdraw_accounts { let withdraw_amount = pool_data .calc_pool_withdraw_amount(withdraw_stake.amount) .unwrap() @@ -923,7 +923,7 @@ fn command_withdraw( &withdraw_stake.pubkey, &stake_receiver.unwrap(), // Cannot be none at this point &config.owner.pubkey(), - &burn_from, + &withdraw_from, &pool_data.pool_mint, &spl_token::id(), &stake_program_id(), @@ -1193,13 +1193,13 @@ fn main() { .help("Stake account to remove from the pool"), ) .arg( - Arg::with_name("burn_from") - .long("burn-from") + Arg::with_name("withdraw_from") + .long("withdraw-from") .validator(is_pubkey) .value_name("ADDRESS") .takes_value(true) .required(true) - .help("Token account to burn pool token from. Must have enough tokens to burn for the full stake address balance."), + .help("Token account to withdraw pool token from. Must have enough tokens for the full stake address balance."), ) .arg( Arg::with_name("new_authority") @@ -1277,16 +1277,16 @@ fn main() { .value_name("AMOUNT") .takes_value(true) .required(true) - .help("Amount of pool tokens to burn and get rewards."), + .help("Amount of pool tokens to withdraw for activated stake."), ) .arg( - Arg::with_name("burn_from") - .long("burn-from") + Arg::with_name("withdraw_from") + .long("withdraw-from") .validator(is_pubkey) .value_name("ADDRESS") .takes_value(true) .required(true) - .help("Account to burn tokens from. Must be owned by the client."), + .help("Account to withdraw tokens from. Must be owned by the client."), ) .arg( Arg::with_name("stake_receiver") @@ -1431,13 +1431,13 @@ fn main() { ("remove-validator-stake", Some(arg_matches)) => { let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); let stake_account: Pubkey = pubkey_of(arg_matches, "stake").unwrap(); - let burn_from: Pubkey = pubkey_of(arg_matches, "burn_from").unwrap(); + let withdraw_from: Pubkey = pubkey_of(arg_matches, "withdraw_from").unwrap(); let new_authority: Option = pubkey_of(arg_matches, "new_authority"); command_vsa_remove( &config, &pool_account, &stake_account, - &burn_from, + &withdraw_from, &new_authority, ) } @@ -1457,11 +1457,17 @@ fn main() { } ("withdraw", Some(arg_matches)) => { let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); - let burn_from: Pubkey = pubkey_of(arg_matches, "burn_from").unwrap(); + let withdraw_from: Pubkey = pubkey_of(arg_matches, "withdraw_from").unwrap(); // convert from float to int, using sol_to_lamports because they have the same precision as SOL let amount: u64 = sol_to_lamports(value_t_or_exit!(arg_matches, "amount", f64)); let stake_receiver: Option = pubkey_of(arg_matches, "stake_receiver"); - command_withdraw(&config, &pool_account, amount, &burn_from, &stake_receiver) + command_withdraw( + &config, + &pool_account, + amount, + &withdraw_from, + &stake_receiver, + ) } ("set-staking-auth", Some(arg_matches)) => { let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); From bd016d57c154f51fb408360f62443973a9866686 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 10 Mar 2021 13:45:42 +0100 Subject: [PATCH 0053/1076] stake-pool-cli: Fix withdraw calc for CLI / program consistency (#1422) * stake-pool-cli: Fix withdraw calc for CLI / program consistency * Run cargo fmt * Integrate review feedback --- clients/cli/src/main.rs | 109 ++++++++++++++++++++-------------------- 1 file changed, 55 insertions(+), 54 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 9e73f9a0..31828300 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -21,7 +21,7 @@ use solana_program::{instruction::Instruction, program_pack::Pack, pubkey::Pubke use solana_sdk::{ account::Account, commitment_config::CommitmentConfig, - native_token::*, + native_token::{self, Sol}, signature::{Keypair, Signer}, system_instruction, transaction::Transaction, @@ -62,7 +62,7 @@ type CommandResult = Result, Error>; const STAKE_STATE_LEN: usize = 200; const MAX_ACCOUNTS_TO_UPDATE: usize = 10; lazy_static! { - static ref MIN_STAKE_BALANCE: u64 = sol_to_lamports(1.0); + static ref MIN_STAKE_BALANCE: u64 = native_token::sol_to_lamports(1.0); } macro_rules! unique_signers { @@ -78,8 +78,8 @@ fn check_fee_payer_balance(config: &Config, required_balance: u64) -> Result<(), Err(format!( "Fee payer, {}, has insufficient balance: {} required, {} available", config.fee_payer.pubkey(), - lamports_to_sol(required_balance), - lamports_to_sol(balance) + Sol(required_balance), + Sol(balance) ) .into()) } else { @@ -109,21 +109,6 @@ fn get_authority_accounts(config: &Config, authority: &Pubkey) -> Vec<(Pubkey, A .unwrap() } -fn _check_owner_balance(config: &Config, required_balance: u64) -> Result<(), Error> { - let balance = config.rpc_client.get_balance(&config.owner.pubkey())?; - if balance < required_balance { - Err(format!( - "Owner, {}, has insufficient balance: {} required, {} available", - config.owner.pubkey(), - lamports_to_sol(required_balance), - lamports_to_sol(balance) - ) - .into()) - } else { - Ok(()) - } -} - fn command_create_pool(config: &Config, fee: PoolFee) -> CommandResult { let mint_account = Keypair::new(); println!("Creating mint {}", mint_account.pubkey()); @@ -409,9 +394,11 @@ fn command_vsa_remove( } if account_data.amount < tokens_to_withdraw { + let pool_mint_data = config.rpc_client.get_account_data(&pool_data.pool_mint)?; + let pool_mint = TokenMint::unpack_from_slice(pool_mint_data.as_slice()).unwrap(); return Err(format!( - "Not enough balance to withdraw to remove validator stake account from the pool. {} pool tokens needed.", - lamports_to_sol(tokens_to_withdraw) + "Not enough balance to burn to remove validator stake account from the pool. {} pool tokens needed.", + spl_token::amount_to_ui_amount(tokens_to_withdraw, pool_mint.decimals) ).into()); } @@ -668,13 +655,13 @@ fn command_list(config: &Config, pool: &Pubkey) -> CommandResult { let balance = account.lamports; total_balance += balance; println!( - "Pubkey: {}\tVote: {}\t{} SOL", + "Pubkey: {}\tVote: {}\t{}", pubkey, stake_data.delegation().unwrap().voter_pubkey, - lamports_to_sol(balance) + Sol(balance) ); } - println!("Total: {} SOL", lamports_to_sol(total_balance)); + println!("Total: {}", Sol(total_balance)); Ok(None) } @@ -742,13 +729,14 @@ fn command_update(config: &Config, pool: &Pubkey) -> CommandResult { struct WithdrawAccount { pubkey: Pubkey, account: Account, - amount: u64, + pool_amount: u64, } fn prepare_withdraw_accounts( config: &Config, + stake_pool: &StakePool, pool_withdraw_authority: &Pubkey, - amount: u64, + pool_amount: u64, ) -> Result, Error> { let mut accounts = get_authority_accounts(config, &pool_withdraw_authority); if accounts.is_empty() { @@ -758,12 +746,22 @@ fn prepare_withdraw_accounts( .rpc_client .get_minimum_balance_for_rent_exemption(STAKE_STATE_LEN)? + 1; - pick_withdraw_accounts(&mut accounts, amount, min_balance) + let pool_mint_data = config.rpc_client.get_account_data(&stake_pool.pool_mint)?; + let pool_mint = TokenMint::unpack_from_slice(pool_mint_data.as_slice()).unwrap(); + pick_withdraw_accounts( + &mut accounts, + stake_pool, + &pool_mint, + pool_amount, + min_balance, + ) } fn pick_withdraw_accounts( accounts: &mut Vec<(Pubkey, Account)>, - amount: u64, + stake_pool: &StakePool, + pool_mint: &TokenMint, + pool_amount: u64, min_balance: u64, ) -> Result, Error> { // Sort from highest to lowest balance @@ -771,21 +769,23 @@ fn pick_withdraw_accounts( // Prepare the list of accounts to withdraw from let mut withdraw_from: Vec = vec![]; - let mut remaining_amount = amount; + let mut remaining_amount = pool_amount; // Go through available accounts and withdraw from largest to smallest for (pubkey, account) in accounts { if account.lamports <= min_balance { continue; } - let available_for_withdrawal = account.lamports - *MIN_STAKE_BALANCE; + let available_for_withdrawal = stake_pool + .calc_lamports_amount(account.lamports - *MIN_STAKE_BALANCE) + .unwrap(); let withdraw_amount = u64::min(available_for_withdrawal, remaining_amount); // Those accounts will be withdrawn completely with `claim` instruction withdraw_from.push(WithdrawAccount { pubkey: *pubkey, account: account.clone(), - amount: withdraw_amount, + pool_amount: withdraw_amount, }); remaining_amount -= withdraw_amount; @@ -797,8 +797,8 @@ fn pick_withdraw_accounts( // Not enough stake to withdraw the specified amount if remaining_amount > 0 { return Err(format!( - "No stake accounts found in this pool with enough balance to withdraw {} SOL.", - lamports_to_sol(amount) + "No stake accounts found in this pool with enough balance to withdraw {} pool tokens.", + spl_token::amount_to_ui_amount(pool_amount, pool_mint.decimals) ) .into()); } @@ -809,13 +809,17 @@ fn pick_withdraw_accounts( fn command_withdraw( config: &Config, pool: &Pubkey, - amount: u64, + pool_amount: f64, withdraw_from: &Pubkey, stake_receiver_param: &Option, ) -> CommandResult { // Get stake pool state let pool_data = config.rpc_client.get_account_data(&pool)?; - let pool_data: StakePool = StakePool::deserialize(pool_data.as_slice()).unwrap(); + let pool_data = StakePool::deserialize(pool_data.as_slice()).unwrap(); + + let pool_mint_data = config.rpc_client.get_account_data(&pool_data.pool_mint)?; + let pool_mint = TokenMint::unpack_from_slice(pool_mint_data.as_slice()).unwrap(); + let pool_amount = spl_token::ui_amount_to_amount(pool_amount, pool_mint.decimals); let pool_withdraw_authority: Pubkey = PoolProcessor::authority_id( &spl_stake_pool::id(), @@ -835,21 +839,18 @@ fn command_withdraw( } // Check withdraw_from balance - if account_data.amount < amount { + if account_data.amount < pool_amount { return Err(format!( "Not enough token balance to withdraw {} pool tokens.\nMaximum withdraw amount is {} pool tokens.", - lamports_to_sol(amount), - lamports_to_sol(account_data.amount) + spl_token::amount_to_ui_amount(pool_amount, pool_mint.decimals), + spl_token::amount_to_ui_amount(account_data.amount, pool_mint.decimals) ) .into()); } - // Convert pool tokens amount to lamports - let sol_withdraw_amount = pool_data.calc_lamports_amount(amount).unwrap(); - // Get the list of accounts to withdraw from let withdraw_accounts: Vec = - prepare_withdraw_accounts(config, &pool_withdraw_authority, sol_withdraw_amount)?; + prepare_withdraw_accounts(config, &pool_data, &pool_withdraw_authority, pool_amount)?; // Construct transaction to withdraw from withdraw_accounts account list let mut instructions: Vec = vec![]; @@ -864,7 +865,7 @@ fn command_withdraw( &pool_withdraw_authority, &config.owner.pubkey(), &[], - amount, + pool_amount, )?, ); @@ -875,15 +876,16 @@ fn command_withdraw( // Go through prepared accounts and withdraw/claim them for withdraw_stake in withdraw_accounts { - let withdraw_amount = pool_data - .calc_pool_withdraw_amount(withdraw_stake.amount) - .unwrap() - + 1; + // Convert pool tokens amount to lamports + let sol_withdraw_amount = pool_data + .calc_lamports_amount(withdraw_stake.pool_amount) + .unwrap(); + println!( - "Withdrawing from account {}, amount {} SOL, {} pool tokens", + "Withdrawing from account {}, amount {}, {} pool tokens", withdraw_stake.pubkey, - lamports_to_sol(withdraw_stake.amount), - lamports_to_sol(withdraw_amount), + Sol(sol_withdraw_amount), + spl_token::amount_to_ui_amount(withdraw_stake.pool_amount, pool_mint.decimals), ); if stake_receiver.is_none() { @@ -927,7 +929,7 @@ fn command_withdraw( &pool_data.pool_mint, &spl_token::id(), &stake_program_id(), - withdraw_amount, + withdraw_stake.pool_amount, )?); } @@ -1458,13 +1460,12 @@ fn main() { ("withdraw", Some(arg_matches)) => { let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); let withdraw_from: Pubkey = pubkey_of(arg_matches, "withdraw_from").unwrap(); - // convert from float to int, using sol_to_lamports because they have the same precision as SOL - let amount: u64 = sol_to_lamports(value_t_or_exit!(arg_matches, "amount", f64)); + let pool_amount = value_t_or_exit!(arg_matches, "amount", f64); let stake_receiver: Option = pubkey_of(arg_matches, "stake_receiver"); command_withdraw( &config, &pool_account, - amount, + pool_amount, &withdraw_from, &stake_receiver, ) From ea69140d4bae6e4f7b83d3a5c74e8107d635c741 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Mon, 15 Mar 2021 22:36:21 -0700 Subject: [PATCH 0054/1076] Switch to Instruction::new_with_bincode --- program/src/stake.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/program/src/stake.rs b/program/src/stake.rs index 47351ff2..f8173a7f 100644 --- a/program/src/stake.rs +++ b/program/src/stake.rs @@ -406,7 +406,7 @@ pub fn split_only( AccountMeta::new_readonly(*authorized_pubkey, true), ]; - Instruction::new(id(), &StakeInstruction::Split(lamports), account_metas) + Instruction::new_with_bincode(id(), &StakeInstruction::Split(lamports), account_metas) } /// FIXME copied from the stake program @@ -422,7 +422,7 @@ pub fn authorize( AccountMeta::new_readonly(*authorized_pubkey, true), ]; - Instruction::new( + Instruction::new_with_bincode( id(), &StakeInstruction::Authorize(*new_authorized_pubkey, stake_authorize), account_metas, @@ -443,7 +443,7 @@ pub fn merge( AccountMeta::new_readonly(*authorized_pubkey, true), ]; - Instruction::new(id(), &StakeInstruction::Merge, account_metas) + Instruction::new_with_bincode(id(), &StakeInstruction::Merge, account_metas) } /// FIXME copied from the stake program @@ -468,7 +468,7 @@ pub fn create_account( /// FIXME copied from the stake program pub fn initialize(stake_pubkey: &Pubkey, authorized: &Authorized, lockup: &Lockup) -> Instruction { - Instruction::new( + Instruction::new_with_bincode( id(), &StakeInstruction::Initialize(*authorized, *lockup), vec![ @@ -492,5 +492,5 @@ pub fn delegate_stake( AccountMeta::new_readonly(Pubkey::from_str(STAKE_CONFIG).unwrap(), false), AccountMeta::new_readonly(*authorized_pubkey, true), ]; - Instruction::new(id(), &StakeInstruction::DelegateStake, account_metas) + Instruction::new_with_bincode(id(), &StakeInstruction::DelegateStake, account_metas) } From f85cd8f0d1d1ba047509d3052bb48022868b22a4 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Mon, 15 Mar 2021 22:38:47 -0700 Subject: [PATCH 0055/1076] Remove tokio dev-dependency --- program/Cargo.toml | 1 - program/tests/deposit.rs | 2 +- program/tests/initialize.rs | 2 +- program/tests/set_owner.rs | 2 +- program/tests/set_staking_authority.rs | 2 +- program/tests/update_list_balance.rs | 2 +- program/tests/update_pool_balance.rs | 1 + program/tests/vsa_add.rs | 2 +- program/tests/vsa_create.rs | 1 + program/tests/vsa_remove.rs | 2 +- program/tests/withdraw.rs | 2 +- 11 files changed, 10 insertions(+), 9 deletions(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 5d1f3d5b..9f59d84a 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -27,7 +27,6 @@ bincode = "1.3.1" solana-program-test = "1.5.11" solana-sdk = "1.5.11" solana-vote-program = "1.5.11" -tokio = { version = "0.3", features = ["macros"]} [lib] crate-type = ["cdylib", "lib"] diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index b1dce30b..b8f4a11f 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -5,7 +5,7 @@ mod helpers; use helpers::*; use solana_program::hash::Hash; -use solana_program_test::BanksClient; +use solana_program_test::*; use solana_sdk::{ instruction::InstructionError, signature::{Keypair, Signer}, diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index 79bcaca3..bb0a4da8 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -9,7 +9,7 @@ use solana_program::{ program_pack::Pack, system_instruction, sysvar, }; -use solana_program_test::BanksClient; +use solana_program_test::*; use solana_sdk::{ instruction::InstructionError, signature::Keypair, signature::Signer, transaction::Transaction, transaction::TransactionError, transport::TransportError, diff --git a/program/tests/set_owner.rs b/program/tests/set_owner.rs index f0897e23..4fa6b3f6 100644 --- a/program/tests/set_owner.rs +++ b/program/tests/set_owner.rs @@ -6,7 +6,7 @@ use helpers::*; use solana_program::hash::Hash; use solana_program::instruction::AccountMeta; use solana_program::instruction::Instruction; -use solana_program_test::BanksClient; +use solana_program_test::*; use solana_sdk::{ instruction::InstructionError, signature::Keypair, signature::Signer, transaction::Transaction, transaction::TransactionError, transport::TransportError, diff --git a/program/tests/set_staking_authority.rs b/program/tests/set_staking_authority.rs index ab45a88e..d0805284 100644 --- a/program/tests/set_staking_authority.rs +++ b/program/tests/set_staking_authority.rs @@ -8,7 +8,7 @@ use solana_program::hash::Hash; use solana_program::instruction::AccountMeta; use solana_program::instruction::Instruction; use solana_program::sysvar; -use solana_program_test::BanksClient; +use solana_program_test::*; use solana_sdk::{ instruction::InstructionError, signature::Keypair, signature::Signer, transaction::Transaction, transaction::TransactionError, transport::TransportError, diff --git a/program/tests/update_list_balance.rs b/program/tests/update_list_balance.rs index 259fd497..418699cb 100644 --- a/program/tests/update_list_balance.rs +++ b/program/tests/update_list_balance.rs @@ -6,7 +6,7 @@ use { crate::helpers::TEST_STAKE_AMOUNT, helpers::*, solana_program::{native_token, pubkey::Pubkey}, - solana_program_test::BanksClient, + solana_program_test::*, solana_sdk::signature::Signer, spl_stake_pool::*, }; diff --git a/program/tests/update_pool_balance.rs b/program/tests/update_pool_balance.rs index 53bbd4d6..ff743ced 100644 --- a/program/tests/update_pool_balance.rs +++ b/program/tests/update_pool_balance.rs @@ -3,6 +3,7 @@ mod helpers; use helpers::*; +use solana_program_test::*; use solana_sdk::{ instruction::InstructionError, signature::Keypair, signature::Signer, transaction::Transaction, transaction::TransactionError, transport::TransportError, diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index bd86a6ca..1ac6994c 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -9,7 +9,7 @@ use solana_program::hash::Hash; use solana_program::instruction::AccountMeta; use solana_program::instruction::Instruction; use solana_program::sysvar; -use solana_program_test::BanksClient; +use solana_program_test::*; use solana_sdk::{ instruction::InstructionError, signature::{Keypair, Signer}, diff --git a/program/tests/vsa_create.rs b/program/tests/vsa_create.rs index ab48b56e..baad6e65 100644 --- a/program/tests/vsa_create.rs +++ b/program/tests/vsa_create.rs @@ -6,6 +6,7 @@ use crate::solana_program::pubkey::Pubkey; use helpers::*; use bincode::deserialize; +use solana_program_test::*; use solana_sdk::{ instruction::InstructionError, signature::{Keypair, Signer}, diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 61aa3843..b375f608 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -9,7 +9,7 @@ use solana_program::instruction::AccountMeta; use solana_program::instruction::Instruction; use solana_program::pubkey::Pubkey; use solana_program::sysvar; -use solana_program_test::BanksClient; +use solana_program_test::*; use solana_sdk::{ instruction::InstructionError, signature::{Keypair, Signer}, diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 17cc7274..925550ea 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -6,7 +6,7 @@ use helpers::*; use solana_program::pubkey::Pubkey; use solana_program::hash::Hash; -use solana_program_test::BanksClient; +use solana_program_test::*; use solana_sdk::{ instruction::InstructionError, signature::{Keypair, Signer}, From 66d7330f3bd80aad2ad97a7108a34f961c4df98d Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Tue, 16 Mar 2021 14:27:45 -0700 Subject: [PATCH 0056/1076] Remove yelling --- program/src/stake.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/program/src/stake.rs b/program/src/stake.rs index f8173a7f..a23f5204 100644 --- a/program/src/stake.rs +++ b/program/src/stake.rs @@ -86,7 +86,7 @@ pub enum StakeInstruction { /// # Account references /// 0. [WRITE] Initialized stake account /// 1. [SIGNER] Lockup authority - SetLockupNOTUSED, + SetLockup, /// Merge two stake accounts. Both accounts must be deactivated and have identical lockup and /// authority keys. @@ -104,7 +104,7 @@ pub enum StakeInstruction { /// # Account references /// 0. [WRITE] Stake account to be updated /// 1. [SIGNER] Base key of stake or withdraw authority - AuthorizeWithSeedNOTUSED, + AuthorizeWithSeed, } /// FIXME copied from the stake program From bf259f29695ced3ed6da0a39746a53609cfcd1c0 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Tue, 16 Mar 2021 13:47:59 -0700 Subject: [PATCH 0057/1076] Bump Solana version to 1.5.15 --- clients/cli/Cargo.toml | 14 +++++++------- program/Cargo.toml | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 995016b0..5ae3b139 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,13 +11,13 @@ version = "2.0.1" [dependencies] clap = "2.33.3" serde_json = "1.0.62" -solana-account-decoder = "1.5.11" -solana-clap-utils = "1.5.11" -solana-cli-config = "1.5.11" -solana-client = "1.5.11" -solana-logger = "1.5.11" -solana-sdk = "1.5.11" -solana-program = "1.5.11" +solana-account-decoder = "1.5.15" +solana-clap-utils = "1.5.15" +solana-cli-config = "1.5.15" +solana-client = "1.5.15" +solana-logger = "1.5.15" +solana-sdk = "1.5.15" +solana-program = "1.5.15" spl-stake-pool = { path="../program", features = [ "no-entrypoint" ] } spl-token = { path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" diff --git a/program/Cargo.toml b/program/Cargo.toml index 9f59d84a..6fa373c9 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,14 +18,14 @@ num-traits = "0.2" num_enum = "0.5.1" serde = "1.0.121" serde_derive = "1.0.103" -solana-program = "1.5.11" +solana-program = "1.5.15" spl-token = { path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" bincode = "1.3.1" [dev-dependencies] -solana-program-test = "1.5.11" -solana-sdk = "1.5.11" +solana-program-test = "1.5.15" +solana-sdk = "1.5.15" solana-vote-program = "1.5.11" [lib] From c201e2020f16c1097ec389e6393ac4ed344c3d42 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Mon, 15 Mar 2021 22:35:48 -0700 Subject: [PATCH 0058/1076] Bump Rust version to 1.50.0 --- clients/cli/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 31828300..da27d4f6 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -1414,8 +1414,8 @@ fn main() { command_create_pool( &config, PoolFee { - numerator, denominator, + numerator, }, ) } From e3d0e902b4adbc079a3d690a1389256686f32364 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Wed, 17 Mar 2021 20:21:21 -0700 Subject: [PATCH 0059/1076] Bump Solana version to 1.6.1 --- clients/cli/Cargo.toml | 14 +++++++------- program/Cargo.toml | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 5ae3b139..d5c6176b 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,13 +11,13 @@ version = "2.0.1" [dependencies] clap = "2.33.3" serde_json = "1.0.62" -solana-account-decoder = "1.5.15" -solana-clap-utils = "1.5.15" -solana-cli-config = "1.5.15" -solana-client = "1.5.15" -solana-logger = "1.5.15" -solana-sdk = "1.5.15" -solana-program = "1.5.15" +solana-account-decoder = "1.6.1" +solana-clap-utils = "1.6.1" +solana-cli-config = "1.6.1" +solana-client = "1.6.1" +solana-logger = "1.6.1" +solana-sdk = "1.6.1" +solana-program = "1.6.1" spl-stake-pool = { path="../program", features = [ "no-entrypoint" ] } spl-token = { path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" diff --git a/program/Cargo.toml b/program/Cargo.toml index 6fa373c9..9b71e396 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,14 +18,14 @@ num-traits = "0.2" num_enum = "0.5.1" serde = "1.0.121" serde_derive = "1.0.103" -solana-program = "1.5.15" +solana-program = "1.6.1" spl-token = { path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" bincode = "1.3.1" [dev-dependencies] -solana-program-test = "1.5.15" -solana-sdk = "1.5.15" +solana-program-test = "1.6.1" +solana-sdk = "1.6.1" solana-vote-program = "1.5.11" [lib] From 973e109b98d99815b4bdc828a31de3d9a467e342 Mon Sep 17 00:00:00 2001 From: Yuriy Savchenko Date: Thu, 18 Mar 2021 13:21:01 +0200 Subject: [PATCH 0060/1076] Set staking authority instruction removed (#1469) * Set staking authority instruction removed * Fixed fmt errors --- clients/cli/src/main.rs | 75 +------ program/src/instruction.rs | 47 +---- program/src/processor.rs | 49 ----- program/tests/set_staking_authority.rs | 273 ------------------------- 4 files changed, 3 insertions(+), 441 deletions(-) delete mode 100644 program/tests/set_staking_authority.rs diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index da27d4f6..eadaff56 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -30,7 +30,7 @@ use spl_stake_pool::{ instruction::{ add_validator_stake_account, create_validator_stake_account, deposit, initialize as initialize_pool, remove_validator_stake_account, set_owner, - set_staking_authority, update_list_balance, update_pool_balance, withdraw, Fee as PoolFee, + update_list_balance, update_pool_balance, withdraw, Fee as PoolFee, InitArgs as PoolInitArgs, }, processor::Processor as PoolProcessor, @@ -947,44 +947,6 @@ fn command_withdraw( Ok(Some(transaction)) } -fn command_set_staking_auth( - config: &Config, - pool: &Pubkey, - stake_account: &Pubkey, - new_staker: &Pubkey, -) -> CommandResult { - let pool_data = config.rpc_client.get_account_data(&pool)?; - let pool_data: StakePool = StakePool::deserialize(pool_data.as_slice()).unwrap(); - - let pool_withdraw_authority: Pubkey = PoolProcessor::authority_id( - &spl_stake_pool::id(), - pool, - PoolProcessor::AUTHORITY_WITHDRAW, - pool_data.withdraw_bump_seed, - ) - .unwrap(); - - let mut transaction = Transaction::new_with_payer( - &[set_staking_authority( - &spl_stake_pool::id(), - &pool, - &config.owner.pubkey(), - &pool_withdraw_authority, - &stake_account, - &new_staker, - &stake_program_id(), - )?], - Some(&config.fee_payer.pubkey()), - ); - - let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; - let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()]; - unique_signers!(signers); - transaction.sign(&signers, recent_blockhash); - Ok(Some(transaction)) -} - fn command_set_owner( config: &Config, pool: &Pubkey, @@ -1299,35 +1261,6 @@ fn main() { .help("Stake account to receive SOL from the stake pool. Defaults to a new stake account."), ) ) - .subcommand(SubCommand::with_name("set-staking-auth").about("Changes staking authority of one of the accounts from the stake pool.") - .arg( - Arg::with_name("pool") - .long("pool") - .validator(is_pubkey) - .value_name("ADDRESS") - .takes_value(true) - .required(true) - .help("Stake pool address."), - ) - .arg( - Arg::with_name("stake_account") - .long("stake-account") - .validator(is_pubkey) - .value_name("ADDRESS") - .takes_value(true) - .required(true) - .help("Stake account address to change staking authority."), - ) - .arg( - Arg::with_name("new_staker") - .long("new-staker") - .validator(is_pubkey) - .value_name("ADDRESS") - .takes_value(true) - .required(true) - .help("Public key of the new staker account."), - ) - ) .subcommand(SubCommand::with_name("set-owner").about("Changes owner or fee receiver account for the stake pool.") .arg( Arg::with_name("pool") @@ -1470,12 +1403,6 @@ fn main() { &stake_receiver, ) } - ("set-staking-auth", Some(arg_matches)) => { - let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); - let stake_account: Pubkey = pubkey_of(arg_matches, "stake_account").unwrap(); - let new_staker: Pubkey = pubkey_of(arg_matches, "new_staker").unwrap(); - command_set_staking_auth(&config, &pool_account, &stake_account, &new_staker) - } ("set-owner", Some(arg_matches)) => { let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); let new_owner: Option = pubkey_of(arg_matches, "new_owner"); diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 427dad21..51f00816 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -140,17 +140,6 @@ pub enum StakePoolInstruction { /// userdata: amount to withdraw Withdraw(u64), - /// Update the staking pubkey for a stake - /// - /// 0. `[w]` StakePool - /// 1. `[s]` Owner - /// 2. `[]` withdraw authority - /// 3. `[w]` Stake to update the staking pubkey - /// 4. '[]` Staking pubkey. - /// 5. '[]' Sysvar clock account (reserved for future use) - /// 6. `[]` Stake program id, - SetStakingAuthority, - /// Update owner /// /// 0. `[w]` StakePool @@ -182,8 +171,7 @@ impl StakePoolInstruction { let val: &u64 = unpack(input)?; Self::Withdraw(*val) } - 8 => Self::SetStakingAuthority, - 9 => Self::SetOwner, + 8 => Self::SetOwner, _ => return Err(ProgramError::InvalidAccountData), }) } @@ -223,11 +211,8 @@ impl StakePoolInstruction { let value = unsafe { &mut *(&mut output[1] as *mut u8 as *mut u64) }; *value = *val; } - Self::SetStakingAuthority => { - output[0] = 8; - } Self::SetOwner => { - output[0] = 9; + output[0] = 8; } } Ok(output) @@ -486,34 +471,6 @@ pub fn withdraw( }) } -/// Creates a 'set staking authority' instruction. -pub fn set_staking_authority( - program_id: &Pubkey, - stake_pool: &Pubkey, - stake_pool_owner: &Pubkey, - stake_pool_withdraw: &Pubkey, - stake_account_to_update: &Pubkey, - stake_account_new_authority: &Pubkey, - stake_program_id: &Pubkey, -) -> Result { - let args = StakePoolInstruction::SetStakingAuthority; - let data = args.serialize()?; - let accounts = vec![ - AccountMeta::new(*stake_pool, false), - AccountMeta::new_readonly(*stake_pool_owner, true), - AccountMeta::new_readonly(*stake_pool_withdraw, false), - AccountMeta::new(*stake_account_to_update, false), - AccountMeta::new_readonly(*stake_account_new_authority, false), - AccountMeta::new_readonly(sysvar::clock::id(), false), - AccountMeta::new_readonly(*stake_program_id, false), - ]; - Ok(Instruction { - program_id: *program_id, - accounts, - data, - }) -} - /// Creates a 'set owner' instruction. pub fn set_owner( program_id: &Pubkey, diff --git a/program/src/processor.rs b/program/src/processor.rs index 7b12d900..1245f910 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1147,51 +1147,6 @@ impl Processor { Ok(()) } - /// Processes [SetStakeAuthority](enum.Instruction.html). - pub fn process_set_staking_auth( - program_id: &Pubkey, - accounts: &[AccountInfo], - ) -> ProgramResult { - let account_info_iter = &mut accounts.iter(); - let stake_pool_info = next_account_info(account_info_iter)?; - let owner_info = next_account_info(account_info_iter)?; - let withdraw_info = next_account_info(account_info_iter)?; - let stake_info = next_account_info(account_info_iter)?; - let staker_info = next_account_info(account_info_iter)?; - // (Reserved) - let reserved = next_account_info(account_info_iter)?; - // Stake program id - let stake_program_info = next_account_info(account_info_iter)?; - - // Check program ids - if *stake_program_info.key != stake::id() { - return Err(ProgramError::IncorrectProgramId); - } - - let stake_pool = StakePool::deserialize(&stake_pool_info.data.borrow())?; - if !stake_pool.is_initialized() { - return Err(StakePoolError::InvalidState.into()); - } - - // Check authority account - stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?; - - // Check owner validity and signature - stake_pool.check_owner(owner_info)?; - - Self::stake_authorize( - stake_pool_info.key, - stake_info.clone(), - withdraw_info.clone(), - Self::AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, - staker_info.key, - stake::StakeAuthorize::Staker, - reserved.clone(), - stake_program_info.clone(), - )?; - Ok(()) - } /// Processes [SetOwner](enum.Instruction.html). pub fn process_set_owner(_program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { @@ -1257,10 +1212,6 @@ impl Processor { msg!("Instruction: Withdraw"); Self::process_withdraw(program_id, amount, accounts) } - StakePoolInstruction::SetStakingAuthority => { - msg!("Instruction: SetStakingAuthority"); - Self::process_set_staking_auth(program_id, accounts) - } StakePoolInstruction::SetOwner => { msg!("Instruction: SetOwner"); Self::process_set_owner(program_id, accounts) diff --git a/program/tests/set_staking_authority.rs b/program/tests/set_staking_authority.rs deleted file mode 100644 index d0805284..00000000 --- a/program/tests/set_staking_authority.rs +++ /dev/null @@ -1,273 +0,0 @@ -#![cfg(feature = "test-bpf")] - -mod helpers; - -use bincode::deserialize; -use helpers::*; -use solana_program::hash::Hash; -use solana_program::instruction::AccountMeta; -use solana_program::instruction::Instruction; -use solana_program::sysvar; -use solana_program_test::*; -use solana_sdk::{ - instruction::InstructionError, signature::Keypair, signature::Signer, transaction::Transaction, - transaction::TransactionError, transport::TransportError, -}; -use spl_stake_pool::*; - -async fn setup() -> ( - BanksClient, - Keypair, - Hash, - StakePoolAccounts, - ValidatorStakeAccount, -) { - let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); - stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) - .await - .unwrap(); - - let user = Keypair::new(); - - let user_stake = ValidatorStakeAccount::new_with_target_authority( - &stake_pool_accounts.deposit_authority, - &stake_pool_accounts.stake_pool.pubkey(), - ); - user_stake - .create_and_delegate(&mut banks_client, &payer, &recent_blockhash) - .await; - - // make pool token account - let user_pool_account = Keypair::new(); - create_token_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_pool_account, - &stake_pool_accounts.pool_mint.pubkey(), - &user.pubkey(), - ) - .await - .unwrap(); - - let error = stake_pool_accounts - .add_validator_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake.stake_account, - &user_pool_account.pubkey(), - ) - .await; - assert!(error.is_none()); - - ( - banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - user_stake, - ) -} - -#[tokio::test] -async fn test_set_staking_authority() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = - setup().await; - - let new_staking_pubkey = Keypair::new().pubkey(); - - let mut transaction = Transaction::new_with_payer( - &[instruction::set_staking_authority( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.owner.pubkey(), - &stake_pool_accounts.withdraw_authority, - &user_stake.stake_account, - &new_staking_pubkey, - &stake::id(), - ) - .unwrap()], - Some(&payer.pubkey()), - ); - transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); - banks_client.process_transaction(transaction).await.unwrap(); - - // Check of stake account authority has changed - let stake = get_account(&mut banks_client, &user_stake.stake_account).await; - let stake_state = deserialize::(&stake.data).unwrap(); - match stake_state { - stake::StakeState::Stake(meta, _) => { - assert_eq!(&meta.authorized.staker, &new_staking_pubkey); - assert_eq!( - &meta.authorized.withdrawer, - &stake_pool_accounts.withdraw_authority - ); - } - _ => panic!(), - } -} - -#[tokio::test] -async fn test_set_staking_authority_with_wrong_stake_program_id() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = - setup().await; - - let new_staking_pubkey = Keypair::new().pubkey(); - - let mut transaction = Transaction::new_with_payer( - &[instruction::set_staking_authority( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.owner.pubkey(), - &stake_pool_accounts.withdraw_authority, - &user_stake.stake_account, - &new_staking_pubkey, - &Keypair::new().pubkey(), - ) - .unwrap()], - Some(&payer.pubkey()), - ); - transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); - let transaction_error = banks_client - .process_transaction(transaction) - .await - .err() - .unwrap(); - - match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { - assert_eq!(error, InstructionError::IncorrectProgramId); - } - _ => panic!( - "Wrong error occurs while try to set staking authority with wrong stake program ID" - ), - } -} - -#[tokio::test] -async fn test_set_staking_authority_with_wrong_withdraw_authority() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = - setup().await; - - let new_staking_pubkey = Keypair::new().pubkey(); - - let mut transaction = Transaction::new_with_payer( - &[instruction::set_staking_authority( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.owner.pubkey(), - &Keypair::new().pubkey(), - &user_stake.stake_account, - &new_staking_pubkey, - &stake::id(), - ) - .unwrap()], - Some(&payer.pubkey()), - ); - transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); - let transaction_error = banks_client - .process_transaction(transaction) - .await - .err() - .unwrap(); - - match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError( - _, - InstructionError::Custom(error_index), - )) => { - let program_error = error::StakePoolError::InvalidProgramAddress as u32; - assert_eq!(error_index, program_error); - } - _ => panic!( - "Wrong error occurs while try to set staking authority with wrong withdraw authority" - ), - } -} - -#[tokio::test] -async fn test_set_staking_authority_with_wrong_owner() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = - setup().await; - - let new_staking_pubkey = Keypair::new().pubkey(); - let wrong_owner = Keypair::new(); - - let mut transaction = Transaction::new_with_payer( - &[instruction::set_staking_authority( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &wrong_owner.pubkey(), - &stake_pool_accounts.withdraw_authority, - &user_stake.stake_account, - &new_staking_pubkey, - &stake::id(), - ) - .unwrap()], - Some(&payer.pubkey()), - ); - transaction.sign(&[&payer, &wrong_owner], recent_blockhash); - let transaction_error = banks_client - .process_transaction(transaction) - .await - .err() - .unwrap(); - - match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError( - _, - InstructionError::Custom(error_index), - )) => { - let program_error = error::StakePoolError::WrongOwner as u32; - assert_eq!(error_index, program_error); - } - _ => panic!("Wrong error occurs while try to set staking authority with wrong owner"), - } -} - -#[tokio::test] -async fn test_set_staking_authority_without_signature() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = - setup().await; - - let new_staking_pubkey = Keypair::new().pubkey(); - - let args = instruction::StakePoolInstruction::SetStakingAuthority; - let data = args.serialize().unwrap(); - let accounts = vec![ - AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), - AccountMeta::new_readonly(stake_pool_accounts.owner.pubkey(), false), - AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false), - AccountMeta::new(user_stake.stake_account, false), - AccountMeta::new_readonly(new_staking_pubkey, false), - AccountMeta::new_readonly(sysvar::clock::id(), false), - AccountMeta::new_readonly(stake::id(), false), - ]; - let instruction = Instruction { - program_id: id(), - accounts, - data, - }; - - let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); - transaction.sign(&[&payer], recent_blockhash); - let transaction_error = banks_client - .process_transaction(transaction) - .await - .err() - .unwrap(); - - match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError( - _, - InstructionError::Custom(error_index), - )) => { - let program_error = error::StakePoolError::SignatureMissing as u32; - assert_eq!(error_index, program_error); - } - _ => panic!("Wrong error occurs while try to set staking authority without signature"), - } -} From eb09cc753f0216f911d46b206c058a60b79afdc5 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 23 Mar 2021 00:33:51 +0100 Subject: [PATCH 0061/1076] stake-pool: Use checked_ceil_div for withdraw calc (#1482) * stake-pool: Use checked_ceil_div for withdraw calc When a stake account is totally removed from a stake pool by the manager, there's a chance that the operation would not take enough of the manager's pool tokens by 1 due to truncation. Do a ceiling division instead, and refactor ceiling division into the math library. * Use new function name on CLI * Cargo fmt --- clients/cli/src/main.rs | 4 ++-- program/Cargo.toml | 1 + program/src/processor.rs | 2 +- program/src/state.rs | 16 ++++++++++------ 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index eadaff56..1e716f51 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -777,7 +777,7 @@ fn pick_withdraw_accounts( continue; } let available_for_withdrawal = stake_pool - .calc_lamports_amount(account.lamports - *MIN_STAKE_BALANCE) + .calc_lamports_withdraw_amount(account.lamports - *MIN_STAKE_BALANCE) .unwrap(); let withdraw_amount = u64::min(available_for_withdrawal, remaining_amount); @@ -878,7 +878,7 @@ fn command_withdraw( for withdraw_stake in withdraw_accounts { // Convert pool tokens amount to lamports let sol_withdraw_amount = pool_data - .calc_lamports_amount(withdraw_stake.pool_amount) + .calc_lamports_withdraw_amount(withdraw_stake.pool_amount) .unwrap(); println!( diff --git a/program/Cargo.toml b/program/Cargo.toml index 9b71e396..974bb885 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -19,6 +19,7 @@ num_enum = "0.5.1" serde = "1.0.121" serde_derive = "1.0.103" solana-program = "1.6.1" +spl-math = { path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-token = { path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" bincode = "1.3.1" diff --git a/program/src/processor.rs b/program/src/processor.rs index 1245f910..6f7fa63a 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1090,7 +1090,7 @@ impl Processor { .ok_or(StakePoolError::ValidatorNotFound)?; let stake_amount = stake_pool - .calc_lamports_amount(pool_amount) + .calc_lamports_withdraw_amount(pool_amount) .ok_or(StakePoolError::CalculationFailure)?; Self::stake_split( diff --git a/program/src/state.rs b/program/src/state.rs index f96493bf..0b935041 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -6,6 +6,7 @@ use { account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, pubkey::Pubkey, }, + spl_math::checked_ceil_div::CheckedCeilDiv, std::convert::{TryFrom, TryInto}, std::mem::size_of, }; @@ -50,10 +51,6 @@ impl StakePool { if self.stake_total == 0 { return Some(stake_lamports); } - self.calc_pool_withdraw_amount(stake_lamports) - } - /// calculate the pool tokens that should be withdrawn - pub fn calc_pool_withdraw_amount(&self, stake_lamports: u64) -> Option { u64::try_from( (stake_lamports as u128) .checked_mul(self.pool_total as u128)? @@ -61,8 +58,15 @@ impl StakePool { ) .ok() } - /// calculate lamports amount - pub fn calc_lamports_amount(&self, pool_tokens: u64) -> Option { + /// calculate the pool tokens that should be withdrawn + pub fn calc_pool_withdraw_amount(&self, stake_lamports: u64) -> Option { + let (quotient, _) = (stake_lamports as u128) + .checked_mul(self.pool_total as u128)? + .checked_ceil_div(self.stake_total as u128)?; + u64::try_from(quotient).ok() + } + /// calculate lamports amount on withdrawal + pub fn calc_lamports_withdraw_amount(&self, pool_tokens: u64) -> Option { u64::try_from( (pool_tokens as u128) .checked_mul(self.stake_total as u128)? From 10445f7acda6dc79d8582b2d924611f844d8b5ba Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Sat, 27 Mar 2021 13:42:29 +0100 Subject: [PATCH 0062/1076] stake-pool: Add borsh support and specify size on creation (#1505) * lending: Update JS tests to solana-test-validator * Add solana tools install * Fix oopsie on the path * Move where deployed programs go * stake-pool: Add borsh support and size on creation We can't specify the size in the instruction unfortunately, since we'd only have 10kb max for the validator list. At roughly 50 bytes per validator, that only gives us 200 validators. On the flip side, using Borsh means we can allow the validator stake list to be any size! * Add AccountType enum * Remove V1 everywhere * Add max validators as parameter and get_instance_packed_len * Add test for adding too many validators * Clippy --- clients/cli/Cargo.toml | 1 + clients/cli/src/main.rs | 143 ++++++++------- program/Cargo.toml | 4 +- program/src/borsh.rs | 39 +++++ program/src/error.rs | 12 +- program/src/instruction.rs | 138 +++------------ program/src/lib.rs | 4 +- program/src/processor.rs | 200 ++++++++++++--------- program/src/state.rs | 239 ++++++++++--------------- program/tests/deposit.rs | 36 ++-- program/tests/helpers/mod.rs | 43 +++-- program/tests/initialize.rs | 253 ++++++++++++++++++--------- program/tests/set_owner.rs | 29 +-- program/tests/update_list_balance.rs | 5 +- program/tests/update_pool_balance.rs | 14 +- program/tests/vsa_add.rs | 108 ++++++++++-- program/tests/vsa_remove.rs | 41 +++-- program/tests/withdraw.rs | 37 ++-- 18 files changed, 746 insertions(+), 600 deletions(-) create mode 100644 program/src/borsh.rs diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index d5c6176b..80a26612 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -9,6 +9,7 @@ repository = "https://github.com/solana-labs/solana-program-library" version = "2.0.1" [dependencies] +borsh = "0.8" clap = "2.33.3" serde_json = "1.0.62" solana-account-decoder = "1.6.1" diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 1e716f51..6b1bc590 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -1,52 +1,58 @@ #[macro_use] extern crate lazy_static; -use bincode::deserialize; -use clap::{ - crate_description, crate_name, crate_version, value_t, value_t_or_exit, App, AppSettings, Arg, - ArgGroup, SubCommand, -}; -use solana_account_decoder::UiAccountEncoding; -use solana_clap_utils::{ - input_parsers::pubkey_of, - input_validators::{is_amount, is_keypair, is_parsable, is_pubkey, is_url}, - keypair::signer_from_path, -}; -use solana_client::{ - rpc_client::RpcClient, - rpc_config::RpcAccountInfoConfig, - rpc_config::RpcProgramAccountsConfig, - rpc_filter::{Memcmp, MemcmpEncodedBytes, RpcFilterType}, -}; -use solana_program::{instruction::Instruction, program_pack::Pack, pubkey::Pubkey}; -use solana_sdk::{ - account::Account, - commitment_config::CommitmentConfig, - native_token::{self, Sol}, - signature::{Keypair, Signer}, - system_instruction, - transaction::Transaction, -}; -use spl_stake_pool::{ - instruction::{ - add_validator_stake_account, create_validator_stake_account, deposit, - initialize as initialize_pool, remove_validator_stake_account, set_owner, - update_list_balance, update_pool_balance, withdraw, Fee as PoolFee, - InitArgs as PoolInitArgs, + +use { + bincode::deserialize, + borsh::BorshDeserialize, + clap::{ + crate_description, crate_name, crate_version, value_t, value_t_or_exit, App, AppSettings, + Arg, ArgGroup, SubCommand, }, - processor::Processor as PoolProcessor, - stake::authorize as authorize_stake, - stake::id as stake_program_id, - stake::StakeAuthorize, - stake::StakeState, - state::StakePool, - state::ValidatorStakeList, -}; -use spl_token::{ - self, instruction::approve as approve_token, instruction::initialize_account, - instruction::initialize_mint, native_mint, state::Account as TokenAccount, - state::Mint as TokenMint, + solana_account_decoder::UiAccountEncoding, + solana_clap_utils::{ + input_parsers::pubkey_of, + input_validators::{is_amount, is_keypair, is_parsable, is_pubkey, is_url}, + keypair::signer_from_path, + }, + solana_client::{ + rpc_client::RpcClient, + rpc_config::RpcAccountInfoConfig, + rpc_config::RpcProgramAccountsConfig, + rpc_filter::{Memcmp, MemcmpEncodedBytes, RpcFilterType}, + }, + solana_program::{ + borsh::get_packed_len, instruction::Instruction, program_pack::Pack, pubkey::Pubkey, + }, + solana_sdk::{ + account::Account, + commitment_config::CommitmentConfig, + native_token::{self, Sol}, + signature::{Keypair, Signer}, + system_instruction, + transaction::Transaction, + }, + spl_stake_pool::{ + borsh::{get_instance_packed_len, try_from_slice_unchecked}, + instruction::{ + add_validator_stake_account, create_validator_stake_account, deposit, + initialize as initialize_pool, remove_validator_stake_account, set_owner, + update_list_balance, update_pool_balance, withdraw, Fee as PoolFee, + }, + processor::Processor as PoolProcessor, + stake::authorize as authorize_stake, + stake::id as stake_program_id, + stake::StakeAuthorize, + stake::StakeState, + state::StakePool, + state::ValidatorStakeList, + }, + spl_token::{ + self, instruction::approve as approve_token, instruction::initialize_account, + instruction::initialize_mint, native_mint, state::Account as TokenAccount, + state::Mint as TokenMint, + }, + std::process::exit, }; -use std::process::exit; struct Config { rpc_client: RpcClient, @@ -109,7 +115,7 @@ fn get_authority_accounts(config: &Config, authority: &Pubkey) -> Vec<(Pubkey, A .unwrap() } -fn command_create_pool(config: &Config, fee: PoolFee) -> CommandResult { +fn command_create_pool(config: &Config, fee: PoolFee, max_validators: u32) -> CommandResult { let mint_account = Keypair::new(); println!("Creating mint {}", mint_account.pubkey()); @@ -132,10 +138,12 @@ fn command_create_pool(config: &Config, fee: PoolFee) -> CommandResult { .get_minimum_balance_for_rent_exemption(TokenAccount::LEN)?; let pool_account_balance = config .rpc_client - .get_minimum_balance_for_rent_exemption(StakePool::LEN)?; + .get_minimum_balance_for_rent_exemption(get_packed_len::())?; + let empty_validator_list = ValidatorStakeList::new_with_max_validators(max_validators); + let validator_stake_list_size = get_instance_packed_len(&empty_validator_list)?; let validator_stake_list_balance = config .rpc_client - .get_minimum_balance_for_rent_exemption(ValidatorStakeList::LEN)?; + .get_minimum_balance_for_rent_exemption(validator_stake_list_size)?; let total_rent_free_balances = mint_account_balance + pool_fee_account_balance + pool_account_balance @@ -177,7 +185,7 @@ fn command_create_pool(config: &Config, fee: PoolFee) -> CommandResult { &config.fee_payer.pubkey(), &pool_account.pubkey(), pool_account_balance, - StakePool::LEN as u64, + get_packed_len::() as u64, &spl_stake_pool::id(), ), // Validator stake account list storage @@ -185,7 +193,7 @@ fn command_create_pool(config: &Config, fee: PoolFee) -> CommandResult { &config.fee_payer.pubkey(), &validator_stake_list.pubkey(), validator_stake_list_balance, - ValidatorStakeList::LEN as u64, + validator_stake_list_size as u64, &spl_stake_pool::id(), ), // Initialize pool token mint account @@ -212,7 +220,8 @@ fn command_create_pool(config: &Config, fee: PoolFee) -> CommandResult { &mint_account.pubkey(), &pool_fee_account.pubkey(), &spl_token::id(), - PoolInitArgs { fee }, + fee, + max_validators, )?, ], Some(&config.fee_payer.pubkey()), @@ -274,7 +283,7 @@ fn command_vsa_add( ) -> CommandResult { // Get stake pool state let pool_data = config.rpc_client.get_account_data(&pool)?; - let pool_data: StakePool = StakePool::deserialize(pool_data.as_slice()).unwrap(); + let pool_data = StakePool::try_from_slice(pool_data.as_slice()).unwrap(); let mut total_rent_free_balances: u64 = 0; @@ -365,7 +374,7 @@ fn command_vsa_remove( ) -> CommandResult { // Get stake pool state let pool_data = config.rpc_client.get_account_data(&pool)?; - let pool_data: StakePool = StakePool::deserialize(pool_data.as_slice()).unwrap(); + let pool_data: StakePool = StakePool::try_from_slice(pool_data.as_slice()).unwrap(); let pool_withdraw_authority: Pubkey = PoolProcessor::authority_id( &spl_stake_pool::id(), @@ -495,7 +504,7 @@ fn command_deposit( ) -> CommandResult { // Get stake pool state let pool_data = config.rpc_client.get_account_data(&pool)?; - let pool_data: StakePool = StakePool::deserialize(pool_data.as_slice()).unwrap(); + let pool_data: StakePool = StakePool::try_from_slice(pool_data.as_slice()).unwrap(); // Get stake account data let stake_data = config.rpc_client.get_account_data(&stake)?; @@ -514,7 +523,7 @@ fn command_deposit( .rpc_client .get_account_data(&pool_data.validator_stake_list)?; let validator_stake_list_data = - ValidatorStakeList::deserialize(&validator_stake_list_data.as_slice())?; + try_from_slice_unchecked::(&validator_stake_list_data.as_slice())?; if !validator_stake_list_data.contains(&validator) { return Err("Stake account for this validator does not exist in the pool.".into()); } @@ -617,14 +626,14 @@ fn command_deposit( fn command_list(config: &Config, pool: &Pubkey) -> CommandResult { // Get stake pool state let pool_data = config.rpc_client.get_account_data(&pool)?; - let pool_data = StakePool::deserialize(pool_data.as_slice()).unwrap(); + let pool_data = StakePool::try_from_slice(pool_data.as_slice()).unwrap(); if config.verbose { let validator_list = config .rpc_client .get_account_data(&pool_data.validator_stake_list)?; let validator_stake_list_data = - ValidatorStakeList::deserialize(&validator_list.as_slice())?; + try_from_slice_unchecked::(&validator_list.as_slice())?; println!("Current validator list"); for validator in validator_stake_list_data.validators { println!( @@ -669,12 +678,12 @@ fn command_list(config: &Config, pool: &Pubkey) -> CommandResult { fn command_update(config: &Config, pool: &Pubkey) -> CommandResult { // Get stake pool state let pool_data = config.rpc_client.get_account_data(&pool)?; - let pool_data = StakePool::deserialize(pool_data.as_slice()).unwrap(); + let pool_data = StakePool::try_from_slice(pool_data.as_slice()).unwrap(); let validator_stake_list_data = config .rpc_client .get_account_data(&pool_data.validator_stake_list)?; let validator_stake_list_data = - ValidatorStakeList::deserialize(&validator_stake_list_data.as_slice())?; + try_from_slice_unchecked::(&validator_stake_list_data.as_slice())?; let epoch_info = config.rpc_client.get_epoch_info()?; @@ -815,7 +824,7 @@ fn command_withdraw( ) -> CommandResult { // Get stake pool state let pool_data = config.rpc_client.get_account_data(&pool)?; - let pool_data = StakePool::deserialize(pool_data.as_slice()).unwrap(); + let pool_data = StakePool::try_from_slice(pool_data.as_slice()).unwrap(); let pool_mint_data = config.rpc_client.get_account_data(&pool_data.pool_mint)?; let pool_mint = TokenMint::unpack_from_slice(pool_mint_data.as_slice()).unwrap(); @@ -954,7 +963,7 @@ fn command_set_owner( new_fee_receiver: &Option, ) -> CommandResult { let pool_data = config.rpc_client.get_account_data(&pool)?; - let pool_data: StakePool = StakePool::deserialize(pool_data.as_slice()).unwrap(); + let pool_data: StakePool = StakePool::try_from_slice(pool_data.as_slice()).unwrap(); // If new accounts are missing in the arguments use the old ones let new_owner: Pubkey = match new_owner { @@ -1088,6 +1097,16 @@ fn main() { .required(true) .help("Fee denominator, fee amount is numerator divided by denominator."), ) + .arg( + Arg::with_name("max_validators") + .long("max-validators") + .short("m") + .validator(is_parsable::) + .value_name("NUMBER") + .takes_value(true) + .required(true) + .help("Max number of validators included in the stake pool"), + ) ) .subcommand(SubCommand::with_name("create-validator-stake").about("Create a new validator stake account to use with the pool") .arg( @@ -1344,12 +1363,14 @@ fn main() { ("create-pool", Some(arg_matches)) => { let numerator = value_t_or_exit!(arg_matches, "fee_numerator", u64); let denominator = value_t_or_exit!(arg_matches, "fee_denominator", u64); + let max_validators = value_t_or_exit!(arg_matches, "max_validators", u32); command_create_pool( &config, PoolFee { denominator, numerator, }, + max_validators, ) } ("create-validator-stake", Some(arg_matches)) => { diff --git a/program/Cargo.toml b/program/Cargo.toml index 974bb885..affab7f7 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -13,6 +13,7 @@ test-bpf = [] [dependencies] arrayref = "0.3.6" +borsh = "0.8" num-derive = "0.3" num-traits = "0.2" num_enum = "0.5.1" @@ -25,9 +26,10 @@ thiserror = "1.0" bincode = "1.3.1" [dev-dependencies] +proptest = "0.10" solana-program-test = "1.6.1" solana-sdk = "1.6.1" -solana-vote-program = "1.5.11" +solana-vote-program = "1.6.1" [lib] crate-type = ["cdylib", "lib"] diff --git a/program/src/borsh.rs b/program/src/borsh.rs new file mode 100644 index 00000000..75bd3758 --- /dev/null +++ b/program/src/borsh.rs @@ -0,0 +1,39 @@ +//! Extra borsh utils +//! TODO delete once try_from_slice_unchecked has been published + +use { + borsh::{maybestd::io::Error, BorshDeserialize, BorshSerialize}, + std::io::{Result as IoResult, Write}, +}; + +/// Deserializes something and allows for incomplete reading +pub fn try_from_slice_unchecked(data: &[u8]) -> Result { + let mut data_mut = data; + let result = T::deserialize(&mut data_mut)?; + Ok(result) +} + +/// Helper struct which to count how much data would be written during serialization +#[derive(Default)] +struct WriteCounter { + count: usize, +} + +impl Write for WriteCounter { + fn write(&mut self, data: &[u8]) -> IoResult { + let amount = data.len(); + self.count += amount; + Ok(amount) + } + + fn flush(&mut self) -> IoResult<()> { + Ok(()) + } +} + +/// Get the worst-case packed length for the given BorshSchema +pub fn get_instance_packed_len(instance: &T) -> Result { + let mut counter = WriteCounter::default(); + instance.serialize(&mut counter)?; + Ok(counter.count) +} diff --git a/program/src/error.rs b/program/src/error.rs index 7acc56a6..e1aa27ea 100644 --- a/program/src/error.rs +++ b/program/src/error.rs @@ -37,8 +37,6 @@ pub enum StakePoolError { /// Invalid validator stake list account. #[error("InvalidValidatorStakeList")] InvalidValidatorStakeList, - - // 10. /// Invalid owner fee account. #[error("InvalidFeeAccount")] InvalidFeeAccount, @@ -56,8 +54,6 @@ pub enum StakePoolError { /// Stake account voting for this validator already exists in the pool. #[error("ValidatorAlreadyAdded")] ValidatorAlreadyAdded, - - // 15. /// Stake account for this validator not found in the pool. #[error("ValidatorNotFound")] ValidatorNotFound, @@ -75,16 +71,14 @@ pub enum StakePoolError { /// Validator stake account is not found in the list storage. #[error("UnknownValidatorStakeAccount")] UnknownValidatorStakeAccount, - - // 20. /// Wrong minting authority set for mint pool account #[error("WrongMintingAuthority")] WrongMintingAuthority, // 20. - /// Account is not rent-exempt - #[error("AccountNotRentExempt")] - AccountNotRentExempt, + /// The size of the given validator stake list does match the expected amount + #[error("UnexpectedValidatorListAccountSize")] + UnexpectedValidatorListAccountSize, } impl From for ProgramError { fn from(e: StakePoolError) -> Self { diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 51f00816..40ff18ad 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -3,19 +3,18 @@ #![allow(clippy::too_many_arguments)] use { + borsh::{BorshDeserialize, BorshSchema, BorshSerialize}, solana_program::{ instruction::{AccountMeta, Instruction}, program_error::ProgramError, pubkey::Pubkey, sysvar, }, - std::mem::size_of, }; -/// Fee rate as a ratio -/// Fee is minted on deposit +/// Fee rate as a ratio, minted on deposit #[repr(C)] -#[derive(Clone, Copy, Debug, Default, PartialEq)] +#[derive(Clone, Copy, Debug, Default, PartialEq, BorshSerialize, BorshDeserialize, BorshSchema)] pub struct Fee { /// denominator of the fee ratio pub denominator: u64, @@ -23,17 +22,9 @@ pub struct Fee { pub numerator: u64, } -/// Inital values for the Stake Pool -#[repr(C)] -#[derive(Clone, Copy, Debug, Default, PartialEq)] -pub struct InitArgs { - /// Fee paid to the owner in pool tokens - pub fee: Fee, -} - /// Instructions supported by the StakePool program. #[repr(C)] -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, BorshSerialize, BorshDeserialize, BorshSchema)] pub enum StakePoolInstruction { /// Initializes a new StakePool. /// @@ -45,7 +36,14 @@ pub enum StakePoolInstruction { /// 5. `[]` Clock sysvar /// 6. `[]` Rent sysvar /// 7. `[]` Token program id - Initialize(InitArgs), + Initialize { + /// Deposit fee assessed + #[allow(dead_code)] // but it's not + fee: Fee, + /// Maximum expected number of validators + #[allow(dead_code)] // but it's not + max_validators: u32, + }, /// Creates new program account for accumulating stakes for a particular validator /// @@ -149,86 +147,6 @@ pub enum StakePoolInstruction { SetOwner, } -impl StakePoolInstruction { - /// Deserializes a byte buffer into an [StakePoolInstruction](enum.StakePoolInstruction.html). - /// TODO efficient unpacking here - pub fn deserialize(input: &[u8]) -> Result { - if input.len() < size_of::() { - return Err(ProgramError::InvalidAccountData); - } - Ok(match input[0] { - 0 => { - let val: &InitArgs = unpack(input)?; - Self::Initialize(*val) - } - 1 => Self::CreateValidatorStakeAccount, - 2 => Self::AddValidatorStakeAccount, - 3 => Self::RemoveValidatorStakeAccount, - 4 => Self::UpdateListBalance, - 5 => Self::UpdatePoolBalance, - 6 => Self::Deposit, - 7 => { - let val: &u64 = unpack(input)?; - Self::Withdraw(*val) - } - 8 => Self::SetOwner, - _ => return Err(ProgramError::InvalidAccountData), - }) - } - - /// Serializes an [StakePoolInstruction](enum.StakePoolInstruction.html) into a byte buffer. - /// TODO efficient packing here - pub fn serialize(&self) -> Result, ProgramError> { - let mut output = vec![0u8; size_of::()]; - match self { - Self::Initialize(init) => { - output[0] = 0; - #[allow(clippy::cast_ptr_alignment)] - let value = unsafe { &mut *(&mut output[1] as *mut u8 as *mut InitArgs) }; - *value = *init; - } - Self::CreateValidatorStakeAccount => { - output[0] = 1; - } - Self::AddValidatorStakeAccount => { - output[0] = 2; - } - Self::RemoveValidatorStakeAccount => { - output[0] = 3; - } - Self::UpdateListBalance => { - output[0] = 4; - } - Self::UpdatePoolBalance => { - output[0] = 5; - } - Self::Deposit => { - output[0] = 6; - } - Self::Withdraw(val) => { - output[0] = 7; - #[allow(clippy::cast_ptr_alignment)] - let value = unsafe { &mut *(&mut output[1] as *mut u8 as *mut u64) }; - *value = *val; - } - Self::SetOwner => { - output[0] = 8; - } - } - Ok(output) - } -} - -/// Unpacks a reference from a bytes buffer. -pub fn unpack(input: &[u8]) -> Result<&T, ProgramError> { - if input.len() < size_of::() + size_of::() { - return Err(ProgramError::InvalidAccountData); - } - #[allow(clippy::cast_ptr_alignment)] - let val: &T = unsafe { &*(&input[1] as *const u8 as *const T) }; - Ok(val) -} - /// Creates an 'initialize' instruction. pub fn initialize( program_id: &Pubkey, @@ -238,10 +156,14 @@ pub fn initialize( pool_mint: &Pubkey, owner_pool_account: &Pubkey, token_program_id: &Pubkey, - init_args: InitArgs, + fee: Fee, + max_validators: u32, ) -> Result { - let init_data = StakePoolInstruction::Initialize(init_args); - let data = init_data.serialize()?; + let init_data = StakePoolInstruction::Initialize { + fee, + max_validators, + }; + let data = init_data.try_to_vec()?; let accounts = vec![ AccountMeta::new(*stake_pool, true), AccountMeta::new_readonly(*owner, true), @@ -285,7 +207,7 @@ pub fn create_validator_stake_account( Ok(Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::CreateValidatorStakeAccount.serialize()?, + data: StakePoolInstruction::CreateValidatorStakeAccount.try_to_vec()?, }) } @@ -320,7 +242,7 @@ pub fn add_validator_stake_account( Ok(Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::AddValidatorStakeAccount.serialize()?, + data: StakePoolInstruction::AddValidatorStakeAccount.try_to_vec()?, }) } @@ -354,7 +276,7 @@ pub fn remove_validator_stake_account( Ok(Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::RemoveValidatorStakeAccount.serialize()?, + data: StakePoolInstruction::RemoveValidatorStakeAccount.try_to_vec()?, }) } @@ -373,7 +295,7 @@ pub fn update_list_balance( Ok(Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::UpdateListBalance.serialize()?, + data: StakePoolInstruction::UpdateListBalance.try_to_vec()?, }) } @@ -391,7 +313,7 @@ pub fn update_pool_balance( Ok(Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::UpdatePoolBalance.serialize()?, + data: StakePoolInstruction::UpdatePoolBalance.try_to_vec()?, }) } @@ -410,8 +332,6 @@ pub fn deposit( token_program_id: &Pubkey, stake_program_id: &Pubkey, ) -> Result { - let args = StakePoolInstruction::Deposit; - let data = args.serialize()?; let accounts = vec![ AccountMeta::new(*stake_pool, false), AccountMeta::new(*validator_stake_list_storage, false), @@ -430,7 +350,7 @@ pub fn deposit( Ok(Instruction { program_id: *program_id, accounts, - data, + data: StakePoolInstruction::Deposit.try_to_vec()?, }) } @@ -449,8 +369,6 @@ pub fn withdraw( stake_program_id: &Pubkey, amount: u64, ) -> Result { - let args = StakePoolInstruction::Withdraw(amount); - let data = args.serialize()?; let accounts = vec![ AccountMeta::new(*stake_pool, false), AccountMeta::new(*validator_stake_list_storage, false), @@ -467,7 +385,7 @@ pub fn withdraw( Ok(Instruction { program_id: *program_id, accounts, - data, + data: StakePoolInstruction::Withdraw(amount).try_to_vec()?, }) } @@ -479,8 +397,6 @@ pub fn set_owner( stake_pool_new_owner: &Pubkey, stake_pool_new_fee_receiver: &Pubkey, ) -> Result { - let args = StakePoolInstruction::SetOwner; - let data = args.serialize()?; let accounts = vec![ AccountMeta::new(*stake_pool, false), AccountMeta::new_readonly(*stake_pool_owner, true), @@ -490,6 +406,6 @@ pub fn set_owner( Ok(Instruction { program_id: *program_id, accounts, - data, + data: StakePoolInstruction::SetOwner.try_to_vec()?, }) } diff --git a/program/src/lib.rs b/program/src/lib.rs index 61a2a883..fa7364cc 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -2,15 +2,13 @@ //! A program for creating pools of Solana stakes managed by a Stake-o-Matic +pub mod borsh; pub mod error; pub mod instruction; pub mod processor; pub mod stake; pub mod state; -/// Current program version -pub const PROGRAM_VERSION: u8 = 1; - #[cfg(not(feature = "no-entrypoint"))] pub mod entrypoint; diff --git a/program/src/processor.rs b/program/src/processor.rs index 6f7fa63a..ee1140a6 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1,33 +1,36 @@ //! Program state processor -use crate::{ - error::StakePoolError, - instruction::{InitArgs, StakePoolInstruction}, - stake, - state::{StakePool, ValidatorStakeInfo, ValidatorStakeList}, - PROGRAM_VERSION, +use { + crate::{ + borsh::try_from_slice_unchecked, + error::StakePoolError, + instruction::{Fee, StakePoolInstruction}, + stake, + state::{AccountType, StakePool, ValidatorStakeInfo, ValidatorStakeList}, + }, + bincode::deserialize, + borsh::{BorshDeserialize, BorshSerialize}, + num_traits::FromPrimitive, + solana_program::{ + account_info::next_account_info, + account_info::AccountInfo, + clock::Clock, + decode_error::DecodeError, + entrypoint::ProgramResult, + msg, + native_token::sol_to_lamports, + program::{invoke, invoke_signed}, + program_error::PrintProgramError, + program_error::ProgramError, + program_pack::Pack, + pubkey::Pubkey, + rent::Rent, + stake_history::StakeHistory, + system_instruction, + sysvar::Sysvar, + }, + spl_token::state::Mint, }; -use bincode::deserialize; -use num_traits::FromPrimitive; -use solana_program::{ - account_info::next_account_info, - account_info::AccountInfo, - clock::Clock, - decode_error::DecodeError, - entrypoint::ProgramResult, - msg, - native_token::sol_to_lamports, - program::{invoke, invoke_signed}, - program_error::PrintProgramError, - program_error::ProgramError, - program_pack::Pack, - pubkey::Pubkey, - rent::Rent, - stake_history::StakeHistory, - system_instruction, - sysvar::Sysvar, -}; -use spl_token::state::Mint; /// Program state handler. pub struct Processor {} @@ -271,8 +274,9 @@ impl Processor { /// Processes `Initialize` instruction. pub fn process_initialize( program_id: &Pubkey, - init: InitArgs, accounts: &[AccountInfo], + fee: Fee, + max_validators: u32, ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; @@ -294,24 +298,33 @@ impl Processor { return Err(StakePoolError::SignatureMissing.into()); } - let mut stake_pool = StakePool::deserialize(&stake_pool_info.data.borrow())?; + let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; // Stake pool account should not be already initialized - if stake_pool.is_initialized() { + if !stake_pool.is_uninitialized() { return Err(StakePoolError::AlreadyInUse.into()); } // Check if validator stake list storage is unitialized - let mut validator_stake_list = - ValidatorStakeList::deserialize(&validator_stake_list_info.data.borrow())?; - if validator_stake_list.is_initialized() { + let mut validator_stake_list = try_from_slice_unchecked::( + &validator_stake_list_info.data.borrow(), + )?; + if !validator_stake_list.is_uninitialized() { return Err(StakePoolError::AlreadyInUse.into()); } - validator_stake_list.version = ValidatorStakeList::VALIDATOR_STAKE_LIST_VERSION; + // Check validator list size + let data_length = validator_stake_list_info.data_len(); + let expected_max_validators = ValidatorStakeList::calculate_max_validators(data_length); + if expected_max_validators != max_validators as usize || max_validators == 0 { + return Err(StakePoolError::UnexpectedValidatorListAccountSize.into()); + } + validator_stake_list.account_type = AccountType::ValidatorStakeList; validator_stake_list.validators.clear(); + validator_stake_list.max_validators = max_validators; // Check if stake pool account is rent-exempt if !rent.is_exempt(stake_pool_info.lamports(), stake_pool_info.data_len()) { - return Err(StakePoolError::AccountNotRentExempt.into()); + msg!("Stake pool not rent-exempt"); + return Err(ProgramError::AccountNotRentExempt); } // Check if validator stake list account is rent-exempt @@ -319,11 +332,12 @@ impl Processor { validator_stake_list_info.lamports(), validator_stake_list_info.data_len(), ) { - return Err(StakePoolError::AccountNotRentExempt.into()); + msg!("Validator stake list not rent-exempt"); + return Err(ProgramError::AccountNotRentExempt); } // Numerator should be smaller than or equal to denominator (fee <= 1) - if init.fee.numerator > init.fee.denominator { + if fee.numerator > fee.denominator { return Err(StakePoolError::FeeTooHigh.into()); } @@ -361,12 +375,12 @@ impl Processor { return Err(StakePoolError::WrongMintingAuthority.into()); } - validator_stake_list.serialize(&mut validator_stake_list_info.data.borrow_mut())?; + validator_stake_list.serialize(&mut *validator_stake_list_info.data.borrow_mut())?; msg!("Clock data: {:?}", clock_info.data.borrow()); msg!("Epoch: {}", clock.epoch); - stake_pool.version = PROGRAM_VERSION; + stake_pool.account_type = AccountType::StakePool; stake_pool.owner = *owner_info.key; stake_pool.deposit_bump_seed = deposit_bump_seed; stake_pool.withdraw_bump_seed = withdraw_bump_seed; @@ -375,9 +389,11 @@ impl Processor { stake_pool.owner_fee_account = *owner_fee_info.key; stake_pool.token_program_id = *token_program_info.key; stake_pool.last_update_epoch = clock.epoch; - stake_pool.fee = init.fee; + stake_pool.fee = fee; - stake_pool.serialize(&mut stake_pool_info.data.borrow_mut()) + stake_pool + .serialize(&mut *stake_pool_info.data.borrow_mut()) + .map_err(|e| e.into()) } /// Processes `CreateValidatorStakeAccount` instruction. @@ -503,8 +519,8 @@ impl Processor { } // Get stake pool stake (and check if it is initialized) - let mut stake_pool = StakePool::deserialize(&stake_pool_info.data.borrow())?; - if !stake_pool.is_initialized() { + let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; + if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); } @@ -533,11 +549,15 @@ impl Processor { } // Read validator stake list account and check if it is valid - let mut validator_stake_list = - ValidatorStakeList::deserialize(&validator_stake_list_info.data.borrow())?; - if !validator_stake_list.is_initialized() { + let mut validator_stake_list = try_from_slice_unchecked::( + &validator_stake_list_info.data.borrow(), + )?; + if !validator_stake_list.is_valid() { return Err(StakePoolError::InvalidState.into()); } + if validator_stake_list.max_validators as usize == validator_stake_list.validators.len() { + return Err(ProgramError::AccountDataTooSmall); + } let validator_account = Self::get_validator_checked(program_id, stake_pool_info, stake_account_info)?; @@ -589,13 +609,13 @@ impl Processor { balance: stake_lamports, last_update_epoch: clock.epoch, }); - validator_stake_list.serialize(&mut validator_stake_list_info.data.borrow_mut())?; + validator_stake_list.serialize(&mut *validator_stake_list_info.data.borrow_mut())?; // Save amounts to the stake pool state stake_pool.pool_total += token_amount; // Only update stake total if the last state update epoch is current stake_pool.stake_total += stake_lamports; - stake_pool.serialize(&mut stake_pool_info.data.borrow_mut())?; + stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; Ok(()) } @@ -636,8 +656,8 @@ impl Processor { } // Get stake pool stake (and check if it is initialized) - let mut stake_pool = StakePool::deserialize(&stake_pool_info.data.borrow())?; - if !stake_pool.is_initialized() { + let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; + if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); } @@ -665,9 +685,10 @@ impl Processor { } // Read validator stake list account and check if it is valid - let mut validator_stake_list = - ValidatorStakeList::deserialize(&validator_stake_list_info.data.borrow())?; - if !validator_stake_list.is_initialized() { + let mut validator_stake_list = try_from_slice_unchecked::( + &validator_stake_list_info.data.borrow(), + )?; + if !validator_stake_list.is_valid() { return Err(StakePoolError::InvalidState.into()); } @@ -716,13 +737,13 @@ impl Processor { validator_stake_list .validators .retain(|item| item.validator_account != validator_account); - validator_stake_list.serialize(&mut validator_stake_list_info.data.borrow_mut())?; + validator_stake_list.serialize(&mut *validator_stake_list_info.data.borrow_mut())?; // Save amounts to the stake pool state stake_pool.pool_total -= token_amount; // Only update stake total if the last state update epoch is current stake_pool.stake_total -= stake_lamports; - stake_pool.serialize(&mut stake_pool_info.data.borrow_mut())?; + stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; Ok(()) } @@ -742,9 +763,10 @@ impl Processor { let validator_stake_accounts = account_info_iter.as_slice(); // Read validator stake list account and check if it is valid - let mut validator_stake_list = - ValidatorStakeList::deserialize(&validator_stake_list_info.data.borrow())?; - if !validator_stake_list.is_initialized() { + let mut validator_stake_list = try_from_slice_unchecked::( + &validator_stake_list_info.data.borrow(), + )?; + if !validator_stake_list.is_valid() { return Err(StakePoolError::InvalidState.into()); } @@ -775,7 +797,7 @@ impl Processor { } if changes { - validator_stake_list.serialize(&mut validator_stake_list_info.data.borrow_mut())?; + validator_stake_list.serialize(&mut *validator_stake_list_info.data.borrow_mut())?; } Ok(()) @@ -796,8 +818,8 @@ impl Processor { let clock = &Clock::from_account_info(clock_info)?; // Get stake pool stake (and check if it is initialized) - let mut stake_pool = StakePool::deserialize(&stake_pool_info.data.borrow())?; - if !stake_pool.is_initialized() { + let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; + if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); } @@ -807,9 +829,10 @@ impl Processor { } // Read validator stake list account and check if it is valid - let validator_stake_list = - ValidatorStakeList::deserialize(&validator_stake_list_info.data.borrow())?; - if !validator_stake_list.is_initialized() { + let validator_stake_list = try_from_slice_unchecked::( + &validator_stake_list_info.data.borrow(), + )?; + if !validator_stake_list.is_valid() { return Err(StakePoolError::InvalidState.into()); } @@ -823,7 +846,7 @@ impl Processor { stake_pool.stake_total = total_balance; stake_pool.last_update_epoch = clock.epoch; - stake_pool.serialize(&mut stake_pool_info.data.borrow_mut())?; + stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; Ok(()) } @@ -894,8 +917,8 @@ impl Processor { return Err(ProgramError::IncorrectProgramId); } - let mut stake_pool = StakePool::deserialize(&stake_pool_info.data.borrow())?; - if !stake_pool.is_initialized() { + let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; + if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); } @@ -924,9 +947,10 @@ impl Processor { } // Read validator stake list account and check if it is valid - let mut validator_stake_list = - ValidatorStakeList::deserialize(&validator_stake_list_info.data.borrow())?; - if !validator_stake_list.is_initialized() { + let mut validator_stake_list = try_from_slice_unchecked::( + &validator_stake_list_info.data.borrow(), + )?; + if !validator_stake_list.is_valid() { return Err(StakePoolError::InvalidState.into()); } @@ -1009,10 +1033,10 @@ impl Processor { )?; stake_pool.pool_total += pool_amount; stake_pool.stake_total += stake_lamports; - stake_pool.serialize(&mut stake_pool_info.data.borrow_mut())?; + stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; validator_list_item.balance = **validator_stake_account_info.lamports.borrow(); - validator_stake_list.serialize(&mut validator_stake_list_info.data.borrow_mut())?; + validator_stake_list.serialize(&mut *validator_stake_list_info.data.borrow_mut())?; Ok(()) } @@ -1053,8 +1077,8 @@ impl Processor { return Err(ProgramError::IncorrectProgramId); } - let mut stake_pool = StakePool::deserialize(&stake_pool_info.data.borrow())?; - if !stake_pool.is_initialized() { + let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; + if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); } @@ -1076,9 +1100,10 @@ impl Processor { } // Read validator stake list account and check if it is valid - let mut validator_stake_list = - ValidatorStakeList::deserialize(&validator_stake_list_info.data.borrow())?; - if !validator_stake_list.is_initialized() { + let mut validator_stake_list = try_from_slice_unchecked::( + &validator_stake_list_info.data.borrow(), + )?; + if !validator_stake_list.is_valid() { return Err(StakePoolError::InvalidState.into()); } @@ -1140,10 +1165,10 @@ impl Processor { stake_pool.pool_total -= pool_amount; stake_pool.stake_total -= stake_amount; - stake_pool.serialize(&mut stake_pool_info.data.borrow_mut())?; + stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; validator_list_item.balance = **stake_split_from.lamports.borrow(); - validator_stake_list.serialize(&mut validator_stake_list_info.data.borrow_mut())?; + validator_stake_list.serialize(&mut *validator_stake_list_info.data.borrow_mut())?; Ok(()) } @@ -1156,8 +1181,8 @@ impl Processor { let new_owner_info = next_account_info(account_info_iter)?; let new_owner_fee_info = next_account_info(account_info_iter)?; - let mut stake_pool = StakePool::deserialize(&stake_pool_info.data.borrow())?; - if !stake_pool.is_initialized() { + let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; + if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); } @@ -1173,16 +1198,19 @@ impl Processor { stake_pool.owner = *new_owner_info.key; stake_pool.owner_fee_account = *new_owner_fee_info.key; - stake_pool.serialize(&mut stake_pool_info.data.borrow_mut())?; + stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; Ok(()) } /// Processes [Instruction](enum.Instruction.html). pub fn process(program_id: &Pubkey, accounts: &[AccountInfo], input: &[u8]) -> ProgramResult { - let instruction = StakePoolInstruction::deserialize(input)?; + let instruction = StakePoolInstruction::try_from_slice(input)?; match instruction { - StakePoolInstruction::Initialize(init) => { + StakePoolInstruction::Initialize { + fee, + max_validators, + } => { msg!("Instruction: Init"); - Self::process_initialize(program_id, init, accounts) + Self::process_initialize(program_id, accounts, fee, max_validators) } StakePoolInstruction::CreateValidatorStakeAccount => { msg!("Instruction: CreateValidatorStakeAccount"); @@ -1248,7 +1276,7 @@ impl PrintProgramError for StakePoolError { msg!("Error: Validator stake account is not found in the list storage") } StakePoolError::WrongMintingAuthority => msg!("Error: Wrong minting authority set for mint pool account"), - StakePoolError::AccountNotRentExempt => msg!("Error: Account is not rent-exempt"), + StakePoolError::UnexpectedValidatorListAccountSize=> msg!("Error: The size of the given validator stake list does match the expected amount"), } } } diff --git a/program/src/state.rs b/program/src/state.rs index 0b935041..868bef6e 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -2,21 +2,35 @@ use { crate::{error::StakePoolError, instruction::Fee, processor::Processor}, - solana_program::{ - account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, - pubkey::Pubkey, - }, + borsh::{BorshDeserialize, BorshSchema, BorshSerialize}, + solana_program::{account_info::AccountInfo, program_error::ProgramError, pubkey::Pubkey}, spl_math::checked_ceil_div::CheckedCeilDiv, - std::convert::{TryFrom, TryInto}, - std::mem::size_of, + std::convert::TryFrom, }; +/// Enum representing the account type managed by the program +#[derive(Clone, Debug, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)] +pub enum AccountType { + /// If the account has not been initialized, the enum will be 0 + Uninitialized, + /// Stake pool + StakePool, + /// Validator stake list + ValidatorStakeList, +} + +impl Default for AccountType { + fn default() -> Self { + AccountType::Uninitialized + } +} + /// Initialized program details. #[repr(C)] -#[derive(Clone, Copy, Debug, Default, PartialEq)] +#[derive(Clone, Debug, Default, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)] pub struct StakePool { - /// Pool version - pub version: u8, + /// Account type, must be StakePool currently + pub account_type: AccountType, /// Owner authority /// allows for updating the staking authority pub owner: Pubkey, @@ -44,8 +58,6 @@ pub struct StakePool { pub fee: Fee, } impl StakePool { - /// Length of state data when serialized - pub const LEN: usize = size_of::(); /// calculate the pool tokens that should be minted pub fn calc_pool_deposit_amount(&self, stake_lamports: u64) -> Option { if self.stake_total == 0 { @@ -129,50 +141,34 @@ impl StakePool { Ok(()) } - /// Check if StakePool is initialized - pub fn is_initialized(&self) -> bool { - self.version > 0 + /// Check if StakePool is actually initialized as a stake pool + pub fn is_valid(&self) -> bool { + self.account_type == AccountType::StakePool } - /// Deserializes a byte buffer into a [StakePool](struct.StakePool.html). - pub fn deserialize(input: &[u8]) -> Result { - if input.len() < size_of::() { - return Err(ProgramError::InvalidAccountData); - } - - let stake_pool: &StakePool = unsafe { &*(&input[0] as *const u8 as *const StakePool) }; - - Ok(*stake_pool) - } - - /// Serializes [StakePool](struct.StakePool.html) into a byte buffer. - pub fn serialize(&self, output: &mut [u8]) -> ProgramResult { - if output.len() < size_of::() { - return Err(ProgramError::InvalidAccountData); - } - #[allow(clippy::cast_ptr_alignment)] - let value = unsafe { &mut *(&mut output[0] as *mut u8 as *mut StakePool) }; - *value = *self; - - Ok(()) + /// Check if StakePool is currently uninitialized + pub fn is_uninitialized(&self) -> bool { + self.account_type == AccountType::Uninitialized } } -const MAX_VALIDATOR_STAKE_ACCOUNTS: usize = 1000; - /// Storage list for all validator stake accounts in the pool. #[repr(C)] -#[derive(Clone, Debug, Default, PartialEq)] +#[derive(Clone, Debug, Default, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)] pub struct ValidatorStakeList { - /// Validator stake list version - pub version: u8, + /// Account type, must be ValidatorStakeList currently + pub account_type: AccountType, + + /// Maximum allowable number of validators + pub max_validators: u32, + /// List of all validator stake accounts and their info pub validators: Vec, } /// Information about the singe validator stake account #[repr(C)] -#[derive(Clone, Copy, Debug, Default, PartialEq)] +#[derive(Clone, Copy, Debug, Default, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)] pub struct ValidatorStakeInfo { /// Validator account pubkey pub validator_account: Pubkey, @@ -185,15 +181,19 @@ pub struct ValidatorStakeInfo { } impl ValidatorStakeList { - /// Length of ValidatorStakeList data when serialized - pub const LEN: usize = - Self::HEADER_LEN + ValidatorStakeInfo::LEN * MAX_VALIDATOR_STAKE_ACCOUNTS; - - /// Header length - pub const HEADER_LEN: usize = size_of::() + size_of::(); + /// Create an empty instance containing space for `max_validators` + pub fn new_with_max_validators(max_validators: u32) -> Self { + Self { + account_type: AccountType::ValidatorStakeList, + max_validators, + validators: vec![ValidatorStakeInfo::default(); max_validators as usize], + } + } - /// Version of validator stake list - pub const VALIDATOR_STAKE_LIST_VERSION: u8 = 1; + /// Calculate the number of validator entries that fit in the provided length + pub fn calculate_max_validators(buffer_length: usize) -> usize { + (buffer_length - 1 - 4 - 4) / 48 + } /// Check if contains validator with particular pubkey pub fn contains(&self, validator: &Pubkey) -> bool { @@ -215,125 +215,62 @@ impl ValidatorStakeList { .find(|x| x.validator_account == *validator) } - /// Check if validator stake list is initialized - pub fn is_initialized(&self) -> bool { - self.version > 0 - } - - /// Deserializes a byte buffer into a ValidatorStakeList. - pub fn deserialize(input: &[u8]) -> Result { - if input.len() < Self::LEN { - return Err(ProgramError::InvalidAccountData); - } - - if input[0] == 0 { - return Ok(ValidatorStakeList { - version: 0, - validators: vec![], - }); - } - - let number_of_validators: usize = u16::from_le_bytes( - input[1..3] - .try_into() - .or(Err(ProgramError::InvalidAccountData))?, - ) as usize; - if number_of_validators > MAX_VALIDATOR_STAKE_ACCOUNTS { - return Err(ProgramError::InvalidAccountData); - } - let mut validators: Vec = Vec::with_capacity(number_of_validators); - - let mut from = Self::HEADER_LEN; - let mut to = from + ValidatorStakeInfo::LEN; - for _ in 0..number_of_validators { - validators.push(ValidatorStakeInfo::deserialize(&input[from..to])?); - from += ValidatorStakeInfo::LEN; - to += ValidatorStakeInfo::LEN; - } - Ok(ValidatorStakeList { - version: input[0], - validators, - }) - } - - /// Serializes ValidatorStakeList into a byte buffer. - pub fn serialize(&self, output: &mut [u8]) -> ProgramResult { - if output.len() < Self::LEN { - return Err(ProgramError::InvalidAccountData); - } - if self.validators.len() > MAX_VALIDATOR_STAKE_ACCOUNTS { - return Err(ProgramError::InvalidAccountData); - } - output[0] = self.version; - output[1..3].copy_from_slice(&u16::to_le_bytes(self.validators.len() as u16)); - let mut from = Self::HEADER_LEN; - let mut to = from + ValidatorStakeInfo::LEN; - for validator in &self.validators { - validator.serialize(&mut output[from..to])?; - from += ValidatorStakeInfo::LEN; - to += ValidatorStakeInfo::LEN; - } - Ok(()) + /// Check if validator stake list is actually initialized as a validator stake list + pub fn is_valid(&self) -> bool { + self.account_type == AccountType::ValidatorStakeList } -} - -impl ValidatorStakeInfo { - /// Length of ValidatorStakeInfo data when serialized - pub const LEN: usize = size_of::(); - /// Deserializes a byte buffer into a ValidatorStakeInfo. - pub fn deserialize(input: &[u8]) -> Result { - if input.len() < Self::LEN { - return Err(ProgramError::InvalidAccountData); - } - #[allow(clippy::cast_ptr_alignment)] - let stake_info: &ValidatorStakeInfo = - unsafe { &*(&input[0] as *const u8 as *const ValidatorStakeInfo) }; - Ok(*stake_info) - } - - /// Serializes ValidatorStakeInfo into a byte buffer. - pub fn serialize(&self, output: &mut [u8]) -> ProgramResult { - if output.len() < Self::LEN { - return Err(ProgramError::InvalidAccountData); - } - - #[allow(clippy::cast_ptr_alignment)] - let value = unsafe { &mut *(&mut output[0] as *mut u8 as *mut ValidatorStakeInfo) }; - *value = *self; - Ok(()) + /// Check if the validator stake list is uninitialized + pub fn is_uninitialized(&self) -> bool { + self.account_type == AccountType::Uninitialized } } #[cfg(test)] mod test { - use super::*; + use { + super::*, + crate::borsh::{get_instance_packed_len, try_from_slice_unchecked}, + proptest::prelude::*, + solana_program::borsh::get_packed_len, + }; #[test] fn test_state_packing() { + let max_validators = 10_000; + let size = + get_instance_packed_len(&ValidatorStakeList::new_with_max_validators(max_validators)) + .unwrap(); // Not initialized let stake_list = ValidatorStakeList { - version: 0, + account_type: AccountType::Uninitialized, + max_validators: 0, validators: vec![], }; - let mut bytes: [u8; ValidatorStakeList::LEN] = [0; ValidatorStakeList::LEN]; + let mut byte_vec = vec![0u8; size]; + let mut bytes = byte_vec.as_mut_slice(); stake_list.serialize(&mut bytes).unwrap(); - let stake_list_unpacked = ValidatorStakeList::deserialize(&bytes).unwrap(); + let stake_list_unpacked = + try_from_slice_unchecked::(&byte_vec).unwrap(); assert_eq!(stake_list_unpacked, stake_list); // Empty let stake_list = ValidatorStakeList { - version: ValidatorStakeList::VALIDATOR_STAKE_LIST_VERSION, + account_type: AccountType::ValidatorStakeList, + max_validators: 0, validators: vec![], }; - let mut bytes: [u8; ValidatorStakeList::LEN] = [0; ValidatorStakeList::LEN]; + let mut byte_vec = vec![0u8; size]; + let mut bytes = byte_vec.as_mut_slice(); stake_list.serialize(&mut bytes).unwrap(); - let stake_list_unpacked = ValidatorStakeList::deserialize(&bytes).unwrap(); + let stake_list_unpacked = + try_from_slice_unchecked::(&byte_vec).unwrap(); assert_eq!(stake_list_unpacked, stake_list); // With several accounts let stake_list = ValidatorStakeList { - version: ValidatorStakeList::VALIDATOR_STAKE_LIST_VERSION, + account_type: AccountType::ValidatorStakeList, + max_validators, validators: vec![ ValidatorStakeInfo { validator_account: Pubkey::new_from_array([1; 32]), @@ -352,9 +289,23 @@ mod test { }, ], }; - let mut bytes: [u8; ValidatorStakeList::LEN] = [0; ValidatorStakeList::LEN]; + let mut byte_vec = vec![0u8; size]; + let mut bytes = byte_vec.as_mut_slice(); stake_list.serialize(&mut bytes).unwrap(); - let stake_list_unpacked = ValidatorStakeList::deserialize(&bytes).unwrap(); + let stake_list_unpacked = + try_from_slice_unchecked::(&byte_vec).unwrap(); assert_eq!(stake_list_unpacked, stake_list); } + + proptest! { + #[test] + fn stake_list_size_calculation(test_amount in 0..=100_000_u32) { + let validators = ValidatorStakeList::new_with_max_validators(test_amount); + let size = get_instance_packed_len(&validators).unwrap(); + assert_eq!(ValidatorStakeList::calculate_max_validators(size), test_amount as usize); + assert_eq!(ValidatorStakeList::calculate_max_validators(size + 1), test_amount as usize); + assert_eq!(ValidatorStakeList::calculate_max_validators(size + get_packed_len::()), (test_amount + 1)as usize); + assert_eq!(ValidatorStakeList::calculate_max_validators(size - 1), (test_amount - 1) as usize); + } + } } diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index b8f4a11f..55f477da 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -2,19 +2,21 @@ mod helpers; -use helpers::*; - -use solana_program::hash::Hash; -use solana_program_test::*; -use solana_sdk::{ - instruction::InstructionError, - signature::{Keypair, Signer}, - transaction::Transaction, - transaction::TransactionError, - transport::TransportError, +use { + borsh::BorshDeserialize, + helpers::*, + solana_program::hash::Hash, + solana_program_test::*, + solana_sdk::{ + instruction::InstructionError, + signature::{Keypair, Signer}, + transaction::Transaction, + transaction::TransactionError, + transport::TransportError, + }, + spl_stake_pool::{borsh::try_from_slice_unchecked, error, id, instruction, stake, state}, + spl_token::error as token_error, }; -use spl_stake_pool::*; -use spl_token::error as token_error; async fn setup() -> ( BanksClient, @@ -129,7 +131,7 @@ async fn test_stake_pool_deposit() { let stake_pool_before = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; let stake_pool_before = - state::StakePool::deserialize(&stake_pool_before.data.as_slice()).unwrap(); + state::StakePool::try_from_slice(&stake_pool_before.data.as_slice()).unwrap(); // Save validator stake account record before depositing let validator_stake_list = get_account( @@ -138,7 +140,8 @@ async fn test_stake_pool_deposit() { ) .await; let validator_stake_list = - state::ValidatorStakeList::deserialize(validator_stake_list.data.as_slice()).unwrap(); + try_from_slice_unchecked::(validator_stake_list.data.as_slice()) + .unwrap(); let validator_stake_item_before = validator_stake_list .find(&validator_stake_account.vote.pubkey()) .unwrap(); @@ -167,7 +170,7 @@ async fn test_stake_pool_deposit() { // Stake pool should add its balance to the pool balance let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; - let stake_pool = state::StakePool::deserialize(&stake_pool.data.as_slice()).unwrap(); + let stake_pool = state::StakePool::try_from_slice(&stake_pool.data.as_slice()).unwrap(); assert_eq!( stake_pool.stake_total, stake_pool_before.stake_total + stake_lamports @@ -195,7 +198,8 @@ async fn test_stake_pool_deposit() { ) .await; let validator_stake_list = - state::ValidatorStakeList::deserialize(validator_stake_list.data.as_slice()).unwrap(); + try_from_slice_unchecked::(validator_stake_list.data.as_slice()) + .unwrap(); let validator_stake_item = validator_stake_list .find(&validator_stake_account.vote.pubkey()) .unwrap(); diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 35863756..aadd29a0 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -1,17 +1,22 @@ #![allow(dead_code)] -use solana_program::{hash::Hash, program_pack::Pack, pubkey::Pubkey, system_instruction}; -use solana_program_test::*; -use solana_sdk::{ - account::Account, - signature::{Keypair, Signer}, - transaction::Transaction, - transport::TransportError, +use { + solana_program::{ + borsh::get_packed_len, hash::Hash, program_pack::Pack, pubkey::Pubkey, system_instruction, + }, + solana_program_test::*, + solana_sdk::{ + account::Account, + signature::{Keypair, Signer}, + transaction::Transaction, + transport::TransportError, + }, + solana_vote_program::{self, vote_state::VoteState}, + spl_stake_pool::{borsh::get_instance_packed_len, id, instruction, processor, stake, state}, }; -use solana_vote_program::{self, vote_state::VoteState}; -use spl_stake_pool::*; pub const TEST_STAKE_AMOUNT: u64 = 100; +pub const MAX_TEST_VALIDATORS: u32 = 10_000; pub fn program_test() -> ProgramTest { ProgramTest::new( @@ -165,11 +170,15 @@ pub async fn create_stake_pool( pool_token_account: &Pubkey, owner: &Keypair, fee: &instruction::Fee, + max_validators: u32, ) -> Result<(), TransportError> { let rent = banks_client.get_rent().await.unwrap(); - let rent_stake_pool = rent.minimum_balance(state::StakePool::LEN); - let rent_validator_stake_list = rent.minimum_balance(state::ValidatorStakeList::LEN); - let init_args = instruction::InitArgs { fee: *fee }; + let rent_stake_pool = rent.minimum_balance(get_packed_len::()); + let validator_stake_list_size = get_instance_packed_len( + &state::ValidatorStakeList::new_with_max_validators(max_validators), + ) + .unwrap(); + let rent_validator_stake_list = rent.minimum_balance(validator_stake_list_size); let mut transaction = Transaction::new_with_payer( &[ @@ -177,14 +186,14 @@ pub async fn create_stake_pool( &payer.pubkey(), &stake_pool.pubkey(), rent_stake_pool, - state::StakePool::LEN as u64, + get_packed_len::() as u64, &id(), ), system_instruction::create_account( &payer.pubkey(), &validator_stake_list.pubkey(), rent_validator_stake_list, - state::ValidatorStakeList::LEN as u64, + validator_stake_list_size as u64, &id(), ), instruction::initialize( @@ -195,7 +204,8 @@ pub async fn create_stake_pool( pool_mint, pool_token_account, &spl_token::id(), - init_args, + fee.clone(), + max_validators, ) .unwrap(), ], @@ -431,6 +441,7 @@ pub struct StakePoolAccounts { pub withdraw_authority: Pubkey, pub deposit_authority: Pubkey, pub fee: instruction::Fee, + pub max_validators: u32, } impl StakePoolAccounts { @@ -462,6 +473,7 @@ impl StakePoolAccounts { numerator: 1, denominator: 100, }, + max_validators: MAX_TEST_VALIDATORS, } } @@ -502,6 +514,7 @@ impl StakePoolAccounts { &self.pool_fee_account.pubkey(), &self.owner, &self.fee, + self.max_validators, ) .await?; Ok(()) diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index bb0a4da8..9a1d7a3b 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -2,19 +2,26 @@ mod helpers; -use helpers::*; -use solana_program::hash::Hash; -use solana_program::{ - instruction::{AccountMeta, Instruction}, - program_pack::Pack, - system_instruction, sysvar, +use { + borsh::BorshSerialize, + helpers::*, + solana_program::{ + borsh::get_packed_len, + hash::Hash, + instruction::{AccountMeta, Instruction}, + program_pack::Pack, + system_instruction, sysvar, + }, + solana_program_test::*, + solana_sdk::{ + instruction::InstructionError, signature::Keypair, signature::Signer, + transaction::Transaction, transaction::TransactionError, transport::TransportError, + }, + spl_stake_pool::{ + borsh::{get_instance_packed_len, try_from_slice_unchecked}, + error, id, instruction, state, + }, }; -use solana_program_test::*; -use solana_sdk::{ - instruction::InstructionError, signature::Keypair, signature::Signer, transaction::Transaction, - transaction::TransactionError, transport::TransportError, -}; -use spl_stake_pool::*; async fn create_mint_and_token_account( banks_client: &mut BanksClient, @@ -55,7 +62,7 @@ async fn test_stake_pool_initialize() { // Stake pool now exists let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; - assert_eq!(stake_pool.data.len(), state::StakePool::LEN); + assert_eq!(stake_pool.data.len(), get_packed_len::()); assert_eq!(stake_pool.owner, id()); // Validator stake list storage initialized @@ -65,8 +72,9 @@ async fn test_stake_pool_initialize() { ) .await; let validator_stake_list = - state::ValidatorStakeList::deserialize(validator_stake_list.data.as_slice()).unwrap(); - assert_eq!(validator_stake_list.is_initialized(), true); + try_from_slice_unchecked::(validator_stake_list.data.as_slice()) + .unwrap(); + assert_eq!(validator_stake_list.is_valid(), true); } #[tokio::test] @@ -157,6 +165,85 @@ async fn test_initialize_stake_pool_with_high_fee() { } } +#[tokio::test] +async fn test_initialize_stake_pool_with_wrong_max_validators() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + + create_mint_and_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + ) + .await; + + let rent = banks_client.get_rent().await.unwrap(); + let rent_stake_pool = rent.minimum_balance(get_packed_len::()); + let validator_stake_list_size = get_instance_packed_len( + &state::ValidatorStakeList::new_with_max_validators(stake_pool_accounts.max_validators - 1), + ) + .unwrap(); + let rent_validator_stake_list = rent.minimum_balance(validator_stake_list_size); + + let mut transaction = Transaction::new_with_payer( + &[ + system_instruction::create_account( + &payer.pubkey(), + &stake_pool_accounts.stake_pool.pubkey(), + rent_stake_pool, + get_packed_len::() as u64, + &id(), + ), + system_instruction::create_account( + &payer.pubkey(), + &stake_pool_accounts.validator_stake_list.pubkey(), + rent_validator_stake_list, + validator_stake_list_size as u64, + &id(), + ), + instruction::initialize( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.owner.pubkey(), + &stake_pool_accounts.validator_stake_list.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &stake_pool_accounts.pool_fee_account.pubkey(), + &spl_token::id(), + stake_pool_accounts.fee.clone(), + stake_pool_accounts.max_validators, + ) + .unwrap(), + ], + Some(&payer.pubkey()), + ); + transaction.sign( + &[ + &payer, + &stake_pool_accounts.stake_pool, + &stake_pool_accounts.validator_stake_list, + &stake_pool_accounts.owner, + ], + recent_blockhash, + ); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::UnexpectedValidatorListAccountSize as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while try to initialize stake pool with high fee"), + } +} + #[tokio::test] async fn test_initialize_stake_pool_with_wrong_mint_authority() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; @@ -192,6 +279,7 @@ async fn test_initialize_stake_pool_with_wrong_mint_authority() { &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.owner, &stake_pool_accounts.fee, + stake_pool_accounts.max_validators, ) .await .err() @@ -245,11 +333,12 @@ async fn test_initialize_stake_pool_with_wrong_token_program_id() { ); banks_client.process_transaction(transaction).await.unwrap(); - let rent_stake_pool = rent.minimum_balance(state::StakePool::LEN); - let rent_validator_stake_list = rent.minimum_balance(state::ValidatorStakeList::LEN); - let init_args = instruction::InitArgs { - fee: stake_pool_accounts.fee, - }; + let rent_stake_pool = rent.minimum_balance(get_packed_len::()); + let validator_stake_list_size = get_instance_packed_len( + &state::ValidatorStakeList::new_with_max_validators(stake_pool_accounts.max_validators), + ) + .unwrap(); + let rent_validator_stake_list = rent.minimum_balance(validator_stake_list_size); let mut transaction = Transaction::new_with_payer( &[ @@ -257,14 +346,14 @@ async fn test_initialize_stake_pool_with_wrong_token_program_id() { &payer.pubkey(), &stake_pool_accounts.stake_pool.pubkey(), rent_stake_pool, - state::StakePool::LEN as u64, + get_packed_len::() as u64, &id(), ), system_instruction::create_account( &payer.pubkey(), &stake_pool_accounts.validator_stake_list.pubkey(), rent_validator_stake_list, - state::ValidatorStakeList::LEN as u64, + validator_stake_list_size as u64, &id(), ), instruction::initialize( @@ -275,7 +364,8 @@ async fn test_initialize_stake_pool_with_wrong_token_program_id() { &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), &wrong_token_program.pubkey(), - init_args, + stake_pool_accounts.fee.clone(), + stake_pool_accounts.max_validators, ) .unwrap(), ], @@ -349,6 +439,7 @@ async fn test_initialize_stake_pool_with_wrong_fee_accounts_owner() { &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.owner, &stake_pool_accounts.fee, + stake_pool_accounts.max_validators, ) .await .err() @@ -409,10 +500,11 @@ async fn test_initialize_stake_pool_with_not_rent_exempt_pool() { .await; let rent = banks_client.get_rent().await.unwrap(); - let rent_validator_stake_list = rent.minimum_balance(state::ValidatorStakeList::LEN); - let init_args = instruction::InitArgs { - fee: stake_pool_accounts.fee, - }; + let validator_stake_list_size = get_instance_packed_len( + &state::ValidatorStakeList::new_with_max_validators(stake_pool_accounts.max_validators), + ) + .unwrap(); + let rent_validator_stake_list = rent.minimum_balance(validator_stake_list_size); let mut transaction = Transaction::new_with_payer( &[ @@ -420,14 +512,14 @@ async fn test_initialize_stake_pool_with_not_rent_exempt_pool() { &payer.pubkey(), &stake_pool_accounts.stake_pool.pubkey(), 1, - state::StakePool::LEN as u64, + get_packed_len::() as u64, &id(), ), system_instruction::create_account( &payer.pubkey(), &stake_pool_accounts.validator_stake_list.pubkey(), rent_validator_stake_list, - state::ValidatorStakeList::LEN as u64, + validator_stake_list_size as u64, &id(), ), instruction::initialize( @@ -438,7 +530,8 @@ async fn test_initialize_stake_pool_with_not_rent_exempt_pool() { &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), &spl_token::id(), - init_args, + stake_pool_accounts.fee.clone(), + stake_pool_accounts.max_validators, ) .unwrap(), ], @@ -453,24 +546,19 @@ async fn test_initialize_stake_pool_with_not_rent_exempt_pool() { ], recent_blockhash, ); - let transaction_error = banks_client - .process_transaction(transaction) - .await - .err() - .unwrap(); - - match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError( - _, - InstructionError::Custom(error_index), - )) => { - let program_error = error::StakePoolError::AccountNotRentExempt as u32; - assert_eq!(error_index, program_error); - } - _ => panic!( - "Wrong error occurs while try to initialize stake pool with not rent exempt stake pool account" - ), - } + assert_eq!( + banks_client + .process_transaction(transaction) + .await + .unwrap_err() + .unwrap(), + TransactionError::InstructionError( + 2, + InstructionError::InvalidError, + // should be InstructionError::AccountNotRentExempt, but the mapping + // is wrong + ) + ); } #[tokio::test] @@ -487,10 +575,11 @@ async fn test_initialize_stake_pool_with_not_rent_exempt_validator_stake_list() .await; let rent = banks_client.get_rent().await.unwrap(); - let rent_stake_pool = rent.minimum_balance(state::StakePool::LEN); - let init_args = instruction::InitArgs { - fee: stake_pool_accounts.fee, - }; + let rent_stake_pool = rent.minimum_balance(get_packed_len::()); + let validator_stake_list_size = get_instance_packed_len( + &state::ValidatorStakeList::new_with_max_validators(stake_pool_accounts.max_validators), + ) + .unwrap(); let mut transaction = Transaction::new_with_payer( &[ @@ -498,14 +587,14 @@ async fn test_initialize_stake_pool_with_not_rent_exempt_validator_stake_list() &payer.pubkey(), &stake_pool_accounts.stake_pool.pubkey(), rent_stake_pool, - state::StakePool::LEN as u64, + get_packed_len::() as u64, &id(), ), system_instruction::create_account( &payer.pubkey(), &stake_pool_accounts.validator_stake_list.pubkey(), 1, - state::ValidatorStakeList::LEN as u64, + validator_stake_list_size as u64, &id(), ), instruction::initialize( @@ -516,7 +605,8 @@ async fn test_initialize_stake_pool_with_not_rent_exempt_validator_stake_list() &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), &spl_token::id(), - init_args, + stake_pool_accounts.fee.clone(), + stake_pool_accounts.max_validators, ) .unwrap(), ], @@ -531,24 +621,20 @@ async fn test_initialize_stake_pool_with_not_rent_exempt_validator_stake_list() ], recent_blockhash, ); - let transaction_error = banks_client - .process_transaction(transaction) - .await - .err() - .unwrap(); - match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError( - _, - InstructionError::Custom(error_index), - )) => { - let program_error = error::StakePoolError::AccountNotRentExempt as u32; - assert_eq!(error_index, program_error); - } - _ => panic!( - "Wrong error occurs while try to initialize stake pool with not rent exempt validator stake list account" - ), - } + assert_eq!( + banks_client + .process_transaction(transaction) + .await + .unwrap_err() + .unwrap(), + TransactionError::InstructionError( + 2, + InstructionError::InvalidError, + // should be InstructionError::AccountNotRentExempt, but the mapping + // is wrong + ) + ); } #[tokio::test] @@ -565,13 +651,18 @@ async fn test_initialize_stake_pool_without_owner_signature() { .await; let rent = banks_client.get_rent().await.unwrap(); - let rent_stake_pool = rent.minimum_balance(state::StakePool::LEN); - let init_args = instruction::InitArgs { - fee: stake_pool_accounts.fee, - }; + let rent_stake_pool = rent.minimum_balance(get_packed_len::()); + let validator_stake_list_size = get_instance_packed_len( + &state::ValidatorStakeList::new_with_max_validators(stake_pool_accounts.max_validators), + ) + .unwrap(); + let rent_validator_stake_list = rent.minimum_balance(validator_stake_list_size); - let init_data = instruction::StakePoolInstruction::Initialize(init_args); - let data = init_data.serialize().unwrap(); + let init_data = instruction::StakePoolInstruction::Initialize { + fee: stake_pool_accounts.fee.clone(), + max_validators: stake_pool_accounts.max_validators, + }; + let data = init_data.try_to_vec().unwrap(); let accounts = vec![ AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), true), AccountMeta::new_readonly(stake_pool_accounts.owner.pubkey(), false), @@ -594,14 +685,14 @@ async fn test_initialize_stake_pool_without_owner_signature() { &payer.pubkey(), &stake_pool_accounts.stake_pool.pubkey(), rent_stake_pool, - state::StakePool::LEN as u64, + get_packed_len::() as u64, &id(), ), system_instruction::create_account( &payer.pubkey(), &stake_pool_accounts.validator_stake_list.pubkey(), - state::ValidatorStakeList::LEN as u64, - state::ValidatorStakeList::LEN as u64, + rent_validator_stake_list, + validator_stake_list_size as u64, &id(), ), stake_pool_init_instruction, diff --git a/program/tests/set_owner.rs b/program/tests/set_owner.rs index 4fa6b3f6..611dcf03 100644 --- a/program/tests/set_owner.rs +++ b/program/tests/set_owner.rs @@ -2,16 +2,20 @@ mod helpers; -use helpers::*; -use solana_program::hash::Hash; -use solana_program::instruction::AccountMeta; -use solana_program::instruction::Instruction; -use solana_program_test::*; -use solana_sdk::{ - instruction::InstructionError, signature::Keypair, signature::Signer, transaction::Transaction, - transaction::TransactionError, transport::TransportError, +use { + borsh::{BorshDeserialize, BorshSerialize}, + helpers::*, + solana_program::{ + hash::Hash, + instruction::{AccountMeta, Instruction}, + }, + solana_program_test::*, + solana_sdk::{ + instruction::InstructionError, signature::Keypair, signature::Signer, + transaction::Transaction, transaction::TransactionError, transport::TransportError, + }, + spl_stake_pool::{error, id, instruction, state}, }; -use spl_stake_pool::*; async fn setup() -> ( BanksClient, @@ -71,7 +75,7 @@ async fn test_set_owner() { banks_client.process_transaction(transaction).await.unwrap(); let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; - let stake_pool = state::StakePool::deserialize(&stake_pool.data.as_slice()).unwrap(); + let stake_pool = state::StakePool::try_from_slice(&stake_pool.data.as_slice()).unwrap(); assert_eq!(stake_pool.owner, new_owner.pubkey()); } @@ -116,8 +120,9 @@ async fn test_set_owner_without_signature() { let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_pool_fee, new_owner) = setup().await; - let args = instruction::StakePoolInstruction::SetOwner; - let data = args.serialize().unwrap(); + let data = instruction::StakePoolInstruction::SetOwner + .try_to_vec() + .unwrap(); let accounts = vec![ AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), AccountMeta::new_readonly(stake_pool_accounts.owner.pubkey(), false), diff --git a/program/tests/update_list_balance.rs b/program/tests/update_list_balance.rs index 418699cb..56b75db8 100644 --- a/program/tests/update_list_balance.rs +++ b/program/tests/update_list_balance.rs @@ -8,7 +8,7 @@ use { solana_program::{native_token, pubkey::Pubkey}, solana_program_test::*, solana_sdk::signature::Signer, - spl_stake_pool::*, + spl_stake_pool::{borsh::try_from_slice_unchecked, stake, state}, }; async fn get_list_sum(banks_client: &mut BanksClient, validator_stake_list_key: &Pubkey) -> u64 { @@ -18,7 +18,8 @@ async fn get_list_sum(banks_client: &mut BanksClient, validator_stake_list_key: .expect("get_account") .expect("validator stake list not none"); let validator_stake_list = - state::ValidatorStakeList::deserialize(validator_stake_list.data.as_slice()).unwrap(); + try_from_slice_unchecked::(validator_stake_list.data.as_slice()) + .unwrap(); validator_stake_list .validators diff --git a/program/tests/update_pool_balance.rs b/program/tests/update_pool_balance.rs index ff743ced..1a1a2f6d 100644 --- a/program/tests/update_pool_balance.rs +++ b/program/tests/update_pool_balance.rs @@ -2,13 +2,15 @@ mod helpers; -use helpers::*; -use solana_program_test::*; -use solana_sdk::{ - instruction::InstructionError, signature::Keypair, signature::Signer, transaction::Transaction, - transaction::TransactionError, transport::TransportError, +use { + helpers::*, + solana_program_test::*, + solana_sdk::{ + instruction::InstructionError, signature::Keypair, signature::Signer, + transaction::Transaction, transaction::TransactionError, transport::TransportError, + }, + spl_stake_pool::*, }; -use spl_stake_pool::*; #[tokio::test] async fn test_update_pool_balance() { diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index 1ac6994c..26c9dcd7 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -2,22 +2,24 @@ mod helpers; -use helpers::*; - -use bincode::deserialize; -use solana_program::hash::Hash; -use solana_program::instruction::AccountMeta; -use solana_program::instruction::Instruction; -use solana_program::sysvar; -use solana_program_test::*; -use solana_sdk::{ - instruction::InstructionError, - signature::{Keypair, Signer}, - transaction::Transaction, - transaction::TransactionError, - transport::TransportError, +use { + bincode::deserialize, + borsh::BorshSerialize, + helpers::*, + solana_program::{ + hash::Hash, + instruction::{AccountMeta, Instruction}, + sysvar, + }, + solana_program_test::*, + solana_sdk::{ + instruction::InstructionError, + signature::{Keypair, Signer}, + transaction::{Transaction, TransactionError}, + transport::TransportError, + }, + spl_stake_pool::{borsh::try_from_slice_unchecked, error, id, instruction, stake, state}, }; -use spl_stake_pool::*; async fn setup() -> ( BanksClient, @@ -113,11 +115,13 @@ async fn test_add_validator_stake_account() { ) .await; let validator_stake_list = - state::ValidatorStakeList::deserialize(validator_stake_list.data.as_slice()).unwrap(); + try_from_slice_unchecked::(validator_stake_list.data.as_slice()) + .unwrap(); assert_eq!( validator_stake_list, state::ValidatorStakeList { - version: state::ValidatorStakeList::VALIDATOR_STAKE_LIST_VERSION, + account_type: state::AccountType::ValidatorStakeList, + max_validators: stake_pool_accounts.max_validators, validators: vec![state::ValidatorStakeInfo { validator_account: user_stake.vote.pubkey(), last_update_epoch: 0, @@ -409,7 +413,7 @@ async fn test_not_owner_try_to_add_validator_stake_account_without_signature() { program_id: id(), accounts, data: instruction::StakePoolInstruction::AddValidatorStakeAccount - .serialize() + .try_to_vec() .unwrap(), }; @@ -543,6 +547,74 @@ async fn test_add_validator_stake_account_with_wrong_stake_program_id() { } } +#[tokio::test] +async fn test_add_too_many_validator_stake_accounts() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let mut stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts.max_validators = 1; + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await + .unwrap(); + + let user = Keypair::new(); + + let user_stake = ValidatorStakeAccount::new_with_target_authority( + &stake_pool_accounts.deposit_authority, + &stake_pool_accounts.stake_pool.pubkey(), + ); + user_stake + .create_and_delegate(&mut banks_client, &payer, &recent_blockhash) + .await; + + // make pool token account + let user_pool_account = Keypair::new(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user.pubkey(), + ) + .await + .unwrap(); + + let error = stake_pool_accounts + .add_validator_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.stake_account, + &user_pool_account.pubkey(), + ) + .await; + assert!(error.is_none()); + + let user_stake = ValidatorStakeAccount::new_with_target_authority( + &stake_pool_accounts.deposit_authority, + &stake_pool_accounts.stake_pool.pubkey(), + ); + user_stake + .create_and_delegate(&mut banks_client, &payer, &recent_blockhash) + .await; + let error = stake_pool_accounts + .add_validator_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.stake_account, + &user_pool_account.pubkey(), + ) + .await + .unwrap() + .unwrap(); + assert_eq!( + error, + TransactionError::InstructionError(0, InstructionError::AccountDataTooSmall), + ); +} + #[tokio::test] async fn test_add_validator_stake_account_to_unupdated_stake_pool() {} // TODO diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index b375f608..4be8f507 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -2,22 +2,25 @@ mod helpers; -use bincode::deserialize; -use helpers::*; -use solana_program::hash::Hash; -use solana_program::instruction::AccountMeta; -use solana_program::instruction::Instruction; -use solana_program::pubkey::Pubkey; -use solana_program::sysvar; -use solana_program_test::*; -use solana_sdk::{ - instruction::InstructionError, - signature::{Keypair, Signer}, - transaction::Transaction, - transaction::TransactionError, - transport::TransportError, +use { + bincode::deserialize, + borsh::BorshSerialize, + helpers::*, + solana_program::{ + hash::Hash, + instruction::{AccountMeta, Instruction}, + pubkey::Pubkey, + sysvar, + }, + solana_program_test::*, + solana_sdk::{ + instruction::InstructionError, + signature::{Keypair, Signer}, + transaction::{Transaction, TransactionError}, + transport::TransportError, + }, + spl_stake_pool::{borsh::try_from_slice_unchecked, error, id, instruction, stake, state}, }; -use spl_stake_pool::*; async fn setup() -> ( BanksClient, @@ -128,11 +131,13 @@ async fn test_remove_validator_stake_account() { ) .await; let validator_stake_list = - state::ValidatorStakeList::deserialize(validator_stake_list.data.as_slice()).unwrap(); + try_from_slice_unchecked::(validator_stake_list.data.as_slice()) + .unwrap(); assert_eq!( validator_stake_list, state::ValidatorStakeList { - version: state::ValidatorStakeList::VALIDATOR_STAKE_LIST_VERSION, + account_type: state::AccountType::ValidatorStakeList, + max_validators: stake_pool_accounts.max_validators, validators: vec![] } ); @@ -495,7 +500,7 @@ async fn test_not_owner_try_to_remove_validator_stake_account_without_signature( program_id: id(), accounts, data: instruction::StakePoolInstruction::RemoveValidatorStakeAccount - .serialize() + .try_to_vec() .unwrap(), }; diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 925550ea..5fc52390 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -2,20 +2,21 @@ mod helpers; -use helpers::*; -use solana_program::pubkey::Pubkey; - -use solana_program::hash::Hash; -use solana_program_test::*; -use solana_sdk::{ - instruction::InstructionError, - signature::{Keypair, Signer}, - transaction::Transaction, - transaction::TransactionError, - transport::TransportError, +use { + borsh::BorshDeserialize, + helpers::*, + solana_program::hash::Hash, + solana_program::pubkey::Pubkey, + solana_program_test::*, + solana_sdk::{ + instruction::InstructionError, + signature::{Keypair, Signer}, + transaction::{Transaction, TransactionError}, + transport::TransportError, + }, + spl_stake_pool::{borsh::try_from_slice_unchecked, error, id, instruction, stake, state}, + spl_token::error::TokenError, }; -use spl_stake_pool::*; -use spl_token::error::TokenError; async fn setup() -> ( BanksClient, @@ -101,7 +102,7 @@ async fn test_stake_pool_withdraw() { let stake_pool_before = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; let stake_pool_before = - state::StakePool::deserialize(&stake_pool_before.data.as_slice()).unwrap(); + state::StakePool::try_from_slice(&stake_pool_before.data.as_slice()).unwrap(); // Save validator stake account record before withdrawal let validator_stake_list = get_account( @@ -110,7 +111,8 @@ async fn test_stake_pool_withdraw() { ) .await; let validator_stake_list = - state::ValidatorStakeList::deserialize(validator_stake_list.data.as_slice()).unwrap(); + try_from_slice_unchecked::(validator_stake_list.data.as_slice()) + .unwrap(); let validator_stake_item_before = validator_stake_list .find(&validator_stake_account.vote.pubkey()) .unwrap(); @@ -136,7 +138,7 @@ async fn test_stake_pool_withdraw() { // Check pool stats let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; - let stake_pool = state::StakePool::deserialize(&stake_pool.data.as_slice()).unwrap(); + let stake_pool = state::StakePool::try_from_slice(&stake_pool.data.as_slice()).unwrap(); assert_eq!( stake_pool.stake_total, stake_pool_before.stake_total - tokens_to_burn @@ -153,7 +155,8 @@ async fn test_stake_pool_withdraw() { ) .await; let validator_stake_list = - state::ValidatorStakeList::deserialize(validator_stake_list.data.as_slice()).unwrap(); + try_from_slice_unchecked::(validator_stake_list.data.as_slice()) + .unwrap(); let validator_stake_item = validator_stake_list .find(&validator_stake_account.vote.pubkey()) .unwrap(); From 66b71ce21982f3478f9d5894ea4990a844a0d08c Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Tue, 30 Mar 2021 08:41:53 -0700 Subject: [PATCH 0063/1076] Update to Solana 1.6.2 --- clients/cli/Cargo.toml | 14 +++++++------- program/Cargo.toml | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 80a26612..9964da78 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -12,13 +12,13 @@ version = "2.0.1" borsh = "0.8" clap = "2.33.3" serde_json = "1.0.62" -solana-account-decoder = "1.6.1" -solana-clap-utils = "1.6.1" -solana-cli-config = "1.6.1" -solana-client = "1.6.1" -solana-logger = "1.6.1" -solana-sdk = "1.6.1" -solana-program = "1.6.1" +solana-account-decoder = "1.6.2" +solana-clap-utils = "1.6.2" +solana-cli-config = "1.6.2" +solana-client = "1.6.2" +solana-logger = "1.6.2" +solana-sdk = "1.6.2" +solana-program = "1.6.2" spl-stake-pool = { path="../program", features = [ "no-entrypoint" ] } spl-token = { path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" diff --git a/program/Cargo.toml b/program/Cargo.toml index affab7f7..48c909a7 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -19,7 +19,7 @@ num-traits = "0.2" num_enum = "0.5.1" serde = "1.0.121" serde_derive = "1.0.103" -solana-program = "1.6.1" +solana-program = "1.6.2" spl-math = { path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-token = { path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" @@ -27,9 +27,9 @@ bincode = "1.3.1" [dev-dependencies] proptest = "0.10" -solana-program-test = "1.6.1" -solana-sdk = "1.6.1" -solana-vote-program = "1.6.1" +solana-program-test = "1.6.2" +solana-sdk = "1.6.2" +solana-vote-program = "1.6.2" [lib] crate-type = ["cdylib", "lib"] From 21a1a0e134d222828aa44d7480460e9799673d65 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Mon, 29 Mar 2021 20:14:36 -0700 Subject: [PATCH 0064/1076] Move to positional parameters --- clients/cli/src/main.rs | 95 +++++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 46 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 6b1bc590..286956c8 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -245,9 +245,12 @@ fn command_create_pool(config: &Config, fee: PoolFee, max_validators: u32) -> Co Ok(Some(transaction)) } -fn command_vsa_create(config: &Config, pool: &Pubkey, validator: &Pubkey) -> CommandResult { - let (stake_account, _) = - PoolProcessor::find_stake_address_for_validator(&spl_stake_pool::id(), &validator, &pool); +fn command_vsa_create(config: &Config, pool: &Pubkey, vote_account: &Pubkey) -> CommandResult { + let (stake_account, _) = PoolProcessor::find_stake_address_for_validator( + &spl_stake_pool::id(), + &vote_account, + &pool, + ); println!("Creating stake account {}", stake_account); @@ -259,7 +262,7 @@ fn command_vsa_create(config: &Config, pool: &Pubkey, validator: &Pubkey) -> Com &pool, &config.fee_payer.pubkey(), &stake_account, - &validator, + &vote_account, &config.owner.pubkey(), &config.owner.pubkey(), &solana_program::system_program::id(), @@ -513,24 +516,24 @@ fn command_deposit( if config.verbose { println!("Depositing stake account {:?}", stake_data); } - let validator: Pubkey = match stake_data { + let vote_account: Pubkey = match stake_data { StakeState::Stake(_, stake) => Ok(stake.delegation.voter_pubkey), _ => Err("Wrong stake account state, must be delegated to validator"), }?; - // Check if this validator has staking account in the pool + // Check if this vote account has staking account in the pool let validator_stake_list_data = config .rpc_client .get_account_data(&pool_data.validator_stake_list)?; let validator_stake_list_data = try_from_slice_unchecked::(&validator_stake_list_data.as_slice())?; - if !validator_stake_list_data.contains(&validator) { + if !validator_stake_list_data.contains(&vote_account) { return Err("Stake account for this validator does not exist in the pool.".into()); } // Calculate validator stake account address linked to the pool let (validator_stake_account, _) = - PoolProcessor::find_stake_address_for_validator(&spl_stake_pool::id(), &validator, pool); + PoolProcessor::find_stake_address_for_validator(&spl_stake_pool::id(), &vote_account, pool); let validator_stake_data = config .rpc_client .get_account_data(&validator_stake_account)?; @@ -637,7 +640,7 @@ fn command_list(config: &Config, pool: &Pubkey) -> CommandResult { println!("Current validator list"); for validator in validator_stake_list_data.validators { println!( - "Vote: {}\tBalance: {}\tEpoch: {}", + "Vote Account: {}\tBalance: {}\tEpoch: {}", validator.validator_account, validator.balance, validator.last_update_epoch ); } @@ -664,7 +667,7 @@ fn command_list(config: &Config, pool: &Pubkey) -> CommandResult { let balance = account.lamports; total_balance += balance; println!( - "Pubkey: {}\tVote: {}\t{}", + "Stake Account: {}\tVote Account: {}\t{}", pubkey, stake_data.delegation().unwrap().voter_pubkey, Sol(balance) @@ -1108,41 +1111,41 @@ fn main() { .help("Max number of validators included in the stake pool"), ) ) - .subcommand(SubCommand::with_name("create-validator-stake").about("Create a new validator stake account to use with the pool") + .subcommand(SubCommand::with_name("create-validator-stake").about("Create a new stake account to use with the pool") .arg( Arg::with_name("pool") - .long("pool") + .index(1) .validator(is_pubkey) - .value_name("ADDRESS") + .value_name("POOL_ADDRESS") .takes_value(true) .required(true) .help("Stake pool address"), ) .arg( - Arg::with_name("validator") - .long("validator") + Arg::with_name("vote_account") + .index(2) .validator(is_pubkey) - .value_name("ADDRESS") + .value_name("VOTE_ACCOUNT_ADDRESS") .takes_value(true) .required(true) - .help("Validator this stake account will vote for"), + .help("The validator vote account that this stake will be delegated to"), ) ) .subcommand(SubCommand::with_name("add-validator-stake").about("Add validator stake account to the stake pool. Must be signed by the pool owner.") .arg( Arg::with_name("pool") - .long("pool") + .index(1) .validator(is_pubkey) - .value_name("ADDRESS") + .value_name("POOL_ADDRESS") .takes_value(true) .required(true) .help("Stake pool address"), ) .arg( - Arg::with_name("stake") - .long("stake") + Arg::with_name("stake_account") + .index(2) .validator(is_pubkey) - .value_name("ADDRESS") + .value_name("STAKE_ACCOUNT_ADDRESS") .takes_value(true) .required(true) .help("Stake account to add to the pool"), @@ -1159,18 +1162,18 @@ fn main() { .subcommand(SubCommand::with_name("remove-validator-stake").about("Add validator stake account to the stake pool. Must be signed by the pool owner.") .arg( Arg::with_name("pool") - .long("pool") + .index(1) .validator(is_pubkey) - .value_name("ADDRESS") + .value_name("POOL_ADDRESS") .takes_value(true) .required(true) .help("Stake pool address"), ) .arg( - Arg::with_name("stake") - .long("stake") + Arg::with_name("stake_account") + .index(2) .validator(is_pubkey) - .value_name("ADDRESS") + .value_name("STAKE_ACCOUNT_ADDRESS") .takes_value(true) .required(true) .help("Stake account to remove from the pool"), @@ -1196,18 +1199,18 @@ fn main() { .subcommand(SubCommand::with_name("deposit").about("Add stake account to the stake pool") .arg( Arg::with_name("pool") - .long("pool") + .index(1) .validator(is_pubkey) - .value_name("ADDRESS") + .value_name("POOL_ADDRESS") .takes_value(true) .required(true) .help("Stake pool address"), ) .arg( - Arg::with_name("stake") - .long("stake") + Arg::with_name("stake_account") + .index(2) .validator(is_pubkey) - .value_name("ADDRESS") + .value_name("STAKE_ACCOUNT_ADDRESS") .takes_value(true) .required(true) .help("Stake address to join the pool"), @@ -1224,9 +1227,9 @@ fn main() { .subcommand(SubCommand::with_name("list").about("List stake accounts managed by this pool") .arg( Arg::with_name("pool") - .long("pool") + .index(1) .validator(is_pubkey) - .value_name("ADDRESS") + .value_name("POOL_ADDRESS") .takes_value(true) .required(true) .help("Stake pool address."), @@ -1235,9 +1238,9 @@ fn main() { .subcommand(SubCommand::with_name("update").about("Updates all balances in the pool after validator stake accounts receive rewards.") .arg( Arg::with_name("pool") - .long("pool") + .index(1) .validator(is_pubkey) - .value_name("ADDRESS") + .value_name("POOL_ADDRESS") .takes_value(true) .required(true) .help("Stake pool address."), @@ -1246,9 +1249,9 @@ fn main() { .subcommand(SubCommand::with_name("withdraw").about("Withdraw amount from the stake pool") .arg( Arg::with_name("pool") - .long("pool") + .index(1) .validator(is_pubkey) - .value_name("ADDRESS") + .value_name("POOL_ADDRESS") .takes_value(true) .required(true) .help("Stake pool address."), @@ -1275,7 +1278,7 @@ fn main() { Arg::with_name("stake_receiver") .long("stake-receiver") .validator(is_pubkey) - .value_name("ADDRESS") + .value_name("STAKE_ACCOUNT_ADDRESS") .takes_value(true) .help("Stake account to receive SOL from the stake pool. Defaults to a new stake account."), ) @@ -1283,9 +1286,9 @@ fn main() { .subcommand(SubCommand::with_name("set-owner").about("Changes owner or fee receiver account for the stake pool.") .arg( Arg::with_name("pool") - .long("pool") + .index(1) .validator(is_pubkey) - .value_name("ADDRESS") + .value_name("POOL_ADDRESS") .takes_value(true) .required(true) .help("Stake pool address."), @@ -1375,18 +1378,18 @@ fn main() { } ("create-validator-stake", Some(arg_matches)) => { let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); - let validator_account: Pubkey = pubkey_of(arg_matches, "validator").unwrap(); - command_vsa_create(&config, &pool_account, &validator_account) + let vote_account: Pubkey = pubkey_of(arg_matches, "vote_account").unwrap(); + command_vsa_create(&config, &pool_account, &vote_account) } ("add-validator-stake", Some(arg_matches)) => { let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); - let stake_account: Pubkey = pubkey_of(arg_matches, "stake").unwrap(); + let stake_account: Pubkey = pubkey_of(arg_matches, "stake_account").unwrap(); let token_receiver: Option = pubkey_of(arg_matches, "token_receiver"); command_vsa_add(&config, &pool_account, &stake_account, &token_receiver) } ("remove-validator-stake", Some(arg_matches)) => { let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); - let stake_account: Pubkey = pubkey_of(arg_matches, "stake").unwrap(); + let stake_account: Pubkey = pubkey_of(arg_matches, "stake_account").unwrap(); let withdraw_from: Pubkey = pubkey_of(arg_matches, "withdraw_from").unwrap(); let new_authority: Option = pubkey_of(arg_matches, "new_authority"); command_vsa_remove( @@ -1399,7 +1402,7 @@ fn main() { } ("deposit", Some(arg_matches)) => { let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); - let stake_account: Pubkey = pubkey_of(arg_matches, "stake").unwrap(); + let stake_account: Pubkey = pubkey_of(arg_matches, "stake_account").unwrap(); let token_receiver: Option = pubkey_of(arg_matches, "token_receiver"); command_deposit(&config, &pool_account, &stake_account, &token_receiver) } From 139d99b0f9e0f7dec2d970c72480140bdd897db2 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Tue, 30 Mar 2021 09:38:18 -0700 Subject: [PATCH 0065/1076] add-validator-stake now cleanly errors if non-active stake is provided --- clients/cli/src/main.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 286956c8..28263834 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -16,9 +16,9 @@ use { }, solana_client::{ rpc_client::RpcClient, - rpc_config::RpcAccountInfoConfig, - rpc_config::RpcProgramAccountsConfig, + rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig}, rpc_filter::{Memcmp, MemcmpEncodedBytes, RpcFilterType}, + rpc_response::StakeActivationState, }, solana_program::{ borsh::get_packed_len, instruction::Instruction, program_pack::Pack, pubkey::Pubkey, @@ -284,6 +284,10 @@ fn command_vsa_add( stake: &Pubkey, token_receiver: &Option, ) -> CommandResult { + if config.rpc_client.get_stake_activation(*stake, None)?.state != StakeActivationState::Active { + return Err("Stake account is not active.".into()); + } + // Get stake pool state let pool_data = config.rpc_client.get_account_data(&pool)?; let pool_data = StakePool::try_from_slice(pool_data.as_slice()).unwrap(); From eec7db9201ae6dc48d46d09db2f15048c2118093 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Tue, 30 Mar 2021 12:06:53 -0700 Subject: [PATCH 0066/1076] Automatically update the stake pool if needed, use the `--no-update` flag to disable --- clients/cli/src/main.rs | 88 +++++++++++++++++++++++++++++------------ 1 file changed, 62 insertions(+), 26 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 28263834..01067341 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -60,10 +60,11 @@ struct Config { owner: Box, fee_payer: Box, dry_run: bool, + no_update: bool, } type Error = Box; -type CommandResult = Result, Error>; +type CommandResult = Result<(), Error>; const STAKE_STATE_LEN: usize = 200; const MAX_ACCOUNTS_TO_UPDATE: usize = 10; @@ -115,6 +116,22 @@ fn get_authority_accounts(config: &Config, authority: &Pubkey) -> Vec<(Pubkey, A .unwrap() } +fn send_transaction( + config: &Config, + transaction: Transaction, +) -> solana_client::client_error::Result<()> { + if config.dry_run { + let result = config.rpc_client.simulate_transaction(&transaction)?; + println!("Simulate result: {:?}", result); + } else { + let signature = config + .rpc_client + .send_and_confirm_transaction_with_spinner(&transaction)?; + println!("Signature: {}", signature); + } + Ok(()) +} + fn command_create_pool(config: &Config, fee: PoolFee, max_validators: u32) -> CommandResult { let mint_account = Keypair::new(); println!("Creating mint {}", mint_account.pubkey()); @@ -242,7 +259,8 @@ fn command_create_pool(config: &Config, fee: PoolFee, max_validators: u32) -> Co ]; unique_signers!(signers); transaction.sign(&signers, recent_blockhash); - Ok(Some(transaction)) + send_transaction(&config, transaction)?; + Ok(()) } fn command_vsa_create(config: &Config, pool: &Pubkey, vote_account: &Pubkey) -> CommandResult { @@ -275,7 +293,8 @@ fn command_vsa_create(config: &Config, pool: &Pubkey, vote_account: &Pubkey) -> let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; transaction.sign(&[config.fee_payer.as_ref()], recent_blockhash); - Ok(Some(transaction)) + send_transaction(&config, transaction)?; + Ok(()) } fn command_vsa_add( @@ -288,6 +307,10 @@ fn command_vsa_add( return Err("Stake account is not active.".into()); } + if !config.no_update { + command_update(config, pool)?; + } + // Get stake pool state let pool_data = config.rpc_client.get_account_data(&pool)?; let pool_data = StakePool::try_from_slice(pool_data.as_slice()).unwrap(); @@ -369,7 +392,8 @@ fn command_vsa_add( )?; unique_signers!(signers); transaction.sign(&signers, recent_blockhash); - Ok(Some(transaction)) + send_transaction(&config, transaction)?; + Ok(()) } fn command_vsa_remove( @@ -379,6 +403,10 @@ fn command_vsa_remove( withdraw_from: &Pubkey, new_authority: &Option, ) -> CommandResult { + if !config.no_update { + command_update(config, pool)?; + } + // Get stake pool state let pool_data = config.rpc_client.get_account_data(&pool)?; let pool_data: StakePool = StakePool::try_from_slice(pool_data.as_slice()).unwrap(); @@ -453,7 +481,8 @@ fn command_vsa_remove( &[config.fee_payer.as_ref(), config.owner.as_ref()], recent_blockhash, ); - Ok(Some(transaction)) + send_transaction(&config, transaction)?; + Ok(()) } fn unwrap_create_token_account( @@ -509,6 +538,10 @@ fn command_deposit( stake: &Pubkey, token_receiver: &Option, ) -> CommandResult { + if !config.no_update { + command_update(config, pool)?; + } + // Get stake pool state let pool_data = config.rpc_client.get_account_data(&pool)?; let pool_data: StakePool = StakePool::try_from_slice(pool_data.as_slice()).unwrap(); @@ -627,7 +660,8 @@ fn command_deposit( )?; unique_signers!(signers); transaction.sign(&signers, recent_blockhash); - Ok(Some(transaction)) + send_transaction(&config, transaction)?; + Ok(()) } fn command_list(config: &Config, pool: &Pubkey) -> CommandResult { @@ -679,7 +713,7 @@ fn command_list(config: &Config, pool: &Pubkey) -> CommandResult { } println!("Total: {}", Sol(total_balance)); - Ok(None) + Ok(()) } fn command_update(config: &Config, pool: &Pubkey) -> CommandResult { @@ -723,8 +757,9 @@ fn command_update(config: &Config, pool: &Pubkey) -> CommandResult { if instructions.is_empty() && pool_data.last_update_epoch == epoch_info.epoch { println!("Stake pool balances are up to date, no update required."); - Ok(None) + Ok(()) } else { + println!("Updating stake pool..."); instructions.push(update_pool_balance( &spl_stake_pool::id(), pool, @@ -737,7 +772,8 @@ fn command_update(config: &Config, pool: &Pubkey) -> CommandResult { let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; transaction.sign(&[config.fee_payer.as_ref()], recent_blockhash); - Ok(Some(transaction)) + send_transaction(&config, transaction)?; + Ok(()) } } @@ -829,6 +865,10 @@ fn command_withdraw( withdraw_from: &Pubkey, stake_receiver_param: &Option, ) -> CommandResult { + if !config.no_update { + command_update(config, pool)?; + } + // Get stake pool state let pool_data = config.rpc_client.get_account_data(&pool)?; let pool_data = StakePool::try_from_slice(pool_data.as_slice()).unwrap(); @@ -959,8 +999,8 @@ fn command_withdraw( )?; unique_signers!(signers); transaction.sign(&signers, recent_blockhash); - - Ok(Some(transaction)) + send_transaction(&config, transaction)?; + Ok(()) } fn command_set_owner( @@ -1014,7 +1054,8 @@ fn command_set_owner( let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()]; unique_signers!(signers); transaction.sign(&signers, recent_blockhash); - Ok(Some(transaction)) + send_transaction(&config, transaction)?; + Ok(()) } fn main() { @@ -1051,6 +1092,13 @@ fn main() { .global(true) .help("Simluate transaction instead of executing"), ) + .arg( + Arg::with_name("no_update") + .long("no-update") + .takes_value(false) + .global(true) + .help("Do not automatically update the stake pool if needed"), + ) .arg( Arg::with_name("json_rpc_url") .long("url") @@ -1354,6 +1402,7 @@ fn main() { }); let verbose = matches.is_present("verbose"); let dry_run = matches.is_present("dry_run"); + let no_update = matches.is_present("no_update"); Config { rpc_client: RpcClient::new_with_commitment(json_rpc_url, CommitmentConfig::confirmed()), @@ -1361,6 +1410,7 @@ fn main() { owner, fee_payer, dry_run, + no_update, } }; @@ -1439,20 +1489,6 @@ fn main() { } _ => unreachable!(), } - .and_then(|transaction| { - if let Some(transaction) = transaction { - if config.dry_run { - let result = config.rpc_client.simulate_transaction(&transaction)?; - println!("Simulate result: {:?}", result); - } else { - let signature = config - .rpc_client - .send_and_confirm_transaction_with_spinner(&transaction)?; - println!("Signature: {}", signature); - } - } - Ok(()) - }) .map_err(|err| { eprintln!("{}", err); exit(1); From 729ad9fe0b6e473c8a82d901627796edae1607d6 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 30 Mar 2021 23:54:06 +0200 Subject: [PATCH 0067/1076] stake-pool: Rename instructions / structs (#1536) * stake-pool: Rename instructions / structs * Cargo fmt * Fix proptest --- clients/cli/src/main.rs | 86 +++++----- program/proptest-regressions/state.txt | 1 + program/src/instruction.rs | 64 +++---- program/src/processor.rs | 161 +++++++++--------- program/src/state.rs | 51 +++--- program/tests/deposit.rs | 36 ++-- program/tests/helpers/mod.rs | 46 ++--- program/tests/initialize.rs | 95 +++++------ ...alance.rs => update_stake_pool_balance.rs} | 10 +- ...ce.rs => update_validator_list_balance.rs} | 23 ++- program/tests/vsa_add.rs | 73 ++++---- program/tests/vsa_remove.rs | 71 ++++---- program/tests/withdraw.rs | 36 ++-- 13 files changed, 368 insertions(+), 385 deletions(-) create mode 100644 program/proptest-regressions/state.txt rename program/tests/{update_pool_balance.rs => update_stake_pool_balance.rs} (85%) rename program/tests/{update_list_balance.rs => update_validator_list_balance.rs} (76%) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 01067341..2802119e 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -34,9 +34,9 @@ use { spl_stake_pool::{ borsh::{get_instance_packed_len, try_from_slice_unchecked}, instruction::{ - add_validator_stake_account, create_validator_stake_account, deposit, - initialize as initialize_pool, remove_validator_stake_account, set_owner, - update_list_balance, update_pool_balance, withdraw, Fee as PoolFee, + add_validator_to_pool, create_validator_stake_account, deposit, + initialize as initialize_pool, remove_validator_from_pool, set_owner, + update_stake_pool_balance, update_validator_list_balance, withdraw, Fee as PoolFee, }, processor::Processor as PoolProcessor, stake::authorize as authorize_stake, @@ -44,7 +44,7 @@ use { stake::StakeAuthorize, stake::StakeState, state::StakePool, - state::ValidatorStakeList, + state::ValidatorList, }, spl_token::{ self, instruction::approve as approve_token, instruction::initialize_account, @@ -145,7 +145,7 @@ fn command_create_pool(config: &Config, fee: PoolFee, max_validators: u32) -> Co let pool_account = Keypair::new(); println!("Creating stake pool {}", pool_account.pubkey()); - let validator_stake_list = Keypair::new(); + let validator_list = Keypair::new(); let mint_account_balance = config .rpc_client @@ -156,15 +156,15 @@ fn command_create_pool(config: &Config, fee: PoolFee, max_validators: u32) -> Co let pool_account_balance = config .rpc_client .get_minimum_balance_for_rent_exemption(get_packed_len::())?; - let empty_validator_list = ValidatorStakeList::new_with_max_validators(max_validators); - let validator_stake_list_size = get_instance_packed_len(&empty_validator_list)?; - let validator_stake_list_balance = config + let empty_validator_list = ValidatorList::new_with_max_validators(max_validators); + let validator_list_size = get_instance_packed_len(&empty_validator_list)?; + let validator_list_balance = config .rpc_client - .get_minimum_balance_for_rent_exemption(validator_stake_list_size)?; + .get_minimum_balance_for_rent_exemption(validator_list_size)?; let total_rent_free_balances = mint_account_balance + pool_fee_account_balance + pool_account_balance - + validator_stake_list_balance; + + validator_list_balance; let default_decimals = native_mint::DECIMALS; @@ -208,9 +208,9 @@ fn command_create_pool(config: &Config, fee: PoolFee, max_validators: u32) -> Co // Validator stake account list storage system_instruction::create_account( &config.fee_payer.pubkey(), - &validator_stake_list.pubkey(), - validator_stake_list_balance, - validator_stake_list_size as u64, + &validator_list.pubkey(), + validator_list_balance, + validator_list_size as u64, &spl_stake_pool::id(), ), // Initialize pool token mint account @@ -233,7 +233,7 @@ fn command_create_pool(config: &Config, fee: PoolFee, max_validators: u32) -> Co &spl_stake_pool::id(), &pool_account.pubkey(), &config.owner.pubkey(), - &validator_stake_list.pubkey(), + &validator_list.pubkey(), &mint_account.pubkey(), &pool_fee_account.pubkey(), &spl_token::id(), @@ -252,7 +252,7 @@ fn command_create_pool(config: &Config, fee: PoolFee, max_validators: u32) -> Co let mut signers = vec![ config.fee_payer.as_ref(), &pool_account, - &validator_stake_list, + &validator_list, &mint_account, &pool_fee_account, config.owner.as_ref(), @@ -367,13 +367,13 @@ fn command_vsa_add( StakeAuthorize::Staker, ), // Add validator stake account to the pool - add_validator_stake_account( + add_validator_to_pool( &spl_stake_pool::id(), &pool, &config.owner.pubkey(), &pool_deposit_authority, &pool_withdraw_authority, - &pool_data.validator_stake_list, + &pool_data.validator_list, &stake, &token_receiver, &pool_data.pool_mint, @@ -458,13 +458,13 @@ fn command_vsa_remove( tokens_to_withdraw, )?, // Create new validator stake account address - remove_validator_stake_account( + remove_validator_from_pool( &spl_stake_pool::id(), &pool, &config.owner.pubkey(), &pool_withdraw_authority, &new_authority, - &pool_data.validator_stake_list, + &pool_data.validator_list, &stake, &withdraw_from, &pool_data.pool_mint, @@ -559,12 +559,12 @@ fn command_deposit( }?; // Check if this vote account has staking account in the pool - let validator_stake_list_data = config + let validator_list_data = config .rpc_client - .get_account_data(&pool_data.validator_stake_list)?; - let validator_stake_list_data = - try_from_slice_unchecked::(&validator_stake_list_data.as_slice())?; - if !validator_stake_list_data.contains(&vote_account) { + .get_account_data(&pool_data.validator_list)?; + let validator_list_data = + try_from_slice_unchecked::(&validator_list_data.as_slice())?; + if !validator_list_data.contains(&vote_account) { return Err("Stake account for this validator does not exist in the pool.".into()); } @@ -637,7 +637,7 @@ fn command_deposit( deposit( &spl_stake_pool::id(), &pool, - &pool_data.validator_stake_list, + &pool_data.validator_list, &pool_deposit_authority, &pool_withdraw_authority, &stake, @@ -672,11 +672,11 @@ fn command_list(config: &Config, pool: &Pubkey) -> CommandResult { if config.verbose { let validator_list = config .rpc_client - .get_account_data(&pool_data.validator_stake_list)?; - let validator_stake_list_data = - try_from_slice_unchecked::(&validator_list.as_slice())?; + .get_account_data(&pool_data.validator_list)?; + let validator_list_data = + try_from_slice_unchecked::(&validator_list.as_slice())?; println!("Current validator list"); - for validator in validator_stake_list_data.validators { + for validator in validator_list_data.validators { println!( "Vote Account: {}\tBalance: {}\tEpoch: {}", validator.validator_account, validator.balance, validator.last_update_epoch @@ -720,15 +720,15 @@ fn command_update(config: &Config, pool: &Pubkey) -> CommandResult { // Get stake pool state let pool_data = config.rpc_client.get_account_data(&pool)?; let pool_data = StakePool::try_from_slice(pool_data.as_slice()).unwrap(); - let validator_stake_list_data = config + let validator_list_data = config .rpc_client - .get_account_data(&pool_data.validator_stake_list)?; - let validator_stake_list_data = - try_from_slice_unchecked::(&validator_stake_list_data.as_slice())?; + .get_account_data(&pool_data.validator_list)?; + let validator_list_data = + try_from_slice_unchecked::(&validator_list_data.as_slice())?; let epoch_info = config.rpc_client.get_epoch_info()?; - let accounts_to_update: Vec = validator_stake_list_data + let accounts_to_update: Vec = validator_list_data .validators .iter() .filter_map(|item| { @@ -748,9 +748,9 @@ fn command_update(config: &Config, pool: &Pubkey) -> CommandResult { let mut instructions: Vec = vec![]; for chunk in accounts_to_update.chunks(MAX_ACCOUNTS_TO_UPDATE) { - instructions.push(update_list_balance( + instructions.push(update_validator_list_balance( &spl_stake_pool::id(), - &pool_data.validator_stake_list, + &pool_data.validator_list, &chunk, )?); } @@ -760,10 +760,10 @@ fn command_update(config: &Config, pool: &Pubkey) -> CommandResult { Ok(()) } else { println!("Updating stake pool..."); - instructions.push(update_pool_balance( + instructions.push(update_stake_pool_balance( &spl_stake_pool::id(), pool, - &pool_data.validator_stake_list, + &pool_data.validator_list, )?); let mut transaction = @@ -976,7 +976,7 @@ fn command_withdraw( instructions.push(withdraw( &spl_stake_pool::id(), &pool, - &pool_data.validator_stake_list, + &pool_data.validator_list, &pool_withdraw_authority, &withdraw_stake.pubkey, &stake_receiver.unwrap(), // Cannot be none at this point @@ -1183,7 +1183,7 @@ fn main() { .help("The validator vote account that this stake will be delegated to"), ) ) - .subcommand(SubCommand::with_name("add-validator-stake").about("Add validator stake account to the stake pool. Must be signed by the pool owner.") + .subcommand(SubCommand::with_name("add-validator").about("Add validator account to the stake pool. Must be signed by the pool owner.") .arg( Arg::with_name("pool") .index(1) @@ -1211,7 +1211,7 @@ fn main() { .help("Account to receive pool token. Must be initialized account of the stake pool token. Defaults to the new pool token account."), ) ) - .subcommand(SubCommand::with_name("remove-validator-stake").about("Add validator stake account to the stake pool. Must be signed by the pool owner.") + .subcommand(SubCommand::with_name("remove-validator").about("Remove validator account from the stake pool. Must be signed by the pool owner.") .arg( Arg::with_name("pool") .index(1) @@ -1435,13 +1435,13 @@ fn main() { let vote_account: Pubkey = pubkey_of(arg_matches, "vote_account").unwrap(); command_vsa_create(&config, &pool_account, &vote_account) } - ("add-validator-stake", Some(arg_matches)) => { + ("add-validator", Some(arg_matches)) => { let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); let stake_account: Pubkey = pubkey_of(arg_matches, "stake_account").unwrap(); let token_receiver: Option = pubkey_of(arg_matches, "token_receiver"); command_vsa_add(&config, &pool_account, &stake_account, &token_receiver) } - ("remove-validator-stake", Some(arg_matches)) => { + ("remove-validator", Some(arg_matches)) => { let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); let stake_account: Pubkey = pubkey_of(arg_matches, "stake_account").unwrap(); let withdraw_from: Pubkey = pubkey_of(arg_matches, "withdraw_from").unwrap(); diff --git a/program/proptest-regressions/state.txt b/program/proptest-regressions/state.txt new file mode 100644 index 00000000..769e8a16 --- /dev/null +++ b/program/proptest-regressions/state.txt @@ -0,0 +1 @@ +cc 41ce1c46341336993e5e5d5aa94c30865e63f9e00d31d397aef88ec79fc312ca diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 40ff18ad..eb2881a5 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -72,7 +72,7 @@ pub enum StakePoolInstruction { /// 9. '[]' Sysvar stake history account /// 10. `[]` Pool token program id, /// 11. `[]` Stake program id, - AddValidatorStakeAccount, + AddValidatorToPool, /// Removes validator stake account from the pool /// @@ -87,21 +87,21 @@ pub enum StakePoolInstruction { /// 8. '[]' Sysvar clock account (required) /// 9. `[]` Pool token program id /// 10. `[]` Stake program id, - RemoveValidatorStakeAccount, + RemoveValidatorFromPool, /// Updates balances of validator stake accounts in the pool /// /// 0. `[w]` Validator stake list storage account /// 1. `[]` Sysvar clock account /// 2. ..2+N ` [] N validator stake accounts to update balances - UpdateListBalance, + UpdateValidatorListBalance, /// Updates total pool balance based on balances in validator stake account list storage /// /// 0. `[w]` Stake pool /// 1. `[]` Validator stake list storage account /// 2. `[]` Sysvar clock account - UpdatePoolBalance, + UpdateStakePoolBalance, /// Deposit some stake into the pool. The output is a "pool" token representing ownership /// into the pool. Inputs are converted to the current ratio. @@ -152,7 +152,7 @@ pub fn initialize( program_id: &Pubkey, stake_pool: &Pubkey, owner: &Pubkey, - validator_stake_list: &Pubkey, + validator_list: &Pubkey, pool_mint: &Pubkey, owner_pool_account: &Pubkey, token_program_id: &Pubkey, @@ -167,7 +167,7 @@ pub fn initialize( let accounts = vec![ AccountMeta::new(*stake_pool, true), AccountMeta::new_readonly(*owner, true), - AccountMeta::new(*validator_stake_list, false), + AccountMeta::new(*validator_list, false), AccountMeta::new_readonly(*pool_mint, false), AccountMeta::new_readonly(*owner_pool_account, false), AccountMeta::new_readonly(sysvar::clock::id(), false), @@ -211,14 +211,14 @@ pub fn create_validator_stake_account( }) } -/// Creates `AddValidatorStakeAccount` instruction (add new validator stake account to the pool) -pub fn add_validator_stake_account( +/// Creates `AddValidatorToPool` instruction (add new validator stake account to the pool) +pub fn add_validator_to_pool( program_id: &Pubkey, stake_pool: &Pubkey, owner: &Pubkey, stake_pool_deposit: &Pubkey, stake_pool_withdraw: &Pubkey, - validator_stake_list: &Pubkey, + validator_list: &Pubkey, stake_account: &Pubkey, pool_tokens_to: &Pubkey, pool_mint: &Pubkey, @@ -230,7 +230,7 @@ pub fn add_validator_stake_account( AccountMeta::new_readonly(*owner, true), AccountMeta::new_readonly(*stake_pool_deposit, false), AccountMeta::new_readonly(*stake_pool_withdraw, false), - AccountMeta::new(*validator_stake_list, false), + AccountMeta::new(*validator_list, false), AccountMeta::new(*stake_account, false), AccountMeta::new(*pool_tokens_to, false), AccountMeta::new(*pool_mint, false), @@ -242,18 +242,18 @@ pub fn add_validator_stake_account( Ok(Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::AddValidatorStakeAccount.try_to_vec()?, + data: StakePoolInstruction::AddValidatorToPool.try_to_vec()?, }) } -/// Creates `RemoveValidatorStakeAccount` instruction (remove validator stake account from the pool) -pub fn remove_validator_stake_account( +/// Creates `RemoveValidatorFromPool` instruction (remove validator stake account from the pool) +pub fn remove_validator_from_pool( program_id: &Pubkey, stake_pool: &Pubkey, owner: &Pubkey, stake_pool_withdraw: &Pubkey, new_stake_authority: &Pubkey, - validator_stake_list: &Pubkey, + validator_list: &Pubkey, stake_account: &Pubkey, burn_from: &Pubkey, pool_mint: &Pubkey, @@ -265,7 +265,7 @@ pub fn remove_validator_stake_account( AccountMeta::new_readonly(*owner, true), AccountMeta::new_readonly(*stake_pool_withdraw, false), AccountMeta::new_readonly(*new_stake_authority, false), - AccountMeta::new(*validator_stake_list, false), + AccountMeta::new(*validator_list, false), AccountMeta::new(*stake_account, false), AccountMeta::new(*burn_from, false), AccountMeta::new(*pool_mint, false), @@ -276,44 +276,44 @@ pub fn remove_validator_stake_account( Ok(Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::RemoveValidatorStakeAccount.try_to_vec()?, + data: StakePoolInstruction::RemoveValidatorFromPool.try_to_vec()?, }) } -/// Creates `UpdateListBalance` instruction (update validator stake account balances) -pub fn update_list_balance( +/// Creates `UpdateValidatorListBalance` instruction (update validator stake account balances) +pub fn update_validator_list_balance( program_id: &Pubkey, - validator_stake_list_storage: &Pubkey, - validator_stake_list: &[Pubkey], + validator_list_storage: &Pubkey, + validator_list: &[Pubkey], ) -> Result { - let mut accounts: Vec = validator_stake_list + let mut accounts: Vec = validator_list .iter() .map(|pubkey| AccountMeta::new_readonly(*pubkey, false)) .collect(); - accounts.insert(0, AccountMeta::new(*validator_stake_list_storage, false)); + accounts.insert(0, AccountMeta::new(*validator_list_storage, false)); accounts.insert(1, AccountMeta::new_readonly(sysvar::clock::id(), false)); Ok(Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::UpdateListBalance.try_to_vec()?, + data: StakePoolInstruction::UpdateValidatorListBalance.try_to_vec()?, }) } -/// Creates `UpdatePoolBalance` instruction (pool balance from the stake account list balances) -pub fn update_pool_balance( +/// Creates `UpdateStakePoolBalance` instruction (pool balance from the stake account list balances) +pub fn update_stake_pool_balance( program_id: &Pubkey, stake_pool: &Pubkey, - validator_stake_list_storage: &Pubkey, + validator_list_storage: &Pubkey, ) -> Result { let accounts = vec![ AccountMeta::new(*stake_pool, false), - AccountMeta::new(*validator_stake_list_storage, false), + AccountMeta::new(*validator_list_storage, false), AccountMeta::new_readonly(sysvar::clock::id(), false), ]; Ok(Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::UpdatePoolBalance.try_to_vec()?, + data: StakePoolInstruction::UpdateStakePoolBalance.try_to_vec()?, }) } @@ -321,7 +321,7 @@ pub fn update_pool_balance( pub fn deposit( program_id: &Pubkey, stake_pool: &Pubkey, - validator_stake_list_storage: &Pubkey, + validator_list_storage: &Pubkey, stake_pool_deposit: &Pubkey, stake_pool_withdraw: &Pubkey, stake_to_join: &Pubkey, @@ -334,7 +334,7 @@ pub fn deposit( ) -> Result { let accounts = vec![ AccountMeta::new(*stake_pool, false), - AccountMeta::new(*validator_stake_list_storage, false), + AccountMeta::new(*validator_list_storage, false), AccountMeta::new_readonly(*stake_pool_deposit, false), AccountMeta::new_readonly(*stake_pool_withdraw, false), AccountMeta::new(*stake_to_join, false), @@ -358,7 +358,7 @@ pub fn deposit( pub fn withdraw( program_id: &Pubkey, stake_pool: &Pubkey, - validator_stake_list_storage: &Pubkey, + validator_list_storage: &Pubkey, stake_pool_withdraw: &Pubkey, stake_to_split: &Pubkey, stake_to_receive: &Pubkey, @@ -371,7 +371,7 @@ pub fn withdraw( ) -> Result { let accounts = vec![ AccountMeta::new(*stake_pool, false), - AccountMeta::new(*validator_stake_list_storage, false), + AccountMeta::new(*validator_list_storage, false), AccountMeta::new_readonly(*stake_pool_withdraw, false), AccountMeta::new(*stake_to_split, false), AccountMeta::new(*stake_to_receive, false), diff --git a/program/src/processor.rs b/program/src/processor.rs index ee1140a6..ad1e790b 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -6,7 +6,7 @@ use { error::StakePoolError, instruction::{Fee, StakePoolInstruction}, stake, - state::{AccountType, StakePool, ValidatorStakeInfo, ValidatorStakeList}, + state::{AccountType, StakePool, ValidatorList, ValidatorStakeInfo}, }, bincode::deserialize, borsh::{BorshDeserialize, BorshSerialize}, @@ -281,7 +281,7 @@ impl Processor { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; let owner_info = next_account_info(account_info_iter)?; - let validator_stake_list_info = next_account_info(account_info_iter)?; + let validator_list_info = next_account_info(account_info_iter)?; let pool_mint_info = next_account_info(account_info_iter)?; let owner_fee_info = next_account_info(account_info_iter)?; // Clock sysvar account @@ -305,21 +305,20 @@ impl Processor { } // Check if validator stake list storage is unitialized - let mut validator_stake_list = try_from_slice_unchecked::( - &validator_stake_list_info.data.borrow(), - )?; - if !validator_stake_list.is_uninitialized() { + let mut validator_list = + try_from_slice_unchecked::(&validator_list_info.data.borrow())?; + if !validator_list.is_uninitialized() { return Err(StakePoolError::AlreadyInUse.into()); } // Check validator list size - let data_length = validator_stake_list_info.data_len(); - let expected_max_validators = ValidatorStakeList::calculate_max_validators(data_length); + let data_length = validator_list_info.data_len(); + let expected_max_validators = ValidatorList::calculate_max_validators(data_length); if expected_max_validators != max_validators as usize || max_validators == 0 { return Err(StakePoolError::UnexpectedValidatorListAccountSize.into()); } - validator_stake_list.account_type = AccountType::ValidatorStakeList; - validator_stake_list.validators.clear(); - validator_stake_list.max_validators = max_validators; + validator_list.account_type = AccountType::ValidatorList; + validator_list.validators.clear(); + validator_list.max_validators = max_validators; // Check if stake pool account is rent-exempt if !rent.is_exempt(stake_pool_info.lamports(), stake_pool_info.data_len()) { @@ -329,8 +328,8 @@ impl Processor { // Check if validator stake list account is rent-exempt if !rent.is_exempt( - validator_stake_list_info.lamports(), - validator_stake_list_info.data_len(), + validator_list_info.lamports(), + validator_list_info.data_len(), ) { msg!("Validator stake list not rent-exempt"); return Err(ProgramError::AccountNotRentExempt); @@ -375,7 +374,7 @@ impl Processor { return Err(StakePoolError::WrongMintingAuthority.into()); } - validator_stake_list.serialize(&mut *validator_stake_list_info.data.borrow_mut())?; + validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; msg!("Clock data: {:?}", clock_info.data.borrow()); msg!("Epoch: {}", clock.epoch); @@ -384,7 +383,7 @@ impl Processor { stake_pool.owner = *owner_info.key; stake_pool.deposit_bump_seed = deposit_bump_seed; stake_pool.withdraw_bump_seed = withdraw_bump_seed; - stake_pool.validator_stake_list = *validator_stake_list_info.key; + stake_pool.validator_list = *validator_list_info.key; stake_pool.pool_mint = *pool_mint_info.key; stake_pool.owner_fee_account = *owner_fee_info.key; stake_pool.token_program_id = *token_program_info.key; @@ -480,8 +479,8 @@ impl Processor { ) } - /// Processes `AddValidatorStakeAccount` instruction. - pub fn process_add_validator_stake_account( + /// Processes `AddValidatorToPool` instruction. + pub fn process_add_validator_to_pool( program_id: &Pubkey, accounts: &[AccountInfo], ) -> ProgramResult { @@ -495,7 +494,7 @@ impl Processor { // Stake pool withdraw authority let withdraw_info = next_account_info(account_info_iter)?; // Account storing validator stake list - let validator_stake_list_info = next_account_info(account_info_iter)?; + let validator_list_info = next_account_info(account_info_iter)?; // Stake account to add to the pool let stake_account_info = next_account_info(account_info_iter)?; // User account to receive pool tokens @@ -544,25 +543,24 @@ impl Processor { } // Check validator stake account list storage - if *validator_stake_list_info.key != stake_pool.validator_stake_list { + if *validator_list_info.key != stake_pool.validator_list { return Err(StakePoolError::InvalidValidatorStakeList.into()); } // Read validator stake list account and check if it is valid - let mut validator_stake_list = try_from_slice_unchecked::( - &validator_stake_list_info.data.borrow(), - )?; - if !validator_stake_list.is_valid() { + let mut validator_list = + try_from_slice_unchecked::(&validator_list_info.data.borrow())?; + if !validator_list.is_valid() { return Err(StakePoolError::InvalidState.into()); } - if validator_stake_list.max_validators as usize == validator_stake_list.validators.len() { + if validator_list.max_validators as usize == validator_list.validators.len() { return Err(ProgramError::AccountDataTooSmall); } let validator_account = Self::get_validator_checked(program_id, stake_pool_info, stake_account_info)?; - if validator_stake_list.contains(&validator_account) { + if validator_list.contains(&validator_account) { return Err(StakePoolError::ValidatorAlreadyAdded.into()); } @@ -604,12 +602,12 @@ impl Processor { Self::check_stake_activation(stake_account_info, clock, stake_history)?; // Add validator to the list and save - validator_stake_list.validators.push(ValidatorStakeInfo { + validator_list.validators.push(ValidatorStakeInfo { validator_account, balance: stake_lamports, last_update_epoch: clock.epoch, }); - validator_stake_list.serialize(&mut *validator_stake_list_info.data.borrow_mut())?; + validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; // Save amounts to the stake pool state stake_pool.pool_total += token_amount; @@ -620,8 +618,8 @@ impl Processor { Ok(()) } - /// Processes `RemoveValidatorStakeAccount` instruction. - pub fn process_remove_validator_stake_account( + /// Processes `RemoveValidatorFromPool` instruction. + pub fn process_remove_validator_from_pool( program_id: &Pubkey, accounts: &[AccountInfo], ) -> ProgramResult { @@ -635,7 +633,7 @@ impl Processor { // New stake authority let new_stake_authority_info = next_account_info(account_info_iter)?; // Account storing validator stake list - let validator_stake_list_info = next_account_info(account_info_iter)?; + let validator_list_info = next_account_info(account_info_iter)?; // Stake account to remove from the pool let stake_account_info = next_account_info(account_info_iter)?; // User account with pool tokens to burn from @@ -680,22 +678,21 @@ impl Processor { } // Check validator stake account list storage - if *validator_stake_list_info.key != stake_pool.validator_stake_list { + if *validator_list_info.key != stake_pool.validator_list { return Err(StakePoolError::InvalidValidatorStakeList.into()); } // Read validator stake list account and check if it is valid - let mut validator_stake_list = try_from_slice_unchecked::( - &validator_stake_list_info.data.borrow(), - )?; - if !validator_stake_list.is_valid() { + let mut validator_list = + try_from_slice_unchecked::(&validator_list_info.data.borrow())?; + if !validator_list.is_valid() { return Err(StakePoolError::InvalidState.into()); } let validator_account = Self::get_validator_checked(program_id, stake_pool_info, stake_account_info)?; - if !validator_stake_list.contains(&validator_account) { + if !validator_list.contains(&validator_account) { return Err(StakePoolError::ValidatorNotFound.into()); } @@ -734,10 +731,10 @@ impl Processor { )?; // Remove validator from the list and save - validator_stake_list + validator_list .validators .retain(|item| item.validator_account != validator_account); - validator_stake_list.serialize(&mut *validator_stake_list_info.data.borrow_mut())?; + validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; // Save amounts to the stake pool state stake_pool.pool_total -= token_amount; @@ -748,14 +745,14 @@ impl Processor { Ok(()) } - /// Processes `UpdateListBalance` instruction. - pub fn process_update_list_balance( + /// Processes `UpdateValidatorListBalance` instruction. + pub fn process_update_validator_list_balance( _program_id: &Pubkey, accounts: &[AccountInfo], ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); // Account storing validator stake list - let validator_stake_list_info = next_account_info(account_info_iter)?; + let validator_list_info = next_account_info(account_info_iter)?; // Clock sysvar account let clock_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(clock_info)?; @@ -763,10 +760,9 @@ impl Processor { let validator_stake_accounts = account_info_iter.as_slice(); // Read validator stake list account and check if it is valid - let mut validator_stake_list = try_from_slice_unchecked::( - &validator_stake_list_info.data.borrow(), - )?; - if !validator_stake_list.is_valid() { + let mut validator_list = + try_from_slice_unchecked::(&validator_list_info.data.borrow())?; + if !validator_list.is_valid() { return Err(StakePoolError::InvalidState.into()); } @@ -777,7 +773,7 @@ impl Processor { let mut changes = false; // Do a brute iteration through the list, optimize if necessary - for validator_stake_record in &mut validator_stake_list.validators { + for validator_stake_record in &mut validator_list.validators { if validator_stake_record.last_update_epoch >= clock.epoch { continue; } @@ -797,14 +793,14 @@ impl Processor { } if changes { - validator_stake_list.serialize(&mut *validator_stake_list_info.data.borrow_mut())?; + validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; } Ok(()) } - /// Processes `UpdatePoolBalance` instruction. - pub fn process_update_pool_balance( + /// Processes `UpdateStakePoolBalance` instruction. + pub fn process_update_stake_pool_balance( _program_id: &Pubkey, accounts: &[AccountInfo], ) -> ProgramResult { @@ -812,7 +808,7 @@ impl Processor { // Stake pool account let stake_pool_info = next_account_info(account_info_iter)?; // Account storing validator stake list - let validator_stake_list_info = next_account_info(account_info_iter)?; + let validator_list_info = next_account_info(account_info_iter)?; // Clock sysvar account let clock_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(clock_info)?; @@ -824,20 +820,19 @@ impl Processor { } // Check validator stake account list storage - if *validator_stake_list_info.key != stake_pool.validator_stake_list { + if *validator_list_info.key != stake_pool.validator_list { return Err(StakePoolError::InvalidValidatorStakeList.into()); } // Read validator stake list account and check if it is valid - let validator_stake_list = try_from_slice_unchecked::( - &validator_stake_list_info.data.borrow(), - )?; - if !validator_stake_list.is_valid() { + let validator_list = + try_from_slice_unchecked::(&validator_list_info.data.borrow())?; + if !validator_list.is_valid() { return Err(StakePoolError::InvalidState.into()); } let mut total_balance: u64 = 0; - for validator_stake_record in validator_stake_list.validators { + for validator_stake_record in validator_list.validators { if validator_stake_record.last_update_epoch < clock.epoch { return Err(StakePoolError::StakeListOutOfDate.into()); } @@ -886,7 +881,7 @@ impl Processor { // Stake pool let stake_pool_info = next_account_info(account_info_iter)?; // Account storing validator stake list - let validator_stake_list_info = next_account_info(account_info_iter)?; + let validator_list_info = next_account_info(account_info_iter)?; // Stake pool deposit authority let deposit_info = next_account_info(account_info_iter)?; // Stake pool withdraw authority @@ -937,7 +932,7 @@ impl Processor { } // Check validator stake account list storage - if *validator_stake_list_info.key != stake_pool.validator_stake_list { + if *validator_list_info.key != stake_pool.validator_list { return Err(StakePoolError::InvalidValidatorStakeList.into()); } @@ -947,17 +942,16 @@ impl Processor { } // Read validator stake list account and check if it is valid - let mut validator_stake_list = try_from_slice_unchecked::( - &validator_stake_list_info.data.borrow(), - )?; - if !validator_stake_list.is_valid() { + let mut validator_list = + try_from_slice_unchecked::(&validator_list_info.data.borrow())?; + if !validator_list.is_valid() { return Err(StakePoolError::InvalidState.into()); } let validator_account = Self::get_validator_checked(program_id, stake_pool_info, validator_stake_account_info)?; - let validator_list_item = validator_stake_list + let validator_list_item = validator_list .find_mut(&validator_account) .ok_or(StakePoolError::ValidatorNotFound)?; @@ -1036,7 +1030,7 @@ impl Processor { stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; validator_list_item.balance = **validator_stake_account_info.lamports.borrow(); - validator_stake_list.serialize(&mut *validator_stake_list_info.data.borrow_mut())?; + validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; Ok(()) } @@ -1051,7 +1045,7 @@ impl Processor { // Stake pool let stake_pool_info = next_account_info(account_info_iter)?; // Account storing validator stake list - let validator_stake_list_info = next_account_info(account_info_iter)?; + let validator_list_info = next_account_info(account_info_iter)?; // Stake pool withdraw authority let withdraw_info = next_account_info(account_info_iter)?; // Stake account to split @@ -1090,7 +1084,7 @@ impl Processor { } // Check validator stake account list storage - if *validator_stake_list_info.key != stake_pool.validator_stake_list { + if *validator_list_info.key != stake_pool.validator_list { return Err(StakePoolError::InvalidValidatorStakeList.into()); } @@ -1100,17 +1094,16 @@ impl Processor { } // Read validator stake list account and check if it is valid - let mut validator_stake_list = try_from_slice_unchecked::( - &validator_stake_list_info.data.borrow(), - )?; - if !validator_stake_list.is_valid() { + let mut validator_list = + try_from_slice_unchecked::(&validator_list_info.data.borrow())?; + if !validator_list.is_valid() { return Err(StakePoolError::InvalidState.into()); } let validator_account = Self::get_validator_checked(program_id, stake_pool_info, stake_split_from)?; - let validator_list_item = validator_stake_list + let validator_list_item = validator_list .find_mut(&validator_account) .ok_or(StakePoolError::ValidatorNotFound)?; @@ -1168,7 +1161,7 @@ impl Processor { stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; validator_list_item.balance = **stake_split_from.lamports.borrow(); - validator_stake_list.serialize(&mut *validator_stake_list_info.data.borrow_mut())?; + validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; Ok(()) } @@ -1216,21 +1209,21 @@ impl Processor { msg!("Instruction: CreateValidatorStakeAccount"); Self::process_create_validator_stake_account(program_id, accounts) } - StakePoolInstruction::AddValidatorStakeAccount => { - msg!("Instruction: AddValidatorStakeAccount"); - Self::process_add_validator_stake_account(program_id, accounts) + StakePoolInstruction::AddValidatorToPool => { + msg!("Instruction: AddValidatorToPool"); + Self::process_add_validator_to_pool(program_id, accounts) } - StakePoolInstruction::RemoveValidatorStakeAccount => { - msg!("Instruction: RemoveValidatorStakeAccount"); - Self::process_remove_validator_stake_account(program_id, accounts) + StakePoolInstruction::RemoveValidatorFromPool => { + msg!("Instruction: RemoveValidatorFromPool"); + Self::process_remove_validator_from_pool(program_id, accounts) } - StakePoolInstruction::UpdateListBalance => { - msg!("Instruction: UpdateListBalance"); - Self::process_update_list_balance(program_id, accounts) + StakePoolInstruction::UpdateValidatorListBalance => { + msg!("Instruction: UpdateValidatorListBalance"); + Self::process_update_validator_list_balance(program_id, accounts) } - StakePoolInstruction::UpdatePoolBalance => { - msg!("Instruction: UpdatePoolBalance"); - Self::process_update_pool_balance(program_id, accounts) + StakePoolInstruction::UpdateStakePoolBalance => { + msg!("Instruction: UpdateStakePoolBalance"); + Self::process_update_stake_pool_balance(program_id, accounts) } StakePoolInstruction::Deposit => { msg!("Instruction: Deposit"); diff --git a/program/src/state.rs b/program/src/state.rs index 868bef6e..d23dcc4b 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -16,7 +16,7 @@ pub enum AccountType { /// Stake pool StakePool, /// Validator stake list - ValidatorStakeList, + ValidatorList, } impl Default for AccountType { @@ -41,7 +41,7 @@ pub struct StakePool { /// for `create_program_address(&[state::StakePool account, "withdrawal"])` pub withdraw_bump_seed: u8, /// Validator stake list storage account - pub validator_stake_list: Pubkey, + pub validator_list: Pubkey, /// Pool Mint pub pool_mint: Pubkey, /// Owner fee account @@ -155,8 +155,8 @@ impl StakePool { /// Storage list for all validator stake accounts in the pool. #[repr(C)] #[derive(Clone, Debug, Default, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)] -pub struct ValidatorStakeList { - /// Account type, must be ValidatorStakeList currently +pub struct ValidatorList { + /// Account type, must be ValidatorList currently pub account_type: AccountType, /// Maximum allowable number of validators @@ -180,11 +180,11 @@ pub struct ValidatorStakeInfo { pub last_update_epoch: u64, } -impl ValidatorStakeList { +impl ValidatorList { /// Create an empty instance containing space for `max_validators` pub fn new_with_max_validators(max_validators: u32) -> Self { Self { - account_type: AccountType::ValidatorStakeList, + account_type: AccountType::ValidatorList, max_validators, validators: vec![ValidatorStakeInfo::default(); max_validators as usize], } @@ -192,7 +192,8 @@ impl ValidatorStakeList { /// Calculate the number of validator entries that fit in the provided length pub fn calculate_max_validators(buffer_length: usize) -> usize { - (buffer_length - 1 - 4 - 4) / 48 + let header_size = 1 + 4 + 4; + buffer_length.saturating_sub(header_size) / 48 } /// Check if contains validator with particular pubkey @@ -217,7 +218,7 @@ impl ValidatorStakeList { /// Check if validator stake list is actually initialized as a validator stake list pub fn is_valid(&self) -> bool { - self.account_type == AccountType::ValidatorStakeList + self.account_type == AccountType::ValidatorList } /// Check if the validator stake list is uninitialized @@ -238,11 +239,10 @@ mod test { #[test] fn test_state_packing() { let max_validators = 10_000; - let size = - get_instance_packed_len(&ValidatorStakeList::new_with_max_validators(max_validators)) - .unwrap(); + let size = get_instance_packed_len(&ValidatorList::new_with_max_validators(max_validators)) + .unwrap(); // Not initialized - let stake_list = ValidatorStakeList { + let stake_list = ValidatorList { account_type: AccountType::Uninitialized, max_validators: 0, validators: vec![], @@ -250,26 +250,24 @@ mod test { let mut byte_vec = vec![0u8; size]; let mut bytes = byte_vec.as_mut_slice(); stake_list.serialize(&mut bytes).unwrap(); - let stake_list_unpacked = - try_from_slice_unchecked::(&byte_vec).unwrap(); + let stake_list_unpacked = try_from_slice_unchecked::(&byte_vec).unwrap(); assert_eq!(stake_list_unpacked, stake_list); // Empty - let stake_list = ValidatorStakeList { - account_type: AccountType::ValidatorStakeList, + let stake_list = ValidatorList { + account_type: AccountType::ValidatorList, max_validators: 0, validators: vec![], }; let mut byte_vec = vec![0u8; size]; let mut bytes = byte_vec.as_mut_slice(); stake_list.serialize(&mut bytes).unwrap(); - let stake_list_unpacked = - try_from_slice_unchecked::(&byte_vec).unwrap(); + let stake_list_unpacked = try_from_slice_unchecked::(&byte_vec).unwrap(); assert_eq!(stake_list_unpacked, stake_list); // With several accounts - let stake_list = ValidatorStakeList { - account_type: AccountType::ValidatorStakeList, + let stake_list = ValidatorList { + account_type: AccountType::ValidatorList, max_validators, validators: vec![ ValidatorStakeInfo { @@ -292,20 +290,19 @@ mod test { let mut byte_vec = vec![0u8; size]; let mut bytes = byte_vec.as_mut_slice(); stake_list.serialize(&mut bytes).unwrap(); - let stake_list_unpacked = - try_from_slice_unchecked::(&byte_vec).unwrap(); + let stake_list_unpacked = try_from_slice_unchecked::(&byte_vec).unwrap(); assert_eq!(stake_list_unpacked, stake_list); } proptest! { #[test] fn stake_list_size_calculation(test_amount in 0..=100_000_u32) { - let validators = ValidatorStakeList::new_with_max_validators(test_amount); + let validators = ValidatorList::new_with_max_validators(test_amount); let size = get_instance_packed_len(&validators).unwrap(); - assert_eq!(ValidatorStakeList::calculate_max_validators(size), test_amount as usize); - assert_eq!(ValidatorStakeList::calculate_max_validators(size + 1), test_amount as usize); - assert_eq!(ValidatorStakeList::calculate_max_validators(size + get_packed_len::()), (test_amount + 1)as usize); - assert_eq!(ValidatorStakeList::calculate_max_validators(size - 1), (test_amount - 1) as usize); + assert_eq!(ValidatorList::calculate_max_validators(size), test_amount as usize); + assert_eq!(ValidatorList::calculate_max_validators(size.saturating_add(1)), test_amount as usize); + assert_eq!(ValidatorList::calculate_max_validators(size.saturating_add(get_packed_len::())), (test_amount + 1)as usize); + assert_eq!(ValidatorList::calculate_max_validators(size.saturating_sub(1)), (test_amount.saturating_sub(1)) as usize); } } } diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 55f477da..e750bd3e 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -32,7 +32,7 @@ async fn setup() -> ( .await .unwrap(); - let validator_stake_account: ValidatorStakeAccount = simple_add_validator_stake_account( + let validator_stake_account: ValidatorStakeAccount = simple_add_validator_to_pool( &mut banks_client, &payer, &recent_blockhash, @@ -134,15 +134,14 @@ async fn test_stake_pool_deposit() { state::StakePool::try_from_slice(&stake_pool_before.data.as_slice()).unwrap(); // Save validator stake account record before depositing - let validator_stake_list = get_account( + let validator_list = get_account( &mut banks_client, - &stake_pool_accounts.validator_stake_list.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), ) .await; - let validator_stake_list = - try_from_slice_unchecked::(validator_stake_list.data.as_slice()) - .unwrap(); - let validator_stake_item_before = validator_stake_list + let validator_list = + try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); + let validator_stake_item_before = validator_list .find(&validator_stake_account.vote.pubkey()) .unwrap(); @@ -192,15 +191,14 @@ async fn test_stake_pool_deposit() { assert_eq!(pool_fee_token_balance, fee); // Check balances in validator stake account list storage - let validator_stake_list = get_account( + let validator_list = get_account( &mut banks_client, - &stake_pool_accounts.validator_stake_list.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), ) .await; - let validator_stake_list = - try_from_slice_unchecked::(validator_stake_list.data.as_slice()) - .unwrap(); - let validator_stake_item = validator_stake_list + let validator_list = + try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); + let validator_stake_item = validator_list .find(&validator_stake_account.vote.pubkey()) .unwrap(); assert_eq!( @@ -245,7 +243,7 @@ async fn test_stake_pool_deposit_with_wrong_stake_program_id() { &[instruction::deposit( &id(), &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.validator_stake_list.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), &stake_pool_accounts.deposit_authority, &stake_pool_accounts.withdraw_authority, &user_stake.pubkey(), @@ -385,7 +383,7 @@ async fn test_stake_pool_deposit_with_wrong_token_program_id() { &[instruction::deposit( &id(), &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.validator_stake_list.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), &stake_pool_accounts.deposit_authority, &stake_pool_accounts.withdraw_authority, &user_stake.pubkey(), @@ -415,7 +413,7 @@ async fn test_stake_pool_deposit_with_wrong_token_program_id() { } #[tokio::test] -async fn test_stake_pool_deposit_with_wrong_validator_stake_list_account() { +async fn test_stake_pool_deposit_with_wrong_validator_list_account() { let ( mut banks_client, payer, @@ -455,8 +453,8 @@ async fn test_stake_pool_deposit_with_wrong_validator_stake_list_account() { .await .unwrap(); - let wrong_validator_stake_list = Keypair::new(); - stake_pool_accounts.validator_stake_list = wrong_validator_stake_list; + let wrong_validator_list = Keypair::new(); + stake_pool_accounts.validator_list = wrong_validator_list; let transaction_error = stake_pool_accounts .deposit_stake( @@ -907,7 +905,7 @@ async fn test_stake_pool_deposit_with_wrong_mint_for_receiver_acc() { } #[tokio::test] -async fn test_deposit_with_uninitialized_validator_stake_list() {} // TODO +async fn test_deposit_with_uninitialized_validator_list() {} // TODO #[tokio::test] async fn test_deposit_with_out_of_dated_pool_balances() {} // TODO diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index aadd29a0..0ca4dbe4 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -165,7 +165,7 @@ pub async fn create_stake_pool( payer: &Keypair, recent_blockhash: &Hash, stake_pool: &Keypair, - validator_stake_list: &Keypair, + validator_list: &Keypair, pool_mint: &Pubkey, pool_token_account: &Pubkey, owner: &Keypair, @@ -174,11 +174,11 @@ pub async fn create_stake_pool( ) -> Result<(), TransportError> { let rent = banks_client.get_rent().await.unwrap(); let rent_stake_pool = rent.minimum_balance(get_packed_len::()); - let validator_stake_list_size = get_instance_packed_len( - &state::ValidatorStakeList::new_with_max_validators(max_validators), + let validator_list_size = get_instance_packed_len( + &state::ValidatorList::new_with_max_validators(max_validators), ) .unwrap(); - let rent_validator_stake_list = rent.minimum_balance(validator_stake_list_size); + let rent_validator_list = rent.minimum_balance(validator_list_size); let mut transaction = Transaction::new_with_payer( &[ @@ -191,16 +191,16 @@ pub async fn create_stake_pool( ), system_instruction::create_account( &payer.pubkey(), - &validator_stake_list.pubkey(), - rent_validator_stake_list, - validator_stake_list_size as u64, + &validator_list.pubkey(), + rent_validator_list, + validator_list_size as u64, &id(), ), instruction::initialize( &id(), &stake_pool.pubkey(), &owner.pubkey(), - &validator_stake_list.pubkey(), + &validator_list.pubkey(), pool_mint, pool_token_account, &spl_token::id(), @@ -212,7 +212,7 @@ pub async fn create_stake_pool( Some(&payer.pubkey()), ); transaction.sign( - &[payer, stake_pool, validator_stake_list, owner], + &[payer, stake_pool, validator_list, owner], *recent_blockhash, ); banks_client.process_transaction(transaction).await?; @@ -434,7 +434,7 @@ impl ValidatorStakeAccount { pub struct StakePoolAccounts { pub stake_pool: Keypair, - pub validator_stake_list: Keypair, + pub validator_list: Keypair, pub pool_mint: Keypair, pub pool_fee_account: Keypair, pub owner: Keypair, @@ -447,7 +447,7 @@ pub struct StakePoolAccounts { impl StakePoolAccounts { pub fn new() -> Self { let stake_pool = Keypair::new(); - let validator_stake_list = Keypair::new(); + let validator_list = Keypair::new(); let stake_pool_address = &stake_pool.pubkey(); let (withdraw_authority, _) = Pubkey::find_program_address( &[&stake_pool_address.to_bytes()[..32], b"withdraw"], @@ -463,7 +463,7 @@ impl StakePoolAccounts { Self { stake_pool, - validator_stake_list, + validator_list, pool_mint, pool_fee_account, owner, @@ -509,7 +509,7 @@ impl StakePoolAccounts { &payer, &recent_blockhash, &self.stake_pool, - &self.validator_stake_list, + &self.validator_list, &self.pool_mint.pubkey(), &self.pool_fee_account.pubkey(), &self.owner, @@ -533,7 +533,7 @@ impl StakePoolAccounts { &[instruction::deposit( &id(), &self.stake_pool.pubkey(), - &self.validator_stake_list.pubkey(), + &self.validator_list.pubkey(), &self.deposit_authority, &self.withdraw_authority, stake, @@ -567,7 +567,7 @@ impl StakePoolAccounts { &[instruction::withdraw( &id(), &self.stake_pool.pubkey(), - &self.validator_stake_list.pubkey(), + &self.validator_list.pubkey(), &self.withdraw_authority, validator_stake_account, stake_recipient, @@ -586,7 +586,7 @@ impl StakePoolAccounts { Ok(()) } - pub async fn add_validator_stake_account( + pub async fn add_validator_to_pool( &self, banks_client: &mut BanksClient, payer: &Keypair, @@ -595,13 +595,13 @@ impl StakePoolAccounts { pool_account: &Pubkey, ) -> Option { let mut transaction = Transaction::new_with_payer( - &[instruction::add_validator_stake_account( + &[instruction::add_validator_to_pool( &id(), &self.stake_pool.pubkey(), &self.owner.pubkey(), &self.deposit_authority, &self.withdraw_authority, - &self.validator_stake_list.pubkey(), + &self.validator_list.pubkey(), stake, pool_account, &self.pool_mint.pubkey(), @@ -615,7 +615,7 @@ impl StakePoolAccounts { banks_client.process_transaction(transaction).await.err() } - pub async fn remove_validator_stake_account( + pub async fn remove_validator_from_pool( &self, banks_client: &mut BanksClient, payer: &Keypair, @@ -625,13 +625,13 @@ impl StakePoolAccounts { new_authority: &Pubkey, ) -> Option { let mut transaction = Transaction::new_with_payer( - &[instruction::remove_validator_stake_account( + &[instruction::remove_validator_from_pool( &id(), &self.stake_pool.pubkey(), &self.owner.pubkey(), &self.withdraw_authority, &new_authority, - &self.validator_stake_list.pubkey(), + &self.validator_list.pubkey(), stake, pool_account, &self.pool_mint.pubkey(), @@ -646,7 +646,7 @@ impl StakePoolAccounts { } } -pub async fn simple_add_validator_stake_account( +pub async fn simple_add_validator_to_pool( banks_client: &mut BanksClient, payer: &Keypair, recent_blockhash: &Hash, @@ -673,7 +673,7 @@ pub async fn simple_add_validator_stake_account( .await .unwrap(); let error = stake_pool_accounts - .add_validator_stake_account( + .add_validator_to_pool( banks_client, &payer, &recent_blockhash, diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index 9a1d7a3b..bdc7c919 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -66,15 +66,14 @@ async fn test_stake_pool_initialize() { assert_eq!(stake_pool.owner, id()); // Validator stake list storage initialized - let validator_stake_list = get_account( + let validator_list = get_account( &mut banks_client, - &stake_pool_accounts.validator_stake_list.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), ) .await; - let validator_stake_list = - try_from_slice_unchecked::(validator_stake_list.data.as_slice()) - .unwrap(); - assert_eq!(validator_stake_list.is_valid(), true); + let validator_list = + try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); + assert_eq!(validator_list.is_valid(), true); } #[tokio::test] @@ -120,7 +119,7 @@ async fn test_initialize_stake_pool_with_already_initialized_stake_list_storage( let latest_blockhash = banks_client.get_recent_blockhash().await.unwrap(); let mut second_stake_pool_accounts = StakePoolAccounts::new(); - second_stake_pool_accounts.validator_stake_list = stake_pool_accounts.validator_stake_list; + second_stake_pool_accounts.validator_list = stake_pool_accounts.validator_list; let transaction_error = second_stake_pool_accounts .initialize_stake_pool(&mut banks_client, &payer, &latest_blockhash) @@ -180,11 +179,11 @@ async fn test_initialize_stake_pool_with_wrong_max_validators() { let rent = banks_client.get_rent().await.unwrap(); let rent_stake_pool = rent.minimum_balance(get_packed_len::()); - let validator_stake_list_size = get_instance_packed_len( - &state::ValidatorStakeList::new_with_max_validators(stake_pool_accounts.max_validators - 1), + let validator_list_size = get_instance_packed_len( + &state::ValidatorList::new_with_max_validators(stake_pool_accounts.max_validators - 1), ) .unwrap(); - let rent_validator_stake_list = rent.minimum_balance(validator_stake_list_size); + let rent_validator_list = rent.minimum_balance(validator_list_size); let mut transaction = Transaction::new_with_payer( &[ @@ -197,16 +196,16 @@ async fn test_initialize_stake_pool_with_wrong_max_validators() { ), system_instruction::create_account( &payer.pubkey(), - &stake_pool_accounts.validator_stake_list.pubkey(), - rent_validator_stake_list, - validator_stake_list_size as u64, + &stake_pool_accounts.validator_list.pubkey(), + rent_validator_list, + validator_list_size as u64, &id(), ), instruction::initialize( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.owner.pubkey(), - &stake_pool_accounts.validator_stake_list.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), &spl_token::id(), @@ -221,7 +220,7 @@ async fn test_initialize_stake_pool_with_wrong_max_validators() { &[ &payer, &stake_pool_accounts.stake_pool, - &stake_pool_accounts.validator_stake_list, + &stake_pool_accounts.validator_list, &stake_pool_accounts.owner, ], recent_blockhash, @@ -274,7 +273,7 @@ async fn test_initialize_stake_pool_with_wrong_mint_authority() { &payer, &recent_blockhash, &stake_pool_accounts.stake_pool, - &stake_pool_accounts.validator_stake_list, + &stake_pool_accounts.validator_list, &wrong_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.owner, @@ -334,11 +333,11 @@ async fn test_initialize_stake_pool_with_wrong_token_program_id() { banks_client.process_transaction(transaction).await.unwrap(); let rent_stake_pool = rent.minimum_balance(get_packed_len::()); - let validator_stake_list_size = get_instance_packed_len( - &state::ValidatorStakeList::new_with_max_validators(stake_pool_accounts.max_validators), + let validator_list_size = get_instance_packed_len( + &state::ValidatorList::new_with_max_validators(stake_pool_accounts.max_validators), ) .unwrap(); - let rent_validator_stake_list = rent.minimum_balance(validator_stake_list_size); + let rent_validator_list = rent.minimum_balance(validator_list_size); let mut transaction = Transaction::new_with_payer( &[ @@ -351,16 +350,16 @@ async fn test_initialize_stake_pool_with_wrong_token_program_id() { ), system_instruction::create_account( &payer.pubkey(), - &stake_pool_accounts.validator_stake_list.pubkey(), - rent_validator_stake_list, - validator_stake_list_size as u64, + &stake_pool_accounts.validator_list.pubkey(), + rent_validator_list, + validator_list_size as u64, &id(), ), instruction::initialize( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.owner.pubkey(), - &stake_pool_accounts.validator_stake_list.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), &wrong_token_program.pubkey(), @@ -375,7 +374,7 @@ async fn test_initialize_stake_pool_with_wrong_token_program_id() { &[ &payer, &stake_pool_accounts.stake_pool, - &stake_pool_accounts.validator_stake_list, + &stake_pool_accounts.validator_list, &stake_pool_accounts.owner, ], recent_blockhash, @@ -434,7 +433,7 @@ async fn test_initialize_stake_pool_with_wrong_fee_accounts_owner() { &payer, &recent_blockhash, &stake_pool_accounts.stake_pool, - &stake_pool_accounts.validator_stake_list, + &stake_pool_accounts.validator_list, &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.owner, @@ -500,11 +499,11 @@ async fn test_initialize_stake_pool_with_not_rent_exempt_pool() { .await; let rent = banks_client.get_rent().await.unwrap(); - let validator_stake_list_size = get_instance_packed_len( - &state::ValidatorStakeList::new_with_max_validators(stake_pool_accounts.max_validators), + let validator_list_size = get_instance_packed_len( + &state::ValidatorList::new_with_max_validators(stake_pool_accounts.max_validators), ) .unwrap(); - let rent_validator_stake_list = rent.minimum_balance(validator_stake_list_size); + let rent_validator_list = rent.minimum_balance(validator_list_size); let mut transaction = Transaction::new_with_payer( &[ @@ -517,16 +516,16 @@ async fn test_initialize_stake_pool_with_not_rent_exempt_pool() { ), system_instruction::create_account( &payer.pubkey(), - &stake_pool_accounts.validator_stake_list.pubkey(), - rent_validator_stake_list, - validator_stake_list_size as u64, + &stake_pool_accounts.validator_list.pubkey(), + rent_validator_list, + validator_list_size as u64, &id(), ), instruction::initialize( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.owner.pubkey(), - &stake_pool_accounts.validator_stake_list.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), &spl_token::id(), @@ -541,7 +540,7 @@ async fn test_initialize_stake_pool_with_not_rent_exempt_pool() { &[ &payer, &stake_pool_accounts.stake_pool, - &stake_pool_accounts.validator_stake_list, + &stake_pool_accounts.validator_list, &stake_pool_accounts.owner, ], recent_blockhash, @@ -562,7 +561,7 @@ async fn test_initialize_stake_pool_with_not_rent_exempt_pool() { } #[tokio::test] -async fn test_initialize_stake_pool_with_not_rent_exempt_validator_stake_list() { +async fn test_initialize_stake_pool_with_not_rent_exempt_validator_list() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); @@ -576,8 +575,8 @@ async fn test_initialize_stake_pool_with_not_rent_exempt_validator_stake_list() let rent = banks_client.get_rent().await.unwrap(); let rent_stake_pool = rent.minimum_balance(get_packed_len::()); - let validator_stake_list_size = get_instance_packed_len( - &state::ValidatorStakeList::new_with_max_validators(stake_pool_accounts.max_validators), + let validator_list_size = get_instance_packed_len( + &state::ValidatorList::new_with_max_validators(stake_pool_accounts.max_validators), ) .unwrap(); @@ -592,16 +591,16 @@ async fn test_initialize_stake_pool_with_not_rent_exempt_validator_stake_list() ), system_instruction::create_account( &payer.pubkey(), - &stake_pool_accounts.validator_stake_list.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), 1, - validator_stake_list_size as u64, + validator_list_size as u64, &id(), ), instruction::initialize( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.owner.pubkey(), - &stake_pool_accounts.validator_stake_list.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), &spl_token::id(), @@ -616,7 +615,7 @@ async fn test_initialize_stake_pool_with_not_rent_exempt_validator_stake_list() &[ &payer, &stake_pool_accounts.stake_pool, - &stake_pool_accounts.validator_stake_list, + &stake_pool_accounts.validator_list, &stake_pool_accounts.owner, ], recent_blockhash, @@ -652,11 +651,11 @@ async fn test_initialize_stake_pool_without_owner_signature() { let rent = banks_client.get_rent().await.unwrap(); let rent_stake_pool = rent.minimum_balance(get_packed_len::()); - let validator_stake_list_size = get_instance_packed_len( - &state::ValidatorStakeList::new_with_max_validators(stake_pool_accounts.max_validators), + let validator_list_size = get_instance_packed_len( + &state::ValidatorList::new_with_max_validators(stake_pool_accounts.max_validators), ) .unwrap(); - let rent_validator_stake_list = rent.minimum_balance(validator_stake_list_size); + let rent_validator_list = rent.minimum_balance(validator_list_size); let init_data = instruction::StakePoolInstruction::Initialize { fee: stake_pool_accounts.fee.clone(), @@ -666,7 +665,7 @@ async fn test_initialize_stake_pool_without_owner_signature() { let accounts = vec![ AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), true), AccountMeta::new_readonly(stake_pool_accounts.owner.pubkey(), false), - AccountMeta::new(stake_pool_accounts.validator_stake_list.pubkey(), false), + AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false), AccountMeta::new_readonly(stake_pool_accounts.pool_mint.pubkey(), false), AccountMeta::new_readonly(stake_pool_accounts.pool_fee_account.pubkey(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), @@ -690,9 +689,9 @@ async fn test_initialize_stake_pool_without_owner_signature() { ), system_instruction::create_account( &payer.pubkey(), - &stake_pool_accounts.validator_stake_list.pubkey(), - rent_validator_stake_list, - validator_stake_list_size as u64, + &stake_pool_accounts.validator_list.pubkey(), + rent_validator_list, + validator_list_size as u64, &id(), ), stake_pool_init_instruction, @@ -703,7 +702,7 @@ async fn test_initialize_stake_pool_without_owner_signature() { &[ &payer, &stake_pool_accounts.stake_pool, - &stake_pool_accounts.validator_stake_list, + &stake_pool_accounts.validator_list, ], recent_blockhash, ); diff --git a/program/tests/update_pool_balance.rs b/program/tests/update_stake_pool_balance.rs similarity index 85% rename from program/tests/update_pool_balance.rs rename to program/tests/update_stake_pool_balance.rs index 1a1a2f6d..2fb1790a 100644 --- a/program/tests/update_pool_balance.rs +++ b/program/tests/update_stake_pool_balance.rs @@ -13,7 +13,7 @@ use { }; #[tokio::test] -async fn test_update_pool_balance() { +async fn test_update_stake_pool_balance() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts @@ -25,7 +25,7 @@ async fn test_update_pool_balance() { } #[tokio::test] -async fn test_update_pool_balance_with_wrong_validator_stake_list() { +async fn test_update_stake_pool_balance_with_wrong_validator_list() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts @@ -35,7 +35,7 @@ async fn test_update_pool_balance_with_wrong_validator_stake_list() { let wrong_stake_list_storage = Keypair::new(); let mut transaction = Transaction::new_with_payer( - &[instruction::update_pool_balance( + &[instruction::update_stake_pool_balance( &id(), &stake_pool_accounts.stake_pool.pubkey(), &wrong_stake_list_storage.pubkey(), @@ -64,7 +64,7 @@ async fn test_update_pool_balance_with_wrong_validator_stake_list() { } #[tokio::test] -async fn test_update_pool_balance_with_uninitialized_validator_stake_list() {} // TODO +async fn test_update_stake_pool_balance_with_uninitialized_validator_list() {} // TODO #[tokio::test] -async fn test_update_pool_balance_with_out_of_dated_validators_balances() {} // TODO +async fn test_update_stake_pool_balance_with_out_of_dated_validators_balances() {} // TODO diff --git a/program/tests/update_list_balance.rs b/program/tests/update_validator_list_balance.rs similarity index 76% rename from program/tests/update_list_balance.rs rename to program/tests/update_validator_list_balance.rs index 56b75db8..ecbca99f 100644 --- a/program/tests/update_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -11,17 +11,16 @@ use { spl_stake_pool::{borsh::try_from_slice_unchecked, stake, state}, }; -async fn get_list_sum(banks_client: &mut BanksClient, validator_stake_list_key: &Pubkey) -> u64 { - let validator_stake_list = banks_client - .get_account(*validator_stake_list_key) +async fn get_list_sum(banks_client: &mut BanksClient, validator_list_key: &Pubkey) -> u64 { + let validator_list = banks_client + .get_account(*validator_list_key) .await .expect("get_account") .expect("validator stake list not none"); - let validator_stake_list = - try_from_slice_unchecked::(validator_stake_list.data.as_slice()) - .unwrap(); + let validator_list = + try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); - validator_stake_list + validator_list .validators .iter() .map(|info| info.balance) @@ -29,7 +28,7 @@ async fn get_list_sum(banks_client: &mut BanksClient, validator_stake_list_key: } #[tokio::test] -async fn test_update_list_balance() { +async fn test_update_validator_list_balance() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts @@ -42,7 +41,7 @@ async fn test_update_list_balance() { const STAKE_ACCOUNTS: u64 = 3; for _ in 0..STAKE_ACCOUNTS { stake_accounts.push( - simple_add_validator_stake_account( + simple_add_validator_to_pool( &mut banks_client, &payer, &recent_blockhash, @@ -74,7 +73,7 @@ async fn test_update_list_balance() { assert_eq!( get_list_sum( &mut banks_client, - &stake_pool_accounts.validator_stake_list.pubkey() + &stake_pool_accounts.validator_list.pubkey() ) .await, STAKE_ACCOUNTS * (stake_rent + TEST_STAKE_AMOUNT) @@ -84,7 +83,7 @@ async fn test_update_list_balance() { } #[tokio::test] -async fn test_update_list_balance_with_uninitialized_validator_stake_list() {} // TODO +async fn test_update_validator_list_balance_with_uninitialized_validator_list() {} // TODO #[tokio::test] -async fn test_update_list_balance_with_wrong_stake_state() {} // TODO +async fn test_update_validator_list_balance_with_wrong_stake_state() {} // TODO diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index 26c9dcd7..048f0ef1 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -70,7 +70,7 @@ async fn setup() -> ( } #[tokio::test] -async fn test_add_validator_stake_account() { +async fn test_add_validator_to_pool() { let ( mut banks_client, payer, @@ -81,7 +81,7 @@ async fn test_add_validator_stake_account() { ) = setup().await; let error = stake_pool_accounts - .add_validator_stake_account( + .add_validator_to_pool( &mut banks_client, &payer, &recent_blockhash, @@ -109,18 +109,17 @@ async fn test_add_validator_stake_account() { assert_eq!(pool_fee_token_balance, 0); // No fee when adding validator stake accounts // Check if validator account was added to the list - let validator_stake_list = get_account( + let validator_list = get_account( &mut banks_client, - &stake_pool_accounts.validator_stake_list.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), ) .await; - let validator_stake_list = - try_from_slice_unchecked::(validator_stake_list.data.as_slice()) - .unwrap(); + let validator_list = + try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); assert_eq!( - validator_stake_list, - state::ValidatorStakeList { - account_type: state::AccountType::ValidatorStakeList, + validator_list, + state::ValidatorList { + account_type: state::AccountType::ValidatorList, max_validators: stake_pool_accounts.max_validators, validators: vec![state::ValidatorStakeInfo { validator_account: user_stake.vote.pubkey(), @@ -149,7 +148,7 @@ async fn test_add_validator_stake_account() { } #[tokio::test] -async fn test_add_validator_stake_account_with_wrong_token_program_id() { +async fn test_add_validator_to_pool_with_wrong_token_program_id() { let ( mut banks_client, payer, @@ -160,13 +159,13 @@ async fn test_add_validator_stake_account_with_wrong_token_program_id() { ) = setup().await; let mut transaction = Transaction::new_with_payer( - &[instruction::add_validator_stake_account( + &[instruction::add_validator_to_pool( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.owner.pubkey(), &stake_pool_accounts.deposit_authority, &stake_pool_accounts.withdraw_authority, - &stake_pool_accounts.validator_stake_list.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), &user_stake.stake_account, &user_pool_account.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), @@ -192,7 +191,7 @@ async fn test_add_validator_stake_account_with_wrong_token_program_id() { } #[tokio::test] -async fn test_add_validator_stake_account_with_wrong_pool_mint_account() { +async fn test_add_validator_to_pool_with_wrong_pool_mint_account() { let ( mut banks_client, payer, @@ -205,13 +204,13 @@ async fn test_add_validator_stake_account_with_wrong_pool_mint_account() { let wrong_pool_mint = Keypair::new(); let mut transaction = Transaction::new_with_payer( - &[instruction::add_validator_stake_account( + &[instruction::add_validator_to_pool( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.owner.pubkey(), &stake_pool_accounts.deposit_authority, &stake_pool_accounts.withdraw_authority, - &stake_pool_accounts.validator_stake_list.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), &user_stake.stake_account, &user_pool_account.pubkey(), &wrong_pool_mint.pubkey(), @@ -241,7 +240,7 @@ async fn test_add_validator_stake_account_with_wrong_pool_mint_account() { } #[tokio::test] -async fn test_add_validator_stake_account_with_wrong_validator_stake_list_account() { +async fn test_add_validator_to_pool_with_wrong_validator_list_account() { let ( mut banks_client, payer, @@ -251,16 +250,16 @@ async fn test_add_validator_stake_account_with_wrong_validator_stake_list_accoun user_pool_account, ) = setup().await; - let wrong_validator_stake_list = Keypair::new(); + let wrong_validator_list = Keypair::new(); let mut transaction = Transaction::new_with_payer( - &[instruction::add_validator_stake_account( + &[instruction::add_validator_to_pool( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.owner.pubkey(), &stake_pool_accounts.deposit_authority, &stake_pool_accounts.withdraw_authority, - &wrong_validator_stake_list.pubkey(), + &wrong_validator_list.pubkey(), &user_stake.stake_account, &user_pool_account.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), @@ -301,7 +300,7 @@ async fn test_try_to_add_already_added_validator_stake_account() { ) = setup().await; stake_pool_accounts - .add_validator_stake_account( + .add_validator_to_pool( &mut banks_client, &payer, &recent_blockhash, @@ -313,7 +312,7 @@ async fn test_try_to_add_already_added_validator_stake_account() { let latest_blockhash = banks_client.get_recent_blockhash().await.unwrap(); let transaction_error = stake_pool_accounts - .add_validator_stake_account( + .add_validator_to_pool( &mut banks_client, &payer, &latest_blockhash, @@ -336,7 +335,7 @@ async fn test_try_to_add_already_added_validator_stake_account() { } #[tokio::test] -async fn test_not_owner_try_to_add_validator_stake_account() { +async fn test_not_owner_try_to_add_validator_to_pool() { let ( mut banks_client, payer, @@ -349,13 +348,13 @@ async fn test_not_owner_try_to_add_validator_stake_account() { let malicious = Keypair::new(); let mut transaction = Transaction::new_with_payer( - &[instruction::add_validator_stake_account( + &[instruction::add_validator_to_pool( &id(), &stake_pool_accounts.stake_pool.pubkey(), &malicious.pubkey(), &stake_pool_accounts.deposit_authority, &stake_pool_accounts.withdraw_authority, - &stake_pool_accounts.validator_stake_list.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), &user_stake.stake_account, &user_pool_account.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), @@ -385,7 +384,7 @@ async fn test_not_owner_try_to_add_validator_stake_account() { } #[tokio::test] -async fn test_not_owner_try_to_add_validator_stake_account_without_signature() { +async fn test_not_owner_try_to_add_validator_to_pool_without_signature() { let ( mut banks_client, payer, @@ -400,7 +399,7 @@ async fn test_not_owner_try_to_add_validator_stake_account_without_signature() { AccountMeta::new_readonly(stake_pool_accounts.owner.pubkey(), false), AccountMeta::new_readonly(stake_pool_accounts.deposit_authority, false), AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false), - AccountMeta::new(stake_pool_accounts.validator_stake_list.pubkey(), false), + AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false), AccountMeta::new(user_stake.stake_account, false), AccountMeta::new(user_pool_account.pubkey(), false), AccountMeta::new(stake_pool_accounts.pool_mint.pubkey(), false), @@ -412,7 +411,7 @@ async fn test_not_owner_try_to_add_validator_stake_account_without_signature() { let instruction = Instruction { program_id: id(), accounts, - data: instruction::StakePoolInstruction::AddValidatorStakeAccount + data: instruction::StakePoolInstruction::AddValidatorToPool .try_to_vec() .unwrap(), }; @@ -438,7 +437,7 @@ async fn test_not_owner_try_to_add_validator_stake_account_without_signature() { } #[tokio::test] -async fn test_add_validator_stake_account_when_stake_acc_not_in_stake_state() { +async fn test_add_validator_to_pool_when_stake_acc_not_in_stake_state() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts @@ -478,7 +477,7 @@ async fn test_add_validator_stake_account_when_stake_acc_not_in_stake_state() { .unwrap(); let transaction_error = stake_pool_accounts - .add_validator_stake_account( + .add_validator_to_pool( &mut banks_client, &payer, &recent_blockhash, @@ -501,7 +500,7 @@ async fn test_add_validator_stake_account_when_stake_acc_not_in_stake_state() { } #[tokio::test] -async fn test_add_validator_stake_account_with_wrong_stake_program_id() { +async fn test_add_validator_to_pool_with_wrong_stake_program_id() { let ( mut banks_client, payer, @@ -514,13 +513,13 @@ async fn test_add_validator_stake_account_with_wrong_stake_program_id() { let wrong_stake_program = Keypair::new(); let mut transaction = Transaction::new_with_payer( - &[instruction::add_validator_stake_account( + &[instruction::add_validator_to_pool( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.owner.pubkey(), &stake_pool_accounts.deposit_authority, &stake_pool_accounts.withdraw_authority, - &stake_pool_accounts.validator_stake_list.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), &user_stake.stake_account, &user_pool_account.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), @@ -581,7 +580,7 @@ async fn test_add_too_many_validator_stake_accounts() { .unwrap(); let error = stake_pool_accounts - .add_validator_stake_account( + .add_validator_to_pool( &mut banks_client, &payer, &recent_blockhash, @@ -599,7 +598,7 @@ async fn test_add_too_many_validator_stake_accounts() { .create_and_delegate(&mut banks_client, &payer, &recent_blockhash) .await; let error = stake_pool_accounts - .add_validator_stake_account( + .add_validator_to_pool( &mut banks_client, &payer, &recent_blockhash, @@ -616,7 +615,7 @@ async fn test_add_too_many_validator_stake_accounts() { } #[tokio::test] -async fn test_add_validator_stake_account_to_unupdated_stake_pool() {} // TODO +async fn test_add_validator_to_pool_to_unupdated_stake_pool() {} // TODO #[tokio::test] -async fn test_add_validator_stake_account_with_uninitialized_validator_stake_list_account() {} // TODO +async fn test_add_validator_to_pool_with_uninitialized_validator_list_account() {} // TODO diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 4be8f507..8cc29eda 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -62,7 +62,7 @@ async fn setup() -> ( .unwrap(); let error = stake_pool_accounts - .add_validator_stake_account( + .add_validator_to_pool( &mut banks_client, &payer, &recent_blockhash, @@ -84,7 +84,7 @@ async fn setup() -> ( } #[tokio::test] -async fn test_remove_validator_stake_account() { +async fn test_remove_validator_from_pool() { let ( mut banks_client, payer, @@ -109,7 +109,7 @@ async fn test_remove_validator_stake_account() { let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts - .remove_validator_stake_account( + .remove_validator_from_pool( &mut banks_client, &payer, &recent_blockhash, @@ -125,18 +125,17 @@ async fn test_remove_validator_stake_account() { assert_eq!(tokens_left, 0); // Check if account was removed from the list of stake accounts - let validator_stake_list = get_account( + let validator_list = get_account( &mut banks_client, - &stake_pool_accounts.validator_stake_list.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), ) .await; - let validator_stake_list = - try_from_slice_unchecked::(validator_stake_list.data.as_slice()) - .unwrap(); + let validator_list = + try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); assert_eq!( - validator_stake_list, - state::ValidatorStakeList { - account_type: state::AccountType::ValidatorStakeList, + validator_list, + state::ValidatorList { + account_type: state::AccountType::ValidatorList, max_validators: stake_pool_accounts.max_validators, validators: vec![] } @@ -155,7 +154,7 @@ async fn test_remove_validator_stake_account() { } #[tokio::test] -async fn test_remove_validator_stake_account_with_wrong_stake_program_id() { +async fn test_remove_validator_from_pool_with_wrong_stake_program_id() { let ( mut banks_client, payer, @@ -170,13 +169,13 @@ async fn test_remove_validator_stake_account_with_wrong_stake_program_id() { let new_authority = Pubkey::new_unique(); let mut transaction = Transaction::new_with_payer( - &[instruction::remove_validator_stake_account( + &[instruction::remove_validator_from_pool( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.owner.pubkey(), &stake_pool_accounts.withdraw_authority, &new_authority, - &stake_pool_accounts.validator_stake_list.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), &user_stake.stake_account, &user_pool_account.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), @@ -205,7 +204,7 @@ async fn test_remove_validator_stake_account_with_wrong_stake_program_id() { } #[tokio::test] -async fn test_remove_validator_stake_account_with_wrong_token_program_id() { +async fn test_remove_validator_from_pool_with_wrong_token_program_id() { let ( mut banks_client, payer, @@ -220,13 +219,13 @@ async fn test_remove_validator_stake_account_with_wrong_token_program_id() { let new_authority = Pubkey::new_unique(); let mut transaction = Transaction::new_with_payer( - &[instruction::remove_validator_stake_account( + &[instruction::remove_validator_from_pool( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.owner.pubkey(), &stake_pool_accounts.withdraw_authority, &new_authority, - &stake_pool_accounts.validator_stake_list.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), &user_stake.stake_account, &user_pool_account.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), @@ -252,7 +251,7 @@ async fn test_remove_validator_stake_account_with_wrong_token_program_id() { } #[tokio::test] -async fn test_remove_validator_stake_account_with_wrong_pool_mint_account() { +async fn test_remove_validator_from_pool_with_wrong_pool_mint_account() { let ( mut banks_client, payer, @@ -267,13 +266,13 @@ async fn test_remove_validator_stake_account_with_wrong_pool_mint_account() { let new_authority = Pubkey::new_unique(); let mut transaction = Transaction::new_with_payer( - &[instruction::remove_validator_stake_account( + &[instruction::remove_validator_from_pool( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.owner.pubkey(), &stake_pool_accounts.withdraw_authority, &new_authority, - &stake_pool_accounts.validator_stake_list.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), &user_stake.stake_account, &user_pool_account.pubkey(), &wrong_pool_mint.pubkey(), @@ -303,7 +302,7 @@ async fn test_remove_validator_stake_account_with_wrong_pool_mint_account() { } #[tokio::test] -async fn test_remove_validator_stake_account_with_wrong_validator_stake_list_account() { +async fn test_remove_validator_from_pool_with_wrong_validator_list_account() { let ( mut banks_client, payer, @@ -314,17 +313,17 @@ async fn test_remove_validator_stake_account_with_wrong_validator_stake_list_acc _, ) = setup().await; - let wrong_validator_stake_list = Keypair::new(); + let wrong_validator_list = Keypair::new(); let new_authority = Pubkey::new_unique(); let mut transaction = Transaction::new_with_payer( - &[instruction::remove_validator_stake_account( + &[instruction::remove_validator_from_pool( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.owner.pubkey(), &stake_pool_accounts.withdraw_authority, &new_authority, - &wrong_validator_stake_list.pubkey(), + &wrong_validator_list.pubkey(), &user_stake.stake_account, &user_pool_account.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), @@ -379,7 +378,7 @@ async fn test_remove_already_removed_validator_stake_account() { let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts - .remove_validator_stake_account( + .remove_validator_from_pool( &mut banks_client, &payer, &recent_blockhash, @@ -393,7 +392,7 @@ async fn test_remove_already_removed_validator_stake_account() { let latest_blockhash = banks_client.get_recent_blockhash().await.unwrap(); let transaction_error = stake_pool_accounts - .remove_validator_stake_account( + .remove_validator_from_pool( &mut banks_client, &payer, &latest_blockhash, @@ -419,7 +418,7 @@ async fn test_remove_already_removed_validator_stake_account() { } #[tokio::test] -async fn test_not_owner_try_to_remove_validator_stake_account() { +async fn test_not_owner_try_to_remove_validator_from_pool() { let ( mut banks_client, payer, @@ -434,13 +433,13 @@ async fn test_not_owner_try_to_remove_validator_stake_account() { let new_authority = Pubkey::new_unique(); let mut transaction = Transaction::new_with_payer( - &[instruction::remove_validator_stake_account( + &[instruction::remove_validator_from_pool( &id(), &stake_pool_accounts.stake_pool.pubkey(), &malicious.pubkey(), &stake_pool_accounts.withdraw_authority, &new_authority, - &stake_pool_accounts.validator_stake_list.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), &user_stake.stake_account, &user_pool_account.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), @@ -470,7 +469,7 @@ async fn test_not_owner_try_to_remove_validator_stake_account() { } #[tokio::test] -async fn test_not_owner_try_to_remove_validator_stake_account_without_signature() { +async fn test_not_owner_try_to_remove_validator_from_pool_without_signature() { let ( mut banks_client, payer, @@ -488,7 +487,7 @@ async fn test_not_owner_try_to_remove_validator_stake_account_without_signature( AccountMeta::new_readonly(stake_pool_accounts.owner.pubkey(), false), AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false), AccountMeta::new_readonly(new_authority, false), - AccountMeta::new(stake_pool_accounts.validator_stake_list.pubkey(), false), + AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false), AccountMeta::new(user_stake.stake_account, false), AccountMeta::new(user_pool_account.pubkey(), false), AccountMeta::new(stake_pool_accounts.pool_mint.pubkey(), false), @@ -499,7 +498,7 @@ async fn test_not_owner_try_to_remove_validator_stake_account_without_signature( let instruction = Instruction { program_id: id(), accounts, - data: instruction::StakePoolInstruction::RemoveValidatorStakeAccount + data: instruction::StakePoolInstruction::RemoveValidatorFromPool .try_to_vec() .unwrap(), }; @@ -525,7 +524,7 @@ async fn test_not_owner_try_to_remove_validator_stake_account_without_signature( } #[tokio::test] -async fn test_remove_validator_stake_account_when_stake_acc_not_in_stake_state() { +async fn test_remove_validator_from_pool_when_stake_acc_not_in_stake_state() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts @@ -567,7 +566,7 @@ async fn test_remove_validator_stake_account_when_stake_acc_not_in_stake_state() let new_authority = Pubkey::new_unique(); let transaction_error = stake_pool_accounts - .remove_validator_stake_account( + .remove_validator_from_pool( &mut banks_client, &payer, &recent_blockhash, @@ -591,7 +590,7 @@ async fn test_remove_validator_stake_account_when_stake_acc_not_in_stake_state() } #[tokio::test] -async fn test_remove_validator_stake_account_from_unupdated_stake_pool() {} // TODO +async fn test_remove_validator_from_pool_from_unupdated_stake_pool() {} // TODO #[tokio::test] -async fn test_remove_validator_stake_account_with_uninitialized_validator_stake_list_account() {} // TODO +async fn test_remove_validator_from_pool_with_uninitialized_validator_list_account() {} // TODO diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 5fc52390..c5e73777 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -34,7 +34,7 @@ async fn setup() -> ( .await .unwrap(); - let validator_stake_account: ValidatorStakeAccount = simple_add_validator_stake_account( + let validator_stake_account: ValidatorStakeAccount = simple_add_validator_to_pool( &mut banks_client, &payer, &recent_blockhash, @@ -105,15 +105,14 @@ async fn test_stake_pool_withdraw() { state::StakePool::try_from_slice(&stake_pool_before.data.as_slice()).unwrap(); // Save validator stake account record before withdrawal - let validator_stake_list = get_account( + let validator_list = get_account( &mut banks_client, - &stake_pool_accounts.validator_stake_list.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), ) .await; - let validator_stake_list = - try_from_slice_unchecked::(validator_stake_list.data.as_slice()) - .unwrap(); - let validator_stake_item_before = validator_stake_list + let validator_list = + try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); + let validator_stake_item_before = validator_list .find(&validator_stake_account.vote.pubkey()) .unwrap(); @@ -149,15 +148,14 @@ async fn test_stake_pool_withdraw() { ); // Check validator stake list storage - let validator_stake_list = get_account( + let validator_list = get_account( &mut banks_client, - &stake_pool_accounts.validator_stake_list.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), ) .await; - let validator_stake_list = - try_from_slice_unchecked::(validator_stake_list.data.as_slice()) - .unwrap(); - let validator_stake_item = validator_stake_list + let validator_list = + try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); + let validator_stake_item = validator_list .find(&validator_stake_account.vote.pubkey()) .unwrap(); assert_eq!( @@ -212,7 +210,7 @@ async fn test_stake_pool_withdraw_with_wrong_stake_program() { &[instruction::withdraw( &id(), &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.validator_stake_list.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), &stake_pool_accounts.withdraw_authority, &validator_stake_account.stake_account, &user_stake_recipient.pubkey(), @@ -308,7 +306,7 @@ async fn test_stake_pool_withdraw_with_wrong_token_program_id() { &[instruction::withdraw( &id(), &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.validator_stake_list.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), &stake_pool_accounts.withdraw_authority, &validator_stake_account.stake_account, &user_stake_recipient.pubkey(), @@ -338,7 +336,7 @@ async fn test_stake_pool_withdraw_with_wrong_token_program_id() { } #[tokio::test] -async fn test_stake_pool_withdraw_with_wrong_validator_stake_list() { +async fn test_stake_pool_withdraw_with_wrong_validator_list() { let ( mut banks_client, payer, @@ -353,7 +351,7 @@ async fn test_stake_pool_withdraw_with_wrong_validator_stake_list() { let user_stake_recipient = Keypair::new(); let new_authority = Pubkey::new_unique(); - stake_pool_accounts.validator_stake_list = Keypair::new(); + stake_pool_accounts.validator_list = Keypair::new(); let transaction_error = stake_pool_accounts .withdraw_stake( @@ -678,7 +676,7 @@ async fn test_stake_pool_withdraw_token_delegate_was_not_setup() { .await .unwrap(); - let validator_stake_account: ValidatorStakeAccount = simple_add_validator_stake_account( + let validator_stake_account: ValidatorStakeAccount = simple_add_validator_to_pool( &mut banks_client, &payer, &recent_blockhash, @@ -746,7 +744,7 @@ async fn test_stake_pool_withdraw_with_low_delegation() { .await .unwrap(); - let validator_stake_account: ValidatorStakeAccount = simple_add_validator_stake_account( + let validator_stake_account: ValidatorStakeAccount = simple_add_validator_to_pool( &mut banks_client, &payer, &recent_blockhash, From d1e88b5126d5ae2270dab9bb2ab642d2aa41ab82 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Tue, 30 Mar 2021 13:47:09 -0700 Subject: [PATCH 0068/1076] Minor config -> rpc_client refactor --- clients/cli/src/main.rs | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 2802119e..f52c6165 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -94,14 +94,13 @@ fn check_fee_payer_balance(config: &Config, required_balance: u64) -> Result<(), } } -fn get_authority_accounts(config: &Config, authority: &Pubkey) -> Vec<(Pubkey, Account)> { - config - .rpc_client +fn get_authority_accounts(rpc_client: &RpcClient, authority: &Pubkey) -> Vec<(Pubkey, Account)> { + rpc_client .get_program_accounts_with_config( &stake_program_id(), RpcProgramAccountsConfig { filters: Some(vec![RpcFilterType::Memcmp(Memcmp { - offset: 44, // 44 is Withdrawer authority offset in stake accoun stake + offset: 44, // 44 is Withdrawer authority offset in stake account stake bytes: MemcmpEncodedBytes::Binary( bs58::encode(authority.to_bytes()).into_string(), ), @@ -692,7 +691,7 @@ fn command_list(config: &Config, pool: &Pubkey) -> CommandResult { ) .unwrap(); - let accounts = get_authority_accounts(config, &pool_withdraw_authority); + let accounts = get_authority_accounts(&config.rpc_client, &pool_withdraw_authority); if accounts.is_empty() { return Err("No accounts found.".to_string().into()); @@ -785,20 +784,17 @@ struct WithdrawAccount { } fn prepare_withdraw_accounts( - config: &Config, + rpc_client: &RpcClient, stake_pool: &StakePool, pool_withdraw_authority: &Pubkey, pool_amount: u64, ) -> Result, Error> { - let mut accounts = get_authority_accounts(config, &pool_withdraw_authority); + let mut accounts = get_authority_accounts(rpc_client, &pool_withdraw_authority); if accounts.is_empty() { return Err("No accounts found.".to_string().into()); } - let min_balance = config - .rpc_client - .get_minimum_balance_for_rent_exemption(STAKE_STATE_LEN)? - + 1; - let pool_mint_data = config.rpc_client.get_account_data(&stake_pool.pool_mint)?; + let min_balance = rpc_client.get_minimum_balance_for_rent_exemption(STAKE_STATE_LEN)? + 1; + let pool_mint_data = rpc_client.get_account_data(&stake_pool.pool_mint)?; let pool_mint = TokenMint::unpack_from_slice(pool_mint_data.as_slice()).unwrap(); pick_withdraw_accounts( &mut accounts, @@ -905,8 +901,12 @@ fn command_withdraw( } // Get the list of accounts to withdraw from - let withdraw_accounts: Vec = - prepare_withdraw_accounts(config, &pool_data, &pool_withdraw_authority, pool_amount)?; + let withdraw_accounts: Vec = prepare_withdraw_accounts( + &config.rpc_client, + &pool_data, + &pool_withdraw_authority, + pool_amount, + )?; // Construct transaction to withdraw from withdraw_accounts account list let mut instructions: Vec = vec![]; From e69c1f4878782b7685479f70332740ab56f85bc4 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 31 Mar 2021 00:54:15 +0200 Subject: [PATCH 0069/1076] Rework create validator stake account (#1539) --- clients/cli/src/main.rs | 16 +-- program/src/instruction.rs | 52 ++++----- program/src/processor.rs | 42 ++++++- program/src/stake.rs | 16 ++- program/tests/deposit.rs | 140 ++++++---------------- program/tests/helpers/mod.rs | 41 +++---- program/tests/vsa_add.rs | 133 +++++++-------------- program/tests/vsa_create.rs | 220 +++++++++++++++++++++-------------- program/tests/vsa_remove.rs | 121 +++++-------------- program/tests/withdraw.rs | 170 +++++++-------------------- 10 files changed, 379 insertions(+), 572 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index f52c6165..6497b1d4 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -277,13 +277,10 @@ fn command_vsa_create(config: &Config, pool: &Pubkey, vote_account: &Pubkey) -> create_validator_stake_account( &spl_stake_pool::id(), &pool, + &config.owner.pubkey(), &config.fee_payer.pubkey(), &stake_account, &vote_account, - &config.owner.pubkey(), - &config.owner.pubkey(), - &solana_program::system_program::id(), - &stake_program_id(), )?, ], Some(&config.fee_payer.pubkey()), @@ -291,7 +288,10 @@ fn command_vsa_create(config: &Config, pool: &Pubkey, vote_account: &Pubkey) -> let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; - transaction.sign(&[config.fee_payer.as_ref()], recent_blockhash); + transaction.sign( + &[config.fee_payer.as_ref(), config.owner.as_ref()], + recent_blockhash, + ); send_transaction(&config, transaction)?; Ok(()) } @@ -377,7 +377,6 @@ fn command_vsa_add( &token_receiver, &pool_data.pool_mint, &spl_token::id(), - &stake_program_id(), )?, ]); @@ -468,7 +467,6 @@ fn command_vsa_remove( &withdraw_from, &pool_data.pool_mint, &spl_token::id(), - &stake_program_id(), )?, ], Some(&config.fee_payer.pubkey()), @@ -645,7 +643,6 @@ fn command_deposit( &pool_data.owner_fee_account, &pool_data.pool_mint, &spl_token::id(), - &stake_program_id(), )?, ]); @@ -984,7 +981,6 @@ fn command_withdraw( &withdraw_from, &pool_data.pool_mint, &spl_token::id(), - &stake_program_id(), withdraw_stake.pool_amount, )?); } @@ -1163,7 +1159,7 @@ fn main() { .help("Max number of validators included in the stake pool"), ) ) - .subcommand(SubCommand::with_name("create-validator-stake").about("Create a new stake account to use with the pool") + .subcommand(SubCommand::with_name("create-validator-stake").about("Create a new stake account to use with the pool. Must be signed by the pool owner.") .arg( Arg::with_name("pool") .index(1) diff --git a/program/src/instruction.rs b/program/src/instruction.rs index eb2881a5..db304387 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -3,12 +3,13 @@ #![allow(clippy::too_many_arguments)] use { + crate::stake, borsh::{BorshDeserialize, BorshSchema, BorshSerialize}, solana_program::{ instruction::{AccountMeta, Instruction}, program_error::ProgramError, pubkey::Pubkey, - sysvar, + system_program, sysvar, }, }; @@ -48,17 +49,17 @@ pub enum StakePoolInstruction { /// Creates new program account for accumulating stakes for a particular validator /// /// 0. `[]` Stake pool account this stake will belong to - /// 1. `[ws]` Funding account (must be a system account) - /// 2. `[w]` Stake account to be created - /// 3. `[]` Validator this stake account will vote for - /// 4. `[]` Stake authority for the new stake account - /// 5. `[]` Withdraw authority for the new stake account - /// 6. `[]` Rent sysvar - /// 7. `[]` System program - /// 8. `[]` Stake program + /// 1. `[s]` Owner + /// 2. `[ws]` Funding account (must be a system account) + /// 3. `[w]` Stake account to be created + /// 4. `[]` Validator this stake account will vote for + /// 5. `[]` Rent sysvar + /// 6. `[]` System program + /// 7. `[]` Stake program CreateValidatorStakeAccount, - /// Adds validator stake account to the pool + /// Adds stake account delegated to validator to the pool's list of + /// managed validators /// /// 0. `[w]` Stake pool /// 1. `[s]` Owner @@ -185,24 +186,23 @@ pub fn initialize( pub fn create_validator_stake_account( program_id: &Pubkey, stake_pool: &Pubkey, + owner: &Pubkey, funder: &Pubkey, stake_account: &Pubkey, validator: &Pubkey, - stake_authority: &Pubkey, - withdraw_authority: &Pubkey, - system_program_id: &Pubkey, - stake_program_id: &Pubkey, ) -> Result { let accounts = vec![ AccountMeta::new_readonly(*stake_pool, false), + AccountMeta::new_readonly(*owner, true), AccountMeta::new(*funder, true), AccountMeta::new(*stake_account, false), AccountMeta::new_readonly(*validator, false), - AccountMeta::new_readonly(*stake_authority, false), - AccountMeta::new_readonly(*withdraw_authority, false), AccountMeta::new_readonly(sysvar::rent::id(), false), - AccountMeta::new_readonly(*system_program_id, false), - AccountMeta::new_readonly(*stake_program_id, false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(sysvar::stake_history::id(), false), + AccountMeta::new_readonly(stake::config_id(), false), + AccountMeta::new_readonly(system_program::id(), false), + AccountMeta::new_readonly(stake::id(), false), ]; Ok(Instruction { program_id: *program_id, @@ -220,10 +220,9 @@ pub fn add_validator_to_pool( stake_pool_withdraw: &Pubkey, validator_list: &Pubkey, stake_account: &Pubkey, - pool_tokens_to: &Pubkey, + pool_token_receiver: &Pubkey, pool_mint: &Pubkey, token_program_id: &Pubkey, - stake_program_id: &Pubkey, ) -> Result { let accounts = vec![ AccountMeta::new(*stake_pool, false), @@ -232,12 +231,12 @@ pub fn add_validator_to_pool( AccountMeta::new_readonly(*stake_pool_withdraw, false), AccountMeta::new(*validator_list, false), AccountMeta::new(*stake_account, false), - AccountMeta::new(*pool_tokens_to, false), + AccountMeta::new(*pool_token_receiver, false), AccountMeta::new(*pool_mint, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), AccountMeta::new_readonly(*token_program_id, false), - AccountMeta::new_readonly(*stake_program_id, false), + AccountMeta::new_readonly(stake::id(), false), ]; Ok(Instruction { program_id: *program_id, @@ -258,7 +257,6 @@ pub fn remove_validator_from_pool( burn_from: &Pubkey, pool_mint: &Pubkey, token_program_id: &Pubkey, - stake_program_id: &Pubkey, ) -> Result { let accounts = vec![ AccountMeta::new(*stake_pool, false), @@ -271,7 +269,7 @@ pub fn remove_validator_from_pool( AccountMeta::new(*pool_mint, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(*token_program_id, false), - AccountMeta::new_readonly(*stake_program_id, false), + AccountMeta::new_readonly(stake::id(), false), ]; Ok(Instruction { program_id: *program_id, @@ -330,7 +328,6 @@ pub fn deposit( pool_fee_to: &Pubkey, pool_mint: &Pubkey, token_program_id: &Pubkey, - stake_program_id: &Pubkey, ) -> Result { let accounts = vec![ AccountMeta::new(*stake_pool, false), @@ -345,7 +342,7 @@ pub fn deposit( AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), AccountMeta::new_readonly(*token_program_id, false), - AccountMeta::new_readonly(*stake_program_id, false), + AccountMeta::new_readonly(stake::id(), false), ]; Ok(Instruction { program_id: *program_id, @@ -366,7 +363,6 @@ pub fn withdraw( burn_from: &Pubkey, pool_mint: &Pubkey, token_program_id: &Pubkey, - stake_program_id: &Pubkey, amount: u64, ) -> Result { let accounts = vec![ @@ -380,7 +376,7 @@ pub fn withdraw( AccountMeta::new(*pool_mint, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(*token_program_id, false), - AccountMeta::new_readonly(*stake_program_id, false), + AccountMeta::new_readonly(stake::id(), false), ]; Ok(Instruction { program_id: *program_id, diff --git a/program/src/processor.rs b/program/src/processor.rs index ad1e790b..d9c35f53 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -403,24 +403,38 @@ impl Processor { let account_info_iter = &mut accounts.iter(); // Stake pool account let stake_pool_info = next_account_info(account_info_iter)?; + // Owner account + let owner_info = next_account_info(account_info_iter)?; // Account creation funder account let funder_info = next_account_info(account_info_iter)?; // Stake account to be created let stake_account_info = next_account_info(account_info_iter)?; // Validator this stake account will vote for let validator_info = next_account_info(account_info_iter)?; - // Stake authority for the new stake account - let stake_authority_info = next_account_info(account_info_iter)?; - // Withdraw authority for the new stake account - let withdraw_authority_info = next_account_info(account_info_iter)?; // Rent sysvar account let rent_info = next_account_info(account_info_iter)?; let rent = &Rent::from_account_info(rent_info)?; + // Clock sysvar account + let clock_info = next_account_info(account_info_iter)?; + // Stake history sysvar account + let stake_history_info = next_account_info(account_info_iter)?; + // Stake config sysvar account + let stake_config_info = next_account_info(account_info_iter)?; // System program id let system_program_info = next_account_info(account_info_iter)?; // Staking program id let stake_program_info = next_account_info(account_info_iter)?; + // Get stake pool stake (and check if it is initialized) + if stake_pool_info.owner != program_id { + return Err(ProgramError::IncorrectProgramId); + } + let stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; + if !stake_pool.is_valid() { + return Err(StakePoolError::InvalidState.into()); + } + stake_pool.check_owner(owner_info)?; + // Check program ids if *system_program_info.key != solana_program::system_program::id() { return Err(ProgramError::IncorrectProgramId); @@ -466,8 +480,8 @@ impl Processor { &stake::initialize( &stake_account_info.key, &stake::Authorized { - staker: *stake_authority_info.key, - withdrawer: *withdraw_authority_info.key, + staker: *owner_info.key, + withdrawer: *owner_info.key, }, &stake::Lockup::default(), ), @@ -476,6 +490,22 @@ impl Processor { rent_info.clone(), stake_program_info.clone(), ], + )?; + + invoke( + &stake::delegate_stake( + &stake_account_info.key, + &owner_info.key, + &validator_info.key, + ), + &[ + stake_account_info.clone(), + validator_info.clone(), + clock_info.clone(), + stake_history_info.clone(), + stake_config_info.clone(), + owner_info.clone(), + ], ) } diff --git a/program/src/stake.rs b/program/src/stake.rs index a23f5204..2eeb53b3 100644 --- a/program/src/stake.rs +++ b/program/src/stake.rs @@ -13,6 +13,10 @@ use std::str::FromStr; solana_program::declare_id!("Stake11111111111111111111111111111111111111"); const STAKE_CONFIG: &str = "StakeConfig11111111111111111111111111111111"; +/// Id for stake config account +pub fn config_id() -> Pubkey { + Pubkey::from_str(STAKE_CONFIG).unwrap() +} /// FIXME copied from solana stake program #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] @@ -489,8 +493,18 @@ pub fn delegate_stake( AccountMeta::new_readonly(*vote_pubkey, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), - AccountMeta::new_readonly(Pubkey::from_str(STAKE_CONFIG).unwrap(), false), + AccountMeta::new_readonly(config_id(), false), AccountMeta::new_readonly(*authorized_pubkey, true), ]; Instruction::new_with_bincode(id(), &StakeInstruction::DelegateStake, account_metas) } + +/// FIXME copied from stake program +pub fn deactivate_stake(stake_pubkey: &Pubkey, authorized_pubkey: &Pubkey) -> Instruction { + let account_metas = vec![ + AccountMeta::new(*stake_pubkey, false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(*authorized_pubkey, true), + ]; + Instruction::new_with_bincode(id(), &StakeInstruction::Deactivate, account_metas) +} diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index e750bd3e..a5b911d4 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -3,12 +3,16 @@ mod helpers; use { - borsh::BorshDeserialize, + borsh::{BorshDeserialize, BorshSerialize}, helpers::*, - solana_program::hash::Hash, + solana_program::{ + hash::Hash, + instruction::{AccountMeta, Instruction, InstructionError}, + pubkey::Pubkey, + sysvar, + }, solana_program_test::*, solana_sdk::{ - instruction::InstructionError, signature::{Keypair, Signer}, transaction::Transaction, transaction::TransactionError, @@ -237,26 +241,32 @@ async fn test_stake_pool_deposit_with_wrong_stake_program_id() { .await .unwrap(); - let wrong_stake_program = Keypair::new(); + let wrong_stake_program = Pubkey::new_unique(); + + let accounts = vec![ + AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), + AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false), + AccountMeta::new_readonly(stake_pool_accounts.deposit_authority, false), + AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false), + AccountMeta::new(user_stake.pubkey(), false), + AccountMeta::new(validator_stake_account.stake_account, false), + AccountMeta::new(user_pool_account.pubkey(), false), + AccountMeta::new(stake_pool_accounts.pool_fee_account.pubkey(), false), + AccountMeta::new(stake_pool_accounts.pool_mint.pubkey(), false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(sysvar::stake_history::id(), false), + AccountMeta::new_readonly(spl_token::id(), false), + AccountMeta::new_readonly(wrong_stake_program, false), + ]; + let instruction = Instruction { + program_id: id(), + accounts, + data: instruction::StakePoolInstruction::Deposit + .try_to_vec() + .unwrap(), + }; - let mut transaction = Transaction::new_with_payer( - &[instruction::deposit( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.validator_list.pubkey(), - &stake_pool_accounts.deposit_authority, - &stake_pool_accounts.withdraw_authority, - &user_stake.pubkey(), - &validator_stake_account.stake_account, - &user_pool_account.pubkey(), - &stake_pool_accounts.pool_fee_account.pubkey(), - &stake_pool_accounts.pool_mint.pubkey(), - &spl_token::id(), - &wrong_stake_program.pubkey(), - ) - .unwrap()], - Some(&payer.pubkey()), - ); + let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); transaction.sign(&[&payer], recent_blockhash); let transaction_error = banks_client .process_transaction(transaction) @@ -392,7 +402,6 @@ async fn test_stake_pool_deposit_with_wrong_token_program_id() { &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), &wrong_token_program.pubkey(), - &stake::id(), ) .unwrap()], Some(&payer.pubkey()), @@ -482,7 +491,7 @@ async fn test_stake_pool_deposit_with_wrong_validator_list_account() { } #[tokio::test] -async fn test_stake_pool_deposit_where_stake_acc_not_in_stake_state() { +async fn test_stake_pool_deposit_to_unknown_validator() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts @@ -494,90 +503,13 @@ async fn test_stake_pool_deposit_where_stake_acc_not_in_stake_state() { &stake_pool_accounts.deposit_authority, &stake_pool_accounts.stake_pool.pubkey(), ); - - let user_stake_authority = Keypair::new(); - create_validator_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &validator_stake_account.stake_pool, - &validator_stake_account.stake_account, - &validator_stake_account.vote.pubkey(), - &user_stake_authority.pubkey(), - &validator_stake_account.target_authority, - ) - .await; - - let user_pool_account = Keypair::new(); - let user = Keypair::new(); - create_token_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_pool_account, - &stake_pool_accounts.pool_mint.pubkey(), - &user.pubkey(), - ) - .await - .unwrap(); - - let user_stake_acc = Keypair::new(); - let lockup = stake::Lockup::default(); - let authorized = stake::Authorized { - staker: stake_pool_accounts.deposit_authority, - withdrawer: stake_pool_accounts.deposit_authority, - }; - create_independent_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake_acc, - &authorized, - &lockup, - ) - .await; - let transaction_error = stake_pool_accounts - .deposit_stake( + validator_stake_account + .create_and_delegate( &mut banks_client, &payer, &recent_blockhash, - &user_stake_acc.pubkey(), - &user_pool_account.pubkey(), - &validator_stake_account.stake_account, + &stake_pool_accounts.owner, ) - .await - .err() - .unwrap(); - - match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError( - _, - InstructionError::Custom(error_index), - )) => { - let program_error = error::StakePoolError::WrongStakeState as u32; - assert_eq!(error_index, program_error); - } - _ => panic!( - "Wrong error occurs while try to make a deposit when stake acc not in stake state" - ), - } -} - -#[tokio::test] -async fn test_stake_pool_deposit_to_unknown_validator() { - let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); - stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) - .await - .unwrap(); - - let validator_stake_account = ValidatorStakeAccount::new_with_target_authority( - &stake_pool_accounts.deposit_authority, - &stake_pool_accounts.stake_pool.pubkey(), - ); - validator_stake_account - .create_and_delegate(&mut banks_client, &payer, &recent_blockhash) .await; let user_pool_account = Keypair::new(); diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 0ca4dbe4..13f8569e 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -300,30 +300,26 @@ pub async fn create_validator_stake_account( payer: &Keypair, recent_blockhash: &Hash, stake_pool: &Pubkey, + owner: &Keypair, stake_account: &Pubkey, validator: &Pubkey, - stake_authority: &Pubkey, - withdraw_authority: &Pubkey, ) { let mut transaction = Transaction::new_with_payer( &[ instruction::create_validator_stake_account( &id(), &stake_pool, + &owner.pubkey(), &payer.pubkey(), &stake_account, &validator, - &stake_authority, - &withdraw_authority, - &solana_program::system_program::id(), - &stake::id(), ) .unwrap(), system_instruction::transfer(&payer.pubkey(), &stake_account, TEST_STAKE_AMOUNT), ], Some(&payer.pubkey()), ); - transaction.sign(&[payer], *recent_blockhash); + transaction.sign(&[payer, owner], *recent_blockhash); banks_client.process_transaction(transaction).await.unwrap(); } @@ -393,29 +389,29 @@ impl ValidatorStakeAccount { mut banks_client: &mut BanksClient, payer: &Keypair, recent_blockhash: &Hash, + owner: &Keypair, ) { - // make stake account - let user_stake_authority = Keypair::new(); + create_vote(&mut banks_client, &payer, &recent_blockhash, &self.vote).await; + create_validator_stake_account( &mut banks_client, &payer, &recent_blockhash, &self.stake_pool, + owner, &self.stake_account, &self.vote.pubkey(), - &user_stake_authority.pubkey(), - &self.target_authority, ) .await; - create_vote(&mut banks_client, &payer, &recent_blockhash, &self.vote).await; - delegate_stake_account( + authorize_stake_account( &mut banks_client, &payer, &recent_blockhash, &self.stake_account, - &user_stake_authority, - &self.vote.pubkey(), + &owner, + &self.target_authority, + stake::StakeAuthorize::Staker, ) .await; @@ -424,9 +420,9 @@ impl ValidatorStakeAccount { &payer, &recent_blockhash, &self.stake_account, - &user_stake_authority, + &owner, &self.target_authority, - stake::StakeAuthorize::Staker, + stake::StakeAuthorize::Withdrawer, ) .await; } @@ -542,7 +538,6 @@ impl StakePoolAccounts { &self.pool_fee_account.pubkey(), &self.pool_mint.pubkey(), &spl_token::id(), - &stake::id(), ) .unwrap()], Some(&payer.pubkey()), @@ -575,7 +570,6 @@ impl StakePoolAccounts { pool_account, &self.pool_mint.pubkey(), &spl_token::id(), - &stake::id(), amount, ) .unwrap()], @@ -606,7 +600,6 @@ impl StakePoolAccounts { pool_account, &self.pool_mint.pubkey(), &spl_token::id(), - &stake::id(), ) .unwrap()], Some(&payer.pubkey()), @@ -636,7 +629,6 @@ impl StakePoolAccounts { pool_account, &self.pool_mint.pubkey(), &spl_token::id(), - &stake::id(), ) .unwrap()], Some(&payer.pubkey()), @@ -657,7 +649,12 @@ pub async fn simple_add_validator_to_pool( &stake_pool_accounts.stake_pool.pubkey(), ); user_stake - .create_and_delegate(banks_client, &payer, &recent_blockhash) + .create_and_delegate( + banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.owner, + ) .await; let user_pool_account = Keypair::new(); diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index 048f0ef1..f2645f1b 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -8,12 +8,12 @@ use { helpers::*, solana_program::{ hash::Hash, - instruction::{AccountMeta, Instruction}, + instruction::{AccountMeta, Instruction, InstructionError}, + pubkey::Pubkey, sysvar, }, solana_program_test::*, solana_sdk::{ - instruction::InstructionError, signature::{Keypair, Signer}, transaction::{Transaction, TransactionError}, transport::TransportError, @@ -43,7 +43,12 @@ async fn setup() -> ( &stake_pool_accounts.stake_pool.pubkey(), ); user_stake - .create_and_delegate(&mut banks_client, &payer, &recent_blockhash) + .create_and_delegate( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.owner, + ) .await; // make pool token account @@ -170,7 +175,6 @@ async fn test_add_validator_to_pool_with_wrong_token_program_id() { &user_pool_account.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), &stake::id(), - &stake::id(), ) .unwrap()], Some(&payer.pubkey()), @@ -215,7 +219,6 @@ async fn test_add_validator_to_pool_with_wrong_pool_mint_account() { &user_pool_account.pubkey(), &wrong_pool_mint.pubkey(), &spl_token::id(), - &stake::id(), ) .unwrap()], Some(&payer.pubkey()), @@ -264,7 +267,6 @@ async fn test_add_validator_to_pool_with_wrong_validator_list_account() { &user_pool_account.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), &spl_token::id(), - &stake::id(), ) .unwrap()], Some(&payer.pubkey()), @@ -359,7 +361,6 @@ async fn test_not_owner_try_to_add_validator_to_pool() { &user_pool_account.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), &spl_token::id(), - &stake::id(), ) .unwrap()], Some(&payer.pubkey()), @@ -436,69 +437,6 @@ async fn test_not_owner_try_to_add_validator_to_pool_without_signature() { } } -#[tokio::test] -async fn test_add_validator_to_pool_when_stake_acc_not_in_stake_state() { - let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); - stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) - .await - .unwrap(); - - let user = Keypair::new(); - - let user_stake = ValidatorStakeAccount::new_with_target_authority( - &stake_pool_accounts.deposit_authority, - &stake_pool_accounts.stake_pool.pubkey(), - ); - let user_stake_authority = Keypair::new(); - create_validator_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake.stake_pool, - &user_stake.stake_account, - &user_stake.vote.pubkey(), - &user_stake_authority.pubkey(), - &user_stake.target_authority, - ) - .await; - - let user_pool_account = Keypair::new(); - create_token_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_pool_account, - &stake_pool_accounts.pool_mint.pubkey(), - &user.pubkey(), - ) - .await - .unwrap(); - - let transaction_error = stake_pool_accounts - .add_validator_to_pool( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake.stake_account, - &user_pool_account.pubkey(), - ) - .await - .unwrap(); - - match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError( - _, - InstructionError::Custom(error_index), - )) => { - let program_error = error::StakePoolError::WrongStakeState as u32; - assert_eq!(error_index, program_error); - } - _ => panic!("Wrong error occurs while try to add validator stake account when it isn't in stake state"), - } -} - #[tokio::test] async fn test_add_validator_to_pool_with_wrong_stake_program_id() { let ( @@ -510,25 +448,30 @@ async fn test_add_validator_to_pool_with_wrong_stake_program_id() { user_pool_account, ) = setup().await; - let wrong_stake_program = Keypair::new(); + let wrong_stake_program = Pubkey::new_unique(); - let mut transaction = Transaction::new_with_payer( - &[instruction::add_validator_to_pool( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.owner.pubkey(), - &stake_pool_accounts.deposit_authority, - &stake_pool_accounts.withdraw_authority, - &stake_pool_accounts.validator_list.pubkey(), - &user_stake.stake_account, - &user_pool_account.pubkey(), - &stake_pool_accounts.pool_mint.pubkey(), - &spl_token::id(), - &wrong_stake_program.pubkey(), - ) - .unwrap()], - Some(&payer.pubkey()), - ); + let accounts = vec![ + AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), + AccountMeta::new_readonly(stake_pool_accounts.owner.pubkey(), true), + AccountMeta::new_readonly(stake_pool_accounts.deposit_authority, false), + AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false), + AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false), + AccountMeta::new(user_stake.stake_account, false), + AccountMeta::new(user_pool_account.pubkey(), false), + AccountMeta::new(stake_pool_accounts.pool_mint.pubkey(), false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(sysvar::stake_history::id(), false), + AccountMeta::new_readonly(spl_token::id(), false), + AccountMeta::new_readonly(wrong_stake_program, false), + ]; + let instruction = Instruction { + program_id: id(), + accounts, + data: instruction::StakePoolInstruction::AddValidatorToPool + .try_to_vec() + .unwrap(), + }; + let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); let transaction_error = banks_client .process_transaction(transaction) @@ -563,7 +506,12 @@ async fn test_add_too_many_validator_stake_accounts() { &stake_pool_accounts.stake_pool.pubkey(), ); user_stake - .create_and_delegate(&mut banks_client, &payer, &recent_blockhash) + .create_and_delegate( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.owner, + ) .await; // make pool token account @@ -595,7 +543,12 @@ async fn test_add_too_many_validator_stake_accounts() { &stake_pool_accounts.stake_pool.pubkey(), ); user_stake - .create_and_delegate(&mut banks_client, &payer, &recent_blockhash) + .create_and_delegate( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.owner, + ) .await; let error = stake_pool_accounts .add_validator_to_pool( diff --git a/program/tests/vsa_create.rs b/program/tests/vsa_create.rs index baad6e65..e0f36fde 100644 --- a/program/tests/vsa_create.rs +++ b/program/tests/vsa_create.rs @@ -2,22 +2,27 @@ mod helpers; -use crate::solana_program::pubkey::Pubkey; -use helpers::*; - -use bincode::deserialize; -use solana_program_test::*; -use solana_sdk::{ - instruction::InstructionError, - signature::{Keypair, Signer}, - transaction::Transaction, - transaction::TransactionError, - transport::TransportError, +use { + bincode::deserialize, + borsh::BorshSerialize, + helpers::*, + solana_program::{ + instruction::{AccountMeta, Instruction, InstructionError}, + pubkey::Pubkey, + system_program, sysvar, + }, + solana_program_test::*, + solana_sdk::{ + signature::{Keypair, Signer}, + transaction::Transaction, + transaction::TransactionError, + transport::TransportError, + }, + spl_stake_pool::{error, id, instruction, processor, stake}, }; -use spl_stake_pool::*; #[tokio::test] -async fn test_create_validator_stake_account() { +async fn success_create_validator_stake_account() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts @@ -25,13 +30,12 @@ async fn test_create_validator_stake_account() { .await .unwrap(); - let validator = Pubkey::new_unique(); - let user_stake_authority = Keypair::new(); - let user_withdraw_authority = Keypair::new(); + let validator = Keypair::new(); + create_vote(&mut banks_client, &payer, &recent_blockhash, &validator).await; let (stake_account, _) = processor::Processor::find_stake_address_for_validator( &id(), - &validator, + &validator.pubkey(), &stake_pool_accounts.stake_pool.pubkey(), ); @@ -39,37 +43,35 @@ async fn test_create_validator_stake_account() { &[instruction::create_validator_stake_account( &id(), &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.owner.pubkey(), &payer.pubkey(), &stake_account, - &validator, - &user_stake_authority.pubkey(), - &user_withdraw_authority.pubkey(), - &solana_program::system_program::id(), - &stake::id(), + &validator.pubkey(), ) .unwrap()], Some(&payer.pubkey()), ); - transaction.sign(&[&payer], recent_blockhash); + transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); banks_client.process_transaction(transaction).await.unwrap(); // Check authorities let stake = get_account(&mut banks_client, &stake_account).await; let stake_state = deserialize::(&stake.data).unwrap(); match stake_state { - stake::StakeState::Initialized(meta) => { - assert_eq!(&meta.authorized.staker, &user_stake_authority.pubkey()); + stake::StakeState::Stake(meta, stake) => { + assert_eq!(&meta.authorized.staker, &stake_pool_accounts.owner.pubkey()); assert_eq!( &meta.authorized.withdrawer, - &user_withdraw_authority.pubkey() + &stake_pool_accounts.owner.pubkey() ); + assert_eq!(stake.delegation.voter_pubkey, validator.pubkey()); } _ => panic!(), } } #[tokio::test] -async fn test_create_validator_stake_account_with_incorrect_address() { +async fn fail_create_validator_stake_account_on_non_vote_account() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts @@ -78,48 +80,41 @@ async fn test_create_validator_stake_account_with_incorrect_address() { .unwrap(); let validator = Pubkey::new_unique(); - let user_stake_authority = Keypair::new(); - let user_withdraw_authority = Keypair::new(); - let stake_account = Keypair::new(); + + let (stake_account, _) = processor::Processor::find_stake_address_for_validator( + &id(), + &validator, + &stake_pool_accounts.stake_pool.pubkey(), + ); let mut transaction = Transaction::new_with_payer( &[instruction::create_validator_stake_account( &id(), &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.owner.pubkey(), &payer.pubkey(), - &stake_account.pubkey(), + &stake_account, &validator, - &user_stake_authority.pubkey(), - &user_withdraw_authority.pubkey(), - &solana_program::system_program::id(), - &stake::id(), ) .unwrap()], Some(&payer.pubkey()), ); - transaction.sign(&[&payer], recent_blockhash); + transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); let transaction_error = banks_client .process_transaction(transaction) .await .err() + .unwrap() .unwrap(); - match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError( - _, - InstructionError::Custom(error_index), - )) => { - let program_error = error::StakePoolError::InvalidStakeAccountAddress as u32; - assert_eq!(error_index, program_error); - } - _ => panic!( - "Wrong error occurs while try to create validator stake account with incorrect address" - ), - } + assert_eq!( + transaction_error, + TransactionError::InstructionError(0, InstructionError::IncorrectProgramId,) + ); } #[tokio::test] -async fn test_create_validator_stake_account_with_wrong_system_program() { +async fn fail_create_validator_stake_account_with_wrong_system_program() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts @@ -128,51 +123,51 @@ async fn test_create_validator_stake_account_with_wrong_system_program() { .unwrap(); let validator = Pubkey::new_unique(); - let user_stake_authority = Keypair::new(); - let user_withdraw_authority = Keypair::new(); let (stake_account, _) = processor::Processor::find_stake_address_for_validator( &id(), &validator, &stake_pool_accounts.stake_pool.pubkey(), ); + let wrong_system_program = Pubkey::new_unique(); + let accounts = vec![ + AccountMeta::new_readonly(stake_pool_accounts.stake_pool.pubkey(), false), + AccountMeta::new_readonly(stake_pool_accounts.owner.pubkey(), true), + AccountMeta::new(payer.pubkey(), true), + AccountMeta::new(stake_account, false), + AccountMeta::new_readonly(validator, false), + AccountMeta::new_readonly(sysvar::rent::id(), false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(sysvar::stake_history::id(), false), + AccountMeta::new_readonly(stake::config_id(), false), + AccountMeta::new_readonly(wrong_system_program, false), + AccountMeta::new_readonly(stake::id(), false), + ]; + let instruction = Instruction { + program_id: id(), + accounts, + data: instruction::StakePoolInstruction::CreateValidatorStakeAccount + .try_to_vec() + .unwrap(), + }; - let wrong_system_program = Keypair::new(); - - let mut transaction = Transaction::new_with_payer( - &[instruction::create_validator_stake_account( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &payer.pubkey(), - &stake_account, - &validator, - &user_stake_authority.pubkey(), - &user_withdraw_authority.pubkey(), - &wrong_system_program.pubkey(), - &stake::id(), - ) - .unwrap()], - Some(&payer.pubkey()), - ); - transaction.sign(&[&payer], recent_blockhash); + let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); + transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); let transaction_error = banks_client .process_transaction(transaction) .await .err() + .unwrap() .unwrap(); - match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { - assert_eq!(error, InstructionError::IncorrectProgramId); - } - _ => panic!( - "Wrong error occurs while try to create validator stake account with wrong token program ID" - ), - } + assert_eq!( + transaction_error, + TransactionError::InstructionError(0, InstructionError::IncorrectProgramId,) + ); } #[tokio::test] -async fn test_create_validator_stake_account_with_wrong_stake_program() { +async fn fail_create_validator_stake_account_with_wrong_stake_program() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts @@ -181,33 +176,74 @@ async fn test_create_validator_stake_account_with_wrong_stake_program() { .unwrap(); let validator = Pubkey::new_unique(); - let user_stake_authority = Keypair::new(); - let user_withdraw_authority = Keypair::new(); let (stake_account, _) = processor::Processor::find_stake_address_for_validator( &id(), &validator, &stake_pool_accounts.stake_pool.pubkey(), ); + let wrong_stake_program = Pubkey::new_unique(); + let accounts = vec![ + AccountMeta::new_readonly(stake_pool_accounts.stake_pool.pubkey(), false), + AccountMeta::new_readonly(stake_pool_accounts.owner.pubkey(), true), + AccountMeta::new(payer.pubkey(), true), + AccountMeta::new(stake_account, false), + AccountMeta::new_readonly(validator, false), + AccountMeta::new_readonly(sysvar::rent::id(), false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(sysvar::stake_history::id(), false), + AccountMeta::new_readonly(stake::config_id(), false), + AccountMeta::new_readonly(system_program::id(), false), + AccountMeta::new_readonly(wrong_stake_program, false), + ]; + let instruction = Instruction { + program_id: id(), + accounts, + data: instruction::StakePoolInstruction::CreateValidatorStakeAccount + .try_to_vec() + .unwrap(), + }; + + let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); + transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); - let wrong_stake_program = Keypair::new(); + assert_eq!( + transaction_error, + TransactionError::InstructionError(0, InstructionError::IncorrectProgramId,) + ); +} + +#[tokio::test] +async fn fail_create_validator_stake_account_with_incorrect_address() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await + .unwrap(); + + let validator = Pubkey::new_unique(); + let stake_account = Keypair::new(); let mut transaction = Transaction::new_with_payer( &[instruction::create_validator_stake_account( &id(), &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.owner.pubkey(), &payer.pubkey(), - &stake_account, + &stake_account.pubkey(), &validator, - &user_stake_authority.pubkey(), - &user_withdraw_authority.pubkey(), - &solana_program::system_program::id(), - &wrong_stake_program.pubkey(), ) .unwrap()], Some(&payer.pubkey()), ); - transaction.sign(&[&payer], recent_blockhash); + transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); let transaction_error = banks_client .process_transaction(transaction) .await @@ -215,11 +251,15 @@ async fn test_create_validator_stake_account_with_wrong_stake_program() { .unwrap(); match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { - assert_eq!(error, InstructionError::IncorrectProgramId); + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::InvalidStakeAccountAddress as u32; + assert_eq!(error_index, program_error); } _ => panic!( - "Wrong error occurs while try to create validator stake account with wrong stake program ID" + "Wrong error occurs while try to create validator stake account with incorrect address" ), } } diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 8cc29eda..93d8dd93 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -8,13 +8,12 @@ use { helpers::*, solana_program::{ hash::Hash, - instruction::{AccountMeta, Instruction}, + instruction::{AccountMeta, Instruction, InstructionError}, pubkey::Pubkey, sysvar, }, solana_program_test::*, solana_sdk::{ - instruction::InstructionError, signature::{Keypair, Signer}, transaction::{Transaction, TransactionError}, transport::TransportError, @@ -45,7 +44,12 @@ async fn setup() -> ( &stake_pool_accounts.stake_pool.pubkey(), ); user_stake - .create_and_delegate(&mut banks_client, &payer, &recent_blockhash) + .create_and_delegate( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.owner, + ) .await; // make pool token account @@ -165,26 +169,31 @@ async fn test_remove_validator_from_pool_with_wrong_stake_program_id() { _, ) = setup().await; - let wrong_stake_program = Keypair::new(); + let wrong_stake_program = Pubkey::new_unique(); let new_authority = Pubkey::new_unique(); - let mut transaction = Transaction::new_with_payer( - &[instruction::remove_validator_from_pool( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.owner.pubkey(), - &stake_pool_accounts.withdraw_authority, - &new_authority, - &stake_pool_accounts.validator_list.pubkey(), - &user_stake.stake_account, - &user_pool_account.pubkey(), - &stake_pool_accounts.pool_mint.pubkey(), - &spl_token::id(), - &wrong_stake_program.pubkey(), - ) - .unwrap()], - Some(&payer.pubkey()), - ); + let accounts = vec![ + AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), + AccountMeta::new_readonly(stake_pool_accounts.owner.pubkey(), true), + AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false), + AccountMeta::new_readonly(new_authority, false), + AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false), + AccountMeta::new(user_stake.stake_account, false), + AccountMeta::new(user_pool_account.pubkey(), false), + AccountMeta::new(stake_pool_accounts.pool_mint.pubkey(), false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(spl_token::id(), false), + AccountMeta::new_readonly(wrong_stake_program, false), + ]; + let instruction = Instruction { + program_id: id(), + accounts, + data: instruction::StakePoolInstruction::RemoveValidatorFromPool + .try_to_vec() + .unwrap(), + }; + + let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); let transaction_error = banks_client .process_transaction(transaction) @@ -230,7 +239,6 @@ async fn test_remove_validator_from_pool_with_wrong_token_program_id() { &user_pool_account.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), &wrong_token_program.pubkey(), - &stake::id(), ) .unwrap()], Some(&payer.pubkey()), @@ -277,7 +285,6 @@ async fn test_remove_validator_from_pool_with_wrong_pool_mint_account() { &user_pool_account.pubkey(), &wrong_pool_mint.pubkey(), &spl_token::id(), - &stake::id(), ) .unwrap()], Some(&payer.pubkey()), @@ -328,7 +335,6 @@ async fn test_remove_validator_from_pool_with_wrong_validator_list_account() { &user_pool_account.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), &spl_token::id(), - &stake::id(), ) .unwrap()], Some(&payer.pubkey()), @@ -444,7 +450,6 @@ async fn test_not_owner_try_to_remove_validator_from_pool() { &user_pool_account.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), &spl_token::id(), - &stake::id(), ) .unwrap()], Some(&payer.pubkey()), @@ -523,72 +528,6 @@ async fn test_not_owner_try_to_remove_validator_from_pool_without_signature() { } } -#[tokio::test] -async fn test_remove_validator_from_pool_when_stake_acc_not_in_stake_state() { - let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); - stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) - .await - .unwrap(); - - let user = Keypair::new(); - - let user_stake = ValidatorStakeAccount::new_with_target_authority( - &stake_pool_accounts.deposit_authority, - &stake_pool_accounts.stake_pool.pubkey(), - ); - let user_stake_authority = Keypair::new(); - create_validator_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake.stake_pool, - &user_stake.stake_account, - &user_stake.vote.pubkey(), - &user_stake_authority.pubkey(), - &user_stake.target_authority, - ) - .await; - - let user_pool_account = Keypair::new(); - create_token_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_pool_account, - &stake_pool_accounts.pool_mint.pubkey(), - &user.pubkey(), - ) - .await - .unwrap(); - - let new_authority = Pubkey::new_unique(); - - let transaction_error = stake_pool_accounts - .remove_validator_from_pool( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake.stake_account, - &user_pool_account.pubkey(), - &new_authority, - ) - .await - .unwrap(); - - match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError( - _, - InstructionError::Custom(error_index), - )) => { - let program_error = error::StakePoolError::WrongStakeState as u32; - assert_eq!(error_index, program_error); - } - _ => panic!("Wrong error occurs while try to add validator stake account when it isn't in stake state"), - } -} - #[tokio::test] async fn test_remove_validator_from_pool_from_unupdated_stake_pool() {} // TODO diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index c5e73777..ecb4e08a 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -3,13 +3,16 @@ mod helpers; use { - borsh::BorshDeserialize, + borsh::{BorshDeserialize, BorshSerialize}, helpers::*, - solana_program::hash::Hash, - solana_program::pubkey::Pubkey, + solana_program::{ + hash::Hash, + instruction::{AccountMeta, Instruction, InstructionError}, + pubkey::Pubkey, + sysvar, + }, solana_program_test::*, solana_sdk::{ - instruction::InstructionError, signature::{Keypair, Signer}, transaction::{Transaction, TransactionError}, transport::TransportError, @@ -204,26 +207,30 @@ async fn test_stake_pool_withdraw_with_wrong_stake_program() { let user_stake_recipient = Keypair::new(); let new_authority = Pubkey::new_unique(); - let wrong_stake_program = Keypair::new(); + let wrong_stake_program = Pubkey::new_unique(); + + let accounts = vec![ + AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), + AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false), + AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false), + AccountMeta::new(validator_stake_account.stake_account, false), + AccountMeta::new(user_stake_recipient.pubkey(), false), + AccountMeta::new_readonly(new_authority, false), + AccountMeta::new(deposit_info.user_pool_account, false), + AccountMeta::new(stake_pool_accounts.pool_mint.pubkey(), false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(spl_token::id(), false), + AccountMeta::new_readonly(wrong_stake_program, false), + ]; + let instruction = Instruction { + program_id: id(), + accounts, + data: instruction::StakePoolInstruction::Withdraw(tokens_to_burn) + .try_to_vec() + .unwrap(), + }; - let mut transaction = Transaction::new_with_payer( - &[instruction::withdraw( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.validator_list.pubkey(), - &stake_pool_accounts.withdraw_authority, - &validator_stake_account.stake_account, - &user_stake_recipient.pubkey(), - &new_authority, - &deposit_info.user_pool_account, - &stake_pool_accounts.pool_mint.pubkey(), - &spl_token::id(), - &wrong_stake_program.pubkey(), - tokens_to_burn, - ) - .unwrap()], - Some(&payer.pubkey()), - ); + let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); transaction.sign(&[&payer], recent_blockhash); let transaction_error = banks_client .process_transaction(transaction) @@ -314,7 +321,6 @@ async fn test_stake_pool_withdraw_with_wrong_token_program_id() { &deposit_info.user_pool_account, &stake_pool_accounts.pool_mint.pubkey(), &wrong_token_program.pubkey(), - &stake::id(), tokens_to_burn, ) .unwrap()], @@ -383,7 +389,7 @@ async fn test_stake_pool_withdraw_with_wrong_validator_list() { } #[tokio::test] -async fn test_stake_pool_withdraw_when_stake_acc_not_in_stake_state() { +async fn test_stake_pool_withdraw_from_unknown_validator() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts @@ -395,114 +401,13 @@ async fn test_stake_pool_withdraw_when_stake_acc_not_in_stake_state() { &stake_pool_accounts.deposit_authority, &stake_pool_accounts.stake_pool.pubkey(), ); - - let user_stake_authority = Keypair::new(); - create_validator_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &validator_stake_account.stake_pool, - &validator_stake_account.stake_account, - &validator_stake_account.vote.pubkey(), - &user_stake_authority.pubkey(), - &validator_stake_account.target_authority, - ) - .await; - - let user = Keypair::new(); - // make stake account - let user_stake = Keypair::new(); - let lockup = stake::Lockup::default(); - let authorized = stake::Authorized { - staker: stake_pool_accounts.deposit_authority, - withdrawer: stake_pool_accounts.deposit_authority, - }; - create_independent_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake, - &authorized, - &lockup, - ) - .await; - // make pool token account - let user_pool_account = Keypair::new(); - create_token_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_pool_account, - &stake_pool_accounts.pool_mint.pubkey(), - &user.pubkey(), - ) - .await - .unwrap(); - - let user_pool_account = user_pool_account.pubkey(); - let pool_tokens = get_token_balance(&mut banks_client, &user_pool_account).await; - - let tokens_to_burn = pool_tokens / 4; - - // Delegate tokens for burning - delegate_tokens( - &mut banks_client, - &payer, - &recent_blockhash, - &user_pool_account, - &user, - &stake_pool_accounts.withdraw_authority, - tokens_to_burn, - ) - .await; - - // Create stake account to withdraw to - let user_stake_recipient = Keypair::new(); - - let new_authority = Pubkey::new_unique(); - - let transaction_error = stake_pool_accounts - .withdraw_stake( + validator_stake_account + .create_and_delegate( &mut banks_client, &payer, &recent_blockhash, - &user_stake_recipient.pubkey(), - &user_pool_account, - &validator_stake_account.stake_account, - &new_authority, - tokens_to_burn, + &stake_pool_accounts.owner, ) - .await - .err() - .unwrap(); - - match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError( - _, - InstructionError::Custom(error_index), - )) => { - let program_error = error::StakePoolError::WrongStakeState as u32; - assert_eq!(error_index, program_error); - } - _ => panic!("Wrong error occurs while try to withdraw when stake acc not in stake state"), - } -} - -#[tokio::test] -async fn test_stake_pool_withdraw_from_unknown_validator() { - let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); - stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) - .await - .unwrap(); - - let validator_stake_account = ValidatorStakeAccount::new_with_target_authority( - &stake_pool_accounts.deposit_authority, - &stake_pool_accounts.stake_pool.pubkey(), - ); - validator_stake_account - .create_and_delegate(&mut banks_client, &payer, &recent_blockhash) .await; let user_stake = ValidatorStakeAccount::new_with_target_authority( @@ -510,7 +415,12 @@ async fn test_stake_pool_withdraw_from_unknown_validator() { &stake_pool_accounts.stake_pool.pubkey(), ); user_stake - .create_and_delegate(&mut banks_client, &payer, &recent_blockhash) + .create_and_delegate( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.owner, + ) .await; let user_pool_account = Keypair::new(); From 631d029f81f5dfc4280e56ed9df9e86bd4fdffe3 Mon Sep 17 00:00:00 2001 From: Jack May Date: Tue, 30 Mar 2021 17:30:44 -0700 Subject: [PATCH 0070/1076] Allow for fixed error mappings (#1541) --- program/tests/initialize.rs | 43 ++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index bdc7c919..fe503d0e 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -545,18 +545,15 @@ async fn test_initialize_stake_pool_with_not_rent_exempt_pool() { ], recent_blockhash, ); - assert_eq!( - banks_client - .process_transaction(transaction) - .await - .unwrap_err() - .unwrap(), - TransactionError::InstructionError( - 2, - InstructionError::InvalidError, - // should be InstructionError::AccountNotRentExempt, but the mapping - // is wrong - ) + let result = banks_client + .process_transaction(transaction) + .await + .unwrap_err() + .unwrap(); + assert!( + result == TransactionError::InstructionError(2, InstructionError::InvalidError,) + || result + == TransactionError::InstructionError(2, InstructionError::AccountNotRentExempt,) ); } @@ -621,18 +618,16 @@ async fn test_initialize_stake_pool_with_not_rent_exempt_validator_list() { recent_blockhash, ); - assert_eq!( - banks_client - .process_transaction(transaction) - .await - .unwrap_err() - .unwrap(), - TransactionError::InstructionError( - 2, - InstructionError::InvalidError, - // should be InstructionError::AccountNotRentExempt, but the mapping - // is wrong - ) + let result = banks_client + .process_transaction(transaction) + .await + .unwrap_err() + .unwrap(); + + assert!( + result == TransactionError::InstructionError(2, InstructionError::InvalidError,) + || result + == TransactionError::InstructionError(2, InstructionError::AccountNotRentExempt,) ); } From 403756d74587807b68c6c48c6cfe1d995248ca27 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Wed, 31 Mar 2021 10:04:41 -0700 Subject: [PATCH 0071/1076] Code cleanup v0 --- clients/cli/src/main.rs | 171 +++++++++--------- program/src/instruction.rs | 14 +- program/src/lib.rs | 43 ++++- program/src/processor.rs | 153 ++++++---------- program/src/{stake.rs => stake_program.rs} | 0 program/src/state.rs | 4 +- program/tests/deposit.rs | 44 ++--- program/tests/helpers/mod.rs | 44 +++-- .../tests/update_validator_list_balance.rs | 4 +- program/tests/vsa_add.rs | 12 +- program/tests/vsa_create.rs | 20 +- program/tests/vsa_remove.rs | 10 +- program/tests/withdraw.rs | 8 +- 13 files changed, 267 insertions(+), 260 deletions(-) rename program/src/{stake.rs => stake_program.rs} (100%) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 6497b1d4..479c335b 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -15,6 +15,7 @@ use { keypair::signer_from_path, }, solana_client::{ + client_error::ClientError, rpc_client::RpcClient, rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig}, rpc_filter::{Memcmp, MemcmpEncodedBytes, RpcFilterType}, @@ -24,7 +25,6 @@ use { borsh::get_packed_len, instruction::Instruction, program_pack::Pack, pubkey::Pubkey, }, solana_sdk::{ - account::Account, commitment_config::CommitmentConfig, native_token::{self, Sol}, signature::{Keypair, Signer}, @@ -33,18 +33,15 @@ use { }, spl_stake_pool::{ borsh::{get_instance_packed_len, try_from_slice_unchecked}, + create_pool_authority_address, find_authority_bump_seed, find_stake_address_for_validator, instruction::{ add_validator_to_pool, create_validator_stake_account, deposit, initialize as initialize_pool, remove_validator_from_pool, set_owner, update_stake_pool_balance, update_validator_list_balance, withdraw, Fee as PoolFee, }, - processor::Processor as PoolProcessor, - stake::authorize as authorize_stake, - stake::id as stake_program_id, - stake::StakeAuthorize, - stake::StakeState, - state::StakePool, - state::ValidatorList, + stake_program::{self, StakeAuthorize, StakeState}, + state::{StakePool, ValidatorList}, + AUTHORITY_DEPOSIT, AUTHORITY_WITHDRAW, }, spl_token::{ self, instruction::approve as approve_token, instruction::initialize_account, @@ -94,16 +91,17 @@ fn check_fee_payer_balance(config: &Config, required_balance: u64) -> Result<(), } } -fn get_authority_accounts(rpc_client: &RpcClient, authority: &Pubkey) -> Vec<(Pubkey, Account)> { +fn get_stake_accounts_by_withdrawer( + rpc_client: &RpcClient, + withdrawer: &Pubkey, +) -> Result, ClientError> { rpc_client .get_program_accounts_with_config( - &stake_program_id(), + &stake_program::id(), RpcProgramAccountsConfig { filters: Some(vec![RpcFilterType::Memcmp(Memcmp { offset: 44, // 44 is Withdrawer authority offset in stake account stake - bytes: MemcmpEncodedBytes::Binary( - bs58::encode(authority.to_bytes()).into_string(), - ), + bytes: MemcmpEncodedBytes::Binary(format!("{}", withdrawer)), encoding: None, })]), account_config: RpcAccountInfoConfig { @@ -112,7 +110,20 @@ fn get_authority_accounts(rpc_client: &RpcClient, authority: &Pubkey) -> Vec<(Pu }, }, ) - .unwrap() + .map(|accounts| { + accounts + .into_iter() + .filter_map( + |(address, account)| match deserialize(account.data.as_slice()) { + Ok(stake_state) => Some((address, account.lamports, stake_state)), + Err(err) => { + eprintln!("Invalid stake account data for {}: {}", address, err); + None + } + }, + ) + .collect() + }) } fn send_transaction( @@ -168,10 +179,10 @@ fn command_create_pool(config: &Config, fee: PoolFee, max_validators: u32) -> Co let default_decimals = native_mint::DECIMALS; // Calculate withdraw authority used for minting pool tokens - let (withdraw_authority, _) = PoolProcessor::find_authority_bump_seed( + let (withdraw_authority, _) = find_authority_bump_seed( &spl_stake_pool::id(), &pool_account.pubkey(), - PoolProcessor::AUTHORITY_WITHDRAW, + AUTHORITY_WITHDRAW, ); if config.verbose { @@ -263,11 +274,8 @@ fn command_create_pool(config: &Config, fee: PoolFee, max_validators: u32) -> Co } fn command_vsa_create(config: &Config, pool: &Pubkey, vote_account: &Pubkey) -> CommandResult { - let (stake_account, _) = PoolProcessor::find_stake_address_for_validator( - &spl_stake_pool::id(), - &vote_account, - &pool, - ); + let (stake_account, _) = + find_stake_address_for_validator(&spl_stake_pool::id(), &vote_account, &pool); println!("Creating stake account {}", stake_account); @@ -335,31 +343,31 @@ fn command_vsa_add( )?; // Calculate Deposit and Withdraw stake pool authorities - let pool_deposit_authority: Pubkey = PoolProcessor::authority_id( + let pool_deposit_authority: Pubkey = create_pool_authority_address( &spl_stake_pool::id(), pool, - PoolProcessor::AUTHORITY_DEPOSIT, + AUTHORITY_DEPOSIT, pool_data.deposit_bump_seed, ) .unwrap(); - let pool_withdraw_authority: Pubkey = PoolProcessor::authority_id( + let pool_withdraw_authority: Pubkey = create_pool_authority_address( &spl_stake_pool::id(), pool, - PoolProcessor::AUTHORITY_WITHDRAW, + AUTHORITY_WITHDRAW, pool_data.withdraw_bump_seed, ) .unwrap(); instructions.extend(vec![ // Set Withdrawer on stake account to Deposit authority of the stake pool - authorize_stake( + stake_program::authorize( &stake, &config.owner.pubkey(), &pool_deposit_authority, StakeAuthorize::Withdrawer, ), // Set Staker on stake account to Deposit authority of the stake pool - authorize_stake( + stake_program::authorize( &stake, &config.owner.pubkey(), &pool_deposit_authority, @@ -409,10 +417,10 @@ fn command_vsa_remove( let pool_data = config.rpc_client.get_account_data(&pool)?; let pool_data: StakePool = StakePool::try_from_slice(pool_data.as_slice()).unwrap(); - let pool_withdraw_authority: Pubkey = PoolProcessor::authority_id( + let pool_withdraw_authority: Pubkey = create_pool_authority_address( &spl_stake_pool::id(), pool, - PoolProcessor::AUTHORITY_WITHDRAW, + AUTHORITY_WITHDRAW, pool_data.withdraw_bump_seed, ) .unwrap(); @@ -567,7 +575,7 @@ fn command_deposit( // Calculate validator stake account address linked to the pool let (validator_stake_account, _) = - PoolProcessor::find_stake_address_for_validator(&spl_stake_pool::id(), &vote_account, pool); + find_stake_address_for_validator(&spl_stake_pool::id(), &vote_account, pool); let validator_stake_data = config .rpc_client .get_account_data(&validator_stake_account)?; @@ -600,31 +608,31 @@ fn command_deposit( )?; // Calculate Deposit and Withdraw stake pool authorities - let pool_deposit_authority: Pubkey = PoolProcessor::authority_id( + let pool_deposit_authority: Pubkey = create_pool_authority_address( &spl_stake_pool::id(), pool, - PoolProcessor::AUTHORITY_DEPOSIT, + AUTHORITY_DEPOSIT, pool_data.deposit_bump_seed, ) .unwrap(); - let pool_withdraw_authority: Pubkey = PoolProcessor::authority_id( + let pool_withdraw_authority: Pubkey = create_pool_authority_address( &spl_stake_pool::id(), pool, - PoolProcessor::AUTHORITY_WITHDRAW, + AUTHORITY_WITHDRAW, pool_data.withdraw_bump_seed, ) .unwrap(); instructions.extend(vec![ // Set Withdrawer on stake account to Deposit authority of the stake pool - authorize_stake( + stake_program::authorize( &stake, &config.owner.pubkey(), &pool_deposit_authority, StakeAuthorize::Withdrawer, ), // Set Staker on stake account to Deposit authority of the stake pool - authorize_stake( + stake_program::authorize( &stake, &config.owner.pubkey(), &pool_deposit_authority, @@ -663,14 +671,22 @@ fn command_deposit( fn command_list(config: &Config, pool: &Pubkey) -> CommandResult { // Get stake pool state let pool_data = config.rpc_client.get_account_data(&pool)?; - let pool_data = StakePool::try_from_slice(pool_data.as_slice()).unwrap(); + let pool_data = StakePool::try_from_slice(pool_data.as_slice()) + .map_err(|err| format!("Invalid pool {}: {}", pool, err))?; if config.verbose { let validator_list = config .rpc_client .get_account_data(&pool_data.validator_list)?; - let validator_list_data = - try_from_slice_unchecked::(&validator_list.as_slice())?; + let validator_list_data = try_from_slice_unchecked::( + &validator_list.as_slice(), + ) + .map_err(|err| { + format!( + "Invalid validator list{}: {}", + pool_data.validator_list, err + ) + })?; println!("Current validator list"); for validator in validator_list_data.validators { println!( @@ -680,31 +696,27 @@ fn command_list(config: &Config, pool: &Pubkey) -> CommandResult { } } - let pool_withdraw_authority: Pubkey = PoolProcessor::authority_id( + let pool_withdraw_authority: Pubkey = create_pool_authority_address( &spl_stake_pool::id(), pool, - PoolProcessor::AUTHORITY_WITHDRAW, + AUTHORITY_WITHDRAW, pool_data.withdraw_bump_seed, ) .unwrap(); - let accounts = get_authority_accounts(&config.rpc_client, &pool_withdraw_authority); - + let accounts = get_stake_accounts_by_withdrawer(&config.rpc_client, &pool_withdraw_authority)?; if accounts.is_empty() { return Err("No accounts found.".to_string().into()); } let mut total_balance: u64 = 0; - for (pubkey, account) in accounts { - let stake_data: StakeState = - deserialize(account.data.as_slice()).or(Err("Invalid stake account data"))?; - let balance = account.lamports; - total_balance += balance; + for (pubkey, lamports, stake_state) in accounts { + total_balance += lamports; println!( "Stake Account: {}\tVote Account: {}\t{}", pubkey, - stake_data.delegation().unwrap().voter_pubkey, - Sol(balance) + stake_state.delegation().expect("delegation").voter_pubkey, + Sol(lamports) ); } println!("Total: {}", Sol(total_balance)); @@ -731,7 +743,7 @@ fn command_update(config: &Config, pool: &Pubkey) -> CommandResult { if item.last_update_epoch >= epoch_info.epoch { None } else { - let (stake_account, _) = PoolProcessor::find_stake_address_for_validator( + let (stake_account, _) = find_stake_address_for_validator( &spl_stake_pool::id(), &item.validator_account, &pool, @@ -775,8 +787,7 @@ fn command_update(config: &Config, pool: &Pubkey) -> CommandResult { #[derive(PartialEq, Debug)] struct WithdrawAccount { - pubkey: Pubkey, - account: Account, + address: Pubkey, pool_amount: u64, } @@ -786,53 +797,37 @@ fn prepare_withdraw_accounts( pool_withdraw_authority: &Pubkey, pool_amount: u64, ) -> Result, Error> { - let mut accounts = get_authority_accounts(rpc_client, &pool_withdraw_authority); + let mut accounts = get_stake_accounts_by_withdrawer(rpc_client, &pool_withdraw_authority)?; if accounts.is_empty() { return Err("No accounts found.".to_string().into()); } let min_balance = rpc_client.get_minimum_balance_for_rent_exemption(STAKE_STATE_LEN)? + 1; let pool_mint_data = rpc_client.get_account_data(&stake_pool.pool_mint)?; let pool_mint = TokenMint::unpack_from_slice(pool_mint_data.as_slice()).unwrap(); - pick_withdraw_accounts( - &mut accounts, - stake_pool, - &pool_mint, - pool_amount, - min_balance, - ) -} -fn pick_withdraw_accounts( - accounts: &mut Vec<(Pubkey, Account)>, - stake_pool: &StakePool, - pool_mint: &TokenMint, - pool_amount: u64, - min_balance: u64, -) -> Result, Error> { // Sort from highest to lowest balance - accounts.sort_by(|a, b| b.1.lamports.cmp(&a.1.lamports)); + accounts.sort_by(|a, b| b.1.cmp(&a.1)); // Prepare the list of accounts to withdraw from let mut withdraw_from: Vec = vec![]; let mut remaining_amount = pool_amount; // Go through available accounts and withdraw from largest to smallest - for (pubkey, account) in accounts { - if account.lamports <= min_balance { + for (address, lamports, _) in accounts { + if lamports <= min_balance { continue; } let available_for_withdrawal = stake_pool - .calc_lamports_withdraw_amount(account.lamports - *MIN_STAKE_BALANCE) + .calc_lamports_withdraw_amount(lamports - *MIN_STAKE_BALANCE) .unwrap(); - let withdraw_amount = u64::min(available_for_withdrawal, remaining_amount); + let pool_amount = u64::min(available_for_withdrawal, remaining_amount); // Those accounts will be withdrawn completely with `claim` instruction withdraw_from.push(WithdrawAccount { - pubkey: *pubkey, - account: account.clone(), - pool_amount: withdraw_amount, + address, + pool_amount, }); - remaining_amount -= withdraw_amount; + remaining_amount -= pool_amount; if remaining_amount == 0 { break; @@ -870,10 +865,10 @@ fn command_withdraw( let pool_mint = TokenMint::unpack_from_slice(pool_mint_data.as_slice()).unwrap(); let pool_amount = spl_token::ui_amount_to_amount(pool_amount, pool_mint.decimals); - let pool_withdraw_authority: Pubkey = PoolProcessor::authority_id( + let pool_withdraw_authority: Pubkey = create_pool_authority_address( &spl_stake_pool::id(), pool, - PoolProcessor::AUTHORITY_WITHDRAW, + AUTHORITY_WITHDRAW, pool_data.withdraw_bump_seed, ) .unwrap(); @@ -898,7 +893,7 @@ fn command_withdraw( } // Get the list of accounts to withdraw from - let withdraw_accounts: Vec = prepare_withdraw_accounts( + let withdraw_accounts = prepare_withdraw_accounts( &config.rpc_client, &pool_data, &pool_withdraw_authority, @@ -928,17 +923,17 @@ fn command_withdraw( let mut total_rent_free_balances = 0; // Go through prepared accounts and withdraw/claim them - for withdraw_stake in withdraw_accounts { + for withdraw_account in withdraw_accounts { // Convert pool tokens amount to lamports let sol_withdraw_amount = pool_data - .calc_lamports_withdraw_amount(withdraw_stake.pool_amount) + .calc_lamports_withdraw_amount(withdraw_account.pool_amount) .unwrap(); println!( "Withdrawing from account {}, amount {}, {} pool tokens", - withdraw_stake.pubkey, + withdraw_account.address, Sol(sol_withdraw_amount), - spl_token::amount_to_ui_amount(withdraw_stake.pool_amount, pool_mint.decimals), + spl_token::amount_to_ui_amount(withdraw_account.pool_amount, pool_mint.decimals), ); if stake_receiver.is_none() { @@ -959,7 +954,7 @@ fn command_withdraw( &stake_receiver_account.pubkey(), stake_receiver_account_balance, STAKE_STATE_LEN as u64, - &stake_program_id(), + &stake_program::id(), ), ); @@ -975,13 +970,13 @@ fn command_withdraw( &pool, &pool_data.validator_list, &pool_withdraw_authority, - &withdraw_stake.pubkey, + &withdraw_account.address, &stake_receiver.unwrap(), // Cannot be none at this point &config.owner.pubkey(), &withdraw_from, &pool_data.pool_mint, &spl_token::id(), - withdraw_stake.pool_amount, + withdraw_account.pool_amount, )?); } diff --git a/program/src/instruction.rs b/program/src/instruction.rs index db304387..58b210db 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -3,7 +3,7 @@ #![allow(clippy::too_many_arguments)] use { - crate::stake, + crate::stake_program, borsh::{BorshDeserialize, BorshSchema, BorshSerialize}, solana_program::{ instruction::{AccountMeta, Instruction}, @@ -200,9 +200,9 @@ pub fn create_validator_stake_account( AccountMeta::new_readonly(sysvar::rent::id(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), - AccountMeta::new_readonly(stake::config_id(), false), + AccountMeta::new_readonly(stake_program::config_id(), false), AccountMeta::new_readonly(system_program::id(), false), - AccountMeta::new_readonly(stake::id(), false), + AccountMeta::new_readonly(stake_program::id(), false), ]; Ok(Instruction { program_id: *program_id, @@ -236,7 +236,7 @@ pub fn add_validator_to_pool( AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), AccountMeta::new_readonly(*token_program_id, false), - AccountMeta::new_readonly(stake::id(), false), + AccountMeta::new_readonly(stake_program::id(), false), ]; Ok(Instruction { program_id: *program_id, @@ -269,7 +269,7 @@ pub fn remove_validator_from_pool( AccountMeta::new(*pool_mint, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(*token_program_id, false), - AccountMeta::new_readonly(stake::id(), false), + AccountMeta::new_readonly(stake_program::id(), false), ]; Ok(Instruction { program_id: *program_id, @@ -342,7 +342,7 @@ pub fn deposit( AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), AccountMeta::new_readonly(*token_program_id, false), - AccountMeta::new_readonly(stake::id(), false), + AccountMeta::new_readonly(stake_program::id(), false), ]; Ok(Instruction { program_id: *program_id, @@ -376,7 +376,7 @@ pub fn withdraw( AccountMeta::new(*pool_mint, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(*token_program_id, false), - AccountMeta::new_readonly(stake::id(), false), + AccountMeta::new_readonly(stake_program::id(), false), ]; Ok(Instruction { program_id: *program_id, diff --git a/program/src/lib.rs b/program/src/lib.rs index fa7364cc..ee484f03 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -6,7 +6,7 @@ pub mod borsh; pub mod error; pub mod instruction; pub mod processor; -pub mod stake; +pub mod stake_program; pub mod state; #[cfg(not(feature = "no-entrypoint"))] @@ -14,5 +14,46 @@ pub mod entrypoint; // Export current sdk types for downstream users building with a different sdk version pub use solana_program; +use solana_program::{program_error::ProgramError, pubkey::Pubkey}; + +/// Seed for deposit authority seed +pub const AUTHORITY_DEPOSIT: &[u8] = b"deposit"; + +/// Seed for withdraw authority seed +pub const AUTHORITY_WITHDRAW: &[u8] = b"withdraw"; + +/// Calculates the authority address +pub fn create_pool_authority_address( + program_id: &Pubkey, + stake_pool: &Pubkey, + authority: &[u8], + bump_seed: u8, +) -> Result { + Pubkey::create_program_address( + &[&stake_pool.to_bytes()[..32], authority, &[bump_seed]], + program_id, + ) + .map_err(|_| crate::error::StakePoolError::InvalidProgramAddress.into()) +} + +/// Generates seed bump for stake pool authorities +pub fn find_authority_bump_seed( + program_id: &Pubkey, + stake_pool: &Pubkey, + authority: &[u8], +) -> (Pubkey, u8) { + Pubkey::find_program_address(&[&stake_pool.to_bytes()[..32], authority], program_id) +} +/// Generates stake account address for the validator +pub fn find_stake_address_for_validator( + program_id: &Pubkey, + validator: &Pubkey, + stake_pool: &Pubkey, +) -> (Pubkey, u8) { + Pubkey::find_program_address( + &[&validator.to_bytes()[..32], &stake_pool.to_bytes()[..32]], + program_id, + ) +} solana_program::declare_id!("poo1B9L9nR3CrcaziKVYVpRX6A9Y1LAXYasjjfCbApj"); diff --git a/program/src/processor.rs b/program/src/processor.rs index d9c35f53..88331c64 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -3,10 +3,13 @@ use { crate::{ borsh::try_from_slice_unchecked, + create_pool_authority_address, error::StakePoolError, + find_authority_bump_seed, find_stake_address_for_validator, instruction::{Fee, StakePoolInstruction}, - stake, + stake_program, state::{AccountType, StakePool, ValidatorList, ValidatorStakeInfo}, + AUTHORITY_DEPOSIT, AUTHORITY_WITHDRAW, }, bincode::deserialize, borsh::{BorshDeserialize, BorshSerialize}, @@ -35,53 +38,16 @@ use { /// Program state handler. pub struct Processor {} impl Processor { - /// Suffix for deposit authority seed - pub const AUTHORITY_DEPOSIT: &'static [u8] = b"deposit"; - /// Suffix for withdraw authority seed - pub const AUTHORITY_WITHDRAW: &'static [u8] = b"withdraw"; - /// Calculates the authority id by generating a program address. - pub fn authority_id( - program_id: &Pubkey, - stake_pool: &Pubkey, - authority_type: &[u8], - bump_seed: u8, - ) -> Result { - Pubkey::create_program_address( - &[&stake_pool.to_bytes()[..32], authority_type, &[bump_seed]], - program_id, - ) - .map_err(|_| StakePoolError::InvalidProgramAddress.into()) - } - /// Generates seed bump for stake pool authorities - pub fn find_authority_bump_seed( - program_id: &Pubkey, - stake_pool: &Pubkey, - authority_type: &[u8], - ) -> (Pubkey, u8) { - Pubkey::find_program_address(&[&stake_pool.to_bytes()[..32], authority_type], program_id) - } - /// Generates stake account address for the validator - pub fn find_stake_address_for_validator( - program_id: &Pubkey, - validator: &Pubkey, - stake_pool: &Pubkey, - ) -> (Pubkey, u8) { - Pubkey::find_program_address( - &[&validator.to_bytes()[..32], &stake_pool.to_bytes()[..32]], - program_id, - ) - } - /// Checks withdraw or deposit authority pub fn check_authority( authority_to_check: &Pubkey, program_id: &Pubkey, stake_pool_key: &Pubkey, - authority_type: &[u8], + authority: &[u8], bump_seed: u8, ) -> Result<(), ProgramError> { if *authority_to_check - != Self::authority_id(program_id, stake_pool_key, authority_type, bump_seed)? + != create_pool_authority_address(program_id, stake_pool_key, authority, bump_seed)? { return Err(StakePoolError::InvalidProgramAddress.into()); } @@ -90,10 +56,10 @@ impl Processor { /// Returns validator address for a particular stake account pub fn get_validator(stake_account_info: &AccountInfo) -> Result { - let stake_state: stake::StakeState = deserialize(&stake_account_info.data.borrow()) + let stake_state: stake_program::StakeState = deserialize(&stake_account_info.data.borrow()) .or(Err(ProgramError::InvalidAccountData))?; match stake_state { - stake::StakeState::Stake(_, stake) => Ok(stake.delegation.voter_pubkey), + stake_program::StakeState::Stake(_, stake) => Ok(stake.delegation.voter_pubkey), _ => Err(StakePoolError::WrongStakeState.into()), } } @@ -106,11 +72,8 @@ impl Processor { stake_account_info: &AccountInfo, ) -> bool { // Check stake account address validity - let (stake_address, _) = Self::find_stake_address_for_validator( - &program_id, - &validator_account, - &stake_pool_info.key, - ); + let (stake_address, _) = + find_stake_address_for_validator(&program_id, &validator_account, &stake_pool_info.key); stake_address == *stake_account_info.key } @@ -147,7 +110,8 @@ impl Processor { let authority_signature_seeds = [&me_bytes[..32], authority_type, &[bump_seed]]; let signers = &[&authority_signature_seeds[..]]; - let ix = stake::split_only(stake_account.key, authority.key, amount, split_stake.key); + let ix = + stake_program::split_only(stake_account.key, authority.key, amount, split_stake.key); invoke_signed(&ix, &[stake_account, split_stake, authority], signers) } @@ -169,7 +133,7 @@ impl Processor { let authority_signature_seeds = [&me_bytes[..32], authority_type, &[bump_seed]]; let signers = &[&authority_signature_seeds[..]]; - let ix = stake::merge(merge_with.key, stake_account.key, authority.key); + let ix = stake_program::merge(merge_with.key, stake_account.key, authority.key); invoke_signed( &ix, @@ -194,7 +158,7 @@ impl Processor { authority_type: &[u8], bump_seed: u8, new_staker: &Pubkey, - staker_auth: stake::StakeAuthorize, + staker_auth: stake_program::StakeAuthorize, reserved: AccountInfo<'a>, stake_program_info: AccountInfo<'a>, ) -> Result<(), ProgramError> { @@ -202,7 +166,8 @@ impl Processor { let authority_signature_seeds = [&me_bytes[..32], authority_type, &[bump_seed]]; let signers = &[&authority_signature_seeds[..]]; - let ix = stake::authorize(stake_account.key, authority.key, new_staker, staker_auth); + let ix = + stake_program::authorize(stake_account.key, authority.key, new_staker, staker_auth); invoke_signed( &ix, @@ -357,16 +322,10 @@ impl Processor { return Err(StakePoolError::WrongAccountMint.into()); } - let (_, deposit_bump_seed) = Self::find_authority_bump_seed( - program_id, - stake_pool_info.key, - Self::AUTHORITY_DEPOSIT, - ); - let (withdraw_authority_key, withdraw_bump_seed) = Self::find_authority_bump_seed( - program_id, - stake_pool_info.key, - Self::AUTHORITY_WITHDRAW, - ); + let (_, deposit_bump_seed) = + find_authority_bump_seed(program_id, stake_pool_info.key, AUTHORITY_DEPOSIT); + let (withdraw_authority_key, withdraw_bump_seed) = + find_authority_bump_seed(program_id, stake_pool_info.key, AUTHORITY_WITHDRAW); let pool_mint = Mint::unpack_from_slice(&pool_mint_info.data.borrow())?; @@ -439,12 +398,12 @@ impl Processor { if *system_program_info.key != solana_program::system_program::id() { return Err(ProgramError::IncorrectProgramId); } - if *stake_program_info.key != stake::id() { + if *stake_program_info.key != stake_program::id() { return Err(ProgramError::IncorrectProgramId); } // Check stake account address validity - let (stake_address, bump_seed) = Self::find_stake_address_for_validator( + let (stake_address, bump_seed) = find_stake_address_for_validator( &program_id, &validator_info.key, &stake_pool_info.key, @@ -460,8 +419,8 @@ impl Processor { ]; // Fund the stake account with 1 SOL + rent-exempt balance - let required_lamports = - sol_to_lamports(1.0) + rent.minimum_balance(std::mem::size_of::()); + let required_lamports = sol_to_lamports(1.0) + + rent.minimum_balance(std::mem::size_of::()); // Create new stake account invoke_signed( @@ -469,21 +428,21 @@ impl Processor { &funder_info.key, &stake_account_info.key, required_lamports, - std::mem::size_of::() as u64, - &stake::id(), + std::mem::size_of::() as u64, + &stake_program::id(), ), &[funder_info.clone(), stake_account_info.clone()], &[&stake_account_signer_seeds], )?; invoke( - &stake::initialize( + &stake_program::initialize( &stake_account_info.key, - &stake::Authorized { + &stake_program::Authorized { staker: *owner_info.key, withdrawer: *owner_info.key, }, - &stake::Lockup::default(), + &stake_program::Lockup::default(), ), &[ stake_account_info.clone(), @@ -493,7 +452,7 @@ impl Processor { )?; invoke( - &stake::delegate_stake( + &stake_program::delegate_stake( &stake_account_info.key, &owner_info.key, &validator_info.key, @@ -543,7 +502,7 @@ impl Processor { let stake_program_info = next_account_info(account_info_iter)?; // Check program ids - if *stake_program_info.key != stake::id() { + if *stake_program_info.key != stake_program::id() { return Err(ProgramError::IncorrectProgramId); } @@ -596,14 +555,14 @@ impl Processor { // Update Withdrawer and Staker authority to the program withdraw authority for authority in &[ - stake::StakeAuthorize::Withdrawer, - stake::StakeAuthorize::Staker, + stake_program::StakeAuthorize::Withdrawer, + stake_program::StakeAuthorize::Staker, ] { Self::stake_authorize( stake_pool_info.key, stake_account_info.clone(), deposit_info.clone(), - Self::AUTHORITY_DEPOSIT, + AUTHORITY_DEPOSIT, stake_pool.deposit_bump_seed, withdraw_info.key, *authority, @@ -623,7 +582,7 @@ impl Processor { pool_mint_info.clone(), dest_user_info.clone(), withdraw_info.clone(), - Self::AUTHORITY_WITHDRAW, + AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, token_amount, )?; @@ -679,7 +638,7 @@ impl Processor { let stake_program_info = next_account_info(account_info_iter)?; // Check program ids - if *stake_program_info.key != stake::id() { + if *stake_program_info.key != stake_program::id() { return Err(ProgramError::IncorrectProgramId); } @@ -728,14 +687,14 @@ impl Processor { // Update Withdrawer and Staker authority to the provided authority for authority in &[ - stake::StakeAuthorize::Withdrawer, - stake::StakeAuthorize::Staker, + stake_program::StakeAuthorize::Withdrawer, + stake_program::StakeAuthorize::Staker, ] { Self::stake_authorize( stake_pool_info.key, stake_account_info.clone(), withdraw_info.clone(), - Self::AUTHORITY_WITHDRAW, + AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, new_stake_authority_info.key, *authority, @@ -755,7 +714,7 @@ impl Processor { burn_from_info.clone(), pool_mint_info.clone(), withdraw_info.clone(), - Self::AUTHORITY_WITHDRAW, + AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, token_amount, )?; @@ -886,7 +845,7 @@ impl Processor { //#[cfg(not(feature = "test-bpf"))] // This check is commented to make tests run without special command line arguments /*{ - let stake_acc_state: stake::StakeState = + let stake_acc_state: stake_program::StakeState = deserialize(&stake_info.data.borrow()).unwrap(); let delegation = stake_acc_state.delegation(); if let Some(delegation) = delegation { @@ -938,7 +897,7 @@ impl Processor { let stake_program_info = next_account_info(account_info_iter)?; // Check program ids - if *stake_program_info.key != stake::id() { + if *stake_program_info.key != stake_program::id() { return Err(ProgramError::IncorrectProgramId); } @@ -1002,10 +961,10 @@ impl Processor { stake_pool_info.key, stake_info.clone(), deposit_info.clone(), - Self::AUTHORITY_DEPOSIT, + AUTHORITY_DEPOSIT, stake_pool.deposit_bump_seed, withdraw_info.key, - stake::StakeAuthorize::Withdrawer, + stake_program::StakeAuthorize::Withdrawer, clock_info.clone(), stake_program_info.clone(), )?; @@ -1014,10 +973,10 @@ impl Processor { stake_pool_info.key, stake_info.clone(), deposit_info.clone(), - Self::AUTHORITY_DEPOSIT, + AUTHORITY_DEPOSIT, stake_pool.deposit_bump_seed, withdraw_info.key, - stake::StakeAuthorize::Staker, + stake_program::StakeAuthorize::Staker, clock_info.clone(), stake_program_info.clone(), )?; @@ -1026,7 +985,7 @@ impl Processor { stake_pool_info.key, stake_info.clone(), withdraw_info.clone(), - Self::AUTHORITY_WITHDRAW, + AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, validator_stake_account_info.clone(), clock_info.clone(), @@ -1040,7 +999,7 @@ impl Processor { pool_mint_info.clone(), dest_user_info.clone(), withdraw_info.clone(), - Self::AUTHORITY_WITHDRAW, + AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, user_amount, )?; @@ -1051,7 +1010,7 @@ impl Processor { pool_mint_info.clone(), owner_fee_info.clone(), withdraw_info.clone(), - Self::AUTHORITY_WITHDRAW, + AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, fee_amount, )?; @@ -1097,7 +1056,7 @@ impl Processor { let stake_program_info = next_account_info(account_info_iter)?; // Check program ids - if *stake_program_info.key != stake::id() { + if *stake_program_info.key != stake_program::id() { return Err(ProgramError::IncorrectProgramId); } @@ -1145,7 +1104,7 @@ impl Processor { stake_pool_info.key, stake_split_from.clone(), withdraw_info.clone(), - Self::AUTHORITY_WITHDRAW, + AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, stake_amount, stake_split_to.clone(), @@ -1155,10 +1114,10 @@ impl Processor { stake_pool_info.key, stake_split_to.clone(), withdraw_info.clone(), - Self::AUTHORITY_WITHDRAW, + AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, user_stake_authority.key, - stake::StakeAuthorize::Withdrawer, + stake_program::StakeAuthorize::Withdrawer, clock_info.clone(), stake_program_info.clone(), )?; @@ -1167,10 +1126,10 @@ impl Processor { stake_pool_info.key, stake_split_to.clone(), withdraw_info.clone(), - Self::AUTHORITY_WITHDRAW, + AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, user_stake_authority.key, - stake::StakeAuthorize::Staker, + stake_program::StakeAuthorize::Staker, clock_info.clone(), stake_program_info.clone(), )?; @@ -1181,7 +1140,7 @@ impl Processor { burn_from_info.clone(), pool_mint_info.clone(), withdraw_info.clone(), - Self::AUTHORITY_WITHDRAW, + AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, pool_amount, )?; diff --git a/program/src/stake.rs b/program/src/stake_program.rs similarity index 100% rename from program/src/stake.rs rename to program/src/stake_program.rs diff --git a/program/src/state.rs b/program/src/state.rs index d23dcc4b..497bb64c 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -110,7 +110,7 @@ impl StakePool { authority_to_check, program_id, stake_pool_key, - Processor::AUTHORITY_WITHDRAW, + crate::AUTHORITY_WITHDRAW, self.withdraw_bump_seed, ) } @@ -125,7 +125,7 @@ impl StakePool { authority_to_check, program_id, stake_pool_key, - Processor::AUTHORITY_DEPOSIT, + crate::AUTHORITY_DEPOSIT, self.deposit_bump_seed, ) } diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index a5b911d4..7ef729d7 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -18,7 +18,9 @@ use { transaction::TransactionError, transport::TransportError, }, - spl_stake_pool::{borsh::try_from_slice_unchecked, error, id, instruction, stake, state}, + spl_stake_pool::{ + borsh::try_from_slice_unchecked, error, id, instruction, stake_program, state, + }, spl_token::error as token_error, }; @@ -61,10 +63,10 @@ async fn test_stake_pool_deposit() { let user = Keypair::new(); // make stake account let user_stake = Keypair::new(); - let lockup = stake::Lockup::default(); + let lockup = stake_program::Lockup::default(); let stake_authority = Keypair::new(); - let authorized = stake::Authorized { + let authorized = stake_program::Authorized { staker: stake_authority.pubkey(), withdrawer: stake_authority.pubkey(), }; @@ -104,7 +106,7 @@ async fn test_stake_pool_deposit() { &user_stake.pubkey(), &stake_authority, &stake_pool_accounts.deposit_authority, - stake::StakeAuthorize::Withdrawer, + stake_program::StakeAuthorize::Withdrawer, ) .await; authorize_stake_account( @@ -114,7 +116,7 @@ async fn test_stake_pool_deposit() { &user_stake.pubkey(), &stake_authority, &stake_pool_accounts.deposit_authority, - stake::StakeAuthorize::Staker, + stake_program::StakeAuthorize::Staker, ) .await; @@ -295,8 +297,8 @@ async fn test_stake_pool_deposit_with_wrong_pool_fee_account() { let user = Keypair::new(); // make stake account let user_stake = Keypair::new(); - let lockup = stake::Lockup::default(); - let authorized = stake::Authorized { + let lockup = stake_program::Lockup::default(); + let authorized = stake_program::Authorized { staker: stake_pool_accounts.deposit_authority, withdrawer: stake_pool_accounts.deposit_authority, }; @@ -359,8 +361,8 @@ async fn test_stake_pool_deposit_with_wrong_token_program_id() { let user = Keypair::new(); // make stake account let user_stake = Keypair::new(); - let lockup = stake::Lockup::default(); - let authorized = stake::Authorized { + let lockup = stake_program::Lockup::default(); + let authorized = stake_program::Authorized { staker: stake_pool_accounts.deposit_authority, withdrawer: stake_pool_accounts.deposit_authority, }; @@ -434,8 +436,8 @@ async fn test_stake_pool_deposit_with_wrong_validator_list_account() { let user = Keypair::new(); // make stake account let user_stake = Keypair::new(); - let lockup = stake::Lockup::default(); - let authorized = stake::Authorized { + let lockup = stake_program::Lockup::default(); + let authorized = stake_program::Authorized { staker: stake_pool_accounts.deposit_authority, withdrawer: stake_pool_accounts.deposit_authority, }; @@ -527,8 +529,8 @@ async fn test_stake_pool_deposit_to_unknown_validator() { // make stake account let user_stake = Keypair::new(); - let lockup = stake::Lockup::default(); - let authorized = stake::Authorized { + let lockup = stake_program::Lockup::default(); + let authorized = stake_program::Authorized { staker: stake_pool_accounts.deposit_authority, withdrawer: stake_pool_accounts.deposit_authority, }; @@ -582,8 +584,8 @@ async fn test_stake_pool_deposit_with_wrong_deposit_authority() { let user = Keypair::new(); // make stake account let user_stake = Keypair::new(); - let lockup = stake::Lockup::default(); - let authorized = stake::Authorized { + let lockup = stake_program::Lockup::default(); + let authorized = stake_program::Authorized { staker: stake_pool_accounts.deposit_authority, withdrawer: stake_pool_accounts.deposit_authority, }; @@ -650,8 +652,8 @@ async fn test_stake_pool_deposit_with_wrong_withdraw_authority() { let user = Keypair::new(); // make stake account let user_stake = Keypair::new(); - let lockup = stake::Lockup::default(); - let authorized = stake::Authorized { + let lockup = stake_program::Lockup::default(); + let authorized = stake_program::Authorized { staker: stake_pool_accounts.deposit_authority, withdrawer: stake_pool_accounts.deposit_authority, }; @@ -713,8 +715,8 @@ async fn test_stake_pool_deposit_with_wrong_set_deposit_authority() { let user = Keypair::new(); // make stake account let user_stake = Keypair::new(); - let lockup = stake::Lockup::default(); - let authorized = stake::Authorized { + let lockup = stake_program::Lockup::default(); + let authorized = stake_program::Authorized { staker: Keypair::new().pubkey(), withdrawer: stake_pool_accounts.deposit_authority, }; @@ -770,8 +772,8 @@ async fn test_stake_pool_deposit_with_wrong_mint_for_receiver_acc() { // make stake account let user_stake = Keypair::new(); - let lockup = stake::Lockup::default(); - let authorized = stake::Authorized { + let lockup = stake_program::Lockup::default(); + let authorized = stake_program::Authorized { staker: stake_pool_accounts.deposit_authority, withdrawer: stake_pool_accounts.deposit_authority, }; diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 13f8569e..df282a4a 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -12,7 +12,10 @@ use { transport::TransportError, }, solana_vote_program::{self, vote_state::VoteState}, - spl_stake_pool::{borsh::get_instance_packed_len, id, instruction, processor, stake, state}, + spl_stake_pool::{ + borsh::get_instance_packed_len, find_stake_address_for_validator, id, instruction, + processor, stake_program, state, + }, }; pub const TEST_STAKE_AMOUNT: u64 = 100; @@ -247,15 +250,15 @@ pub async fn create_independent_stake_account( payer: &Keypair, recent_blockhash: &Hash, stake: &Keypair, - authorized: &stake::Authorized, - lockup: &stake::Lockup, + authorized: &stake_program::Authorized, + lockup: &stake_program::Lockup, ) -> u64 { let rent = banks_client.get_rent().await.unwrap(); let lamports = - rent.minimum_balance(std::mem::size_of::()) + TEST_STAKE_AMOUNT; + rent.minimum_balance(std::mem::size_of::()) + TEST_STAKE_AMOUNT; let mut transaction = Transaction::new_with_payer( - &stake::create_account( + &stake_program::create_account( &payer.pubkey(), &stake.pubkey(), authorized, @@ -277,15 +280,15 @@ pub async fn create_blank_stake_account( stake: &Keypair, ) -> u64 { let rent = banks_client.get_rent().await.unwrap(); - let lamports = rent.minimum_balance(std::mem::size_of::()) + 1; + let lamports = rent.minimum_balance(std::mem::size_of::()) + 1; let mut transaction = Transaction::new_with_payer( &[system_instruction::create_account( &payer.pubkey(), &stake.pubkey(), lamports, - std::mem::size_of::() as u64, - &stake::id(), + std::mem::size_of::() as u64, + &stake_program::id(), )], Some(&payer.pubkey()), ); @@ -332,7 +335,11 @@ pub async fn delegate_stake_account( vote: &Pubkey, ) { let mut transaction = Transaction::new_with_payer( - &[stake::delegate_stake(&stake, &authorized.pubkey(), &vote)], + &[stake_program::delegate_stake( + &stake, + &authorized.pubkey(), + &vote, + )], Some(&payer.pubkey()), ); transaction.sign(&[payer, authorized], *recent_blockhash); @@ -346,10 +353,10 @@ pub async fn authorize_stake_account( stake: &Pubkey, authorized: &Keypair, new_authorized: &Pubkey, - stake_authorize: stake::StakeAuthorize, + stake_authorize: stake_program::StakeAuthorize, ) { let mut transaction = Transaction::new_with_payer( - &[stake::authorize( + &[stake_program::authorize( &stake, &authorized.pubkey(), &new_authorized, @@ -371,11 +378,8 @@ pub struct ValidatorStakeAccount { impl ValidatorStakeAccount { pub fn new_with_target_authority(authority: &Pubkey, stake_pool: &Pubkey) -> Self { let validator = Keypair::new(); - let (stake_account, _) = processor::Processor::find_stake_address_for_validator( - &id(), - &validator.pubkey(), - stake_pool, - ); + let (stake_account, _) = + find_stake_address_for_validator(&id(), &validator.pubkey(), stake_pool); ValidatorStakeAccount { stake_account, target_authority: *authority, @@ -411,7 +415,7 @@ impl ValidatorStakeAccount { &self.stake_account, &owner, &self.target_authority, - stake::StakeAuthorize::Staker, + stake_program::StakeAuthorize::Staker, ) .await; @@ -422,7 +426,7 @@ impl ValidatorStakeAccount { &self.stake_account, &owner, &self.target_authority, - stake::StakeAuthorize::Withdrawer, + stake_program::StakeAuthorize::Withdrawer, ) .await; } @@ -700,8 +704,8 @@ pub async fn simple_deposit( let user = Keypair::new(); // make stake account let user_stake = Keypair::new(); - let lockup = stake::Lockup::default(); - let authorized = stake::Authorized { + let lockup = stake_program::Lockup::default(); + let authorized = stake_program::Authorized { staker: stake_pool_accounts.deposit_authority, withdrawer: stake_pool_accounts.deposit_authority, }; diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index ecbca99f..02846783 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -8,7 +8,7 @@ use { solana_program::{native_token, pubkey::Pubkey}, solana_program_test::*, solana_sdk::signature::Signer, - spl_stake_pool::{borsh::try_from_slice_unchecked, stake, state}, + spl_stake_pool::{borsh::try_from_slice_unchecked, stake_program, state}, }; async fn get_list_sum(banks_client: &mut BanksClient, validator_list_key: &Pubkey) -> u64 { @@ -66,7 +66,7 @@ async fn test_update_validator_list_balance() { } let rent = banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()) + let stake_rent = rent.minimum_balance(std::mem::size_of::()) + native_token::sol_to_lamports(1.0); // Check current balance in the list diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index f2645f1b..9be382b5 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -18,7 +18,9 @@ use { transaction::{Transaction, TransactionError}, transport::TransportError, }, - spl_stake_pool::{borsh::try_from_slice_unchecked, error, id, instruction, stake, state}, + spl_stake_pool::{ + borsh::try_from_slice_unchecked, error, id, instruction, stake_program, state, + }, }; async fn setup() -> ( @@ -136,9 +138,9 @@ async fn test_add_validator_to_pool() { // Check of stake account authority has changed let stake = get_account(&mut banks_client, &user_stake.stake_account).await; - let stake_state = deserialize::(&stake.data).unwrap(); + let stake_state = deserialize::(&stake.data).unwrap(); match stake_state { - stake::StakeState::Stake(meta, _) => { + stake_program::StakeState::Stake(meta, _) => { assert_eq!( &meta.authorized.staker, &stake_pool_accounts.withdraw_authority @@ -174,7 +176,7 @@ async fn test_add_validator_to_pool_with_wrong_token_program_id() { &user_stake.stake_account, &user_pool_account.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), - &stake::id(), + &stake_program::id(), ) .unwrap()], Some(&payer.pubkey()), @@ -407,7 +409,7 @@ async fn test_not_owner_try_to_add_validator_to_pool_without_signature() { AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), AccountMeta::new_readonly(spl_token::id(), false), - AccountMeta::new_readonly(stake::id(), false), + AccountMeta::new_readonly(stake_program::id(), false), ]; let instruction = Instruction { program_id: id(), diff --git a/program/tests/vsa_create.rs b/program/tests/vsa_create.rs index e0f36fde..16fe1cf1 100644 --- a/program/tests/vsa_create.rs +++ b/program/tests/vsa_create.rs @@ -18,7 +18,7 @@ use { transaction::TransactionError, transport::TransportError, }, - spl_stake_pool::{error, id, instruction, processor, stake}, + spl_stake_pool::{error, find_stake_address_for_validator, id, instruction, stake_program}, }; #[tokio::test] @@ -33,7 +33,7 @@ async fn success_create_validator_stake_account() { let validator = Keypair::new(); create_vote(&mut banks_client, &payer, &recent_blockhash, &validator).await; - let (stake_account, _) = processor::Processor::find_stake_address_for_validator( + let (stake_account, _) = find_stake_address_for_validator( &id(), &validator.pubkey(), &stake_pool_accounts.stake_pool.pubkey(), @@ -56,9 +56,9 @@ async fn success_create_validator_stake_account() { // Check authorities let stake = get_account(&mut banks_client, &stake_account).await; - let stake_state = deserialize::(&stake.data).unwrap(); + let stake_state = deserialize::(&stake.data).unwrap(); match stake_state { - stake::StakeState::Stake(meta, stake) => { + stake_program::StakeState::Stake(meta, stake) => { assert_eq!(&meta.authorized.staker, &stake_pool_accounts.owner.pubkey()); assert_eq!( &meta.authorized.withdrawer, @@ -81,7 +81,7 @@ async fn fail_create_validator_stake_account_on_non_vote_account() { let validator = Pubkey::new_unique(); - let (stake_account, _) = processor::Processor::find_stake_address_for_validator( + let (stake_account, _) = find_stake_address_for_validator( &id(), &validator, &stake_pool_accounts.stake_pool.pubkey(), @@ -124,7 +124,7 @@ async fn fail_create_validator_stake_account_with_wrong_system_program() { let validator = Pubkey::new_unique(); - let (stake_account, _) = processor::Processor::find_stake_address_for_validator( + let (stake_account, _) = find_stake_address_for_validator( &id(), &validator, &stake_pool_accounts.stake_pool.pubkey(), @@ -139,9 +139,9 @@ async fn fail_create_validator_stake_account_with_wrong_system_program() { AccountMeta::new_readonly(sysvar::rent::id(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), - AccountMeta::new_readonly(stake::config_id(), false), + AccountMeta::new_readonly(stake_program::config_id(), false), AccountMeta::new_readonly(wrong_system_program, false), - AccountMeta::new_readonly(stake::id(), false), + AccountMeta::new_readonly(stake_program::id(), false), ]; let instruction = Instruction { program_id: id(), @@ -177,7 +177,7 @@ async fn fail_create_validator_stake_account_with_wrong_stake_program() { let validator = Pubkey::new_unique(); - let (stake_account, _) = processor::Processor::find_stake_address_for_validator( + let (stake_account, _) = find_stake_address_for_validator( &id(), &validator, &stake_pool_accounts.stake_pool.pubkey(), @@ -192,7 +192,7 @@ async fn fail_create_validator_stake_account_with_wrong_stake_program() { AccountMeta::new_readonly(sysvar::rent::id(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), - AccountMeta::new_readonly(stake::config_id(), false), + AccountMeta::new_readonly(stake_program::config_id(), false), AccountMeta::new_readonly(system_program::id(), false), AccountMeta::new_readonly(wrong_stake_program, false), ]; diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 93d8dd93..77476147 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -18,7 +18,9 @@ use { transaction::{Transaction, TransactionError}, transport::TransportError, }, - spl_stake_pool::{borsh::try_from_slice_unchecked, error, id, instruction, stake, state}, + spl_stake_pool::{ + borsh::try_from_slice_unchecked, error, id, instruction, stake_program, state, + }, }; async fn setup() -> ( @@ -147,9 +149,9 @@ async fn test_remove_validator_from_pool() { // Check of stake account authority has changed let stake = get_account(&mut banks_client, &user_stake.stake_account).await; - let stake_state = deserialize::(&stake.data).unwrap(); + let stake_state = deserialize::(&stake.data).unwrap(); match stake_state { - stake::StakeState::Stake(meta, _) => { + stake_program::StakeState::Stake(meta, _) => { assert_eq!(&meta.authorized.staker, &new_authority); assert_eq!(&meta.authorized.withdrawer, &new_authority); } @@ -498,7 +500,7 @@ async fn test_not_owner_try_to_remove_validator_from_pool_without_signature() { AccountMeta::new(stake_pool_accounts.pool_mint.pubkey(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(spl_token::id(), false), - AccountMeta::new_readonly(stake::id(), false), + AccountMeta::new_readonly(stake_program::id(), false), ]; let instruction = Instruction { program_id: id(), diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index ecb4e08a..5fdb3447 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -17,7 +17,9 @@ use { transaction::{Transaction, TransactionError}, transport::TransportError, }, - spl_stake_pool::{borsh::try_from_slice_unchecked, error, id, instruction, stake, state}, + spl_stake_pool::{ + borsh::try_from_slice_unchecked, error, id, instruction, stake_program, state, + }, spl_token::error::TokenError, }; @@ -439,8 +441,8 @@ async fn test_stake_pool_withdraw_from_unknown_validator() { let user = Keypair::new(); // make stake account let user_stake = Keypair::new(); - let lockup = stake::Lockup::default(); - let authorized = stake::Authorized { + let lockup = stake_program::Lockup::default(); + let authorized = stake_program::Authorized { staker: stake_pool_accounts.deposit_authority, withdrawer: stake_pool_accounts.deposit_authority, }; From 89d9bccee463ddbfacf1712bd87851780af1eb8f Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Wed, 31 Mar 2021 10:54:55 -0700 Subject: [PATCH 0072/1076] Code cleanup v1 --- clients/cli/src/client.rs | 115 ++++++++++++++++ clients/cli/src/main.rs | 282 +++++++++++++------------------------- 2 files changed, 208 insertions(+), 189 deletions(-) create mode 100644 clients/cli/src/client.rs diff --git a/clients/cli/src/client.rs b/clients/cli/src/client.rs new file mode 100644 index 00000000..011194c1 --- /dev/null +++ b/clients/cli/src/client.rs @@ -0,0 +1,115 @@ +use { + bincode::deserialize, + borsh::BorshDeserialize, + solana_account_decoder::UiAccountEncoding, + solana_client::{ + client_error::ClientError, + rpc_client::RpcClient, + rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig}, + rpc_filter::{Memcmp, MemcmpEncodedBytes, RpcFilterType}, + }, + solana_program::{program_pack::Pack, pubkey::Pubkey}, + spl_stake_pool::{ + borsh::try_from_slice_unchecked, + stake_program, + state::{StakePool, ValidatorList}, + }, +}; + +type Error = Box; + +pub(crate) fn get_stake_pool( + rpc_client: &RpcClient, + pool_address: &Pubkey, +) -> Result { + let account_data = rpc_client.get_account_data(pool_address)?; + let stake_pool = StakePool::try_from_slice(account_data.as_slice()) + .map_err(|err| format!("Invalid stake pool {}: {}", pool_address, err))?; + Ok(stake_pool) +} + +pub(crate) fn get_validator_list( + rpc_client: &RpcClient, + validator_list_address: &Pubkey, +) -> Result { + let account_data = rpc_client.get_account_data(validator_list_address)?; + let validator_list = try_from_slice_unchecked::(&account_data.as_slice()) + .map_err(|err| format!("Invalid validator list {}: {}", validator_list_address, err))?; + Ok(validator_list) +} + +pub(crate) fn get_token_account( + rpc_client: &RpcClient, + token_account_address: &Pubkey, + expected_token_mint: &Pubkey, +) -> Result { + let account_data = rpc_client.get_account_data(token_account_address)?; + let token_account = spl_token::state::Account::unpack_from_slice(account_data.as_slice()) + .map_err(|err| format!("Invalid token account {}: {}", token_account_address, err))?; + + if token_account.mint != *expected_token_mint { + Err(format!( + "Invalid token mint for {}, expected mint is {}", + token_account_address, expected_token_mint + ) + .into()) + } else { + Ok(token_account) + } +} + +pub(crate) fn get_token_mint( + rpc_client: &RpcClient, + token_mint_address: &Pubkey, +) -> Result { + let account_data = rpc_client.get_account_data(token_mint_address)?; + let token_mint = spl_token::state::Mint::unpack_from_slice(account_data.as_slice()) + .map_err(|err| format!("Invalid token mint {}: {}", token_mint_address, err))?; + + Ok(token_mint) +} + +pub(crate) fn get_stake_state( + rpc_client: &RpcClient, + stake_address: &Pubkey, +) -> Result { + let account_data = rpc_client.get_account_data(stake_address)?; + let stake_state = deserialize(account_data.as_slice()) + .map_err(|err| format!("Invalid stake account {}: {}", stake_address, err))?; + Ok(stake_state) +} + +pub(crate) fn get_stake_accounts_by_withdrawer( + rpc_client: &RpcClient, + withdrawer: &Pubkey, +) -> Result, ClientError> { + rpc_client + .get_program_accounts_with_config( + &stake_program::id(), + RpcProgramAccountsConfig { + filters: Some(vec![RpcFilterType::Memcmp(Memcmp { + offset: 44, // 44 is Withdrawer authority offset in stake account stake + bytes: MemcmpEncodedBytes::Binary(format!("{}", withdrawer)), + encoding: None, + })]), + account_config: RpcAccountInfoConfig { + encoding: Some(UiAccountEncoding::Base64), + ..RpcAccountInfoConfig::default() + }, + }, + ) + .map(|accounts| { + accounts + .into_iter() + .filter_map( + |(address, account)| match deserialize(account.data.as_slice()) { + Ok(stake_state) => Some((address, account.lamports, stake_state)), + Err(err) => { + eprintln!("Invalid stake account data for {}: {}", address, err); + None + } + }, + ) + .collect() + }) +} diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 479c335b..02a1f0a8 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -1,26 +1,20 @@ #[macro_use] extern crate lazy_static; +mod client; + use { - bincode::deserialize, - borsh::BorshDeserialize, + crate::client::*, clap::{ crate_description, crate_name, crate_version, value_t, value_t_or_exit, App, AppSettings, Arg, ArgGroup, SubCommand, }, - solana_account_decoder::UiAccountEncoding, solana_clap_utils::{ input_parsers::pubkey_of, input_validators::{is_amount, is_keypair, is_parsable, is_pubkey, is_url}, keypair::signer_from_path, }, - solana_client::{ - client_error::ClientError, - rpc_client::RpcClient, - rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig}, - rpc_filter::{Memcmp, MemcmpEncodedBytes, RpcFilterType}, - rpc_response::StakeActivationState, - }, + solana_client::{rpc_client::RpcClient, rpc_response::StakeActivationState}, solana_program::{ borsh::get_packed_len, instruction::Instruction, program_pack::Pack, pubkey::Pubkey, }, @@ -32,22 +26,13 @@ use { transaction::Transaction, }, spl_stake_pool::{ - borsh::{get_instance_packed_len, try_from_slice_unchecked}, + self, + borsh::get_instance_packed_len, create_pool_authority_address, find_authority_bump_seed, find_stake_address_for_validator, - instruction::{ - add_validator_to_pool, create_validator_stake_account, deposit, - initialize as initialize_pool, remove_validator_from_pool, set_owner, - update_stake_pool_balance, update_validator_list_balance, withdraw, Fee as PoolFee, - }, stake_program::{self, StakeAuthorize, StakeState}, state::{StakePool, ValidatorList}, AUTHORITY_DEPOSIT, AUTHORITY_WITHDRAW, }, - spl_token::{ - self, instruction::approve as approve_token, instruction::initialize_account, - instruction::initialize_mint, native_mint, state::Account as TokenAccount, - state::Mint as TokenMint, - }, std::process::exit, }; @@ -91,41 +76,6 @@ fn check_fee_payer_balance(config: &Config, required_balance: u64) -> Result<(), } } -fn get_stake_accounts_by_withdrawer( - rpc_client: &RpcClient, - withdrawer: &Pubkey, -) -> Result, ClientError> { - rpc_client - .get_program_accounts_with_config( - &stake_program::id(), - RpcProgramAccountsConfig { - filters: Some(vec![RpcFilterType::Memcmp(Memcmp { - offset: 44, // 44 is Withdrawer authority offset in stake account stake - bytes: MemcmpEncodedBytes::Binary(format!("{}", withdrawer)), - encoding: None, - })]), - account_config: RpcAccountInfoConfig { - encoding: Some(UiAccountEncoding::Base64), - ..RpcAccountInfoConfig::default() - }, - }, - ) - .map(|accounts| { - accounts - .into_iter() - .filter_map( - |(address, account)| match deserialize(account.data.as_slice()) { - Ok(stake_state) => Some((address, account.lamports, stake_state)), - Err(err) => { - eprintln!("Invalid stake account data for {}: {}", address, err); - None - } - }, - ) - .collect() - }) -} - fn send_transaction( config: &Config, transaction: Transaction, @@ -142,7 +92,11 @@ fn send_transaction( Ok(()) } -fn command_create_pool(config: &Config, fee: PoolFee, max_validators: u32) -> CommandResult { +fn command_create_pool( + config: &Config, + fee: spl_stake_pool::instruction::Fee, + max_validators: u32, +) -> CommandResult { let mint_account = Keypair::new(); println!("Creating mint {}", mint_account.pubkey()); @@ -159,10 +113,10 @@ fn command_create_pool(config: &Config, fee: PoolFee, max_validators: u32) -> Co let mint_account_balance = config .rpc_client - .get_minimum_balance_for_rent_exemption(TokenMint::LEN)?; + .get_minimum_balance_for_rent_exemption(spl_token::state::Mint::LEN)?; let pool_fee_account_balance = config .rpc_client - .get_minimum_balance_for_rent_exemption(TokenAccount::LEN)?; + .get_minimum_balance_for_rent_exemption(spl_token::state::Account::LEN)?; let pool_account_balance = config .rpc_client .get_minimum_balance_for_rent_exemption(get_packed_len::())?; @@ -176,7 +130,7 @@ fn command_create_pool(config: &Config, fee: PoolFee, max_validators: u32) -> Co + pool_account_balance + validator_list_balance; - let default_decimals = native_mint::DECIMALS; + let default_decimals = spl_token::native_mint::DECIMALS; // Calculate withdraw authority used for minting pool tokens let (withdraw_authority, _) = find_authority_bump_seed( @@ -196,7 +150,7 @@ fn command_create_pool(config: &Config, fee: PoolFee, max_validators: u32) -> Co &config.fee_payer.pubkey(), &mint_account.pubkey(), mint_account_balance, - TokenMint::LEN as u64, + spl_token::state::Mint::LEN as u64, &spl_token::id(), ), // Account for the pool fee accumulation @@ -204,7 +158,7 @@ fn command_create_pool(config: &Config, fee: PoolFee, max_validators: u32) -> Co &config.fee_payer.pubkey(), &pool_fee_account.pubkey(), pool_fee_account_balance, - TokenAccount::LEN as u64, + spl_token::state::Account::LEN as u64, &spl_token::id(), ), // Account for the stake pool @@ -224,7 +178,7 @@ fn command_create_pool(config: &Config, fee: PoolFee, max_validators: u32) -> Co &spl_stake_pool::id(), ), // Initialize pool token mint account - initialize_mint( + spl_token::instruction::initialize_mint( &spl_token::id(), &mint_account.pubkey(), &withdraw_authority, @@ -232,14 +186,14 @@ fn command_create_pool(config: &Config, fee: PoolFee, max_validators: u32) -> Co default_decimals, )?, // Initialize fee receiver account - initialize_account( + spl_token::instruction::initialize_account( &spl_token::id(), &pool_fee_account.pubkey(), &mint_account.pubkey(), &config.owner.pubkey(), )?, // Initialize stake pool account - initialize_pool( + spl_stake_pool::instruction::initialize( &spl_stake_pool::id(), &pool_account.pubkey(), &config.owner.pubkey(), @@ -282,7 +236,7 @@ fn command_vsa_create(config: &Config, pool: &Pubkey, vote_account: &Pubkey) -> let mut transaction = Transaction::new_with_payer( &[ // Create new validator stake account address - create_validator_stake_account( + spl_stake_pool::instruction::create_validator_stake_account( &spl_stake_pool::id(), &pool, &config.owner.pubkey(), @@ -318,9 +272,7 @@ fn command_vsa_add( command_update(config, pool)?; } - // Get stake pool state - let pool_data = config.rpc_client.get_account_data(&pool)?; - let pool_data = StakePool::try_from_slice(pool_data.as_slice()).unwrap(); + let pool_data = get_stake_pool(&config.rpc_client, pool)?; let mut total_rent_free_balances: u64 = 0; @@ -374,7 +326,7 @@ fn command_vsa_add( StakeAuthorize::Staker, ), // Add validator stake account to the pool - add_validator_to_pool( + spl_stake_pool::instruction::add_validator_to_pool( &spl_stake_pool::id(), &pool, &config.owner.pubkey(), @@ -413,10 +365,7 @@ fn command_vsa_remove( command_update(config, pool)?; } - // Get stake pool state - let pool_data = config.rpc_client.get_account_data(&pool)?; - let pool_data: StakePool = StakePool::try_from_slice(pool_data.as_slice()).unwrap(); - + let pool_data = get_stake_pool(&config.rpc_client, pool)?; let pool_withdraw_authority: Pubkey = create_pool_authority_address( &spl_stake_pool::id(), pool, @@ -435,17 +384,11 @@ fn command_vsa_remove( .unwrap(); // Check balance and mint - let account_data = config.rpc_client.get_account_data(&withdraw_from)?; - let account_data: TokenAccount = - TokenAccount::unpack_from_slice(account_data.as_slice()).unwrap(); + let token_account = + get_token_account(&config.rpc_client, &withdraw_from, &pool_data.pool_mint)?; - if account_data.mint != pool_data.pool_mint { - return Err("Wrong token account.".into()); - } - - if account_data.amount < tokens_to_withdraw { - let pool_mint_data = config.rpc_client.get_account_data(&pool_data.pool_mint)?; - let pool_mint = TokenMint::unpack_from_slice(pool_mint_data.as_slice()).unwrap(); + if token_account.amount < tokens_to_withdraw { + let pool_mint = get_token_mint(&config.rpc_client, &pool_data.pool_mint)?; return Err(format!( "Not enough balance to burn to remove validator stake account from the pool. {} pool tokens needed.", spl_token::amount_to_ui_amount(tokens_to_withdraw, pool_mint.decimals) @@ -455,7 +398,7 @@ fn command_vsa_remove( let mut transaction = Transaction::new_with_payer( &[ // Approve spending token - approve_token( + spl_token::instruction::approve( &spl_token::id(), &withdraw_from, &pool_withdraw_authority, @@ -464,7 +407,7 @@ fn command_vsa_remove( tokens_to_withdraw, )?, // Create new validator stake account address - remove_validator_from_pool( + spl_stake_pool::instruction::remove_validator_from_pool( &spl_stake_pool::id(), &pool, &config.owner.pubkey(), @@ -509,7 +452,7 @@ where let min_account_balance = config .rpc_client - .get_minimum_balance_for_rent_exemption(TokenAccount::LEN)?; + .get_minimum_balance_for_rent_exemption(spl_token::state::Account::LEN)?; instructions.extend(vec![ // Creating new account @@ -517,11 +460,11 @@ where &config.fee_payer.pubkey(), &keypair.pubkey(), min_account_balance, - TokenAccount::LEN as u64, + spl_token::state::Account::LEN as u64, &spl_token::id(), ), // Initialize token receiver account - initialize_account( + spl_token::instruction::initialize_account( &spl_token::id(), &keypair.pubkey(), mint, @@ -547,44 +490,31 @@ fn command_deposit( command_update(config, pool)?; } - // Get stake pool state - let pool_data = config.rpc_client.get_account_data(&pool)?; - let pool_data: StakePool = StakePool::try_from_slice(pool_data.as_slice()).unwrap(); + let pool_data = get_stake_pool(&config.rpc_client, pool)?; + let stake_state = get_stake_state(&config.rpc_client, &stake)?; - // Get stake account data - let stake_data = config.rpc_client.get_account_data(&stake)?; - let stake_data: StakeState = - deserialize(stake_data.as_slice()).or(Err("Invalid stake account data"))?; if config.verbose { - println!("Depositing stake account {:?}", stake_data); + println!("Depositing stake account {:?}", stake_state); } - let vote_account: Pubkey = match stake_data { + let vote_account: Pubkey = match stake_state { StakeState::Stake(_, stake) => Ok(stake.delegation.voter_pubkey), _ => Err("Wrong stake account state, must be delegated to validator"), }?; // Check if this vote account has staking account in the pool - let validator_list_data = config - .rpc_client - .get_account_data(&pool_data.validator_list)?; - let validator_list_data = - try_from_slice_unchecked::(&validator_list_data.as_slice())?; - if !validator_list_data.contains(&vote_account) { + let validator_list = get_validator_list(&config.rpc_client, &pool_data.validator_list)?; + if !validator_list.contains(&vote_account) { return Err("Stake account for this validator does not exist in the pool.".into()); } // Calculate validator stake account address linked to the pool let (validator_stake_account, _) = find_stake_address_for_validator(&spl_stake_pool::id(), &vote_account, pool); - let validator_stake_data = config - .rpc_client - .get_account_data(&validator_stake_account)?; - let validator_stake_data: StakeState = - deserialize(validator_stake_data.as_slice()).or(Err("Invalid stake account data"))?; + + let validator_stake_state = get_stake_state(&config.rpc_client, &validator_stake_account)?; + println!("Depositing into stake account {}", validator_stake_account); if config.verbose { - println!("Depositing into stake account {:?}", validator_stake_data); - } else { - println!("Depositing into stake account {}", validator_stake_account); + println!("{:?}", validator_stake_state); } let mut instructions: Vec = vec![]; @@ -639,7 +569,7 @@ fn command_deposit( StakeAuthorize::Staker, ), // Add stake account to the pool - deposit( + spl_stake_pool::instruction::deposit( &spl_stake_pool::id(), &pool, &pool_data.validator_list, @@ -669,26 +599,12 @@ fn command_deposit( } fn command_list(config: &Config, pool: &Pubkey) -> CommandResult { - // Get stake pool state - let pool_data = config.rpc_client.get_account_data(&pool)?; - let pool_data = StakePool::try_from_slice(pool_data.as_slice()) - .map_err(|err| format!("Invalid pool {}: {}", pool, err))?; + let pool_data = get_stake_pool(&config.rpc_client, pool)?; if config.verbose { - let validator_list = config - .rpc_client - .get_account_data(&pool_data.validator_list)?; - let validator_list_data = try_from_slice_unchecked::( - &validator_list.as_slice(), - ) - .map_err(|err| { - format!( - "Invalid validator list{}: {}", - pool_data.validator_list, err - ) - })?; println!("Current validator list"); - for validator in validator_list_data.validators { + let validator_list = get_validator_list(&config.rpc_client, &pool_data.validator_list)?; + for validator in validator_list.validators { println!( "Vote Account: {}\tBalance: {}\tEpoch: {}", validator.validator_account, validator.balance, validator.last_update_epoch @@ -725,18 +641,11 @@ fn command_list(config: &Config, pool: &Pubkey) -> CommandResult { } fn command_update(config: &Config, pool: &Pubkey) -> CommandResult { - // Get stake pool state - let pool_data = config.rpc_client.get_account_data(&pool)?; - let pool_data = StakePool::try_from_slice(pool_data.as_slice()).unwrap(); - let validator_list_data = config - .rpc_client - .get_account_data(&pool_data.validator_list)?; - let validator_list_data = - try_from_slice_unchecked::(&validator_list_data.as_slice())?; - + let pool_data = get_stake_pool(&config.rpc_client, pool)?; + let validator_list = get_validator_list(&config.rpc_client, &pool_data.validator_list)?; let epoch_info = config.rpc_client.get_epoch_info()?; - let accounts_to_update: Vec = validator_list_data + let accounts_to_update: Vec = validator_list .validators .iter() .filter_map(|item| { @@ -756,7 +665,7 @@ fn command_update(config: &Config, pool: &Pubkey) -> CommandResult { let mut instructions: Vec = vec![]; for chunk in accounts_to_update.chunks(MAX_ACCOUNTS_TO_UPDATE) { - instructions.push(update_validator_list_balance( + instructions.push(spl_stake_pool::instruction::update_validator_list_balance( &spl_stake_pool::id(), &pool_data.validator_list, &chunk, @@ -768,7 +677,7 @@ fn command_update(config: &Config, pool: &Pubkey) -> CommandResult { Ok(()) } else { println!("Updating stake pool..."); - instructions.push(update_stake_pool_balance( + instructions.push(spl_stake_pool::instruction::update_stake_pool_balance( &spl_stake_pool::id(), pool, &pool_data.validator_list, @@ -802,8 +711,7 @@ fn prepare_withdraw_accounts( return Err("No accounts found.".to_string().into()); } let min_balance = rpc_client.get_minimum_balance_for_rent_exemption(STAKE_STATE_LEN)? + 1; - let pool_mint_data = rpc_client.get_account_data(&stake_pool.pool_mint)?; - let pool_mint = TokenMint::unpack_from_slice(pool_mint_data.as_slice()).unwrap(); + let pool_mint = get_token_mint(rpc_client, &stake_pool.pool_mint)?; // Sort from highest to lowest balance accounts.sort_by(|a, b| b.1.cmp(&a.1)); @@ -857,12 +765,8 @@ fn command_withdraw( command_update(config, pool)?; } - // Get stake pool state - let pool_data = config.rpc_client.get_account_data(&pool)?; - let pool_data = StakePool::try_from_slice(pool_data.as_slice()).unwrap(); - - let pool_mint_data = config.rpc_client.get_account_data(&pool_data.pool_mint)?; - let pool_mint = TokenMint::unpack_from_slice(pool_mint_data.as_slice()).unwrap(); + let pool_data = get_stake_pool(&config.rpc_client, pool)?; + let pool_mint = get_token_mint(&config.rpc_client, &pool_data.pool_mint)?; let pool_amount = spl_token::ui_amount_to_amount(pool_amount, pool_mint.decimals); let pool_withdraw_authority: Pubkey = create_pool_authority_address( @@ -874,20 +778,15 @@ fn command_withdraw( .unwrap(); // Check withdraw_from account type - let account_data = config.rpc_client.get_account_data(&withdraw_from)?; - let account_data: TokenAccount = - TokenAccount::unpack_from_slice(account_data.as_slice()).unwrap(); - - if account_data.mint != pool_data.pool_mint { - return Err("Wrong token account.".into()); - } + let token_account = + get_token_account(&config.rpc_client, &withdraw_from, &pool_data.pool_mint)?; // Check withdraw_from balance - if account_data.amount < pool_amount { + if token_account.amount < pool_amount { return Err(format!( "Not enough token balance to withdraw {} pool tokens.\nMaximum withdraw amount is {} pool tokens.", spl_token::amount_to_ui_amount(pool_amount, pool_mint.decimals), - spl_token::amount_to_ui_amount(account_data.amount, pool_mint.decimals) + spl_token::amount_to_ui_amount(token_account.amount, pool_mint.decimals) ) .into()); } @@ -907,7 +806,7 @@ fn command_withdraw( instructions.push( // Approve spending token - approve_token( + spl_token::instruction::approve( &spl_token::id(), &withdraw_from, &pool_withdraw_authority, @@ -965,7 +864,7 @@ fn command_withdraw( stake_receiver = Some(stake_receiver_account.pubkey()); } - instructions.push(withdraw( + instructions.push(spl_stake_pool::instruction::withdraw( &spl_stake_pool::id(), &pool, &pool_data.validator_list, @@ -1000,27 +899,19 @@ fn command_set_owner( new_owner: &Option, new_fee_receiver: &Option, ) -> CommandResult { - let pool_data = config.rpc_client.get_account_data(&pool)?; - let pool_data: StakePool = StakePool::try_from_slice(pool_data.as_slice()).unwrap(); + let pool_data = get_stake_pool(&config.rpc_client, pool)?; // If new accounts are missing in the arguments use the old ones - let new_owner: Pubkey = match new_owner { + let new_owner = match new_owner { None => pool_data.owner, Some(value) => *value, }; - let new_fee_receiver: Pubkey = match new_fee_receiver { + let new_fee_receiver = match new_fee_receiver { None => pool_data.owner_fee_account, Some(value) => { // Check for fee receiver being a valid token account and have to same mint as the stake pool - let account_data = config.rpc_client.get_account_data(value)?; - let account_data: TokenAccount = - match TokenAccount::unpack_from_slice(account_data.as_slice()) { - Ok(data) => data, - Err(_) => { - return Err(format!("{} is not a token account", value).into()); - } - }; - if account_data.mint != pool_data.pool_mint { + let token_account = get_token_account(&config.rpc_client, value, &pool_data.pool_mint)?; + if token_account.mint != pool_data.pool_mint { return Err("Fee receiver account belongs to a different mint" .to_string() .into()); @@ -1030,7 +921,7 @@ fn command_set_owner( }; let mut transaction = Transaction::new_with_payer( - &[set_owner( + &[spl_stake_pool::instruction::set_owner( &spl_stake_pool::id(), &pool, &config.owner.pubkey(), @@ -1122,7 +1013,8 @@ fn main() { Defaults to the client keypair.", ), ) - .subcommand(SubCommand::with_name("create-pool").about("Create a new stake pool") + .subcommand(SubCommand::with_name("create-pool") + .about("Create a new stake pool") .arg( Arg::with_name("fee_numerator") .long("fee-numerator") @@ -1154,7 +1046,8 @@ fn main() { .help("Max number of validators included in the stake pool"), ) ) - .subcommand(SubCommand::with_name("create-validator-stake").about("Create a new stake account to use with the pool. Must be signed by the pool owner.") + .subcommand(SubCommand::with_name("create-validator-stake") + .about("Create a new stake account to use with the pool. Must be signed by the pool owner.") .arg( Arg::with_name("pool") .index(1) @@ -1174,7 +1067,8 @@ fn main() { .help("The validator vote account that this stake will be delegated to"), ) ) - .subcommand(SubCommand::with_name("add-validator").about("Add validator account to the stake pool. Must be signed by the pool owner.") + .subcommand(SubCommand::with_name("add-validator") + .about("Add validator account to the stake pool. Must be signed by the pool owner.") .arg( Arg::with_name("pool") .index(1) @@ -1199,10 +1093,12 @@ fn main() { .validator(is_pubkey) .value_name("ADDRESS") .takes_value(true) - .help("Account to receive pool token. Must be initialized account of the stake pool token. Defaults to the new pool token account."), + .help("Account to receive pool token. Must be initialized account of the stake pool token. \ + Defaults to the new pool token account."), ) ) - .subcommand(SubCommand::with_name("remove-validator").about("Remove validator account from the stake pool. Must be signed by the pool owner.") + .subcommand(SubCommand::with_name("remove-validator") + .about("Remove validator account from the stake pool. Must be signed by the pool owner.") .arg( Arg::with_name("pool") .index(1) @@ -1228,7 +1124,8 @@ fn main() { .value_name("ADDRESS") .takes_value(true) .required(true) - .help("Token account to withdraw pool token from. Must have enough tokens for the full stake address balance."), + .help("Token account to withdraw pool token from. \ + Must have enough tokens for the full stake address balance."), ) .arg( Arg::with_name("new_authority") @@ -1236,10 +1133,12 @@ fn main() { .validator(is_pubkey) .value_name("ADDRESS") .takes_value(true) - .help("New authority to set as Staker and Withdrawer in the stake account removed from the pool. Defaults to the wallet owner pubkey."), + .help("New authority to set as Staker and Withdrawer in the stake account removed from the pool. + Defaults to the wallet owner pubkey."), ) ) - .subcommand(SubCommand::with_name("deposit").about("Add stake account to the stake pool") + .subcommand(SubCommand::with_name("deposit") + .about("Add stake account to the stake pool") .arg( Arg::with_name("pool") .index(1) @@ -1264,10 +1163,12 @@ fn main() { .validator(is_pubkey) .value_name("ADDRESS") .takes_value(true) - .help("Account to receive pool token. Must be initialized account of the stake pool token. Defaults to the new pool token account."), + .help("Account to receive pool token. Must be initialized account of the stake pool token. \ + Defaults to the new pool token account."), ) ) - .subcommand(SubCommand::with_name("list").about("List stake accounts managed by this pool") + .subcommand(SubCommand::with_name("list") + .about("List stake accounts managed by this pool") .arg( Arg::with_name("pool") .index(1) @@ -1278,7 +1179,8 @@ fn main() { .help("Stake pool address."), ) ) - .subcommand(SubCommand::with_name("update").about("Updates all balances in the pool after validator stake accounts receive rewards.") + .subcommand(SubCommand::with_name("update") + .about("Updates all balances in the pool after validator stake accounts receive rewards.") .arg( Arg::with_name("pool") .index(1) @@ -1289,7 +1191,8 @@ fn main() { .help("Stake pool address."), ) ) - .subcommand(SubCommand::with_name("withdraw").about("Withdraw amount from the stake pool") + .subcommand(SubCommand::with_name("withdraw") + .about("Withdraw amount from the stake pool") .arg( Arg::with_name("pool") .index(1) @@ -1326,7 +1229,8 @@ fn main() { .help("Stake account to receive SOL from the stake pool. Defaults to a new stake account."), ) ) - .subcommand(SubCommand::with_name("set-owner").about("Changes owner or fee receiver account for the stake pool.") + .subcommand(SubCommand::with_name("set-owner") + .about("Changes owner or fee receiver account for the stake pool.") .arg( Arg::with_name("pool") .index(1) @@ -1414,7 +1318,7 @@ fn main() { let max_validators = value_t_or_exit!(arg_matches, "max_validators", u32); command_create_pool( &config, - PoolFee { + spl_stake_pool::instruction::Fee { denominator, numerator, }, From ea7dd0db093bb145971f91c051f556c7ec908668 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Wed, 31 Mar 2021 18:39:50 -0700 Subject: [PATCH 0073/1076] Code cleanup v2 --- clients/cli/src/main.rs | 4 +- program/src/processor.rs | 155 ++++++--------------------------------- program/src/state.rs | 28 +++---- program/tests/vsa_add.rs | 2 +- 4 files changed, 39 insertions(+), 150 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 02a1f0a8..eee9fca6 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -607,7 +607,7 @@ fn command_list(config: &Config, pool: &Pubkey) -> CommandResult { for validator in validator_list.validators { println!( "Vote Account: {}\tBalance: {}\tEpoch: {}", - validator.validator_account, validator.balance, validator.last_update_epoch + validator.vote_account, validator.balance, validator.last_update_epoch ); } } @@ -654,7 +654,7 @@ fn command_update(config: &Config, pool: &Pubkey) -> CommandResult { } else { let (stake_account, _) = find_stake_address_for_validator( &spl_stake_pool::id(), - &item.validator_account, + &item.vote_account, &pool, ); Some(stake_account) diff --git a/program/src/processor.rs b/program/src/processor.rs index 88331c64..edae062f 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -66,14 +66,14 @@ impl Processor { /// Checks if validator stake account is a proper program address pub fn is_validator_stake_address( - validator_account: &Pubkey, + vote_account: &Pubkey, program_id: &Pubkey, stake_pool_info: &AccountInfo, stake_account_info: &AccountInfo, ) -> bool { // Check stake account address validity let (stake_address, _) = - find_stake_address_for_validator(&program_id, &validator_account, &stake_pool_info.key); + find_stake_address_for_validator(&program_id, &vote_account, &stake_pool_info.key); stake_address == *stake_account_info.key } @@ -83,17 +83,17 @@ impl Processor { stake_pool_info: &AccountInfo, stake_account_info: &AccountInfo, ) -> Result { - let validator_account = Self::get_validator(stake_account_info)?; + let vote_account = Self::get_validator(stake_account_info)?; if !Self::is_validator_stake_address( - &validator_account, + &vote_account, program_id, stake_pool_info, stake_account_info, ) { return Err(StakePoolError::InvalidStakeAccountAddress.into()); } - Ok(validator_account) + Ok(vote_account) } /// Issue a stake_split instruction. @@ -249,33 +249,27 @@ impl Processor { let validator_list_info = next_account_info(account_info_iter)?; let pool_mint_info = next_account_info(account_info_iter)?; let owner_fee_info = next_account_info(account_info_iter)?; - // Clock sysvar account let clock_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(clock_info)?; - // Rent sysvar account let rent_info = next_account_info(account_info_iter)?; let rent = &Rent::from_account_info(rent_info)?; - // Token program ID let token_program_info = next_account_info(account_info_iter)?; - // Check if transaction was signed by owner if !owner_info.is_signer { return Err(StakePoolError::SignatureMissing.into()); } let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; - // Stake pool account should not be already initialized if !stake_pool.is_uninitialized() { return Err(StakePoolError::AlreadyInUse.into()); } - // Check if validator stake list storage is unitialized let mut validator_list = try_from_slice_unchecked::(&validator_list_info.data.borrow())?; if !validator_list.is_uninitialized() { return Err(StakePoolError::AlreadyInUse.into()); } - // Check validator list size + let data_length = validator_list_info.data_len(); let expected_max_validators = ValidatorList::calculate_max_validators(data_length); if expected_max_validators != max_validators as usize || max_validators == 0 { @@ -285,13 +279,11 @@ impl Processor { validator_list.validators.clear(); validator_list.max_validators = max_validators; - // Check if stake pool account is rent-exempt if !rent.is_exempt(stake_pool_info.lamports(), stake_pool_info.data_len()) { msg!("Stake pool not rent-exempt"); return Err(ProgramError::AccountNotRentExempt); } - // Check if validator stake list account is rent-exempt if !rent.is_exempt( validator_list_info.lamports(), validator_list_info.data_len(), @@ -305,17 +297,14 @@ impl Processor { return Err(StakePoolError::FeeTooHigh.into()); } - // Check if fee account's owner the same as token program id if owner_fee_info.owner != token_program_info.key { return Err(StakePoolError::InvalidFeeAccount.into()); } - // Check pool mint program ID if pool_mint_info.owner != token_program_info.key { return Err(ProgramError::IncorrectProgramId); } - // Check for owner fee account to have proper mint assigned if *pool_mint_info.key != spl_token::state::Account::unpack_from_slice(&owner_fee_info.data.borrow())?.mint { @@ -360,31 +349,19 @@ impl Processor { accounts: &[AccountInfo], ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); - // Stake pool account let stake_pool_info = next_account_info(account_info_iter)?; - // Owner account let owner_info = next_account_info(account_info_iter)?; - // Account creation funder account let funder_info = next_account_info(account_info_iter)?; - // Stake account to be created let stake_account_info = next_account_info(account_info_iter)?; - // Validator this stake account will vote for let validator_info = next_account_info(account_info_iter)?; - // Rent sysvar account let rent_info = next_account_info(account_info_iter)?; let rent = &Rent::from_account_info(rent_info)?; - // Clock sysvar account let clock_info = next_account_info(account_info_iter)?; - // Stake history sysvar account let stake_history_info = next_account_info(account_info_iter)?; - // Stake config sysvar account let stake_config_info = next_account_info(account_info_iter)?; - // System program id let system_program_info = next_account_info(account_info_iter)?; - // Staking program id let stake_program_info = next_account_info(account_info_iter)?; - // Get stake pool stake (and check if it is initialized) if stake_pool_info.owner != program_id { return Err(ProgramError::IncorrectProgramId); } @@ -394,7 +371,6 @@ impl Processor { } stake_pool.check_owner(owner_info)?; - // Check program ids if *system_program_info.key != solana_program::system_program::id() { return Err(ProgramError::IncorrectProgramId); } @@ -402,7 +378,6 @@ impl Processor { return Err(ProgramError::IncorrectProgramId); } - // Check stake account address validity let (stake_address, bump_seed) = find_stake_address_for_validator( &program_id, &validator_info.key, @@ -474,52 +449,35 @@ impl Processor { accounts: &[AccountInfo], ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); - // Stake pool account let stake_pool_info = next_account_info(account_info_iter)?; - // Pool owner account let owner_info = next_account_info(account_info_iter)?; - // Stake pool deposit authority let deposit_info = next_account_info(account_info_iter)?; - // Stake pool withdraw authority let withdraw_info = next_account_info(account_info_iter)?; - // Account storing validator stake list let validator_list_info = next_account_info(account_info_iter)?; - // Stake account to add to the pool let stake_account_info = next_account_info(account_info_iter)?; - // User account to receive pool tokens let dest_user_info = next_account_info(account_info_iter)?; - // Pool token mint account let pool_mint_info = next_account_info(account_info_iter)?; - // Clock sysvar account let clock_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(clock_info)?; - // Stake history sysvar account let stake_history_info = next_account_info(account_info_iter)?; let stake_history = &StakeHistory::from_account_info(stake_history_info)?; - // Pool token program id let token_program_info = next_account_info(account_info_iter)?; - // Staking program id let stake_program_info = next_account_info(account_info_iter)?; - // Check program ids if *stake_program_info.key != stake_program::id() { return Err(ProgramError::IncorrectProgramId); } - // Get stake pool stake (and check if it is initialized) let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); } - // Check authority accounts stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?; stake_pool.check_authority_deposit(deposit_info.key, program_id, stake_pool_info.key)?; - // Check owner validity and signature stake_pool.check_owner(owner_info)?; - // Check stake pool last update epoch if stake_pool.last_update_epoch < clock.epoch { return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); } @@ -531,12 +489,10 @@ impl Processor { return Err(StakePoolError::WrongPoolMint.into()); } - // Check validator stake account list storage if *validator_list_info.key != stake_pool.validator_list { return Err(StakePoolError::InvalidValidatorStakeList.into()); } - // Read validator stake list account and check if it is valid let mut validator_list = try_from_slice_unchecked::(&validator_list_info.data.borrow())?; if !validator_list.is_valid() { @@ -546,10 +502,10 @@ impl Processor { return Err(ProgramError::AccountDataTooSmall); } - let validator_account = + let vote_account = Self::get_validator_checked(program_id, stake_pool_info, stake_account_info)?; - if validator_list.contains(&validator_account) { + if validator_list.contains(&vote_account) { return Err(StakePoolError::ValidatorAlreadyAdded.into()); } @@ -592,7 +548,7 @@ impl Processor { // Add validator to the list and save validator_list.validators.push(ValidatorStakeInfo { - validator_account, + vote_account, balance: stake_lamports, last_update_epoch: clock.epoch, }); @@ -613,48 +569,31 @@ impl Processor { accounts: &[AccountInfo], ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); - // Stake pool account let stake_pool_info = next_account_info(account_info_iter)?; - // Pool owner account let owner_info = next_account_info(account_info_iter)?; - // Stake pool withdraw authority let withdraw_info = next_account_info(account_info_iter)?; - // New stake authority let new_stake_authority_info = next_account_info(account_info_iter)?; - // Account storing validator stake list let validator_list_info = next_account_info(account_info_iter)?; - // Stake account to remove from the pool let stake_account_info = next_account_info(account_info_iter)?; - // User account with pool tokens to burn from let burn_from_info = next_account_info(account_info_iter)?; - // Pool token mint account let pool_mint_info = next_account_info(account_info_iter)?; - // Clock sysvar account let clock_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(clock_info)?; - // Pool token program id let token_program_info = next_account_info(account_info_iter)?; - // Staking program id let stake_program_info = next_account_info(account_info_iter)?; - // Check program ids if *stake_program_info.key != stake_program::id() { return Err(ProgramError::IncorrectProgramId); } - // Get stake pool stake (and check if it is initialized) let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); } - // Check authority account stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?; - - // Check owner validity and signature stake_pool.check_owner(owner_info)?; - // Check stake pool last update epoch if stake_pool.last_update_epoch < clock.epoch { return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); } @@ -666,26 +605,23 @@ impl Processor { return Err(StakePoolError::WrongPoolMint.into()); } - // Check validator stake account list storage if *validator_list_info.key != stake_pool.validator_list { return Err(StakePoolError::InvalidValidatorStakeList.into()); } - // Read validator stake list account and check if it is valid let mut validator_list = try_from_slice_unchecked::(&validator_list_info.data.borrow())?; if !validator_list.is_valid() { return Err(StakePoolError::InvalidState.into()); } - let validator_account = + let vote_account = Self::get_validator_checked(program_id, stake_pool_info, stake_account_info)?; - if !validator_list.contains(&validator_account) { + if !validator_list.contains(&vote_account) { return Err(StakePoolError::ValidatorNotFound.into()); } - // Update Withdrawer and Staker authority to the provided authority for authority in &[ stake_program::StakeAuthorize::Withdrawer, stake_program::StakeAuthorize::Staker, @@ -722,7 +658,7 @@ impl Processor { // Remove validator from the list and save validator_list .validators - .retain(|item| item.validator_account != validator_account); + .retain(|item| item.vote_account != vote_account); validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; // Save amounts to the stake pool state @@ -740,22 +676,18 @@ impl Processor { accounts: &[AccountInfo], ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); - // Account storing validator stake list let validator_list_info = next_account_info(account_info_iter)?; - // Clock sysvar account let clock_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(clock_info)?; - // Validator stake accounts let validator_stake_accounts = account_info_iter.as_slice(); - // Read validator stake list account and check if it is valid let mut validator_list = try_from_slice_unchecked::(&validator_list_info.data.borrow())?; if !validator_list.is_valid() { return Err(StakePoolError::InvalidState.into()); } - let validator_accounts: Vec> = validator_stake_accounts + let vote_accounts: Vec> = validator_stake_accounts .iter() .map(|stake| Self::get_validator(stake).ok()) .collect(); @@ -766,12 +698,11 @@ impl Processor { if validator_stake_record.last_update_epoch >= clock.epoch { continue; } - for (validator_stake_account, validator_account) in validator_stake_accounts - .iter() - .zip(validator_accounts.iter()) + for (validator_stake_account, vote_account) in + validator_stake_accounts.iter().zip(vote_accounts.iter()) { - if validator_stake_record.validator_account - != validator_account.ok_or(StakePoolError::WrongStakeState)? + if validator_stake_record.vote_account + != vote_account.ok_or(StakePoolError::WrongStakeState)? { continue; } @@ -794,26 +725,20 @@ impl Processor { accounts: &[AccountInfo], ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); - // Stake pool account let stake_pool_info = next_account_info(account_info_iter)?; - // Account storing validator stake list let validator_list_info = next_account_info(account_info_iter)?; - // Clock sysvar account let clock_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(clock_info)?; - // Get stake pool stake (and check if it is initialized) let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); } - // Check validator stake account list storage if *validator_list_info.key != stake_pool.validator_list { return Err(StakePoolError::InvalidValidatorStakeList.into()); } - // Read validator stake list account and check if it is valid let validator_list = try_from_slice_unchecked::(&validator_list_info.data.borrow())?; if !validator_list.is_valid() { @@ -867,36 +792,22 @@ impl Processor { /// Processes [Deposit](enum.Instruction.html). pub fn process_deposit(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { let account_info_iter = &mut accounts.iter(); - // Stake pool let stake_pool_info = next_account_info(account_info_iter)?; - // Account storing validator stake list let validator_list_info = next_account_info(account_info_iter)?; - // Stake pool deposit authority let deposit_info = next_account_info(account_info_iter)?; - // Stake pool withdraw authority let withdraw_info = next_account_info(account_info_iter)?; - // Stake account to join the pool (withdraw should be set to stake pool deposit) let stake_info = next_account_info(account_info_iter)?; - // Validator stake account to merge with let validator_stake_account_info = next_account_info(account_info_iter)?; - // User account to receive pool tokens let dest_user_info = next_account_info(account_info_iter)?; - // Account to receive pool fee tokens let owner_fee_info = next_account_info(account_info_iter)?; - // Pool token mint account let pool_mint_info = next_account_info(account_info_iter)?; - // Clock sysvar account let clock_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(clock_info)?; - // Stake history sysvar account let stake_history_info = next_account_info(account_info_iter)?; let stake_history = &StakeHistory::from_account_info(stake_history_info)?; - // Pool token program id let token_program_info = next_account_info(account_info_iter)?; - // Stake program id let stake_program_info = next_account_info(account_info_iter)?; - // Check program ids if *stake_program_info.key != stake_program::id() { return Err(ProgramError::IncorrectProgramId); } @@ -906,10 +817,8 @@ impl Processor { return Err(StakePoolError::InvalidState.into()); } - // Check if stake is active Self::check_stake_activation(stake_info, clock, stake_history)?; - // Check authority accounts stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?; stake_pool.check_authority_deposit(deposit_info.key, program_id, stake_pool_info.key)?; @@ -920,28 +829,25 @@ impl Processor { return Err(ProgramError::IncorrectProgramId); } - // Check validator stake account list storage if *validator_list_info.key != stake_pool.validator_list { return Err(StakePoolError::InvalidValidatorStakeList.into()); } - // Check stake pool last update epoch if stake_pool.last_update_epoch < clock.epoch { return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); } - // Read validator stake list account and check if it is valid let mut validator_list = try_from_slice_unchecked::(&validator_list_info.data.borrow())?; if !validator_list.is_valid() { return Err(StakePoolError::InvalidState.into()); } - let validator_account = + let vote_account = Self::get_validator_checked(program_id, stake_pool_info, validator_stake_account_info)?; let validator_list_item = validator_list - .find_mut(&validator_account) + .find_mut(&vote_account) .ok_or(StakePoolError::ValidatorNotFound)?; let stake_lamports = **stake_info.lamports.borrow(); @@ -1031,31 +937,19 @@ impl Processor { accounts: &[AccountInfo], ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); - // Stake pool let stake_pool_info = next_account_info(account_info_iter)?; - // Account storing validator stake list let validator_list_info = next_account_info(account_info_iter)?; - // Stake pool withdraw authority let withdraw_info = next_account_info(account_info_iter)?; - // Stake account to split let stake_split_from = next_account_info(account_info_iter)?; - // Unitialized stake account to receive withdrawal let stake_split_to = next_account_info(account_info_iter)?; - // User account to set as a new withdraw authority let user_stake_authority = next_account_info(account_info_iter)?; - // User account with pool tokens to burn from let burn_from_info = next_account_info(account_info_iter)?; - // Pool token mint account let pool_mint_info = next_account_info(account_info_iter)?; - // Clock sysvar account let clock_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(clock_info)?; - // Pool token program id let token_program_info = next_account_info(account_info_iter)?; - // Stake program id let stake_program_info = next_account_info(account_info_iter)?; - // Check program ids if *stake_program_info.key != stake_program::id() { return Err(ProgramError::IncorrectProgramId); } @@ -1065,35 +959,31 @@ impl Processor { return Err(StakePoolError::InvalidState.into()); } - // Check authority account stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?; if stake_pool.token_program_id != *token_program_info.key { return Err(ProgramError::IncorrectProgramId); } - // Check validator stake account list storage if *validator_list_info.key != stake_pool.validator_list { return Err(StakePoolError::InvalidValidatorStakeList.into()); } - // Check stake pool last update epoch if stake_pool.last_update_epoch < clock.epoch { return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); } - // Read validator stake list account and check if it is valid let mut validator_list = try_from_slice_unchecked::(&validator_list_info.data.borrow())?; if !validator_list.is_valid() { return Err(StakePoolError::InvalidState.into()); } - let validator_account = + let vote_account = Self::get_validator_checked(program_id, stake_pool_info, stake_split_from)?; let validator_list_item = validator_list - .find_mut(&validator_account) + .find_mut(&vote_account) .ok_or(StakePoolError::ValidatorNotFound)?; let stake_amount = stake_pool @@ -1168,10 +1058,8 @@ impl Processor { return Err(StakePoolError::InvalidState.into()); } - // Check owner validity and signature stake_pool.check_owner(owner_info)?; - // Check for owner fee account to have proper mint assigned if stake_pool.pool_mint != spl_token::state::Account::unpack_from_slice(&new_owner_fee_info.data.borrow())?.mint { @@ -1183,6 +1071,7 @@ impl Processor { stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; Ok(()) } + /// Processes [Instruction](enum.Instruction.html). pub fn process(program_id: &Pubkey, accounts: &[AccountInfo], input: &[u8]) -> ProgramResult { let instruction = StakePoolInstruction::try_from_slice(input)?; diff --git a/program/src/state.rs b/program/src/state.rs index 497bb64c..5743c944 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -170,10 +170,10 @@ pub struct ValidatorList { #[repr(C)] #[derive(Clone, Copy, Debug, Default, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)] pub struct ValidatorStakeInfo { - /// Validator account pubkey - pub validator_account: Pubkey, + /// Validator vote account address + pub vote_account: Pubkey, - /// Account balance in lamports + /// Balance of the validator's stake account pub balance: u64, /// Last epoch balance field was updated @@ -197,23 +197,23 @@ impl ValidatorList { } /// Check if contains validator with particular pubkey - pub fn contains(&self, validator: &Pubkey) -> bool { + pub fn contains(&self, vote_account: &Pubkey) -> bool { self.validators .iter() - .any(|x| x.validator_account == *validator) + .any(|x| x.vote_account == *vote_account) } - /// Check if contains validator with particular pubkey (mutable) - pub fn find_mut(&mut self, validator: &Pubkey) -> Option<&mut ValidatorStakeInfo> { + /// Check if contains validator with particular pubkey + pub fn find_mut(&mut self, vote_account: &Pubkey) -> Option<&mut ValidatorStakeInfo> { self.validators .iter_mut() - .find(|x| x.validator_account == *validator) + .find(|x| x.vote_account == *vote_account) } - /// Check if contains validator with particular pubkey (immutable) - pub fn find(&self, validator: &Pubkey) -> Option<&ValidatorStakeInfo> { + /// Check if contains validator with particular pubkey + pub fn find(&self, vote_account: &Pubkey) -> Option<&ValidatorStakeInfo> { self.validators .iter() - .find(|x| x.validator_account == *validator) + .find(|x| x.vote_account == *vote_account) } /// Check if validator stake list is actually initialized as a validator stake list @@ -271,17 +271,17 @@ mod test { max_validators, validators: vec![ ValidatorStakeInfo { - validator_account: Pubkey::new_from_array([1; 32]), + vote_account: Pubkey::new_from_array([1; 32]), balance: 123456789, last_update_epoch: 987654321, }, ValidatorStakeInfo { - validator_account: Pubkey::new_from_array([2; 32]), + vote_account: Pubkey::new_from_array([2; 32]), balance: 998877665544, last_update_epoch: 11223445566, }, ValidatorStakeInfo { - validator_account: Pubkey::new_from_array([3; 32]), + vote_account: Pubkey::new_from_array([3; 32]), balance: 0, last_update_epoch: 999999999999999, }, diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index 9be382b5..fdcd5591 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -129,7 +129,7 @@ async fn test_add_validator_to_pool() { account_type: state::AccountType::ValidatorList, max_validators: stake_pool_accounts.max_validators, validators: vec![state::ValidatorStakeInfo { - validator_account: user_stake.vote.pubkey(), + vote_account: user_stake.vote.pubkey(), last_update_epoch: 0, balance: stake_account_balance, }] From d2828ff43bce3a8c8db2cb1a6d5eac48f179f08c Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Wed, 31 Mar 2021 20:08:20 -0700 Subject: [PATCH 0074/1076] De-tangle processor/state dependencies --- clients/cli/src/main.rs | 87 ++++++++++++++++++------------------ program/src/borsh.rs | 6 +-- program/src/entrypoint.rs | 5 ++- program/src/processor.rs | 64 +++++++++----------------- program/src/state.rs | 50 ++++++++++++++------- program/tests/helpers/mod.rs | 6 +-- program/tests/initialize.rs | 30 ++++++------- 7 files changed, 123 insertions(+), 125 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index eee9fca6..6e8d9a23 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -120,7 +120,7 @@ fn command_create_pool( let pool_account_balance = config .rpc_client .get_minimum_balance_for_rent_exemption(get_packed_len::())?; - let empty_validator_list = ValidatorList::new_with_max_validators(max_validators); + let empty_validator_list = ValidatorList::new(max_validators); let validator_list_size = get_instance_packed_len(&empty_validator_list)?; let validator_list_balance = config .rpc_client @@ -272,7 +272,7 @@ fn command_vsa_add( command_update(config, pool)?; } - let pool_data = get_stake_pool(&config.rpc_client, pool)?; + let stake_pool = get_stake_pool(&config.rpc_client, pool)?; let mut total_rent_free_balances: u64 = 0; @@ -286,7 +286,7 @@ fn command_vsa_add( &config, &token_receiver, &token_receiver_account, - &pool_data.pool_mint, + &stake_pool.pool_mint, &mut instructions, |balance| { signers.push(&token_receiver_account); @@ -299,14 +299,14 @@ fn command_vsa_add( &spl_stake_pool::id(), pool, AUTHORITY_DEPOSIT, - pool_data.deposit_bump_seed, + stake_pool.deposit_bump_seed, ) .unwrap(); let pool_withdraw_authority: Pubkey = create_pool_authority_address( &spl_stake_pool::id(), pool, AUTHORITY_WITHDRAW, - pool_data.withdraw_bump_seed, + stake_pool.withdraw_bump_seed, ) .unwrap(); @@ -332,10 +332,10 @@ fn command_vsa_add( &config.owner.pubkey(), &pool_deposit_authority, &pool_withdraw_authority, - &pool_data.validator_list, + &stake_pool.validator_list, &stake, &token_receiver, - &pool_data.pool_mint, + &stake_pool.pool_mint, &spl_token::id(), )?, ]); @@ -365,12 +365,12 @@ fn command_vsa_remove( command_update(config, pool)?; } - let pool_data = get_stake_pool(&config.rpc_client, pool)?; + let stake_pool = get_stake_pool(&config.rpc_client, pool)?; let pool_withdraw_authority: Pubkey = create_pool_authority_address( &spl_stake_pool::id(), pool, AUTHORITY_WITHDRAW, - pool_data.withdraw_bump_seed, + stake_pool.withdraw_bump_seed, ) .unwrap(); @@ -379,16 +379,16 @@ fn command_vsa_remove( // Calculate amount of tokens to withdraw let stake_account = config.rpc_client.get_account(&stake)?; - let tokens_to_withdraw = pool_data + let tokens_to_withdraw = stake_pool .calc_pool_withdraw_amount(stake_account.lamports) .unwrap(); // Check balance and mint let token_account = - get_token_account(&config.rpc_client, &withdraw_from, &pool_data.pool_mint)?; + get_token_account(&config.rpc_client, &withdraw_from, &stake_pool.pool_mint)?; if token_account.amount < tokens_to_withdraw { - let pool_mint = get_token_mint(&config.rpc_client, &pool_data.pool_mint)?; + let pool_mint = get_token_mint(&config.rpc_client, &stake_pool.pool_mint)?; return Err(format!( "Not enough balance to burn to remove validator stake account from the pool. {} pool tokens needed.", spl_token::amount_to_ui_amount(tokens_to_withdraw, pool_mint.decimals) @@ -413,10 +413,10 @@ fn command_vsa_remove( &config.owner.pubkey(), &pool_withdraw_authority, &new_authority, - &pool_data.validator_list, + &stake_pool.validator_list, &stake, &withdraw_from, - &pool_data.pool_mint, + &stake_pool.pool_mint, &spl_token::id(), )?, ], @@ -490,7 +490,7 @@ fn command_deposit( command_update(config, pool)?; } - let pool_data = get_stake_pool(&config.rpc_client, pool)?; + let stake_pool = get_stake_pool(&config.rpc_client, pool)?; let stake_state = get_stake_state(&config.rpc_client, &stake)?; if config.verbose { @@ -502,7 +502,7 @@ fn command_deposit( }?; // Check if this vote account has staking account in the pool - let validator_list = get_validator_list(&config.rpc_client, &pool_data.validator_list)?; + let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?; if !validator_list.contains(&vote_account) { return Err("Stake account for this validator does not exist in the pool.".into()); } @@ -529,7 +529,7 @@ fn command_deposit( &config, &token_receiver, &token_receiver_account, - &pool_data.pool_mint, + &stake_pool.pool_mint, &mut instructions, |balance| { signers.push(&token_receiver_account); @@ -542,14 +542,14 @@ fn command_deposit( &spl_stake_pool::id(), pool, AUTHORITY_DEPOSIT, - pool_data.deposit_bump_seed, + stake_pool.deposit_bump_seed, ) .unwrap(); let pool_withdraw_authority: Pubkey = create_pool_authority_address( &spl_stake_pool::id(), pool, AUTHORITY_WITHDRAW, - pool_data.withdraw_bump_seed, + stake_pool.withdraw_bump_seed, ) .unwrap(); @@ -572,14 +572,14 @@ fn command_deposit( spl_stake_pool::instruction::deposit( &spl_stake_pool::id(), &pool, - &pool_data.validator_list, + &stake_pool.validator_list, &pool_deposit_authority, &pool_withdraw_authority, &stake, &validator_stake_account, &token_receiver, - &pool_data.owner_fee_account, - &pool_data.pool_mint, + &stake_pool.owner_fee_account, + &stake_pool.pool_mint, &spl_token::id(), )?, ]); @@ -599,11 +599,11 @@ fn command_deposit( } fn command_list(config: &Config, pool: &Pubkey) -> CommandResult { - let pool_data = get_stake_pool(&config.rpc_client, pool)?; + let stake_pool = get_stake_pool(&config.rpc_client, pool)?; if config.verbose { println!("Current validator list"); - let validator_list = get_validator_list(&config.rpc_client, &pool_data.validator_list)?; + let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?; for validator in validator_list.validators { println!( "Vote Account: {}\tBalance: {}\tEpoch: {}", @@ -616,7 +616,7 @@ fn command_list(config: &Config, pool: &Pubkey) -> CommandResult { &spl_stake_pool::id(), pool, AUTHORITY_WITHDRAW, - pool_data.withdraw_bump_seed, + stake_pool.withdraw_bump_seed, ) .unwrap(); @@ -641,8 +641,8 @@ fn command_list(config: &Config, pool: &Pubkey) -> CommandResult { } fn command_update(config: &Config, pool: &Pubkey) -> CommandResult { - let pool_data = get_stake_pool(&config.rpc_client, pool)?; - let validator_list = get_validator_list(&config.rpc_client, &pool_data.validator_list)?; + let stake_pool = get_stake_pool(&config.rpc_client, pool)?; + let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?; let epoch_info = config.rpc_client.get_epoch_info()?; let accounts_to_update: Vec = validator_list @@ -667,12 +667,12 @@ fn command_update(config: &Config, pool: &Pubkey) -> CommandResult { for chunk in accounts_to_update.chunks(MAX_ACCOUNTS_TO_UPDATE) { instructions.push(spl_stake_pool::instruction::update_validator_list_balance( &spl_stake_pool::id(), - &pool_data.validator_list, + &stake_pool.validator_list, &chunk, )?); } - if instructions.is_empty() && pool_data.last_update_epoch == epoch_info.epoch { + if instructions.is_empty() && stake_pool.last_update_epoch == epoch_info.epoch { println!("Stake pool balances are up to date, no update required."); Ok(()) } else { @@ -680,7 +680,7 @@ fn command_update(config: &Config, pool: &Pubkey) -> CommandResult { instructions.push(spl_stake_pool::instruction::update_stake_pool_balance( &spl_stake_pool::id(), pool, - &pool_data.validator_list, + &stake_pool.validator_list, )?); let mut transaction = @@ -765,21 +765,21 @@ fn command_withdraw( command_update(config, pool)?; } - let pool_data = get_stake_pool(&config.rpc_client, pool)?; - let pool_mint = get_token_mint(&config.rpc_client, &pool_data.pool_mint)?; + let stake_pool = get_stake_pool(&config.rpc_client, pool)?; + let pool_mint = get_token_mint(&config.rpc_client, &stake_pool.pool_mint)?; let pool_amount = spl_token::ui_amount_to_amount(pool_amount, pool_mint.decimals); let pool_withdraw_authority: Pubkey = create_pool_authority_address( &spl_stake_pool::id(), pool, AUTHORITY_WITHDRAW, - pool_data.withdraw_bump_seed, + stake_pool.withdraw_bump_seed, ) .unwrap(); // Check withdraw_from account type let token_account = - get_token_account(&config.rpc_client, &withdraw_from, &pool_data.pool_mint)?; + get_token_account(&config.rpc_client, &withdraw_from, &stake_pool.pool_mint)?; // Check withdraw_from balance if token_account.amount < pool_amount { @@ -794,7 +794,7 @@ fn command_withdraw( // Get the list of accounts to withdraw from let withdraw_accounts = prepare_withdraw_accounts( &config.rpc_client, - &pool_data, + &stake_pool, &pool_withdraw_authority, pool_amount, )?; @@ -824,7 +824,7 @@ fn command_withdraw( // Go through prepared accounts and withdraw/claim them for withdraw_account in withdraw_accounts { // Convert pool tokens amount to lamports - let sol_withdraw_amount = pool_data + let sol_withdraw_amount = stake_pool .calc_lamports_withdraw_amount(withdraw_account.pool_amount) .unwrap(); @@ -867,13 +867,13 @@ fn command_withdraw( instructions.push(spl_stake_pool::instruction::withdraw( &spl_stake_pool::id(), &pool, - &pool_data.validator_list, + &stake_pool.validator_list, &pool_withdraw_authority, &withdraw_account.address, &stake_receiver.unwrap(), // Cannot be none at this point &config.owner.pubkey(), &withdraw_from, - &pool_data.pool_mint, + &stake_pool.pool_mint, &spl_token::id(), withdraw_account.pool_amount, )?); @@ -899,19 +899,20 @@ fn command_set_owner( new_owner: &Option, new_fee_receiver: &Option, ) -> CommandResult { - let pool_data = get_stake_pool(&config.rpc_client, pool)?; + let stake_pool = get_stake_pool(&config.rpc_client, pool)?; // If new accounts are missing in the arguments use the old ones let new_owner = match new_owner { - None => pool_data.owner, + None => stake_pool.owner, Some(value) => *value, }; let new_fee_receiver = match new_fee_receiver { - None => pool_data.owner_fee_account, + None => stake_pool.owner_fee_account, Some(value) => { // Check for fee receiver being a valid token account and have to same mint as the stake pool - let token_account = get_token_account(&config.rpc_client, value, &pool_data.pool_mint)?; - if token_account.mint != pool_data.pool_mint { + let token_account = + get_token_account(&config.rpc_client, value, &stake_pool.pool_mint)?; + if token_account.mint != stake_pool.pool_mint { return Err("Fee receiver account belongs to a different mint" .to_string() .into()); diff --git a/program/src/borsh.rs b/program/src/borsh.rs index 75bd3758..e62bcbba 100644 --- a/program/src/borsh.rs +++ b/program/src/borsh.rs @@ -3,7 +3,7 @@ use { borsh::{maybestd::io::Error, BorshDeserialize, BorshSerialize}, - std::io::{Result as IoResult, Write}, + std::io::{self, Write}, }; /// Deserializes something and allows for incomplete reading @@ -20,13 +20,13 @@ struct WriteCounter { } impl Write for WriteCounter { - fn write(&mut self, data: &[u8]) -> IoResult { + fn write(&mut self, data: &[u8]) -> io::Result { let amount = data.len(); self.count += amount; Ok(amount) } - fn flush(&mut self) -> IoResult<()> { + fn flush(&mut self) -> io::Result<()> { Ok(()) } } diff --git a/program/src/entrypoint.rs b/program/src/entrypoint.rs index 6a3262b2..e2d4de2a 100644 --- a/program/src/entrypoint.rs +++ b/program/src/entrypoint.rs @@ -17,7 +17,8 @@ fn process_instruction( if let Err(error) = Processor::process(program_id, accounts, instruction_data) { // catch the error so we can print it error.print::(); - return Err(error); + Err(error) + } else { + Ok(()) } - Ok(()) } diff --git a/program/src/processor.rs b/program/src/processor.rs index edae062f..16cc5fd8 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -3,7 +3,6 @@ use { crate::{ borsh::try_from_slice_unchecked, - create_pool_authority_address, error::StakePoolError, find_authority_bump_seed, find_stake_address_for_validator, instruction::{Fee, StakePoolInstruction}, @@ -38,24 +37,8 @@ use { /// Program state handler. pub struct Processor {} impl Processor { - /// Checks withdraw or deposit authority - pub fn check_authority( - authority_to_check: &Pubkey, - program_id: &Pubkey, - stake_pool_key: &Pubkey, - authority: &[u8], - bump_seed: u8, - ) -> Result<(), ProgramError> { - if *authority_to_check - != create_pool_authority_address(program_id, stake_pool_key, authority, bump_seed)? - { - return Err(StakePoolError::InvalidProgramAddress.into()); - } - Ok(()) - } - /// Returns validator address for a particular stake account - pub fn get_validator(stake_account_info: &AccountInfo) -> Result { + fn get_validator(stake_account_info: &AccountInfo) -> Result { let stake_state: stake_program::StakeState = deserialize(&stake_account_info.data.borrow()) .or(Err(ProgramError::InvalidAccountData))?; match stake_state { @@ -65,7 +48,7 @@ impl Processor { } /// Checks if validator stake account is a proper program address - pub fn is_validator_stake_address( + fn is_validator_stake_address( vote_account: &Pubkey, program_id: &Pubkey, stake_pool_info: &AccountInfo, @@ -78,7 +61,7 @@ impl Processor { } /// Returns validator address for a particular stake account and checks its validity - pub fn get_validator_checked( + fn get_validator_checked( program_id: &Pubkey, stake_pool_info: &AccountInfo, stake_account_info: &AccountInfo, @@ -97,7 +80,7 @@ impl Processor { } /// Issue a stake_split instruction. - pub fn stake_split<'a>( + fn stake_split<'a>( stake_pool: &Pubkey, stake_account: AccountInfo<'a>, authority: AccountInfo<'a>, @@ -118,7 +101,7 @@ impl Processor { /// Issue a stake_merge instruction. #[allow(clippy::too_many_arguments)] - pub fn stake_merge<'a>( + fn stake_merge<'a>( stake_pool: &Pubkey, stake_account: AccountInfo<'a>, authority: AccountInfo<'a>, @@ -151,7 +134,7 @@ impl Processor { /// Issue a stake_set_owner instruction. #[allow(clippy::too_many_arguments)] - pub fn stake_authorize<'a>( + fn stake_authorize<'a>( stake_pool: &Pubkey, stake_account: AccountInfo<'a>, authority: AccountInfo<'a>, @@ -159,7 +142,7 @@ impl Processor { bump_seed: u8, new_staker: &Pubkey, staker_auth: stake_program::StakeAuthorize, - reserved: AccountInfo<'a>, + clock: AccountInfo<'a>, stake_program_info: AccountInfo<'a>, ) -> Result<(), ProgramError> { let me_bytes = stake_pool.to_bytes(); @@ -171,14 +154,14 @@ impl Processor { invoke_signed( &ix, - &[stake_account, reserved, authority, stake_program_info], + &[stake_account, clock, authority, stake_program_info], signers, ) } /// Issue a spl_token `Burn` instruction. #[allow(clippy::too_many_arguments)] - pub fn token_burn<'a>( + fn token_burn<'a>( stake_pool: &Pubkey, token_program: AccountInfo<'a>, burn_account: AccountInfo<'a>, @@ -210,7 +193,7 @@ impl Processor { /// Issue a spl_token `MintTo` instruction. #[allow(clippy::too_many_arguments)] - pub fn token_mint_to<'a>( + fn token_mint_to<'a>( stake_pool: &Pubkey, token_program: AccountInfo<'a>, mint: AccountInfo<'a>, @@ -237,7 +220,7 @@ impl Processor { } /// Processes `Initialize` instruction. - pub fn process_initialize( + fn process_initialize( program_id: &Pubkey, accounts: &[AccountInfo], fee: Fee, @@ -344,7 +327,7 @@ impl Processor { } /// Processes `CreateValidatorStakeAccount` instruction. - pub fn process_create_validator_stake_account( + fn process_create_validator_stake_account( program_id: &Pubkey, accounts: &[AccountInfo], ) -> ProgramResult { @@ -444,7 +427,7 @@ impl Processor { } /// Processes `AddValidatorToPool` instruction. - pub fn process_add_validator_to_pool( + fn process_add_validator_to_pool( program_id: &Pubkey, accounts: &[AccountInfo], ) -> ProgramResult { @@ -546,7 +529,6 @@ impl Processor { // Check if stake is warmed up Self::check_stake_activation(stake_account_info, clock, stake_history)?; - // Add validator to the list and save validator_list.validators.push(ValidatorStakeInfo { vote_account, balance: stake_lamports, @@ -554,9 +536,7 @@ impl Processor { }); validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; - // Save amounts to the stake pool state stake_pool.pool_total += token_amount; - // Only update stake total if the last state update epoch is current stake_pool.stake_total += stake_lamports; stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; @@ -564,7 +544,7 @@ impl Processor { } /// Processes `RemoveValidatorFromPool` instruction. - pub fn process_remove_validator_from_pool( + fn process_remove_validator_from_pool( program_id: &Pubkey, accounts: &[AccountInfo], ) -> ProgramResult { @@ -655,15 +635,12 @@ impl Processor { token_amount, )?; - // Remove validator from the list and save validator_list .validators .retain(|item| item.vote_account != vote_account); validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; - // Save amounts to the stake pool state stake_pool.pool_total -= token_amount; - // Only update stake total if the last state update epoch is current stake_pool.stake_total -= stake_lamports; stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; @@ -671,7 +648,7 @@ impl Processor { } /// Processes `UpdateValidatorListBalance` instruction. - pub fn process_update_validator_list_balance( + fn process_update_validator_list_balance( _program_id: &Pubkey, accounts: &[AccountInfo], ) -> ProgramResult { @@ -720,7 +697,7 @@ impl Processor { } /// Processes `UpdateStakePoolBalance` instruction. - pub fn process_update_stake_pool_balance( + fn process_update_stake_pool_balance( _program_id: &Pubkey, accounts: &[AccountInfo], ) -> ProgramResult { @@ -761,7 +738,8 @@ impl Processor { } /// Check stake activation status - pub fn check_stake_activation( + #[allow(clippy::unnecessary_wraps)] + fn check_stake_activation( _stake_info: &AccountInfo, _clock: &Clock, _stake_history: &StakeHistory, @@ -790,7 +768,7 @@ impl Processor { } /// Processes [Deposit](enum.Instruction.html). - pub fn process_deposit(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { + fn process_deposit(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; let validator_list_info = next_account_info(account_info_iter)?; @@ -931,7 +909,7 @@ impl Processor { } /// Processes [Withdraw](enum.Instruction.html). - pub fn process_withdraw( + fn process_withdraw( program_id: &Pubkey, pool_amount: u64, accounts: &[AccountInfo], @@ -1046,7 +1024,7 @@ impl Processor { } /// Processes [SetOwner](enum.Instruction.html). - pub fn process_set_owner(_program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { + fn process_set_owner(_program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; let owner_info = next_account_info(account_info_iter)?; diff --git a/program/src/state.rs b/program/src/state.rs index 5743c944..7fcfdca8 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -1,7 +1,7 @@ //! State transition types use { - crate::{error::StakePoolError, instruction::Fee, processor::Processor}, + crate::{error::StakePoolError, instruction::Fee}, borsh::{BorshDeserialize, BorshSchema, BorshSerialize}, solana_program::{account_info::AccountInfo, program_error::ProgramError, pubkey::Pubkey}, spl_math::checked_ceil_div::CheckedCeilDiv, @@ -99,17 +99,38 @@ impl StakePool { .ok() } + /// Checks withdraw or deposit authority + fn check_authority( + authority: &Pubkey, + program_id: &Pubkey, + stake_pool_address: &Pubkey, + seed: &[u8], + bump_seed: u8, + ) -> Result<(), ProgramError> { + if *authority + != crate::create_pool_authority_address( + program_id, + stake_pool_address, + seed, + bump_seed, + )? + { + return Err(StakePoolError::InvalidProgramAddress.into()); + } + Ok(()) + } + /// Checks withdraw authority pub fn check_authority_withdraw( &self, - authority_to_check: &Pubkey, + withdraw_authority: &Pubkey, program_id: &Pubkey, - stake_pool_key: &Pubkey, + stake_pool_address: &Pubkey, ) -> Result<(), ProgramError> { - Processor::check_authority( - authority_to_check, + Self::check_authority( + withdraw_authority, program_id, - stake_pool_key, + stake_pool_address, crate::AUTHORITY_WITHDRAW, self.withdraw_bump_seed, ) @@ -117,14 +138,14 @@ impl StakePool { /// Checks deposit authority pub fn check_authority_deposit( &self, - authority_to_check: &Pubkey, + deposit_authority: &Pubkey, program_id: &Pubkey, - stake_pool_key: &Pubkey, + stake_pool_address: &Pubkey, ) -> Result<(), ProgramError> { - Processor::check_authority( - authority_to_check, + Self::check_authority( + deposit_authority, program_id, - stake_pool_key, + stake_pool_address, crate::AUTHORITY_DEPOSIT, self.deposit_bump_seed, ) @@ -182,7 +203,7 @@ pub struct ValidatorStakeInfo { impl ValidatorList { /// Create an empty instance containing space for `max_validators` - pub fn new_with_max_validators(max_validators: u32) -> Self { + pub fn new(max_validators: u32) -> Self { Self { account_type: AccountType::ValidatorList, max_validators, @@ -239,8 +260,7 @@ mod test { #[test] fn test_state_packing() { let max_validators = 10_000; - let size = get_instance_packed_len(&ValidatorList::new_with_max_validators(max_validators)) - .unwrap(); + let size = get_instance_packed_len(&ValidatorList::new(max_validators)).unwrap(); // Not initialized let stake_list = ValidatorList { account_type: AccountType::Uninitialized, @@ -297,7 +317,7 @@ mod test { proptest! { #[test] fn stake_list_size_calculation(test_amount in 0..=100_000_u32) { - let validators = ValidatorList::new_with_max_validators(test_amount); + let validators = ValidatorList::new(test_amount); let size = get_instance_packed_len(&validators).unwrap(); assert_eq!(ValidatorList::calculate_max_validators(size), test_amount as usize); assert_eq!(ValidatorList::calculate_max_validators(size.saturating_add(1)), test_amount as usize); diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index df282a4a..6fc860a4 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -177,10 +177,8 @@ pub async fn create_stake_pool( ) -> Result<(), TransportError> { let rent = banks_client.get_rent().await.unwrap(); let rent_stake_pool = rent.minimum_balance(get_packed_len::()); - let validator_list_size = get_instance_packed_len( - &state::ValidatorList::new_with_max_validators(max_validators), - ) - .unwrap(); + let validator_list_size = + get_instance_packed_len(&state::ValidatorList::new(max_validators)).unwrap(); let rent_validator_list = rent.minimum_balance(validator_list_size); let mut transaction = Transaction::new_with_payer( diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index fe503d0e..02909957 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -179,9 +179,9 @@ async fn test_initialize_stake_pool_with_wrong_max_validators() { let rent = banks_client.get_rent().await.unwrap(); let rent_stake_pool = rent.minimum_balance(get_packed_len::()); - let validator_list_size = get_instance_packed_len( - &state::ValidatorList::new_with_max_validators(stake_pool_accounts.max_validators - 1), - ) + let validator_list_size = get_instance_packed_len(&state::ValidatorList::new( + stake_pool_accounts.max_validators - 1, + )) .unwrap(); let rent_validator_list = rent.minimum_balance(validator_list_size); @@ -333,9 +333,9 @@ async fn test_initialize_stake_pool_with_wrong_token_program_id() { banks_client.process_transaction(transaction).await.unwrap(); let rent_stake_pool = rent.minimum_balance(get_packed_len::()); - let validator_list_size = get_instance_packed_len( - &state::ValidatorList::new_with_max_validators(stake_pool_accounts.max_validators), - ) + let validator_list_size = get_instance_packed_len(&state::ValidatorList::new( + stake_pool_accounts.max_validators, + )) .unwrap(); let rent_validator_list = rent.minimum_balance(validator_list_size); @@ -499,9 +499,9 @@ async fn test_initialize_stake_pool_with_not_rent_exempt_pool() { .await; let rent = banks_client.get_rent().await.unwrap(); - let validator_list_size = get_instance_packed_len( - &state::ValidatorList::new_with_max_validators(stake_pool_accounts.max_validators), - ) + let validator_list_size = get_instance_packed_len(&state::ValidatorList::new( + stake_pool_accounts.max_validators, + )) .unwrap(); let rent_validator_list = rent.minimum_balance(validator_list_size); @@ -572,9 +572,9 @@ async fn test_initialize_stake_pool_with_not_rent_exempt_validator_list() { let rent = banks_client.get_rent().await.unwrap(); let rent_stake_pool = rent.minimum_balance(get_packed_len::()); - let validator_list_size = get_instance_packed_len( - &state::ValidatorList::new_with_max_validators(stake_pool_accounts.max_validators), - ) + let validator_list_size = get_instance_packed_len(&state::ValidatorList::new( + stake_pool_accounts.max_validators, + )) .unwrap(); let mut transaction = Transaction::new_with_payer( @@ -646,9 +646,9 @@ async fn test_initialize_stake_pool_without_owner_signature() { let rent = banks_client.get_rent().await.unwrap(); let rent_stake_pool = rent.minimum_balance(get_packed_len::()); - let validator_list_size = get_instance_packed_len( - &state::ValidatorList::new_with_max_validators(stake_pool_accounts.max_validators), - ) + let validator_list_size = get_instance_packed_len(&state::ValidatorList::new( + stake_pool_accounts.max_validators, + )) .unwrap(); let rent_validator_list = rent.minimum_balance(validator_list_size); From 45a29a98db2f60d44b8a067621a968a77d567911 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Wed, 31 Mar 2021 22:24:35 -0700 Subject: [PATCH 0075/1076] Reboot program address derivation helpers --- clients/cli/src/client.rs | 6 +- clients/cli/src/main.rs | 176 +++++++++++++++-------------------- program/src/lib.rs | 49 +++++----- program/src/processor.rs | 9 +- program/src/state.rs | 33 ++++--- program/tests/helpers/mod.rs | 7 +- program/tests/vsa_create.rs | 25 ++--- 7 files changed, 135 insertions(+), 170 deletions(-) diff --git a/clients/cli/src/client.rs b/clients/cli/src/client.rs index 011194c1..adc45bd1 100644 --- a/clients/cli/src/client.rs +++ b/clients/cli/src/client.rs @@ -79,9 +79,9 @@ pub(crate) fn get_stake_state( Ok(stake_state) } -pub(crate) fn get_stake_accounts_by_withdrawer( +pub(crate) fn get_stake_accounts_by_withdraw_authority( rpc_client: &RpcClient, - withdrawer: &Pubkey, + withdraw_authority: &Pubkey, ) -> Result, ClientError> { rpc_client .get_program_accounts_with_config( @@ -89,7 +89,7 @@ pub(crate) fn get_stake_accounts_by_withdrawer( RpcProgramAccountsConfig { filters: Some(vec![RpcFilterType::Memcmp(Memcmp { offset: 44, // 44 is Withdrawer authority offset in stake account stake - bytes: MemcmpEncodedBytes::Binary(format!("{}", withdrawer)), + bytes: MemcmpEncodedBytes::Binary(format!("{}", withdraw_authority)), encoding: None, })]), account_config: RpcAccountInfoConfig { diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 6e8d9a23..b17077a9 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -28,10 +28,10 @@ use { spl_stake_pool::{ self, borsh::get_instance_packed_len, - create_pool_authority_address, find_authority_bump_seed, find_stake_address_for_validator, + find_deposit_authority_program_address, find_stake_program_address, + find_withdraw_authority_program_address, stake_program::{self, StakeAuthorize, StakeState}, state::{StakePool, ValidatorList}, - AUTHORITY_DEPOSIT, AUTHORITY_WITHDRAW, }, std::process::exit, }; @@ -133,11 +133,8 @@ fn command_create_pool( let default_decimals = spl_token::native_mint::DECIMALS; // Calculate withdraw authority used for minting pool tokens - let (withdraw_authority, _) = find_authority_bump_seed( - &spl_stake_pool::id(), - &pool_account.pubkey(), - AUTHORITY_WITHDRAW, - ); + let (withdraw_authority, _) = + find_withdraw_authority_program_address(&spl_stake_pool::id(), &pool_account.pubkey()); if config.verbose { println!("Stake pool withdraw authority {}", withdraw_authority); @@ -227,9 +224,13 @@ fn command_create_pool( Ok(()) } -fn command_vsa_create(config: &Config, pool: &Pubkey, vote_account: &Pubkey) -> CommandResult { +fn command_vsa_create( + config: &Config, + stake_pool_address: &Pubkey, + vote_account: &Pubkey, +) -> CommandResult { let (stake_account, _) = - find_stake_address_for_validator(&spl_stake_pool::id(), &vote_account, &pool); + find_stake_program_address(&spl_stake_pool::id(), &vote_account, &stake_pool_address); println!("Creating stake account {}", stake_account); @@ -238,7 +239,7 @@ fn command_vsa_create(config: &Config, pool: &Pubkey, vote_account: &Pubkey) -> // Create new validator stake account address spl_stake_pool::instruction::create_validator_stake_account( &spl_stake_pool::id(), - &pool, + &stake_pool_address, &config.owner.pubkey(), &config.fee_payer.pubkey(), &stake_account, @@ -260,7 +261,7 @@ fn command_vsa_create(config: &Config, pool: &Pubkey, vote_account: &Pubkey) -> fn command_vsa_add( config: &Config, - pool: &Pubkey, + stake_pool_address: &Pubkey, stake: &Pubkey, token_receiver: &Option, ) -> CommandResult { @@ -269,10 +270,10 @@ fn command_vsa_add( } if !config.no_update { - command_update(config, pool)?; + command_update(config, stake_pool_address)?; } - let stake_pool = get_stake_pool(&config.rpc_client, pool)?; + let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; let mut total_rent_free_balances: u64 = 0; @@ -295,20 +296,11 @@ fn command_vsa_add( )?; // Calculate Deposit and Withdraw stake pool authorities - let pool_deposit_authority: Pubkey = create_pool_authority_address( - &spl_stake_pool::id(), - pool, - AUTHORITY_DEPOSIT, - stake_pool.deposit_bump_seed, - ) - .unwrap(); - let pool_withdraw_authority: Pubkey = create_pool_authority_address( - &spl_stake_pool::id(), - pool, - AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, - ) - .unwrap(); + let pool_deposit_authority = + find_deposit_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; + + let pool_withdraw_authority = + find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; instructions.extend(vec![ // Set Withdrawer on stake account to Deposit authority of the stake pool @@ -328,7 +320,7 @@ fn command_vsa_add( // Add validator stake account to the pool spl_stake_pool::instruction::add_validator_to_pool( &spl_stake_pool::id(), - &pool, + &stake_pool_address, &config.owner.pubkey(), &pool_deposit_authority, &pool_withdraw_authority, @@ -356,23 +348,18 @@ fn command_vsa_add( fn command_vsa_remove( config: &Config, - pool: &Pubkey, + stake_pool_address: &Pubkey, stake: &Pubkey, withdraw_from: &Pubkey, new_authority: &Option, ) -> CommandResult { if !config.no_update { - command_update(config, pool)?; + command_update(config, stake_pool_address)?; } - let stake_pool = get_stake_pool(&config.rpc_client, pool)?; - let pool_withdraw_authority: Pubkey = create_pool_authority_address( - &spl_stake_pool::id(), - pool, - AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, - ) - .unwrap(); + let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; + let pool_withdraw_authority = + find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; let owner_pubkey = config.owner.pubkey(); let new_authority = new_authority.as_ref().unwrap_or(&owner_pubkey); @@ -409,7 +396,7 @@ fn command_vsa_remove( // Create new validator stake account address spl_stake_pool::instruction::remove_validator_from_pool( &spl_stake_pool::id(), - &pool, + &stake_pool_address, &config.owner.pubkey(), &pool_withdraw_authority, &new_authority, @@ -482,21 +469,21 @@ where fn command_deposit( config: &Config, - pool: &Pubkey, + stake_pool_address: &Pubkey, stake: &Pubkey, token_receiver: &Option, ) -> CommandResult { if !config.no_update { - command_update(config, pool)?; + command_update(config, stake_pool_address)?; } - let stake_pool = get_stake_pool(&config.rpc_client, pool)?; + let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; let stake_state = get_stake_state(&config.rpc_client, &stake)?; if config.verbose { println!("Depositing stake account {:?}", stake_state); } - let vote_account: Pubkey = match stake_state { + let vote_account = match stake_state { StakeState::Stake(_, stake) => Ok(stake.delegation.voter_pubkey), _ => Err("Wrong stake account state, must be delegated to validator"), }?; @@ -509,7 +496,7 @@ fn command_deposit( // Calculate validator stake account address linked to the pool let (validator_stake_account, _) = - find_stake_address_for_validator(&spl_stake_pool::id(), &vote_account, pool); + find_stake_program_address(&spl_stake_pool::id(), &vote_account, stake_pool_address); let validator_stake_state = get_stake_state(&config.rpc_client, &validator_stake_account)?; println!("Depositing into stake account {}", validator_stake_account); @@ -538,20 +525,11 @@ fn command_deposit( )?; // Calculate Deposit and Withdraw stake pool authorities - let pool_deposit_authority: Pubkey = create_pool_authority_address( - &spl_stake_pool::id(), - pool, - AUTHORITY_DEPOSIT, - stake_pool.deposit_bump_seed, - ) - .unwrap(); - let pool_withdraw_authority: Pubkey = create_pool_authority_address( - &spl_stake_pool::id(), - pool, - AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, - ) - .unwrap(); + let pool_deposit_authority = + find_deposit_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; + + let pool_withdraw_authority = + find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; instructions.extend(vec![ // Set Withdrawer on stake account to Deposit authority of the stake pool @@ -571,7 +549,7 @@ fn command_deposit( // Add stake account to the pool spl_stake_pool::instruction::deposit( &spl_stake_pool::id(), - &pool, + &stake_pool_address, &stake_pool.validator_list, &pool_deposit_authority, &pool_withdraw_authority, @@ -598,8 +576,8 @@ fn command_deposit( Ok(()) } -fn command_list(config: &Config, pool: &Pubkey) -> CommandResult { - let stake_pool = get_stake_pool(&config.rpc_client, pool)?; +fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { + let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; if config.verbose { println!("Current validator list"); @@ -612,15 +590,11 @@ fn command_list(config: &Config, pool: &Pubkey) -> CommandResult { } } - let pool_withdraw_authority: Pubkey = create_pool_authority_address( - &spl_stake_pool::id(), - pool, - AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, - ) - .unwrap(); + let pool_withdraw_authority = + find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; - let accounts = get_stake_accounts_by_withdrawer(&config.rpc_client, &pool_withdraw_authority)?; + let accounts = + get_stake_accounts_by_withdraw_authority(&config.rpc_client, &pool_withdraw_authority)?; if accounts.is_empty() { return Err("No accounts found.".to_string().into()); } @@ -640,8 +614,8 @@ fn command_list(config: &Config, pool: &Pubkey) -> CommandResult { Ok(()) } -fn command_update(config: &Config, pool: &Pubkey) -> CommandResult { - let stake_pool = get_stake_pool(&config.rpc_client, pool)?; +fn command_update(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { + let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?; let epoch_info = config.rpc_client.get_epoch_info()?; @@ -652,10 +626,10 @@ fn command_update(config: &Config, pool: &Pubkey) -> CommandResult { if item.last_update_epoch >= epoch_info.epoch { None } else { - let (stake_account, _) = find_stake_address_for_validator( + let (stake_account, _) = find_stake_program_address( &spl_stake_pool::id(), &item.vote_account, - &pool, + &stake_pool_address, ); Some(stake_account) } @@ -679,7 +653,7 @@ fn command_update(config: &Config, pool: &Pubkey) -> CommandResult { println!("Updating stake pool..."); instructions.push(spl_stake_pool::instruction::update_stake_pool_balance( &spl_stake_pool::id(), - pool, + stake_pool_address, &stake_pool.validator_list, )?); @@ -706,7 +680,8 @@ fn prepare_withdraw_accounts( pool_withdraw_authority: &Pubkey, pool_amount: u64, ) -> Result, Error> { - let mut accounts = get_stake_accounts_by_withdrawer(rpc_client, &pool_withdraw_authority)?; + let mut accounts = + get_stake_accounts_by_withdraw_authority(rpc_client, &pool_withdraw_authority)?; if accounts.is_empty() { return Err("No accounts found.".to_string().into()); } @@ -756,26 +731,21 @@ fn prepare_withdraw_accounts( fn command_withdraw( config: &Config, - pool: &Pubkey, + stake_pool_address: &Pubkey, pool_amount: f64, withdraw_from: &Pubkey, stake_receiver_param: &Option, ) -> CommandResult { if !config.no_update { - command_update(config, pool)?; + command_update(config, stake_pool_address)?; } - let stake_pool = get_stake_pool(&config.rpc_client, pool)?; + let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; let pool_mint = get_token_mint(&config.rpc_client, &stake_pool.pool_mint)?; let pool_amount = spl_token::ui_amount_to_amount(pool_amount, pool_mint.decimals); - let pool_withdraw_authority: Pubkey = create_pool_authority_address( - &spl_stake_pool::id(), - pool, - AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, - ) - .unwrap(); + let pool_withdraw_authority = + find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; // Check withdraw_from account type let token_account = @@ -866,7 +836,7 @@ fn command_withdraw( instructions.push(spl_stake_pool::instruction::withdraw( &spl_stake_pool::id(), - &pool, + &stake_pool_address, &stake_pool.validator_list, &pool_withdraw_authority, &withdraw_account.address, @@ -895,11 +865,11 @@ fn command_withdraw( fn command_set_owner( config: &Config, - pool: &Pubkey, + stake_pool_address: &Pubkey, new_owner: &Option, new_fee_receiver: &Option, ) -> CommandResult { - let stake_pool = get_stake_pool(&config.rpc_client, pool)?; + let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; // If new accounts are missing in the arguments use the old ones let new_owner = match new_owner { @@ -924,7 +894,7 @@ fn command_set_owner( let mut transaction = Transaction::new_with_payer( &[spl_stake_pool::instruction::set_owner( &spl_stake_pool::id(), - &pool, + &stake_pool_address, &config.owner.pubkey(), &new_owner, &new_fee_receiver, @@ -1327,20 +1297,20 @@ fn main() { ) } ("create-validator-stake", Some(arg_matches)) => { - let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); - let vote_account: Pubkey = pubkey_of(arg_matches, "vote_account").unwrap(); + let pool_account = pubkey_of(arg_matches, "pool").unwrap(); + let vote_account = pubkey_of(arg_matches, "vote_account").unwrap(); command_vsa_create(&config, &pool_account, &vote_account) } ("add-validator", Some(arg_matches)) => { - let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); - let stake_account: Pubkey = pubkey_of(arg_matches, "stake_account").unwrap(); + let pool_account = pubkey_of(arg_matches, "pool").unwrap(); + let stake_account = pubkey_of(arg_matches, "stake_account").unwrap(); let token_receiver: Option = pubkey_of(arg_matches, "token_receiver"); command_vsa_add(&config, &pool_account, &stake_account, &token_receiver) } ("remove-validator", Some(arg_matches)) => { - let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); - let stake_account: Pubkey = pubkey_of(arg_matches, "stake_account").unwrap(); - let withdraw_from: Pubkey = pubkey_of(arg_matches, "withdraw_from").unwrap(); + let pool_account = pubkey_of(arg_matches, "pool").unwrap(); + let stake_account = pubkey_of(arg_matches, "stake_account").unwrap(); + let withdraw_from = pubkey_of(arg_matches, "withdraw_from").unwrap(); let new_authority: Option = pubkey_of(arg_matches, "new_authority"); command_vsa_remove( &config, @@ -1351,22 +1321,22 @@ fn main() { ) } ("deposit", Some(arg_matches)) => { - let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); - let stake_account: Pubkey = pubkey_of(arg_matches, "stake_account").unwrap(); + let pool_account = pubkey_of(arg_matches, "pool").unwrap(); + let stake_account = pubkey_of(arg_matches, "stake_account").unwrap(); let token_receiver: Option = pubkey_of(arg_matches, "token_receiver"); command_deposit(&config, &pool_account, &stake_account, &token_receiver) } ("list", Some(arg_matches)) => { - let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); + let pool_account = pubkey_of(arg_matches, "pool").unwrap(); command_list(&config, &pool_account) } ("update", Some(arg_matches)) => { - let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); + let pool_account = pubkey_of(arg_matches, "pool").unwrap(); command_update(&config, &pool_account) } ("withdraw", Some(arg_matches)) => { - let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); - let withdraw_from: Pubkey = pubkey_of(arg_matches, "withdraw_from").unwrap(); + let pool_account = pubkey_of(arg_matches, "pool").unwrap(); + let withdraw_from = pubkey_of(arg_matches, "withdraw_from").unwrap(); let pool_amount = value_t_or_exit!(arg_matches, "amount", f64); let stake_receiver: Option = pubkey_of(arg_matches, "stake_receiver"); command_withdraw( @@ -1378,7 +1348,7 @@ fn main() { ) } ("set-owner", Some(arg_matches)) => { - let pool_account: Pubkey = pubkey_of(arg_matches, "pool").unwrap(); + let pool_account = pubkey_of(arg_matches, "pool").unwrap(); let new_owner: Option = pubkey_of(arg_matches, "new_owner"); let new_fee_receiver: Option = pubkey_of(arg_matches, "new_fee_receiver"); command_set_owner(&config, &pool_account, &new_owner, &new_fee_receiver) diff --git a/program/src/lib.rs b/program/src/lib.rs index ee484f03..964f263e 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -1,6 +1,6 @@ #![deny(missing_docs)] -//! A program for creating pools of Solana stakes managed by a Stake-o-Matic +//! A program for creating and managing pools of stake pub mod borsh; pub mod error; @@ -14,44 +14,47 @@ pub mod entrypoint; // Export current sdk types for downstream users building with a different sdk version pub use solana_program; -use solana_program::{program_error::ProgramError, pubkey::Pubkey}; +use solana_program::pubkey::Pubkey; /// Seed for deposit authority seed -pub const AUTHORITY_DEPOSIT: &[u8] = b"deposit"; +const AUTHORITY_DEPOSIT: &[u8] = b"deposit"; /// Seed for withdraw authority seed -pub const AUTHORITY_WITHDRAW: &[u8] = b"withdraw"; +const AUTHORITY_WITHDRAW: &[u8] = b"withdraw"; -/// Calculates the authority address -pub fn create_pool_authority_address( +/// Generates the deposit authority program address for the stake pool +pub fn find_deposit_authority_program_address( program_id: &Pubkey, - stake_pool: &Pubkey, - authority: &[u8], - bump_seed: u8, -) -> Result { - Pubkey::create_program_address( - &[&stake_pool.to_bytes()[..32], authority, &[bump_seed]], + stake_pool_address: &Pubkey, +) -> (Pubkey, u8) { + Pubkey::find_program_address( + &[&stake_pool_address.to_bytes()[..32], AUTHORITY_DEPOSIT], program_id, ) - .map_err(|_| crate::error::StakePoolError::InvalidProgramAddress.into()) } -/// Generates seed bump for stake pool authorities -pub fn find_authority_bump_seed( +/// Generates the withdraw authority program address for the stake pool +pub fn find_withdraw_authority_program_address( program_id: &Pubkey, - stake_pool: &Pubkey, - authority: &[u8], + stake_pool_address: &Pubkey, ) -> (Pubkey, u8) { - Pubkey::find_program_address(&[&stake_pool.to_bytes()[..32], authority], program_id) + Pubkey::find_program_address( + &[&stake_pool_address.to_bytes()[..32], AUTHORITY_WITHDRAW], + program_id, + ) } -/// Generates stake account address for the validator -pub fn find_stake_address_for_validator( + +/// Generates the stake program address for a validator's vote account +pub fn find_stake_program_address( program_id: &Pubkey, - validator: &Pubkey, - stake_pool: &Pubkey, + vote_account_address: &Pubkey, + stake_pool_address: &Pubkey, ) -> (Pubkey, u8) { Pubkey::find_program_address( - &[&validator.to_bytes()[..32], &stake_pool.to_bytes()[..32]], + &[ + &vote_account_address.to_bytes()[..32], + &stake_pool_address.to_bytes()[..32], + ], program_id, ) } diff --git a/program/src/processor.rs b/program/src/processor.rs index 16cc5fd8..c3d036fa 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -4,7 +4,6 @@ use { crate::{ borsh::try_from_slice_unchecked, error::StakePoolError, - find_authority_bump_seed, find_stake_address_for_validator, instruction::{Fee, StakePoolInstruction}, stake_program, state::{AccountType, StakePool, ValidatorList, ValidatorStakeInfo}, @@ -56,7 +55,7 @@ impl Processor { ) -> bool { // Check stake account address validity let (stake_address, _) = - find_stake_address_for_validator(&program_id, &vote_account, &stake_pool_info.key); + crate::find_stake_program_address(&program_id, &vote_account, &stake_pool_info.key); stake_address == *stake_account_info.key } @@ -295,9 +294,9 @@ impl Processor { } let (_, deposit_bump_seed) = - find_authority_bump_seed(program_id, stake_pool_info.key, AUTHORITY_DEPOSIT); + crate::find_deposit_authority_program_address(program_id, stake_pool_info.key); let (withdraw_authority_key, withdraw_bump_seed) = - find_authority_bump_seed(program_id, stake_pool_info.key, AUTHORITY_WITHDRAW); + crate::find_withdraw_authority_program_address(program_id, stake_pool_info.key); let pool_mint = Mint::unpack_from_slice(&pool_mint_info.data.borrow())?; @@ -361,7 +360,7 @@ impl Processor { return Err(ProgramError::IncorrectProgramId); } - let (stake_address, bump_seed) = find_stake_address_for_validator( + let (stake_address, bump_seed) = crate::find_stake_program_address( &program_id, &validator_info.key, &stake_pool_info.key, diff --git a/program/src/state.rs b/program/src/state.rs index 7fcfdca8..4c9966fe 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -99,29 +99,32 @@ impl StakePool { .ok() } - /// Checks withdraw or deposit authority + /// Checks that the withdraw or deposit authority is valid fn check_authority( - authority: &Pubkey, + authority_address: &Pubkey, program_id: &Pubkey, stake_pool_address: &Pubkey, - seed: &[u8], + authority_seed: &[u8], bump_seed: u8, ) -> Result<(), ProgramError> { - if *authority - != crate::create_pool_authority_address( + if *authority_address + == Pubkey::create_program_address( + &[ + &stake_pool_address.to_bytes()[..32], + authority_seed, + &[bump_seed], + ], program_id, - stake_pool_address, - seed, - bump_seed, )? { - return Err(StakePoolError::InvalidProgramAddress.into()); + Ok(()) + } else { + Err(StakePoolError::InvalidProgramAddress.into()) } - Ok(()) } - /// Checks withdraw authority - pub fn check_authority_withdraw( + /// Checks that the withdraw authority is valid + pub(crate) fn check_authority_withdraw( &self, withdraw_authority: &Pubkey, program_id: &Pubkey, @@ -135,8 +138,8 @@ impl StakePool { self.withdraw_bump_seed, ) } - /// Checks deposit authority - pub fn check_authority_deposit( + /// Checks that the deposit authority is valid + pub(crate) fn check_authority_deposit( &self, deposit_authority: &Pubkey, program_id: &Pubkey, @@ -152,7 +155,7 @@ impl StakePool { } /// Check owner validity and signature - pub fn check_owner(&self, owner_info: &AccountInfo) -> Result<(), ProgramError> { + pub(crate) fn check_owner(&self, owner_info: &AccountInfo) -> Result<(), ProgramError> { if *owner_info.key != self.owner { return Err(StakePoolError::WrongOwner.into()); } diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 6fc860a4..807e7620 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -13,8 +13,8 @@ use { }, solana_vote_program::{self, vote_state::VoteState}, spl_stake_pool::{ - borsh::get_instance_packed_len, find_stake_address_for_validator, id, instruction, - processor, stake_program, state, + borsh::get_instance_packed_len, find_stake_program_address, id, instruction, processor, + stake_program, state, }, }; @@ -376,8 +376,7 @@ pub struct ValidatorStakeAccount { impl ValidatorStakeAccount { pub fn new_with_target_authority(authority: &Pubkey, stake_pool: &Pubkey) -> Self { let validator = Keypair::new(); - let (stake_account, _) = - find_stake_address_for_validator(&id(), &validator.pubkey(), stake_pool); + let (stake_account, _) = find_stake_program_address(&id(), &validator.pubkey(), stake_pool); ValidatorStakeAccount { stake_account, target_authority: *authority, diff --git a/program/tests/vsa_create.rs b/program/tests/vsa_create.rs index 16fe1cf1..aaa4e422 100644 --- a/program/tests/vsa_create.rs +++ b/program/tests/vsa_create.rs @@ -18,7 +18,7 @@ use { transaction::TransactionError, transport::TransportError, }, - spl_stake_pool::{error, find_stake_address_for_validator, id, instruction, stake_program}, + spl_stake_pool::{error, find_stake_program_address, id, instruction, stake_program}, }; #[tokio::test] @@ -33,7 +33,7 @@ async fn success_create_validator_stake_account() { let validator = Keypair::new(); create_vote(&mut banks_client, &payer, &recent_blockhash, &validator).await; - let (stake_account, _) = find_stake_address_for_validator( + let (stake_account, _) = find_stake_program_address( &id(), &validator.pubkey(), &stake_pool_accounts.stake_pool.pubkey(), @@ -81,11 +81,8 @@ async fn fail_create_validator_stake_account_on_non_vote_account() { let validator = Pubkey::new_unique(); - let (stake_account, _) = find_stake_address_for_validator( - &id(), - &validator, - &stake_pool_accounts.stake_pool.pubkey(), - ); + let (stake_account, _) = + find_stake_program_address(&id(), &validator, &stake_pool_accounts.stake_pool.pubkey()); let mut transaction = Transaction::new_with_payer( &[instruction::create_validator_stake_account( @@ -124,11 +121,8 @@ async fn fail_create_validator_stake_account_with_wrong_system_program() { let validator = Pubkey::new_unique(); - let (stake_account, _) = find_stake_address_for_validator( - &id(), - &validator, - &stake_pool_accounts.stake_pool.pubkey(), - ); + let (stake_account, _) = + find_stake_program_address(&id(), &validator, &stake_pool_accounts.stake_pool.pubkey()); let wrong_system_program = Pubkey::new_unique(); let accounts = vec![ AccountMeta::new_readonly(stake_pool_accounts.stake_pool.pubkey(), false), @@ -177,11 +171,8 @@ async fn fail_create_validator_stake_account_with_wrong_stake_program() { let validator = Pubkey::new_unique(); - let (stake_account, _) = find_stake_address_for_validator( - &id(), - &validator, - &stake_pool_accounts.stake_pool.pubkey(), - ); + let (stake_account, _) = + find_stake_program_address(&id(), &validator, &stake_pool_accounts.stake_pool.pubkey()); let wrong_stake_program = Pubkey::new_unique(); let accounts = vec![ AccountMeta::new_readonly(stake_pool_accounts.stake_pool.pubkey(), false), From 04cb6185d099c7893394308efffa89f3ddfbb6ae Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Wed, 31 Mar 2021 23:17:46 -0700 Subject: [PATCH 0076/1076] More variable renaming --- clients/cli/src/main.rs | 80 +++++++++++++++++++++++------------------ 1 file changed, 46 insertions(+), 34 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index b17077a9..82bb9caf 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -106,8 +106,8 @@ fn command_create_pool( pool_fee_account.pubkey() ); - let pool_account = Keypair::new(); - println!("Creating stake pool {}", pool_account.pubkey()); + let stake_pool_keypair = Keypair::new(); + println!("Creating stake pool {}", stake_pool_keypair.pubkey()); let validator_list = Keypair::new(); @@ -117,7 +117,7 @@ fn command_create_pool( let pool_fee_account_balance = config .rpc_client .get_minimum_balance_for_rent_exemption(spl_token::state::Account::LEN)?; - let pool_account_balance = config + let stake_pool_account_lamports = config .rpc_client .get_minimum_balance_for_rent_exemption(get_packed_len::())?; let empty_validator_list = ValidatorList::new(max_validators); @@ -127,14 +127,16 @@ fn command_create_pool( .get_minimum_balance_for_rent_exemption(validator_list_size)?; let total_rent_free_balances = mint_account_balance + pool_fee_account_balance - + pool_account_balance + + stake_pool_account_lamports + validator_list_balance; let default_decimals = spl_token::native_mint::DECIMALS; // Calculate withdraw authority used for minting pool tokens - let (withdraw_authority, _) = - find_withdraw_authority_program_address(&spl_stake_pool::id(), &pool_account.pubkey()); + let (withdraw_authority, _) = find_withdraw_authority_program_address( + &spl_stake_pool::id(), + &stake_pool_keypair.pubkey(), + ); if config.verbose { println!("Stake pool withdraw authority {}", withdraw_authority); @@ -161,8 +163,8 @@ fn command_create_pool( // Account for the stake pool system_instruction::create_account( &config.fee_payer.pubkey(), - &pool_account.pubkey(), - pool_account_balance, + &stake_pool_keypair.pubkey(), + stake_pool_account_lamports, get_packed_len::() as u64, &spl_stake_pool::id(), ), @@ -192,7 +194,7 @@ fn command_create_pool( // Initialize stake pool account spl_stake_pool::instruction::initialize( &spl_stake_pool::id(), - &pool_account.pubkey(), + &stake_pool_keypair.pubkey(), &config.owner.pubkey(), &validator_list.pubkey(), &mint_account.pubkey(), @@ -212,7 +214,7 @@ fn command_create_pool( )?; let mut signers = vec![ config.fee_payer.as_ref(), - &pool_account, + &stake_pool_keypair, &validator_list, &mint_account, &pool_fee_account, @@ -599,9 +601,9 @@ fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { return Err("No accounts found.".to_string().into()); } - let mut total_balance: u64 = 0; + let mut total_lamports: u64 = 0; for (pubkey, lamports, stake_state) in accounts { - total_balance += lamports; + total_lamports += lamports; println!( "Stake Account: {}\tVote Account: {}\t{}", pubkey, @@ -609,7 +611,7 @@ fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { Sol(lamports) ); } - println!("Total: {}", Sol(total_balance)); + println!("Total Stake: {}", Sol(total_lamports)); Ok(()) } @@ -638,11 +640,11 @@ fn command_update(config: &Config, stake_pool_address: &Pubkey) -> CommandResult let mut instructions: Vec = vec![]; - for chunk in accounts_to_update.chunks(MAX_ACCOUNTS_TO_UPDATE) { + for accounts_chunk in accounts_to_update.chunks(MAX_ACCOUNTS_TO_UPDATE) { instructions.push(spl_stake_pool::instruction::update_validator_list_balance( &spl_stake_pool::id(), &stake_pool.validator_list, - &chunk, + &accounts_chunk, )?); } @@ -912,6 +914,8 @@ fn command_set_owner( } fn main() { + solana_logger::setup_with_default("solana=info"); + let matches = App::new(crate_name!()) .about(crate_description!()) .version(crate_version!()) @@ -1280,8 +1284,6 @@ fn main() { } }; - solana_logger::setup_with_default("solana=info"); - let _ = match matches.subcommand() { ("create-pool", Some(arg_matches)) => { let numerator = value_t_or_exit!(arg_matches, "fee_numerator", u64); @@ -1297,61 +1299,71 @@ fn main() { ) } ("create-validator-stake", Some(arg_matches)) => { - let pool_account = pubkey_of(arg_matches, "pool").unwrap(); - let vote_account = pubkey_of(arg_matches, "vote_account").unwrap(); - command_vsa_create(&config, &pool_account, &vote_account) + let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); + let vote_account_address = pubkey_of(arg_matches, "vote_account_address").unwrap(); + command_vsa_create(&config, &stake_pool_address, &vote_account_address) } ("add-validator", Some(arg_matches)) => { - let pool_account = pubkey_of(arg_matches, "pool").unwrap(); + let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); let stake_account = pubkey_of(arg_matches, "stake_account").unwrap(); let token_receiver: Option = pubkey_of(arg_matches, "token_receiver"); - command_vsa_add(&config, &pool_account, &stake_account, &token_receiver) + command_vsa_add( + &config, + &stake_pool_address, + &stake_account, + &token_receiver, + ) } ("remove-validator", Some(arg_matches)) => { - let pool_account = pubkey_of(arg_matches, "pool").unwrap(); + let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); let stake_account = pubkey_of(arg_matches, "stake_account").unwrap(); let withdraw_from = pubkey_of(arg_matches, "withdraw_from").unwrap(); let new_authority: Option = pubkey_of(arg_matches, "new_authority"); command_vsa_remove( &config, - &pool_account, + &stake_pool_address, &stake_account, &withdraw_from, &new_authority, ) } ("deposit", Some(arg_matches)) => { - let pool_account = pubkey_of(arg_matches, "pool").unwrap(); + let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); let stake_account = pubkey_of(arg_matches, "stake_account").unwrap(); let token_receiver: Option = pubkey_of(arg_matches, "token_receiver"); - command_deposit(&config, &pool_account, &stake_account, &token_receiver) + command_deposit( + &config, + &stake_pool_address, + &stake_account, + &token_receiver, + ) } ("list", Some(arg_matches)) => { - let pool_account = pubkey_of(arg_matches, "pool").unwrap(); - command_list(&config, &pool_account) + let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); + command_list(&config, &stake_pool_address) } ("update", Some(arg_matches)) => { - let pool_account = pubkey_of(arg_matches, "pool").unwrap(); - command_update(&config, &pool_account) + let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); + command_update(&config, &stake_pool_address) } ("withdraw", Some(arg_matches)) => { - let pool_account = pubkey_of(arg_matches, "pool").unwrap(); + let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); let withdraw_from = pubkey_of(arg_matches, "withdraw_from").unwrap(); let pool_amount = value_t_or_exit!(arg_matches, "amount", f64); let stake_receiver: Option = pubkey_of(arg_matches, "stake_receiver"); command_withdraw( &config, - &pool_account, + &stake_pool_address, pool_amount, &withdraw_from, &stake_receiver, ) } ("set-owner", Some(arg_matches)) => { - let pool_account = pubkey_of(arg_matches, "pool").unwrap(); + let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); let new_owner: Option = pubkey_of(arg_matches, "new_owner"); let new_fee_receiver: Option = pubkey_of(arg_matches, "new_fee_receiver"); - command_set_owner(&config, &pool_account, &new_owner, &new_fee_receiver) + command_set_owner(&config, &stake_pool_address, &new_owner, &new_fee_receiver) } _ => unreachable!(), } From 052e72a97b3e05b416189438a0ce032d0d2b12b0 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 2 Apr 2021 10:56:12 +0200 Subject: [PATCH 0077/1076] stake-pool: Separate manager from owner (#1560) * stake-pool: Separate manager from owner * Add manager pubkey to stake pool * Differentiate manager functions from owner functions * Include a `set_manager` function to be used by the owner * Change the term `owner` to `authority` in the CLI for clarity * Rename manager -> staker and owner -> manager * Split staker, manager, and token owner in CLI * "Do not disturb the boss" --- clients/cli/src/main.rs | 205 +++++++++++++----- program/src/error.rs | 11 +- program/src/instruction.rs | 108 +++++---- program/src/processor.rs | 100 ++++++--- program/src/state.rs | 35 ++- program/tests/deposit.rs | 6 +- program/tests/helpers/mod.rs | 60 ++--- program/tests/initialize.rs | 39 ++-- .../tests/{set_owner.rs => set_manager.rs} | 64 +++--- program/tests/set_staker.rs | 176 +++++++++++++++ program/tests/vsa_add.rs | 30 +-- program/tests/vsa_create.rs | 27 ++- program/tests/vsa_remove.rs | 30 +-- program/tests/withdraw.rs | 4 +- 14 files changed, 634 insertions(+), 261 deletions(-) rename program/tests/{set_owner.rs => set_manager.rs} (76%) create mode 100644 program/tests/set_staker.rs diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 82bb9caf..f056c558 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -39,7 +39,9 @@ use { struct Config { rpc_client: RpcClient, verbose: bool, - owner: Box, + manager: Box, + staker: Box, + token_owner: Box, fee_payer: Box, dry_run: bool, no_update: bool, @@ -189,13 +191,14 @@ fn command_create_pool( &spl_token::id(), &pool_fee_account.pubkey(), &mint_account.pubkey(), - &config.owner.pubkey(), + &config.manager.pubkey(), )?, // Initialize stake pool account spl_stake_pool::instruction::initialize( &spl_stake_pool::id(), &stake_pool_keypair.pubkey(), - &config.owner.pubkey(), + &config.manager.pubkey(), + &config.staker.pubkey(), &validator_list.pubkey(), &mint_account.pubkey(), &pool_fee_account.pubkey(), @@ -218,7 +221,7 @@ fn command_create_pool( &validator_list, &mint_account, &pool_fee_account, - config.owner.as_ref(), + config.manager.as_ref(), ]; unique_signers!(signers); transaction.sign(&signers, recent_blockhash); @@ -242,7 +245,7 @@ fn command_vsa_create( spl_stake_pool::instruction::create_validator_stake_account( &spl_stake_pool::id(), &stake_pool_address, - &config.owner.pubkey(), + &config.staker.pubkey(), &config.fee_payer.pubkey(), &stake_account, &vote_account, @@ -254,7 +257,7 @@ fn command_vsa_create( let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; transaction.sign( - &[config.fee_payer.as_ref(), config.owner.as_ref()], + &[config.fee_payer.as_ref(), config.staker.as_ref()], recent_blockhash, ); send_transaction(&config, transaction)?; @@ -282,7 +285,7 @@ fn command_vsa_add( let token_receiver_account = Keypair::new(); let mut instructions: Vec = vec![]; - let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()]; + let mut signers = vec![config.fee_payer.as_ref(), config.staker.as_ref()]; // Create token account if not specified let token_receiver = unwrap_create_token_account( @@ -308,14 +311,14 @@ fn command_vsa_add( // Set Withdrawer on stake account to Deposit authority of the stake pool stake_program::authorize( &stake, - &config.owner.pubkey(), + &config.staker.pubkey(), &pool_deposit_authority, StakeAuthorize::Withdrawer, ), // Set Staker on stake account to Deposit authority of the stake pool stake_program::authorize( &stake, - &config.owner.pubkey(), + &config.staker.pubkey(), &pool_deposit_authority, StakeAuthorize::Staker, ), @@ -323,7 +326,7 @@ fn command_vsa_add( spl_stake_pool::instruction::add_validator_to_pool( &spl_stake_pool::id(), &stake_pool_address, - &config.owner.pubkey(), + &config.staker.pubkey(), &pool_deposit_authority, &pool_withdraw_authority, &stake_pool.validator_list, @@ -363,8 +366,8 @@ fn command_vsa_remove( let pool_withdraw_authority = find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; - let owner_pubkey = config.owner.pubkey(); - let new_authority = new_authority.as_ref().unwrap_or(&owner_pubkey); + let staker_pubkey = config.staker.pubkey(); + let new_authority = new_authority.as_ref().unwrap_or(&staker_pubkey); // Calculate amount of tokens to withdraw let stake_account = config.rpc_client.get_account(&stake)?; @@ -391,7 +394,7 @@ fn command_vsa_remove( &spl_token::id(), &withdraw_from, &pool_withdraw_authority, - &config.owner.pubkey(), + &config.token_owner.pubkey(), &[], tokens_to_withdraw, )?, @@ -399,7 +402,7 @@ fn command_vsa_remove( spl_stake_pool::instruction::remove_validator_from_pool( &spl_stake_pool::id(), &stake_pool_address, - &config.owner.pubkey(), + &config.staker.pubkey(), &pool_withdraw_authority, &new_authority, &stake_pool.validator_list, @@ -415,7 +418,7 @@ fn command_vsa_remove( let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; transaction.sign( - &[config.fee_payer.as_ref(), config.owner.as_ref()], + &[config.fee_payer.as_ref(), config.staker.as_ref()], recent_blockhash, ); send_transaction(&config, transaction)?; @@ -457,7 +460,7 @@ where &spl_token::id(), &keypair.pubkey(), mint, - &config.owner.pubkey(), + &config.token_owner.pubkey(), )?, ]); @@ -507,7 +510,7 @@ fn command_deposit( } let mut instructions: Vec = vec![]; - let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()]; + let mut signers = vec![config.fee_payer.as_ref(), config.staker.as_ref()]; let mut total_rent_free_balances: u64 = 0; @@ -537,14 +540,14 @@ fn command_deposit( // Set Withdrawer on stake account to Deposit authority of the stake pool stake_program::authorize( &stake, - &config.owner.pubkey(), + &config.staker.pubkey(), &pool_deposit_authority, StakeAuthorize::Withdrawer, ), // Set Staker on stake account to Deposit authority of the stake pool stake_program::authorize( &stake, - &config.owner.pubkey(), + &config.staker.pubkey(), &pool_deposit_authority, StakeAuthorize::Staker, ), @@ -558,7 +561,7 @@ fn command_deposit( &stake, &validator_stake_account, &token_receiver, - &stake_pool.owner_fee_account, + &stake_pool.manager_fee_account, &stake_pool.pool_mint, &spl_token::id(), )?, @@ -773,7 +776,7 @@ fn command_withdraw( // Construct transaction to withdraw from withdraw_accounts account list let mut instructions: Vec = vec![]; - let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()]; + let mut signers = vec![config.fee_payer.as_ref(), config.token_owner.as_ref()]; let stake_receiver_account = Keypair::new(); // Will be added to signers if creating new account instructions.push( @@ -782,7 +785,7 @@ fn command_withdraw( &spl_token::id(), &withdraw_from, &pool_withdraw_authority, - &config.owner.pubkey(), + &config.token_owner.pubkey(), &[], pool_amount, )?, @@ -843,7 +846,7 @@ fn command_withdraw( &pool_withdraw_authority, &withdraw_account.address, &stake_receiver.unwrap(), // Cannot be none at this point - &config.owner.pubkey(), + &config.staker.pubkey(), &withdraw_from, &stake_pool.pool_mint, &spl_token::id(), @@ -865,21 +868,21 @@ fn command_withdraw( Ok(()) } -fn command_set_owner( +fn command_set_manager( config: &Config, stake_pool_address: &Pubkey, - new_owner: &Option, + new_manager: &Option, new_fee_receiver: &Option, ) -> CommandResult { let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; // If new accounts are missing in the arguments use the old ones - let new_owner = match new_owner { - None => stake_pool.owner, + let new_manager = match new_manager { + None => stake_pool.manager, Some(value) => *value, }; let new_fee_receiver = match new_fee_receiver { - None => stake_pool.owner_fee_account, + None => stake_pool.manager_fee_account, Some(value) => { // Check for fee receiver being a valid token account and have to same mint as the stake pool let token_account = @@ -894,11 +897,11 @@ fn command_set_owner( }; let mut transaction = Transaction::new_with_payer( - &[spl_stake_pool::instruction::set_owner( + &[spl_stake_pool::instruction::set_manager( &spl_stake_pool::id(), &stake_pool_address, - &config.owner.pubkey(), - &new_owner, + &config.manager.pubkey(), + &new_manager, &new_fee_receiver, )?], Some(&config.fee_payer.pubkey()), @@ -906,7 +909,31 @@ fn command_set_owner( let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; - let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()]; + let mut signers = vec![config.fee_payer.as_ref(), config.manager.as_ref()]; + unique_signers!(signers); + transaction.sign(&signers, recent_blockhash); + send_transaction(&config, transaction)?; + Ok(()) +} + +fn command_set_staker( + config: &Config, + stake_pool_address: &Pubkey, + new_staker: &Pubkey, +) -> CommandResult { + let mut transaction = Transaction::new_with_payer( + &[spl_stake_pool::instruction::set_staker( + &spl_stake_pool::id(), + &stake_pool_address, + &config.manager.pubkey(), + &new_staker, + )?], + Some(&config.fee_payer.pubkey()), + ); + + let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; + let mut signers = vec![config.fee_payer.as_ref(), config.manager.as_ref()]; unique_signers!(signers); transaction.sign(&signers, recent_blockhash); send_transaction(&config, transaction)?; @@ -965,13 +992,37 @@ fn main() { .help("JSON RPC URL for the cluster. Default from the configuration file."), ) .arg( - Arg::with_name("owner") - .long("owner") + Arg::with_name("staker") + .long("staker") .value_name("KEYPAIR") .validator(is_keypair) .takes_value(true) .help( - "Specify the stake pool or stake account owner. \ + "Specify the stake pool staker. \ + This may be a keypair file, the ASK keyword. \ + Defaults to the client keypair.", + ), + ) + .arg( + Arg::with_name("manager") + .long("manager") + .value_name("KEYPAIR") + .validator(is_keypair) + .takes_value(true) + .help( + "Specify the stake pool manager. \ + This may be a keypair file, the ASK keyword. \ + Defaults to the client keypair.", + ), + ) + .arg( + Arg::with_name("token_owner") + .long("token-owner") + .value_name("KEYPAIR") + .validator(is_keypair) + .takes_value(true) + .help( + "Specify the owner of the pool token account. \ This may be a keypair file, the ASK keyword. \ Defaults to the client keypair.", ), @@ -1022,7 +1073,7 @@ fn main() { ) ) .subcommand(SubCommand::with_name("create-validator-stake") - .about("Create a new stake account to use with the pool. Must be signed by the pool owner.") + .about("Create a new stake account to use with the pool. Must be signed by the pool staker.") .arg( Arg::with_name("pool") .index(1) @@ -1043,7 +1094,7 @@ fn main() { ) ) .subcommand(SubCommand::with_name("add-validator") - .about("Add validator account to the stake pool. Must be signed by the pool owner.") + .about("Add validator account to the stake pool. Must be signed by the pool staker.") .arg( Arg::with_name("pool") .index(1) @@ -1073,7 +1124,7 @@ fn main() { ) ) .subcommand(SubCommand::with_name("remove-validator") - .about("Remove validator account from the stake pool. Must be signed by the pool owner.") + .about("Remove validator account from the stake pool. Must be signed by the pool staker.") .arg( Arg::with_name("pool") .index(1) @@ -1204,8 +1255,8 @@ fn main() { .help("Stake account to receive SOL from the stake pool. Defaults to a new stake account."), ) ) - .subcommand(SubCommand::with_name("set-owner") - .about("Changes owner or fee receiver account for the stake pool.") + .subcommand(SubCommand::with_name("set-manager") + .about("Change manager or fee receiver account for the stake pool. Must be signed by the current manager.") .arg( Arg::with_name("pool") .index(1) @@ -1216,12 +1267,12 @@ fn main() { .help("Stake pool address."), ) .arg( - Arg::with_name("new_owner") - .long("new-owner") + Arg::with_name("new_manager") + .long("new-manager") .validator(is_pubkey) .value_name("ADDRESS") .takes_value(true) - .help("Public key for the new stake pool owner."), + .help("Public key for the new stake pool manager."), ) .arg( Arg::with_name("new_fee_receiver") @@ -1232,12 +1283,32 @@ fn main() { .help("Public key for the new account to set as the stake pool fee receiver."), ) .group(ArgGroup::with_name("new_accounts") - .arg("new_owner") + .arg("new_manager") .arg("new_fee_receiver") .required(true) .multiple(true) ) ) + .subcommand(SubCommand::with_name("set-staker") + .about("Change staker account for the stake pool. Must be signed by the manager or current staker.") + .arg( + Arg::with_name("pool") + .index(1) + .validator(is_pubkey) + .value_name("POOL_ADDRESS") + .takes_value(true) + .required(true) + .help("Stake pool address."), + ) + .arg( + Arg::with_name("new_staker") + .index(2) + .validator(is_pubkey) + .value_name("ADDRESS") + .takes_value(true) + .help("Public key for the new stake pool staker."), + ) + ) .get_matches(); let mut wallet_manager = None; @@ -1250,10 +1321,30 @@ fn main() { let json_rpc_url = value_t!(matches, "json_rpc_url", String) .unwrap_or_else(|_| cli_config.json_rpc_url.clone()); - let owner = signer_from_path( + let staker = signer_from_path( + &matches, + &cli_config.keypair_path, + "staker", + &mut wallet_manager, + ) + .unwrap_or_else(|e| { + eprintln!("error: {}", e); + exit(1); + }); + let manager = signer_from_path( + &matches, + &cli_config.keypair_path, + "manager", + &mut wallet_manager, + ) + .unwrap_or_else(|e| { + eprintln!("error: {}", e); + exit(1); + }); + let token_owner = signer_from_path( &matches, &cli_config.keypair_path, - "owner", + "token_owner", &mut wallet_manager, ) .unwrap_or_else(|e| { @@ -1277,7 +1368,9 @@ fn main() { Config { rpc_client: RpcClient::new_with_commitment(json_rpc_url, CommitmentConfig::confirmed()), verbose, - owner, + manager, + staker, + token_owner, fee_payer, dry_run, no_update, @@ -1300,7 +1393,7 @@ fn main() { } ("create-validator-stake", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); - let vote_account_address = pubkey_of(arg_matches, "vote_account_address").unwrap(); + let vote_account_address = pubkey_of(arg_matches, "vote_account").unwrap(); command_vsa_create(&config, &stake_pool_address, &vote_account_address) } ("add-validator", Some(arg_matches)) => { @@ -1359,11 +1452,21 @@ fn main() { &stake_receiver, ) } - ("set-owner", Some(arg_matches)) => { + ("set-manager", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); - let new_owner: Option = pubkey_of(arg_matches, "new_owner"); + let new_manager: Option = pubkey_of(arg_matches, "new_manager"); let new_fee_receiver: Option = pubkey_of(arg_matches, "new_fee_receiver"); - command_set_owner(&config, &stake_pool_address, &new_owner, &new_fee_receiver) + command_set_manager( + &config, + &stake_pool_address, + &new_manager, + &new_fee_receiver, + ) + } + ("set-staker", Some(arg_matches)) => { + let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); + let new_staker = pubkey_of(arg_matches, "new_staker").unwrap(); + command_set_staker(&config, &stake_pool_address, &new_staker) } _ => unreachable!(), } diff --git a/program/src/error.rs b/program/src/error.rs index e1aa27ea..62767d42 100644 --- a/program/src/error.rs +++ b/program/src/error.rs @@ -28,16 +28,16 @@ pub enum StakePoolError { /// Token account is associated with the wrong mint. #[error("WrongAccountMint")] WrongAccountMint, - /// Wrong pool owner account. - #[error("WrongOwner")] - WrongOwner, + /// Wrong pool manager account. + #[error("WrongManager")] + WrongManager, /// Required signature is missing. #[error("SignatureMissing")] SignatureMissing, /// Invalid validator stake list account. #[error("InvalidValidatorStakeList")] InvalidValidatorStakeList, - /// Invalid owner fee account. + /// Invalid manager fee account. #[error("InvalidFeeAccount")] InvalidFeeAccount, @@ -79,6 +79,9 @@ pub enum StakePoolError { /// The size of the given validator stake list does match the expected amount #[error("UnexpectedValidatorListAccountSize")] UnexpectedValidatorListAccountSize, + /// Wrong pool staker account. + #[error("WrongStaker")] + WrongStaker, } impl From for ProgramError { fn from(e: StakePoolError) -> Self { diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 58b210db..d7073076 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -30,13 +30,14 @@ pub enum StakePoolInstruction { /// Initializes a new StakePool. /// /// 0. `[w]` New StakePool to create. - /// 1. `[s]` Owner - /// 2. `[w]` Uninitialized validator stake list storage account - /// 3. `[]` pool token Mint. Must be non zero, owned by withdraw authority. - /// 4. `[]` Pool Account to deposit the generated fee for owner. - /// 5. `[]` Clock sysvar - /// 6. `[]` Rent sysvar - /// 7. `[]` Token program id + /// 1. `[s]` Manager + /// 2. `[]` Staker + /// 3. `[w]` Uninitialized validator stake list storage account + /// 4. `[]` Pool token mint. Must be non zero, owned by withdraw authority. + /// 5. `[]` Pool account to deposit the generated fee for manager. + /// 6. `[]` Clock sysvar + /// 7. `[]` Rent sysvar + /// 8. `[]` Token program id Initialize { /// Deposit fee assessed #[allow(dead_code)] // but it's not @@ -46,10 +47,11 @@ pub enum StakePoolInstruction { max_validators: u32, }, - /// Creates new program account for accumulating stakes for a particular validator + /// (Staker only) Creates new program account for accumulating stakes for + /// a particular validator /// /// 0. `[]` Stake pool account this stake will belong to - /// 1. `[s]` Owner + /// 1. `[s]` Staker /// 2. `[ws]` Funding account (must be a system account) /// 3. `[w]` Stake account to be created /// 4. `[]` Validator this stake account will vote for @@ -58,11 +60,11 @@ pub enum StakePoolInstruction { /// 7. `[]` Stake program CreateValidatorStakeAccount, - /// Adds stake account delegated to validator to the pool's list of - /// managed validators + /// (Staker only) Adds stake account delegated to validator to the pool's + /// list of managed validators /// /// 0. `[w]` Stake pool - /// 1. `[s]` Owner + /// 1. `[s]` Staker /// 2. `[]` Stake pool deposit authority /// 3. `[]` Stake pool withdraw authority /// 4. `[w]` Validator stake list storage account @@ -75,10 +77,10 @@ pub enum StakePoolInstruction { /// 11. `[]` Stake program id, AddValidatorToPool, - /// Removes validator stake account from the pool + /// (Staker only) Removes validator from the pool /// /// 0. `[w]` Stake pool - /// 1. `[s]` Owner + /// 1. `[s]` Staker /// 2. `[]` Stake pool withdraw authority /// 3. `[]` New withdraw/staker authority to set in the stake account /// 4. `[w]` Validator stake list storage account @@ -139,23 +141,31 @@ pub enum StakePoolInstruction { /// userdata: amount to withdraw Withdraw(u64), - /// Update owner + /// (Manager only) Update manager /// - /// 0. `[w]` StakePool - /// 1. `[s]` Owner - /// 2. '[]` New owner pubkey - /// 3. '[]` New owner fee account - SetOwner, + /// 0. `[w]` StakePool + /// 1. `[s]` Manager + /// 2. '[]` New manager pubkey + /// 3. '[]` New manager fee account + SetManager, + + /// (Manager or staker only) Update staker + /// + /// 0. `[w]` StakePool + /// 1. `[s]` Manager or current staker + /// 2. '[]` New staker pubkey + SetStaker, } /// Creates an 'initialize' instruction. pub fn initialize( program_id: &Pubkey, stake_pool: &Pubkey, - owner: &Pubkey, + manager: &Pubkey, + staker: &Pubkey, validator_list: &Pubkey, pool_mint: &Pubkey, - owner_pool_account: &Pubkey, + manager_pool_account: &Pubkey, token_program_id: &Pubkey, fee: Fee, max_validators: u32, @@ -167,10 +177,11 @@ pub fn initialize( let data = init_data.try_to_vec()?; let accounts = vec![ AccountMeta::new(*stake_pool, true), - AccountMeta::new_readonly(*owner, true), + AccountMeta::new_readonly(*manager, true), + AccountMeta::new_readonly(*staker, false), AccountMeta::new(*validator_list, false), AccountMeta::new_readonly(*pool_mint, false), - AccountMeta::new_readonly(*owner_pool_account, false), + AccountMeta::new_readonly(*manager_pool_account, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::rent::id(), false), AccountMeta::new_readonly(*token_program_id, false), @@ -186,14 +197,14 @@ pub fn initialize( pub fn create_validator_stake_account( program_id: &Pubkey, stake_pool: &Pubkey, - owner: &Pubkey, + staker: &Pubkey, funder: &Pubkey, stake_account: &Pubkey, validator: &Pubkey, ) -> Result { let accounts = vec![ AccountMeta::new_readonly(*stake_pool, false), - AccountMeta::new_readonly(*owner, true), + AccountMeta::new_readonly(*staker, true), AccountMeta::new(*funder, true), AccountMeta::new(*stake_account, false), AccountMeta::new_readonly(*validator, false), @@ -215,7 +226,7 @@ pub fn create_validator_stake_account( pub fn add_validator_to_pool( program_id: &Pubkey, stake_pool: &Pubkey, - owner: &Pubkey, + staker: &Pubkey, stake_pool_deposit: &Pubkey, stake_pool_withdraw: &Pubkey, validator_list: &Pubkey, @@ -226,7 +237,7 @@ pub fn add_validator_to_pool( ) -> Result { let accounts = vec![ AccountMeta::new(*stake_pool, false), - AccountMeta::new_readonly(*owner, true), + AccountMeta::new_readonly(*staker, true), AccountMeta::new_readonly(*stake_pool_deposit, false), AccountMeta::new_readonly(*stake_pool_withdraw, false), AccountMeta::new(*validator_list, false), @@ -249,7 +260,7 @@ pub fn add_validator_to_pool( pub fn remove_validator_from_pool( program_id: &Pubkey, stake_pool: &Pubkey, - owner: &Pubkey, + staker: &Pubkey, stake_pool_withdraw: &Pubkey, new_stake_authority: &Pubkey, validator_list: &Pubkey, @@ -260,7 +271,7 @@ pub fn remove_validator_from_pool( ) -> Result { let accounts = vec![ AccountMeta::new(*stake_pool, false), - AccountMeta::new_readonly(*owner, true), + AccountMeta::new_readonly(*staker, true), AccountMeta::new_readonly(*stake_pool_withdraw, false), AccountMeta::new_readonly(*new_stake_authority, false), AccountMeta::new(*validator_list, false), @@ -385,23 +396,42 @@ pub fn withdraw( }) } -/// Creates a 'set owner' instruction. -pub fn set_owner( +/// Creates a 'set manager' instruction. +pub fn set_manager( + program_id: &Pubkey, + stake_pool: &Pubkey, + manager: &Pubkey, + new_manager: &Pubkey, + new_fee_receiver: &Pubkey, +) -> Result { + let accounts = vec![ + AccountMeta::new(*stake_pool, false), + AccountMeta::new_readonly(*manager, true), + AccountMeta::new_readonly(*new_manager, false), + AccountMeta::new_readonly(*new_fee_receiver, false), + ]; + Ok(Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::SetManager.try_to_vec()?, + }) +} + +/// Creates a 'set staker' instruction. +pub fn set_staker( program_id: &Pubkey, stake_pool: &Pubkey, - stake_pool_owner: &Pubkey, - stake_pool_new_owner: &Pubkey, - stake_pool_new_fee_receiver: &Pubkey, + set_staker_authority: &Pubkey, + new_staker: &Pubkey, ) -> Result { let accounts = vec![ AccountMeta::new(*stake_pool, false), - AccountMeta::new_readonly(*stake_pool_owner, true), - AccountMeta::new_readonly(*stake_pool_new_owner, false), - AccountMeta::new_readonly(*stake_pool_new_fee_receiver, false), + AccountMeta::new_readonly(*set_staker_authority, true), + AccountMeta::new_readonly(*new_staker, false), ]; Ok(Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::SetOwner.try_to_vec()?, + data: StakePoolInstruction::SetStaker.try_to_vec()?, }) } diff --git a/program/src/processor.rs b/program/src/processor.rs index c3d036fa..a4ae3725 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -131,7 +131,7 @@ impl Processor { ) } - /// Issue a stake_set_owner instruction. + /// Issue a stake_set_manager instruction. #[allow(clippy::too_many_arguments)] fn stake_authorize<'a>( stake_pool: &Pubkey, @@ -227,17 +227,18 @@ impl Processor { ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; - let owner_info = next_account_info(account_info_iter)?; + let manager_info = next_account_info(account_info_iter)?; + let staker_info = next_account_info(account_info_iter)?; let validator_list_info = next_account_info(account_info_iter)?; let pool_mint_info = next_account_info(account_info_iter)?; - let owner_fee_info = next_account_info(account_info_iter)?; + let manager_fee_info = next_account_info(account_info_iter)?; let clock_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(clock_info)?; let rent_info = next_account_info(account_info_iter)?; let rent = &Rent::from_account_info(rent_info)?; let token_program_info = next_account_info(account_info_iter)?; - if !owner_info.is_signer { + if !manager_info.is_signer { return Err(StakePoolError::SignatureMissing.into()); } @@ -279,7 +280,7 @@ impl Processor { return Err(StakePoolError::FeeTooHigh.into()); } - if owner_fee_info.owner != token_program_info.key { + if manager_fee_info.owner != token_program_info.key { return Err(StakePoolError::InvalidFeeAccount.into()); } @@ -288,7 +289,7 @@ impl Processor { } if *pool_mint_info.key - != spl_token::state::Account::unpack_from_slice(&owner_fee_info.data.borrow())?.mint + != spl_token::state::Account::unpack_from_slice(&manager_fee_info.data.borrow())?.mint { return Err(StakePoolError::WrongAccountMint.into()); } @@ -310,12 +311,13 @@ impl Processor { msg!("Epoch: {}", clock.epoch); stake_pool.account_type = AccountType::StakePool; - stake_pool.owner = *owner_info.key; + stake_pool.manager = *manager_info.key; + stake_pool.staker = *staker_info.key; stake_pool.deposit_bump_seed = deposit_bump_seed; stake_pool.withdraw_bump_seed = withdraw_bump_seed; stake_pool.validator_list = *validator_list_info.key; stake_pool.pool_mint = *pool_mint_info.key; - stake_pool.owner_fee_account = *owner_fee_info.key; + stake_pool.manager_fee_account = *manager_fee_info.key; stake_pool.token_program_id = *token_program_info.key; stake_pool.last_update_epoch = clock.epoch; stake_pool.fee = fee; @@ -332,7 +334,7 @@ impl Processor { ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; - let owner_info = next_account_info(account_info_iter)?; + let staker_info = next_account_info(account_info_iter)?; let funder_info = next_account_info(account_info_iter)?; let stake_account_info = next_account_info(account_info_iter)?; let validator_info = next_account_info(account_info_iter)?; @@ -351,7 +353,7 @@ impl Processor { if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); } - stake_pool.check_owner(owner_info)?; + stake_pool.check_staker(staker_info)?; if *system_program_info.key != solana_program::system_program::id() { return Err(ProgramError::IncorrectProgramId); @@ -396,8 +398,8 @@ impl Processor { &stake_program::initialize( &stake_account_info.key, &stake_program::Authorized { - staker: *owner_info.key, - withdrawer: *owner_info.key, + staker: *staker_info.key, + withdrawer: *staker_info.key, }, &stake_program::Lockup::default(), ), @@ -411,7 +413,7 @@ impl Processor { invoke( &stake_program::delegate_stake( &stake_account_info.key, - &owner_info.key, + &staker_info.key, &validator_info.key, ), &[ @@ -420,7 +422,7 @@ impl Processor { clock_info.clone(), stake_history_info.clone(), stake_config_info.clone(), - owner_info.clone(), + staker_info.clone(), ], ) } @@ -432,7 +434,7 @@ impl Processor { ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; - let owner_info = next_account_info(account_info_iter)?; + let staker_info = next_account_info(account_info_iter)?; let deposit_info = next_account_info(account_info_iter)?; let withdraw_info = next_account_info(account_info_iter)?; let validator_list_info = next_account_info(account_info_iter)?; @@ -458,7 +460,7 @@ impl Processor { stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?; stake_pool.check_authority_deposit(deposit_info.key, program_id, stake_pool_info.key)?; - stake_pool.check_owner(owner_info)?; + stake_pool.check_staker(staker_info)?; if stake_pool.last_update_epoch < clock.epoch { return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); @@ -549,7 +551,7 @@ impl Processor { ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; - let owner_info = next_account_info(account_info_iter)?; + let staker_info = next_account_info(account_info_iter)?; let withdraw_info = next_account_info(account_info_iter)?; let new_stake_authority_info = next_account_info(account_info_iter)?; let validator_list_info = next_account_info(account_info_iter)?; @@ -571,7 +573,7 @@ impl Processor { } stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?; - stake_pool.check_owner(owner_info)?; + stake_pool.check_staker(staker_info)?; if stake_pool.last_update_epoch < clock.epoch { return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); @@ -776,7 +778,7 @@ impl Processor { let stake_info = next_account_info(account_info_iter)?; let validator_stake_account_info = next_account_info(account_info_iter)?; let dest_user_info = next_account_info(account_info_iter)?; - let owner_fee_info = next_account_info(account_info_iter)?; + let manager_fee_info = next_account_info(account_info_iter)?; let pool_mint_info = next_account_info(account_info_iter)?; let clock_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(clock_info)?; @@ -799,7 +801,7 @@ impl Processor { stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?; stake_pool.check_authority_deposit(deposit_info.key, program_id, stake_pool_info.key)?; - if stake_pool.owner_fee_account != *owner_fee_info.key { + if stake_pool.manager_fee_account != *manager_fee_info.key { return Err(StakePoolError::InvalidFeeAccount.into()); } if stake_pool.token_program_id != *token_program_info.key { @@ -891,7 +893,7 @@ impl Processor { stake_pool_info.key, token_program_info.clone(), pool_mint_info.clone(), - owner_fee_info.clone(), + manager_fee_info.clone(), withdraw_info.clone(), AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, @@ -1022,29 +1024,52 @@ impl Processor { Ok(()) } - /// Processes [SetOwner](enum.Instruction.html). - fn process_set_owner(_program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { + /// Processes [SetManager](enum.Instruction.html). + fn process_set_manager(_program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; - let owner_info = next_account_info(account_info_iter)?; - let new_owner_info = next_account_info(account_info_iter)?; - let new_owner_fee_info = next_account_info(account_info_iter)?; + let manager_info = next_account_info(account_info_iter)?; + let new_manager_info = next_account_info(account_info_iter)?; + let new_manager_fee_info = next_account_info(account_info_iter)?; let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); } - stake_pool.check_owner(owner_info)?; + stake_pool.check_manager(manager_info)?; if stake_pool.pool_mint - != spl_token::state::Account::unpack_from_slice(&new_owner_fee_info.data.borrow())?.mint + != spl_token::state::Account::unpack_from_slice(&new_manager_fee_info.data.borrow())? + .mint { return Err(StakePoolError::WrongAccountMint.into()); } - stake_pool.owner = *new_owner_info.key; - stake_pool.owner_fee_account = *new_owner_fee_info.key; + stake_pool.manager = *new_manager_info.key; + stake_pool.manager_fee_account = *new_manager_fee_info.key; + stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; + Ok(()) + } + + /// Processes [SetManager](enum.Instruction.html). + fn process_set_staker(_program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { + let account_info_iter = &mut accounts.iter(); + let stake_pool_info = next_account_info(account_info_iter)?; + let set_staker_authority_info = next_account_info(account_info_iter)?; + let new_staker_info = next_account_info(account_info_iter)?; + + let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; + if !stake_pool.is_valid() { + return Err(StakePoolError::InvalidState.into()); + } + + let staker_signed = stake_pool.check_staker(set_staker_authority_info); + let manager_signed = stake_pool.check_manager(set_staker_authority_info); + if staker_signed.is_err() && manager_signed.is_err() { + return Err(StakePoolError::SignatureMissing.into()); + } + stake_pool.staker = *new_staker_info.key; stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; Ok(()) } @@ -1088,9 +1113,13 @@ impl Processor { msg!("Instruction: Withdraw"); Self::process_withdraw(program_id, amount, accounts) } - StakePoolInstruction::SetOwner => { - msg!("Instruction: SetOwner"); - Self::process_set_owner(program_id, accounts) + StakePoolInstruction::SetManager => { + msg!("Instruction: SetManager"); + Self::process_set_manager(program_id, accounts) + } + StakePoolInstruction::SetStaker => { + msg!("Instruction: SetStaker"); + Self::process_set_staker(program_id, accounts) } } } @@ -1108,10 +1137,10 @@ impl PrintProgramError for StakePoolError { StakePoolError::CalculationFailure => msg!("Error: The calculation failed"), StakePoolError::FeeTooHigh => msg!("Error: Stake pool fee > 1"), StakePoolError::WrongAccountMint => msg!("Error: Token account is associated with the wrong mint"), - StakePoolError::WrongOwner => msg!("Error: Wrong pool owner account"), + StakePoolError::WrongManager => msg!("Error: Wrong pool manager account"), StakePoolError::SignatureMissing => msg!("Error: Required signature is missing"), StakePoolError::InvalidValidatorStakeList => msg!("Error: Invalid validator stake list account"), - StakePoolError::InvalidFeeAccount => msg!("Error: Invalid owner fee account"), + StakePoolError::InvalidFeeAccount => msg!("Error: Invalid manager fee account"), StakePoolError::WrongPoolMint => msg!("Error: Specified pool mint account is wrong"), StakePoolError::WrongStakeState => msg!("Error: Stake account is not in the state expected by the program"), StakePoolError::UserStakeNotActive => msg!("Error: User stake is not active"), @@ -1125,6 +1154,7 @@ impl PrintProgramError for StakePoolError { } StakePoolError::WrongMintingAuthority => msg!("Error: Wrong minting authority set for mint pool account"), StakePoolError::UnexpectedValidatorListAccountSize=> msg!("Error: The size of the given validator stake list does match the expected amount"), + StakePoolError::WrongStaker=> msg!("Error: Wrong pool staker account"), } } } diff --git a/program/src/state.rs b/program/src/state.rs index 4c9966fe..86ef6bc4 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -31,9 +31,11 @@ impl Default for AccountType { pub struct StakePool { /// Account type, must be StakePool currently pub account_type: AccountType, - /// Owner authority - /// allows for updating the staking authority - pub owner: Pubkey, + /// Manager authority, allows for updating the staker, manager, and fee account + pub manager: Pubkey, + /// Staker authority, allows for adding and removing validators, and managing stake + /// distribution + pub staker: Pubkey, /// Deposit authority bump seed /// for `create_program_address(&[state::StakePool account, "deposit"])` pub deposit_bump_seed: u8, @@ -44,8 +46,8 @@ pub struct StakePool { pub validator_list: Pubkey, /// Pool Mint pub pool_mint: Pubkey, - /// Owner fee account - pub owner_fee_account: Pubkey, + /// Manager fee account + pub manager_fee_account: Pubkey, /// Pool token program id pub token_program_id: Pubkey, /// total stake under management @@ -86,7 +88,7 @@ impl StakePool { ) .ok() } - /// calculate the fee in pool tokens that goes to the owner + /// calculate the fee in pool tokens that goes to the manager pub fn calc_fee_amount(&self, pool_amount: u64) -> Option { if self.fee.denominator == 0 { return Some(0); @@ -154,12 +156,23 @@ impl StakePool { ) } - /// Check owner validity and signature - pub(crate) fn check_owner(&self, owner_info: &AccountInfo) -> Result<(), ProgramError> { - if *owner_info.key != self.owner { - return Err(StakePoolError::WrongOwner.into()); + /// Check manager validity and signature + pub(crate) fn check_manager(&self, manager_info: &AccountInfo) -> Result<(), ProgramError> { + if *manager_info.key != self.manager { + return Err(StakePoolError::WrongManager.into()); } - if !owner_info.is_signer { + if !manager_info.is_signer { + return Err(StakePoolError::SignatureMissing.into()); + } + Ok(()) + } + + /// Check staker validity and signature + pub(crate) fn check_staker(&self, staker_info: &AccountInfo) -> Result<(), ProgramError> { + if *staker_info.key != self.staker { + return Err(StakePoolError::WrongStaker.into()); + } + if !staker_info.is_signer { return Err(StakePoolError::SignatureMissing.into()); } Ok(()) diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 7ef729d7..fa69ab44 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -510,7 +510,7 @@ async fn test_stake_pool_deposit_to_unknown_validator() { &mut banks_client, &payer, &recent_blockhash, - &stake_pool_accounts.owner, + &stake_pool_accounts.staker, ) .await; @@ -789,7 +789,7 @@ async fn test_stake_pool_deposit_with_wrong_mint_for_receiver_acc() { let outside_mint = Keypair::new(); let outside_withdraw_auth = Keypair::new(); - let outside_owner = Keypair::new(); + let outside_manager = Keypair::new(); let outside_pool_fee_acc = Keypair::new(); create_mint( @@ -808,7 +808,7 @@ async fn test_stake_pool_deposit_with_wrong_mint_for_receiver_acc() { &recent_blockhash, &outside_pool_fee_acc, &outside_mint.pubkey(), - &outside_owner.pubkey(), + &outside_manager.pubkey(), ) .await .unwrap(); diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 807e7620..fefb613d 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -42,7 +42,7 @@ pub async fn create_mint( payer: &Keypair, recent_blockhash: &Hash, pool_mint: &Keypair, - owner: &Pubkey, + manager: &Pubkey, ) -> Result<(), TransportError> { let rent = banks_client.get_rent().await.unwrap(); let mint_rent = rent.minimum_balance(spl_token::state::Mint::LEN); @@ -59,7 +59,7 @@ pub async fn create_mint( spl_token::instruction::initialize_mint( &spl_token::id(), &pool_mint.pubkey(), - &owner, + &manager, None, 0, ) @@ -97,7 +97,7 @@ pub async fn create_token_account( recent_blockhash: &Hash, account: &Keypair, pool_mint: &Pubkey, - owner: &Pubkey, + manager: &Pubkey, ) -> Result<(), TransportError> { let rent = banks_client.get_rent().await.unwrap(); let account_rent = rent.minimum_balance(spl_token::state::Account::LEN); @@ -115,7 +115,7 @@ pub async fn create_token_account( &spl_token::id(), &account.pubkey(), pool_mint, - owner, + manager, ) .unwrap(), ], @@ -142,7 +142,7 @@ pub async fn delegate_tokens( payer: &Keypair, recent_blockhash: &Hash, account: &Pubkey, - owner: &Keypair, + manager: &Keypair, delegate: &Pubkey, amount: u64, ) { @@ -151,14 +151,14 @@ pub async fn delegate_tokens( &spl_token::id(), &account, &delegate, - &owner.pubkey(), + &manager.pubkey(), &[], amount, ) .unwrap()], Some(&payer.pubkey()), ); - transaction.sign(&[payer, owner], *recent_blockhash); + transaction.sign(&[payer, manager], *recent_blockhash); banks_client.process_transaction(transaction).await.unwrap(); } @@ -171,7 +171,8 @@ pub async fn create_stake_pool( validator_list: &Keypair, pool_mint: &Pubkey, pool_token_account: &Pubkey, - owner: &Keypair, + manager: &Keypair, + staker: &Pubkey, fee: &instruction::Fee, max_validators: u32, ) -> Result<(), TransportError> { @@ -200,7 +201,8 @@ pub async fn create_stake_pool( instruction::initialize( &id(), &stake_pool.pubkey(), - &owner.pubkey(), + &manager.pubkey(), + staker, &validator_list.pubkey(), pool_mint, pool_token_account, @@ -213,7 +215,7 @@ pub async fn create_stake_pool( Some(&payer.pubkey()), ); transaction.sign( - &[payer, stake_pool, validator_list, owner], + &[payer, stake_pool, validator_list, manager], *recent_blockhash, ); banks_client.process_transaction(transaction).await?; @@ -301,7 +303,7 @@ pub async fn create_validator_stake_account( payer: &Keypair, recent_blockhash: &Hash, stake_pool: &Pubkey, - owner: &Keypair, + staker: &Keypair, stake_account: &Pubkey, validator: &Pubkey, ) { @@ -310,7 +312,7 @@ pub async fn create_validator_stake_account( instruction::create_validator_stake_account( &id(), &stake_pool, - &owner.pubkey(), + &staker.pubkey(), &payer.pubkey(), &stake_account, &validator, @@ -320,7 +322,7 @@ pub async fn create_validator_stake_account( ], Some(&payer.pubkey()), ); - transaction.sign(&[payer, owner], *recent_blockhash); + transaction.sign(&[payer, staker], *recent_blockhash); banks_client.process_transaction(transaction).await.unwrap(); } @@ -390,7 +392,7 @@ impl ValidatorStakeAccount { mut banks_client: &mut BanksClient, payer: &Keypair, recent_blockhash: &Hash, - owner: &Keypair, + staker: &Keypair, ) { create_vote(&mut banks_client, &payer, &recent_blockhash, &self.vote).await; @@ -399,7 +401,7 @@ impl ValidatorStakeAccount { &payer, &recent_blockhash, &self.stake_pool, - owner, + staker, &self.stake_account, &self.vote.pubkey(), ) @@ -410,7 +412,7 @@ impl ValidatorStakeAccount { &payer, &recent_blockhash, &self.stake_account, - &owner, + &staker, &self.target_authority, stake_program::StakeAuthorize::Staker, ) @@ -421,7 +423,7 @@ impl ValidatorStakeAccount { &payer, &recent_blockhash, &self.stake_account, - &owner, + &staker, &self.target_authority, stake_program::StakeAuthorize::Withdrawer, ) @@ -434,7 +436,8 @@ pub struct StakePoolAccounts { pub validator_list: Keypair, pub pool_mint: Keypair, pub pool_fee_account: Keypair, - pub owner: Keypair, + pub manager: Keypair, + pub staker: Keypair, pub withdraw_authority: Pubkey, pub deposit_authority: Pubkey, pub fee: instruction::Fee, @@ -456,14 +459,16 @@ impl StakePoolAccounts { ); let pool_mint = Keypair::new(); let pool_fee_account = Keypair::new(); - let owner = Keypair::new(); + let manager = Keypair::new(); + let staker = Keypair::new(); Self { stake_pool, validator_list, pool_mint, pool_fee_account, - owner, + manager, + staker, withdraw_authority, deposit_authority, fee: instruction::Fee { @@ -498,7 +503,7 @@ impl StakePoolAccounts { &recent_blockhash, &self.pool_fee_account, &self.pool_mint.pubkey(), - &self.owner.pubkey(), + &self.manager.pubkey(), ) .await?; create_stake_pool( @@ -509,7 +514,8 @@ impl StakePoolAccounts { &self.validator_list, &self.pool_mint.pubkey(), &self.pool_fee_account.pubkey(), - &self.owner, + &self.manager, + &self.staker.pubkey(), &self.fee, self.max_validators, ) @@ -593,7 +599,7 @@ impl StakePoolAccounts { &[instruction::add_validator_to_pool( &id(), &self.stake_pool.pubkey(), - &self.owner.pubkey(), + &self.staker.pubkey(), &self.deposit_authority, &self.withdraw_authority, &self.validator_list.pubkey(), @@ -605,7 +611,7 @@ impl StakePoolAccounts { .unwrap()], Some(&payer.pubkey()), ); - transaction.sign(&[payer, &self.owner], *recent_blockhash); + transaction.sign(&[payer, &self.staker], *recent_blockhash); banks_client.process_transaction(transaction).await.err() } @@ -622,7 +628,7 @@ impl StakePoolAccounts { &[instruction::remove_validator_from_pool( &id(), &self.stake_pool.pubkey(), - &self.owner.pubkey(), + &self.staker.pubkey(), &self.withdraw_authority, &new_authority, &self.validator_list.pubkey(), @@ -634,7 +640,7 @@ impl StakePoolAccounts { .unwrap()], Some(&payer.pubkey()), ); - transaction.sign(&[payer, &self.owner], *recent_blockhash); + transaction.sign(&[payer, &self.staker], *recent_blockhash); banks_client.process_transaction(transaction).await.err() } } @@ -654,7 +660,7 @@ pub async fn simple_add_validator_to_pool( banks_client, &payer, &recent_blockhash, - &stake_pool_accounts.owner, + &stake_pool_accounts.staker, ) .await; diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index 02909957..8cb2c2ff 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -45,7 +45,7 @@ async fn create_mint_and_token_account( recent_blockhash, &stake_pool_accounts.pool_fee_account, &stake_pool_accounts.pool_mint.pubkey(), - &stake_pool_accounts.owner.pubkey(), + &stake_pool_accounts.manager.pubkey(), ) .await .unwrap(); @@ -204,7 +204,8 @@ async fn test_initialize_stake_pool_with_wrong_max_validators() { instruction::initialize( &id(), &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.owner.pubkey(), + &stake_pool_accounts.manager.pubkey(), + &stake_pool_accounts.staker.pubkey(), &stake_pool_accounts.validator_list.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), @@ -221,7 +222,7 @@ async fn test_initialize_stake_pool_with_wrong_max_validators() { &payer, &stake_pool_accounts.stake_pool, &stake_pool_accounts.validator_list, - &stake_pool_accounts.owner, + &stake_pool_accounts.manager, ], recent_blockhash, ); @@ -276,7 +277,8 @@ async fn test_initialize_stake_pool_with_wrong_mint_authority() { &stake_pool_accounts.validator_list, &wrong_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), - &stake_pool_accounts.owner, + &stake_pool_accounts.manager, + &stake_pool_accounts.staker.pubkey(), &stake_pool_accounts.fee, stake_pool_accounts.max_validators, ) @@ -358,7 +360,8 @@ async fn test_initialize_stake_pool_with_wrong_token_program_id() { instruction::initialize( &id(), &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.owner.pubkey(), + &stake_pool_accounts.manager.pubkey(), + &stake_pool_accounts.staker.pubkey(), &stake_pool_accounts.validator_list.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), @@ -375,7 +378,7 @@ async fn test_initialize_stake_pool_with_wrong_token_program_id() { &payer, &stake_pool_accounts.stake_pool, &stake_pool_accounts.validator_list, - &stake_pool_accounts.owner, + &stake_pool_accounts.manager, ], recent_blockhash, ); @@ -396,7 +399,7 @@ async fn test_initialize_stake_pool_with_wrong_token_program_id() { } #[tokio::test] -async fn test_initialize_stake_pool_with_wrong_fee_accounts_owner() { +async fn test_initialize_stake_pool_with_wrong_fee_accounts_manager() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); @@ -436,7 +439,8 @@ async fn test_initialize_stake_pool_with_wrong_fee_accounts_owner() { &stake_pool_accounts.validator_list, &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), - &stake_pool_accounts.owner, + &stake_pool_accounts.manager, + &stake_pool_accounts.staker.pubkey(), &stake_pool_accounts.fee, stake_pool_accounts.max_validators, ) @@ -453,7 +457,7 @@ async fn test_initialize_stake_pool_with_wrong_fee_accounts_owner() { assert_eq!(error_index, program_error); } _ => panic!( - "Wrong error occurs while try to initialize stake pool with wrong fee account's owner" + "Wrong error occurs while try to initialize stake pool with wrong fee account's manager" ), } } @@ -524,7 +528,8 @@ async fn test_initialize_stake_pool_with_not_rent_exempt_pool() { instruction::initialize( &id(), &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.owner.pubkey(), + &stake_pool_accounts.manager.pubkey(), + &stake_pool_accounts.staker.pubkey(), &stake_pool_accounts.validator_list.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), @@ -541,7 +546,7 @@ async fn test_initialize_stake_pool_with_not_rent_exempt_pool() { &payer, &stake_pool_accounts.stake_pool, &stake_pool_accounts.validator_list, - &stake_pool_accounts.owner, + &stake_pool_accounts.manager, ], recent_blockhash, ); @@ -596,7 +601,8 @@ async fn test_initialize_stake_pool_with_not_rent_exempt_validator_list() { instruction::initialize( &id(), &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.owner.pubkey(), + &stake_pool_accounts.manager.pubkey(), + &stake_pool_accounts.staker.pubkey(), &stake_pool_accounts.validator_list.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), @@ -613,7 +619,7 @@ async fn test_initialize_stake_pool_with_not_rent_exempt_validator_list() { &payer, &stake_pool_accounts.stake_pool, &stake_pool_accounts.validator_list, - &stake_pool_accounts.owner, + &stake_pool_accounts.manager, ], recent_blockhash, ); @@ -632,7 +638,7 @@ async fn test_initialize_stake_pool_with_not_rent_exempt_validator_list() { } #[tokio::test] -async fn test_initialize_stake_pool_without_owner_signature() { +async fn test_initialize_stake_pool_without_manager_signature() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); @@ -659,7 +665,8 @@ async fn test_initialize_stake_pool_without_owner_signature() { let data = init_data.try_to_vec().unwrap(); let accounts = vec![ AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), true), - AccountMeta::new_readonly(stake_pool_accounts.owner.pubkey(), false), + AccountMeta::new_readonly(stake_pool_accounts.manager.pubkey(), false), + AccountMeta::new_readonly(stake_pool_accounts.staker.pubkey(), false), AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false), AccountMeta::new_readonly(stake_pool_accounts.pool_mint.pubkey(), false), AccountMeta::new_readonly(stake_pool_accounts.pool_fee_account.pubkey(), false), @@ -716,7 +723,7 @@ async fn test_initialize_stake_pool_without_owner_signature() { assert_eq!(error_index, program_error); } _ => panic!( - "Wrong error occurs while try to initialize stake pool without owner's signature" + "Wrong error occurs while try to initialize stake pool without manager's signature" ), } } diff --git a/program/tests/set_owner.rs b/program/tests/set_manager.rs similarity index 76% rename from program/tests/set_owner.rs rename to program/tests/set_manager.rs index 611dcf03..0b0223fe 100644 --- a/program/tests/set_owner.rs +++ b/program/tests/set_manager.rs @@ -33,14 +33,14 @@ async fn setup() -> ( .unwrap(); let new_pool_fee = Keypair::new(); - let new_owner = Keypair::new(); + let new_manager = Keypair::new(); create_token_account( &mut banks_client, &payer, &recent_blockhash, &new_pool_fee, &stake_pool_accounts.pool_mint.pubkey(), - &new_owner.pubkey(), + &new_manager.pubkey(), ) .await .unwrap(); @@ -51,52 +51,52 @@ async fn setup() -> ( recent_blockhash, stake_pool_accounts, new_pool_fee, - new_owner, + new_manager, ) } #[tokio::test] -async fn test_set_owner() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_pool_fee, new_owner) = +async fn test_set_manager() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_pool_fee, new_manager) = setup().await; let mut transaction = Transaction::new_with_payer( - &[instruction::set_owner( + &[instruction::set_manager( &id(), &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.owner.pubkey(), - &new_owner.pubkey(), + &stake_pool_accounts.manager.pubkey(), + &new_manager.pubkey(), &new_pool_fee.pubkey(), ) .unwrap()], Some(&payer.pubkey()), ); - transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); + transaction.sign(&[&payer, &stake_pool_accounts.manager], recent_blockhash); banks_client.process_transaction(transaction).await.unwrap(); let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; let stake_pool = state::StakePool::try_from_slice(&stake_pool.data.as_slice()).unwrap(); - assert_eq!(stake_pool.owner, new_owner.pubkey()); + assert_eq!(stake_pool.manager, new_manager.pubkey()); } #[tokio::test] -async fn test_set_owner_by_malicious() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_pool_fee, new_owner) = +async fn test_set_manager_by_malicious() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_pool_fee, new_manager) = setup().await; let mut transaction = Transaction::new_with_payer( - &[instruction::set_owner( + &[instruction::set_manager( &id(), &stake_pool_accounts.stake_pool.pubkey(), - &new_owner.pubkey(), - &new_owner.pubkey(), + &new_manager.pubkey(), + &new_manager.pubkey(), &new_pool_fee.pubkey(), ) .unwrap()], Some(&payer.pubkey()), ); - transaction.sign(&[&payer, &new_owner], recent_blockhash); + transaction.sign(&[&payer, &new_manager], recent_blockhash); let transaction_error = banks_client .process_transaction(transaction) .await @@ -108,25 +108,25 @@ async fn test_set_owner_by_malicious() { _, InstructionError::Custom(error_index), )) => { - let program_error = error::StakePoolError::WrongOwner as u32; + let program_error = error::StakePoolError::WrongManager as u32; assert_eq!(error_index, program_error); } - _ => panic!("Wrong error occurs while malicious try to set owner"), + _ => panic!("Wrong error occurs while malicious try to set manager"), } } #[tokio::test] -async fn test_set_owner_without_signature() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_pool_fee, new_owner) = +async fn test_set_manager_without_signature() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_pool_fee, new_manager) = setup().await; - let data = instruction::StakePoolInstruction::SetOwner + let data = instruction::StakePoolInstruction::SetManager .try_to_vec() .unwrap(); let accounts = vec![ AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), - AccountMeta::new_readonly(stake_pool_accounts.owner.pubkey(), false), - AccountMeta::new_readonly(new_owner.pubkey(), false), + AccountMeta::new_readonly(stake_pool_accounts.manager.pubkey(), false), + AccountMeta::new_readonly(new_manager.pubkey(), false), AccountMeta::new_readonly(new_pool_fee.pubkey(), false), ]; let instruction = Instruction { @@ -151,12 +151,12 @@ async fn test_set_owner_without_signature() { let program_error = error::StakePoolError::SignatureMissing as u32; assert_eq!(error_index, program_error); } - _ => panic!("Wrong error occurs while try to set new owner without signature"), + _ => panic!("Wrong error occurs while try to set new manager without signature"), } } #[tokio::test] -async fn test_set_owner_with_wrong_mint_for_pool_fee_acc() { +async fn test_set_manager_with_wrong_mint_for_pool_fee_acc() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts @@ -167,7 +167,7 @@ async fn test_set_owner_with_wrong_mint_for_pool_fee_acc() { let new_mint = Keypair::new(); let new_withdraw_auth = Keypair::new(); let new_pool_fee = Keypair::new(); - let new_owner = Keypair::new(); + let new_manager = Keypair::new(); create_mint( &mut banks_client, @@ -184,23 +184,23 @@ async fn test_set_owner_with_wrong_mint_for_pool_fee_acc() { &recent_blockhash, &new_pool_fee, &new_mint.pubkey(), - &new_owner.pubkey(), + &new_manager.pubkey(), ) .await .unwrap(); let mut transaction = Transaction::new_with_payer( - &[instruction::set_owner( + &[instruction::set_manager( &id(), &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.owner.pubkey(), - &new_owner.pubkey(), + &stake_pool_accounts.manager.pubkey(), + &new_manager.pubkey(), &new_pool_fee.pubkey(), ) .unwrap()], Some(&payer.pubkey()), ); - transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); + transaction.sign(&[&payer, &stake_pool_accounts.manager], recent_blockhash); let transaction_error = banks_client .process_transaction(transaction) .await @@ -215,6 +215,6 @@ async fn test_set_owner_with_wrong_mint_for_pool_fee_acc() { let program_error = error::StakePoolError::WrongAccountMint as u32; assert_eq!(error_index, program_error); } - _ => panic!("Wrong error occurs while try to set new owner with wrong mint"), + _ => panic!("Wrong error occurs while try to set new manager with wrong mint"), } } diff --git a/program/tests/set_staker.rs b/program/tests/set_staker.rs new file mode 100644 index 00000000..b8d30171 --- /dev/null +++ b/program/tests/set_staker.rs @@ -0,0 +1,176 @@ +#![cfg(feature = "test-bpf")] + +mod helpers; + +use { + borsh::{BorshDeserialize, BorshSerialize}, + helpers::*, + solana_program::{ + hash::Hash, + instruction::{AccountMeta, Instruction}, + }, + solana_program_test::*, + solana_sdk::{ + instruction::InstructionError, signature::Keypair, signature::Signer, + transaction::Transaction, transaction::TransactionError, transport::TransportError, + }, + spl_stake_pool::{error, id, instruction, state}, +}; + +async fn setup() -> (BanksClient, Keypair, Hash, StakePoolAccounts, Keypair) { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await + .unwrap(); + + let new_staker = Keypair::new(); + + ( + banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + new_staker, + ) +} + +#[tokio::test] +async fn success_set_staker_as_manager() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_staker) = + setup().await; + + let mut transaction = Transaction::new_with_payer( + &[instruction::set_staker( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + &new_staker.pubkey(), + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &stake_pool_accounts.manager], recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); + + let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; + let stake_pool = state::StakePool::try_from_slice(&stake_pool.data.as_slice()).unwrap(); + + assert_eq!(stake_pool.staker, new_staker.pubkey()); +} + +#[tokio::test] +async fn success_set_staker_as_staker() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_staker) = + setup().await; + + let mut transaction = Transaction::new_with_payer( + &[instruction::set_staker( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.staker.pubkey(), + &new_staker.pubkey(), + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); + + let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; + let stake_pool = state::StakePool::try_from_slice(&stake_pool.data.as_slice()).unwrap(); + + assert_eq!(stake_pool.staker, new_staker.pubkey()); + + let mut transaction = Transaction::new_with_payer( + &[instruction::set_staker( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &new_staker.pubkey(), + &stake_pool_accounts.staker.pubkey(), + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &new_staker], recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); + + let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; + let stake_pool = state::StakePool::try_from_slice(&stake_pool.data.as_slice()).unwrap(); + + assert_eq!(stake_pool.staker, stake_pool_accounts.staker.pubkey()); +} + +#[tokio::test] +async fn fail_wrong_manager() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_staker) = + setup().await; + + let mut transaction = Transaction::new_with_payer( + &[instruction::set_staker( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &new_staker.pubkey(), + &new_staker.pubkey(), + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &new_staker], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::SignatureMissing as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while malicious try to set manager"), + } +} + +#[tokio::test] +async fn fail_set_staker_without_signature() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_staker) = + setup().await; + + let data = instruction::StakePoolInstruction::SetStaker + .try_to_vec() + .unwrap(); + let accounts = vec![ + AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), + AccountMeta::new_readonly(stake_pool_accounts.manager.pubkey(), false), + AccountMeta::new_readonly(new_staker.pubkey(), false), + ]; + let instruction = Instruction { + program_id: id(), + accounts, + data, + }; + + let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); + transaction.sign(&[&payer], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::SignatureMissing as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while try to set new manager without signature"), + } +} diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index fdcd5591..37fe9b1e 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -49,7 +49,7 @@ async fn setup() -> ( &mut banks_client, &payer, &recent_blockhash, - &stake_pool_accounts.owner, + &stake_pool_accounts.staker, ) .await; @@ -169,7 +169,7 @@ async fn test_add_validator_to_pool_with_wrong_token_program_id() { &[instruction::add_validator_to_pool( &id(), &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.owner.pubkey(), + &stake_pool_accounts.staker.pubkey(), &stake_pool_accounts.deposit_authority, &stake_pool_accounts.withdraw_authority, &stake_pool_accounts.validator_list.pubkey(), @@ -181,7 +181,7 @@ async fn test_add_validator_to_pool_with_wrong_token_program_id() { .unwrap()], Some(&payer.pubkey()), ); - transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); + transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); let transaction_error = banks_client .process_transaction(transaction) .await @@ -213,7 +213,7 @@ async fn test_add_validator_to_pool_with_wrong_pool_mint_account() { &[instruction::add_validator_to_pool( &id(), &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.owner.pubkey(), + &stake_pool_accounts.staker.pubkey(), &stake_pool_accounts.deposit_authority, &stake_pool_accounts.withdraw_authority, &stake_pool_accounts.validator_list.pubkey(), @@ -225,7 +225,7 @@ async fn test_add_validator_to_pool_with_wrong_pool_mint_account() { .unwrap()], Some(&payer.pubkey()), ); - transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); + transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); let transaction_error = banks_client .process_transaction(transaction) .await @@ -261,7 +261,7 @@ async fn test_add_validator_to_pool_with_wrong_validator_list_account() { &[instruction::add_validator_to_pool( &id(), &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.owner.pubkey(), + &stake_pool_accounts.staker.pubkey(), &stake_pool_accounts.deposit_authority, &stake_pool_accounts.withdraw_authority, &wrong_validator_list.pubkey(), @@ -273,7 +273,7 @@ async fn test_add_validator_to_pool_with_wrong_validator_list_account() { .unwrap()], Some(&payer.pubkey()), ); - transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); + transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); let transaction_error = banks_client .process_transaction(transaction) .await @@ -339,7 +339,7 @@ async fn test_try_to_add_already_added_validator_stake_account() { } #[tokio::test] -async fn test_not_owner_try_to_add_validator_to_pool() { +async fn test_not_staker_try_to_add_validator_to_pool() { let ( mut banks_client, payer, @@ -379,7 +379,7 @@ async fn test_not_owner_try_to_add_validator_to_pool() { _, InstructionError::Custom(error_index), )) => { - let program_error = error::StakePoolError::WrongOwner as u32; + let program_error = error::StakePoolError::WrongStaker as u32; assert_eq!(error_index, program_error); } _ => panic!("Wrong error occurs while malicious try to add validator stake account"), @@ -387,7 +387,7 @@ async fn test_not_owner_try_to_add_validator_to_pool() { } #[tokio::test] -async fn test_not_owner_try_to_add_validator_to_pool_without_signature() { +async fn test_not_staker_try_to_add_validator_to_pool_without_signature() { let ( mut banks_client, payer, @@ -399,7 +399,7 @@ async fn test_not_owner_try_to_add_validator_to_pool_without_signature() { let accounts = vec![ AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), - AccountMeta::new_readonly(stake_pool_accounts.owner.pubkey(), false), + AccountMeta::new_readonly(stake_pool_accounts.staker.pubkey(), false), AccountMeta::new_readonly(stake_pool_accounts.deposit_authority, false), AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false), AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false), @@ -454,7 +454,7 @@ async fn test_add_validator_to_pool_with_wrong_stake_program_id() { let accounts = vec![ AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), - AccountMeta::new_readonly(stake_pool_accounts.owner.pubkey(), true), + AccountMeta::new_readonly(stake_pool_accounts.staker.pubkey(), true), AccountMeta::new_readonly(stake_pool_accounts.deposit_authority, false), AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false), AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false), @@ -474,7 +474,7 @@ async fn test_add_validator_to_pool_with_wrong_stake_program_id() { .unwrap(), }; let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); - transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); + transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); let transaction_error = banks_client .process_transaction(transaction) .await @@ -512,7 +512,7 @@ async fn test_add_too_many_validator_stake_accounts() { &mut banks_client, &payer, &recent_blockhash, - &stake_pool_accounts.owner, + &stake_pool_accounts.staker, ) .await; @@ -549,7 +549,7 @@ async fn test_add_too_many_validator_stake_accounts() { &mut banks_client, &payer, &recent_blockhash, - &stake_pool_accounts.owner, + &stake_pool_accounts.staker, ) .await; let error = stake_pool_accounts diff --git a/program/tests/vsa_create.rs b/program/tests/vsa_create.rs index aaa4e422..317e59a6 100644 --- a/program/tests/vsa_create.rs +++ b/program/tests/vsa_create.rs @@ -43,7 +43,7 @@ async fn success_create_validator_stake_account() { &[instruction::create_validator_stake_account( &id(), &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.owner.pubkey(), + &stake_pool_accounts.staker.pubkey(), &payer.pubkey(), &stake_account, &validator.pubkey(), @@ -51,7 +51,7 @@ async fn success_create_validator_stake_account() { .unwrap()], Some(&payer.pubkey()), ); - transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); + transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); banks_client.process_transaction(transaction).await.unwrap(); // Check authorities @@ -59,10 +59,13 @@ async fn success_create_validator_stake_account() { let stake_state = deserialize::(&stake.data).unwrap(); match stake_state { stake_program::StakeState::Stake(meta, stake) => { - assert_eq!(&meta.authorized.staker, &stake_pool_accounts.owner.pubkey()); + assert_eq!( + &meta.authorized.staker, + &stake_pool_accounts.staker.pubkey() + ); assert_eq!( &meta.authorized.withdrawer, - &stake_pool_accounts.owner.pubkey() + &stake_pool_accounts.staker.pubkey() ); assert_eq!(stake.delegation.voter_pubkey, validator.pubkey()); } @@ -88,7 +91,7 @@ async fn fail_create_validator_stake_account_on_non_vote_account() { &[instruction::create_validator_stake_account( &id(), &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.owner.pubkey(), + &stake_pool_accounts.staker.pubkey(), &payer.pubkey(), &stake_account, &validator, @@ -96,7 +99,7 @@ async fn fail_create_validator_stake_account_on_non_vote_account() { .unwrap()], Some(&payer.pubkey()), ); - transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); + transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); let transaction_error = banks_client .process_transaction(transaction) .await @@ -126,7 +129,7 @@ async fn fail_create_validator_stake_account_with_wrong_system_program() { let wrong_system_program = Pubkey::new_unique(); let accounts = vec![ AccountMeta::new_readonly(stake_pool_accounts.stake_pool.pubkey(), false), - AccountMeta::new_readonly(stake_pool_accounts.owner.pubkey(), true), + AccountMeta::new_readonly(stake_pool_accounts.staker.pubkey(), true), AccountMeta::new(payer.pubkey(), true), AccountMeta::new(stake_account, false), AccountMeta::new_readonly(validator, false), @@ -146,7 +149,7 @@ async fn fail_create_validator_stake_account_with_wrong_system_program() { }; let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); - transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); + transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); let transaction_error = banks_client .process_transaction(transaction) .await @@ -176,7 +179,7 @@ async fn fail_create_validator_stake_account_with_wrong_stake_program() { let wrong_stake_program = Pubkey::new_unique(); let accounts = vec![ AccountMeta::new_readonly(stake_pool_accounts.stake_pool.pubkey(), false), - AccountMeta::new_readonly(stake_pool_accounts.owner.pubkey(), true), + AccountMeta::new_readonly(stake_pool_accounts.staker.pubkey(), true), AccountMeta::new(payer.pubkey(), true), AccountMeta::new(stake_account, false), AccountMeta::new_readonly(validator, false), @@ -196,7 +199,7 @@ async fn fail_create_validator_stake_account_with_wrong_stake_program() { }; let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); - transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); + transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); let transaction_error = banks_client .process_transaction(transaction) .await @@ -226,7 +229,7 @@ async fn fail_create_validator_stake_account_with_incorrect_address() { &[instruction::create_validator_stake_account( &id(), &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.owner.pubkey(), + &stake_pool_accounts.staker.pubkey(), &payer.pubkey(), &stake_account.pubkey(), &validator, @@ -234,7 +237,7 @@ async fn fail_create_validator_stake_account_with_incorrect_address() { .unwrap()], Some(&payer.pubkey()), ); - transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); + transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); let transaction_error = banks_client .process_transaction(transaction) .await diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 77476147..8773481f 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -50,7 +50,7 @@ async fn setup() -> ( &mut banks_client, &payer, &recent_blockhash, - &stake_pool_accounts.owner, + &stake_pool_accounts.staker, ) .await; @@ -176,7 +176,7 @@ async fn test_remove_validator_from_pool_with_wrong_stake_program_id() { let new_authority = Pubkey::new_unique(); let accounts = vec![ AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), - AccountMeta::new_readonly(stake_pool_accounts.owner.pubkey(), true), + AccountMeta::new_readonly(stake_pool_accounts.staker.pubkey(), true), AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false), AccountMeta::new_readonly(new_authority, false), AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false), @@ -196,7 +196,7 @@ async fn test_remove_validator_from_pool_with_wrong_stake_program_id() { }; let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); - transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); + transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); let transaction_error = banks_client .process_transaction(transaction) .await @@ -233,7 +233,7 @@ async fn test_remove_validator_from_pool_with_wrong_token_program_id() { &[instruction::remove_validator_from_pool( &id(), &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.owner.pubkey(), + &stake_pool_accounts.staker.pubkey(), &stake_pool_accounts.withdraw_authority, &new_authority, &stake_pool_accounts.validator_list.pubkey(), @@ -245,7 +245,7 @@ async fn test_remove_validator_from_pool_with_wrong_token_program_id() { .unwrap()], Some(&payer.pubkey()), ); - transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); + transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); let transaction_error = banks_client .process_transaction(transaction) .await @@ -279,7 +279,7 @@ async fn test_remove_validator_from_pool_with_wrong_pool_mint_account() { &[instruction::remove_validator_from_pool( &id(), &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.owner.pubkey(), + &stake_pool_accounts.staker.pubkey(), &stake_pool_accounts.withdraw_authority, &new_authority, &stake_pool_accounts.validator_list.pubkey(), @@ -291,7 +291,7 @@ async fn test_remove_validator_from_pool_with_wrong_pool_mint_account() { .unwrap()], Some(&payer.pubkey()), ); - transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); + transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); let transaction_error = banks_client .process_transaction(transaction) .await @@ -329,7 +329,7 @@ async fn test_remove_validator_from_pool_with_wrong_validator_list_account() { &[instruction::remove_validator_from_pool( &id(), &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.owner.pubkey(), + &stake_pool_accounts.staker.pubkey(), &stake_pool_accounts.withdraw_authority, &new_authority, &wrong_validator_list.pubkey(), @@ -341,7 +341,7 @@ async fn test_remove_validator_from_pool_with_wrong_validator_list_account() { .unwrap()], Some(&payer.pubkey()), ); - transaction.sign(&[&payer, &stake_pool_accounts.owner], recent_blockhash); + transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); let transaction_error = banks_client .process_transaction(transaction) .await @@ -426,7 +426,7 @@ async fn test_remove_already_removed_validator_stake_account() { } #[tokio::test] -async fn test_not_owner_try_to_remove_validator_from_pool() { +async fn test_not_staker_try_to_remove_validator_from_pool() { let ( mut banks_client, payer, @@ -468,15 +468,17 @@ async fn test_not_owner_try_to_remove_validator_from_pool() { _, InstructionError::Custom(error_index), )) => { - let program_error = error::StakePoolError::WrongOwner as u32; + let program_error = error::StakePoolError::WrongStaker as u32; assert_eq!(error_index, program_error); } - _ => panic!("Wrong error occurs while not an owner try to remove validator stake address"), + _ => { + panic!("Wrong error occurs while not an staker try to remove validator stake address") + } } } #[tokio::test] -async fn test_not_owner_try_to_remove_validator_from_pool_without_signature() { +async fn test_not_staker_try_to_remove_validator_from_pool_without_signature() { let ( mut banks_client, payer, @@ -491,7 +493,7 @@ async fn test_not_owner_try_to_remove_validator_from_pool_without_signature() { let accounts = vec![ AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), - AccountMeta::new_readonly(stake_pool_accounts.owner.pubkey(), false), + AccountMeta::new_readonly(stake_pool_accounts.staker.pubkey(), false), AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false), AccountMeta::new_readonly(new_authority, false), AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false), diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 5fdb3447..879abdd4 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -408,7 +408,7 @@ async fn test_stake_pool_withdraw_from_unknown_validator() { &mut banks_client, &payer, &recent_blockhash, - &stake_pool_accounts.owner, + &stake_pool_accounts.staker, ) .await; @@ -421,7 +421,7 @@ async fn test_stake_pool_withdraw_from_unknown_validator() { &mut banks_client, &payer, &recent_blockhash, - &stake_pool_accounts.owner, + &stake_pool_accounts.staker, ) .await; From 741b90821a44b0349c462aae69530d0b640be691 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Fri, 2 Apr 2021 12:33:38 -0700 Subject: [PATCH 0078/1076] Reimplement `spl-stake-pool list` command to use the StakePool/ValidatorList as the primary source of information --- clients/cli/src/client.rs | 14 +- clients/cli/src/main.rs | 122 +++++++++++------- program/src/processor.rs | 68 +++++----- program/src/state.rs | 63 +++++---- program/tests/deposit.rs | 14 +- .../tests/update_validator_list_balance.rs | 2 +- program/tests/vsa_add.rs | 8 +- program/tests/withdraw.rs | 14 +- 8 files changed, 177 insertions(+), 128 deletions(-) diff --git a/clients/cli/src/client.rs b/clients/cli/src/client.rs index adc45bd1..1a06e722 100644 --- a/clients/cli/src/client.rs +++ b/clients/cli/src/client.rs @@ -18,17 +18,17 @@ use { type Error = Box; -pub(crate) fn get_stake_pool( +pub fn get_stake_pool( rpc_client: &RpcClient, - pool_address: &Pubkey, + stake_pool_address: &Pubkey, ) -> Result { - let account_data = rpc_client.get_account_data(pool_address)?; + let account_data = rpc_client.get_account_data(stake_pool_address)?; let stake_pool = StakePool::try_from_slice(account_data.as_slice()) - .map_err(|err| format!("Invalid stake pool {}: {}", pool_address, err))?; + .map_err(|err| format!("Invalid stake pool {}: {}", stake_pool_address, err))?; Ok(stake_pool) } -pub(crate) fn get_validator_list( +pub fn get_validator_list( rpc_client: &RpcClient, validator_list_address: &Pubkey, ) -> Result { @@ -38,7 +38,7 @@ pub(crate) fn get_validator_list( Ok(validator_list) } -pub(crate) fn get_token_account( +pub fn get_token_account( rpc_client: &RpcClient, token_account_address: &Pubkey, expected_token_mint: &Pubkey, @@ -58,7 +58,7 @@ pub(crate) fn get_token_account( } } -pub(crate) fn get_token_mint( +pub fn get_token_mint( rpc_client: &RpcClient, token_mint_address: &Pubkey, ) -> Result { diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index f056c558..b9ebce57 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -372,7 +372,7 @@ fn command_vsa_remove( // Calculate amount of tokens to withdraw let stake_account = config.rpc_client.get_account(&stake)?; let tokens_to_withdraw = stake_pool - .calc_pool_withdraw_amount(stake_account.lamports) + .calc_pool_tokens_for_withdraw(stake_account.lamports) .unwrap(); // Check balance and mint @@ -583,47 +583,84 @@ fn command_deposit( fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; + let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?; + let pool_mint = get_token_mint(&config.rpc_client, &stake_pool.pool_mint)?; + let epoch_info = config.rpc_client.get_epoch_info()?; + + for validator in validator_list.validators { + println!( + "Validator Vote Account: {}\tBalance: {}\tLast Update Epoch: {}{}", + validator.vote_account, + Sol(validator.stake_lamports), + validator.last_update_epoch, + if validator.last_update_epoch != epoch_info.epoch { + " [UPDATE REQUIRED]" + } else { + "" + } + ); + } + + println!( + "Total Pool Stake: {}{}", + Sol(stake_pool.total_stake_lamports), + if stake_pool.last_update_epoch != epoch_info.epoch { + " [UPDATE REQUIRED]" + } else { + "" + } + ); + println!( + "Total Pool Tokens: {}", + spl_token::amount_to_ui_amount(stake_pool.pool_token_supply, pool_mint.decimals) + ); if config.verbose { - println!("Current validator list"); - let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?; - for validator in validator_list.validators { + println!(); + + let pool_withdraw_authority = + find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; + + let accounts = + get_stake_accounts_by_withdraw_authority(&config.rpc_client, &pool_withdraw_authority)?; + if accounts.is_empty() { + return Err(format!("No stake accounts found for {}", pool_withdraw_authority).into()); + } + + let mut total_stake_lamports: u64 = 0; + for (pubkey, stake_lamports, stake_state) in accounts { + total_stake_lamports += stake_lamports; println!( - "Vote Account: {}\tBalance: {}\tEpoch: {}", - validator.vote_account, validator.balance, validator.last_update_epoch + "Stake Account: {}\tVote Account: {}\t{}", + pubkey, + stake_state.delegation().expect("delegation").voter_pubkey, + Sol(stake_lamports) ); } - } - - let pool_withdraw_authority = - find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; - - let accounts = - get_stake_accounts_by_withdraw_authority(&config.rpc_client, &pool_withdraw_authority)?; - if accounts.is_empty() { - return Err("No accounts found.".to_string().into()); - } + println!("Total Stake Account Balance: {}", Sol(total_stake_lamports)); - let mut total_lamports: u64 = 0; - for (pubkey, lamports, stake_state) in accounts { - total_lamports += lamports; - println!( - "Stake Account: {}\tVote Account: {}\t{}", - pubkey, - stake_state.delegation().expect("delegation").voter_pubkey, - Sol(lamports) - ); + if pool_mint.supply != stake_pool.pool_token_supply { + println!( + "BUG! Pool Tokens supply mismatch. Pool mint reports {}", + spl_token::amount_to_ui_amount(pool_mint.supply, pool_mint.decimals) + ); + } } - println!("Total Stake: {}", Sol(total_lamports)); Ok(()) } fn command_update(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; - let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?; let epoch_info = config.rpc_client.get_epoch_info()?; + if stake_pool.last_update_epoch == epoch_info.epoch { + println!("Update not required"); + return Ok(()); + } + + let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?; + let accounts_to_update: Vec = validator_list .validators .iter() @@ -651,26 +688,21 @@ fn command_update(config: &Config, stake_pool_address: &Pubkey) -> CommandResult )?); } - if instructions.is_empty() && stake_pool.last_update_epoch == epoch_info.epoch { - println!("Stake pool balances are up to date, no update required."); - Ok(()) - } else { - println!("Updating stake pool..."); - instructions.push(spl_stake_pool::instruction::update_stake_pool_balance( - &spl_stake_pool::id(), - stake_pool_address, - &stake_pool.validator_list, - )?); + println!("Updating stake pool..."); + instructions.push(spl_stake_pool::instruction::update_stake_pool_balance( + &spl_stake_pool::id(), + stake_pool_address, + &stake_pool.validator_list, + )?); - let mut transaction = - Transaction::new_with_payer(&instructions, Some(&config.fee_payer.pubkey())); + let mut transaction = + Transaction::new_with_payer(&instructions, Some(&config.fee_payer.pubkey())); - let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; - transaction.sign(&[config.fee_payer.as_ref()], recent_blockhash); - send_transaction(&config, transaction)?; - Ok(()) - } + let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; + transaction.sign(&[config.fee_payer.as_ref()], recent_blockhash); + send_transaction(&config, transaction)?; + Ok(()) } #[derive(PartialEq, Debug)] diff --git a/program/src/processor.rs b/program/src/processor.rs index a4ae3725..61fdcec5 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -513,8 +513,8 @@ impl Processor { // Calculate and mint tokens let stake_lamports = **stake_account_info.lamports.borrow(); - let token_amount = stake_pool - .calc_pool_deposit_amount(stake_lamports) + let pool_tokens = stake_pool + .calc_pool_tokens_for_deposit(stake_lamports) .ok_or(StakePoolError::CalculationFailure)?; Self::token_mint_to( stake_pool_info.key, @@ -524,7 +524,7 @@ impl Processor { withdraw_info.clone(), AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, - token_amount, + pool_tokens, )?; // Check if stake is warmed up @@ -532,13 +532,13 @@ impl Processor { validator_list.validators.push(ValidatorStakeInfo { vote_account, - balance: stake_lamports, + stake_lamports, last_update_epoch: clock.epoch, }); validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; - stake_pool.pool_total += token_amount; - stake_pool.stake_total += stake_lamports; + stake_pool.pool_token_supply += pool_tokens; + stake_pool.total_stake_lamports += stake_lamports; stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; Ok(()) @@ -622,8 +622,8 @@ impl Processor { // Calculate and burn tokens let stake_lamports = **stake_account_info.lamports.borrow(); - let token_amount = stake_pool - .calc_pool_withdraw_amount(stake_lamports) + let pool_tokens = stake_pool + .calc_pool_tokens_for_withdraw(stake_lamports) .ok_or(StakePoolError::CalculationFailure)?; Self::token_burn( stake_pool_info.key, @@ -633,7 +633,7 @@ impl Processor { withdraw_info.clone(), AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, - token_amount, + pool_tokens, )?; validator_list @@ -641,8 +641,8 @@ impl Processor { .retain(|item| item.vote_account != vote_account); validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; - stake_pool.pool_total -= token_amount; - stake_pool.stake_total -= stake_lamports; + stake_pool.pool_token_supply -= pool_tokens; + stake_pool.total_stake_lamports -= stake_lamports; stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; Ok(()) @@ -685,7 +685,7 @@ impl Processor { continue; } validator_stake_record.last_update_epoch = clock.epoch; - validator_stake_record.balance = **validator_stake_account.lamports.borrow(); + validator_stake_record.stake_lamports = **validator_stake_account.lamports.borrow(); changes = true; } } @@ -723,15 +723,15 @@ impl Processor { return Err(StakePoolError::InvalidState.into()); } - let mut total_balance: u64 = 0; + let mut total_stake_lamports: u64 = 0; for validator_stake_record in validator_list.validators { if validator_stake_record.last_update_epoch < clock.epoch { return Err(StakePoolError::StakeListOutOfDate.into()); } - total_balance += validator_stake_record.balance; + total_stake_lamports += validator_stake_record.stake_lamports; } - stake_pool.stake_total = total_balance; + stake_pool.total_stake_lamports = total_stake_lamports; stake_pool.last_update_epoch = clock.epoch; stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; @@ -830,16 +830,16 @@ impl Processor { .ok_or(StakePoolError::ValidatorNotFound)?; let stake_lamports = **stake_info.lamports.borrow(); - let pool_amount = stake_pool - .calc_pool_deposit_amount(stake_lamports) + let new_pool_tokens = stake_pool + .calc_pool_tokens_for_deposit(stake_lamports) .ok_or(StakePoolError::CalculationFailure)?; - let fee_amount = stake_pool - .calc_fee_amount(pool_amount) + let fee_pool_tokens = stake_pool + .calc_fee_amount(new_pool_tokens) .ok_or(StakePoolError::CalculationFailure)?; - let user_amount = pool_amount - .checked_sub(fee_amount) + let user_pool_tokens = new_pool_tokens + .checked_sub(fee_pool_tokens) .ok_or(StakePoolError::CalculationFailure)?; Self::stake_authorize( @@ -886,7 +886,7 @@ impl Processor { withdraw_info.clone(), AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, - user_amount, + user_pool_tokens, )?; Self::token_mint_to( @@ -897,13 +897,13 @@ impl Processor { withdraw_info.clone(), AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, - fee_amount, + fee_pool_tokens, )?; - stake_pool.pool_total += pool_amount; - stake_pool.stake_total += stake_lamports; + stake_pool.pool_token_supply += new_pool_tokens; + stake_pool.total_stake_lamports += stake_lamports; stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; - validator_list_item.balance = **validator_stake_account_info.lamports.borrow(); + validator_list_item.stake_lamports = **validator_stake_account_info.lamports.borrow(); validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; Ok(()) @@ -912,7 +912,7 @@ impl Processor { /// Processes [Withdraw](enum.Instruction.html). fn process_withdraw( program_id: &Pubkey, - pool_amount: u64, + pool_tokens: u64, accounts: &[AccountInfo], ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); @@ -965,8 +965,8 @@ impl Processor { .find_mut(&vote_account) .ok_or(StakePoolError::ValidatorNotFound)?; - let stake_amount = stake_pool - .calc_lamports_withdraw_amount(pool_amount) + let stake_lamports = stake_pool + .calc_lamports_withdraw_amount(pool_tokens) .ok_or(StakePoolError::CalculationFailure)?; Self::stake_split( @@ -975,7 +975,7 @@ impl Processor { withdraw_info.clone(), AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, - stake_amount, + stake_lamports, stake_split_to.clone(), )?; @@ -1011,14 +1011,14 @@ impl Processor { withdraw_info.clone(), AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, - pool_amount, + pool_tokens, )?; - stake_pool.pool_total -= pool_amount; - stake_pool.stake_total -= stake_amount; + stake_pool.pool_token_supply -= pool_tokens; + stake_pool.total_stake_lamports -= stake_lamports; stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; - validator_list_item.balance = **stake_split_from.lamports.borrow(); + validator_list_item.stake_lamports = **stake_split_from.lamports.borrow(); validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; Ok(()) diff --git a/program/src/state.rs b/program/src/state.rs index 86ef6bc4..48380391 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -31,60 +31,75 @@ impl Default for AccountType { pub struct StakePool { /// Account type, must be StakePool currently pub account_type: AccountType, + /// Manager authority, allows for updating the staker, manager, and fee account pub manager: Pubkey, + /// Staker authority, allows for adding and removing validators, and managing stake /// distribution pub staker: Pubkey, + /// Deposit authority bump seed /// for `create_program_address(&[state::StakePool account, "deposit"])` pub deposit_bump_seed: u8, + /// Withdrawal authority bump seed /// for `create_program_address(&[state::StakePool account, "withdrawal"])` pub withdraw_bump_seed: u8, + /// Validator stake list storage account pub validator_list: Pubkey, + /// Pool Mint pub pool_mint: Pubkey, + /// Manager fee account pub manager_fee_account: Pubkey, + /// Pool token program id pub token_program_id: Pubkey, - /// total stake under management - pub stake_total: u64, - /// total pool - pub pool_total: u64, - /// Last epoch stake_total field was updated + + /// Total stake under management. + /// Note that if `last_update_epoch` does not match the current epoch then this field may not + /// be accurate + pub total_stake_lamports: u64, + + /// Total supply of pool tokens (should always match the supply in the Pool Mint) + pub pool_token_supply: u64, + + /// Last epoch the `total_stake_lamports` field was updated pub last_update_epoch: u64, + /// Fee applied to deposits pub fee: Fee, } impl StakePool { - /// calculate the pool tokens that should be minted - pub fn calc_pool_deposit_amount(&self, stake_lamports: u64) -> Option { - if self.stake_total == 0 { + /// calculate the pool tokens that should be minted for a deposit of `stake_lamports` + pub fn calc_pool_tokens_for_deposit(&self, stake_lamports: u64) -> Option { + if self.total_stake_lamports == 0 { return Some(stake_lamports); } u64::try_from( (stake_lamports as u128) - .checked_mul(self.pool_total as u128)? - .checked_div(self.stake_total as u128)?, + .checked_mul(self.pool_token_supply as u128)? + .checked_div(self.total_stake_lamports as u128)?, ) .ok() } - /// calculate the pool tokens that should be withdrawn - pub fn calc_pool_withdraw_amount(&self, stake_lamports: u64) -> Option { + /// calculate the pool tokens that should be burned for a withdrawal of `stake_lamports` + pub fn calc_pool_tokens_for_withdraw(&self, stake_lamports: u64) -> Option { let (quotient, _) = (stake_lamports as u128) - .checked_mul(self.pool_total as u128)? - .checked_ceil_div(self.stake_total as u128)?; + .checked_mul(self.pool_token_supply as u128)? + .checked_ceil_div(self.total_stake_lamports as u128)?; u64::try_from(quotient).ok() } + /// calculate lamports amount on withdrawal pub fn calc_lamports_withdraw_amount(&self, pool_tokens: u64) -> Option { u64::try_from( (pool_tokens as u128) - .checked_mul(self.stake_total as u128)? - .checked_div(self.pool_total as u128)?, + .checked_mul(self.total_stake_lamports as u128)? + .checked_div(self.pool_token_supply as u128)?, ) .ok() } @@ -199,7 +214,7 @@ pub struct ValidatorList { /// Maximum allowable number of validators pub max_validators: u32, - /// List of all validator stake accounts and their info + /// List of stake info for each validator in the pool pub validators: Vec, } @@ -210,10 +225,12 @@ pub struct ValidatorStakeInfo { /// Validator vote account address pub vote_account: Pubkey, - /// Balance of the validator's stake account - pub balance: u64, + /// Amount of stake delegated to this validator + /// Note that if `last_update_epoch` does not match the current epoch then this field may not + /// be accurate + pub stake_lamports: u64, - /// Last epoch balance field was updated + /// Last epoch the `stake_lamports` field was updated pub last_update_epoch: u64, } @@ -308,17 +325,17 @@ mod test { validators: vec![ ValidatorStakeInfo { vote_account: Pubkey::new_from_array([1; 32]), - balance: 123456789, + stake_lamports: 123456789, last_update_epoch: 987654321, }, ValidatorStakeInfo { vote_account: Pubkey::new_from_array([2; 32]), - balance: 998877665544, + stake_lamports: 998877665544, last_update_epoch: 11223445566, }, ValidatorStakeInfo { vote_account: Pubkey::new_from_array([3; 32]), - balance: 0, + stake_lamports: 0, last_update_epoch: 999999999999999, }, ], diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index fa69ab44..3f96894e 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -177,12 +177,12 @@ async fn test_stake_pool_deposit() { let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; let stake_pool = state::StakePool::try_from_slice(&stake_pool.data.as_slice()).unwrap(); assert_eq!( - stake_pool.stake_total, - stake_pool_before.stake_total + stake_lamports + stake_pool.total_stake_lamports, + stake_pool_before.total_stake_lamports + stake_lamports ); assert_eq!( - stake_pool.pool_total, - stake_pool_before.pool_total + tokens_issued + stake_pool.pool_token_supply, + stake_pool_before.pool_token_supply + tokens_issued ); // Check minted tokens @@ -208,8 +208,8 @@ async fn test_stake_pool_deposit() { .find(&validator_stake_account.vote.pubkey()) .unwrap(); assert_eq!( - validator_stake_item.balance, - validator_stake_item_before.balance + stake_lamports + validator_stake_item.stake_lamports, + validator_stake_item_before.stake_lamports + stake_lamports ); // Check validator stake account actual SOL balance @@ -217,7 +217,7 @@ async fn test_stake_pool_deposit() { get_account(&mut banks_client, &validator_stake_account.stake_account).await; assert_eq!( validator_stake_account.lamports, - validator_stake_item.balance + validator_stake_item.stake_lamports ); } diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index 02846783..1d86deee 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -23,7 +23,7 @@ async fn get_list_sum(banks_client: &mut BanksClient, validator_list_key: &Pubke validator_list .validators .iter() - .map(|info| info.balance) + .map(|info| info.stake_lamports) .sum() } diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index 37fe9b1e..2338b515 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -98,14 +98,14 @@ async fn test_add_validator_to_pool() { .await; assert!(error.is_none()); - let stake_account_balance = banks_client + let stake_lamports = banks_client .get_account(user_stake.stake_account) .await .unwrap() .unwrap() .lamports; - let deposit_tokens = stake_account_balance; // For now 1:1 math - // Check token account balance + let deposit_tokens = stake_lamports; // For now 1:1 math + // Check token account balance let token_balance = get_token_balance(&mut banks_client, &user_pool_account.pubkey()).await; assert_eq!(token_balance, deposit_tokens); let pool_fee_token_balance = get_token_balance( @@ -131,7 +131,7 @@ async fn test_add_validator_to_pool() { validators: vec![state::ValidatorStakeInfo { vote_account: user_stake.vote.pubkey(), last_update_epoch: 0, - balance: stake_account_balance, + stake_lamports, }] } ); diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 879abdd4..db29772f 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -144,12 +144,12 @@ async fn test_stake_pool_withdraw() { let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; let stake_pool = state::StakePool::try_from_slice(&stake_pool.data.as_slice()).unwrap(); assert_eq!( - stake_pool.stake_total, - stake_pool_before.stake_total - tokens_to_burn + stake_pool.total_stake_lamports, + stake_pool_before.total_stake_lamports - tokens_to_burn ); assert_eq!( - stake_pool.pool_total, - stake_pool_before.pool_total - tokens_to_burn + stake_pool.pool_token_supply, + stake_pool_before.pool_token_supply - tokens_to_burn ); // Check validator stake list storage @@ -164,8 +164,8 @@ async fn test_stake_pool_withdraw() { .find(&validator_stake_account.vote.pubkey()) .unwrap(); assert_eq!( - validator_stake_item.balance, - validator_stake_item_before.balance - tokens_to_burn + validator_stake_item.stake_lamports, + validator_stake_item_before.stake_lamports - tokens_to_burn ); // Check tokens burned @@ -181,7 +181,7 @@ async fn test_stake_pool_withdraw() { get_account(&mut banks_client, &validator_stake_account.stake_account).await; assert_eq!( validator_stake_account.lamports, - validator_stake_item.balance + validator_stake_item.stake_lamports ); // Check user recipient stake account balance From 4469bcf1ccf6a022d70a166dea2ff75273f48879 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Fri, 2 Apr 2021 20:49:42 -0700 Subject: [PATCH 0079/1076] Break up the UpdateValidatorListBalance instructions over multiple transactions --- clients/cli/src/main.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index b9ebce57..7537b8e7 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -678,8 +678,9 @@ fn command_update(config: &Config, stake_pool_address: &Pubkey) -> CommandResult }) .collect(); - let mut instructions: Vec = vec![]; + println!("Updating stake pool..."); + let mut instructions: Vec = vec![]; for accounts_chunk in accounts_to_update.chunks(MAX_ACCOUNTS_TO_UPDATE) { instructions.push(spl_stake_pool::instruction::update_validator_list_balance( &spl_stake_pool::id(), @@ -688,20 +689,22 @@ fn command_update(config: &Config, stake_pool_address: &Pubkey) -> CommandResult )?); } - println!("Updating stake pool..."); instructions.push(spl_stake_pool::instruction::update_stake_pool_balance( &spl_stake_pool::id(), stake_pool_address, &stake_pool.validator_list, )?); - let mut transaction = - Transaction::new_with_payer(&instructions, Some(&config.fee_payer.pubkey())); + // TODO: A faster solution would be to send all the `update_validator_list_balance` instructions concurrently + for instruction in instructions { + let mut transaction = + Transaction::new_with_payer(&[instruction], Some(&config.fee_payer.pubkey())); - let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; - transaction.sign(&[config.fee_payer.as_ref()], recent_blockhash); - send_transaction(&config, transaction)?; + let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; + transaction.sign(&[config.fee_payer.as_ref()], recent_blockhash); + send_transaction(&config, transaction)?; + } Ok(()) } From 30029db6ba7a754cf45b47b00146470e2d7487c7 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Mon, 5 Apr 2021 20:06:40 +0200 Subject: [PATCH 0080/1076] stake-pool: Ensure zero pool token supply on init (#1572) --- program/src/error.rs | 3 + program/src/instruction.rs | 2 +- program/src/processor.rs | 7 ++- program/tests/helpers/mod.rs | 27 +++++++++ program/tests/initialize.rs | 109 +++++++++++++++++++++++++++-------- 5 files changed, 122 insertions(+), 26 deletions(-) diff --git a/program/src/error.rs b/program/src/error.rs index 62767d42..476ef641 100644 --- a/program/src/error.rs +++ b/program/src/error.rs @@ -82,6 +82,9 @@ pub enum StakePoolError { /// Wrong pool staker account. #[error("WrongStaker")] WrongStaker, + /// Pool token supply is not zero on initialization + #[error("NonZeroPoolTokenSupply")] + NonZeroPoolTokenSupply, } impl From for ProgramError { fn from(e: StakePoolError) -> Self { diff --git a/program/src/instruction.rs b/program/src/instruction.rs index d7073076..825d0e31 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -33,7 +33,7 @@ pub enum StakePoolInstruction { /// 1. `[s]` Manager /// 2. `[]` Staker /// 3. `[w]` Uninitialized validator stake list storage account - /// 4. `[]` Pool token mint. Must be non zero, owned by withdraw authority. + /// 4. `[]` Pool token mint. Must have zero supply, owned by withdraw authority. /// 5. `[]` Pool account to deposit the generated fee for manager. /// 6. `[]` Clock sysvar /// 7. `[]` Rent sysvar diff --git a/program/src/processor.rs b/program/src/processor.rs index 61fdcec5..3ad64bb3 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -281,7 +281,7 @@ impl Processor { } if manager_fee_info.owner != token_program_info.key { - return Err(StakePoolError::InvalidFeeAccount.into()); + return Err(ProgramError::IncorrectProgramId); } if pool_mint_info.owner != token_program_info.key { @@ -301,6 +301,10 @@ impl Processor { let pool_mint = Mint::unpack_from_slice(&pool_mint_info.data.borrow())?; + if pool_mint.supply != 0 { + return Err(StakePoolError::NonZeroPoolTokenSupply.into()); + } + if !pool_mint.mint_authority.contains(&withdraw_authority_key) { return Err(StakePoolError::WrongMintingAuthority.into()); } @@ -1155,6 +1159,7 @@ impl PrintProgramError for StakePoolError { StakePoolError::WrongMintingAuthority => msg!("Error: Wrong minting authority set for mint pool account"), StakePoolError::UnexpectedValidatorListAccountSize=> msg!("Error: The size of the given validator stake list does match the expected amount"), StakePoolError::WrongStaker=> msg!("Error: Wrong pool staker account"), + StakePoolError::NonZeroPoolTokenSupply => msg!("Error: Pool token supply is not zero on initialization"), } } } diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index fefb613d..8b22bd89 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -126,6 +126,33 @@ pub async fn create_token_account( Ok(()) } +pub async fn mint_tokens( + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + mint: &Pubkey, + account: &Pubkey, + mint_authority: &Keypair, + amount: u64, +) -> Result<(), TransportError> { + let transaction = Transaction::new_signed_with_payer( + &[spl_token::instruction::mint_to( + &spl_token::id(), + mint, + account, + &mint_authority.pubkey(), + &[], + amount, + ) + .unwrap()], + Some(&payer.pubkey()), + &[payer, mint_authority], + *recent_blockhash, + ); + banks_client.process_transaction(transaction).await?; + Ok(()) +} + pub async fn get_token_balance(banks_client: &mut BanksClient, token: &Pubkey) -> u64 { let token_account = banks_client .get_account(token.clone()) diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index 8cb2c2ff..3fcbdc83 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -52,7 +52,7 @@ async fn create_mint_and_token_account( } #[tokio::test] -async fn test_stake_pool_initialize() { +async fn success_initialize() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts @@ -77,7 +77,7 @@ async fn test_stake_pool_initialize() { } #[tokio::test] -async fn test_initialize_already_initialized_stake_pool() { +async fn fail_double_initialize() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts @@ -108,7 +108,7 @@ async fn test_initialize_already_initialized_stake_pool() { } #[tokio::test] -async fn test_initialize_stake_pool_with_already_initialized_stake_list_storage() { +async fn fail_initialize_with_already_initialized_validator_list() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts @@ -139,7 +139,7 @@ async fn test_initialize_stake_pool_with_already_initialized_stake_list_storage( } #[tokio::test] -async fn test_initialize_stake_pool_with_high_fee() { +async fn fail_initialize_with_high_fee() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let mut stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts.fee = instruction::Fee { @@ -165,7 +165,7 @@ async fn test_initialize_stake_pool_with_high_fee() { } #[tokio::test] -async fn test_initialize_stake_pool_with_wrong_max_validators() { +async fn fail_initialize_with_wrong_max_validators() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); @@ -245,7 +245,7 @@ async fn test_initialize_stake_pool_with_wrong_max_validators() { } #[tokio::test] -async fn test_initialize_stake_pool_with_wrong_mint_authority() { +async fn fail_initialize_with_wrong_mint_authority() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); let wrong_mint = Keypair::new(); @@ -299,7 +299,7 @@ async fn test_initialize_stake_pool_with_wrong_mint_authority() { } #[tokio::test] -async fn test_initialize_stake_pool_with_wrong_token_program_id() { +async fn fail_initialize_with_wrong_token_program_id() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); @@ -399,7 +399,7 @@ async fn test_initialize_stake_pool_with_wrong_token_program_id() { } #[tokio::test] -async fn test_initialize_stake_pool_with_wrong_fee_accounts_manager() { +async fn fail_initialize_with_wrong_fee_account() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); @@ -446,24 +446,17 @@ async fn test_initialize_stake_pool_with_wrong_fee_accounts_manager() { ) .await .err() + .unwrap() .unwrap(); - match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError( - _, - InstructionError::Custom(error_index), - )) => { - let program_error = error::StakePoolError::InvalidFeeAccount as u32; - assert_eq!(error_index, program_error); - } - _ => panic!( - "Wrong error occurs while try to initialize stake pool with wrong fee account's manager" - ), - } + assert_eq!( + transaction_error, + TransactionError::InstructionError(2, InstructionError::IncorrectProgramId) + ); } #[tokio::test] -async fn test_initialize_stake_pool_with_wrong_withdraw_authority() { +async fn fail_initialize_with_wrong_withdraw_authority() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let mut stake_pool_accounts = StakePoolAccounts::new(); @@ -490,7 +483,7 @@ async fn test_initialize_stake_pool_with_wrong_withdraw_authority() { } #[tokio::test] -async fn test_initialize_stake_pool_with_not_rent_exempt_pool() { +async fn fail_initialize_with_not_rent_exempt_pool() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); @@ -563,7 +556,7 @@ async fn test_initialize_stake_pool_with_not_rent_exempt_pool() { } #[tokio::test] -async fn test_initialize_stake_pool_with_not_rent_exempt_validator_list() { +async fn fail_initialize_with_not_rent_exempt_validator_list() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); @@ -638,7 +631,7 @@ async fn test_initialize_stake_pool_with_not_rent_exempt_validator_list() { } #[tokio::test] -async fn test_initialize_stake_pool_without_manager_signature() { +async fn fail_initialize_without_manager_signature() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); @@ -727,3 +720,71 @@ async fn test_initialize_stake_pool_without_manager_signature() { ), } } + +#[tokio::test] +async fn fail_initialize_with_pre_minted_pool_tokens() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + let mint_authority = Keypair::new(); + + create_mint( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.pool_mint, + &mint_authority.pubkey(), + ) + .await + .unwrap(); + + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.pool_fee_account, + &stake_pool_accounts.pool_mint.pubkey(), + &stake_pool_accounts.manager.pubkey(), + ) + .await + .unwrap(); + + mint_tokens( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.pool_mint.pubkey(), + &stake_pool_accounts.pool_fee_account.pubkey(), + &mint_authority, + 1, + ) + .await + .unwrap(); + + let transaction_error = create_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.stake_pool, + &stake_pool_accounts.validator_list, + &stake_pool_accounts.pool_mint.pubkey(), + &stake_pool_accounts.pool_fee_account.pubkey(), + &stake_pool_accounts.manager, + &stake_pool_accounts.staker.pubkey(), + &stake_pool_accounts.fee, + stake_pool_accounts.max_validators, + ) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::NonZeroPoolTokenSupply as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while try to initialize stake pool with wrong mint authority of pool fee account"), + } +} From 2bf71c9aa644cfdd31a9fb46c2b3b75dd4cf47ad Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 9 Apr 2021 12:32:21 +0200 Subject: [PATCH 0081/1076] stake-pool: Add rebalancing instruction interface (#1563) * stake-pool: Add rebalancing instruction interface * Address feedback * Rename again * Ignore rustdoc code --- program/src/instruction.rs | 108 ++++++++++++++++++++++++++++++++----- program/src/processor.rs | 8 +++ program/src/state.rs | 3 ++ 3 files changed, 107 insertions(+), 12 deletions(-) diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 825d0e31..4c586257 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -33,11 +33,13 @@ pub enum StakePoolInstruction { /// 1. `[s]` Manager /// 2. `[]` Staker /// 3. `[w]` Uninitialized validator stake list storage account - /// 4. `[]` Pool token mint. Must have zero supply, owned by withdraw authority. - /// 5. `[]` Pool account to deposit the generated fee for manager. - /// 6. `[]` Clock sysvar - /// 7. `[]` Rent sysvar - /// 8. `[]` Token program id + /// 4. `[]` Reserve stake account must be initialized, have zero balance, + /// and staker / withdrawer authority set to pool withdraw authority. + /// 5. `[]` Pool token mint. Must have zero supply, owned by withdraw authority. + /// 6. `[]` Pool account to deposit the generated fee for manager. + /// 7. `[]` Clock sysvar + /// 8. `[]` Rent sysvar + /// 9. `[]` Token program id Initialize { /// Deposit fee assessed #[allow(dead_code)] // but it's not @@ -92,18 +94,84 @@ pub enum StakePoolInstruction { /// 10. `[]` Stake program id, RemoveValidatorFromPool, - /// Updates balances of validator stake accounts in the pool + /// (Staker only) Decrease active stake on a validator, eventually moving it to the reserve /// - /// 0. `[w]` Validator stake list storage account - /// 1. `[]` Sysvar clock account - /// 2. ..2+N ` [] N validator stake accounts to update balances + /// Internally, this instruction splits a validator stake account into its + /// corresponding transient stake account and deactivates it. + /// + /// In order to rebalance the pool without taking custody, the staker needs + /// a way of reducing the stake on a stake account. This instruction splits + /// some amount of stake, up to the total activated stake, from the canonical + /// validator stake account, into its "transient" stake account, defined by: + /// + /// ```ignore + /// Pubkey::find_program_address( + /// &[&stake_account_address.to_bytes()[..32],], program_id, + /// ) + /// ``` + /// + /// The instruction only succeeds if the transient stake account does not + /// exist. The amount of lamports to move must be at least rent-exemption + /// plus 1 lamport. + /// + /// 0. `[]` Stake pool + /// 1. `[s]` Stake pool staker + /// 2. `[]` Validator list + /// 3. `[]` Stake pool withdraw authority + /// 5. `[w]` Canonical stake account to split from + /// 5. `[w]` Transient stake account to receive split + /// 6. `[]` Clock sysvar + /// 7. `[]` Rent sysvar + /// 8. `[]` System program + /// 9. `[]` Stake program + /// userdata: amount of lamports to split + DecreaseValidatorStake(u64), + + /// (Staker only) Increase stake on a validator from the reserve account + /// + /// Internally, this instruction splits reserve stake into a transient stake + /// account and delegate to the appropriate validator. `UpdateValidatorListBalance` + /// will do the work of merging once it's ready. + /// + /// This instruction only succeeds if the transient stake account does not exist. + /// The minimum amount to move is rent-exemption plus 1 SOL in order to avoid + /// issues on credits observed when merging active stakes later. + /// + /// 0. `[]` Stake pool + /// 1. `[s]` Stake pool staker + /// 2. `[]` Validator list + /// 3. `[]` Stake pool withdraw authority + /// 4. `[w]` Stake pool reserve stake + /// 5. `[w]` Transient stake account + /// 6. `[]` Canonical stake account + /// 7. '[]' Clock sysvar + /// 8. `[]` Stake program + IncreaseValidatorStake(u64), + + /// Updates balances of validator and transient stake accounts in the pool + /// + /// While going through the pairs of validator and transient stake accounts, + /// if the transient stake is inactive, it is merged into the reserve stake + /// account. If the transient stake is active and has matching credits + /// observed, it is merged into the canonical validator stake account. In + /// all other states, nothing is done, and the balance is simply added to + /// the canonical stake account balance. + /// + /// 0. `[]` Stake pool + /// 1. `[w]` Validator stake list storage account + /// 2. `[w]` Reserve stake account + /// 3. `[]` Stake pool withdraw authority + /// 4. `[]` Sysvar clock account + /// 5. `[]` Stake program + /// 6. ..6+N ` [] N pairs of validator and transient stake accounts UpdateValidatorListBalance, - /// Updates total pool balance based on balances in validator stake account list storage + /// Updates total pool balance based on balances in the reserve and validator list /// /// 0. `[w]` Stake pool /// 1. `[]` Validator stake list storage account - /// 2. `[]` Sysvar clock account + /// 2. `[]` Reserve stake account + /// 3. `[]` Sysvar clock account UpdateStakePoolBalance, /// Deposit some stake into the pool. The output is a "pool" token representing ownership @@ -127,10 +195,14 @@ pub enum StakePoolInstruction { /// Withdraw the token from the pool at the current ratio. /// The amount withdrawn is the MIN(u64, stake size) /// + /// A validator stake account can be withdrawn from freely, and the reserve + /// can only be drawn from if there is no active stake left, where all + /// validator accounts are left with 1 lamport. + /// /// 0. `[w]` Stake pool /// 1. `[w]` Validator stake list storage account /// 2. `[]` Stake pool withdraw authority - /// 3. `[w]` Validator stake account to split + /// 3. `[w]` Validator or reserve stake account to split /// 4. `[w]` Unitialized stake account to receive withdrawal /// 5. `[]` User account to set as a new withdraw authority /// 6. `[w]` User account with pool tokens to burn from @@ -289,6 +361,18 @@ pub fn remove_validator_from_pool( }) } +/// Creates `DecreaseValidatorStake` instruction (rebalance from validator account to +/// transient account) +pub fn decrease_validator_stake() -> Result { + Err(ProgramError::IncorrectProgramId) +} + +/// Creates `IncreaseValidatorStake` instruction (rebalance from reserve account to +/// transient account) +pub fn increase_validator_stake() -> Result { + Err(ProgramError::IncorrectProgramId) +} + /// Creates `UpdateValidatorListBalance` instruction (update validator stake account balances) pub fn update_validator_list_balance( program_id: &Pubkey, diff --git a/program/src/processor.rs b/program/src/processor.rs index 3ad64bb3..43ccfc2a 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1101,6 +1101,14 @@ impl Processor { msg!("Instruction: RemoveValidatorFromPool"); Self::process_remove_validator_from_pool(program_id, accounts) } + StakePoolInstruction::DecreaseValidatorStake(_amount) => { + msg!("Instruction: DecreaseValidatorStake"); + Ok(()) + } + StakePoolInstruction::IncreaseValidatorStake(_amount) => { + msg!("Instruction: IncreaseValidatorStake"); + Ok(()) + } StakePoolInstruction::UpdateValidatorListBalance => { msg!("Instruction: UpdateValidatorListBalance"); Self::process_update_validator_list_balance(program_id, accounts) diff --git a/program/src/state.rs b/program/src/state.rs index 48380391..ea71c521 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -50,6 +50,9 @@ pub struct StakePool { /// Validator stake list storage account pub validator_list: Pubkey, + /// Reserve stake account, holds deactivated stake + pub reserve_stake: Pubkey, + /// Pool Mint pub pool_mint: Pubkey, From a5ba8aae115e7ad08078a32fdd594906b7ade12d Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 15 Apr 2021 12:10:17 +0200 Subject: [PATCH 0082/1076] stake-pool: Assess fee as a percentage of rewards (#1597) * stake-pool: Collect fee every epoch as proportion of rewards * Add more complete tests * Update docs --- clients/cli/src/main.rs | 7 +- program/src/instruction.rs | 21 +- program/src/processor.rs | 74 ++++--- program/src/state.rs | 12 +- program/tests/deposit.rs | 80 +------- program/tests/helpers/mod.rs | 86 +++++++- program/tests/update_stake_pool_balance.rs | 186 +++++++++++++++--- .../tests/update_validator_list_balance.rs | 90 +++++---- 8 files changed, 362 insertions(+), 194 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 7537b8e7..f8ea85da 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -561,7 +561,6 @@ fn command_deposit( &stake, &validator_stake_account, &token_receiver, - &stake_pool.manager_fee_account, &stake_pool.pool_mint, &spl_token::id(), )?, @@ -689,10 +688,16 @@ fn command_update(config: &Config, stake_pool_address: &Pubkey) -> CommandResult )?); } + let (withdraw_authority, _) = + find_withdraw_authority_program_address(&spl_stake_pool::id(), &stake_pool_address); + instructions.push(spl_stake_pool::instruction::update_stake_pool_balance( &spl_stake_pool::id(), stake_pool_address, &stake_pool.validator_list, + &withdraw_authority, + &stake_pool.manager_fee_account, + &stake_pool.pool_mint, )?); // TODO: A faster solution would be to send all the `update_validator_list_balance` instructions concurrently diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 4c586257..46cba5ad 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -13,7 +13,8 @@ use { }, }; -/// Fee rate as a ratio, minted on deposit +/// Fee rate as a ratio, minted on `UpdateStakePoolBalance` as a proportion of +/// the rewards #[repr(C)] #[derive(Clone, Copy, Debug, Default, PartialEq, BorshSerialize, BorshDeserialize, BorshSchema)] pub struct Fee { @@ -41,7 +42,7 @@ pub enum StakePoolInstruction { /// 8. `[]` Rent sysvar /// 9. `[]` Token program id Initialize { - /// Deposit fee assessed + /// Fee assessed as percentage of perceived rewards #[allow(dead_code)] // but it's not fee: Fee, /// Maximum expected number of validators @@ -171,7 +172,11 @@ pub enum StakePoolInstruction { /// 0. `[w]` Stake pool /// 1. `[]` Validator stake list storage account /// 2. `[]` Reserve stake account - /// 3. `[]` Sysvar clock account + /// 3. `[]` Stake pool withdraw authority + /// 4. `[w]` Account to receive pool fee tokens + /// 5. `[w]` Pool mint account + /// 6. `[]` Sysvar clock account + /// 7. `[]` Pool token program UpdateStakePoolBalance, /// Deposit some stake into the pool. The output is a "pool" token representing ownership @@ -184,7 +189,6 @@ pub enum StakePoolInstruction { /// 4. `[w]` Stake account to join the pool (withdraw should be set to stake pool deposit) /// 5. `[w]` Validator stake account for the stake account to be merged with /// 6. `[w]` User account to receive pool tokens - /// 7. `[w]` Account to receive pool fee tokens /// 8. `[w]` Pool token mint account /// 9. '[]' Sysvar clock account (required) /// 10. '[]' Sysvar stake history account @@ -397,11 +401,18 @@ pub fn update_stake_pool_balance( program_id: &Pubkey, stake_pool: &Pubkey, validator_list_storage: &Pubkey, + withdraw_authority: &Pubkey, + manager_fee_account: &Pubkey, + stake_pool_mint: &Pubkey, ) -> Result { let accounts = vec![ AccountMeta::new(*stake_pool, false), AccountMeta::new(*validator_list_storage, false), + AccountMeta::new_readonly(*withdraw_authority, false), + AccountMeta::new(*manager_fee_account, false), + AccountMeta::new(*stake_pool_mint, false), AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(spl_token::id(), false), ]; Ok(Instruction { program_id: *program_id, @@ -420,7 +431,6 @@ pub fn deposit( stake_to_join: &Pubkey, validator_stake_accont: &Pubkey, pool_tokens_to: &Pubkey, - pool_fee_to: &Pubkey, pool_mint: &Pubkey, token_program_id: &Pubkey, ) -> Result { @@ -432,7 +442,6 @@ pub fn deposit( AccountMeta::new(*stake_to_join, false), AccountMeta::new(*validator_stake_accont, false), AccountMeta::new(*pool_tokens_to, false), - AccountMeta::new(*pool_fee_to, false), AccountMeta::new(*pool_mint, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), diff --git a/program/src/processor.rs b/program/src/processor.rs index 43ccfc2a..15b3ab3f 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -465,6 +465,7 @@ impl Processor { stake_pool.check_authority_deposit(deposit_info.key, program_id, stake_pool_info.key)?; stake_pool.check_staker(staker_info)?; + stake_pool.check_mint(pool_mint_info)?; if stake_pool.last_update_epoch < clock.epoch { return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); @@ -473,9 +474,6 @@ impl Processor { if stake_pool.token_program_id != *token_program_info.key { return Err(ProgramError::IncorrectProgramId); } - if stake_pool.pool_mint != *pool_mint_info.key { - return Err(StakePoolError::WrongPoolMint.into()); - } if *validator_list_info.key != stake_pool.validator_list { return Err(StakePoolError::InvalidValidatorStakeList.into()); @@ -586,9 +584,7 @@ impl Processor { if stake_pool.token_program_id != *token_program_info.key { return Err(ProgramError::IncorrectProgramId); } - if stake_pool.pool_mint != *pool_mint_info.key { - return Err(StakePoolError::WrongPoolMint.into()); - } + stake_pool.check_mint(pool_mint_info)?; if *validator_list_info.key != stake_pool.validator_list { return Err(StakePoolError::InvalidValidatorStakeList.into()); @@ -703,23 +699,35 @@ impl Processor { /// Processes `UpdateStakePoolBalance` instruction. fn process_update_stake_pool_balance( - _program_id: &Pubkey, + program_id: &Pubkey, accounts: &[AccountInfo], ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; let validator_list_info = next_account_info(account_info_iter)?; + let withdraw_info = next_account_info(account_info_iter)?; + let manager_fee_info = next_account_info(account_info_iter)?; + let pool_mint_info = next_account_info(account_info_iter)?; let clock_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(clock_info)?; + let token_program_info = next_account_info(account_info_iter)?; let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); } + stake_pool.check_mint(pool_mint_info)?; + stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?; + if stake_pool.manager_fee_account != *manager_fee_info.key { + return Err(StakePoolError::InvalidFeeAccount.into()); + } if *validator_list_info.key != stake_pool.validator_list { return Err(StakePoolError::InvalidValidatorStakeList.into()); } + if stake_pool.token_program_id != *token_program_info.key { + return Err(ProgramError::IncorrectProgramId); + } let validator_list = try_from_slice_unchecked::(&validator_list_info.data.borrow())?; @@ -727,7 +735,8 @@ impl Processor { return Err(StakePoolError::InvalidState.into()); } - let mut total_stake_lamports: u64 = 0; + let previous_lamports = stake_pool.total_stake_lamports; + let mut total_stake_lamports = 0; for validator_stake_record in validator_list.validators { if validator_stake_record.last_update_epoch < clock.epoch { return Err(StakePoolError::StakeListOutOfDate.into()); @@ -736,6 +745,29 @@ impl Processor { } stake_pool.total_stake_lamports = total_stake_lamports; + + let reward_lamports = total_stake_lamports.saturating_sub(previous_lamports); + let fee = stake_pool + .calc_fee_amount(reward_lamports) + .ok_or(StakePoolError::CalculationFailure)?; + + if fee > 0 { + Self::token_mint_to( + stake_pool_info.key, + token_program_info.clone(), + pool_mint_info.clone(), + manager_fee_info.clone(), + withdraw_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.withdraw_bump_seed, + fee, + )?; + + stake_pool.pool_token_supply = stake_pool + .pool_token_supply + .checked_add(fee) + .ok_or(StakePoolError::CalculationFailure)?; + } stake_pool.last_update_epoch = clock.epoch; stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; @@ -782,7 +814,6 @@ impl Processor { let stake_info = next_account_info(account_info_iter)?; let validator_stake_account_info = next_account_info(account_info_iter)?; let dest_user_info = next_account_info(account_info_iter)?; - let manager_fee_info = next_account_info(account_info_iter)?; let pool_mint_info = next_account_info(account_info_iter)?; let clock_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(clock_info)?; @@ -804,10 +835,8 @@ impl Processor { stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?; stake_pool.check_authority_deposit(deposit_info.key, program_id, stake_pool_info.key)?; + stake_pool.check_mint(pool_mint_info)?; - if stake_pool.manager_fee_account != *manager_fee_info.key { - return Err(StakePoolError::InvalidFeeAccount.into()); - } if stake_pool.token_program_id != *token_program_info.key { return Err(ProgramError::IncorrectProgramId); } @@ -838,14 +867,6 @@ impl Processor { .calc_pool_tokens_for_deposit(stake_lamports) .ok_or(StakePoolError::CalculationFailure)?; - let fee_pool_tokens = stake_pool - .calc_fee_amount(new_pool_tokens) - .ok_or(StakePoolError::CalculationFailure)?; - - let user_pool_tokens = new_pool_tokens - .checked_sub(fee_pool_tokens) - .ok_or(StakePoolError::CalculationFailure)?; - Self::stake_authorize( stake_pool_info.key, stake_info.clone(), @@ -890,19 +911,9 @@ impl Processor { withdraw_info.clone(), AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, - user_pool_tokens, + new_pool_tokens, )?; - Self::token_mint_to( - stake_pool_info.key, - token_program_info.clone(), - pool_mint_info.clone(), - manager_fee_info.clone(), - withdraw_info.clone(), - AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, - fee_pool_tokens, - )?; stake_pool.pool_token_supply += new_pool_tokens; stake_pool.total_stake_lamports += stake_lamports; stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; @@ -943,6 +954,7 @@ impl Processor { } stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?; + stake_pool.check_mint(pool_mint_info)?; if stake_pool.token_program_id != *token_program_info.key { return Err(ProgramError::IncorrectProgramId); diff --git a/program/src/state.rs b/program/src/state.rs index ea71c521..1dc9f5c5 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -107,10 +107,11 @@ impl StakePool { .ok() } /// calculate the fee in pool tokens that goes to the manager - pub fn calc_fee_amount(&self, pool_amount: u64) -> Option { + pub fn calc_fee_amount(&self, reward_lamports: u64) -> Option { if self.fee.denominator == 0 { return Some(0); } + let pool_amount = self.calc_pool_tokens_for_deposit(reward_lamports)?; u64::try_from( (pool_amount as u128) .checked_mul(self.fee.numerator as u128)? @@ -174,6 +175,15 @@ impl StakePool { ) } + /// Check staker validity and signature + pub(crate) fn check_mint(&self, mint_info: &AccountInfo) -> Result<(), ProgramError> { + if *mint_info.key != self.pool_mint { + Err(StakePoolError::WrongPoolMint.into()) + } else { + Ok(()) + } + } + /// Check manager validity and signature pub(crate) fn check_manager(&self, manager_info: &AccountInfo) -> Result<(), ProgramError> { if *manager_info.key != self.manager { diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 3f96894e..98a912ff 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -171,7 +171,6 @@ async fn test_stake_pool_deposit() { .is_none()); let tokens_issued = stake_lamports; // For now tokens are 1:1 to stake - let fee = stake_pool_accounts.calculate_fee(tokens_issued); // Stake pool should add its balance to the pool balance let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; @@ -188,13 +187,7 @@ async fn test_stake_pool_deposit() { // Check minted tokens let user_token_balance = get_token_balance(&mut banks_client, &user_pool_account.pubkey()).await; - assert_eq!(user_token_balance, tokens_issued - fee); - let pool_fee_token_balance = get_token_balance( - &mut banks_client, - &stake_pool_accounts.pool_fee_account.pubkey(), - ) - .await; - assert_eq!(pool_fee_token_balance, fee); + assert_eq!(user_token_balance, tokens_issued); // Check balances in validator stake account list storage let validator_list = get_account( @@ -253,7 +246,6 @@ async fn test_stake_pool_deposit_with_wrong_stake_program_id() { AccountMeta::new(user_stake.pubkey(), false), AccountMeta::new(validator_stake_account.stake_account, false), AccountMeta::new(user_pool_account.pubkey(), false), - AccountMeta::new(stake_pool_accounts.pool_fee_account.pubkey(), false), AccountMeta::new(stake_pool_accounts.pool_mint.pubkey(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), @@ -284,75 +276,6 @@ async fn test_stake_pool_deposit_with_wrong_stake_program_id() { } } -#[tokio::test] -async fn test_stake_pool_deposit_with_wrong_pool_fee_account() { - let ( - mut banks_client, - payer, - recent_blockhash, - mut stake_pool_accounts, - validator_stake_account, - ) = setup().await; - - let user = Keypair::new(); - // make stake account - let user_stake = Keypair::new(); - let lockup = stake_program::Lockup::default(); - let authorized = stake_program::Authorized { - staker: stake_pool_accounts.deposit_authority, - withdrawer: stake_pool_accounts.deposit_authority, - }; - create_independent_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake, - &authorized, - &lockup, - ) - .await; - - // make pool token account - let user_pool_account = Keypair::new(); - create_token_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_pool_account, - &stake_pool_accounts.pool_mint.pubkey(), - &user.pubkey(), - ) - .await - .unwrap(); - - let wrong_pool_fee_acc = Keypair::new(); - stake_pool_accounts.pool_fee_account = wrong_pool_fee_acc; - - let transaction_error = stake_pool_accounts - .deposit_stake( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake.pubkey(), - &user_pool_account.pubkey(), - &validator_stake_account.stake_account, - ) - .await - .err() - .unwrap(); - - match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError( - _, - InstructionError::Custom(error_index), - )) => { - let program_error = error::StakePoolError::InvalidFeeAccount as u32; - assert_eq!(error_index, program_error); - } - _ => panic!("Wrong error occurs while try to make a deposit with wrong pool fee account"), - } -} - #[tokio::test] async fn test_stake_pool_deposit_with_wrong_token_program_id() { let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake_account) = @@ -401,7 +324,6 @@ async fn test_stake_pool_deposit_with_wrong_token_program_id() { &user_stake.pubkey(), &validator_stake_account.stake_account, &user_pool_account.pubkey(), - &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), &wrong_token_program.pubkey(), ) diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 8b22bd89..298ba222 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -13,8 +13,8 @@ use { }, solana_vote_program::{self, vote_state::VoteState}, spl_stake_pool::{ - borsh::get_instance_packed_len, find_stake_program_address, id, instruction, processor, - stake_program, state, + borsh::{get_instance_packed_len, try_from_slice_unchecked}, + find_stake_program_address, id, instruction, processor, stake_program, state, }, }; @@ -154,16 +154,19 @@ pub async fn mint_tokens( } pub async fn get_token_balance(banks_client: &mut BanksClient, token: &Pubkey) -> u64 { - let token_account = banks_client - .get_account(token.clone()) - .await - .unwrap() - .unwrap(); + let token_account = banks_client.get_account(*token).await.unwrap().unwrap(); let account_info: spl_token::state::Account = spl_token::state::Account::unpack_from_slice(token_account.data.as_slice()).unwrap(); account_info.amount } +pub async fn get_token_supply(banks_client: &mut BanksClient, mint: &Pubkey) -> u64 { + let mint_account = banks_client.get_account(*mint).await.unwrap().unwrap(); + let account_info = + spl_token::state::Mint::unpack_from_slice(mint_account.data.as_slice()).unwrap(); + account_info.supply +} + pub async fn delegate_tokens( banks_client: &mut BanksClient, payer: &Keypair, @@ -559,7 +562,7 @@ impl StakePoolAccounts { pool_account: &Pubkey, validator_stake_account: &Pubkey, ) -> Result<(), TransportError> { - let mut transaction = Transaction::new_with_payer( + let transaction = Transaction::new_signed_with_payer( &[instruction::deposit( &id(), &self.stake_pool.pubkey(), @@ -569,14 +572,14 @@ impl StakePoolAccounts { stake, validator_stake_account, pool_account, - &self.pool_fee_account.pubkey(), &self.pool_mint.pubkey(), &spl_token::id(), ) .unwrap()], Some(&payer.pubkey()), + &[payer], + *recent_blockhash, ); - transaction.sign(&[payer], *recent_blockhash); banks_client.process_transaction(transaction).await?; Ok(()) } @@ -614,6 +617,50 @@ impl StakePoolAccounts { Ok(()) } + pub async fn update_validator_list_balance( + &self, + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + validator_list: &[Pubkey], + ) -> Option { + let transaction = Transaction::new_signed_with_payer( + &[instruction::update_validator_list_balance( + &id(), + &self.validator_list.pubkey(), + validator_list, + ) + .unwrap()], + Some(&payer.pubkey()), + &[payer], + *recent_blockhash, + ); + banks_client.process_transaction(transaction).await.err() + } + + pub async fn update_stake_pool_balance( + &self, + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + ) -> Option { + let transaction = Transaction::new_signed_with_payer( + &[instruction::update_stake_pool_balance( + &id(), + &self.stake_pool.pubkey(), + &self.validator_list.pubkey(), + &self.withdraw_authority, + &self.pool_fee_account.pubkey(), + &self.pool_mint.pubkey(), + ) + .unwrap()], + Some(&payer.pubkey()), + &[payer], + *recent_blockhash, + ); + banks_client.process_transaction(transaction).await.err() + } + pub async fn add_validator_to_pool( &self, banks_client: &mut BanksClient, @@ -783,3 +830,22 @@ pub async fn simple_deposit( pool_tokens, } } + +pub async fn get_validator_list_sum( + banks_client: &mut BanksClient, + validator_list_key: &Pubkey, +) -> u64 { + let validator_list = banks_client + .get_account(*validator_list_key) + .await + .unwrap() + .unwrap(); + let validator_list = + try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); + + validator_list + .validators + .iter() + .map(|info| info.stake_lamports) + .sum() +} diff --git a/program/tests/update_stake_pool_balance.rs b/program/tests/update_stake_pool_balance.rs index 2fb1790a..eb54da80 100644 --- a/program/tests/update_stake_pool_balance.rs +++ b/program/tests/update_stake_pool_balance.rs @@ -3,60 +3,192 @@ mod helpers; use { + borsh::BorshDeserialize, helpers::*, + solana_program::{instruction::InstructionError, pubkey::Pubkey}, solana_program_test::*, solana_sdk::{ - instruction::InstructionError, signature::Keypair, signature::Signer, - transaction::Transaction, transaction::TransactionError, transport::TransportError, + signature::{Keypair, Signer}, + transaction::TransactionError, }, - spl_stake_pool::*, + spl_stake_pool::{error::StakePoolError, state::StakePool}, }; +async fn setup() -> ( + ProgramTestContext, + StakePoolAccounts, + Vec, +) { + let mut context = program_test().start_with_context().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await + .unwrap(); + + // Add several accounts + let mut stake_accounts: Vec = vec![]; + const STAKE_ACCOUNTS: u64 = 3; + for _ in 0..STAKE_ACCOUNTS { + stake_accounts.push( + simple_add_validator_to_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + ) + .await, + ); + } + + (context, stake_pool_accounts, stake_accounts) +} + +#[tokio::test] +async fn success() { + let (mut context, stake_pool_accounts, stake_accounts) = setup().await; + + let error = stake_pool_accounts + .update_stake_pool_balance( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; + assert!(error.is_none()); + + // Add extra funds, simulating rewards + const EXTRA_STAKE_AMOUNT: u64 = 1_000_000; + for stake_account in &stake_accounts { + transfer( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_account.stake_account, + EXTRA_STAKE_AMOUNT, + ) + .await; + } + + let before_balance = get_validator_list_sum( + &mut context.banks_client, + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + + // Update epoch + context.warp_to_slot(50_000).unwrap(); + + // Update list and pool + let error = stake_pool_accounts + .update_validator_list_balance( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + stake_accounts + .iter() + .map(|v| v.stake_account) + .collect::>() + .as_slice(), + ) + .await; + assert!(error.is_none()); + let error = stake_pool_accounts + .update_stake_pool_balance( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; + assert!(error.is_none()); + + // Check fee + let after_balance = get_validator_list_sum( + &mut context.banks_client, + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + + let actual_fee = get_token_balance( + &mut context.banks_client, + &stake_pool_accounts.pool_fee_account.pubkey(), + ) + .await; + let pool_token_supply = get_token_supply( + &mut context.banks_client, + &stake_pool_accounts.pool_mint.pubkey(), + ) + .await; + + let stake_pool_info = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = StakePool::try_from_slice(&stake_pool_info.data).unwrap(); + let expected_fee = stake_pool + .calc_fee_amount(after_balance - before_balance) + .unwrap(); + assert_eq!(actual_fee, expected_fee); + assert_eq!(pool_token_supply, stake_pool.pool_token_supply); +} + #[tokio::test] -async fn test_update_stake_pool_balance() { +async fn fail_with_wrong_validator_list() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let mut stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) .await .unwrap(); - // TODO: Waiting for the ability to advance clock (or modify account data) to finish the tests + let wrong_validator_list = Keypair::new(); + stake_pool_accounts.validator_list = wrong_validator_list; + let error = stake_pool_accounts + .update_stake_pool_balance(&mut banks_client, &payer, &recent_blockhash) + .await + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + ) => { + let program_error = StakePoolError::InvalidValidatorStakeList as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while try to update pool balance with wrong validator stake list account"), + } } #[tokio::test] -async fn test_update_stake_pool_balance_with_wrong_validator_list() { +async fn fail_with_wrong_pool_fee_account() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let mut stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) .await .unwrap(); - let wrong_stake_list_storage = Keypair::new(); - let mut transaction = Transaction::new_with_payer( - &[instruction::update_stake_pool_balance( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &wrong_stake_list_storage.pubkey(), - ) - .unwrap()], - Some(&payer.pubkey()), - ); - - transaction.sign(&[&payer], recent_blockhash); - let transaction_error = banks_client - .process_transaction(transaction) + let wrong_fee_account = Keypair::new(); + stake_pool_accounts.pool_fee_account = wrong_fee_account; + let error = stake_pool_accounts + .update_stake_pool_balance(&mut banks_client, &payer, &recent_blockhash) .await - .err() + .unwrap() .unwrap(); - match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError( + match error { + TransactionError::InstructionError( _, InstructionError::Custom(error_index), - )) => { - let program_error = error::StakePoolError::InvalidValidatorStakeList as u32; + ) => { + let program_error = StakePoolError::InvalidFeeAccount as u32; assert_eq!(error_index, program_error); } _ => panic!("Wrong error occurs while try to update pool balance with wrong validator stake list account"), diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index 1d86deee..0270b38c 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -8,31 +8,19 @@ use { solana_program::{native_token, pubkey::Pubkey}, solana_program_test::*, solana_sdk::signature::Signer, - spl_stake_pool::{borsh::try_from_slice_unchecked, stake_program, state}, + spl_stake_pool::stake_program, }; -async fn get_list_sum(banks_client: &mut BanksClient, validator_list_key: &Pubkey) -> u64 { - let validator_list = banks_client - .get_account(*validator_list_key) - .await - .expect("get_account") - .expect("validator stake list not none"); - let validator_list = - try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); - - validator_list - .validators - .iter() - .map(|info| info.stake_lamports) - .sum() -} - #[tokio::test] -async fn test_update_validator_list_balance() { - let (mut banks_client, payer, recent_blockhash) = program_test().start().await; +async fn success() { + let mut context = program_test().start_with_context().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .initialize_stake_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) .await .unwrap(); @@ -42,44 +30,68 @@ async fn test_update_validator_list_balance() { for _ in 0..STAKE_ACCOUNTS { stake_accounts.push( simple_add_validator_to_pool( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &stake_pool_accounts, ) .await, ); } - // Add stake extra funds - const EXTRA_STAKE: u64 = 1_000_000; + let rent = context.banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()) + + native_token::sol_to_lamports(1.0); - for stake_account in stake_accounts { + // Check current balance in the list + assert_eq!( + get_validator_list_sum( + &mut context.banks_client, + &stake_pool_accounts.validator_list.pubkey() + ) + .await, + STAKE_ACCOUNTS * (stake_rent + TEST_STAKE_AMOUNT) + ); + + // Add extra funds, simulating rewards + const EXTRA_STAKE_AMOUNT: u64 = 1_000_000; + + for stake_account in &stake_accounts { transfer( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &stake_account.stake_account, - EXTRA_STAKE, + EXTRA_STAKE_AMOUNT, ) .await; } - let rent = banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()) - + native_token::sol_to_lamports(1.0); + // Update epoch + context.warp_to_slot(50_000).unwrap(); - // Check current balance in the list + stake_pool_accounts + .update_validator_list_balance( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + stake_accounts + .iter() + .map(|v| v.stake_account) + .collect::>() + .as_slice(), + ) + .await; + + // Check balance updated assert_eq!( - get_list_sum( - &mut banks_client, + get_validator_list_sum( + &mut context.banks_client, &stake_pool_accounts.validator_list.pubkey() ) .await, - STAKE_ACCOUNTS * (stake_rent + TEST_STAKE_AMOUNT) + STAKE_ACCOUNTS * (stake_rent + TEST_STAKE_AMOUNT + EXTRA_STAKE_AMOUNT) ); - - // TODO: Execute update list with updated clock } #[tokio::test] From 6bb5f1f55489e8605a10be18023e1c61063e31db Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 21 Apr 2021 13:06:43 +0200 Subject: [PATCH 0083/1076] stake-pool: Rework add / remove validator to not use pool tokens (#1581) * Rework remove * Add tests * Transition to checked math * Update CLI for new types / instructions * Cargo fmt * Rename voter_pubkey -> vote_account_address * Remove max check * Update validator balance test --- clients/cli/src/main.rs | 84 +--- program/src/error.rs | 3 + program/src/instruction.rs | 45 +-- program/src/lib.rs | 16 +- program/src/processor.rs | 339 ++++++++-------- program/src/stake_program.rs | 8 + program/src/state.rs | 22 +- program/tests/deposit.rs | 9 +- program/tests/helpers/mod.rs | 78 ++-- program/tests/update_stake_pool_balance.rs | 51 ++- .../tests/update_validator_list_balance.rs | 18 +- program/tests/vsa_add.rs | 369 ++++++++---------- program/tests/vsa_remove.rs | 281 +++---------- program/tests/withdraw.rs | 129 ++++-- 14 files changed, 639 insertions(+), 813 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index f8ea85da..5b47cf58 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -264,12 +264,7 @@ fn command_vsa_create( Ok(()) } -fn command_vsa_add( - config: &Config, - stake_pool_address: &Pubkey, - stake: &Pubkey, - token_receiver: &Option, -) -> CommandResult { +fn command_vsa_add(config: &Config, stake_pool_address: &Pubkey, stake: &Pubkey) -> CommandResult { if config.rpc_client.get_stake_activation(*stake, None)?.state != StakeActivationState::Active { return Err("Stake account is not active.".into()); } @@ -280,26 +275,9 @@ fn command_vsa_add( let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; - let mut total_rent_free_balances: u64 = 0; - - let token_receiver_account = Keypair::new(); - let mut instructions: Vec = vec![]; let mut signers = vec![config.fee_payer.as_ref(), config.staker.as_ref()]; - // Create token account if not specified - let token_receiver = unwrap_create_token_account( - &config, - &token_receiver, - &token_receiver_account, - &stake_pool.pool_mint, - &mut instructions, - |balance| { - signers.push(&token_receiver_account); - total_rent_free_balances += balance; - }, - )?; - // Calculate Deposit and Withdraw stake pool authorities let pool_deposit_authority = find_deposit_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; @@ -331,9 +309,6 @@ fn command_vsa_add( &pool_withdraw_authority, &stake_pool.validator_list, &stake, - &token_receiver, - &stake_pool.pool_mint, - &spl_token::id(), )?, ]); @@ -341,10 +316,7 @@ fn command_vsa_add( Transaction::new_with_payer(&instructions, Some(&config.fee_payer.pubkey())); let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_fee_payer_balance( - config, - total_rent_free_balances + fee_calculator.calculate_fee(&transaction.message()), - )?; + check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; unique_signers!(signers); transaction.sign(&signers, recent_blockhash); send_transaction(&config, transaction)?; @@ -355,7 +327,6 @@ fn command_vsa_remove( config: &Config, stake_pool_address: &Pubkey, stake: &Pubkey, - withdraw_from: &Pubkey, new_authority: &Option, ) -> CommandResult { if !config.no_update { @@ -369,35 +340,8 @@ fn command_vsa_remove( let staker_pubkey = config.staker.pubkey(); let new_authority = new_authority.as_ref().unwrap_or(&staker_pubkey); - // Calculate amount of tokens to withdraw - let stake_account = config.rpc_client.get_account(&stake)?; - let tokens_to_withdraw = stake_pool - .calc_pool_tokens_for_withdraw(stake_account.lamports) - .unwrap(); - - // Check balance and mint - let token_account = - get_token_account(&config.rpc_client, &withdraw_from, &stake_pool.pool_mint)?; - - if token_account.amount < tokens_to_withdraw { - let pool_mint = get_token_mint(&config.rpc_client, &stake_pool.pool_mint)?; - return Err(format!( - "Not enough balance to burn to remove validator stake account from the pool. {} pool tokens needed.", - spl_token::amount_to_ui_amount(tokens_to_withdraw, pool_mint.decimals) - ).into()); - } - let mut transaction = Transaction::new_with_payer( &[ - // Approve spending token - spl_token::instruction::approve( - &spl_token::id(), - &withdraw_from, - &pool_withdraw_authority, - &config.token_owner.pubkey(), - &[], - tokens_to_withdraw, - )?, // Create new validator stake account address spl_stake_pool::instruction::remove_validator_from_pool( &spl_stake_pool::id(), @@ -407,9 +351,6 @@ fn command_vsa_remove( &new_authority, &stake_pool.validator_list, &stake, - &withdraw_from, - &stake_pool.pool_mint, - &spl_token::id(), )?, ], Some(&config.fee_payer.pubkey()), @@ -589,7 +530,7 @@ fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { for validator in validator_list.validators { println!( "Validator Vote Account: {}\tBalance: {}\tLast Update Epoch: {}{}", - validator.vote_account, + validator.vote_account_address, Sol(validator.stake_lamports), validator.last_update_epoch, if validator.last_update_epoch != epoch_info.epoch { @@ -669,7 +610,7 @@ fn command_update(config: &Config, stake_pool_address: &Pubkey) -> CommandResult } else { let (stake_account, _) = find_stake_program_address( &spl_stake_pool::id(), - &item.vote_account, + &item.vote_account_address, &stake_pool_address, ); Some(stake_account) @@ -1439,26 +1380,13 @@ fn main() { ("add-validator", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); let stake_account = pubkey_of(arg_matches, "stake_account").unwrap(); - let token_receiver: Option = pubkey_of(arg_matches, "token_receiver"); - command_vsa_add( - &config, - &stake_pool_address, - &stake_account, - &token_receiver, - ) + command_vsa_add(&config, &stake_pool_address, &stake_account) } ("remove-validator", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); let stake_account = pubkey_of(arg_matches, "stake_account").unwrap(); - let withdraw_from = pubkey_of(arg_matches, "withdraw_from").unwrap(); let new_authority: Option = pubkey_of(arg_matches, "new_authority"); - command_vsa_remove( - &config, - &stake_pool_address, - &stake_account, - &withdraw_from, - &new_authority, - ) + command_vsa_remove(&config, &stake_pool_address, &stake_account, &new_authority) } ("deposit", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); diff --git a/program/src/error.rs b/program/src/error.rs index 476ef641..7fa227e7 100644 --- a/program/src/error.rs +++ b/program/src/error.rs @@ -85,6 +85,9 @@ pub enum StakePoolError { /// Pool token supply is not zero on initialization #[error("NonZeroPoolTokenSupply")] NonZeroPoolTokenSupply, + /// The lamports in the validator stake account is not equal to the minimum + #[error("StakeLamportsNotEqualToMinimum")] + StakeLamportsNotEqualToMinimum, } impl From for ProgramError { fn from(e: StakePoolError) -> Self { diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 46cba5ad..b2e5210c 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -64,7 +64,16 @@ pub enum StakePoolInstruction { CreateValidatorStakeAccount, /// (Staker only) Adds stake account delegated to validator to the pool's - /// list of managed validators + /// list of managed validators. + /// + /// The stake account must have the rent-exempt amount plus at least 1 SOL, + /// and at most 1.001 SOL. + /// + /// Once we delegate even 1 SOL, it will accrue rewards one epoch later, + /// so we'll have more than 1 active SOL at this point. + /// At 10% annualized rewards, 1 epoch of 2 days will accrue + /// 0.000547945 SOL, so we check that it is at least 1 SOL, and at most + /// 1.001 SOL. /// /// 0. `[w]` Stake pool /// 1. `[s]` Staker @@ -72,26 +81,23 @@ pub enum StakePoolInstruction { /// 3. `[]` Stake pool withdraw authority /// 4. `[w]` Validator stake list storage account /// 5. `[w]` Stake account to add to the pool, its withdraw authority should be set to stake pool deposit - /// 6. `[w]` User account to receive pool tokens - /// 7. `[w]` Pool token mint account - /// 8. `[]` Clock sysvar (required) - /// 9. '[]' Sysvar stake history account - /// 10. `[]` Pool token program id, - /// 11. `[]` Stake program id, + /// 6. `[]` Clock sysvar + /// 7. '[]' Sysvar stake history account + /// 8. `[]` Stake program AddValidatorToPool, /// (Staker only) Removes validator from the pool /// + /// Only succeeds if the validator stake account has the minimum of 1 SOL + /// plus the rent-exempt amount. + /// /// 0. `[w]` Stake pool /// 1. `[s]` Staker /// 2. `[]` Stake pool withdraw authority /// 3. `[]` New withdraw/staker authority to set in the stake account /// 4. `[w]` Validator stake list storage account /// 5. `[w]` Stake account to remove from the pool - /// 6. `[w]` User account with pool tokens to burn from - /// 7. `[w]` Pool token mint account - /// 8. '[]' Sysvar clock account (required) - /// 9. `[]` Pool token program id + /// 8. '[]' Sysvar clock /// 10. `[]` Stake program id, RemoveValidatorFromPool, @@ -197,7 +203,10 @@ pub enum StakePoolInstruction { Deposit, /// Withdraw the token from the pool at the current ratio. - /// The amount withdrawn is the MIN(u64, stake size) + /// + /// Succeeds if the stake account has enough SOL to cover the desired amount + /// of pool tokens, and if the withdrawal keeps the total staked amount + /// above the minimum of rent-exempt amount + 1 SOL. /// /// A validator stake account can be withdrawn from freely, and the reserve /// can only be drawn from if there is no active stake left, where all @@ -307,9 +316,6 @@ pub fn add_validator_to_pool( stake_pool_withdraw: &Pubkey, validator_list: &Pubkey, stake_account: &Pubkey, - pool_token_receiver: &Pubkey, - pool_mint: &Pubkey, - token_program_id: &Pubkey, ) -> Result { let accounts = vec![ AccountMeta::new(*stake_pool, false), @@ -318,11 +324,8 @@ pub fn add_validator_to_pool( AccountMeta::new_readonly(*stake_pool_withdraw, false), AccountMeta::new(*validator_list, false), AccountMeta::new(*stake_account, false), - AccountMeta::new(*pool_token_receiver, false), - AccountMeta::new(*pool_mint, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), - AccountMeta::new_readonly(*token_program_id, false), AccountMeta::new_readonly(stake_program::id(), false), ]; Ok(Instruction { @@ -341,9 +344,6 @@ pub fn remove_validator_from_pool( new_stake_authority: &Pubkey, validator_list: &Pubkey, stake_account: &Pubkey, - burn_from: &Pubkey, - pool_mint: &Pubkey, - token_program_id: &Pubkey, ) -> Result { let accounts = vec![ AccountMeta::new(*stake_pool, false), @@ -352,10 +352,7 @@ pub fn remove_validator_from_pool( AccountMeta::new_readonly(*new_stake_authority, false), AccountMeta::new(*validator_list, false), AccountMeta::new(*stake_account, false), - AccountMeta::new(*burn_from, false), - AccountMeta::new(*pool_mint, false), AccountMeta::new_readonly(sysvar::clock::id(), false), - AccountMeta::new_readonly(*token_program_id, false), AccountMeta::new_readonly(stake_program::id(), false), ]; Ok(Instruction { diff --git a/program/src/lib.rs b/program/src/lib.rs index 964f263e..c681105b 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -14,7 +14,10 @@ pub mod entrypoint; // Export current sdk types for downstream users building with a different sdk version pub use solana_program; -use solana_program::pubkey::Pubkey; +use { + crate::stake_program::Meta, + solana_program::{native_token::LAMPORTS_PER_SOL, pubkey::Pubkey}, +}; /// Seed for deposit authority seed const AUTHORITY_DEPOSIT: &[u8] = b"deposit"; @@ -22,6 +25,17 @@ const AUTHORITY_DEPOSIT: &[u8] = b"deposit"; /// Seed for withdraw authority seed const AUTHORITY_WITHDRAW: &[u8] = b"withdraw"; +/// Minimum amount of staked SOL required in a validator stake account to allow +/// for merges without a mismatch on credits observed +pub const MINIMUM_ACTIVE_STAKE: u64 = LAMPORTS_PER_SOL; + +/// Get the stake amount under consideration when calculating pool token +/// conversions +pub fn minimum_stake_lamports(meta: &Meta) -> u64 { + meta.rent_exempt_reserve + .saturating_add(MINIMUM_ACTIVE_STAKE) +} + /// Generates the deposit authority program address for the stake pool pub fn find_deposit_authority_program_address( program_id: &Pubkey, diff --git a/program/src/processor.rs b/program/src/processor.rs index 15b3ab3f..f4e26ab0 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -5,9 +5,9 @@ use { borsh::try_from_slice_unchecked, error::StakePoolError, instruction::{Fee, StakePoolInstruction}, - stake_program, + minimum_stake_lamports, stake_program, state::{AccountType, StakePool, ValidatorList, ValidatorStakeInfo}, - AUTHORITY_DEPOSIT, AUTHORITY_WITHDRAW, + AUTHORITY_DEPOSIT, AUTHORITY_WITHDRAW, MINIMUM_ACTIVE_STAKE, }, bincode::deserialize, borsh::{BorshDeserialize, BorshSerialize}, @@ -19,7 +19,6 @@ use { decode_error::DecodeError, entrypoint::ProgramResult, msg, - native_token::sol_to_lamports, program::{invoke, invoke_signed}, program_error::PrintProgramError, program_error::ProgramError, @@ -27,57 +26,59 @@ use { pubkey::Pubkey, rent::Rent, stake_history::StakeHistory, - system_instruction, + system_instruction, system_program, sysvar::Sysvar, }, spl_token::state::Mint, }; -/// Program state handler. -pub struct Processor {} -impl Processor { - /// Returns validator address for a particular stake account - fn get_validator(stake_account_info: &AccountInfo) -> Result { - let stake_state: stake_program::StakeState = deserialize(&stake_account_info.data.borrow()) - .or(Err(ProgramError::InvalidAccountData))?; - match stake_state { - stake_program::StakeState::Stake(_, stake) => Ok(stake.delegation.voter_pubkey), - _ => Err(StakePoolError::WrongStakeState.into()), - } - } - - /// Checks if validator stake account is a proper program address - fn is_validator_stake_address( - vote_account: &Pubkey, - program_id: &Pubkey, - stake_pool_info: &AccountInfo, - stake_account_info: &AccountInfo, - ) -> bool { - // Check stake account address validity - let (stake_address, _) = - crate::find_stake_program_address(&program_id, &vote_account, &stake_pool_info.key); - stake_address == *stake_account_info.key +/// Deserialize the stake state from AccountInfo +fn get_stake_state( + stake_account_info: &AccountInfo, +) -> Result<(stake_program::Meta, stake_program::Stake), ProgramError> { + let stake_state: stake_program::StakeState = + deserialize(&stake_account_info.data.borrow()).or(Err(ProgramError::InvalidAccountData))?; + match stake_state { + stake_program::StakeState::Stake(meta, stake) => Ok((meta, stake)), + _ => Err(StakePoolError::WrongStakeState.into()), } +} - /// Returns validator address for a particular stake account and checks its validity - fn get_validator_checked( - program_id: &Pubkey, - stake_pool_info: &AccountInfo, - stake_account_info: &AccountInfo, - ) -> Result { - let vote_account = Self::get_validator(stake_account_info)?; +/// Checks if validator stake account is a proper program address +fn is_validator_stake_address( + program_id: &Pubkey, + stake_pool_address: &Pubkey, + stake_account_address: &Pubkey, + vote_address: &Pubkey, +) -> bool { + // Check stake account address validity + let (stake_address, _) = + crate::find_stake_program_address(&program_id, &vote_address, &stake_pool_address); + stake_address == *stake_account_address +} - if !Self::is_validator_stake_address( - &vote_account, - program_id, - stake_pool_info, - stake_account_info, - ) { - return Err(StakePoolError::InvalidStakeAccountAddress.into()); - } - Ok(vote_account) +/// Check validity of vote address for a particular stake account +fn check_validator_stake_address( + program_id: &Pubkey, + stake_pool_address: &Pubkey, + stake_account_address: &Pubkey, + vote_address: &Pubkey, +) -> Result<(), ProgramError> { + if !is_validator_stake_address( + program_id, + stake_pool_address, + stake_account_address, + vote_address, + ) { + Err(StakePoolError::InvalidStakeAccountAddress.into()) + } else { + Ok(()) } +} +/// Program state handler. +pub struct Processor {} +impl Processor { /// Issue a stake_split instruction. fn stake_split<'a>( stake_pool: &Pubkey, @@ -359,7 +360,7 @@ impl Processor { } stake_pool.check_staker(staker_info)?; - if *system_program_info.key != solana_program::system_program::id() { + if *system_program_info.key != system_program::id() { return Err(ProgramError::IncorrectProgramId); } if *stake_program_info.key != stake_program::id() { @@ -382,7 +383,7 @@ impl Processor { ]; // Fund the stake account with 1 SOL + rent-exempt balance - let required_lamports = sol_to_lamports(1.0) + let required_lamports = MINIMUM_ACTIVE_STAKE + rent.minimum_balance(std::mem::size_of::()); // Create new stake account @@ -443,20 +444,20 @@ impl Processor { let withdraw_info = next_account_info(account_info_iter)?; let validator_list_info = next_account_info(account_info_iter)?; let stake_account_info = next_account_info(account_info_iter)?; - let dest_user_info = next_account_info(account_info_iter)?; - let pool_mint_info = next_account_info(account_info_iter)?; let clock_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(clock_info)?; let stake_history_info = next_account_info(account_info_iter)?; let stake_history = &StakeHistory::from_account_info(stake_history_info)?; - let token_program_info = next_account_info(account_info_iter)?; let stake_program_info = next_account_info(account_info_iter)?; if *stake_program_info.key != stake_program::id() { return Err(ProgramError::IncorrectProgramId); } - let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; + if stake_pool_info.owner != program_id { + return Err(ProgramError::IncorrectProgramId); + } + let stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); } @@ -465,16 +466,11 @@ impl Processor { stake_pool.check_authority_deposit(deposit_info.key, program_id, stake_pool_info.key)?; stake_pool.check_staker(staker_info)?; - stake_pool.check_mint(pool_mint_info)?; if stake_pool.last_update_epoch < clock.epoch { return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); } - if stake_pool.token_program_id != *token_program_info.key { - return Err(ProgramError::IncorrectProgramId); - } - if *validator_list_info.key != stake_pool.validator_list { return Err(StakePoolError::InvalidValidatorStakeList.into()); } @@ -488,13 +484,34 @@ impl Processor { return Err(ProgramError::AccountDataTooSmall); } - let vote_account = - Self::get_validator_checked(program_id, stake_pool_info, stake_account_info)?; + let (meta, stake) = get_stake_state(stake_account_info)?; + let vote_account_address = stake.delegation.voter_pubkey; + check_validator_stake_address( + program_id, + stake_pool_info.key, + stake_account_info.key, + &vote_account_address, + )?; - if validator_list.contains(&vote_account) { + if validator_list.contains(&vote_account_address) { return Err(StakePoolError::ValidatorAlreadyAdded.into()); } + // Check amount of lamports + let stake_lamports = **stake_account_info.lamports.borrow(); + let minimum_lamport_amount = minimum_stake_lamports(&meta); + if stake_lamports != minimum_lamport_amount { + msg!( + "Error: attempting to add stake with {} lamports, must have {} lamports", + stake_lamports, + minimum_lamport_amount + ); + return Err(StakePoolError::StakeLamportsNotEqualToMinimum.into()); + } + + // Check if stake is warmed up + Self::check_stake_activation(stake_account_info, clock, stake_history)?; + // Update Withdrawer and Staker authority to the program withdraw authority for authority in &[ stake_program::StakeAuthorize::Withdrawer, @@ -513,36 +530,13 @@ impl Processor { )?; } - // Calculate and mint tokens - let stake_lamports = **stake_account_info.lamports.borrow(); - let pool_tokens = stake_pool - .calc_pool_tokens_for_deposit(stake_lamports) - .ok_or(StakePoolError::CalculationFailure)?; - Self::token_mint_to( - stake_pool_info.key, - token_program_info.clone(), - pool_mint_info.clone(), - dest_user_info.clone(), - withdraw_info.clone(), - AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, - pool_tokens, - )?; - - // Check if stake is warmed up - Self::check_stake_activation(stake_account_info, clock, stake_history)?; - validator_list.validators.push(ValidatorStakeInfo { - vote_account, - stake_lamports, + vote_account_address, + stake_lamports: stake_lamports.saturating_sub(minimum_lamport_amount), last_update_epoch: clock.epoch, }); validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; - stake_pool.pool_token_supply += pool_tokens; - stake_pool.total_stake_lamports += stake_lamports; - stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; - Ok(()) } @@ -558,18 +552,18 @@ impl Processor { let new_stake_authority_info = next_account_info(account_info_iter)?; let validator_list_info = next_account_info(account_info_iter)?; let stake_account_info = next_account_info(account_info_iter)?; - let burn_from_info = next_account_info(account_info_iter)?; - let pool_mint_info = next_account_info(account_info_iter)?; let clock_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(clock_info)?; - let token_program_info = next_account_info(account_info_iter)?; let stake_program_info = next_account_info(account_info_iter)?; if *stake_program_info.key != stake_program::id() { return Err(ProgramError::IncorrectProgramId); } - let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; + if stake_pool_info.owner != program_id { + return Err(ProgramError::IncorrectProgramId); + } + let stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); } @@ -581,11 +575,6 @@ impl Processor { return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); } - if stake_pool.token_program_id != *token_program_info.key { - return Err(ProgramError::IncorrectProgramId); - } - stake_pool.check_mint(pool_mint_info)?; - if *validator_list_info.key != stake_pool.validator_list { return Err(StakePoolError::InvalidValidatorStakeList.into()); } @@ -596,13 +585,30 @@ impl Processor { return Err(StakePoolError::InvalidState.into()); } - let vote_account = - Self::get_validator_checked(program_id, stake_pool_info, stake_account_info)?; + let (meta, stake) = get_stake_state(stake_account_info)?; + let vote_account_address = stake.delegation.voter_pubkey; + check_validator_stake_address( + program_id, + stake_pool_info.key, + stake_account_info.key, + &vote_account_address, + )?; - if !validator_list.contains(&vote_account) { + if !validator_list.contains(&vote_account_address) { return Err(StakePoolError::ValidatorNotFound.into()); } + let stake_lamports = **stake_account_info.lamports.borrow(); + let required_lamports = minimum_stake_lamports(&meta); + if stake_lamports != required_lamports { + msg!( + "Attempting to remove validator account with {} lamports, must have {} lamports", + stake_lamports, + required_lamports + ); + return Err(StakePoolError::StakeLamportsNotEqualToMinimum.into()); + } + for authority in &[ stake_program::StakeAuthorize::Withdrawer, stake_program::StakeAuthorize::Staker, @@ -620,31 +626,11 @@ impl Processor { )?; } - // Calculate and burn tokens - let stake_lamports = **stake_account_info.lamports.borrow(); - let pool_tokens = stake_pool - .calc_pool_tokens_for_withdraw(stake_lamports) - .ok_or(StakePoolError::CalculationFailure)?; - Self::token_burn( - stake_pool_info.key, - token_program_info.clone(), - burn_from_info.clone(), - pool_mint_info.clone(), - withdraw_info.clone(), - AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, - pool_tokens, - )?; - validator_list .validators - .retain(|item| item.vote_account != vote_account); + .retain(|item| item.vote_account_address != vote_account_address); validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; - stake_pool.pool_token_supply -= pool_tokens; - stake_pool.total_stake_lamports -= stake_lamports; - stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; - Ok(()) } @@ -665,10 +651,11 @@ impl Processor { return Err(StakePoolError::InvalidState.into()); } - let vote_accounts: Vec> = validator_stake_accounts - .iter() - .map(|stake| Self::get_validator(stake).ok()) - .collect(); + let stake_states: Vec<(stake_program::Meta, stake_program::Stake)> = + validator_stake_accounts + .iter() + .filter_map(|stake| get_stake_state(stake).ok()) + .collect(); let mut changes = false; // Do a brute iteration through the list, optimize if necessary @@ -676,16 +663,17 @@ impl Processor { if validator_stake_record.last_update_epoch >= clock.epoch { continue; } - for (validator_stake_account, vote_account) in - validator_stake_accounts.iter().zip(vote_accounts.iter()) + for (validator_stake_account, (meta, stake)) in + validator_stake_accounts.iter().zip(stake_states.iter()) { - if validator_stake_record.vote_account - != vote_account.ok_or(StakePoolError::WrongStakeState)? - { + if validator_stake_record.vote_account_address != stake.delegation.voter_pubkey { continue; } validator_stake_record.last_update_epoch = clock.epoch; - validator_stake_record.stake_lamports = **validator_stake_account.lamports.borrow(); + validator_stake_record.stake_lamports = validator_stake_account + .lamports + .borrow() + .saturating_sub(minimum_stake_lamports(&meta)); changes = true; } } @@ -736,16 +724,16 @@ impl Processor { } let previous_lamports = stake_pool.total_stake_lamports; - let mut total_stake_lamports = 0; + let mut total_stake_lamports: u64 = 0; for validator_stake_record in validator_list.validators { if validator_stake_record.last_update_epoch < clock.epoch { return Err(StakePoolError::StakeListOutOfDate.into()); } - total_stake_lamports += validator_stake_record.stake_lamports; + total_stake_lamports = total_stake_lamports + .checked_add(validator_stake_record.stake_lamports) + .ok_or(StakePoolError::CalculationFailure)?; } - stake_pool.total_stake_lamports = total_stake_lamports; - let reward_lamports = total_stake_lamports.saturating_sub(previous_lamports); let fee = stake_pool .calc_fee_amount(reward_lamports) @@ -768,6 +756,7 @@ impl Processor { .checked_add(fee) .ok_or(StakePoolError::CalculationFailure)?; } + stake_pool.total_stake_lamports = total_stake_lamports; stake_pool.last_update_epoch = clock.epoch; stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; @@ -855,11 +844,17 @@ impl Processor { return Err(StakePoolError::InvalidState.into()); } - let vote_account = - Self::get_validator_checked(program_id, stake_pool_info, validator_stake_account_info)?; + let (meta, stake) = get_stake_state(validator_stake_account_info)?; + let vote_account_address = stake.delegation.voter_pubkey; + check_validator_stake_address( + program_id, + stake_pool_info.key, + validator_stake_account_info.key, + &vote_account_address, + )?; let validator_list_item = validator_list - .find_mut(&vote_account) + .find_mut(&vote_account_address) .ok_or(StakePoolError::ValidatorNotFound)?; let stake_lamports = **stake_info.lamports.borrow(); @@ -914,11 +909,21 @@ impl Processor { new_pool_tokens, )?; - stake_pool.pool_token_supply += new_pool_tokens; - stake_pool.total_stake_lamports += stake_lamports; + stake_pool.pool_token_supply = stake_pool + .pool_token_supply + .checked_add(new_pool_tokens) + .ok_or(StakePoolError::CalculationFailure)?; + stake_pool.total_stake_lamports = stake_pool + .total_stake_lamports + .checked_add(stake_lamports) + .ok_or(StakePoolError::CalculationFailure)?; stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; - validator_list_item.stake_lamports = **validator_stake_account_info.lamports.borrow(); + validator_list_item.stake_lamports = validator_stake_account_info + .lamports + .borrow() + .checked_sub(minimum_stake_lamports(&meta)) + .ok_or(StakePoolError::CalculationFailure)?; validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; Ok(()) @@ -974,24 +979,49 @@ impl Processor { return Err(StakePoolError::InvalidState.into()); } - let vote_account = - Self::get_validator_checked(program_id, stake_pool_info, stake_split_from)?; + let (meta, stake) = get_stake_state(stake_split_from)?; + let vote_account_address = stake.delegation.voter_pubkey; + check_validator_stake_address( + program_id, + stake_pool_info.key, + stake_split_from.key, + &vote_account_address, + )?; let validator_list_item = validator_list - .find_mut(&vote_account) + .find_mut(&vote_account_address) .ok_or(StakePoolError::ValidatorNotFound)?; - let stake_lamports = stake_pool + let withdraw_lamports = stake_pool .calc_lamports_withdraw_amount(pool_tokens) .ok_or(StakePoolError::CalculationFailure)?; + let required_lamports = minimum_stake_lamports(&meta); + let current_lamports = **stake_split_from.lamports.borrow(); + let remaining_lamports = current_lamports.saturating_sub(withdraw_lamports); + if remaining_lamports < required_lamports { + msg!("Attempting to withdraw {} lamports from validator account with {} lamports, {} must remain", withdraw_lamports, current_lamports, required_lamports); + return Err(StakePoolError::StakeLamportsNotEqualToMinimum.into()); + } + + Self::token_burn( + stake_pool_info.key, + token_program_info.clone(), + burn_from_info.clone(), + pool_mint_info.clone(), + withdraw_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.withdraw_bump_seed, + pool_tokens, + )?; + Self::stake_split( stake_pool_info.key, stake_split_from.clone(), withdraw_info.clone(), AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, - stake_lamports, + withdraw_lamports, stake_split_to.clone(), )?; @@ -1019,22 +1049,20 @@ impl Processor { stake_program_info.clone(), )?; - Self::token_burn( - stake_pool_info.key, - token_program_info.clone(), - burn_from_info.clone(), - pool_mint_info.clone(), - withdraw_info.clone(), - AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, - pool_tokens, - )?; - - stake_pool.pool_token_supply -= pool_tokens; - stake_pool.total_stake_lamports -= stake_lamports; + stake_pool.pool_token_supply = stake_pool + .pool_token_supply + .checked_sub(pool_tokens) + .ok_or(StakePoolError::CalculationFailure)?; + stake_pool.total_stake_lamports = stake_pool + .total_stake_lamports + .checked_sub(withdraw_lamports) + .ok_or(StakePoolError::CalculationFailure)?; stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; - validator_list_item.stake_lamports = **stake_split_from.lamports.borrow(); + validator_list_item.stake_lamports = validator_list_item + .stake_lamports + .checked_sub(withdraw_lamports) + .ok_or(StakePoolError::CalculationFailure)?; validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; Ok(()) @@ -1180,6 +1208,7 @@ impl PrintProgramError for StakePoolError { StakePoolError::UnexpectedValidatorListAccountSize=> msg!("Error: The size of the given validator stake list does match the expected amount"), StakePoolError::WrongStaker=> msg!("Error: Wrong pool staker account"), StakePoolError::NonZeroPoolTokenSupply => msg!("Error: Pool token supply is not zero on initialization"), + StakePoolError::StakeLamportsNotEqualToMinimum => msg!("Error: The lamports in the validator stake account is not equal to the minimum"), } } } diff --git a/program/src/stake_program.rs b/program/src/stake_program.rs index 2eeb53b3..3ea41fd3 100644 --- a/program/src/stake_program.rs +++ b/program/src/stake_program.rs @@ -200,6 +200,14 @@ impl StakeState { _ => None, } } + /// Get meta + pub fn meta(&self) -> Option<&Meta> { + match self { + StakeState::Initialized(meta) => Some(meta), + StakeState::Stake(meta, _) => Some(meta), + _ => None, + } + } } /// FIXME copied from the stake program diff --git a/program/src/state.rs b/program/src/state.rs index 1dc9f5c5..ad41c4e0 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -79,7 +79,7 @@ pub struct StakePool { impl StakePool { /// calculate the pool tokens that should be minted for a deposit of `stake_lamports` pub fn calc_pool_tokens_for_deposit(&self, stake_lamports: u64) -> Option { - if self.total_stake_lamports == 0 { + if self.total_stake_lamports == 0 || self.pool_token_supply == 0 { return Some(stake_lamports); } u64::try_from( @@ -236,7 +236,7 @@ pub struct ValidatorList { #[derive(Clone, Copy, Debug, Default, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)] pub struct ValidatorStakeInfo { /// Validator vote account address - pub vote_account: Pubkey, + pub vote_account_address: Pubkey, /// Amount of stake delegated to this validator /// Note that if `last_update_epoch` does not match the current epoch then this field may not @@ -264,23 +264,23 @@ impl ValidatorList { } /// Check if contains validator with particular pubkey - pub fn contains(&self, vote_account: &Pubkey) -> bool { + pub fn contains(&self, vote_account_address: &Pubkey) -> bool { self.validators .iter() - .any(|x| x.vote_account == *vote_account) + .any(|x| x.vote_account_address == *vote_account_address) } /// Check if contains validator with particular pubkey - pub fn find_mut(&mut self, vote_account: &Pubkey) -> Option<&mut ValidatorStakeInfo> { + pub fn find_mut(&mut self, vote_account_address: &Pubkey) -> Option<&mut ValidatorStakeInfo> { self.validators .iter_mut() - .find(|x| x.vote_account == *vote_account) + .find(|x| x.vote_account_address == *vote_account_address) } /// Check if contains validator with particular pubkey - pub fn find(&self, vote_account: &Pubkey) -> Option<&ValidatorStakeInfo> { + pub fn find(&self, vote_account_address: &Pubkey) -> Option<&ValidatorStakeInfo> { self.validators .iter() - .find(|x| x.vote_account == *vote_account) + .find(|x| x.vote_account_address == *vote_account_address) } /// Check if validator stake list is actually initialized as a validator stake list @@ -337,17 +337,17 @@ mod test { max_validators, validators: vec![ ValidatorStakeInfo { - vote_account: Pubkey::new_from_array([1; 32]), + vote_account_address: Pubkey::new_from_array([1; 32]), stake_lamports: 123456789, last_update_epoch: 987654321, }, ValidatorStakeInfo { - vote_account: Pubkey::new_from_array([2; 32]), + vote_account_address: Pubkey::new_from_array([2; 32]), stake_lamports: 998877665544, last_update_epoch: 11223445566, }, ValidatorStakeInfo { - vote_account: Pubkey::new_from_array([3; 32]), + vote_account_address: Pubkey::new_from_array([3; 32]), stake_lamports: 0, last_update_epoch: 999999999999999, }, diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 98a912ff..db3b4545 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -3,6 +3,7 @@ mod helpers; use { + bincode::deserialize, borsh::{BorshDeserialize, BorshSerialize}, helpers::*, solana_program::{ @@ -19,7 +20,8 @@ use { transport::TransportError, }, spl_stake_pool::{ - borsh::try_from_slice_unchecked, error, id, instruction, stake_program, state, + borsh::try_from_slice_unchecked, error, id, instruction, minimum_stake_lamports, + stake_program, state, }, spl_token::error as token_error, }; @@ -208,8 +210,11 @@ async fn test_stake_pool_deposit() { // Check validator stake account actual SOL balance let validator_stake_account = get_account(&mut banks_client, &validator_stake_account.stake_account).await; + let stake_state = + deserialize::(&validator_stake_account.data).unwrap(); + let meta = stake_state.meta().unwrap(); assert_eq!( - validator_stake_account.lamports, + validator_stake_account.lamports - minimum_stake_lamports(&meta), validator_stake_item.stake_lamports ); } diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 298ba222..8da7ee77 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -79,15 +79,16 @@ pub async fn transfer( recipient: &Pubkey, amount: u64, ) { - let mut transaction = Transaction::new_with_payer( + let transaction = Transaction::new_signed_with_payer( &[system_instruction::transfer( &payer.pubkey(), recipient, amount, )], Some(&payer.pubkey()), + &[payer], + *recent_blockhash, ); - transaction.sign(&[payer], *recent_blockhash); banks_client.process_transaction(transaction).await.unwrap(); } @@ -287,7 +288,7 @@ pub async fn create_independent_stake_account( let lamports = rent.minimum_balance(std::mem::size_of::()) + TEST_STAKE_AMOUNT; - let mut transaction = Transaction::new_with_payer( + let transaction = Transaction::new_signed_with_payer( &stake_program::create_account( &payer.pubkey(), &stake.pubkey(), @@ -296,8 +297,9 @@ pub async fn create_independent_stake_account( lamports, ), Some(&payer.pubkey()), + &[payer, stake], + *recent_blockhash, ); - transaction.sign(&[payer, stake], *recent_blockhash); banks_client.process_transaction(transaction).await.unwrap(); lamports @@ -312,7 +314,7 @@ pub async fn create_blank_stake_account( let rent = banks_client.get_rent().await.unwrap(); let lamports = rent.minimum_balance(std::mem::size_of::()) + 1; - let mut transaction = Transaction::new_with_payer( + let transaction = Transaction::new_signed_with_payer( &[system_instruction::create_account( &payer.pubkey(), &stake.pubkey(), @@ -321,8 +323,9 @@ pub async fn create_blank_stake_account( &stake_program::id(), )], Some(&payer.pubkey()), + &[payer, stake], + *recent_blockhash, ); - transaction.sign(&[payer, stake], *recent_blockhash); banks_client.process_transaction(transaction).await.unwrap(); lamports @@ -337,22 +340,20 @@ pub async fn create_validator_stake_account( stake_account: &Pubkey, validator: &Pubkey, ) { - let mut transaction = Transaction::new_with_payer( - &[ - instruction::create_validator_stake_account( - &id(), - &stake_pool, - &staker.pubkey(), - &payer.pubkey(), - &stake_account, - &validator, - ) - .unwrap(), - system_instruction::transfer(&payer.pubkey(), &stake_account, TEST_STAKE_AMOUNT), - ], + let transaction = Transaction::new_signed_with_payer( + &[instruction::create_validator_stake_account( + &id(), + &stake_pool, + &staker.pubkey(), + &payer.pubkey(), + &stake_account, + &validator, + ) + .unwrap()], Some(&payer.pubkey()), + &[payer, staker], + *recent_blockhash, ); - transaction.sign(&[payer, staker], *recent_blockhash); banks_client.process_transaction(transaction).await.unwrap(); } @@ -594,8 +595,8 @@ impl StakePoolAccounts { validator_stake_account: &Pubkey, recipient_new_authority: &Pubkey, amount: u64, - ) -> Result<(), TransportError> { - let mut transaction = Transaction::new_with_payer( + ) -> Option { + let transaction = Transaction::new_signed_with_payer( &[instruction::withdraw( &id(), &self.stake_pool.pubkey(), @@ -611,10 +612,10 @@ impl StakePoolAccounts { ) .unwrap()], Some(&payer.pubkey()), + &[payer], + *recent_blockhash, ); - transaction.sign(&[payer], *recent_blockhash); - banks_client.process_transaction(transaction).await?; - Ok(()) + banks_client.process_transaction(transaction).await.err() } pub async fn update_validator_list_balance( @@ -667,9 +668,8 @@ impl StakePoolAccounts { payer: &Keypair, recent_blockhash: &Hash, stake: &Pubkey, - pool_account: &Pubkey, ) -> Option { - let mut transaction = Transaction::new_with_payer( + let transaction = Transaction::new_signed_with_payer( &[instruction::add_validator_to_pool( &id(), &self.stake_pool.pubkey(), @@ -678,14 +678,12 @@ impl StakePoolAccounts { &self.withdraw_authority, &self.validator_list.pubkey(), stake, - pool_account, - &self.pool_mint.pubkey(), - &spl_token::id(), ) .unwrap()], Some(&payer.pubkey()), + &[payer, &self.staker], + *recent_blockhash, ); - transaction.sign(&[payer, &self.staker], *recent_blockhash); banks_client.process_transaction(transaction).await.err() } @@ -695,7 +693,6 @@ impl StakePoolAccounts { payer: &Keypair, recent_blockhash: &Hash, stake: &Pubkey, - pool_account: &Pubkey, new_authority: &Pubkey, ) -> Option { let mut transaction = Transaction::new_with_payer( @@ -707,9 +704,6 @@ impl StakePoolAccounts { &new_authority, &self.validator_list.pubkey(), stake, - pool_account, - &self.pool_mint.pubkey(), - &spl_token::id(), ) .unwrap()], Some(&payer.pubkey()), @@ -738,25 +732,12 @@ pub async fn simple_add_validator_to_pool( ) .await; - let user_pool_account = Keypair::new(); - let user = Keypair::new(); - create_token_account( - banks_client, - &payer, - &recent_blockhash, - &user_pool_account, - &stake_pool_accounts.pool_mint.pubkey(), - &user.pubkey(), - ) - .await - .unwrap(); let error = stake_pool_accounts .add_validator_to_pool( banks_client, &payer, &recent_blockhash, &user_stake.stake_account, - &user_pool_account.pubkey(), ) .await; assert!(error.is_none()); @@ -764,6 +745,7 @@ pub async fn simple_add_validator_to_pool( user_stake } +#[derive(Debug)] pub struct DepositInfo { pub user: Keypair, pub user_pool_account: Pubkey, diff --git a/program/tests/update_stake_pool_balance.rs b/program/tests/update_stake_pool_balance.rs index eb54da80..cd319643 100644 --- a/program/tests/update_stake_pool_balance.rs +++ b/program/tests/update_stake_pool_balance.rs @@ -34,15 +34,24 @@ async fn setup() -> ( let mut stake_accounts: Vec = vec![]; const STAKE_ACCOUNTS: u64 = 3; for _ in 0..STAKE_ACCOUNTS { - stake_accounts.push( - simple_add_validator_to_pool( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts, - ) - .await, - ); + let validator_stake_account = simple_add_validator_to_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + ) + .await; + + let _deposit_info = simple_deposit( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + &validator_stake_account, + ) + .await; + + stake_accounts.push(validator_stake_account); } (context, stake_pool_accounts, stake_accounts) @@ -52,6 +61,18 @@ async fn setup() -> ( async fn success() { let (mut context, stake_pool_accounts, stake_accounts) = setup().await; + let before_balance = get_validator_list_sum( + &mut context.banks_client, + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + + let before_token_supply = get_token_supply( + &mut context.banks_client, + &stake_pool_accounts.pool_mint.pubkey(), + ) + .await; + let error = stake_pool_accounts .update_stake_pool_balance( &mut context.banks_client, @@ -74,12 +95,6 @@ async fn success() { .await; } - let before_balance = get_validator_list_sum( - &mut context.banks_client, - &stake_pool_accounts.validator_list.pubkey(), - ) - .await; - // Update epoch context.warp_to_slot(50_000).unwrap(); @@ -130,9 +145,9 @@ async fn success() { ) .await; let stake_pool = StakePool::try_from_slice(&stake_pool_info.data).unwrap(); - let expected_fee = stake_pool - .calc_fee_amount(after_balance - before_balance) - .unwrap(); + let expected_fee = (after_balance - before_balance) * before_token_supply / before_balance + * stake_pool.fee.numerator + / stake_pool.fee.denominator; assert_eq!(actual_fee, expected_fee); assert_eq!(pool_token_supply, stake_pool.pool_token_supply); } diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index 0270b38c..cd954aa0 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -3,12 +3,8 @@ mod helpers; use { - crate::helpers::TEST_STAKE_AMOUNT, - helpers::*, - solana_program::{native_token, pubkey::Pubkey}, - solana_program_test::*, + helpers::*, solana_program::pubkey::Pubkey, solana_program_test::*, solana_sdk::signature::Signer, - spl_stake_pool::stake_program, }; #[tokio::test] @@ -39,10 +35,6 @@ async fn success() { ); } - let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()) - + native_token::sol_to_lamports(1.0); - // Check current balance in the list assert_eq!( get_validator_list_sum( @@ -50,7 +42,7 @@ async fn success() { &stake_pool_accounts.validator_list.pubkey() ) .await, - STAKE_ACCOUNTS * (stake_rent + TEST_STAKE_AMOUNT) + 0, ); // Add extra funds, simulating rewards @@ -90,12 +82,12 @@ async fn success() { &stake_pool_accounts.validator_list.pubkey() ) .await, - STAKE_ACCOUNTS * (stake_rent + TEST_STAKE_AMOUNT + EXTRA_STAKE_AMOUNT) + STAKE_ACCOUNTS * EXTRA_STAKE_AMOUNT ); } #[tokio::test] -async fn test_update_validator_list_balance_with_uninitialized_validator_list() {} // TODO +async fn fail_with_uninitialized_validator_list() {} // TODO #[tokio::test] -async fn test_update_validator_list_balance_with_wrong_stake_state() {} // TODO +async fn fail_with_wrong_stake_state() {} // TODO diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index 2338b515..d5935e5b 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -19,7 +19,8 @@ use { transport::TransportError, }, spl_stake_pool::{ - borsh::try_from_slice_unchecked, error, id, instruction, stake_program, state, + borsh::try_from_slice_unchecked, error::StakePoolError, id, instruction, stake_program, + state, }, }; @@ -29,7 +30,6 @@ async fn setup() -> ( Hash, StakePoolAccounts, ValidatorStakeAccount, - Keypair, ) { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); @@ -38,8 +38,6 @@ async fn setup() -> ( .await .unwrap(); - let user = Keypair::new(); - let user_stake = ValidatorStakeAccount::new_with_target_authority( &stake_pool_accounts.deposit_authority, &stake_pool_accounts.stake_pool.pubkey(), @@ -53,39 +51,19 @@ async fn setup() -> ( ) .await; - // make pool token account - let user_pool_account = Keypair::new(); - create_token_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_pool_account, - &stake_pool_accounts.pool_mint.pubkey(), - &user.pubkey(), - ) - .await - .unwrap(); - ( banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake, - user_pool_account, ) } #[tokio::test] -async fn test_add_validator_to_pool() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - user_stake, - user_pool_account, - ) = setup().await; +async fn success() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + setup().await; let error = stake_pool_accounts .add_validator_to_pool( @@ -93,28 +71,10 @@ async fn test_add_validator_to_pool() { &payer, &recent_blockhash, &user_stake.stake_account, - &user_pool_account.pubkey(), ) .await; assert!(error.is_none()); - let stake_lamports = banks_client - .get_account(user_stake.stake_account) - .await - .unwrap() - .unwrap() - .lamports; - let deposit_tokens = stake_lamports; // For now 1:1 math - // Check token account balance - let token_balance = get_token_balance(&mut banks_client, &user_pool_account.pubkey()).await; - assert_eq!(token_balance, deposit_tokens); - let pool_fee_token_balance = get_token_balance( - &mut banks_client, - &stake_pool_accounts.pool_fee_account.pubkey(), - ) - .await; - assert_eq!(pool_fee_token_balance, 0); // No fee when adding validator stake accounts - // Check if validator account was added to the list let validator_list = get_account( &mut banks_client, @@ -129,9 +89,9 @@ async fn test_add_validator_to_pool() { account_type: state::AccountType::ValidatorList, max_validators: stake_pool_accounts.max_validators, validators: vec![state::ValidatorStakeInfo { - vote_account: user_stake.vote.pubkey(), + vote_account_address: user_stake.vote.pubkey(), last_update_epoch: 0, - stake_lamports, + stake_lamports: 0, }] } ); @@ -155,15 +115,11 @@ async fn test_add_validator_to_pool() { } #[tokio::test] -async fn test_add_validator_to_pool_with_wrong_token_program_id() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - user_stake, - user_pool_account, - ) = setup().await; +async fn fail_with_wrong_validator_list_account() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + setup().await; + + let wrong_validator_list = Keypair::new(); let mut transaction = Transaction::new_with_payer( &[instruction::add_validator_to_pool( @@ -172,11 +128,8 @@ async fn test_add_validator_to_pool_with_wrong_token_program_id() { &stake_pool_accounts.staker.pubkey(), &stake_pool_accounts.deposit_authority, &stake_pool_accounts.withdraw_authority, - &stake_pool_accounts.validator_list.pubkey(), + &wrong_validator_list.pubkey(), &user_stake.stake_account, - &user_pool_account.pubkey(), - &stake_pool_accounts.pool_mint.pubkey(), - &stake_program::id(), ) .unwrap()], Some(&payer.pubkey()), @@ -189,119 +142,161 @@ async fn test_add_validator_to_pool_with_wrong_token_program_id() { .unwrap(); match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { - assert_eq!(error, InstructionError::IncorrectProgramId); + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = StakePoolError::InvalidValidatorStakeList as u32; + assert_eq!(error_index, program_error); } - _ => panic!("Wrong error occurs while try to add validator stake address with wrong token program ID"), + _ => panic!("Wrong error occurs while try to add validator stake address with wrong validator stake list account"), } } #[tokio::test] -async fn test_add_validator_to_pool_with_wrong_pool_mint_account() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - user_stake, - user_pool_account, - ) = setup().await; +async fn fail_too_little_stake() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await + .unwrap(); + + let user_stake = ValidatorStakeAccount::new_with_target_authority( + &stake_pool_accounts.deposit_authority, + &stake_pool_accounts.stake_pool.pubkey(), + ); + create_vote( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.vote, + ) + .await; - let wrong_pool_mint = Keypair::new(); + create_validator_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.stake_pool, + &stake_pool_accounts.staker, + &user_stake.stake_account, + &user_stake.vote.pubkey(), + ) + .await; - let mut transaction = Transaction::new_with_payer( - &[instruction::add_validator_to_pool( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.staker.pubkey(), - &stake_pool_accounts.deposit_authority, - &stake_pool_accounts.withdraw_authority, - &stake_pool_accounts.validator_list.pubkey(), + // Create stake account to withdraw to + let split = Keypair::new(); + create_blank_stake_account(&mut banks_client, &payer, &recent_blockhash, &split).await; + let transaction = Transaction::new_signed_with_payer( + &[stake_program::split_only( &user_stake.stake_account, - &user_pool_account.pubkey(), - &wrong_pool_mint.pubkey(), - &spl_token::id(), - ) - .unwrap()], + &stake_pool_accounts.staker.pubkey(), + 1, + &split.pubkey(), + )], Some(&payer.pubkey()), + &[&payer, &stake_pool_accounts.staker], + recent_blockhash, ); - transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); - let transaction_error = banks_client - .process_transaction(transaction) + + banks_client.process_transaction(transaction).await.unwrap(); + + authorize_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.stake_account, + &stake_pool_accounts.staker, + &user_stake.target_authority, + stake_program::StakeAuthorize::Staker, + ) + .await; + + authorize_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.stake_account, + &stake_pool_accounts.staker, + &user_stake.target_authority, + stake_program::StakeAuthorize::Withdrawer, + ) + .await; + + let error = stake_pool_accounts + .add_validator_to_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.stake_account, + ) .await - .err() + .unwrap() .unwrap(); - - match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError( - _, - InstructionError::Custom(error_index), - )) => { - let program_error = error::StakePoolError::WrongPoolMint as u32; - assert_eq!(error_index, program_error); - } - _ => panic!("Wrong error occurs while try to add validator stake address with wrong pool mint account"), - } + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::StakeLamportsNotEqualToMinimum as u32) + ), + ); } #[tokio::test] -async fn test_add_validator_to_pool_with_wrong_validator_list_account() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - user_stake, - user_pool_account, - ) = setup().await; +async fn fail_too_much_stake() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await + .unwrap(); - let wrong_validator_list = Keypair::new(); + let user_stake = ValidatorStakeAccount::new_with_target_authority( + &stake_pool_accounts.deposit_authority, + &stake_pool_accounts.stake_pool.pubkey(), + ); + user_stake + .create_and_delegate( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.staker, + ) + .await; - let mut transaction = Transaction::new_with_payer( - &[instruction::add_validator_to_pool( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.staker.pubkey(), - &stake_pool_accounts.deposit_authority, - &stake_pool_accounts.withdraw_authority, - &wrong_validator_list.pubkey(), + transfer( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.stake_account, + 1, + ) + .await; + + let error = stake_pool_accounts + .add_validator_to_pool( + &mut banks_client, + &payer, + &recent_blockhash, &user_stake.stake_account, - &user_pool_account.pubkey(), - &stake_pool_accounts.pool_mint.pubkey(), - &spl_token::id(), ) - .unwrap()], - Some(&payer.pubkey()), - ); - transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); - let transaction_error = banks_client - .process_transaction(transaction) .await - .err() + .unwrap() .unwrap(); - - match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError( - _, - InstructionError::Custom(error_index), - )) => { - let program_error = error::StakePoolError::InvalidValidatorStakeList as u32; - assert_eq!(error_index, program_error); - } - _ => panic!("Wrong error occurs while try to add validator stake address with wrong validator stake list account"), - } + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::StakeLamportsNotEqualToMinimum as u32) + ), + ); } #[tokio::test] -async fn test_try_to_add_already_added_validator_stake_account() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - user_stake, - user_pool_account, - ) = setup().await; +async fn fail_double_add() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + setup().await; stake_pool_accounts .add_validator_to_pool( @@ -309,7 +304,6 @@ async fn test_try_to_add_already_added_validator_stake_account() { &payer, &recent_blockhash, &user_stake.stake_account, - &user_pool_account.pubkey(), ) .await; @@ -321,7 +315,6 @@ async fn test_try_to_add_already_added_validator_stake_account() { &payer, &latest_blockhash, &user_stake.stake_account, - &user_pool_account.pubkey(), ) .await .unwrap(); @@ -331,7 +324,7 @@ async fn test_try_to_add_already_added_validator_stake_account() { _, InstructionError::Custom(error_index), )) => { - let program_error = error::StakePoolError::ValidatorAlreadyAdded as u32; + let program_error = StakePoolError::ValidatorAlreadyAdded as u32; assert_eq!(error_index, program_error); } _ => panic!("Wrong error occurs while try to add already added validator stake account"), @@ -339,15 +332,9 @@ async fn test_try_to_add_already_added_validator_stake_account() { } #[tokio::test] -async fn test_not_staker_try_to_add_validator_to_pool() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - user_stake, - user_pool_account, - ) = setup().await; +async fn fail_wrong_staker() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + setup().await; let malicious = Keypair::new(); @@ -360,9 +347,6 @@ async fn test_not_staker_try_to_add_validator_to_pool() { &stake_pool_accounts.withdraw_authority, &stake_pool_accounts.validator_list.pubkey(), &user_stake.stake_account, - &user_pool_account.pubkey(), - &stake_pool_accounts.pool_mint.pubkey(), - &spl_token::id(), ) .unwrap()], Some(&payer.pubkey()), @@ -379,7 +363,7 @@ async fn test_not_staker_try_to_add_validator_to_pool() { _, InstructionError::Custom(error_index), )) => { - let program_error = error::StakePoolError::WrongStaker as u32; + let program_error = StakePoolError::WrongStaker as u32; assert_eq!(error_index, program_error); } _ => panic!("Wrong error occurs while malicious try to add validator stake account"), @@ -387,15 +371,9 @@ async fn test_not_staker_try_to_add_validator_to_pool() { } #[tokio::test] -async fn test_not_staker_try_to_add_validator_to_pool_without_signature() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - user_stake, - user_pool_account, - ) = setup().await; +async fn fail_without_signature() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + setup().await; let accounts = vec![ AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), @@ -404,11 +382,8 @@ async fn test_not_staker_try_to_add_validator_to_pool_without_signature() { AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false), AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false), AccountMeta::new(user_stake.stake_account, false), - AccountMeta::new(user_pool_account.pubkey(), false), - AccountMeta::new(stake_pool_accounts.pool_mint.pubkey(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), - AccountMeta::new_readonly(spl_token::id(), false), AccountMeta::new_readonly(stake_program::id(), false), ]; let instruction = Instruction { @@ -432,7 +407,7 @@ async fn test_not_staker_try_to_add_validator_to_pool_without_signature() { _, InstructionError::Custom(error_index), )) => { - let program_error = error::StakePoolError::SignatureMissing as u32; + let program_error = StakePoolError::SignatureMissing as u32; assert_eq!(error_index, program_error); } _ => panic!("Wrong error occurs while malicious try to add validator stake account without signing transaction"), @@ -440,15 +415,9 @@ async fn test_not_staker_try_to_add_validator_to_pool_without_signature() { } #[tokio::test] -async fn test_add_validator_to_pool_with_wrong_stake_program_id() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - user_stake, - user_pool_account, - ) = setup().await; +async fn fail_with_wrong_stake_program_id() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + setup().await; let wrong_stake_program = Pubkey::new_unique(); @@ -459,11 +428,8 @@ async fn test_add_validator_to_pool_with_wrong_stake_program_id() { AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false), AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false), AccountMeta::new(user_stake.stake_account, false), - AccountMeta::new(user_pool_account.pubkey(), false), - AccountMeta::new(stake_pool_accounts.pool_mint.pubkey(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), - AccountMeta::new_readonly(spl_token::id(), false), AccountMeta::new_readonly(wrong_stake_program, false), ]; let instruction = Instruction { @@ -492,7 +458,7 @@ async fn test_add_validator_to_pool_with_wrong_stake_program_id() { } #[tokio::test] -async fn test_add_too_many_validator_stake_accounts() { +async fn fail_add_too_many_validator_stake_accounts() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let mut stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts.max_validators = 1; @@ -501,8 +467,6 @@ async fn test_add_too_many_validator_stake_accounts() { .await .unwrap(); - let user = Keypair::new(); - let user_stake = ValidatorStakeAccount::new_with_target_authority( &stake_pool_accounts.deposit_authority, &stake_pool_accounts.stake_pool.pubkey(), @@ -516,26 +480,12 @@ async fn test_add_too_many_validator_stake_accounts() { ) .await; - // make pool token account - let user_pool_account = Keypair::new(); - create_token_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_pool_account, - &stake_pool_accounts.pool_mint.pubkey(), - &user.pubkey(), - ) - .await - .unwrap(); - let error = stake_pool_accounts .add_validator_to_pool( &mut banks_client, &payer, &recent_blockhash, &user_stake.stake_account, - &user_pool_account.pubkey(), ) .await; assert!(error.is_none()); @@ -558,7 +508,6 @@ async fn test_add_too_many_validator_stake_accounts() { &payer, &recent_blockhash, &user_stake.stake_account, - &user_pool_account.pubkey(), ) .await .unwrap() @@ -570,7 +519,7 @@ async fn test_add_too_many_validator_stake_accounts() { } #[tokio::test] -async fn test_add_validator_to_pool_to_unupdated_stake_pool() {} // TODO +async fn fail_with_unupdated_stake_pool() {} // TODO #[tokio::test] -async fn test_add_validator_to_pool_with_uninitialized_validator_list_account() {} // TODO +async fn fail_with_uninitialized_validator_list_account() {} // TODO diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 8773481f..5e6e4b2f 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -19,7 +19,8 @@ use { transport::TransportError, }, spl_stake_pool::{ - borsh::try_from_slice_unchecked, error, id, instruction, stake_program, state, + borsh::try_from_slice_unchecked, error::StakePoolError, id, instruction, stake_program, + state, }, }; @@ -29,8 +30,6 @@ async fn setup() -> ( Hash, StakePoolAccounts, ValidatorStakeAccount, - Keypair, - Keypair, ) { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); @@ -39,8 +38,6 @@ async fn setup() -> ( .await .unwrap(); - let user = Keypair::new(); - let user_stake = ValidatorStakeAccount::new_with_target_authority( &stake_pool_accounts.deposit_authority, &stake_pool_accounts.stake_pool.pubkey(), @@ -54,26 +51,12 @@ async fn setup() -> ( ) .await; - // make pool token account - let user_pool_account = Keypair::new(); - create_token_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_pool_account, - &stake_pool_accounts.pool_mint.pubkey(), - &user.pubkey(), - ) - .await - .unwrap(); - let error = stake_pool_accounts .add_validator_to_pool( &mut banks_client, &payer, &recent_blockhash, &user_stake.stake_account, - &user_pool_account.pubkey(), ) .await; assert!(error.is_none()); @@ -84,34 +67,13 @@ async fn setup() -> ( recent_blockhash, stake_pool_accounts, user_stake, - user_pool_account, - user, ) } #[tokio::test] -async fn test_remove_validator_from_pool() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - user_stake, - user_pool_account, - user, - ) = setup().await; - - let tokens_to_burn = get_token_balance(&mut banks_client, &user_pool_account.pubkey()).await; - delegate_tokens( - &mut banks_client, - &payer, - &recent_blockhash, - &user_pool_account.pubkey(), - &user, - &stake_pool_accounts.withdraw_authority, - tokens_to_burn, - ) - .await; +async fn success() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + setup().await; let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts @@ -120,16 +82,11 @@ async fn test_remove_validator_from_pool() { &payer, &recent_blockhash, &user_stake.stake_account, - &user_pool_account.pubkey(), &new_authority, ) .await; assert!(error.is_none()); - // Check if all tokens were burned - let tokens_left = get_token_balance(&mut banks_client, &user_pool_account.pubkey()).await; - assert_eq!(tokens_left, 0); - // Check if account was removed from the list of stake accounts let validator_list = get_account( &mut banks_client, @@ -160,16 +117,9 @@ async fn test_remove_validator_from_pool() { } #[tokio::test] -async fn test_remove_validator_from_pool_with_wrong_stake_program_id() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - user_stake, - user_pool_account, - _, - ) = setup().await; +async fn fail_with_wrong_stake_program_id() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + setup().await; let wrong_stake_program = Pubkey::new_unique(); @@ -181,10 +131,7 @@ async fn test_remove_validator_from_pool_with_wrong_stake_program_id() { AccountMeta::new_readonly(new_authority, false), AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false), AccountMeta::new(user_stake.stake_account, false), - AccountMeta::new(user_pool_account.pubkey(), false), - AccountMeta::new(stake_pool_accounts.pool_mint.pubkey(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), - AccountMeta::new_readonly(spl_token::id(), false), AccountMeta::new_readonly(wrong_stake_program, false), ]; let instruction = Instruction { @@ -215,64 +162,11 @@ async fn test_remove_validator_from_pool_with_wrong_stake_program_id() { } #[tokio::test] -async fn test_remove_validator_from_pool_with_wrong_token_program_id() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - user_stake, - user_pool_account, - _, - ) = setup().await; +async fn fail_with_wrong_validator_list_account() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + setup().await; - let wrong_token_program = Keypair::new(); - - let new_authority = Pubkey::new_unique(); - let mut transaction = Transaction::new_with_payer( - &[instruction::remove_validator_from_pool( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.staker.pubkey(), - &stake_pool_accounts.withdraw_authority, - &new_authority, - &stake_pool_accounts.validator_list.pubkey(), - &user_stake.stake_account, - &user_pool_account.pubkey(), - &stake_pool_accounts.pool_mint.pubkey(), - &wrong_token_program.pubkey(), - ) - .unwrap()], - Some(&payer.pubkey()), - ); - transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); - let transaction_error = banks_client - .process_transaction(transaction) - .await - .err() - .unwrap(); - - match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { - assert_eq!(error, InstructionError::IncorrectProgramId); - } - _ => panic!("Wrong error occurs while try to remove validator stake address with wrong token program ID"), - } -} - -#[tokio::test] -async fn test_remove_validator_from_pool_with_wrong_pool_mint_account() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - user_stake, - user_pool_account, - _, - ) = setup().await; - - let wrong_pool_mint = Keypair::new(); + let wrong_validator_list = Keypair::new(); let new_authority = Pubkey::new_unique(); let mut transaction = Transaction::new_with_payer( @@ -282,11 +176,8 @@ async fn test_remove_validator_from_pool_with_wrong_pool_mint_account() { &stake_pool_accounts.staker.pubkey(), &stake_pool_accounts.withdraw_authority, &new_authority, - &stake_pool_accounts.validator_list.pubkey(), + &wrong_validator_list.pubkey(), &user_stake.stake_account, - &user_pool_account.pubkey(), - &wrong_pool_mint.pubkey(), - &spl_token::id(), ) .unwrap()], Some(&payer.pubkey()), @@ -303,86 +194,52 @@ async fn test_remove_validator_from_pool_with_wrong_pool_mint_account() { _, InstructionError::Custom(error_index), )) => { - let program_error = error::StakePoolError::WrongPoolMint as u32; + let program_error = StakePoolError::InvalidValidatorStakeList as u32; assert_eq!(error_index, program_error); } - _ => panic!("Wrong error occurs while try to remove validator stake address with wrong pool mint account"), + _ => panic!("Wrong error occurs while try to remove validator stake address with wrong validator stake list account"), } } #[tokio::test] -async fn test_remove_validator_from_pool_with_wrong_validator_list_account() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - user_stake, - user_pool_account, - _, - ) = setup().await; +async fn fail_not_at_minimum() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + setup().await; - let wrong_validator_list = Keypair::new(); + transfer( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.stake_account, + 1_000_001, + ) + .await; let new_authority = Pubkey::new_unique(); - let mut transaction = Transaction::new_with_payer( - &[instruction::remove_validator_from_pool( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.staker.pubkey(), - &stake_pool_accounts.withdraw_authority, - &new_authority, - &wrong_validator_list.pubkey(), + let error = stake_pool_accounts + .remove_validator_from_pool( + &mut banks_client, + &payer, + &recent_blockhash, &user_stake.stake_account, - &user_pool_account.pubkey(), - &stake_pool_accounts.pool_mint.pubkey(), - &spl_token::id(), + &new_authority, ) - .unwrap()], - Some(&payer.pubkey()), - ); - transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); - let transaction_error = banks_client - .process_transaction(transaction) .await - .err() + .unwrap() .unwrap(); - - match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError( - _, - InstructionError::Custom(error_index), - )) => { - let program_error = error::StakePoolError::InvalidValidatorStakeList as u32; - assert_eq!(error_index, program_error); - } - _ => panic!("Wrong error occurs while try to remove validator stake address with wrong validator stake list account"), - } + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::StakeLamportsNotEqualToMinimum as u32) + ), + ); } #[tokio::test] -async fn test_remove_already_removed_validator_stake_account() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - user_stake, - user_pool_account, - user, - ) = setup().await; - - let tokens_to_burn = get_token_balance(&mut banks_client, &user_pool_account.pubkey()).await; - delegate_tokens( - &mut banks_client, - &payer, - &recent_blockhash, - &user_pool_account.pubkey(), - &user, - &stake_pool_accounts.withdraw_authority, - tokens_to_burn, - ) - .await; +async fn fail_double_remove() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + setup().await; let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts @@ -391,7 +248,6 @@ async fn test_remove_already_removed_validator_stake_account() { &payer, &recent_blockhash, &user_stake.stake_account, - &user_pool_account.pubkey(), &new_authority, ) .await; @@ -405,7 +261,6 @@ async fn test_remove_already_removed_validator_stake_account() { &payer, &latest_blockhash, &user_stake.stake_account, - &user_pool_account.pubkey(), &new_authority, ) .await @@ -416,7 +271,7 @@ async fn test_remove_already_removed_validator_stake_account() { _, InstructionError::Custom(error_index), )) => { - let program_error = error::StakePoolError::ValidatorNotFound as u32; + let program_error = StakePoolError::ValidatorNotFound as u32; assert_eq!(error_index, program_error); } _ => { @@ -426,16 +281,9 @@ async fn test_remove_already_removed_validator_stake_account() { } #[tokio::test] -async fn test_not_staker_try_to_remove_validator_from_pool() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - user_stake, - user_pool_account, - _, - ) = setup().await; +async fn fail_wrong_staker() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + setup().await; let malicious = Keypair::new(); @@ -449,9 +297,6 @@ async fn test_not_staker_try_to_remove_validator_from_pool() { &new_authority, &stake_pool_accounts.validator_list.pubkey(), &user_stake.stake_account, - &user_pool_account.pubkey(), - &stake_pool_accounts.pool_mint.pubkey(), - &spl_token::id(), ) .unwrap()], Some(&payer.pubkey()), @@ -468,7 +313,7 @@ async fn test_not_staker_try_to_remove_validator_from_pool() { _, InstructionError::Custom(error_index), )) => { - let program_error = error::StakePoolError::WrongStaker as u32; + let program_error = StakePoolError::WrongStaker as u32; assert_eq!(error_index, program_error); } _ => { @@ -478,16 +323,9 @@ async fn test_not_staker_try_to_remove_validator_from_pool() { } #[tokio::test] -async fn test_not_staker_try_to_remove_validator_from_pool_without_signature() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - user_stake, - user_pool_account, - _, - ) = setup().await; +async fn fail_no_signature() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + setup().await; let new_authority = Pubkey::new_unique(); @@ -498,10 +336,7 @@ async fn test_not_staker_try_to_remove_validator_from_pool_without_signature() { AccountMeta::new_readonly(new_authority, false), AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false), AccountMeta::new(user_stake.stake_account, false), - AccountMeta::new(user_pool_account.pubkey(), false), - AccountMeta::new(stake_pool_accounts.pool_mint.pubkey(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), - AccountMeta::new_readonly(spl_token::id(), false), AccountMeta::new_readonly(stake_program::id(), false), ]; let instruction = Instruction { @@ -512,8 +347,12 @@ async fn test_not_staker_try_to_remove_validator_from_pool_without_signature() { .unwrap(), }; - let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); - transaction.sign(&[&payer], recent_blockhash); + let transaction = Transaction::new_signed_with_payer( + &[instruction], + Some(&payer.pubkey()), + &[&payer], + recent_blockhash, + ); let transaction_error = banks_client .process_transaction(transaction) .await @@ -525,7 +364,7 @@ async fn test_not_staker_try_to_remove_validator_from_pool_without_signature() { _, InstructionError::Custom(error_index), )) => { - let program_error = error::StakePoolError::SignatureMissing as u32; + let program_error = StakePoolError::SignatureMissing as u32; assert_eq!(error_index, program_error); } _ => panic!("Wrong error occurs while malicious try to remove validator stake account without signing transaction"), @@ -533,7 +372,7 @@ async fn test_not_staker_try_to_remove_validator_from_pool_without_signature() { } #[tokio::test] -async fn test_remove_validator_from_pool_from_unupdated_stake_pool() {} // TODO +async fn fail_not_updated_stake_pool() {} // TODO #[tokio::test] -async fn test_remove_validator_from_pool_with_uninitialized_validator_list_account() {} // TODO +async fn fail_with_uninitialized_validator_list_account() {} // TODO diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index db29772f..cf63c8bc 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -3,6 +3,7 @@ mod helpers; use { + bincode::deserialize, borsh::{BorshDeserialize, BorshSerialize}, helpers::*, solana_program::{ @@ -18,7 +19,8 @@ use { transport::TransportError, }, spl_stake_pool::{ - borsh::try_from_slice_unchecked, error, id, instruction, stake_program, state, + borsh::try_from_slice_unchecked, error::StakePoolError, id, instruction, + minimum_stake_lamports, stake_program, state, }, spl_token::error::TokenError, }; @@ -39,7 +41,7 @@ async fn setup() -> ( .await .unwrap(); - let validator_stake_account: ValidatorStakeAccount = simple_add_validator_to_pool( + let validator_stake_account = simple_add_validator_to_pool( &mut banks_client, &payer, &recent_blockhash, @@ -47,7 +49,7 @@ async fn setup() -> ( ) .await; - let deposit_info: DepositInfo = simple_deposit( + let deposit_info = simple_deposit( &mut banks_client, &payer, &recent_blockhash, @@ -82,7 +84,7 @@ async fn setup() -> ( } #[tokio::test] -async fn test_stake_pool_withdraw() { +async fn success() { let ( mut banks_client, payer, @@ -126,7 +128,7 @@ async fn test_stake_pool_withdraw() { get_token_balance(&mut banks_client, &deposit_info.user_pool_account).await; let new_authority = Pubkey::new_unique(); - stake_pool_accounts + let error = stake_pool_accounts .withdraw_stake( &mut banks_client, &payer, @@ -137,8 +139,8 @@ async fn test_stake_pool_withdraw() { &new_authority, tokens_to_burn, ) - .await - .unwrap(); + .await; + assert!(error.is_none()); // Check pool stats let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; @@ -179,8 +181,11 @@ async fn test_stake_pool_withdraw() { // Check validator stake account balance let validator_stake_account = get_account(&mut banks_client, &validator_stake_account.stake_account).await; + let stake_state = + deserialize::(&validator_stake_account.data).unwrap(); + let meta = stake_state.meta().unwrap(); assert_eq!( - validator_stake_account.lamports, + validator_stake_account.lamports - minimum_stake_lamports(&meta), validator_stake_item.stake_lamports ); @@ -194,7 +199,7 @@ async fn test_stake_pool_withdraw() { } #[tokio::test] -async fn test_stake_pool_withdraw_with_wrong_stake_program() { +async fn fail_with_wrong_stake_program() { let ( mut banks_client, payer, @@ -249,7 +254,7 @@ async fn test_stake_pool_withdraw_with_wrong_stake_program() { } #[tokio::test] -async fn test_stake_pool_withdraw_with_wrong_withdraw_authority() { +async fn fail_with_wrong_withdraw_authority() { let ( mut banks_client, payer, @@ -278,7 +283,6 @@ async fn test_stake_pool_withdraw_with_wrong_withdraw_authority() { tokens_to_burn, ) .await - .err() .unwrap(); match transaction_error { @@ -286,7 +290,7 @@ async fn test_stake_pool_withdraw_with_wrong_withdraw_authority() { _, InstructionError::Custom(error_index), )) => { - let program_error = error::StakePoolError::InvalidProgramAddress as u32; + let program_error = StakePoolError::InvalidProgramAddress as u32; assert_eq!(error_index, program_error); } _ => panic!("Wrong error occurs while try to withdraw with wrong withdraw authority"), @@ -294,7 +298,7 @@ async fn test_stake_pool_withdraw_with_wrong_withdraw_authority() { } #[tokio::test] -async fn test_stake_pool_withdraw_with_wrong_token_program_id() { +async fn fail_with_wrong_token_program_id() { let ( mut banks_client, payer, @@ -344,7 +348,7 @@ async fn test_stake_pool_withdraw_with_wrong_token_program_id() { } #[tokio::test] -async fn test_stake_pool_withdraw_with_wrong_validator_list() { +async fn fail_with_wrong_validator_list() { let ( mut banks_client, payer, @@ -373,7 +377,6 @@ async fn test_stake_pool_withdraw_with_wrong_validator_list() { tokens_to_burn, ) .await - .err() .unwrap(); match transaction_error { @@ -381,7 +384,7 @@ async fn test_stake_pool_withdraw_with_wrong_validator_list() { _, InstructionError::Custom(error_index), )) => { - let program_error = error::StakePoolError::InvalidValidatorStakeList as u32; + let program_error = StakePoolError::InvalidValidatorStakeList as u32; assert_eq!(error_index, program_error); } _ => panic!( @@ -391,7 +394,7 @@ async fn test_stake_pool_withdraw_with_wrong_validator_list() { } #[tokio::test] -async fn test_stake_pool_withdraw_from_unknown_validator() { +async fn fail_with_unknown_validator() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts @@ -502,7 +505,6 @@ async fn test_stake_pool_withdraw_from_unknown_validator() { tokens_to_burn, ) .await - .err() .unwrap(); match transaction_error { @@ -510,7 +512,7 @@ async fn test_stake_pool_withdraw_from_unknown_validator() { _, InstructionError::Custom(error_index), )) => { - let program_error = error::StakePoolError::ValidatorNotFound as u32; + let program_error = StakePoolError::ValidatorNotFound as u32; assert_eq!(error_index, program_error); } _ => panic!("Wrong error occurs while try to do withdraw from unknown validator"), @@ -518,7 +520,7 @@ async fn test_stake_pool_withdraw_from_unknown_validator() { } #[tokio::test] -async fn test_stake_pool_double_withdraw_to_the_same_account() { +async fn fail_double_withdraw_to_the_same_account() { let ( mut banks_client, payer, @@ -540,7 +542,7 @@ async fn test_stake_pool_double_withdraw_to_the_same_account() { .await; let new_authority = Pubkey::new_unique(); - stake_pool_accounts + let error = stake_pool_accounts .withdraw_stake( &mut banks_client, &payer, @@ -551,11 +553,23 @@ async fn test_stake_pool_double_withdraw_to_the_same_account() { &new_authority, tokens_to_burn, ) - .await - .unwrap(); + .await; + assert!(error.is_none()); let latest_blockhash = banks_client.get_recent_blockhash().await.unwrap(); + // Delegate tokens for burning + delegate_tokens( + &mut banks_client, + &payer, + &latest_blockhash, + &deposit_info.user_pool_account, + &deposit_info.user, + &stake_pool_accounts.withdraw_authority, + tokens_to_burn, + ) + .await; + let transaction_error = stake_pool_accounts .withdraw_stake( &mut banks_client, @@ -568,7 +582,6 @@ async fn test_stake_pool_double_withdraw_to_the_same_account() { tokens_to_burn, ) .await - .err() .unwrap(); match transaction_error { @@ -580,7 +593,7 @@ async fn test_stake_pool_double_withdraw_to_the_same_account() { } #[tokio::test] -async fn test_stake_pool_withdraw_token_delegate_was_not_setup() { +async fn fail_without_token_approval() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts @@ -588,7 +601,7 @@ async fn test_stake_pool_withdraw_token_delegate_was_not_setup() { .await .unwrap(); - let validator_stake_account: ValidatorStakeAccount = simple_add_validator_to_pool( + let validator_stake_account = simple_add_validator_to_pool( &mut banks_client, &payer, &recent_blockhash, @@ -596,7 +609,7 @@ async fn test_stake_pool_withdraw_token_delegate_was_not_setup() { ) .await; - let deposit_info: DepositInfo = simple_deposit( + let deposit_info = simple_deposit( &mut banks_client, &payer, &recent_blockhash, @@ -630,7 +643,6 @@ async fn test_stake_pool_withdraw_token_delegate_was_not_setup() { tokens_to_burn, ) .await - .err() .unwrap(); match transaction_error { @@ -648,7 +660,7 @@ async fn test_stake_pool_withdraw_token_delegate_was_not_setup() { } #[tokio::test] -async fn test_stake_pool_withdraw_with_low_delegation() { +async fn fail_with_low_delegation() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts @@ -656,7 +668,7 @@ async fn test_stake_pool_withdraw_with_low_delegation() { .await .unwrap(); - let validator_stake_account: ValidatorStakeAccount = simple_add_validator_to_pool( + let validator_stake_account = simple_add_validator_to_pool( &mut banks_client, &payer, &recent_blockhash, @@ -664,7 +676,7 @@ async fn test_stake_pool_withdraw_with_low_delegation() { ) .await; - let deposit_info: DepositInfo = simple_deposit( + let deposit_info = simple_deposit( &mut banks_client, &payer, &recent_blockhash, @@ -710,7 +722,6 @@ async fn test_stake_pool_withdraw_with_low_delegation() { tokens_to_burn, ) .await - .err() .unwrap(); match transaction_error { @@ -726,3 +737,57 @@ async fn test_stake_pool_withdraw_with_low_delegation() { ), } } + +#[tokio::test] +async fn fail_overdraw_validator() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + _validator_stake_account, + deposit_info, + tokens_to_burn, + ) = setup().await; + + // Create stake account to withdraw to + let user_stake_recipient = Keypair::new(); + let _initial_stake_lamports = create_blank_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake_recipient, + ) + .await; + + let validator_stake_account = simple_add_validator_to_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + ) + .await; + + let new_authority = Pubkey::new_unique(); + let error = stake_pool_accounts + .withdraw_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake_recipient.pubkey(), + &deposit_info.user_pool_account, + &validator_stake_account.stake_account, + &new_authority, + tokens_to_burn, + ) + .await + .unwrap() + .unwrap(); + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::StakeLamportsNotEqualToMinimum as u32) + ), + ); +} From b9a5c92ba61b2d659ee356b1e458e24be7823b75 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 21 Apr 2021 14:20:55 +0200 Subject: [PATCH 0084/1076] stake-pool: Set fee (#1604) * stake-pool: Add set_fee instruction * Add more tests * Add set-fee CLI instruction * Update documentation * Cargo fmt * Re-format * Fix clippy --- clients/cli/src/main.rs | 70 ++++++++++++-- program/src/instruction.rs | 43 ++++++--- program/src/processor.rs | 42 ++++++++- program/src/state.rs | 13 ++- program/tests/helpers/mod.rs | 6 +- program/tests/initialize.rs | 2 +- program/tests/set_fee.rs | 177 +++++++++++++++++++++++++++++++++++ 7 files changed, 327 insertions(+), 26 deletions(-) create mode 100644 program/tests/set_fee.rs diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 5b47cf58..3f7bc25e 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -31,7 +31,7 @@ use { find_deposit_authority_program_address, find_stake_program_address, find_withdraw_authority_program_address, stake_program::{self, StakeAuthorize, StakeState}, - state::{StakePool, ValidatorList}, + state::{Fee, StakePool, ValidatorList}, }, std::process::exit, }; @@ -94,11 +94,7 @@ fn send_transaction( Ok(()) } -fn command_create_pool( - config: &Config, - fee: spl_stake_pool::instruction::Fee, - max_validators: u32, -) -> CommandResult { +fn command_create_pool(config: &Config, fee: Fee, max_validators: u32) -> CommandResult { let mint_account = Keypair::new(); println!("Creating mint {}", mint_account.pubkey()); @@ -921,6 +917,26 @@ fn command_set_staker( Ok(()) } +fn command_set_fee(config: &Config, stake_pool_address: &Pubkey, new_fee: Fee) -> CommandResult { + let mut transaction = Transaction::new_with_payer( + &[spl_stake_pool::instruction::set_fee( + &spl_stake_pool::id(), + &stake_pool_address, + &config.manager.pubkey(), + new_fee, + )], + Some(&config.fee_payer.pubkey()), + ); + + let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; + let mut signers = vec![config.fee_payer.as_ref(), config.manager.as_ref()]; + unique_signers!(signers); + transaction.sign(&signers, recent_blockhash); + send_transaction(&config, transaction)?; + Ok(()) +} + fn main() { solana_logger::setup_with_default("solana=info"); @@ -1290,6 +1306,36 @@ fn main() { .help("Public key for the new stake pool staker."), ) ) + .subcommand(SubCommand::with_name("set-fee") + .about("Change the fee assessed by the stake pool. Must be signed by the manager.") + .arg( + Arg::with_name("pool") + .index(1) + .validator(is_pubkey) + .value_name("POOL_ADDRESS") + .takes_value(true) + .required(true) + .help("Stake pool address."), + ) + .arg( + Arg::with_name("fee_numerator") + .index(2) + .validator(is_parsable::) + .value_name("NUMERATOR") + .takes_value(true) + .required(true) + .help("Fee numerator, fee amount is numerator divided by denominator."), + ) + .arg( + Arg::with_name("fee_denominator") + .index(3) + .validator(is_parsable::) + .value_name("DENOMINATOR") + .takes_value(true) + .required(true) + .help("Fee denominator, fee amount is numerator divided by denominator."), + ) + ) .get_matches(); let mut wallet_manager = None; @@ -1365,7 +1411,7 @@ fn main() { let max_validators = value_t_or_exit!(arg_matches, "max_validators", u32); command_create_pool( &config, - spl_stake_pool::instruction::Fee { + Fee { denominator, numerator, }, @@ -1436,6 +1482,16 @@ fn main() { let new_staker = pubkey_of(arg_matches, "new_staker").unwrap(); command_set_staker(&config, &stake_pool_address, &new_staker) } + ("set-fee", Some(arg_matches)) => { + let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); + let numerator = value_t_or_exit!(arg_matches, "fee_numerator", u64); + let denominator = value_t_or_exit!(arg_matches, "fee_denominator", u64); + let new_fee = Fee { + denominator, + numerator, + }; + command_set_fee(&config, &stake_pool_address, new_fee) + } _ => unreachable!(), } .map_err(|err| { diff --git a/program/src/instruction.rs b/program/src/instruction.rs index b2e5210c..3cb639c7 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -3,7 +3,7 @@ #![allow(clippy::too_many_arguments)] use { - crate::stake_program, + crate::{stake_program, state::Fee}, borsh::{BorshDeserialize, BorshSchema, BorshSerialize}, solana_program::{ instruction::{AccountMeta, Instruction}, @@ -13,17 +13,6 @@ use { }, }; -/// Fee rate as a ratio, minted on `UpdateStakePoolBalance` as a proportion of -/// the rewards -#[repr(C)] -#[derive(Clone, Copy, Debug, Default, PartialEq, BorshSerialize, BorshDeserialize, BorshSchema)] -pub struct Fee { - /// denominator of the fee ratio - pub denominator: u64, - /// numerator of the fee ratio - pub numerator: u64, -} - /// Instructions supported by the StakePool program. #[repr(C)] #[derive(Clone, Debug, PartialEq, BorshSerialize, BorshDeserialize, BorshSchema)] @@ -234,6 +223,17 @@ pub enum StakePoolInstruction { /// 3. '[]` New manager fee account SetManager, + /// (Manager only) Update fee + /// + /// 0. `[w]` StakePool + /// 1. `[s]` Manager + /// 2. `[]` Sysvar clock + SetFee { + /// Fee assessed as percentage of perceived rewards + #[allow(dead_code)] // but it's not + fee: Fee, + }, + /// (Manager or staker only) Update staker /// /// 0. `[w]` StakePool @@ -507,6 +507,25 @@ pub fn set_manager( }) } +/// Creates a 'set fee' instruction. +pub fn set_fee( + program_id: &Pubkey, + stake_pool: &Pubkey, + manager: &Pubkey, + fee: Fee, +) -> Instruction { + let accounts = vec![ + AccountMeta::new(*stake_pool, false), + AccountMeta::new_readonly(*manager, true), + AccountMeta::new_readonly(sysvar::clock::id(), false), + ]; + Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::SetFee { fee }.try_to_vec().unwrap(), + } +} + /// Creates a 'set staker' instruction. pub fn set_staker( program_id: &Pubkey, diff --git a/program/src/processor.rs b/program/src/processor.rs index f4e26ab0..98c1e72e 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -4,9 +4,9 @@ use { crate::{ borsh::try_from_slice_unchecked, error::StakePoolError, - instruction::{Fee, StakePoolInstruction}, + instruction::StakePoolInstruction, minimum_stake_lamports, stake_program, - state::{AccountType, StakePool, ValidatorList, ValidatorStakeInfo}, + state::{AccountType, Fee, StakePool, ValidatorList, ValidatorStakeInfo}, AUTHORITY_DEPOSIT, AUTHORITY_WITHDRAW, MINIMUM_ACTIVE_STAKE, }, bincode::deserialize, @@ -1096,6 +1096,40 @@ impl Processor { Ok(()) } + /// Processes [SetFee](enum.Instruction.html). + fn process_set_fee(_program_id: &Pubkey, accounts: &[AccountInfo], fee: Fee) -> ProgramResult { + let account_info_iter = &mut accounts.iter(); + let stake_pool_info = next_account_info(account_info_iter)?; + let manager_info = next_account_info(account_info_iter)?; + let clock_info = next_account_info(account_info_iter)?; + let clock = &Clock::from_account_info(clock_info)?; + + let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; + if !stake_pool.is_valid() { + return Err(StakePoolError::InvalidState.into()); + } + + stake_pool.check_manager(manager_info)?; + + if stake_pool.last_update_epoch < clock.epoch { + return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); + } + + // Numerator should be smaller than or equal to denominator (fee <= 1) + if fee.numerator > fee.denominator { + msg!( + "Fee greater than 100%, numerator {}, denominator {}", + fee.numerator, + fee.denominator + ); + return Err(StakePoolError::FeeTooHigh.into()); + } + + stake_pool.fee = fee; + stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; + Ok(()) + } + /// Processes [SetManager](enum.Instruction.html). fn process_set_staker(_program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { let account_info_iter = &mut accounts.iter(); @@ -1169,6 +1203,10 @@ impl Processor { msg!("Instruction: SetManager"); Self::process_set_manager(program_id, accounts) } + StakePoolInstruction::SetFee { fee } => { + msg!("Instruction: SetFee"); + Self::process_set_fee(program_id, accounts, fee) + } StakePoolInstruction::SetStaker => { msg!("Instruction: SetStaker"); Self::process_set_staker(program_id, accounts) diff --git a/program/src/state.rs b/program/src/state.rs index ad41c4e0..e66ef017 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -1,7 +1,7 @@ //! State transition types use { - crate::{error::StakePoolError, instruction::Fee}, + crate::error::StakePoolError, borsh::{BorshDeserialize, BorshSchema, BorshSerialize}, solana_program::{account_info::AccountInfo, program_error::ProgramError, pubkey::Pubkey}, spl_math::checked_ceil_div::CheckedCeilDiv, @@ -294,6 +294,17 @@ impl ValidatorList { } } +/// Fee rate as a ratio, minted on `UpdateStakePoolBalance` as a proportion of +/// the rewards +#[repr(C)] +#[derive(Clone, Copy, Debug, Default, PartialEq, BorshSerialize, BorshDeserialize, BorshSchema)] +pub struct Fee { + /// denominator of the fee ratio + pub denominator: u64, + /// numerator of the fee ratio + pub numerator: u64, +} + #[cfg(test)] mod test { use { diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 8da7ee77..9db44382 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -204,7 +204,7 @@ pub async fn create_stake_pool( pool_token_account: &Pubkey, manager: &Keypair, staker: &Pubkey, - fee: &instruction::Fee, + fee: &state::Fee, max_validators: u32, ) -> Result<(), TransportError> { let rent = banks_client.get_rent().await.unwrap(); @@ -471,7 +471,7 @@ pub struct StakePoolAccounts { pub staker: Keypair, pub withdraw_authority: Pubkey, pub deposit_authority: Pubkey, - pub fee: instruction::Fee, + pub fee: state::Fee, pub max_validators: u32, } @@ -502,7 +502,7 @@ impl StakePoolAccounts { staker, withdraw_authority, deposit_authority, - fee: instruction::Fee { + fee: state::Fee { numerator: 1, denominator: 100, }, diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index 3fcbdc83..92ae7ca8 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -142,7 +142,7 @@ async fn fail_initialize_with_already_initialized_validator_list() { async fn fail_initialize_with_high_fee() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let mut stake_pool_accounts = StakePoolAccounts::new(); - stake_pool_accounts.fee = instruction::Fee { + stake_pool_accounts.fee = state::Fee { numerator: 100001, denominator: 100000, }; diff --git a/program/tests/set_fee.rs b/program/tests/set_fee.rs new file mode 100644 index 00000000..745550bd --- /dev/null +++ b/program/tests/set_fee.rs @@ -0,0 +1,177 @@ +#![cfg(feature = "test-bpf")] + +mod helpers; + +use { + borsh::BorshDeserialize, + helpers::*, + solana_program::hash::Hash, + solana_program_test::*, + solana_sdk::{ + instruction::InstructionError, signature::Keypair, signature::Signer, + transaction::Transaction, transaction::TransactionError, + }, + spl_stake_pool::{ + error, id, instruction, + state::{Fee, StakePool}, + }, +}; + +async fn setup() -> (BanksClient, Keypair, Hash, StakePoolAccounts, Fee) { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .await + .unwrap(); + let new_fee = Fee { + numerator: 10, + denominator: 10, + }; + + ( + banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + new_fee, + ) +} + +#[tokio::test] +async fn success() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_fee) = setup().await; + + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + new_fee.clone(), + )], + Some(&payer.pubkey()), + &[&payer, &stake_pool_accounts.manager], + recent_blockhash, + ); + banks_client.process_transaction(transaction).await.unwrap(); + + let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; + let stake_pool = StakePool::try_from_slice(&stake_pool.data.as_slice()).unwrap(); + + assert_eq!(stake_pool.fee, new_fee); +} + +#[tokio::test] +async fn fail_wrong_manager() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_fee) = setup().await; + + let wrong_manager = Keypair::new(); + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &wrong_manager.pubkey(), + new_fee, + )], + Some(&payer.pubkey()), + &[&payer, &wrong_manager], + recent_blockhash, + ); + let error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = error::StakePoolError::WrongManager as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while malicious try to set manager"), + } +} + +#[tokio::test] +async fn fail_bad_fee() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, _new_fee) = setup().await; + + let new_fee = Fee { + numerator: 11, + denominator: 10, + }; + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + new_fee, + )], + Some(&payer.pubkey()), + &[&payer, &stake_pool_accounts.manager], + recent_blockhash, + ); + let error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = error::StakePoolError::FeeTooHigh as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while malicious try to set manager"), + } +} + +#[tokio::test] +async fn fail_not_updated() { + let mut context = program_test().start_with_context().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await + .unwrap(); + let new_fee = Fee { + numerator: 10, + denominator: 100, + }; + + // move forward so an update is required + context.warp_to_slot(50_000).unwrap(); + + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + new_fee, + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = error::StakePoolError::StakeListAndPoolOutOfDate as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while malicious try to set manager"), + } +} From 7d8428bd35c676a49b72344eb854e4c765241387 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 21 Apr 2021 22:20:27 +0200 Subject: [PATCH 0085/1076] stake-pool: Add reserve stake and decrease / increase validator stake instruction (#1617) * Add reserve stake account * Add decrease validator stake instruction * Cargo fmt * Add increase instruction * Add more increase tests * Fix set fee tests * Fix clippy in tests * Add test-bpf feature to increase / decrease tests --- clients/cli/src/main.rs | 27 +- program/src/instruction.rs | 97 +++- program/src/lib.rs | 19 + program/src/processor.rs | 463 ++++++++++++++++-- program/src/state.rs | 77 ++- program/tests/decrease.rs | 391 +++++++++++++++ program/tests/deposit.rs | 12 +- program/tests/helpers/mod.rs | 101 +++- program/tests/increase.rs | 389 +++++++++++++++ program/tests/initialize.rs | 282 +++++++++-- program/tests/set_fee.rs | 5 +- program/tests/set_manager.rs | 4 +- program/tests/set_staker.rs | 2 +- program/tests/update_stake_pool_balance.rs | 6 +- .../tests/update_validator_list_balance.rs | 1 + program/tests/vsa_add.rs | 8 +- program/tests/vsa_create.rs | 10 +- program/tests/vsa_remove.rs | 2 +- program/tests/withdraw.rs | 12 +- 19 files changed, 1780 insertions(+), 128 deletions(-) create mode 100644 program/tests/decrease.rs create mode 100644 program/tests/increase.rs diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 3f7bc25e..4ceb5558 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -95,6 +95,9 @@ fn send_transaction( } fn command_create_pool(config: &Config, fee: Fee, max_validators: u32) -> CommandResult { + let reserve_stake = Keypair::new(); + println!("Creating reserve stake {}", reserve_stake.pubkey()); + let mint_account = Keypair::new(); println!("Creating mint {}", mint_account.pubkey()); @@ -109,6 +112,10 @@ fn command_create_pool(config: &Config, fee: Fee, max_validators: u32) -> Comman let validator_list = Keypair::new(); + let reserve_stake_balance = config + .rpc_client + .get_minimum_balance_for_rent_exemption(STAKE_STATE_LEN)? + + 1; let mint_account_balance = config .rpc_client .get_minimum_balance_for_rent_exemption(spl_token::state::Mint::LEN)?; @@ -123,7 +130,8 @@ fn command_create_pool(config: &Config, fee: Fee, max_validators: u32) -> Comman let validator_list_balance = config .rpc_client .get_minimum_balance_for_rent_exemption(validator_list_size)?; - let total_rent_free_balances = mint_account_balance + let total_rent_free_balances = reserve_stake_balance + + mint_account_balance + pool_fee_account_balance + stake_pool_account_lamports + validator_list_balance; @@ -142,6 +150,22 @@ fn command_create_pool(config: &Config, fee: Fee, max_validators: u32) -> Comman let mut transaction = Transaction::new_with_payer( &[ + // Account for the stake pool reserve + system_instruction::create_account( + &config.fee_payer.pubkey(), + &reserve_stake.pubkey(), + reserve_stake_balance, + STAKE_STATE_LEN as u64, + &stake_program::id(), + ), + stake_program::initialize( + &reserve_stake.pubkey(), + &stake_program::Authorized { + staker: withdraw_authority, + withdrawer: withdraw_authority, + }, + &stake_program::Lockup::default(), + ), // Account for the stake pool mint system_instruction::create_account( &config.fee_payer.pubkey(), @@ -196,6 +220,7 @@ fn command_create_pool(config: &Config, fee: Fee, max_validators: u32) -> Comman &config.manager.pubkey(), &config.staker.pubkey(), &validator_list.pubkey(), + &reserve_stake.pubkey(), &mint_account.pubkey(), &pool_fee_account.pubkey(), &spl_token::id(), diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 3cb639c7..106eab33 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -48,8 +48,10 @@ pub enum StakePoolInstruction { /// 3. `[w]` Stake account to be created /// 4. `[]` Validator this stake account will vote for /// 5. `[]` Rent sysvar - /// 6. `[]` System program - /// 7. `[]` Stake program + /// 6. `[]` Stake History sysvar + /// 7. `[]` Stake Config sysvar + /// 8. `[]` System program + /// 9. `[]` Stake program CreateValidatorStakeAccount, /// (Staker only) Adds stake account delegated to validator to the pool's @@ -98,13 +100,7 @@ pub enum StakePoolInstruction { /// In order to rebalance the pool without taking custody, the staker needs /// a way of reducing the stake on a stake account. This instruction splits /// some amount of stake, up to the total activated stake, from the canonical - /// validator stake account, into its "transient" stake account, defined by: - /// - /// ```ignore - /// Pubkey::find_program_address( - /// &[&stake_account_address.to_bytes()[..32],], program_id, - /// ) - /// ``` + /// validator stake account, into its "transient" stake account. /// /// The instruction only succeeds if the transient stake account does not /// exist. The amount of lamports to move must be at least rent-exemption @@ -112,15 +108,15 @@ pub enum StakePoolInstruction { /// /// 0. `[]` Stake pool /// 1. `[s]` Stake pool staker - /// 2. `[]` Validator list - /// 3. `[]` Stake pool withdraw authority + /// 2. `[]` Stake pool withdraw authority + /// 3. `[]` Validator list /// 5. `[w]` Canonical stake account to split from /// 5. `[w]` Transient stake account to receive split /// 6. `[]` Clock sysvar /// 7. `[]` Rent sysvar /// 8. `[]` System program /// 9. `[]` Stake program - /// userdata: amount of lamports to split + /// userdata: amount of lamports to split into the transient stake account DecreaseValidatorStake(u64), /// (Staker only) Increase stake on a validator from the reserve account @@ -135,13 +131,18 @@ pub enum StakePoolInstruction { /// /// 0. `[]` Stake pool /// 1. `[s]` Stake pool staker - /// 2. `[]` Validator list - /// 3. `[]` Stake pool withdraw authority + /// 2. `[]` Stake pool withdraw authority + /// 3. `[]` Validator list /// 4. `[w]` Stake pool reserve stake /// 5. `[w]` Transient stake account - /// 6. `[]` Canonical stake account + /// 6. `[]` Validator vote account to delegate to /// 7. '[]' Clock sysvar - /// 8. `[]` Stake program + /// 8. '[]' Rent sysvar + /// 9. `[]` Stake History sysvar + /// 10. `[]` Stake Config sysvar + /// 11. `[]` System program + /// 12. `[]` Stake program + /// userdata: amount of lamports to split into the transient stake account IncreaseValidatorStake(u64), /// Updates balances of validator and transient stake accounts in the pool @@ -249,6 +250,7 @@ pub fn initialize( manager: &Pubkey, staker: &Pubkey, validator_list: &Pubkey, + reserve_stake: &Pubkey, pool_mint: &Pubkey, manager_pool_account: &Pubkey, token_program_id: &Pubkey, @@ -265,6 +267,7 @@ pub fn initialize( AccountMeta::new_readonly(*manager, true), AccountMeta::new_readonly(*staker, false), AccountMeta::new(*validator_list, false), + AccountMeta::new_readonly(*reserve_stake, false), AccountMeta::new_readonly(*pool_mint, false), AccountMeta::new_readonly(*manager_pool_account, false), AccountMeta::new_readonly(sysvar::clock::id(), false), @@ -364,14 +367,68 @@ pub fn remove_validator_from_pool( /// Creates `DecreaseValidatorStake` instruction (rebalance from validator account to /// transient account) -pub fn decrease_validator_stake() -> Result { - Err(ProgramError::IncorrectProgramId) +pub fn decrease_validator_stake( + program_id: &Pubkey, + stake_pool: &Pubkey, + staker: &Pubkey, + stake_pool_withdraw_authority: &Pubkey, + validator_list: &Pubkey, + validator_stake: &Pubkey, + transient_stake: &Pubkey, + lamports: u64, +) -> Result { + let accounts = vec![ + AccountMeta::new_readonly(*stake_pool, false), + AccountMeta::new_readonly(*staker, true), + AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), + AccountMeta::new_readonly(*validator_list, false), + AccountMeta::new(*validator_stake, false), + AccountMeta::new(*transient_stake, false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(sysvar::rent::id(), false), + AccountMeta::new_readonly(system_program::id(), false), + AccountMeta::new_readonly(stake_program::id(), false), + ]; + Ok(Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::DecreaseValidatorStake(lamports).try_to_vec()?, + }) } /// Creates `IncreaseValidatorStake` instruction (rebalance from reserve account to /// transient account) -pub fn increase_validator_stake() -> Result { - Err(ProgramError::IncorrectProgramId) +pub fn increase_validator_stake( + program_id: &Pubkey, + stake_pool: &Pubkey, + staker: &Pubkey, + stake_pool_withdraw_authority: &Pubkey, + validator_list: &Pubkey, + reserve_stake: &Pubkey, + transient_stake: &Pubkey, + validator: &Pubkey, + lamports: u64, +) -> Result { + let accounts = vec![ + AccountMeta::new_readonly(*stake_pool, false), + AccountMeta::new_readonly(*staker, true), + AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), + AccountMeta::new_readonly(*validator_list, false), + AccountMeta::new(*reserve_stake, false), + AccountMeta::new(*transient_stake, false), + AccountMeta::new_readonly(*validator, false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(sysvar::rent::id(), false), + AccountMeta::new_readonly(sysvar::stake_history::id(), false), + AccountMeta::new_readonly(stake_program::config_id(), false), + AccountMeta::new_readonly(system_program::id(), false), + AccountMeta::new_readonly(stake_program::id(), false), + ]; + Ok(Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::IncreaseValidatorStake(lamports).try_to_vec()?, + }) } /// Creates `UpdateValidatorListBalance` instruction (update validator stake account balances) diff --git a/program/src/lib.rs b/program/src/lib.rs index c681105b..a889c6ba 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -25,6 +25,9 @@ const AUTHORITY_DEPOSIT: &[u8] = b"deposit"; /// Seed for withdraw authority seed const AUTHORITY_WITHDRAW: &[u8] = b"withdraw"; +/// Seed for transient stake account +const TRANSIENT_STAKE_SEED: &[u8] = b"transient"; + /// Minimum amount of staked SOL required in a validator stake account to allow /// for merges without a mismatch on credits observed pub const MINIMUM_ACTIVE_STAKE: u64 = LAMPORTS_PER_SOL; @@ -73,4 +76,20 @@ pub fn find_stake_program_address( ) } +/// Generates the stake program address for a validator's vote account +pub fn find_transient_stake_program_address( + program_id: &Pubkey, + vote_account_address: &Pubkey, + stake_pool_address: &Pubkey, +) -> (Pubkey, u8) { + Pubkey::find_program_address( + &[ + TRANSIENT_STAKE_SEED, + &vote_account_address.to_bytes()[..32], + &stake_pool_address.to_bytes()[..32], + ], + program_id, + ) +} + solana_program::declare_id!("poo1B9L9nR3CrcaziKVYVpRX6A9Y1LAXYasjjfCbApj"); diff --git a/program/src/processor.rs b/program/src/processor.rs index 98c1e72e..11eb3afd 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -7,7 +7,7 @@ use { instruction::StakePoolInstruction, minimum_stake_lamports, stake_program, state::{AccountType, Fee, StakePool, ValidatorList, ValidatorStakeInfo}, - AUTHORITY_DEPOSIT, AUTHORITY_WITHDRAW, MINIMUM_ACTIVE_STAKE, + AUTHORITY_DEPOSIT, AUTHORITY_WITHDRAW, MINIMUM_ACTIVE_STAKE, TRANSIENT_STAKE_SEED, }, bincode::deserialize, borsh::{BorshDeserialize, BorshSerialize}, @@ -44,33 +44,89 @@ fn get_stake_state( } } -/// Checks if validator stake account is a proper program address -fn is_validator_stake_address( +/// Check validity of vote address for a particular stake account +fn check_validator_stake_address( program_id: &Pubkey, stake_pool_address: &Pubkey, stake_account_address: &Pubkey, vote_address: &Pubkey, -) -> bool { +) -> Result<(), ProgramError> { // Check stake account address validity - let (stake_address, _) = + let (validator_stake_address, _) = crate::find_stake_program_address(&program_id, &vote_address, &stake_pool_address); - stake_address == *stake_account_address + if validator_stake_address != *stake_account_address { + msg!( + "Incorrect stake account address for vote {}, expected {}, received {}", + vote_address, + validator_stake_address, + stake_account_address + ); + Err(StakePoolError::InvalidStakeAccountAddress.into()) + } else { + Ok(()) + } } /// Check validity of vote address for a particular stake account -fn check_validator_stake_address( +fn check_transient_stake_address( program_id: &Pubkey, stake_pool_address: &Pubkey, stake_account_address: &Pubkey, vote_address: &Pubkey, -) -> Result<(), ProgramError> { - if !is_validator_stake_address( - program_id, - stake_pool_address, - stake_account_address, - vote_address, - ) { +) -> Result { + // Check stake account address validity + let (transient_stake_address, bump_seed) = crate::find_transient_stake_program_address( + &program_id, + &vote_address, + &stake_pool_address, + ); + if transient_stake_address != *stake_account_address { Err(StakePoolError::InvalidStakeAccountAddress.into()) + } else { + Ok(bump_seed) + } +} + +/// Check system program address +fn check_system_program(program_id: &Pubkey) -> Result<(), ProgramError> { + if *program_id != system_program::id() { + msg!( + "Expected system program {}, received {}", + system_program::id(), + program_id + ); + Err(ProgramError::IncorrectProgramId) + } else { + Ok(()) + } +} + +/// Check stake program address +fn check_stake_program(program_id: &Pubkey) -> Result<(), ProgramError> { + if *program_id != stake_program::id() { + msg!( + "Expected stake program {}, received {}", + stake_program::id(), + program_id + ); + Err(ProgramError::IncorrectProgramId) + } else { + Ok(()) + } +} + +/// Check account owner is the given program +fn check_account_owner( + account_info: &AccountInfo, + program_id: &Pubkey, +) -> Result<(), ProgramError> { + if *program_id != *account_info.owner { + msg!( + "Expected account to be owned by program {}, received {}", + program_id, + account_info.owner + ); + Err(ProgramError::IncorrectProgramId) } else { Ok(()) } @@ -79,6 +135,61 @@ fn check_validator_stake_address( /// Program state handler. pub struct Processor {} impl Processor { + /// Issue a stake_deactivate instruction. + #[allow(clippy::too_many_arguments)] + fn stake_delegate<'a>( + stake_info: AccountInfo<'a>, + vote_account_info: AccountInfo<'a>, + clock_info: AccountInfo<'a>, + stake_history_info: AccountInfo<'a>, + stake_config_info: AccountInfo<'a>, + authority_info: AccountInfo<'a>, + stake_pool: &Pubkey, + authority_type: &[u8], + bump_seed: u8, + ) -> Result<(), ProgramError> { + let authority_signature_seeds = + [&stake_pool.to_bytes()[..32], authority_type, &[bump_seed]]; + let signers = &[&authority_signature_seeds[..]]; + + let ix = stake_program::delegate_stake( + stake_info.key, + authority_info.key, + vote_account_info.key, + ); + + invoke_signed( + &ix, + &[ + stake_info, + vote_account_info, + clock_info, + stake_history_info, + stake_config_info, + authority_info, + ], + signers, + ) + } + + /// Issue a stake_deactivate instruction. + fn stake_deactivate<'a>( + stake_info: AccountInfo<'a>, + clock_info: AccountInfo<'a>, + authority_info: AccountInfo<'a>, + stake_pool: &Pubkey, + authority_type: &[u8], + bump_seed: u8, + ) -> Result<(), ProgramError> { + let authority_signature_seeds = + [&stake_pool.to_bytes()[..32], authority_type, &[bump_seed]]; + let signers = &[&authority_signature_seeds[..]]; + + let ix = stake_program::deactivate_stake(stake_info.key, authority_info.key); + + invoke_signed(&ix, &[stake_info, clock_info, authority_info], signers) + } + /// Issue a stake_split instruction. fn stake_split<'a>( stake_pool: &Pubkey, @@ -231,6 +342,7 @@ impl Processor { let manager_info = next_account_info(account_info_iter)?; let staker_info = next_account_info(account_info_iter)?; let validator_list_info = next_account_info(account_info_iter)?; + let reserve_stake_info = next_account_info(account_info_iter)?; let pool_mint_info = next_account_info(account_info_iter)?; let manager_fee_info = next_account_info(account_info_iter)?; let clock_info = next_account_info(account_info_iter)?; @@ -240,23 +352,31 @@ impl Processor { let token_program_info = next_account_info(account_info_iter)?; if !manager_info.is_signer { + msg!("Manager did not sign initialization"); return Err(StakePoolError::SignatureMissing.into()); } let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; if !stake_pool.is_uninitialized() { + msg!("Provided stake pool already in use"); return Err(StakePoolError::AlreadyInUse.into()); } let mut validator_list = try_from_slice_unchecked::(&validator_list_info.data.borrow())?; if !validator_list.is_uninitialized() { + msg!("Provided validator list already in use"); return Err(StakePoolError::AlreadyInUse.into()); } let data_length = validator_list_info.data_len(); let expected_max_validators = ValidatorList::calculate_max_validators(data_length); if expected_max_validators != max_validators as usize || max_validators == 0 { + msg!( + "Incorrect validator list size provided, expected {}, provided {}", + expected_max_validators, + max_validators + ); return Err(StakePoolError::UnexpectedValidatorListAccountSize.into()); } validator_list.account_type = AccountType::ValidatorList; @@ -310,14 +430,46 @@ impl Processor { return Err(StakePoolError::WrongMintingAuthority.into()); } - validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; + if *reserve_stake_info.owner != stake_program::id() { + msg!("Reserve stake account not owned by stake program"); + return Err(ProgramError::IncorrectProgramId); + } + let stake_state: stake_program::StakeState = deserialize(&reserve_stake_info.data.borrow()) + .or(Err(ProgramError::InvalidAccountData))?; + if let stake_program::StakeState::Initialized(meta) = stake_state { + if meta.lockup != stake_program::Lockup::default() { + msg!("Reserve stake account has some lockup"); + return Err(StakePoolError::WrongStakeState.into()); + } + + if meta.authorized.staker != withdraw_authority_key { + msg!( + "Reserve stake account has incorrect staker {}, should be {}", + meta.authorized.staker, + withdraw_authority_key + ); + return Err(StakePoolError::WrongStakeState.into()); + } + + if meta.authorized.withdrawer != withdraw_authority_key { + msg!( + "Reserve stake account has incorrect withdrawer {}, should be {}", + meta.authorized.staker, + withdraw_authority_key + ); + return Err(StakePoolError::WrongStakeState.into()); + } + } else { + msg!("Reserve stake account not in intialized state"); + return Err(StakePoolError::WrongStakeState.into()); + } - msg!("Clock data: {:?}", clock_info.data.borrow()); - msg!("Epoch: {}", clock.epoch); + validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; stake_pool.account_type = AccountType::StakePool; stake_pool.manager = *manager_info.key; stake_pool.staker = *staker_info.key; + stake_pool.reserve_stake = *reserve_stake_info.key; stake_pool.deposit_bump_seed = deposit_bump_seed; stake_pool.withdraw_bump_seed = withdraw_bump_seed; stake_pool.validator_list = *validator_list_info.key; @@ -360,12 +512,8 @@ impl Processor { } stake_pool.check_staker(staker_info)?; - if *system_program_info.key != system_program::id() { - return Err(ProgramError::IncorrectProgramId); - } - if *stake_program_info.key != stake_program::id() { - return Err(ProgramError::IncorrectProgramId); - } + check_system_program(system_program_info.key)?; + check_stake_program(stake_program_info.key)?; let (stake_address, bump_seed) = crate::find_stake_program_address( &program_id, @@ -450,9 +598,7 @@ impl Processor { let stake_history = &StakeHistory::from_account_info(stake_history_info)?; let stake_program_info = next_account_info(account_info_iter)?; - if *stake_program_info.key != stake_program::id() { - return Err(ProgramError::IncorrectProgramId); - } + check_stake_program(stake_program_info.key)?; if stake_pool_info.owner != program_id { return Err(ProgramError::IncorrectProgramId); @@ -556,9 +702,7 @@ impl Processor { let clock = &Clock::from_account_info(clock_info)?; let stake_program_info = next_account_info(account_info_iter)?; - if *stake_program_info.key != stake_program::id() { - return Err(ProgramError::IncorrectProgramId); - } + check_stake_program(stake_program_info.key)?; if stake_pool_info.owner != program_id { return Err(ProgramError::IncorrectProgramId); @@ -634,6 +778,259 @@ impl Processor { Ok(()) } + /// Processes `DecreaseValidatorStake` instruction. + fn process_decrease_validator_stake( + program_id: &Pubkey, + accounts: &[AccountInfo], + lamports: u64, + ) -> ProgramResult { + let account_info_iter = &mut accounts.iter(); + let stake_pool_info = next_account_info(account_info_iter)?; + let staker_info = next_account_info(account_info_iter)?; + let withdraw_authority_info = next_account_info(account_info_iter)?; + let validator_list_info = next_account_info(account_info_iter)?; + let validator_stake_account_info = next_account_info(account_info_iter)?; + let transient_stake_account_info = next_account_info(account_info_iter)?; + let clock_info = next_account_info(account_info_iter)?; + let clock = &Clock::from_account_info(clock_info)?; + let rent_info = next_account_info(account_info_iter)?; + let rent = &Rent::from_account_info(rent_info)?; + let system_program_info = next_account_info(account_info_iter)?; + let stake_program_info = next_account_info(account_info_iter)?; + + check_system_program(system_program_info.key)?; + check_stake_program(stake_program_info.key)?; + check_account_owner(stake_pool_info, program_id)?; + + let stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; + if !stake_pool.is_valid() { + msg!("Expected valid stake pool"); + return Err(StakePoolError::InvalidState.into()); + } + + stake_pool.check_authority_withdraw( + withdraw_authority_info.key, + program_id, + stake_pool_info.key, + )?; + stake_pool.check_staker(staker_info)?; + + if stake_pool.last_update_epoch < clock.epoch { + return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); + } + + stake_pool.check_validator_list(validator_list_info)?; + + let validator_list = + try_from_slice_unchecked::(&validator_list_info.data.borrow())?; + if !validator_list.is_valid() { + return Err(StakePoolError::InvalidState.into()); + } + + let (_meta, stake) = get_stake_state(validator_stake_account_info)?; + let vote_account_address = stake.delegation.voter_pubkey; + check_validator_stake_address( + program_id, + stake_pool_info.key, + validator_stake_account_info.key, + &vote_account_address, + )?; + + let transient_stake_bump_seed = check_transient_stake_address( + program_id, + stake_pool_info.key, + transient_stake_account_info.key, + &vote_account_address, + )?; + let transient_stake_account_signer_seeds: &[&[_]] = &[ + TRANSIENT_STAKE_SEED, + &vote_account_address.to_bytes()[..32], + &stake_pool_info.key.to_bytes()[..32], + &[transient_stake_bump_seed], + ]; + + if !validator_list.contains(&vote_account_address) { + msg!( + "Vote account {} not found in stake pool", + vote_account_address + ); + return Err(StakePoolError::ValidatorNotFound.into()); + } + + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + if lamports <= stake_rent { + msg!( + "Need more than {} lamports for transient stake to be rent-exempt, {} provided", + stake_rent, + lamports + ); + return Err(ProgramError::AccountNotRentExempt); + } + + // create transient stake account + invoke_signed( + &system_instruction::create_account( + &transient_stake_account_info.key, // doesn't matter since no lamports are transferred + &transient_stake_account_info.key, + 0, + std::mem::size_of::() as u64, + &stake_program::id(), + ), + &[transient_stake_account_info.clone()], + &[&transient_stake_account_signer_seeds], + )?; + + // split into transient stake account + Self::stake_split( + stake_pool_info.key, + validator_stake_account_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.withdraw_bump_seed, + lamports, + transient_stake_account_info.clone(), + )?; + + // deactivate transient stake + Self::stake_deactivate( + transient_stake_account_info.clone(), + clock_info.clone(), + withdraw_authority_info.clone(), + stake_pool_info.key, + AUTHORITY_WITHDRAW, + stake_pool.withdraw_bump_seed, + )?; + + Ok(()) + } + + /// Processes `IncreaseValidatorStake` instruction. + fn process_increase_validator_stake( + program_id: &Pubkey, + accounts: &[AccountInfo], + lamports: u64, + ) -> ProgramResult { + let account_info_iter = &mut accounts.iter(); + let stake_pool_info = next_account_info(account_info_iter)?; + let staker_info = next_account_info(account_info_iter)?; + let withdraw_authority_info = next_account_info(account_info_iter)?; + let validator_list_info = next_account_info(account_info_iter)?; + let reserve_stake_account_info = next_account_info(account_info_iter)?; + let transient_stake_account_info = next_account_info(account_info_iter)?; + let validator_vote_account_info = next_account_info(account_info_iter)?; + let clock_info = next_account_info(account_info_iter)?; + let clock = &Clock::from_account_info(clock_info)?; + let rent_info = next_account_info(account_info_iter)?; + let rent = &Rent::from_account_info(rent_info)?; + let stake_history_info = next_account_info(account_info_iter)?; + let stake_config_info = next_account_info(account_info_iter)?; + let system_program_info = next_account_info(account_info_iter)?; + let stake_program_info = next_account_info(account_info_iter)?; + + check_system_program(system_program_info.key)?; + check_stake_program(stake_program_info.key)?; + check_account_owner(stake_pool_info, program_id)?; + + let stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; + if !stake_pool.is_valid() { + msg!("Expected valid stake pool"); + return Err(StakePoolError::InvalidState.into()); + } + + stake_pool.check_authority_withdraw( + withdraw_authority_info.key, + program_id, + stake_pool_info.key, + )?; + stake_pool.check_staker(staker_info)?; + + if stake_pool.last_update_epoch < clock.epoch { + return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); + } + + stake_pool.check_validator_list(validator_list_info)?; + + let validator_list = + try_from_slice_unchecked::(&validator_list_info.data.borrow())?; + if !validator_list.is_valid() { + return Err(StakePoolError::InvalidState.into()); + } + + stake_pool.check_reserve_stake(reserve_stake_account_info)?; + + let vote_account_address = validator_vote_account_info.key; + + let transient_stake_bump_seed = check_transient_stake_address( + program_id, + stake_pool_info.key, + transient_stake_account_info.key, + &vote_account_address, + )?; + let transient_stake_account_signer_seeds: &[&[_]] = &[ + TRANSIENT_STAKE_SEED, + &vote_account_address.to_bytes()[..32], + &stake_pool_info.key.to_bytes()[..32], + &[transient_stake_bump_seed], + ]; + + if !validator_list.contains(&validator_vote_account_info.key) { + msg!( + "Vote account {} not found in stake pool", + vote_account_address + ); + return Err(StakePoolError::ValidatorNotFound.into()); + } + + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + if lamports <= stake_rent { + msg!( + "Need more than {} lamports for transient stake to be rent-exempt, {} provided", + stake_rent, + lamports + ); + return Err(ProgramError::AccountNotRentExempt); + } + + // create transient stake account + invoke_signed( + &system_instruction::create_account( + &transient_stake_account_info.key, // doesn't matter since no lamports are transferred + &transient_stake_account_info.key, + 0, + std::mem::size_of::() as u64, + &stake_program::id(), + ), + &[transient_stake_account_info.clone()], + &[&transient_stake_account_signer_seeds], + )?; + + // split into transient stake account + Self::stake_split( + stake_pool_info.key, + reserve_stake_account_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.withdraw_bump_seed, + lamports, + transient_stake_account_info.clone(), + )?; + + // activate transient stake to validator + Self::stake_delegate( + transient_stake_account_info.clone(), + validator_vote_account_info.clone(), + clock_info.clone(), + stake_history_info.clone(), + stake_config_info.clone(), + withdraw_authority_info.clone(), + stake_pool_info.key, + AUTHORITY_WITHDRAW, + stake_pool.withdraw_bump_seed, + )?; + + Ok(()) + } + /// Processes `UpdateValidatorListBalance` instruction. fn process_update_validator_list_balance( _program_id: &Pubkey, @@ -1175,13 +1572,13 @@ impl Processor { msg!("Instruction: RemoveValidatorFromPool"); Self::process_remove_validator_from_pool(program_id, accounts) } - StakePoolInstruction::DecreaseValidatorStake(_amount) => { + StakePoolInstruction::DecreaseValidatorStake(amount) => { msg!("Instruction: DecreaseValidatorStake"); - Ok(()) + Self::process_decrease_validator_stake(program_id, accounts, amount) } - StakePoolInstruction::IncreaseValidatorStake(_amount) => { + StakePoolInstruction::IncreaseValidatorStake(amount) => { msg!("Instruction: IncreaseValidatorStake"); - Ok(()) + Self::process_increase_validator_stake(program_id, accounts, amount) } StakePoolInstruction::UpdateValidatorListBalance => { msg!("Instruction: UpdateValidatorListBalance"); diff --git a/program/src/state.rs b/program/src/state.rs index e66ef017..94f1e317 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -3,7 +3,7 @@ use { crate::error::StakePoolError, borsh::{BorshDeserialize, BorshSchema, BorshSerialize}, - solana_program::{account_info::AccountInfo, program_error::ProgramError, pubkey::Pubkey}, + solana_program::{account_info::AccountInfo, msg, program_error::ProgramError, pubkey::Pubkey}, spl_math::checked_ceil_div::CheckedCeilDiv, std::convert::TryFrom, }; @@ -63,8 +63,8 @@ pub struct StakePool { pub token_program_id: Pubkey, /// Total stake under management. - /// Note that if `last_update_epoch` does not match the current epoch then this field may not - /// be accurate + /// Note that if `last_update_epoch` does not match the current epoch then + /// this field may not be accurate pub total_stake_lamports: u64, /// Total supply of pool tokens (should always match the supply in the Pool Mint) @@ -128,18 +128,23 @@ impl StakePool { authority_seed: &[u8], bump_seed: u8, ) -> Result<(), ProgramError> { - if *authority_address - == Pubkey::create_program_address( - &[ - &stake_pool_address.to_bytes()[..32], - authority_seed, - &[bump_seed], - ], - program_id, - )? - { + let expected_address = Pubkey::create_program_address( + &[ + &stake_pool_address.to_bytes()[..32], + authority_seed, + &[bump_seed], + ], + program_id, + )?; + + if *authority_address == expected_address { Ok(()) } else { + msg!( + "Incorrect authority provided, expected {}, received {}", + expected_address, + authority_address + ); Err(StakePoolError::InvalidProgramAddress.into()) } } @@ -187,9 +192,15 @@ impl StakePool { /// Check manager validity and signature pub(crate) fn check_manager(&self, manager_info: &AccountInfo) -> Result<(), ProgramError> { if *manager_info.key != self.manager { + msg!( + "Incorrect manager provided, expected {}, received {}", + self.manager, + manager_info.key + ); return Err(StakePoolError::WrongManager.into()); } if !manager_info.is_signer { + msg!("Manager signature missing"); return Err(StakePoolError::SignatureMissing.into()); } Ok(()) @@ -198,14 +209,54 @@ impl StakePool { /// Check staker validity and signature pub(crate) fn check_staker(&self, staker_info: &AccountInfo) -> Result<(), ProgramError> { if *staker_info.key != self.staker { + msg!( + "Incorrect staker provided, expected {}, received {}", + self.staker, + staker_info.key + ); return Err(StakePoolError::WrongStaker.into()); } if !staker_info.is_signer { + msg!("Staker signature missing"); return Err(StakePoolError::SignatureMissing.into()); } Ok(()) } + /// Check the validator list is valid + pub fn check_validator_list( + &self, + validator_list_info: &AccountInfo, + ) -> Result<(), ProgramError> { + if *validator_list_info.key != self.validator_list { + msg!( + "Invalid validator list provided, expected {}, received {}", + self.validator_list, + validator_list_info.key + ); + Err(StakePoolError::InvalidValidatorStakeList.into()) + } else { + Ok(()) + } + } + + /// Check the validator list is valid + pub fn check_reserve_stake( + &self, + reserve_stake_info: &AccountInfo, + ) -> Result<(), ProgramError> { + if *reserve_stake_info.key != self.reserve_stake { + msg!( + "Invalid reserve stake provided, expected {}, received {}", + self.reserve_stake, + reserve_stake_info.key + ); + Err(StakePoolError::InvalidProgramAddress.into()) + } else { + Ok(()) + } + } + /// Check if StakePool is actually initialized as a stake pool pub fn is_valid(&self) -> bool { self.account_type == AccountType::StakePool diff --git a/program/tests/decrease.rs b/program/tests/decrease.rs new file mode 100644 index 00000000..ad8c76e5 --- /dev/null +++ b/program/tests/decrease.rs @@ -0,0 +1,391 @@ +#![cfg(feature = "test-bpf")] + +mod helpers; + +use { + bincode::deserialize, + helpers::*, + solana_program::{ + clock::Epoch, hash::Hash, instruction::InstructionError, pubkey::Pubkey, + system_instruction::SystemError, + }, + solana_program_test::*, + solana_sdk::{ + signature::{Keypair, Signer}, + transaction::{Transaction, TransactionError}, + }, + spl_stake_pool::{error::StakePoolError, id, instruction, stake_program}, +}; + +async fn setup() -> ( + BanksClient, + Keypair, + Hash, + StakePoolAccounts, + ValidatorStakeAccount, + DepositInfo, + u64, +) { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .await + .unwrap(); + + let validator_stake_account = simple_add_validator_to_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + ) + .await; + + let deposit_info = simple_deposit( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + &validator_stake_account, + 100_000_000, + ) + .await; + + let lamports = deposit_info.stake_lamports / 2; + + ( + banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + validator_stake_account, + deposit_info, + lamports, + ) +} + +#[tokio::test] +async fn success() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + validator_stake, + _deposit_info, + decrease_lamports, + ) = setup().await; + + // Save validator stake + let pre_validator_stake_account = + get_account(&mut banks_client, &validator_stake.stake_account).await; + + // Check no transient stake + let transient_account = banks_client + .get_account(validator_stake.transient_stake_account) + .await + .unwrap(); + assert!(transient_account.is_none()); + + let error = stake_pool_accounts + .decrease_validator_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &validator_stake.stake_account, + &validator_stake.transient_stake_account, + decrease_lamports, + ) + .await; + assert!(error.is_none()); + + // Check validator stake account balance + let validator_stake_account = + get_account(&mut banks_client, &validator_stake.stake_account).await; + let validator_stake_state = + deserialize::(&validator_stake_account.data).unwrap(); + assert_eq!( + pre_validator_stake_account.lamports - decrease_lamports, + validator_stake_account.lamports + ); + assert_eq!( + validator_stake_state + .delegation() + .unwrap() + .deactivation_epoch, + Epoch::MAX + ); + + // Check transient stake account state and balance + let transient_stake_account = + get_account(&mut banks_client, &validator_stake.transient_stake_account).await; + let transient_stake_state = + deserialize::(&transient_stake_account.data).unwrap(); + assert_eq!(transient_stake_account.lamports, decrease_lamports); + assert_ne!( + transient_stake_state + .delegation() + .unwrap() + .deactivation_epoch, + Epoch::MAX + ); +} + +#[tokio::test] +async fn fail_with_wrong_withdraw_authority() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + validator_stake, + _deposit_info, + decrease_lamports, + ) = setup().await; + + let wrong_authority = Pubkey::new_unique(); + + let transaction = Transaction::new_signed_with_payer( + &[instruction::decrease_validator_stake( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.staker.pubkey(), + &wrong_authority, + &stake_pool_accounts.validator_list.pubkey(), + &validator_stake.stake_account, + &validator_stake.transient_stake_account, + decrease_lamports, + ) + .unwrap()], + Some(&payer.pubkey()), + &[&payer, &stake_pool_accounts.staker], + recent_blockhash, + ); + let error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = StakePoolError::InvalidProgramAddress as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while decreasing with wrong withdraw authority"), + } +} + +#[tokio::test] +async fn fail_with_wrong_validator_list() { + let ( + mut banks_client, + payer, + recent_blockhash, + mut stake_pool_accounts, + validator_stake, + _deposit_info, + decrease_lamports, + ) = setup().await; + + stake_pool_accounts.validator_list = Keypair::new(); + + let transaction = Transaction::new_signed_with_payer( + &[instruction::decrease_validator_stake( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.staker.pubkey(), + &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts.validator_list.pubkey(), + &validator_stake.stake_account, + &validator_stake.transient_stake_account, + decrease_lamports, + ) + .unwrap()], + Some(&payer.pubkey()), + &[&payer, &stake_pool_accounts.staker], + recent_blockhash, + ); + let error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = StakePoolError::InvalidValidatorStakeList as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while decreasing with wrong validator stake list account"), + } +} + +#[tokio::test] +async fn fail_with_unknown_validator() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + _validator_stake, + _deposit_info, + decrease_lamports, + ) = setup().await; + + let unknown_stake = ValidatorStakeAccount::new_with_target_authority( + &stake_pool_accounts.deposit_authority, + &stake_pool_accounts.stake_pool.pubkey(), + ); + unknown_stake + .create_and_delegate( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.staker, + ) + .await; + + let transaction = Transaction::new_signed_with_payer( + &[instruction::decrease_validator_stake( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.staker.pubkey(), + &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts.validator_list.pubkey(), + &unknown_stake.stake_account, + &unknown_stake.transient_stake_account, + decrease_lamports, + ) + .unwrap()], + Some(&payer.pubkey()), + &[&payer, &stake_pool_accounts.staker], + recent_blockhash, + ); + let error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = StakePoolError::ValidatorNotFound as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while decreasing stake from unknown validator"), + } +} + +#[tokio::test] +async fn fail_decrease_twice() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + validator_stake, + _deposit_info, + decrease_lamports, + ) = setup().await; + + let error = stake_pool_accounts + .decrease_validator_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &validator_stake.stake_account, + &validator_stake.transient_stake_account, + decrease_lamports / 3, + ) + .await; + assert!(error.is_none()); + + let error = stake_pool_accounts + .decrease_validator_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &validator_stake.stake_account, + &validator_stake.transient_stake_account, + decrease_lamports / 2, + ) + .await + .unwrap() + .unwrap(); + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = SystemError::AccountAlreadyInUse as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error"), + } +} + +#[tokio::test] +async fn fail_with_small_lamport_amount() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + validator_stake, + _deposit_info, + _decrease_lamports, + ) = setup().await; + + let rent = banks_client.get_rent().await.unwrap(); + let lamports = rent.minimum_balance(std::mem::size_of::()); + + let error = stake_pool_accounts + .decrease_validator_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &validator_stake.stake_account, + &validator_stake.transient_stake_account, + lamports, + ) + .await + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::InvalidError) => {} + _ => panic!("Wrong error occurs while try to decrease small stake"), + } +} + +#[tokio::test] +async fn fail_overdraw_validator() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + validator_stake, + deposit_info, + _decrease_lamports, + ) = setup().await; + + let error = stake_pool_accounts + .decrease_validator_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &validator_stake.stake_account, + &validator_stake.transient_stake_account, + deposit_info.stake_lamports * 1_000_000, + ) + .await + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::InsufficientFunds) => {} + _ => panic!("Wrong error occurs while overdrawing stake account on decrease"), + } +} diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index db3b4545..798fb7b1 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -36,7 +36,7 @@ async fn setup() -> ( let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await .unwrap(); @@ -80,6 +80,7 @@ async fn test_stake_pool_deposit() { &user_stake, &authorized, &lockup, + TEST_STAKE_AMOUNT, ) .await; @@ -301,6 +302,7 @@ async fn test_stake_pool_deposit_with_wrong_token_program_id() { &user_stake, &authorized, &lockup, + TEST_STAKE_AMOUNT, ) .await; @@ -375,6 +377,7 @@ async fn test_stake_pool_deposit_with_wrong_validator_list_account() { &user_stake, &authorized, &lockup, + TEST_STAKE_AMOUNT, ) .await; @@ -424,7 +427,7 @@ async fn test_stake_pool_deposit_to_unknown_validator() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await .unwrap(); @@ -468,6 +471,7 @@ async fn test_stake_pool_deposit_to_unknown_validator() { &user_stake, &authorized, &lockup, + TEST_STAKE_AMOUNT, ) .await; @@ -523,6 +527,7 @@ async fn test_stake_pool_deposit_with_wrong_deposit_authority() { &user_stake, &authorized, &lockup, + TEST_STAKE_AMOUNT, ) .await; @@ -591,6 +596,7 @@ async fn test_stake_pool_deposit_with_wrong_withdraw_authority() { &user_stake, &authorized, &lockup, + TEST_STAKE_AMOUNT, ) .await; @@ -654,6 +660,7 @@ async fn test_stake_pool_deposit_with_wrong_set_deposit_authority() { &user_stake, &authorized, &lockup, + TEST_STAKE_AMOUNT, ) .await; // make pool token account @@ -711,6 +718,7 @@ async fn test_stake_pool_deposit_with_wrong_mint_for_receiver_acc() { &user_stake, &authorized, &lockup, + TEST_STAKE_AMOUNT, ) .await; diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 9db44382..903796f8 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -14,11 +14,12 @@ use { solana_vote_program::{self, vote_state::VoteState}, spl_stake_pool::{ borsh::{get_instance_packed_len, try_from_slice_unchecked}, - find_stake_program_address, id, instruction, processor, stake_program, state, + find_stake_program_address, find_transient_stake_program_address, id, instruction, + processor, stake_program, state, }, }; -pub const TEST_STAKE_AMOUNT: u64 = 100; +pub const TEST_STAKE_AMOUNT: u64 = 1_000_000; pub const MAX_TEST_VALIDATORS: u32 = 10_000; pub fn program_test() -> ProgramTest { @@ -200,6 +201,7 @@ pub async fn create_stake_pool( recent_blockhash: &Hash, stake_pool: &Keypair, validator_list: &Keypair, + reserve_stake: &Pubkey, pool_mint: &Pubkey, pool_token_account: &Pubkey, manager: &Keypair, @@ -235,10 +237,11 @@ pub async fn create_stake_pool( &manager.pubkey(), staker, &validator_list.pubkey(), + reserve_stake, pool_mint, pool_token_account, &spl_token::id(), - fee.clone(), + *fee, max_validators, ) .unwrap(), @@ -283,10 +286,11 @@ pub async fn create_independent_stake_account( stake: &Keypair, authorized: &stake_program::Authorized, lockup: &stake_program::Lockup, + stake_amount: u64, ) -> u64 { let rent = banks_client.get_rent().await.unwrap(); let lamports = - rent.minimum_balance(std::mem::size_of::()) + TEST_STAKE_AMOUNT; + rent.minimum_balance(std::mem::size_of::()) + stake_amount; let transaction = Transaction::new_signed_with_payer( &stake_program::create_account( @@ -401,6 +405,7 @@ pub async fn authorize_stake_account( pub struct ValidatorStakeAccount { pub stake_account: Pubkey, + pub transient_stake_account: Pubkey, pub target_authority: Pubkey, pub vote: Keypair, pub stake_pool: Pubkey, @@ -410,8 +415,11 @@ impl ValidatorStakeAccount { pub fn new_with_target_authority(authority: &Pubkey, stake_pool: &Pubkey) -> Self { let validator = Keypair::new(); let (stake_account, _) = find_stake_program_address(&id(), &validator.pubkey(), stake_pool); + let (transient_stake_account, _) = + find_transient_stake_program_address(&id(), &validator.pubkey(), stake_pool); ValidatorStakeAccount { stake_account, + transient_stake_account, target_authority: *authority, vote: validator, stake_pool: *stake_pool, @@ -465,6 +473,7 @@ impl ValidatorStakeAccount { pub struct StakePoolAccounts { pub stake_pool: Keypair, pub validator_list: Keypair, + pub reserve_stake: Keypair, pub pool_mint: Keypair, pub pool_fee_account: Keypair, pub manager: Keypair, @@ -488,6 +497,7 @@ impl StakePoolAccounts { &[&stake_pool_address.to_bytes()[..32], b"deposit"], &id(), ); + let reserve_stake = Keypair::new(); let pool_mint = Keypair::new(); let pool_fee_account = Keypair::new(); let manager = Keypair::new(); @@ -496,6 +506,7 @@ impl StakePoolAccounts { Self { stake_pool, validator_list, + reserve_stake, pool_mint, pool_fee_account, manager, @@ -519,6 +530,7 @@ impl StakePoolAccounts { mut banks_client: &mut BanksClient, payer: &Keypair, recent_blockhash: &Hash, + reserve_lamports: u64, ) -> Result<(), TransportError> { create_mint( &mut banks_client, @@ -537,12 +549,26 @@ impl StakePoolAccounts { &self.manager.pubkey(), ) .await?; + create_independent_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &self.reserve_stake, + &stake_program::Authorized { + staker: self.withdraw_authority, + withdrawer: self.withdraw_authority, + }, + &stake_program::Lockup::default(), + reserve_lamports, + ) + .await; create_stake_pool( &mut banks_client, &payer, &recent_blockhash, &self.stake_pool, &self.validator_list, + &self.reserve_stake.pubkey(), &self.pool_mint.pubkey(), &self.pool_fee_account.pubkey(), &self.manager, @@ -585,6 +611,7 @@ impl StakePoolAccounts { Ok(()) } + #[allow(clippy::too_many_arguments)] pub async fn withdraw_stake( &self, banks_client: &mut BanksClient, @@ -695,7 +722,7 @@ impl StakePoolAccounts { stake: &Pubkey, new_authority: &Pubkey, ) -> Option { - let mut transaction = Transaction::new_with_payer( + let transaction = Transaction::new_signed_with_payer( &[instruction::remove_validator_from_pool( &id(), &self.stake_pool.pubkey(), @@ -707,8 +734,66 @@ impl StakePoolAccounts { ) .unwrap()], Some(&payer.pubkey()), + &[payer, &self.staker], + *recent_blockhash, + ); + banks_client.process_transaction(transaction).await.err() + } + + pub async fn decrease_validator_stake( + &self, + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + validator_stake: &Pubkey, + transient_stake: &Pubkey, + lamports: u64, + ) -> Option { + let transaction = Transaction::new_signed_with_payer( + &[instruction::decrease_validator_stake( + &id(), + &self.stake_pool.pubkey(), + &self.staker.pubkey(), + &self.withdraw_authority, + &self.validator_list.pubkey(), + validator_stake, + transient_stake, + lamports, + ) + .unwrap()], + Some(&payer.pubkey()), + &[payer, &self.staker], + *recent_blockhash, + ); + banks_client.process_transaction(transaction).await.err() + } + + pub async fn increase_validator_stake( + &self, + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + transient_stake: &Pubkey, + validator: &Pubkey, + lamports: u64, + ) -> Option { + let transaction = Transaction::new_signed_with_payer( + &[instruction::increase_validator_stake( + &id(), + &self.stake_pool.pubkey(), + &self.staker.pubkey(), + &self.withdraw_authority, + &self.validator_list.pubkey(), + &self.reserve_stake.pubkey(), + transient_stake, + validator, + lamports, + ) + .unwrap()], + Some(&payer.pubkey()), + &[payer, &self.staker], + *recent_blockhash, ); - transaction.sign(&[payer, &self.staker], *recent_blockhash); banks_client.process_transaction(transaction).await.err() } } @@ -759,6 +844,7 @@ pub async fn simple_deposit( recent_blockhash: &Hash, stake_pool_accounts: &StakePoolAccounts, validator_stake_account: &ValidatorStakeAccount, + stake_lamports: u64, ) -> DepositInfo { let user = Keypair::new(); // make stake account @@ -768,13 +854,14 @@ pub async fn simple_deposit( staker: stake_pool_accounts.deposit_authority, withdrawer: stake_pool_accounts.deposit_authority, }; - let stake_lamports = create_independent_stake_account( + create_independent_stake_account( banks_client, payer, recent_blockhash, &user_stake, &authorized, &lockup, + stake_lamports, ) .await; // make pool token account diff --git a/program/tests/increase.rs b/program/tests/increase.rs new file mode 100644 index 00000000..9d02c1c3 --- /dev/null +++ b/program/tests/increase.rs @@ -0,0 +1,389 @@ +#![cfg(feature = "test-bpf")] + +mod helpers; + +use { + bincode::deserialize, + helpers::*, + solana_program::{ + clock::Epoch, hash::Hash, instruction::InstructionError, pubkey::Pubkey, + system_instruction::SystemError, + }, + solana_program_test::*, + solana_sdk::{ + signature::{Keypair, Signer}, + transaction::{Transaction, TransactionError}, + }, + spl_stake_pool::{error::StakePoolError, id, instruction, stake_program}, +}; + +async fn setup() -> ( + BanksClient, + Keypair, + Hash, + StakePoolAccounts, + ValidatorStakeAccount, + u64, +) { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + let reserve_lamports = 100_000_000; + stake_pool_accounts + .initialize_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + reserve_lamports, + ) + .await + .unwrap(); + + let validator_stake_account = simple_add_validator_to_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + ) + .await; + + let _deposit_info = simple_deposit( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + &validator_stake_account, + 5_000_000, + ) + .await; + + ( + banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + validator_stake_account, + reserve_lamports, + ) +} + +#[tokio::test] +async fn success() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + validator_stake, + reserve_lamports, + ) = setup().await; + + // Save reserve stake + let pre_reserve_stake_account = get_account( + &mut banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + ) + .await; + + // Check no transient stake + let transient_account = banks_client + .get_account(validator_stake.transient_stake_account) + .await + .unwrap(); + assert!(transient_account.is_none()); + + let rent = banks_client.get_rent().await.unwrap(); + let lamports = rent.minimum_balance(std::mem::size_of::()); + let reserve_lamports = reserve_lamports - lamports; + let error = stake_pool_accounts + .increase_validator_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &validator_stake.transient_stake_account, + &validator_stake.vote.pubkey(), + reserve_lamports, + ) + .await; + assert!(error.is_none()); + + // Check reserve stake account balance + let reserve_stake_account = get_account( + &mut banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + ) + .await; + let reserve_stake_state = + deserialize::(&reserve_stake_account.data).unwrap(); + assert_eq!( + pre_reserve_stake_account.lamports - reserve_lamports, + reserve_stake_account.lamports + ); + assert!(reserve_stake_state.delegation().is_none()); + + // Check transient stake account state and balance + let transient_stake_account = + get_account(&mut banks_client, &validator_stake.transient_stake_account).await; + let transient_stake_state = + deserialize::(&transient_stake_account.data).unwrap(); + assert_eq!(transient_stake_account.lamports, reserve_lamports); + assert_ne!( + transient_stake_state.delegation().unwrap().activation_epoch, + Epoch::MAX + ); +} + +#[tokio::test] +async fn fail_with_wrong_withdraw_authority() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + validator_stake, + reserve_lamports, + ) = setup().await; + + let wrong_authority = Pubkey::new_unique(); + + let transaction = Transaction::new_signed_with_payer( + &[instruction::increase_validator_stake( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.staker.pubkey(), + &wrong_authority, + &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), + &validator_stake.transient_stake_account, + &validator_stake.vote.pubkey(), + reserve_lamports / 2, + ) + .unwrap()], + Some(&payer.pubkey()), + &[&payer, &stake_pool_accounts.staker], + recent_blockhash, + ); + let error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = StakePoolError::InvalidProgramAddress as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error"), + } +} + +#[tokio::test] +async fn fail_with_wrong_validator_list() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + validator_stake, + reserve_lamports, + ) = setup().await; + + let wrong_validator_list = Pubkey::new_unique(); + + let transaction = Transaction::new_signed_with_payer( + &[instruction::increase_validator_stake( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.staker.pubkey(), + &stake_pool_accounts.withdraw_authority, + &wrong_validator_list, + &stake_pool_accounts.reserve_stake.pubkey(), + &validator_stake.transient_stake_account, + &validator_stake.vote.pubkey(), + reserve_lamports / 2, + ) + .unwrap()], + Some(&payer.pubkey()), + &[&payer, &stake_pool_accounts.staker], + recent_blockhash, + ); + let error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = StakePoolError::InvalidValidatorStakeList as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error"), + } +} + +#[tokio::test] +async fn fail_with_unknown_validator() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + _validator_stake, + reserve_lamports, + ) = setup().await; + + let unknown_stake = ValidatorStakeAccount::new_with_target_authority( + &stake_pool_accounts.deposit_authority, + &stake_pool_accounts.stake_pool.pubkey(), + ); + unknown_stake + .create_and_delegate( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.staker, + ) + .await; + + let transaction = Transaction::new_signed_with_payer( + &[instruction::increase_validator_stake( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.staker.pubkey(), + &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), + &unknown_stake.transient_stake_account, + &unknown_stake.vote.pubkey(), + reserve_lamports / 2, + ) + .unwrap()], + Some(&payer.pubkey()), + &[&payer, &stake_pool_accounts.staker], + recent_blockhash, + ); + let error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = StakePoolError::ValidatorNotFound as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error"), + } +} + +#[tokio::test] +async fn fail_increase_twice() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + validator_stake, + reserve_lamports, + ) = setup().await; + + let error = stake_pool_accounts + .increase_validator_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &validator_stake.transient_stake_account, + &validator_stake.vote.pubkey(), + reserve_lamports / 3, + ) + .await; + assert!(error.is_none()); + + let error = stake_pool_accounts + .increase_validator_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &validator_stake.transient_stake_account, + &validator_stake.vote.pubkey(), + reserve_lamports / 4, + ) + .await + .unwrap() + .unwrap(); + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = SystemError::AccountAlreadyInUse as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error"), + } +} + +#[tokio::test] +async fn fail_with_small_lamport_amount() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + validator_stake, + _reserve_lamports, + ) = setup().await; + + let rent = banks_client.get_rent().await.unwrap(); + let lamports = rent.minimum_balance(std::mem::size_of::()); + + let error = stake_pool_accounts + .increase_validator_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &validator_stake.transient_stake_account, + &validator_stake.vote.pubkey(), + lamports, + ) + .await + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::InvalidError) => {} + _ => panic!("Wrong error"), + } +} + +#[tokio::test] +async fn fail_overdraw_reserve() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + validator_stake, + reserve_lamports, + ) = setup().await; + + let error = stake_pool_accounts + .increase_validator_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &validator_stake.transient_stake_account, + &validator_stake.vote.pubkey(), + reserve_lamports, + ) + .await + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::InsufficientFunds) => {} + _ => panic!("Wrong error occurs while overdrawing reserve stake"), + } +} diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index 92ae7ca8..44d47a2d 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -10,6 +10,7 @@ use { hash::Hash, instruction::{AccountMeta, Instruction}, program_pack::Pack, + pubkey::Pubkey, system_instruction, sysvar, }, solana_program_test::*, @@ -19,11 +20,11 @@ use { }, spl_stake_pool::{ borsh::{get_instance_packed_len, try_from_slice_unchecked}, - error, id, instruction, state, + error, id, instruction, stake_program, state, }, }; -async fn create_mint_and_token_account( +async fn create_required_accounts( banks_client: &mut BanksClient, payer: &Keypair, recent_blockhash: &Hash, @@ -49,14 +50,28 @@ async fn create_mint_and_token_account( ) .await .unwrap(); + + create_independent_stake_account( + banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.reserve_stake, + &stake_program::Authorized { + staker: stake_pool_accounts.withdraw_authority, + withdrawer: stake_pool_accounts.withdraw_authority, + }, + &stake_program::Lockup::default(), + 1, + ) + .await; } #[tokio::test] -async fn success_initialize() { +async fn success() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await .unwrap(); @@ -81,7 +96,7 @@ async fn fail_double_initialize() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await .unwrap(); @@ -91,7 +106,7 @@ async fn fail_double_initialize() { second_stake_pool_accounts.stake_pool = stake_pool_accounts.stake_pool; let transaction_error = second_stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &latest_blockhash) + .initialize_stake_pool(&mut banks_client, &payer, &latest_blockhash, 1) .await .err() .unwrap(); @@ -108,11 +123,11 @@ async fn fail_double_initialize() { } #[tokio::test] -async fn fail_initialize_with_already_initialized_validator_list() { +async fn fail_with_already_initialized_validator_list() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await .unwrap(); @@ -122,7 +137,7 @@ async fn fail_initialize_with_already_initialized_validator_list() { second_stake_pool_accounts.validator_list = stake_pool_accounts.validator_list; let transaction_error = second_stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &latest_blockhash) + .initialize_stake_pool(&mut banks_client, &payer, &latest_blockhash, 1) .await .err() .unwrap(); @@ -139,7 +154,7 @@ async fn fail_initialize_with_already_initialized_validator_list() { } #[tokio::test] -async fn fail_initialize_with_high_fee() { +async fn fail_with_high_fee() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let mut stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts.fee = state::Fee { @@ -148,7 +163,7 @@ async fn fail_initialize_with_high_fee() { }; let transaction_error = stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await .err() .unwrap(); @@ -165,11 +180,11 @@ async fn fail_initialize_with_high_fee() { } #[tokio::test] -async fn fail_initialize_with_wrong_max_validators() { +async fn fail_with_wrong_max_validators() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); - create_mint_and_token_account( + create_required_accounts( &mut banks_client, &payer, &recent_blockhash, @@ -207,10 +222,11 @@ async fn fail_initialize_with_wrong_max_validators() { &stake_pool_accounts.manager.pubkey(), &stake_pool_accounts.staker.pubkey(), &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), &spl_token::id(), - stake_pool_accounts.fee.clone(), + stake_pool_accounts.fee, stake_pool_accounts.max_validators, ) .unwrap(), @@ -245,12 +261,12 @@ async fn fail_initialize_with_wrong_max_validators() { } #[tokio::test] -async fn fail_initialize_with_wrong_mint_authority() { +async fn fail_with_wrong_mint_authority() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); let wrong_mint = Keypair::new(); - create_mint_and_token_account( + create_required_accounts( &mut banks_client, &payer, &recent_blockhash, @@ -275,6 +291,7 @@ async fn fail_initialize_with_wrong_mint_authority() { &recent_blockhash, &stake_pool_accounts.stake_pool, &stake_pool_accounts.validator_list, + &stake_pool_accounts.reserve_stake.pubkey(), &wrong_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.manager, @@ -299,7 +316,7 @@ async fn fail_initialize_with_wrong_mint_authority() { } #[tokio::test] -async fn fail_initialize_with_wrong_token_program_id() { +async fn fail_with_wrong_token_program_id() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); @@ -363,10 +380,11 @@ async fn fail_initialize_with_wrong_token_program_id() { &stake_pool_accounts.manager.pubkey(), &stake_pool_accounts.staker.pubkey(), &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), &wrong_token_program.pubkey(), - stake_pool_accounts.fee.clone(), + stake_pool_accounts.fee, stake_pool_accounts.max_validators, ) .unwrap(), @@ -399,7 +417,7 @@ async fn fail_initialize_with_wrong_token_program_id() { } #[tokio::test] -async fn fail_initialize_with_wrong_fee_account() { +async fn fail_with_wrong_fee_account() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); @@ -437,6 +455,7 @@ async fn fail_initialize_with_wrong_fee_account() { &recent_blockhash, &stake_pool_accounts.stake_pool, &stake_pool_accounts.validator_list, + &stake_pool_accounts.reserve_stake.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.manager, @@ -456,14 +475,14 @@ async fn fail_initialize_with_wrong_fee_account() { } #[tokio::test] -async fn fail_initialize_with_wrong_withdraw_authority() { +async fn fail_with_wrong_withdraw_authority() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let mut stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts.withdraw_authority = Keypair::new().pubkey(); let transaction_error = stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await .err() .unwrap(); @@ -483,11 +502,11 @@ async fn fail_initialize_with_wrong_withdraw_authority() { } #[tokio::test] -async fn fail_initialize_with_not_rent_exempt_pool() { +async fn fail_with_not_rent_exempt_pool() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); - create_mint_and_token_account( + create_required_accounts( &mut banks_client, &payer, &recent_blockhash, @@ -524,10 +543,11 @@ async fn fail_initialize_with_not_rent_exempt_pool() { &stake_pool_accounts.manager.pubkey(), &stake_pool_accounts.staker.pubkey(), &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), &spl_token::id(), - stake_pool_accounts.fee.clone(), + stake_pool_accounts.fee, stake_pool_accounts.max_validators, ) .unwrap(), @@ -556,11 +576,11 @@ async fn fail_initialize_with_not_rent_exempt_pool() { } #[tokio::test] -async fn fail_initialize_with_not_rent_exempt_validator_list() { +async fn fail_with_not_rent_exempt_validator_list() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); - create_mint_and_token_account( + create_required_accounts( &mut banks_client, &payer, &recent_blockhash, @@ -597,10 +617,11 @@ async fn fail_initialize_with_not_rent_exempt_validator_list() { &stake_pool_accounts.manager.pubkey(), &stake_pool_accounts.staker.pubkey(), &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), &spl_token::id(), - stake_pool_accounts.fee.clone(), + stake_pool_accounts.fee, stake_pool_accounts.max_validators, ) .unwrap(), @@ -631,11 +652,11 @@ async fn fail_initialize_with_not_rent_exempt_validator_list() { } #[tokio::test] -async fn fail_initialize_without_manager_signature() { +async fn fail_without_manager_signature() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); - create_mint_and_token_account( + create_required_accounts( &mut banks_client, &payer, &recent_blockhash, @@ -652,7 +673,7 @@ async fn fail_initialize_without_manager_signature() { let rent_validator_list = rent.minimum_balance(validator_list_size); let init_data = instruction::StakePoolInstruction::Initialize { - fee: stake_pool_accounts.fee.clone(), + fee: stake_pool_accounts.fee, max_validators: stake_pool_accounts.max_validators, }; let data = init_data.try_to_vec().unwrap(); @@ -661,6 +682,7 @@ async fn fail_initialize_without_manager_signature() { AccountMeta::new_readonly(stake_pool_accounts.manager.pubkey(), false), AccountMeta::new_readonly(stake_pool_accounts.staker.pubkey(), false), AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false), + AccountMeta::new_readonly(stake_pool_accounts.reserve_stake.pubkey(), false), AccountMeta::new_readonly(stake_pool_accounts.pool_mint.pubkey(), false), AccountMeta::new_readonly(stake_pool_accounts.pool_fee_account.pubkey(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), @@ -722,7 +744,7 @@ async fn fail_initialize_without_manager_signature() { } #[tokio::test] -async fn fail_initialize_with_pre_minted_pool_tokens() { +async fn fail_with_pre_minted_pool_tokens() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); let mint_authority = Keypair::new(); @@ -766,6 +788,7 @@ async fn fail_initialize_with_pre_minted_pool_tokens() { &recent_blockhash, &stake_pool_accounts.stake_pool, &stake_pool_accounts.validator_list, + &stake_pool_accounts.reserve_stake.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.manager, @@ -788,3 +811,200 @@ async fn fail_initialize_with_pre_minted_pool_tokens() { _ => panic!("Wrong error occurs while try to initialize stake pool with wrong mint authority of pool fee account"), } } + +#[tokio::test] +async fn fail_with_bad_reserve() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + let wrong_authority = Pubkey::new_unique(); + + create_required_accounts( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + ) + .await; + + { + let bad_stake = Keypair::new(); + create_independent_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &bad_stake, + &stake_program::Authorized { + staker: wrong_authority, + withdrawer: stake_pool_accounts.withdraw_authority, + }, + &stake_program::Lockup::default(), + 1, + ) + .await; + + let error = create_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.stake_pool, + &stake_pool_accounts.validator_list, + &bad_stake.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &stake_pool_accounts.pool_fee_account.pubkey(), + &stake_pool_accounts.manager, + &stake_pool_accounts.staker.pubkey(), + &stake_pool_accounts.fee, + stake_pool_accounts.max_validators, + ) + .await + .err() + .unwrap() + .unwrap(); + + assert_eq!( + error, + TransactionError::InstructionError( + 2, + InstructionError::Custom(error::StakePoolError::WrongStakeState as u32), + ) + ); + } + + { + let bad_stake = Keypair::new(); + create_independent_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &bad_stake, + &stake_program::Authorized { + staker: stake_pool_accounts.withdraw_authority, + withdrawer: wrong_authority, + }, + &stake_program::Lockup::default(), + 1, + ) + .await; + + let error = create_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.stake_pool, + &stake_pool_accounts.validator_list, + &bad_stake.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &stake_pool_accounts.pool_fee_account.pubkey(), + &stake_pool_accounts.manager, + &stake_pool_accounts.staker.pubkey(), + &stake_pool_accounts.fee, + stake_pool_accounts.max_validators, + ) + .await + .err() + .unwrap() + .unwrap(); + + assert_eq!( + error, + TransactionError::InstructionError( + 2, + InstructionError::Custom(error::StakePoolError::WrongStakeState as u32), + ) + ); + } + + { + let bad_stake = Keypair::new(); + create_independent_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &bad_stake, + &stake_program::Authorized { + staker: stake_pool_accounts.withdraw_authority, + withdrawer: stake_pool_accounts.withdraw_authority, + }, + &stake_program::Lockup { + custodian: wrong_authority, + ..stake_program::Lockup::default() + }, + 1, + ) + .await; + + let error = create_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.stake_pool, + &stake_pool_accounts.validator_list, + &bad_stake.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &stake_pool_accounts.pool_fee_account.pubkey(), + &stake_pool_accounts.manager, + &stake_pool_accounts.staker.pubkey(), + &stake_pool_accounts.fee, + stake_pool_accounts.max_validators, + ) + .await + .err() + .unwrap() + .unwrap(); + + assert_eq!( + error, + TransactionError::InstructionError( + 2, + InstructionError::Custom(error::StakePoolError::WrongStakeState as u32), + ) + ); + } + + { + let bad_stake = Keypair::new(); + let rent = banks_client.get_rent().await.unwrap(); + let lamports = rent.minimum_balance(std::mem::size_of::()); + + let transaction = Transaction::new_signed_with_payer( + &[system_instruction::create_account( + &payer.pubkey(), + &bad_stake.pubkey(), + lamports, + std::mem::size_of::() as u64, + &stake_program::id(), + )], + Some(&payer.pubkey()), + &[&payer, &bad_stake], + recent_blockhash, + ); + banks_client.process_transaction(transaction).await.unwrap(); + + let error = create_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.stake_pool, + &stake_pool_accounts.validator_list, + &bad_stake.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &stake_pool_accounts.pool_fee_account.pubkey(), + &stake_pool_accounts.manager, + &stake_pool_accounts.staker.pubkey(), + &stake_pool_accounts.fee, + stake_pool_accounts.max_validators, + ) + .await + .err() + .unwrap() + .unwrap(); + + assert_eq!( + error, + TransactionError::InstructionError( + 2, + InstructionError::Custom(error::StakePoolError::WrongStakeState as u32), + ) + ); + } +} diff --git a/program/tests/set_fee.rs b/program/tests/set_fee.rs index 745550bd..af485557 100644 --- a/program/tests/set_fee.rs +++ b/program/tests/set_fee.rs @@ -21,7 +21,7 @@ async fn setup() -> (BanksClient, Keypair, Hash, StakePoolAccounts, Fee) { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await .unwrap(); let new_fee = Fee { @@ -47,7 +47,7 @@ async fn success() { &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - new_fee.clone(), + new_fee, )], Some(&payer.pubkey()), &[&payer, &stake_pool_accounts.manager], @@ -137,6 +137,7 @@ async fn fail_not_updated() { &mut context.banks_client, &context.payer, &context.last_blockhash, + 1, ) .await .unwrap(); diff --git a/program/tests/set_manager.rs b/program/tests/set_manager.rs index 0b0223fe..4b7fc86f 100644 --- a/program/tests/set_manager.rs +++ b/program/tests/set_manager.rs @@ -28,7 +28,7 @@ async fn setup() -> ( let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await .unwrap(); @@ -160,7 +160,7 @@ async fn test_set_manager_with_wrong_mint_for_pool_fee_acc() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await .unwrap(); diff --git a/program/tests/set_staker.rs b/program/tests/set_staker.rs index b8d30171..1dac586b 100644 --- a/program/tests/set_staker.rs +++ b/program/tests/set_staker.rs @@ -21,7 +21,7 @@ async fn setup() -> (BanksClient, Keypair, Hash, StakePoolAccounts, Keypair) { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await .unwrap(); diff --git a/program/tests/update_stake_pool_balance.rs b/program/tests/update_stake_pool_balance.rs index cd319643..d91a62d7 100644 --- a/program/tests/update_stake_pool_balance.rs +++ b/program/tests/update_stake_pool_balance.rs @@ -26,6 +26,7 @@ async fn setup() -> ( &mut context.banks_client, &context.payer, &context.last_blockhash, + 1, ) .await .unwrap(); @@ -48,6 +49,7 @@ async fn setup() -> ( &context.last_blockhash, &stake_pool_accounts, &validator_stake_account, + TEST_STAKE_AMOUNT, ) .await; @@ -157,7 +159,7 @@ async fn fail_with_wrong_validator_list() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let mut stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await .unwrap(); @@ -186,7 +188,7 @@ async fn fail_with_wrong_pool_fee_account() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let mut stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await .unwrap(); diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index cd954aa0..5f8826ae 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -16,6 +16,7 @@ async fn success() { &mut context.banks_client, &context.payer, &context.last_blockhash, + 1, ) .await .unwrap(); diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index d5935e5b..5ab38eb6 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -34,7 +34,7 @@ async fn setup() -> ( let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await .unwrap(); @@ -158,7 +158,7 @@ async fn fail_too_little_stake() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await .unwrap(); @@ -248,7 +248,7 @@ async fn fail_too_much_stake() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await .unwrap(); @@ -463,7 +463,7 @@ async fn fail_add_too_many_validator_stake_accounts() { let mut stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts.max_validators = 1; stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await .unwrap(); diff --git a/program/tests/vsa_create.rs b/program/tests/vsa_create.rs index 317e59a6..ab7016e7 100644 --- a/program/tests/vsa_create.rs +++ b/program/tests/vsa_create.rs @@ -26,7 +26,7 @@ async fn success_create_validator_stake_account() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await .unwrap(); @@ -78,7 +78,7 @@ async fn fail_create_validator_stake_account_on_non_vote_account() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await .unwrap(); @@ -118,7 +118,7 @@ async fn fail_create_validator_stake_account_with_wrong_system_program() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await .unwrap(); @@ -168,7 +168,7 @@ async fn fail_create_validator_stake_account_with_wrong_stake_program() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await .unwrap(); @@ -218,7 +218,7 @@ async fn fail_create_validator_stake_account_with_incorrect_address() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await .unwrap(); diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 5e6e4b2f..1677bb48 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -34,7 +34,7 @@ async fn setup() -> ( let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await .unwrap(); diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index cf63c8bc..250d5e70 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -37,7 +37,7 @@ async fn setup() -> ( let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await .unwrap(); @@ -55,6 +55,7 @@ async fn setup() -> ( &recent_blockhash, &stake_pool_accounts, &validator_stake_account, + TEST_STAKE_AMOUNT, ) .await; @@ -398,7 +399,7 @@ async fn fail_with_unknown_validator() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await .unwrap(); @@ -456,6 +457,7 @@ async fn fail_with_unknown_validator() { &user_stake, &authorized, &lockup, + TEST_STAKE_AMOUNT, ) .await; // make pool token account @@ -597,7 +599,7 @@ async fn fail_without_token_approval() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await .unwrap(); @@ -615,6 +617,7 @@ async fn fail_without_token_approval() { &recent_blockhash, &stake_pool_accounts, &validator_stake_account, + TEST_STAKE_AMOUNT, ) .await; @@ -664,7 +667,7 @@ async fn fail_with_low_delegation() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash) + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await .unwrap(); @@ -682,6 +685,7 @@ async fn fail_with_low_delegation() { &recent_blockhash, &stake_pool_accounts, &validator_stake_account, + TEST_STAKE_AMOUNT, ) .await; From 9dcc0021007d9fd83783630f097c404cbb3fbfaf Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 22 Apr 2021 01:41:15 +0200 Subject: [PATCH 0086/1076] stake-pool: Add merging transient stakes in update (#1618) * Add check for transient stake account activation on removal * Add proper merging logic during update * Format + clippy * Add max possible validators * Disallow removal for any transient stake state * Reduce number of accounts for BPF instruction usage --- clients/cli/src/main.rs | 66 ++- program/src/instruction.rs | 118 +++-- program/src/lib.rs | 10 + program/src/processor.rs | 356 +++++++++++---- program/src/stake_program.rs | 217 ++++++++- program/tests/decrease.rs | 2 +- program/tests/deposit.rs | 1 + program/tests/helpers/mod.rs | 326 +++++++++++--- program/tests/update_stake_pool_balance.rs | 37 +- .../tests/update_validator_list_balance.rs | 417 ++++++++++++++++-- program/tests/vsa_add.rs | 1 + program/tests/vsa_create.rs | 16 +- program/tests/vsa_remove.rs | 61 ++- program/tests/withdraw.rs | 38 +- 14 files changed, 1382 insertions(+), 284 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 4ceb5558..34fe91f6 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -29,9 +29,10 @@ use { self, borsh::get_instance_packed_len, find_deposit_authority_program_address, find_stake_program_address, - find_withdraw_authority_program_address, + find_transient_stake_program_address, find_withdraw_authority_program_address, stake_program::{self, StakeAuthorize, StakeState}, state::{Fee, StakePool, ValidatorList}, + MAX_VALIDATORS_TO_UPDATE, }, std::process::exit, }; @@ -51,7 +52,6 @@ type Error = Box; type CommandResult = Result<(), Error>; const STAKE_STATE_LEN: usize = 200; -const MAX_ACCOUNTS_TO_UPDATE: usize = 10; lazy_static! { static ref MIN_STAKE_BALANCE: u64 = native_token::sol_to_lamports(1.0); } @@ -347,7 +347,7 @@ fn command_vsa_add(config: &Config, stake_pool_address: &Pubkey, stake: &Pubkey) fn command_vsa_remove( config: &Config, stake_pool_address: &Pubkey, - stake: &Pubkey, + vote_account: &Pubkey, new_authority: &Option, ) -> CommandResult { if !config.no_update { @@ -357,6 +357,13 @@ fn command_vsa_remove( let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; let pool_withdraw_authority = find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; + let (validator_stake_account, _) = + find_stake_program_address(&spl_stake_pool::id(), &vote_account, stake_pool_address); + let (transient_stake_account, _) = find_transient_stake_program_address( + &spl_stake_pool::id(), + &vote_account, + stake_pool_address, + ); let staker_pubkey = config.staker.pubkey(); let new_authority = new_authority.as_ref().unwrap_or(&staker_pubkey); @@ -371,7 +378,8 @@ fn command_vsa_remove( &pool_withdraw_authority, &new_authority, &stake_pool.validator_list, - &stake, + &validator_stake_account, + &transient_stake_account, )?, ], Some(&config.fee_payer.pubkey()), @@ -640,27 +648,34 @@ fn command_update(config: &Config, stake_pool_address: &Pubkey) -> CommandResult .collect(); println!("Updating stake pool..."); + let (withdraw_authority, _) = + find_withdraw_authority_program_address(&spl_stake_pool::id(), &stake_pool_address); let mut instructions: Vec = vec![]; - for accounts_chunk in accounts_to_update.chunks(MAX_ACCOUNTS_TO_UPDATE) { + let mut start_index = 0; + for accounts_chunk in accounts_to_update.chunks(MAX_VALIDATORS_TO_UPDATE) { instructions.push(spl_stake_pool::instruction::update_validator_list_balance( &spl_stake_pool::id(), + stake_pool_address, + &withdraw_authority, &stake_pool.validator_list, + &stake_pool.reserve_stake, &accounts_chunk, - )?); + start_index, + false, + )); + start_index += MAX_VALIDATORS_TO_UPDATE as u32; } - let (withdraw_authority, _) = - find_withdraw_authority_program_address(&spl_stake_pool::id(), &stake_pool_address); - instructions.push(spl_stake_pool::instruction::update_stake_pool_balance( &spl_stake_pool::id(), stake_pool_address, - &stake_pool.validator_list, &withdraw_authority, + &stake_pool.validator_list, + &stake_pool.reserve_stake, &stake_pool.manager_fee_account, &stake_pool.pool_mint, - )?); + )); // TODO: A faster solution would be to send all the `update_validator_list_balance` instructions concurrently for instruction in instructions { @@ -1135,15 +1150,6 @@ fn main() { .required(true) .help("Stake account to add to the pool"), ) - .arg( - Arg::with_name("token_receiver") - .long("token-receiver") - .validator(is_pubkey) - .value_name("ADDRESS") - .takes_value(true) - .help("Account to receive pool token. Must be initialized account of the stake pool token. \ - Defaults to the new pool token account."), - ) ) .subcommand(SubCommand::with_name("remove-validator") .about("Remove validator account from the stake pool. Must be signed by the pool staker.") @@ -1157,23 +1163,13 @@ fn main() { .help("Stake pool address"), ) .arg( - Arg::with_name("stake_account") + Arg::with_name("vote_account") .index(2) .validator(is_pubkey) - .value_name("STAKE_ACCOUNT_ADDRESS") - .takes_value(true) - .required(true) - .help("Stake account to remove from the pool"), - ) - .arg( - Arg::with_name("withdraw_from") - .long("withdraw-from") - .validator(is_pubkey) - .value_name("ADDRESS") + .value_name("VOTE_ACCOUNT_ADDRESS") .takes_value(true) .required(true) - .help("Token account to withdraw pool token from. \ - Must have enough tokens for the full stake address balance."), + .help("Vote account for the validator to remove from the pool"), ) .arg( Arg::with_name("new_authority") @@ -1455,9 +1451,9 @@ fn main() { } ("remove-validator", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); - let stake_account = pubkey_of(arg_matches, "stake_account").unwrap(); + let vote_account = pubkey_of(arg_matches, "vote_account").unwrap(); let new_authority: Option = pubkey_of(arg_matches, "new_authority"); - command_vsa_remove(&config, &stake_pool_address, &stake_account, &new_authority) + command_vsa_remove(&config, &stake_pool_address, &vote_account, &new_authority) } ("deposit", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 106eab33..0983bf3a 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -3,7 +3,9 @@ #![allow(clippy::too_many_arguments)] use { - crate::{stake_program, state::Fee}, + crate::{ + find_stake_program_address, find_transient_stake_program_address, stake_program, state::Fee, + }, borsh::{BorshDeserialize, BorshSchema, BorshSerialize}, solana_program::{ instruction::{AccountMeta, Instruction}, @@ -88,8 +90,9 @@ pub enum StakePoolInstruction { /// 3. `[]` New withdraw/staker authority to set in the stake account /// 4. `[w]` Validator stake list storage account /// 5. `[w]` Stake account to remove from the pool - /// 8. '[]' Sysvar clock - /// 10. `[]` Stake program id, + /// 6. `[]` Transient stake account, to check that that we're not trying to activate + /// 7. '[]' Sysvar clock + /// 8. `[]` Stake program id, RemoveValidatorFromPool, /// (Staker only) Decrease active stake on a validator, eventually moving it to the reserve @@ -132,7 +135,7 @@ pub enum StakePoolInstruction { /// 0. `[]` Stake pool /// 1. `[s]` Stake pool staker /// 2. `[]` Stake pool withdraw authority - /// 3. `[]` Validator list + /// 3. `[w]` Validator list /// 4. `[w]` Stake pool reserve stake /// 5. `[w]` Transient stake account /// 6. `[]` Validator vote account to delegate to @@ -149,26 +152,36 @@ pub enum StakePoolInstruction { /// /// While going through the pairs of validator and transient stake accounts, /// if the transient stake is inactive, it is merged into the reserve stake - /// account. If the transient stake is active and has matching credits + /// account. If the transient stake is active and has matching credits /// observed, it is merged into the canonical validator stake account. In /// all other states, nothing is done, and the balance is simply added to /// the canonical stake account balance. /// /// 0. `[]` Stake pool - /// 1. `[w]` Validator stake list storage account - /// 2. `[w]` Reserve stake account - /// 3. `[]` Stake pool withdraw authority - /// 4. `[]` Sysvar clock account - /// 5. `[]` Stake program - /// 6. ..6+N ` [] N pairs of validator and transient stake accounts - UpdateValidatorListBalance, + /// 1. `[]` Stake pool withdraw authority + /// 2. `[w]` Validator stake list storage account + /// 3. `[w]` Reserve stake account + /// 4. `[]` Sysvar clock + /// 5. `[]` Sysvar stake history + /// 6. `[]` Stake program + /// 7. ..7+N ` [] N pairs of validator and transient stake accounts + UpdateValidatorListBalance { + /// Index to start updating on the validator list + #[allow(dead_code)] // but it's not + start_index: u32, + /// If true, don't try merging transient stake accounts into the reserve or + /// validator stake account. Useful for testing or if a particular stake + /// account is in a bad state, but we still want to update + #[allow(dead_code)] // but it's not + no_merge: bool, + }, /// Updates total pool balance based on balances in the reserve and validator list /// /// 0. `[w]` Stake pool - /// 1. `[]` Validator stake list storage account - /// 2. `[]` Reserve stake account - /// 3. `[]` Stake pool withdraw authority + /// 1. `[]` Stake pool withdraw authority + /// 2. `[]` Validator stake list storage account + /// 3. `[]` Reserve stake account /// 4. `[w]` Account to receive pool fee tokens /// 5. `[w]` Pool mint account /// 6. `[]` Sysvar clock account @@ -347,6 +360,7 @@ pub fn remove_validator_from_pool( new_stake_authority: &Pubkey, validator_list: &Pubkey, stake_account: &Pubkey, + transient_stake_account: &Pubkey, ) -> Result { let accounts = vec![ AccountMeta::new(*stake_pool, false), @@ -355,6 +369,7 @@ pub fn remove_validator_from_pool( AccountMeta::new_readonly(*new_stake_authority, false), AccountMeta::new(*validator_list, false), AccountMeta::new(*stake_account, false), + AccountMeta::new_readonly(*transient_stake_account, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(stake_program::id(), false), ]; @@ -413,7 +428,7 @@ pub fn increase_validator_stake( AccountMeta::new_readonly(*stake_pool, false), AccountMeta::new_readonly(*staker, true), AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), - AccountMeta::new_readonly(*validator_list, false), + AccountMeta::new(*validator_list, false), AccountMeta::new(*reserve_stake, false), AccountMeta::new(*transient_stake, false), AccountMeta::new_readonly(*validator, false), @@ -434,45 +449,80 @@ pub fn increase_validator_stake( /// Creates `UpdateValidatorListBalance` instruction (update validator stake account balances) pub fn update_validator_list_balance( program_id: &Pubkey, - validator_list_storage: &Pubkey, - validator_list: &[Pubkey], -) -> Result { - let mut accounts: Vec = validator_list - .iter() - .map(|pubkey| AccountMeta::new_readonly(*pubkey, false)) - .collect(); - accounts.insert(0, AccountMeta::new(*validator_list_storage, false)); - accounts.insert(1, AccountMeta::new_readonly(sysvar::clock::id(), false)); - Ok(Instruction { + stake_pool: &Pubkey, + stake_pool_withdraw_authority: &Pubkey, + validator_list: &Pubkey, + reserve_stake: &Pubkey, + validator_vote_accounts: &[Pubkey], + start_index: u32, + no_merge: bool, +) -> Instruction { + let mut accounts = vec![ + AccountMeta::new_readonly(*stake_pool, false), + AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), + AccountMeta::new(*validator_list, false), + AccountMeta::new(*reserve_stake, false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(sysvar::stake_history::id(), false), + AccountMeta::new_readonly(stake_program::id(), false), + ]; + accounts.append( + &mut validator_vote_accounts + .iter() + .flat_map(|vote_account_address| { + let (validator_stake_account, _) = + find_stake_program_address(program_id, vote_account_address, stake_pool); + let (transient_stake_account, _) = find_transient_stake_program_address( + program_id, + vote_account_address, + stake_pool, + ); + vec![ + AccountMeta::new(validator_stake_account, false), + AccountMeta::new(transient_stake_account, false), + ] + }) + .collect::>(), + ); + Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::UpdateValidatorListBalance.try_to_vec()?, - }) + data: StakePoolInstruction::UpdateValidatorListBalance { + start_index, + no_merge, + } + .try_to_vec() + .unwrap(), + } } /// Creates `UpdateStakePoolBalance` instruction (pool balance from the stake account list balances) pub fn update_stake_pool_balance( program_id: &Pubkey, stake_pool: &Pubkey, - validator_list_storage: &Pubkey, withdraw_authority: &Pubkey, + validator_list_storage: &Pubkey, + reserve_stake: &Pubkey, manager_fee_account: &Pubkey, stake_pool_mint: &Pubkey, -) -> Result { +) -> Instruction { let accounts = vec![ AccountMeta::new(*stake_pool, false), - AccountMeta::new(*validator_list_storage, false), AccountMeta::new_readonly(*withdraw_authority, false), + AccountMeta::new_readonly(*validator_list_storage, false), + AccountMeta::new_readonly(*reserve_stake, false), AccountMeta::new(*manager_fee_account, false), AccountMeta::new(*stake_pool_mint, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(spl_token::id(), false), ]; - Ok(Instruction { + Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::UpdateStakePoolBalance.try_to_vec()?, - }) + data: StakePoolInstruction::UpdateStakePoolBalance + .try_to_vec() + .unwrap(), + } } /// Creates a 'Deposit' instruction. diff --git a/program/src/lib.rs b/program/src/lib.rs index a889c6ba..333e7603 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -32,6 +32,10 @@ const TRANSIENT_STAKE_SEED: &[u8] = b"transient"; /// for merges without a mismatch on credits observed pub const MINIMUM_ACTIVE_STAKE: u64 = LAMPORTS_PER_SOL; +/// Maximum amount of validator stake accounts to update per +/// `UpdateValidatorListBalance` instruction, based on compute limits +pub const MAX_VALIDATORS_TO_UPDATE: usize = 10; + /// Get the stake amount under consideration when calculating pool token /// conversions pub fn minimum_stake_lamports(meta: &Meta) -> u64 { @@ -39,6 +43,12 @@ pub fn minimum_stake_lamports(meta: &Meta) -> u64 { .saturating_add(MINIMUM_ACTIVE_STAKE) } +/// Get the stake amount under consideration when calculating pool token +/// conversions +pub fn minimum_reserve_lamports(meta: &Meta) -> u64 { + meta.rent_exempt_reserve.saturating_add(1) +} + /// Generates the deposit authority program address for the stake pool pub fn find_deposit_authority_program_address( program_id: &Pubkey, diff --git a/program/src/processor.rs b/program/src/processor.rs index 11eb3afd..90201651 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -5,11 +5,10 @@ use { borsh::try_from_slice_unchecked, error::StakePoolError, instruction::StakePoolInstruction, - minimum_stake_lamports, stake_program, + minimum_reserve_lamports, minimum_stake_lamports, stake_program, state::{AccountType, Fee, StakePool, ValidatorList, ValidatorStakeInfo}, AUTHORITY_DEPOSIT, AUTHORITY_WITHDRAW, MINIMUM_ACTIVE_STAKE, TRANSIENT_STAKE_SEED, }, - bincode::deserialize, borsh::{BorshDeserialize, BorshSerialize}, num_traits::FromPrimitive, solana_program::{ @@ -36,8 +35,8 @@ use { fn get_stake_state( stake_account_info: &AccountInfo, ) -> Result<(stake_program::Meta, stake_program::Stake), ProgramError> { - let stake_state: stake_program::StakeState = - deserialize(&stake_account_info.data.borrow()).or(Err(ProgramError::InvalidAccountData))?; + let stake_state = + try_from_slice_unchecked::(&stake_account_info.data.borrow())?; match stake_state { stake_program::StakeState::Stake(meta, stake) => Ok((meta, stake)), _ => Err(StakePoolError::WrongStakeState.into()), @@ -214,11 +213,11 @@ impl Processor { #[allow(clippy::too_many_arguments)] fn stake_merge<'a>( stake_pool: &Pubkey, - stake_account: AccountInfo<'a>, + source_account: AccountInfo<'a>, authority: AccountInfo<'a>, authority_type: &[u8], bump_seed: u8, - merge_with: AccountInfo<'a>, + destination_account: AccountInfo<'a>, clock: AccountInfo<'a>, stake_history: AccountInfo<'a>, stake_program_info: AccountInfo<'a>, @@ -227,13 +226,13 @@ impl Processor { let authority_signature_seeds = [&me_bytes[..32], authority_type, &[bump_seed]]; let signers = &[&authority_signature_seeds[..]]; - let ix = stake_program::merge(merge_with.key, stake_account.key, authority.key); + let ix = stake_program::merge(destination_account.key, source_account.key, authority.key); invoke_signed( &ix, &[ - merge_with, - stake_account, + destination_account, + source_account, clock, stake_history, authority, @@ -434,9 +433,11 @@ impl Processor { msg!("Reserve stake account not owned by stake program"); return Err(ProgramError::IncorrectProgramId); } - let stake_state: stake_program::StakeState = deserialize(&reserve_stake_info.data.borrow()) - .or(Err(ProgramError::InvalidAccountData))?; - if let stake_program::StakeState::Initialized(meta) = stake_state { + let stake_state = try_from_slice_unchecked::( + &reserve_stake_info.data.borrow(), + )?; + let total_stake_lamports = if let stake_program::StakeState::Initialized(meta) = stake_state + { if meta.lockup != stake_program::Lockup::default() { msg!("Reserve stake account has some lockup"); return Err(StakePoolError::WrongStakeState.into()); @@ -459,10 +460,14 @@ impl Processor { ); return Err(StakePoolError::WrongStakeState.into()); } + reserve_stake_info + .lamports() + .checked_sub(minimum_reserve_lamports(&meta)) + .ok_or(StakePoolError::CalculationFailure)? } else { msg!("Reserve stake account not in intialized state"); return Err(StakePoolError::WrongStakeState.into()); - } + }; validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; @@ -478,6 +483,7 @@ impl Processor { stake_pool.token_program_id = *token_program_info.key; stake_pool.last_update_epoch = clock.epoch; stake_pool.fee = fee; + stake_pool.total_stake_lamports = total_stake_lamports; stake_pool .serialize(&mut *stake_pool_info.data.borrow_mut()) @@ -594,8 +600,8 @@ impl Processor { let stake_account_info = next_account_info(account_info_iter)?; let clock_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(clock_info)?; - let stake_history_info = next_account_info(account_info_iter)?; - let stake_history = &StakeHistory::from_account_info(stake_history_info)?; + let _stake_history_info = next_account_info(account_info_iter)?; + //let stake_history = &StakeHistory::from_account_info(stake_history_info)?; let stake_program_info = next_account_info(account_info_iter)?; check_stake_program(stake_program_info.key)?; @@ -656,7 +662,7 @@ impl Processor { } // Check if stake is warmed up - Self::check_stake_activation(stake_account_info, clock, stake_history)?; + //Self::check_stake_activation(stake_account_info, clock, stake_history)?; // Update Withdrawer and Staker authority to the program withdraw authority for authority in &[ @@ -698,15 +704,14 @@ impl Processor { let new_stake_authority_info = next_account_info(account_info_iter)?; let validator_list_info = next_account_info(account_info_iter)?; let stake_account_info = next_account_info(account_info_iter)?; + let transient_stake_account_info = next_account_info(account_info_iter)?; let clock_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(clock_info)?; let stake_program_info = next_account_info(account_info_iter)?; check_stake_program(stake_program_info.key)?; + check_account_owner(stake_pool_info, program_id)?; - if stake_pool_info.owner != program_id { - return Err(ProgramError::IncorrectProgramId); - } let stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); @@ -719,9 +724,7 @@ impl Processor { return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); } - if *validator_list_info.key != stake_pool.validator_list { - return Err(StakePoolError::InvalidValidatorStakeList.into()); - } + stake_pool.check_validator_list(validator_list_info)?; let mut validator_list = try_from_slice_unchecked::(&validator_list_info.data.borrow())?; @@ -737,6 +740,22 @@ impl Processor { stake_account_info.key, &vote_account_address, )?; + check_transient_stake_address( + program_id, + stake_pool_info.key, + transient_stake_account_info.key, + &vote_account_address, + )?; + // check that the transient stake account doesn't exist + if get_stake_state(transient_stake_account_info).is_ok() { + msg!( + "Transient stake {} exists, can't remove stake {} on validator {}", + transient_stake_account_info.key, + stake_account_info.key, + vote_account_address + ); + return Err(StakePoolError::WrongStakeState.into()); + } if !validator_list.contains(&vote_account_address) { return Err(StakePoolError::ValidatorNotFound.into()); @@ -950,7 +969,7 @@ impl Processor { stake_pool.check_validator_list(validator_list_info)?; - let validator_list = + let mut validator_list = try_from_slice_unchecked::(&validator_list_info.data.borrow())?; if !validator_list.is_valid() { return Err(StakePoolError::InvalidState.into()); @@ -973,13 +992,15 @@ impl Processor { &[transient_stake_bump_seed], ]; - if !validator_list.contains(&validator_vote_account_info.key) { + let maybe_validator_list_entry = validator_list.find_mut(&vote_account_address); + if maybe_validator_list_entry.is_none() { msg!( "Vote account {} not found in stake pool", vote_account_address ); return Err(StakePoolError::ValidatorNotFound.into()); } + let mut validator_list_entry = maybe_validator_list_entry.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); if lamports <= stake_rent { @@ -991,6 +1012,22 @@ impl Processor { return Err(ProgramError::AccountNotRentExempt); } + if reserve_stake_account_info + .lamports() + .saturating_sub(lamports) + <= stake_rent + { + let max_split_amount = reserve_stake_account_info + .lamports() + .saturating_sub(stake_rent); + msg!( + "Reserve stake does not have enough lamports for increase, must be less than {}, {} requested", + max_split_amount, + lamports + ); + return Err(ProgramError::InsufficientFunds); + } + // create transient stake account invoke_signed( &system_instruction::create_account( @@ -1028,51 +1065,191 @@ impl Processor { stake_pool.withdraw_bump_seed, )?; + validator_list_entry.stake_lamports = validator_list_entry + .stake_lamports + .checked_add(lamports) + .ok_or(StakePoolError::CalculationFailure)?; + validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; + Ok(()) } /// Processes `UpdateValidatorListBalance` instruction. fn process_update_validator_list_balance( - _program_id: &Pubkey, + program_id: &Pubkey, accounts: &[AccountInfo], + start_index: u32, + no_merge: bool, ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); + let stake_pool_info = next_account_info(account_info_iter)?; + let withdraw_authority_info = next_account_info(account_info_iter)?; let validator_list_info = next_account_info(account_info_iter)?; + let reserve_stake_info = next_account_info(account_info_iter)?; let clock_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(clock_info)?; + let stake_history_info = next_account_info(account_info_iter)?; + let stake_program_info = next_account_info(account_info_iter)?; let validator_stake_accounts = account_info_iter.as_slice(); + check_account_owner(stake_pool_info, program_id)?; + let stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; + if !stake_pool.is_valid() { + return Err(StakePoolError::InvalidState.into()); + } + stake_pool.check_validator_list(&validator_list_info)?; + stake_pool.check_authority_withdraw( + withdraw_authority_info.key, + program_id, + stake_pool_info.key, + )?; + stake_pool.check_reserve_stake(reserve_stake_info)?; + check_stake_program(stake_program_info.key)?; + let mut validator_list = try_from_slice_unchecked::(&validator_list_info.data.borrow())?; if !validator_list.is_valid() { return Err(StakePoolError::InvalidState.into()); } - let stake_states: Vec<(stake_program::Meta, stake_program::Stake)> = - validator_stake_accounts - .iter() - .filter_map(|stake| get_stake_state(stake).ok()) - .collect(); - let mut changes = false; - // Do a brute iteration through the list, optimize if necessary - for validator_stake_record in &mut validator_list.validators { - if validator_stake_record.last_update_epoch >= clock.epoch { + let validator_iter = &mut validator_list + .validators + .iter_mut() + .skip(start_index as usize) + .zip(validator_stake_accounts.chunks_exact(2)); + for (validator_stake_record, validator_stakes) in validator_iter { + // chunks_exact means that we always get 2 elements, making this safe + let validator_stake_info = validator_stakes.first().unwrap(); + let transient_stake_info = validator_stakes.last().unwrap(); + if check_validator_stake_address( + program_id, + stake_pool_info.key, + validator_stake_info.key, + &validator_stake_record.vote_account_address, + ) + .is_err() + { continue; - } - for (validator_stake_account, (meta, stake)) in - validator_stake_accounts.iter().zip(stake_states.iter()) + }; + if check_transient_stake_address( + program_id, + stake_pool_info.key, + transient_stake_info.key, + &validator_stake_record.vote_account_address, + ) + .is_err() { - if validator_stake_record.vote_account_address != stake.delegation.voter_pubkey { - continue; + continue; + }; + + let mut stake_lamports = 0; + let validator_stake_state = try_from_slice_unchecked::( + &validator_stake_info.data.borrow(), + ) + .ok(); + let transient_stake_state = try_from_slice_unchecked::( + &transient_stake_info.data.borrow(), + ) + .ok(); + + // Possible merge situations for transient stake + // * active -> merge into validator stake + // * activating -> nothing, just account its lamports + // * deactivating -> nothing, just account its lamports + // * inactive -> merge into reserve stake + // * not a stake -> ignore + match transient_stake_state { + Some(stake_program::StakeState::Initialized(_meta)) => { + if no_merge { + stake_lamports += transient_stake_info.lamports(); + } else { + // merge into reserve + Self::stake_merge( + stake_pool_info.key, + transient_stake_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.withdraw_bump_seed, + reserve_stake_info.clone(), + clock_info.clone(), + stake_history_info.clone(), + stake_program_info.clone(), + )?; + } + } + Some(stake_program::StakeState::Stake(_, stake)) => { + if no_merge { + stake_lamports += transient_stake_info.lamports(); + } else if stake.delegation.deactivation_epoch < clock.epoch { + // deactivated, merge into reserve + Self::stake_merge( + stake_pool_info.key, + transient_stake_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.withdraw_bump_seed, + reserve_stake_info.clone(), + clock_info.clone(), + stake_history_info.clone(), + stake_program_info.clone(), + )?; + } else if stake.delegation.activation_epoch < clock.epoch { + if let Some(stake_program::StakeState::Stake(_, validator_stake)) = + validator_stake_state + { + if stake_program::active_stakes_can_merge(&stake, &validator_stake) + .is_ok() + { + Self::stake_merge( + stake_pool_info.key, + transient_stake_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.withdraw_bump_seed, + validator_stake_info.clone(), + clock_info.clone(), + stake_history_info.clone(), + stake_program_info.clone(), + )?; + } else { + msg!("Stake activating or just active, not ready to merge"); + stake_lamports += transient_stake_info.lamports(); + } + } else { + msg!("Transient stake is activating or active, but validator stake is not, need to add the validator stake account on {} back into the stake pool", stake.delegation.voter_pubkey); + stake_lamports += transient_stake_info.lamports(); + } + } else { + msg!("Transient stake not ready to be merged anywhere"); + stake_lamports += transient_stake_info.lamports(); + } } - validator_stake_record.last_update_epoch = clock.epoch; - validator_stake_record.stake_lamports = validator_stake_account - .lamports - .borrow() - .saturating_sub(minimum_stake_lamports(&meta)); - changes = true; + None + | Some(stake_program::StakeState::Uninitialized) + | Some(stake_program::StakeState::RewardsPool) => {} // do nothing } + + // Status for validator stake + // * active -> do everything + // * any other state / not a stake -> error state, but account for transient stake + match validator_stake_state { + Some(stake_program::StakeState::Stake(meta, _)) => { + stake_lamports += validator_stake_info + .lamports() + .saturating_sub(minimum_stake_lamports(&meta)); + } + Some(stake_program::StakeState::Initialized(_)) + | Some(stake_program::StakeState::Uninitialized) + | Some(stake_program::StakeState::RewardsPool) + | None => { + msg!("Validator stake account no longer part of the pool, not considering"); + } + } + + validator_stake_record.last_update_epoch = clock.epoch; + validator_stake_record.stake_lamports = stake_lamports; + changes = true; } if changes { @@ -1089,8 +1266,9 @@ impl Processor { ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; - let validator_list_info = next_account_info(account_info_iter)?; let withdraw_info = next_account_info(account_info_iter)?; + let validator_list_info = next_account_info(account_info_iter)?; + let reserve_stake_info = next_account_info(account_info_iter)?; let manager_fee_info = next_account_info(account_info_iter)?; let pool_mint_info = next_account_info(account_info_iter)?; let clock_info = next_account_info(account_info_iter)?; @@ -1121,7 +1299,19 @@ impl Processor { } let previous_lamports = stake_pool.total_stake_lamports; - let mut total_stake_lamports: u64 = 0; + let reserve_stake = try_from_slice_unchecked::( + &reserve_stake_info.data.borrow(), + )?; + let mut total_stake_lamports = + if let stake_program::StakeState::Initialized(meta) = reserve_stake { + reserve_stake_info + .lamports() + .checked_sub(minimum_reserve_lamports(&meta)) + .ok_or(StakePoolError::CalculationFailure)? + } else { + msg!("Reserve stake account in unknown state, aborting"); + return Err(StakePoolError::WrongStakeState.into()); + }; for validator_stake_record in validator_list.validators { if validator_stake_record.last_update_epoch < clock.epoch { return Err(StakePoolError::StakeListOutOfDate.into()); @@ -1162,31 +1352,27 @@ impl Processor { /// Check stake activation status #[allow(clippy::unnecessary_wraps)] - fn check_stake_activation( - _stake_info: &AccountInfo, - _clock: &Clock, - _stake_history: &StakeHistory, + fn _check_stake_activation( + stake_info: &AccountInfo, + clock: &Clock, + stake_history: &StakeHistory, ) -> ProgramResult { - // TODO: remove conditional compilation when time travel in tests is possible - //#[cfg(not(feature = "test-bpf"))] - // This check is commented to make tests run without special command line arguments - /*{ - let stake_acc_state: stake_program::StakeState = - deserialize(&stake_info.data.borrow()).unwrap(); - let delegation = stake_acc_state.delegation(); - if let Some(delegation) = delegation { - let target_epoch = clock.epoch; - let history = Some(stake_history); - let fix_stake_deactivate = true; - let (effective, activating, deactivating) = delegation - .stake_activating_and_deactivating(target_epoch, history, fix_stake_deactivate); - if activating != 0 || deactivating != 0 || effective == 0 { - return Err(StakePoolError::UserStakeNotActive.into()); - } - } else { - return Err(StakePoolError::WrongStakeState.into()); + let stake_acc_state = + try_from_slice_unchecked::(&stake_info.data.borrow()) + .unwrap(); + let delegation = stake_acc_state.delegation(); + if let Some(delegation) = delegation { + let target_epoch = clock.epoch; + let history = Some(stake_history); + let fix_stake_deactivate = true; + let (effective, activating, deactivating) = delegation + .stake_activating_and_deactivating(target_epoch, history, fix_stake_deactivate); + if activating != 0 || deactivating != 0 || effective == 0 { + return Err(StakePoolError::UserStakeNotActive.into()); } - }*/ + } else { + return Err(StakePoolError::WrongStakeState.into()); + } Ok(()) } @@ -1204,7 +1390,7 @@ impl Processor { let clock_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(clock_info)?; let stake_history_info = next_account_info(account_info_iter)?; - let stake_history = &StakeHistory::from_account_info(stake_history_info)?; + //let stake_history = &StakeHistory::from_account_info(stake_history_info)?; let token_program_info = next_account_info(account_info_iter)?; let stake_program_info = next_account_info(account_info_iter)?; @@ -1217,7 +1403,7 @@ impl Processor { return Err(StakePoolError::InvalidState.into()); } - Self::check_stake_activation(stake_info, clock, stake_history)?; + //Self::check_stake_activation(stake_info, clock, stake_history)?; stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?; stake_pool.check_authority_deposit(deposit_info.key, program_id, stake_pool_info.key)?; @@ -1259,6 +1445,11 @@ impl Processor { .calc_pool_tokens_for_deposit(stake_lamports) .ok_or(StakePoolError::CalculationFailure)?; + msg!( + "lamports pre merge {}", + validator_stake_account_info.lamports() + ); + Self::stake_authorize( stake_pool_info.key, stake_info.clone(), @@ -1316,9 +1507,12 @@ impl Processor { .ok_or(StakePoolError::CalculationFailure)?; stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; + msg!( + "lamports post merge {}", + validator_stake_account_info.lamports() + ); validator_list_item.stake_lamports = validator_stake_account_info - .lamports - .borrow() + .lamports() .checked_sub(minimum_stake_lamports(&meta)) .ok_or(StakePoolError::CalculationFailure)?; validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; @@ -1557,7 +1751,7 @@ impl Processor { fee, max_validators, } => { - msg!("Instruction: Init"); + msg!("Instruction: Initialize stake pool"); Self::process_initialize(program_id, accounts, fee, max_validators) } StakePoolInstruction::CreateValidatorStakeAccount => { @@ -1580,9 +1774,17 @@ impl Processor { msg!("Instruction: IncreaseValidatorStake"); Self::process_increase_validator_stake(program_id, accounts, amount) } - StakePoolInstruction::UpdateValidatorListBalance => { + StakePoolInstruction::UpdateValidatorListBalance { + start_index, + no_merge, + } => { msg!("Instruction: UpdateValidatorListBalance"); - Self::process_update_validator_list_balance(program_id, accounts) + Self::process_update_validator_list_balance( + program_id, + accounts, + start_index, + no_merge, + ) } StakePoolInstruction::UpdateStakePoolBalance => { msg!("Instruction: UpdateStakePoolBalance"); diff --git a/program/src/stake_program.rs b/program/src/stake_program.rs index 3ea41fd3..daea623a 100644 --- a/program/src/stake_program.rs +++ b/program/src/stake_program.rs @@ -1,14 +1,22 @@ //! FIXME copied from the solana stake program -use serde_derive::{Deserialize, Serialize}; -use solana_program::{ - clock::{Epoch, UnixTimestamp}, - instruction::{AccountMeta, Instruction}, - pubkey::Pubkey, - stake_history::StakeHistory, - system_instruction, sysvar, +use { + borsh::{ + maybestd::io::{Error as IoError, ErrorKind as IoErrorKind, Result as IoResult}, + BorshDeserialize, BorshSchema, BorshSerialize, + }, + serde_derive::{Deserialize, Serialize}, + solana_program::{ + clock::{Epoch, UnixTimestamp}, + instruction::{AccountMeta, Instruction}, + msg, + program_error::ProgramError, + pubkey::Pubkey, + stake_history::StakeHistory, + system_instruction, sysvar, + }, + std::str::FromStr, }; -use std::str::FromStr; solana_program::declare_id!("Stake11111111111111111111111111111111111111"); @@ -125,8 +133,39 @@ pub enum StakeState { RewardsPool, } +impl BorshDeserialize for StakeState { + fn deserialize(buf: &mut &[u8]) -> IoResult { + let u: u32 = BorshDeserialize::deserialize(buf)?; + match u { + 0 => Ok(StakeState::Uninitialized), + 1 => { + let meta: Meta = BorshDeserialize::deserialize(buf)?; + Ok(StakeState::Initialized(meta)) + } + 2 => { + let meta: Meta = BorshDeserialize::deserialize(buf)?; + let stake: Stake = BorshDeserialize::deserialize(buf)?; + Ok(StakeState::Stake(meta, stake)) + } + 3 => Ok(StakeState::RewardsPool), + _ => Err(IoError::new(IoErrorKind::InvalidData, "Invalid enum value")), + } + } +} + /// FIXME copied from the stake program -#[derive(Default, Debug, Serialize, Deserialize, PartialEq, Clone, Copy)] +#[derive( + BorshSerialize, + BorshDeserialize, + BorshSchema, + Default, + Debug, + Serialize, + Deserialize, + PartialEq, + Clone, + Copy, +)] pub struct Meta { /// FIXME copied from the stake program pub rent_exempt_reserve: u64, @@ -137,7 +176,18 @@ pub struct Meta { } /// FIXME copied from the stake program -#[derive(Debug, Default, Serialize, Deserialize, PartialEq, Clone, Copy)] +#[derive( + BorshSerialize, + BorshDeserialize, + BorshSchema, + Debug, + Default, + Serialize, + Deserialize, + PartialEq, + Clone, + Copy, +)] pub struct Stake { /// FIXME copied from the stake program pub delegation: Delegation, @@ -146,7 +196,18 @@ pub struct Stake { } /// FIXME copied from the stake program -#[derive(Debug, Default, Serialize, Deserialize, PartialEq, Clone, Copy)] +#[derive( + BorshSerialize, + BorshDeserialize, + BorshSchema, + Debug, + Default, + Serialize, + Deserialize, + PartialEq, + Clone, + Copy, +)] pub struct Delegation { /// to whom the stake is delegated pub voter_pubkey: Pubkey, @@ -161,7 +222,17 @@ pub struct Delegation { } /// FIXME copied from the stake program -#[derive(Debug, Serialize, Deserialize, PartialEq, Clone, Copy)] +#[derive( + BorshSerialize, + BorshDeserialize, + BorshSchema, + Debug, + Serialize, + Deserialize, + PartialEq, + Clone, + Copy, +)] pub enum StakeAuthorize { /// FIXME copied from the stake program Staker, @@ -169,7 +240,18 @@ pub enum StakeAuthorize { Withdrawer, } /// FIXME copied from the stake program -#[derive(Default, Debug, Serialize, Deserialize, PartialEq, Clone, Copy)] +#[derive( + BorshSerialize, + BorshDeserialize, + BorshSchema, + Default, + Debug, + Serialize, + Deserialize, + PartialEq, + Clone, + Copy, +)] pub struct Authorized { /// FIXME copied from the stake program pub staker: Pubkey, @@ -178,7 +260,18 @@ pub struct Authorized { } /// FIXME copied from the stake program -#[derive(Default, Debug, Serialize, Deserialize, PartialEq, Clone, Copy)] +#[derive( + BorshSerialize, + BorshDeserialize, + BorshSchema, + Default, + Debug, + Serialize, + Deserialize, + PartialEq, + Clone, + Copy, +)] pub struct Lockup { /// UnixTimestamp at which this stake will allow withdrawal, unless the /// transaction is signed by the custodian @@ -405,6 +498,41 @@ impl Delegation { } } +/// FIXME copied from stake program +/// Checks if two active delegations are mergeable, required since we cannot recover +/// from a CPI error. +pub fn active_delegations_can_merge( + stake: &Delegation, + source: &Delegation, +) -> Result<(), ProgramError> { + if stake.voter_pubkey != source.voter_pubkey { + msg!("Unable to merge due to voter mismatch"); + Err(ProgramError::InvalidAccountData) + } else if (stake.warmup_cooldown_rate - source.warmup_cooldown_rate).abs() < f64::EPSILON + && stake.deactivation_epoch == Epoch::MAX + && source.deactivation_epoch == Epoch::MAX + { + Ok(()) + } else { + msg!("Unable to merge due to stake deactivation"); + Err(ProgramError::InvalidAccountData) + } +} + +/// FIXME copied from stake program +/// Checks if two active stakes are mergeable, required since we cannot recover +/// from a CPI error. +pub fn active_stakes_can_merge(stake: &Stake, source: &Stake) -> Result<(), ProgramError> { + active_delegations_can_merge(&stake.delegation, &source.delegation)?; + + if stake.credits_observed == source.credits_observed { + Ok(()) + } else { + msg!("Unable to merge due to credits observed mismatch"); + Err(ProgramError::InvalidAccountData) + } +} + /// FIXME copied from the stake program pub fn split_only( stake_pubkey: &Pubkey, @@ -516,3 +644,64 @@ pub fn deactivate_stake(stake_pubkey: &Pubkey, authorized_pubkey: &Pubkey) -> In ]; Instruction::new_with_bincode(id(), &StakeInstruction::Deactivate, account_metas) } + +#[cfg(test)] +mod test { + use {super::*, crate::borsh::try_from_slice_unchecked, bincode::serialize}; + + fn check_borsh_deserialization(stake: StakeState) { + let serialized = serialize(&stake).unwrap(); + let deserialized = StakeState::try_from_slice(&serialized).unwrap(); + assert_eq!(stake, deserialized); + } + + #[test] + fn bincode_vs_borsh() { + check_borsh_deserialization(StakeState::Uninitialized); + check_borsh_deserialization(StakeState::RewardsPool); + check_borsh_deserialization(StakeState::Initialized(Meta { + rent_exempt_reserve: u64::MAX, + authorized: Authorized { + staker: Pubkey::new_unique(), + withdrawer: Pubkey::new_unique(), + }, + lockup: Lockup::default(), + })); + check_borsh_deserialization(StakeState::Stake( + Meta { + rent_exempt_reserve: 1, + authorized: Authorized { + staker: Pubkey::new_unique(), + withdrawer: Pubkey::new_unique(), + }, + lockup: Lockup::default(), + }, + Stake { + delegation: Delegation { + voter_pubkey: Pubkey::new_unique(), + stake: u64::MAX, + activation_epoch: Epoch::MAX, + deactivation_epoch: Epoch::MAX, + warmup_cooldown_rate: f64::MAX, + }, + credits_observed: 1, + }, + )); + } + + #[test] + fn borsh_deserialization_live_data() { + let data = [ + 1, 0, 0, 0, 128, 213, 34, 0, 0, 0, 0, 0, 133, 0, 79, 231, 141, 29, 73, 61, 232, 35, + 119, 124, 168, 12, 120, 216, 195, 29, 12, 166, 139, 28, 36, 182, 186, 154, 246, 149, + 224, 109, 52, 100, 133, 0, 79, 231, 141, 29, 73, 61, 232, 35, 119, 124, 168, 12, 120, + 216, 195, 29, 12, 166, 139, 28, 36, 182, 186, 154, 246, 149, 224, 109, 52, 100, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + ]; + let _deserialized = try_from_slice_unchecked::(&data).unwrap(); + } +} diff --git a/program/tests/decrease.rs b/program/tests/decrease.rs index ad8c76e5..647d38d9 100644 --- a/program/tests/decrease.rs +++ b/program/tests/decrease.rs @@ -23,7 +23,7 @@ async fn setup() -> ( Hash, StakePoolAccounts, ValidatorStakeAccount, - DepositInfo, + DepositStakeAccount, u64, ) { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 798fb7b1..a202e8d0 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -88,6 +88,7 @@ async fn test_stake_pool_deposit() { &mut banks_client, &payer, &recent_blockhash, + &validator_stake_account.validator, &validator_stake_account.vote, ) .await; diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 903796f8..e99e01fc 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -3,6 +3,7 @@ use { solana_program::{ borsh::get_packed_len, hash::Hash, program_pack::Pack, pubkey::Pubkey, system_instruction, + system_program, }, solana_program_test::*, solana_sdk::{ @@ -11,7 +12,10 @@ use { transaction::Transaction, transport::TransportError, }, - solana_vote_program::{self, vote_state::VoteState}, + solana_vote_program::{ + self, vote_instruction, + vote_state::{VoteInit, VoteState}, + }, spl_stake_pool::{ borsh::{get_instance_packed_len, try_from_slice_unchecked}, find_stake_program_address, find_transient_stake_program_address, id, instruction, @@ -19,7 +23,7 @@ use { }, }; -pub const TEST_STAKE_AMOUNT: u64 = 1_000_000; +pub const TEST_STAKE_AMOUNT: u64 = 100_000_000; pub const MAX_TEST_VALIDATORS: u32 = 10_000; pub fn program_test() -> ProgramTest { @@ -260,22 +264,36 @@ pub async fn create_vote( banks_client: &mut BanksClient, payer: &Keypair, recent_blockhash: &Hash, + validator: &Keypair, vote: &Keypair, ) { let rent = banks_client.get_rent().await.unwrap(); let rent_voter = rent.minimum_balance(VoteState::size_of()); - let mut transaction = Transaction::new_with_payer( - &[system_instruction::create_account( - &payer.pubkey(), - &vote.pubkey(), - rent_voter, - VoteState::size_of() as u64, - &solana_vote_program::id(), - )], + let mut instructions = vec![system_instruction::create_account( + &payer.pubkey(), + &validator.pubkey(), + 42, + 0, + &system_program::id(), + )]; + instructions.append(&mut vote_instruction::create_account( + &payer.pubkey(), + &vote.pubkey(), + &VoteInit { + node_pubkey: validator.pubkey(), + authorized_voter: validator.pubkey(), + ..VoteInit::default() + }, + rent_voter, + )); + + let transaction = Transaction::new_signed_with_payer( + &instructions, Some(&payer.pubkey()), + &[validator, vote, payer], + *recent_blockhash, ); - transaction.sign(&[&vote, payer], *recent_blockhash); banks_client.process_transaction(transaction).await.unwrap(); } @@ -408,20 +426,23 @@ pub struct ValidatorStakeAccount { pub transient_stake_account: Pubkey, pub target_authority: Pubkey, pub vote: Keypair, + pub validator: Keypair, pub stake_pool: Pubkey, } impl ValidatorStakeAccount { pub fn new_with_target_authority(authority: &Pubkey, stake_pool: &Pubkey) -> Self { let validator = Keypair::new(); - let (stake_account, _) = find_stake_program_address(&id(), &validator.pubkey(), stake_pool); + let vote = Keypair::new(); + let (stake_account, _) = find_stake_program_address(&id(), &vote.pubkey(), stake_pool); let (transient_stake_account, _) = - find_transient_stake_program_address(&id(), &validator.pubkey(), stake_pool); + find_transient_stake_program_address(&id(), &vote.pubkey(), stake_pool); ValidatorStakeAccount { stake_account, transient_stake_account, target_authority: *authority, - vote: validator, + vote, + validator, stake_pool: *stake_pool, } } @@ -433,7 +454,14 @@ impl ValidatorStakeAccount { recent_blockhash: &Hash, staker: &Keypair, ) { - create_vote(&mut banks_client, &payer, &recent_blockhash, &self.vote).await; + create_vote( + &mut banks_client, + &payer, + &recent_blockhash, + &self.validator, + &self.vote, + ) + .await; create_validator_stake_account( &mut banks_client, @@ -650,15 +678,20 @@ impl StakePoolAccounts { banks_client: &mut BanksClient, payer: &Keypair, recent_blockhash: &Hash, - validator_list: &[Pubkey], + validator_vote_accounts: &[Pubkey], + no_merge: bool, ) -> Option { let transaction = Transaction::new_signed_with_payer( &[instruction::update_validator_list_balance( &id(), + &self.stake_pool.pubkey(), + &self.withdraw_authority, &self.validator_list.pubkey(), - validator_list, - ) - .unwrap()], + &self.reserve_stake.pubkey(), + validator_vote_accounts, + 0, + no_merge, + )], Some(&payer.pubkey()), &[payer], *recent_blockhash, @@ -676,12 +709,49 @@ impl StakePoolAccounts { &[instruction::update_stake_pool_balance( &id(), &self.stake_pool.pubkey(), - &self.validator_list.pubkey(), &self.withdraw_authority, + &self.validator_list.pubkey(), + &self.reserve_stake.pubkey(), &self.pool_fee_account.pubkey(), &self.pool_mint.pubkey(), - ) - .unwrap()], + )], + Some(&payer.pubkey()), + &[payer], + *recent_blockhash, + ); + banks_client.process_transaction(transaction).await.err() + } + + pub async fn update_all( + &self, + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + validator_vote_accounts: &[Pubkey], + no_merge: bool, + ) -> Option { + let transaction = Transaction::new_signed_with_payer( + &[ + instruction::update_validator_list_balance( + &id(), + &self.stake_pool.pubkey(), + &self.withdraw_authority, + &self.validator_list.pubkey(), + &self.reserve_stake.pubkey(), + validator_vote_accounts, + 0, + no_merge, + ), + instruction::update_stake_pool_balance( + &id(), + &self.stake_pool.pubkey(), + &self.withdraw_authority, + &self.validator_list.pubkey(), + &self.reserve_stake.pubkey(), + &self.pool_fee_account.pubkey(), + &self.pool_mint.pubkey(), + ), + ], Some(&payer.pubkey()), &[payer], *recent_blockhash, @@ -719,8 +789,9 @@ impl StakePoolAccounts { banks_client: &mut BanksClient, payer: &Keypair, recent_blockhash: &Hash, - stake: &Pubkey, new_authority: &Pubkey, + validator_stake: &Pubkey, + transient_stake: &Pubkey, ) -> Option { let transaction = Transaction::new_signed_with_payer( &[instruction::remove_validator_from_pool( @@ -730,7 +801,8 @@ impl StakePoolAccounts { &self.withdraw_authority, &new_authority, &self.validator_list.pubkey(), - stake, + validator_stake, + transient_stake, ) .unwrap()], Some(&payer.pubkey()), @@ -804,11 +876,11 @@ pub async fn simple_add_validator_to_pool( recent_blockhash: &Hash, stake_pool_accounts: &StakePoolAccounts, ) -> ValidatorStakeAccount { - let user_stake = ValidatorStakeAccount::new_with_target_authority( + let validator_stake = ValidatorStakeAccount::new_with_target_authority( &stake_pool_accounts.deposit_authority, &stake_pool_accounts.stake_pool.pubkey(), ); - user_stake + validator_stake .create_and_delegate( banks_client, &payer, @@ -822,20 +894,128 @@ pub async fn simple_add_validator_to_pool( banks_client, &payer, &recent_blockhash, - &user_stake.stake_account, + &validator_stake.stake_account, ) .await; assert!(error.is_none()); - user_stake + validator_stake } #[derive(Debug)] -pub struct DepositInfo { - pub user: Keypair, - pub user_pool_account: Pubkey, +pub struct DepositStakeAccount { + pub authority: Keypair, + pub stake: Keypair, + pub pool_account: Keypair, pub stake_lamports: u64, pub pool_tokens: u64, + pub vote_account: Pubkey, + pub validator_stake_account: Pubkey, +} + +impl DepositStakeAccount { + pub fn new_with_vote( + vote_account: Pubkey, + validator_stake_account: Pubkey, + stake_lamports: u64, + ) -> Self { + let authority = Keypair::new(); + let stake = Keypair::new(); + let pool_account = Keypair::new(); + Self { + authority, + stake, + pool_account, + vote_account, + validator_stake_account, + stake_lamports, + pool_tokens: 0, + } + } + + pub async fn create_and_delegate( + &self, + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + ) { + let lockup = stake_program::Lockup::default(); + let authorized = stake_program::Authorized { + staker: self.authority.pubkey(), + withdrawer: self.authority.pubkey(), + }; + create_independent_stake_account( + banks_client, + payer, + recent_blockhash, + &self.stake, + &authorized, + &lockup, + self.stake_lamports, + ) + .await; + delegate_stake_account( + banks_client, + payer, + recent_blockhash, + &self.stake.pubkey(), + &self.authority, + &self.vote_account, + ) + .await; + } + + pub async fn deposit( + &self, + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + stake_pool_accounts: &StakePoolAccounts, + ) { + authorize_stake_account( + banks_client, + payer, + recent_blockhash, + &self.stake.pubkey(), + &self.authority, + &stake_pool_accounts.deposit_authority, + stake_program::StakeAuthorize::Staker, + ) + .await; + authorize_stake_account( + banks_client, + &payer, + &recent_blockhash, + &self.stake.pubkey(), + &self.authority, + &stake_pool_accounts.deposit_authority, + stake_program::StakeAuthorize::Withdrawer, + ) + .await; + // make pool token account + create_token_account( + banks_client, + payer, + recent_blockhash, + &self.pool_account, + &stake_pool_accounts.pool_mint.pubkey(), + &self.authority.pubkey(), + ) + .await + .unwrap(); + + stake_pool_accounts + .deposit_stake( + banks_client, + payer, + recent_blockhash, + &self.stake.pubkey(), + &self.pool_account.pubkey(), + &self.validator_stake_account, + ) + .await + .unwrap(); + } } pub async fn simple_deposit( @@ -845,76 +1025,118 @@ pub async fn simple_deposit( stake_pool_accounts: &StakePoolAccounts, validator_stake_account: &ValidatorStakeAccount, stake_lamports: u64, -) -> DepositInfo { - let user = Keypair::new(); +) -> DepositStakeAccount { + let authority = Keypair::new(); // make stake account - let user_stake = Keypair::new(); + let stake = Keypair::new(); let lockup = stake_program::Lockup::default(); let authorized = stake_program::Authorized { - staker: stake_pool_accounts.deposit_authority, - withdrawer: stake_pool_accounts.deposit_authority, + staker: authority.pubkey(), + withdrawer: authority.pubkey(), }; create_independent_stake_account( banks_client, payer, recent_blockhash, - &user_stake, + &stake, &authorized, &lockup, stake_lamports, ) .await; + let vote_account = validator_stake_account.vote.pubkey(); + delegate_stake_account( + banks_client, + payer, + recent_blockhash, + &stake.pubkey(), + &authority, + &vote_account, + ) + .await; + authorize_stake_account( + banks_client, + payer, + recent_blockhash, + &stake.pubkey(), + &authority, + &stake_pool_accounts.deposit_authority, + stake_program::StakeAuthorize::Staker, + ) + .await; + authorize_stake_account( + banks_client, + &payer, + &recent_blockhash, + &stake.pubkey(), + &authority, + &stake_pool_accounts.deposit_authority, + stake_program::StakeAuthorize::Withdrawer, + ) + .await; // make pool token account - let user_pool_account = Keypair::new(); + let pool_account = Keypair::new(); create_token_account( banks_client, payer, recent_blockhash, - &user_pool_account, + &pool_account, &stake_pool_accounts.pool_mint.pubkey(), - &user.pubkey(), + &authority.pubkey(), ) .await .unwrap(); + let validator_stake_account = validator_stake_account.stake_account; stake_pool_accounts .deposit_stake( banks_client, payer, recent_blockhash, - &user_stake.pubkey(), - &user_pool_account.pubkey(), - &validator_stake_account.stake_account, + &stake.pubkey(), + &pool_account.pubkey(), + &validator_stake_account, ) .await .unwrap(); - let user_pool_account = user_pool_account.pubkey(); - let pool_tokens = get_token_balance(banks_client, &user_pool_account).await; + let pool_tokens = get_token_balance(banks_client, &pool_account.pubkey()).await; - DepositInfo { - user, - user_pool_account, + DepositStakeAccount { + authority, + stake, + pool_account, stake_lamports, pool_tokens, + vote_account, + validator_stake_account, } } pub async fn get_validator_list_sum( banks_client: &mut BanksClient, - validator_list_key: &Pubkey, + reserve_stake: &Pubkey, + validator_list: &Pubkey, ) -> u64 { let validator_list = banks_client - .get_account(*validator_list_key) + .get_account(*validator_list) .await .unwrap() .unwrap(); let validator_list = try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); + let reserve_stake = banks_client + .get_account(*reserve_stake) + .await + .unwrap() + .unwrap(); - validator_list + let validator_sum: u64 = validator_list .validators .iter() .map(|info| info.stake_lamports) - .sum() + .sum(); + let rent = banks_client.get_rent().await.unwrap(); + let rent = rent.minimum_balance(std::mem::size_of::()); + validator_sum + reserve_stake.lamports - rent - 1 } diff --git a/program/tests/update_stake_pool_balance.rs b/program/tests/update_stake_pool_balance.rs index d91a62d7..33b29abe 100644 --- a/program/tests/update_stake_pool_balance.rs +++ b/program/tests/update_stake_pool_balance.rs @@ -63,13 +63,21 @@ async fn setup() -> ( async fn success() { let (mut context, stake_pool_accounts, stake_accounts) = setup().await; - let before_balance = get_validator_list_sum( + let pre_balance = get_validator_list_sum( &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), &stake_pool_accounts.validator_list.pubkey(), ) .await; + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = StakePool::try_from_slice(&stake_pool.data.as_slice()).unwrap(); + assert_eq!(pre_balance, stake_pool.total_stake_lamports); - let before_token_supply = get_token_supply( + let pre_token_supply = get_token_supply( &mut context.banks_client, &stake_pool_accounts.pool_mint.pubkey(), ) @@ -102,33 +110,34 @@ async fn success() { // Update list and pool let error = stake_pool_accounts - .update_validator_list_balance( + .update_all( &mut context.banks_client, &context.payer, &context.last_blockhash, stake_accounts .iter() - .map(|v| v.stake_account) + .map(|v| v.vote.pubkey()) .collect::>() .as_slice(), - ) - .await; - assert!(error.is_none()); - let error = stake_pool_accounts - .update_stake_pool_balance( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, + false, ) .await; assert!(error.is_none()); // Check fee - let after_balance = get_validator_list_sum( + let post_balance = get_validator_list_sum( &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), &stake_pool_accounts.validator_list.pubkey(), ) .await; + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = StakePool::try_from_slice(&stake_pool.data.as_slice()).unwrap(); + assert_eq!(post_balance, stake_pool.total_stake_lamports); let actual_fee = get_token_balance( &mut context.banks_client, @@ -147,7 +156,7 @@ async fn success() { ) .await; let stake_pool = StakePool::try_from_slice(&stake_pool_info.data).unwrap(); - let expected_fee = (after_balance - before_balance) * before_token_supply / before_balance + let expected_fee = (post_balance - pre_balance) * pre_token_supply / pre_balance * stake_pool.fee.numerator / stake_pool.fee.denominator; assert_eq!(actual_fee, expected_fee); diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index 5f8826ae..03b179ea 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -3,90 +3,449 @@ mod helpers; use { - helpers::*, solana_program::pubkey::Pubkey, solana_program_test::*, + borsh::BorshDeserialize, + helpers::*, + solana_program::pubkey::Pubkey, + solana_program_test::*, solana_sdk::signature::Signer, + spl_stake_pool::{ + stake_program, state::StakePool, MAX_VALIDATORS_TO_UPDATE, MINIMUM_ACTIVE_STAKE, + }, }; -#[tokio::test] -async fn success() { +async fn setup( + num_validators: usize, +) -> ( + ProgramTestContext, + StakePoolAccounts, + Vec, + u64, + u64, +) { let mut context = program_test().start_with_context().await; + let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + let mut slot = first_normal_slot; + context.warp_to_slot(slot).unwrap(); + let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts .initialize_stake_pool( &mut context.banks_client, &context.payer, &context.last_blockhash, - 1, + TEST_STAKE_AMOUNT + 1, ) .await .unwrap(); - // Add several accounts + // Add several accounts with some stake let mut stake_accounts: Vec = vec![]; - const STAKE_ACCOUNTS: u64 = 3; - for _ in 0..STAKE_ACCOUNTS { - stake_accounts.push( - simple_add_validator_to_pool( + let mut deposit_accounts: Vec = vec![]; + for _ in 0..num_validators { + let stake_account = ValidatorStakeAccount::new_with_target_authority( + &stake_pool_accounts.deposit_authority, + &stake_pool_accounts.stake_pool.pubkey(), + ); + stake_account + .create_and_delegate( &mut context.banks_client, &context.payer, &context.last_blockhash, - &stake_pool_accounts, + &stake_pool_accounts.staker, ) - .await, + .await; + + let deposit_account = DepositStakeAccount::new_with_vote( + stake_account.vote.pubkey(), + stake_account.stake_account, + TEST_STAKE_AMOUNT, ); + deposit_account + .create_and_delegate( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; + + stake_accounts.push(stake_account); + deposit_accounts.push(deposit_account); + } + + // Warp forward so the stakes properly activate, and deposit + // TODO This is *bad* -- program-test needs to have some more active stake + // so we can warm up faster than this. Also, we need to do each of these + // warps by hand to get fully active stakes. + for i in 2..50 { + slot = first_normal_slot + i * slots_per_epoch; + context.warp_to_slot(slot).unwrap(); + } + + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + stake_accounts + .iter() + .map(|v| v.vote.pubkey()) + .collect::>() + .as_slice(), + false, + ) + .await; + + for stake_account in &stake_accounts { + let error = stake_pool_accounts + .add_validator_to_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_account.stake_account, + ) + .await; + assert!(error.is_none()); + } + + for deposit_account in &deposit_accounts { + deposit_account + .deposit( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + ) + .await; } + slot += slots_per_epoch; + context.warp_to_slot(slot).unwrap(); + + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + stake_accounts + .iter() + .map(|v| v.vote.pubkey()) + .collect::>() + .as_slice(), + false, + ) + .await; + + ( + context, + stake_pool_accounts, + stake_accounts, + TEST_STAKE_AMOUNT, + slot, + ) +} + +#[tokio::test] +async fn success() { + let num_validators = 5; + let (mut context, stake_pool_accounts, stake_accounts, _, mut slot) = + setup(num_validators).await; + // Check current balance in the list + let rent = context.banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + // initially, have all of the deposits plus their rent, and the reserve stake + let initial_lamports = + (TEST_STAKE_AMOUNT + stake_rent) * num_validators as u64 + TEST_STAKE_AMOUNT; assert_eq!( get_validator_list_sum( &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), &stake_pool_accounts.validator_list.pubkey() ) .await, - 0, + initial_lamports, ); - // Add extra funds, simulating rewards - const EXTRA_STAKE_AMOUNT: u64 = 1_000_000; - + // Simulate rewards for stake_account in &stake_accounts { - transfer( + context.increment_vote_account_credits(&stake_account.vote.pubkey(), 100); + } + + // Warp one more epoch so the rewards are paid out + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + slot += slots_per_epoch; + context.warp_to_slot(slot).unwrap(); + + stake_pool_accounts + .update_all( &mut context.banks_client, &context.payer, &context.last_blockhash, - &stake_account.stake_account, - EXTRA_STAKE_AMOUNT, + stake_accounts + .iter() + .map(|v| v.vote.pubkey()) + .collect::>() + .as_slice(), + false, ) .await; + let new_lamports = get_validator_list_sum( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + assert!(new_lamports > initial_lamports); + + let stake_pool_info = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = StakePool::try_from_slice(&stake_pool_info.data).unwrap(); + assert_eq!(new_lamports, stake_pool.total_stake_lamports); +} + +#[tokio::test] +async fn merge_into_reserve() { + let (mut context, stake_pool_accounts, stake_accounts, lamports, mut slot) = + setup(MAX_VALIDATORS_TO_UPDATE).await; + + let pre_lamports = get_validator_list_sum( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + + let reserve_stake = context + .banks_client + .get_account(stake_pool_accounts.reserve_stake.pubkey()) + .await + .unwrap() + .unwrap(); + let pre_reserve_lamports = reserve_stake.lamports; + + // Decrease from all validators + for stake_account in &stake_accounts { + let error = stake_pool_accounts + .decrease_validator_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_account.stake_account, + &stake_account.transient_stake_account, + lamports, + ) + .await; + assert!(error.is_none()); } - // Update epoch - context.warp_to_slot(50_000).unwrap(); + // Update, should not change, no merges yet + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + stake_accounts + .iter() + .map(|v| v.vote.pubkey()) + .collect::>() + .as_slice(), + false, + ) + .await; + + let expected_lamports = get_validator_list_sum( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + assert_eq!(pre_lamports, expected_lamports); + + let stake_pool_info = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = StakePool::try_from_slice(&stake_pool_info.data).unwrap(); + assert_eq!(expected_lamports, stake_pool.total_stake_lamports); + + // Warp one more epoch so the stakes deactivate + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + slot += slots_per_epoch; + context.warp_to_slot(slot).unwrap(); stake_pool_accounts - .update_validator_list_balance( + .update_all( &mut context.banks_client, &context.payer, &context.last_blockhash, stake_accounts .iter() - .map(|v| v.stake_account) + .map(|v| v.vote.pubkey()) .collect::>() .as_slice(), + false, ) .await; + let expected_lamports = get_validator_list_sum( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + assert_eq!(pre_lamports, expected_lamports); - // Check balance updated - assert_eq!( - get_validator_list_sum( + let reserve_stake = context + .banks_client + .get_account(stake_pool_accounts.reserve_stake.pubkey()) + .await + .unwrap() + .unwrap(); + let post_reserve_lamports = reserve_stake.lamports; + assert!(post_reserve_lamports > pre_reserve_lamports); + + let stake_pool_info = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = StakePool::try_from_slice(&stake_pool_info.data).unwrap(); + assert_eq!(expected_lamports, stake_pool.total_stake_lamports); +} + +#[tokio::test] +async fn merge_into_validator_stake() { + let (mut context, stake_pool_accounts, stake_accounts, lamports, mut slot) = + setup(MAX_VALIDATORS_TO_UPDATE).await; + + let rent = context.banks_client.get_rent().await.unwrap(); + let pre_lamports = get_validator_list_sum( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + + // Increase stake to all validators + for stake_account in &stake_accounts { + let error = stake_pool_accounts + .increase_validator_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_account.transient_stake_account, + &stake_account.vote.pubkey(), + lamports / stake_accounts.len() as u64, + ) + .await; + assert!(error.is_none()); + } + + // Warp just a little bit to get a new blockhash and update again + context.warp_to_slot(slot + 10).unwrap(); + + // Update, should not change, no merges yet + let error = stake_pool_accounts + .update_all( &mut context.banks_client, - &stake_pool_accounts.validator_list.pubkey() + &context.payer, + &context.last_blockhash, + stake_accounts + .iter() + .map(|v| v.vote.pubkey()) + .collect::>() + .as_slice(), + false, ) - .await, - STAKE_ACCOUNTS * EXTRA_STAKE_AMOUNT - ); + .await; + assert!(error.is_none()); + + let expected_lamports = get_validator_list_sum( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + assert_eq!(pre_lamports, expected_lamports); + let stake_pool_info = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = StakePool::try_from_slice(&stake_pool_info.data).unwrap(); + assert_eq!(expected_lamports, stake_pool.total_stake_lamports); + + let stake_pool_info = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = StakePool::try_from_slice(&stake_pool_info.data).unwrap(); + assert_eq!(expected_lamports, stake_pool.total_stake_lamports); + + // Warp one more epoch so the stakes activate, ready to merge + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + slot += slots_per_epoch; + context.warp_to_slot(slot).unwrap(); + + let error = stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + stake_accounts + .iter() + .map(|v| v.vote.pubkey()) + .collect::>() + .as_slice(), + false, + ) + .await; + assert!(error.is_none()); + let current_lamports = get_validator_list_sum( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + let stake_pool_info = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = StakePool::try_from_slice(&stake_pool_info.data).unwrap(); + assert_eq!(current_lamports, stake_pool.total_stake_lamports); + + // Check that transient accounts are gone + for stake_account in &stake_accounts { + assert!(context + .banks_client + .get_account(stake_account.transient_stake_account) + .await + .unwrap() + .is_none()); + } + + // Check validator stake accounts have the expected balance now: + // validator stake account minimum + deposited lamports + 2 rents + increased lamports + let expected_lamports = MINIMUM_ACTIVE_STAKE + + lamports + + lamports / stake_accounts.len() as u64 + + 2 * rent.minimum_balance(std::mem::size_of::()); + for stake_account in &stake_accounts { + let validator_stake = + get_account(&mut context.banks_client, &stake_account.stake_account).await; + assert_eq!(validator_stake.lamports, expected_lamports); + } } +#[tokio::test] +async fn max_validators() {} + #[tokio::test] async fn fail_with_uninitialized_validator_list() {} // TODO diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index 5ab38eb6..535b6df7 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -170,6 +170,7 @@ async fn fail_too_little_stake() { &mut banks_client, &payer, &recent_blockhash, + &user_stake.validator, &user_stake.vote, ) .await; diff --git a/program/tests/vsa_create.rs b/program/tests/vsa_create.rs index ab7016e7..741a7cd5 100644 --- a/program/tests/vsa_create.rs +++ b/program/tests/vsa_create.rs @@ -31,11 +31,19 @@ async fn success_create_validator_stake_account() { .unwrap(); let validator = Keypair::new(); - create_vote(&mut banks_client, &payer, &recent_blockhash, &validator).await; + let vote = Keypair::new(); + create_vote( + &mut banks_client, + &payer, + &recent_blockhash, + &validator, + &vote, + ) + .await; let (stake_account, _) = find_stake_program_address( &id(), - &validator.pubkey(), + &vote.pubkey(), &stake_pool_accounts.stake_pool.pubkey(), ); @@ -46,7 +54,7 @@ async fn success_create_validator_stake_account() { &stake_pool_accounts.staker.pubkey(), &payer.pubkey(), &stake_account, - &validator.pubkey(), + &vote.pubkey(), ) .unwrap()], Some(&payer.pubkey()), @@ -67,7 +75,7 @@ async fn success_create_validator_stake_account() { &meta.authorized.withdrawer, &stake_pool_accounts.staker.pubkey() ); - assert_eq!(stake.delegation.voter_pubkey, validator.pubkey()); + assert_eq!(stake.delegation.voter_pubkey, vote.pubkey()); } _ => panic!(), } diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 1677bb48..b146dd00 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -34,7 +34,7 @@ async fn setup() -> ( let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 10_000_000) .await .unwrap(); @@ -81,8 +81,9 @@ async fn success() { &mut banks_client, &payer, &recent_blockhash, - &user_stake.stake_account, &new_authority, + &user_stake.stake_account, + &user_stake.transient_stake_account, ) .await; assert!(error.is_none()); @@ -131,6 +132,7 @@ async fn fail_with_wrong_stake_program_id() { AccountMeta::new_readonly(new_authority, false), AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false), AccountMeta::new(user_stake.stake_account, false), + AccountMeta::new_readonly(user_stake.transient_stake_account, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(wrong_stake_program, false), ]; @@ -178,6 +180,7 @@ async fn fail_with_wrong_validator_list_account() { &new_authority, &wrong_validator_list.pubkey(), &user_stake.stake_account, + &user_stake.transient_stake_account, ) .unwrap()], Some(&payer.pubkey()), @@ -221,8 +224,9 @@ async fn fail_not_at_minimum() { &mut banks_client, &payer, &recent_blockhash, - &user_stake.stake_account, &new_authority, + &user_stake.stake_account, + &user_stake.transient_stake_account, ) .await .unwrap() @@ -247,8 +251,9 @@ async fn fail_double_remove() { &mut banks_client, &payer, &recent_blockhash, - &user_stake.stake_account, &new_authority, + &user_stake.stake_account, + &user_stake.transient_stake_account, ) .await; assert!(error.is_none()); @@ -260,8 +265,9 @@ async fn fail_double_remove() { &mut banks_client, &payer, &latest_blockhash, - &user_stake.stake_account, &new_authority, + &user_stake.stake_account, + &user_stake.transient_stake_account, ) .await .unwrap(); @@ -297,6 +303,7 @@ async fn fail_wrong_staker() { &new_authority, &stake_pool_accounts.validator_list.pubkey(), &user_stake.stake_account, + &user_stake.transient_stake_account, ) .unwrap()], Some(&payer.pubkey()), @@ -336,6 +343,7 @@ async fn fail_no_signature() { AccountMeta::new_readonly(new_authority, false), AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false), AccountMeta::new(user_stake.stake_account, false), + AccountMeta::new_readonly(user_stake.transient_stake_account, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(stake_program::id(), false), ]; @@ -371,6 +379,49 @@ async fn fail_no_signature() { } } +#[tokio::test] +async fn fail_with_activating_transient_stake() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + setup().await; + + // increase the validator stake + let error = stake_pool_accounts + .increase_validator_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.transient_stake_account, + &user_stake.vote.pubkey(), + 5_000_000, + ) + .await; + assert!(error.is_none()); + + let new_authority = Pubkey::new_unique(); + let error = stake_pool_accounts + .remove_validator_from_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &new_authority, + &user_stake.stake_account, + &user_stake.transient_stake_account, + ) + .await + .unwrap() + .unwrap(); + match error { + TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + ) => { + let program_error = StakePoolError::WrongStakeState as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while removing validator stake account while transient stake is activating"), + } +} + #[tokio::test] async fn fail_not_updated_stake_pool() {} // TODO diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 250d5e70..6250fd1a 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -31,7 +31,7 @@ async fn setup() -> ( Hash, StakePoolAccounts, ValidatorStakeAccount, - DepositInfo, + DepositStakeAccount, u64, ) { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; @@ -66,8 +66,8 @@ async fn setup() -> ( &mut banks_client, &payer, &recent_blockhash, - &deposit_info.user_pool_account, - &deposit_info.user, + &deposit_info.pool_account.pubkey(), + &deposit_info.authority, &stake_pool_accounts.withdraw_authority, tokens_to_burn, ) @@ -126,7 +126,7 @@ async fn success() { // Save user token balance let user_token_balance_before = - get_token_balance(&mut banks_client, &deposit_info.user_pool_account).await; + get_token_balance(&mut banks_client, &deposit_info.pool_account.pubkey()).await; let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts @@ -135,7 +135,7 @@ async fn success() { &payer, &recent_blockhash, &user_stake_recipient.pubkey(), - &deposit_info.user_pool_account, + &deposit_info.pool_account.pubkey(), &validator_stake_account.stake_account, &new_authority, tokens_to_burn, @@ -173,7 +173,7 @@ async fn success() { // Check tokens burned let user_token_balance = - get_token_balance(&mut banks_client, &deposit_info.user_pool_account).await; + get_token_balance(&mut banks_client, &deposit_info.pool_account.pubkey()).await; assert_eq!( user_token_balance, user_token_balance_before - tokens_to_burn @@ -224,7 +224,7 @@ async fn fail_with_wrong_stake_program() { AccountMeta::new(validator_stake_account.stake_account, false), AccountMeta::new(user_stake_recipient.pubkey(), false), AccountMeta::new_readonly(new_authority, false), - AccountMeta::new(deposit_info.user_pool_account, false), + AccountMeta::new(deposit_info.pool_account.pubkey(), false), AccountMeta::new(stake_pool_accounts.pool_mint.pubkey(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(spl_token::id(), false), @@ -278,7 +278,7 @@ async fn fail_with_wrong_withdraw_authority() { &payer, &recent_blockhash, &user_stake_recipient.pubkey(), - &deposit_info.user_pool_account, + &deposit_info.pool_account.pubkey(), &validator_stake_account.stake_account, &new_authority, tokens_to_burn, @@ -325,7 +325,7 @@ async fn fail_with_wrong_token_program_id() { &validator_stake_account.stake_account, &user_stake_recipient.pubkey(), &new_authority, - &deposit_info.user_pool_account, + &deposit_info.pool_account.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), &wrong_token_program.pubkey(), tokens_to_burn, @@ -372,7 +372,7 @@ async fn fail_with_wrong_validator_list() { &payer, &recent_blockhash, &user_stake_recipient.pubkey(), - &deposit_info.user_pool_account, + &deposit_info.pool_account.pubkey(), &validator_stake_account.stake_account, &new_authority, tokens_to_burn, @@ -550,7 +550,7 @@ async fn fail_double_withdraw_to_the_same_account() { &payer, &recent_blockhash, &user_stake_recipient.pubkey(), - &deposit_info.user_pool_account, + &deposit_info.pool_account.pubkey(), &validator_stake_account.stake_account, &new_authority, tokens_to_burn, @@ -565,8 +565,8 @@ async fn fail_double_withdraw_to_the_same_account() { &mut banks_client, &payer, &latest_blockhash, - &deposit_info.user_pool_account, - &deposit_info.user, + &deposit_info.pool_account.pubkey(), + &deposit_info.authority, &stake_pool_accounts.withdraw_authority, tokens_to_burn, ) @@ -578,7 +578,7 @@ async fn fail_double_withdraw_to_the_same_account() { &payer, &latest_blockhash, &user_stake_recipient.pubkey(), - &deposit_info.user_pool_account, + &deposit_info.pool_account.pubkey(), &validator_stake_account.stake_account, &new_authority, tokens_to_burn, @@ -640,7 +640,7 @@ async fn fail_without_token_approval() { &payer, &recent_blockhash, &user_stake_recipient.pubkey(), - &deposit_info.user_pool_account, + &deposit_info.pool_account.pubkey(), &validator_stake_account.stake_account, &new_authority, tokens_to_burn, @@ -696,8 +696,8 @@ async fn fail_with_low_delegation() { &mut banks_client, &payer, &recent_blockhash, - &deposit_info.user_pool_account, - &deposit_info.user, + &deposit_info.pool_account.pubkey(), + &deposit_info.authority, &stake_pool_accounts.withdraw_authority, 1, ) @@ -720,7 +720,7 @@ async fn fail_with_low_delegation() { &payer, &recent_blockhash, &user_stake_recipient.pubkey(), - &deposit_info.user_pool_account, + &deposit_info.pool_account.pubkey(), &validator_stake_account.stake_account, &new_authority, tokens_to_burn, @@ -779,7 +779,7 @@ async fn fail_overdraw_validator() { &payer, &recent_blockhash, &user_stake_recipient.pubkey(), - &deposit_info.user_pool_account, + &deposit_info.pool_account.pubkey(), &validator_stake_account.stake_account, &new_authority, tokens_to_burn, From 4729a8639504c3eb20a25c51546ba1a5b946eddc Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 22 Apr 2021 02:20:35 +0200 Subject: [PATCH 0087/1076] stake-pool-cli: Add increase / decrease validator stake (#1619) --- clients/cli/src/main.rs | 176 ++++++++++++++++++++++++++++++++--- program/src/instruction.rs | 20 ++-- program/tests/decrease.rs | 9 +- program/tests/helpers/mod.rs | 6 +- program/tests/increase.rs | 11 +-- 5 files changed, 183 insertions(+), 39 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 34fe91f6..5de6efc6 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -395,6 +395,95 @@ fn command_vsa_remove( Ok(()) } +fn command_increase_validator_stake( + config: &Config, + stake_pool_address: &Pubkey, + vote_account: &Pubkey, + lamports: u64, +) -> CommandResult { + if !config.no_update { + command_update(config, stake_pool_address)?; + } + + let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; + let pool_withdraw_authority = + find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; + let (transient_stake_address, _) = find_transient_stake_program_address( + &spl_stake_pool::id(), + &vote_account, + stake_pool_address, + ); + + let mut transaction = Transaction::new_with_payer( + &[spl_stake_pool::instruction::increase_validator_stake( + &spl_stake_pool::id(), + &stake_pool_address, + &config.staker.pubkey(), + &pool_withdraw_authority, + &stake_pool.validator_list, + &stake_pool.reserve_stake, + &transient_stake_address, + &vote_account, + lamports, + )], + Some(&config.fee_payer.pubkey()), + ); + + let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; + transaction.sign( + &[config.fee_payer.as_ref(), config.staker.as_ref()], + recent_blockhash, + ); + send_transaction(&config, transaction)?; + Ok(()) +} + +fn command_decrease_validator_stake( + config: &Config, + stake_pool_address: &Pubkey, + vote_account: &Pubkey, + lamports: u64, +) -> CommandResult { + if !config.no_update { + command_update(config, stake_pool_address)?; + } + + let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; + let pool_withdraw_authority = + find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; + let (validator_stake_address, _) = + find_stake_program_address(&spl_stake_pool::id(), &vote_account, stake_pool_address); + let (transient_stake_address, _) = find_transient_stake_program_address( + &spl_stake_pool::id(), + &vote_account, + stake_pool_address, + ); + + let mut transaction = Transaction::new_with_payer( + &[spl_stake_pool::instruction::decrease_validator_stake( + &spl_stake_pool::id(), + &stake_pool_address, + &config.staker.pubkey(), + &pool_withdraw_authority, + &stake_pool.validator_list, + &validator_stake_address, + &transient_stake_address, + lamports, + )], + Some(&config.fee_payer.pubkey()), + ); + + let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; + transaction.sign( + &[config.fee_payer.as_ref(), config.staker.as_ref()], + recent_blockhash, + ); + send_transaction(&config, transaction)?; + Ok(()) +} + fn unwrap_create_token_account( config: &Config, token_optional: &Option, @@ -630,21 +719,10 @@ fn command_update(config: &Config, stake_pool_address: &Pubkey) -> CommandResult let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?; - let accounts_to_update: Vec = validator_list + let vote_accounts: Vec = validator_list .validators .iter() - .filter_map(|item| { - if item.last_update_epoch >= epoch_info.epoch { - None - } else { - let (stake_account, _) = find_stake_program_address( - &spl_stake_pool::id(), - &item.vote_account_address, - &stake_pool_address, - ); - Some(stake_account) - } - }) + .map(|item| item.vote_account_address) .collect(); println!("Updating stake pool..."); @@ -653,7 +731,7 @@ fn command_update(config: &Config, stake_pool_address: &Pubkey) -> CommandResult let mut instructions: Vec = vec![]; let mut start_index = 0; - for accounts_chunk in accounts_to_update.chunks(MAX_VALIDATORS_TO_UPDATE) { + for accounts_chunk in vote_accounts.chunks(MAX_VALIDATORS_TO_UPDATE) { instructions.push(spl_stake_pool::instruction::update_validator_list_balance( &spl_stake_pool::id(), stake_pool_address, @@ -1181,6 +1259,64 @@ fn main() { Defaults to the wallet owner pubkey."), ) ) + .subcommand(SubCommand::with_name("increase-validator-stake") + .about("Increase stake to a validator, drawing from the stake pool reserve. Must be signed by the pool staker.") + .arg( + Arg::with_name("pool") + .index(1) + .validator(is_pubkey) + .value_name("POOL_ADDRESS") + .takes_value(true) + .required(true) + .help("Stake pool address"), + ) + .arg( + Arg::with_name("vote_account") + .index(2) + .validator(is_pubkey) + .value_name("VOTE_ACCOUNT_ADDRESS") + .takes_value(true) + .required(true) + .help("Vote account for the validator to increase stake to"), + ) + .arg( + Arg::with_name("lamports") + .index(3) + .validator(is_pubkey) + .value_name("LAMPORTS") + .takes_value(true) + .help("Amount in lamports to add to the validator stake account. Must be at least the rent-exempt amount for a stake plus 1 SOL for merging."), + ) + ) + .subcommand(SubCommand::with_name("decrease-validator-stake") + .about("Decrease stake to a validator, splitting from the active stake. Must be signed by the pool staker.") + .arg( + Arg::with_name("pool") + .index(1) + .validator(is_pubkey) + .value_name("POOL_ADDRESS") + .takes_value(true) + .required(true) + .help("Stake pool address"), + ) + .arg( + Arg::with_name("vote_account") + .index(2) + .validator(is_pubkey) + .value_name("VOTE_ACCOUNT_ADDRESS") + .takes_value(true) + .required(true) + .help("Vote account for the validator to decrease stake from"), + ) + .arg( + Arg::with_name("lamports") + .index(3) + .validator(is_pubkey) + .value_name("LAMPORTS") + .takes_value(true) + .help("Amount in lamports to remove from the validator stake account. Must be at least the rent-exempt amount for a stake."), + ) + ) .subcommand(SubCommand::with_name("deposit") .about("Add stake account to the stake pool") .arg( @@ -1455,6 +1591,18 @@ fn main() { let new_authority: Option = pubkey_of(arg_matches, "new_authority"); command_vsa_remove(&config, &stake_pool_address, &vote_account, &new_authority) } + ("increase-validator-stake", Some(arg_matches)) => { + let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); + let vote_account = pubkey_of(arg_matches, "vote_account").unwrap(); + let lamports = value_t_or_exit!(arg_matches, "lamports", u64); + command_increase_validator_stake(&config, &stake_pool_address, &vote_account, lamports) + } + ("decrease-validator-stake", Some(arg_matches)) => { + let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); + let vote_account = pubkey_of(arg_matches, "vote_account").unwrap(); + let lamports = value_t_or_exit!(arg_matches, "lamports", u64); + command_decrease_validator_stake(&config, &stake_pool_address, &vote_account, lamports) + } ("deposit", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); let stake_account = pubkey_of(arg_matches, "stake_account").unwrap(); diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 0983bf3a..b8f3f795 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -391,7 +391,7 @@ pub fn decrease_validator_stake( validator_stake: &Pubkey, transient_stake: &Pubkey, lamports: u64, -) -> Result { +) -> Instruction { let accounts = vec![ AccountMeta::new_readonly(*stake_pool, false), AccountMeta::new_readonly(*staker, true), @@ -404,11 +404,13 @@ pub fn decrease_validator_stake( AccountMeta::new_readonly(system_program::id(), false), AccountMeta::new_readonly(stake_program::id(), false), ]; - Ok(Instruction { + Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::DecreaseValidatorStake(lamports).try_to_vec()?, - }) + data: StakePoolInstruction::DecreaseValidatorStake(lamports) + .try_to_vec() + .unwrap(), + } } /// Creates `IncreaseValidatorStake` instruction (rebalance from reserve account to @@ -423,7 +425,7 @@ pub fn increase_validator_stake( transient_stake: &Pubkey, validator: &Pubkey, lamports: u64, -) -> Result { +) -> Instruction { let accounts = vec![ AccountMeta::new_readonly(*stake_pool, false), AccountMeta::new_readonly(*staker, true), @@ -439,11 +441,13 @@ pub fn increase_validator_stake( AccountMeta::new_readonly(system_program::id(), false), AccountMeta::new_readonly(stake_program::id(), false), ]; - Ok(Instruction { + Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::IncreaseValidatorStake(lamports).try_to_vec()?, - }) + data: StakePoolInstruction::IncreaseValidatorStake(lamports) + .try_to_vec() + .unwrap(), + } } /// Creates `UpdateValidatorListBalance` instruction (update validator stake account balances) diff --git a/program/tests/decrease.rs b/program/tests/decrease.rs index 647d38d9..c1a31fce 100644 --- a/program/tests/decrease.rs +++ b/program/tests/decrease.rs @@ -155,8 +155,7 @@ async fn fail_with_wrong_withdraw_authority() { &validator_stake.stake_account, &validator_stake.transient_stake_account, decrease_lamports, - ) - .unwrap()], + )], Some(&payer.pubkey()), &[&payer, &stake_pool_accounts.staker], recent_blockhash, @@ -201,8 +200,7 @@ async fn fail_with_wrong_validator_list() { &validator_stake.stake_account, &validator_stake.transient_stake_account, decrease_lamports, - ) - .unwrap()], + )], Some(&payer.pubkey()), &[&payer, &stake_pool_accounts.staker], recent_blockhash, @@ -258,8 +256,7 @@ async fn fail_with_unknown_validator() { &unknown_stake.stake_account, &unknown_stake.transient_stake_account, decrease_lamports, - ) - .unwrap()], + )], Some(&payer.pubkey()), &[&payer, &stake_pool_accounts.staker], recent_blockhash, diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index e99e01fc..e6ac8061 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -831,8 +831,7 @@ impl StakePoolAccounts { validator_stake, transient_stake, lamports, - ) - .unwrap()], + )], Some(&payer.pubkey()), &[payer, &self.staker], *recent_blockhash, @@ -860,8 +859,7 @@ impl StakePoolAccounts { transient_stake, validator, lamports, - ) - .unwrap()], + )], Some(&payer.pubkey()), &[payer, &self.staker], *recent_blockhash, diff --git a/program/tests/increase.rs b/program/tests/increase.rs index 9d02c1c3..3a540348 100644 --- a/program/tests/increase.rs +++ b/program/tests/increase.rs @@ -27,7 +27,7 @@ async fn setup() -> ( ) { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); - let reserve_lamports = 100_000_000; + let reserve_lamports = 100_000_000_000; stake_pool_accounts .initialize_stake_pool( &mut banks_client, @@ -156,8 +156,7 @@ async fn fail_with_wrong_withdraw_authority() { &validator_stake.transient_stake_account, &validator_stake.vote.pubkey(), reserve_lamports / 2, - ) - .unwrap()], + )], Some(&payer.pubkey()), &[&payer, &stake_pool_accounts.staker], recent_blockhash, @@ -202,8 +201,7 @@ async fn fail_with_wrong_validator_list() { &validator_stake.transient_stake_account, &validator_stake.vote.pubkey(), reserve_lamports / 2, - ) - .unwrap()], + )], Some(&payer.pubkey()), &[&payer, &stake_pool_accounts.staker], recent_blockhash, @@ -259,8 +257,7 @@ async fn fail_with_unknown_validator() { &unknown_stake.transient_stake_account, &unknown_stake.vote.pubkey(), reserve_lamports / 2, - ) - .unwrap()], + )], Some(&payer.pubkey()), &[&payer, &stake_pool_accounts.staker], recent_blockhash, From 3a01afe4c796cd2322571f2befc570aa9049b2e3 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 22 Apr 2021 14:30:47 +0200 Subject: [PATCH 0088/1076] hotfix: ignore tests that break with tip of 1.6 (#1622) --- program/tests/update_validator_list_balance.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index 03b179ea..393db83f 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -146,6 +146,7 @@ async fn setup( } #[tokio::test] +#[ignore] async fn success() { let num_validators = 5; let (mut context, stake_pool_accounts, stake_accounts, _, mut slot) = @@ -208,6 +209,7 @@ async fn success() { } #[tokio::test] +#[ignore] async fn merge_into_reserve() { let (mut context, stake_pool_accounts, stake_accounts, lamports, mut slot) = setup(MAX_VALIDATORS_TO_UPDATE).await; @@ -318,6 +320,7 @@ async fn merge_into_reserve() { } #[tokio::test] +#[ignore] async fn merge_into_validator_stake() { let (mut context, stake_pool_accounts, stake_accounts, lamports, mut slot) = setup(MAX_VALIDATORS_TO_UPDATE).await; From 2c05dc19750c977a82da901304dcb53aa24278b7 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 22 Apr 2021 20:49:30 +0200 Subject: [PATCH 0089/1076] stake-pool: Increase lower limit for increase-validator-stake (#1620) * stake-pool: Increase lower limit for increase-validator-stake * Update test amounts in line with limit --- program/src/processor.rs | 7 +-- program/tests/helpers/mod.rs | 2 +- .../tests/update_validator_list_balance.rs | 48 +++++++++++++++---- program/tests/vsa_remove.rs | 4 +- 4 files changed, 46 insertions(+), 15 deletions(-) diff --git a/program/src/processor.rs b/program/src/processor.rs index 90201651..36bf2e1f 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1003,10 +1003,11 @@ impl Processor { let mut validator_list_entry = maybe_validator_list_entry.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); - if lamports <= stake_rent { + let minimum_lamports = MINIMUM_ACTIVE_STAKE + stake_rent; + if lamports < minimum_lamports { msg!( - "Need more than {} lamports for transient stake to be rent-exempt, {} provided", - stake_rent, + "Need more than {} lamports for transient stake to be rent-exempt and mergeable, {} provided", + minimum_lamports, lamports ); return Err(ProgramError::AccountNotRentExempt); diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index e6ac8061..6bd6c769 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -23,7 +23,7 @@ use { }, }; -pub const TEST_STAKE_AMOUNT: u64 = 100_000_000; +pub const TEST_STAKE_AMOUNT: u64 = 1_500_000_000; pub const MAX_TEST_VALIDATORS: u32 = 10_000; pub fn program_test() -> ProgramTest { diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index 393db83f..460b72ac 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -7,7 +7,7 @@ use { helpers::*, solana_program::pubkey::Pubkey, solana_program_test::*, - solana_sdk::signature::Signer, + solana_sdk::signature::{Keypair, Signer}, spl_stake_pool::{ stake_program, state::StakePool, MAX_VALIDATORS_TO_UPDATE, MINIMUM_ACTIVE_STAKE, }, @@ -21,6 +21,7 @@ async fn setup( Vec, u64, u64, + u64, ) { let mut context = program_test().start_with_context().await; let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; @@ -28,17 +29,39 @@ async fn setup( let mut slot = first_normal_slot; context.warp_to_slot(slot).unwrap(); + let reserve_stake_amount = TEST_STAKE_AMOUNT * num_validators as u64; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts .initialize_stake_pool( &mut context.banks_client, &context.payer, &context.last_blockhash, - TEST_STAKE_AMOUNT + 1, + reserve_stake_amount + 1, ) .await .unwrap(); + // so warmups / cooldowns go faster + let validator = Keypair::new(); + let vote = Keypair::new(); + create_vote( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &validator, + &vote, + ) + .await; + let deposit_account = + DepositStakeAccount::new_with_vote(vote.pubkey(), validator.pubkey(), 100_000_000_000); + deposit_account + .create_and_delegate( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; + // Add several accounts with some stake let mut stake_accounts: Vec = vec![]; let mut deposit_accounts: Vec = vec![]; @@ -141,6 +164,7 @@ async fn setup( stake_pool_accounts, stake_accounts, TEST_STAKE_AMOUNT, + reserve_stake_amount, slot, ) } @@ -149,15 +173,21 @@ async fn setup( #[ignore] async fn success() { let num_validators = 5; - let (mut context, stake_pool_accounts, stake_accounts, _, mut slot) = - setup(num_validators).await; + let ( + mut context, + stake_pool_accounts, + stake_accounts, + validator_lamports, + reserve_lamports, + mut slot, + ) = setup(num_validators).await; // Check current balance in the list let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); // initially, have all of the deposits plus their rent, and the reserve stake let initial_lamports = - (TEST_STAKE_AMOUNT + stake_rent) * num_validators as u64 + TEST_STAKE_AMOUNT; + (validator_lamports + stake_rent) * num_validators as u64 + reserve_lamports; assert_eq!( get_validator_list_sum( &mut context.banks_client, @@ -211,7 +241,7 @@ async fn success() { #[tokio::test] #[ignore] async fn merge_into_reserve() { - let (mut context, stake_pool_accounts, stake_accounts, lamports, mut slot) = + let (mut context, stake_pool_accounts, stake_accounts, lamports, _, mut slot) = setup(MAX_VALIDATORS_TO_UPDATE).await; let pre_lamports = get_validator_list_sum( @@ -322,7 +352,7 @@ async fn merge_into_reserve() { #[tokio::test] #[ignore] async fn merge_into_validator_stake() { - let (mut context, stake_pool_accounts, stake_accounts, lamports, mut slot) = + let (mut context, stake_pool_accounts, stake_accounts, lamports, reserve_lamports, mut slot) = setup(MAX_VALIDATORS_TO_UPDATE).await; let rent = context.banks_client.get_rent().await.unwrap(); @@ -342,7 +372,7 @@ async fn merge_into_validator_stake() { &context.last_blockhash, &stake_account.transient_stake_account, &stake_account.vote.pubkey(), - lamports / stake_accounts.len() as u64, + reserve_lamports / stake_accounts.len() as u64, ) .await; assert!(error.is_none()); @@ -437,7 +467,7 @@ async fn merge_into_validator_stake() { // validator stake account minimum + deposited lamports + 2 rents + increased lamports let expected_lamports = MINIMUM_ACTIVE_STAKE + lamports - + lamports / stake_accounts.len() as u64 + + reserve_lamports / stake_accounts.len() as u64 + 2 * rent.minimum_balance(std::mem::size_of::()); for stake_account in &stake_accounts { let validator_stake = diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index b146dd00..8f89ef95 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -34,7 +34,7 @@ async fn setup() -> ( let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 10_000_000) + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 10_000_000_000) .await .unwrap(); @@ -392,7 +392,7 @@ async fn fail_with_activating_transient_stake() { &recent_blockhash, &user_stake.transient_stake_account, &user_stake.vote.pubkey(), - 5_000_000, + 2_000_000_000, ) .await; assert!(error.is_none()); From efbf552c5d711c12b9b564f0fd0afd584d913a9d Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 22 Apr 2021 21:34:41 +0200 Subject: [PATCH 0090/1076] stake-pool: Add depositor key on init, required on deposit (#1616) * stake-pool: Add depositor key on init, required on deposit Some stake pools need to be private, and not allow outside depositors. Enhance the existing deposit authority in the stake pool be configurable on initialization, and then require its signature on deposit. The existing deposit authority is a program address, making deposits permissionless. This allows a pool creator to set their own deposit_authority on initialization. In a great turn of events, almost everything else works the same way! Here's the current workflow for deposit, where the user calls stake_program::authorize and stake_pool::deposit in the same transaction: * stake_program::authorize assigns staker and withdraw authority to the stake pool deposit authority * stake_pool::deposit - uses the deposit authority to assign authority on the deposited stake account to the stake pool withdraw authority - uses the withdraw authority to merge the deposited stake into the validator stake The deposit authority must "sign" the transaction in order to reassign authority to the withdraw authority. Currently, as a program address, it can just do that. With this change, if the deposit authority is set during initialization, then that deposit authority must sign the instruction. There's also a little update for ease-of-use to always do the stake_program::authorize in the same transaction as stake_pool::deposit. This way, in case someone tries to deposit into a forbidden stake pool, the whole transaction will bail and their stake will stay as theirs. * Address review feedback * Fix rebase issues --- clients/cli/src/main.rs | 137 ++++++--- program/src/instruction.rs | 124 ++++++-- program/src/processor.rs | 260 ++++++++++------- program/src/state.rs | 29 +- program/tests/decrease.rs | 5 +- program/tests/deposit.rs | 266 ++++++++++-------- program/tests/helpers/mod.rs | 124 +++----- program/tests/increase.rs | 5 +- program/tests/initialize.rs | 33 ++- .../tests/update_validator_list_balance.rs | 5 +- program/tests/vsa_add.rs | 51 +--- program/tests/vsa_remove.rs | 5 +- program/tests/withdraw.rs | 11 +- 13 files changed, 602 insertions(+), 453 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 5de6efc6..3532cb88 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -14,7 +14,7 @@ use { input_validators::{is_amount, is_keypair, is_parsable, is_pubkey, is_url}, keypair::signer_from_path, }, - solana_client::{rpc_client::RpcClient, rpc_response::StakeActivationState}, + solana_client::rpc_client::RpcClient, solana_program::{ borsh::get_packed_len, instruction::Instruction, program_pack::Pack, pubkey::Pubkey, }, @@ -28,9 +28,9 @@ use { spl_stake_pool::{ self, borsh::get_instance_packed_len, - find_deposit_authority_program_address, find_stake_program_address, - find_transient_stake_program_address, find_withdraw_authority_program_address, - stake_program::{self, StakeAuthorize, StakeState}, + find_stake_program_address, find_transient_stake_program_address, + find_withdraw_authority_program_address, + stake_program::{self, StakeState}, state::{Fee, StakePool, ValidatorList}, MAX_VALIDATORS_TO_UPDATE, }, @@ -42,6 +42,7 @@ struct Config { verbose: bool, manager: Box, staker: Box, + depositor: Option>, token_owner: Box, fee_payer: Box, dry_run: bool, @@ -94,7 +95,12 @@ fn send_transaction( Ok(()) } -fn command_create_pool(config: &Config, fee: Fee, max_validators: u32) -> CommandResult { +fn command_create_pool( + config: &Config, + deposit_authority: Option, + fee: Fee, + max_validators: u32, +) -> CommandResult { let reserve_stake = Keypair::new(); println!("Creating reserve stake {}", reserve_stake.pubkey()); @@ -224,6 +230,7 @@ fn command_create_pool(config: &Config, fee: Fee, max_validators: u32) -> Comman &mint_account.pubkey(), &pool_fee_account.pubkey(), &spl_token::id(), + deposit_authority, fee, max_validators, )?, @@ -286,7 +293,17 @@ fn command_vsa_create( } fn command_vsa_add(config: &Config, stake_pool_address: &Pubkey, stake: &Pubkey) -> CommandResult { - if config.rpc_client.get_stake_activation(*stake, None)?.state != StakeActivationState::Active { + let stake_state = get_stake_state(&config.rpc_client, &stake)?; + if let stake_program::StakeState::Stake(meta, _stake) = stake_state { + if meta.authorized.withdrawer != config.staker.pubkey() { + let error = format!( + "Stake account withdraw authority must be the staker {}, actual {}", + config.staker.pubkey(), + meta.authorized.withdrawer + ); + return Err(error.into()); + } + } else { return Err("Stake account is not active.".into()); } @@ -299,34 +316,16 @@ fn command_vsa_add(config: &Config, stake_pool_address: &Pubkey, stake: &Pubkey) let mut instructions: Vec = vec![]; let mut signers = vec![config.fee_payer.as_ref(), config.staker.as_ref()]; - // Calculate Deposit and Withdraw stake pool authorities - let pool_deposit_authority = - find_deposit_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; - + // Calculate Withdraw stake pool authorities let pool_withdraw_authority = find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; instructions.extend(vec![ - // Set Withdrawer on stake account to Deposit authority of the stake pool - stake_program::authorize( - &stake, - &config.staker.pubkey(), - &pool_deposit_authority, - StakeAuthorize::Withdrawer, - ), - // Set Staker on stake account to Deposit authority of the stake pool - stake_program::authorize( - &stake, - &config.staker.pubkey(), - &pool_deposit_authority, - StakeAuthorize::Staker, - ), // Add validator stake account to the pool spl_stake_pool::instruction::add_validator_to_pool( &spl_stake_pool::id(), &stake_pool_address, &config.staker.pubkey(), - &pool_deposit_authority, &pool_withdraw_authority, &stake_pool.validator_list, &stake, @@ -588,42 +587,49 @@ fn command_deposit( }, )?; - // Calculate Deposit and Withdraw stake pool authorities - let pool_deposit_authority = - find_deposit_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; - let pool_withdraw_authority = find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; - instructions.extend(vec![ - // Set Withdrawer on stake account to Deposit authority of the stake pool - stake_program::authorize( - &stake, - &config.staker.pubkey(), - &pool_deposit_authority, - StakeAuthorize::Withdrawer, - ), - // Set Staker on stake account to Deposit authority of the stake pool - stake_program::authorize( + let mut deposit_instructions = if let Some(deposit_authority) = config.depositor.as_ref() { + signers.push(deposit_authority.as_ref()); + if deposit_authority.pubkey() != stake_pool.deposit_authority { + let error = format!( + "Invalid deposit authority specified, expected {}, received {}", + stake_pool.deposit_authority, + deposit_authority.pubkey() + ); + return Err(error.into()); + } + + spl_stake_pool::instruction::deposit_with_authority( + &spl_stake_pool::id(), + &stake_pool_address, + &stake_pool.validator_list, + &deposit_authority.pubkey(), + &pool_withdraw_authority, &stake, &config.staker.pubkey(), - &pool_deposit_authority, - StakeAuthorize::Staker, - ), - // Add stake account to the pool + &validator_stake_account, + &token_receiver, + &stake_pool.pool_mint, + &spl_token::id(), + ) + } else { spl_stake_pool::instruction::deposit( &spl_stake_pool::id(), &stake_pool_address, &stake_pool.validator_list, - &pool_deposit_authority, &pool_withdraw_authority, &stake, + &config.staker.pubkey(), &validator_stake_account, &token_receiver, &stake_pool.pool_mint, &spl_token::id(), - )?, - ]); + ) + }; + + instructions.append(&mut deposit_instructions); let mut transaction = Transaction::new_with_payer(&instructions, Some(&config.fee_payer.pubkey())); @@ -1130,6 +1136,17 @@ fn main() { Defaults to the client keypair.", ), ) + .arg( + Arg::with_name("depositor") + .long("depositor") + .value_name("KEYPAIR") + .validator(is_keypair) + .takes_value(true) + .help( + "Specify the stake pool depositor. \ + This may be a keypair file, the ASK keyword.", + ), + ) .arg( Arg::with_name("token_owner") .long("token-owner") @@ -1186,6 +1203,15 @@ fn main() { .required(true) .help("Max number of validators included in the stake pool"), ) + .arg( + Arg::with_name("deposit_authority") + .long("deposit-authority") + .short("a") + .validator(is_pubkey) + .value_name("DEPOSIT_AUTHORITY_ADDRESS") + .takes_value(true) + .help("Deposit authority required to sign all deposits into the stake pool"), + ) ) .subcommand(SubCommand::with_name("create-validator-stake") .about("Create a new stake account to use with the pool. Must be signed by the pool staker.") @@ -1515,6 +1541,22 @@ fn main() { eprintln!("error: {}", e); exit(1); }); + let depositor = if matches.is_present("depositor") { + Some( + signer_from_path( + &matches, + &cli_config.keypair_path, + "depositor", + &mut wallet_manager, + ) + .unwrap_or_else(|e| { + eprintln!("error: {}", e); + exit(1); + }), + ) + } else { + None + }; let manager = signer_from_path( &matches, &cli_config.keypair_path, @@ -1554,6 +1596,7 @@ fn main() { verbose, manager, staker, + depositor, token_owner, fee_payer, dry_run, @@ -1563,11 +1606,13 @@ fn main() { let _ = match matches.subcommand() { ("create-pool", Some(arg_matches)) => { + let deposit_authority = pubkey_of(arg_matches, "deposit_authority"); let numerator = value_t_or_exit!(arg_matches, "fee_numerator", u64); let denominator = value_t_or_exit!(arg_matches, "fee_denominator", u64); let max_validators = value_t_or_exit!(arg_matches, "max_validators", u32); command_create_pool( &config, + deposit_authority, Fee { denominator, numerator, diff --git a/program/src/instruction.rs b/program/src/instruction.rs index b8f3f795..ebf2bf52 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -4,7 +4,8 @@ use { crate::{ - find_stake_program_address, find_transient_stake_program_address, stake_program, state::Fee, + find_deposit_authority_program_address, find_stake_program_address, + find_transient_stake_program_address, stake_program, state::Fee, }, borsh::{BorshDeserialize, BorshSchema, BorshSerialize}, solana_program::{ @@ -32,6 +33,9 @@ pub enum StakePoolInstruction { /// 7. `[]` Clock sysvar /// 8. `[]` Rent sysvar /// 9. `[]` Token program id + /// 10. `[]` (Optional) Deposit authority that must sign all deposits. + /// Defaults to the program address generated using + /// `find_deposit_authority_program_address`, making deposits permissionless. Initialize { /// Fee assessed as percentage of perceived rewards #[allow(dead_code)] // but it's not @@ -70,13 +74,13 @@ pub enum StakePoolInstruction { /// /// 0. `[w]` Stake pool /// 1. `[s]` Staker - /// 2. `[]` Stake pool deposit authority - /// 3. `[]` Stake pool withdraw authority - /// 4. `[w]` Validator stake list storage account - /// 5. `[w]` Stake account to add to the pool, its withdraw authority should be set to stake pool deposit - /// 6. `[]` Clock sysvar - /// 7. '[]' Sysvar stake history account - /// 8. `[]` Stake program + /// 2. `[]` Stake pool withdraw authority + /// 3. `[w]` Validator stake list storage account + /// 4. `[w]` Stake account to add to the pool, its withdraw authority must + /// be set to the staker + /// 5. `[]` Clock sysvar + /// 6. '[]' Sysvar stake history account + /// 7. `[]` Stake program AddValidatorToPool, /// (Staker only) Removes validator from the pool @@ -195,7 +199,7 @@ pub enum StakePoolInstruction { /// 1. `[w]` Validator stake list storage account /// 2. `[]` Stake pool deposit authority /// 3. `[]` Stake pool withdraw authority - /// 4. `[w]` Stake account to join the pool (withdraw should be set to stake pool deposit) + /// 4. `[w]` Stake account to join the pool (withdraw authority for the stake account should be first set to the stake pool deposit authority) /// 5. `[w]` Validator stake account for the stake account to be merged with /// 6. `[w]` User account to receive pool tokens /// 8. `[w]` Pool token mint account @@ -267,6 +271,7 @@ pub fn initialize( pool_mint: &Pubkey, manager_pool_account: &Pubkey, token_program_id: &Pubkey, + deposit_authority: Option, fee: Fee, max_validators: u32, ) -> Result { @@ -275,7 +280,7 @@ pub fn initialize( max_validators, }; let data = init_data.try_to_vec()?; - let accounts = vec![ + let mut accounts = vec![ AccountMeta::new(*stake_pool, true), AccountMeta::new_readonly(*manager, true), AccountMeta::new_readonly(*staker, false), @@ -287,6 +292,9 @@ pub fn initialize( AccountMeta::new_readonly(sysvar::rent::id(), false), AccountMeta::new_readonly(*token_program_id, false), ]; + if let Some(deposit_authority) = deposit_authority { + accounts.push(AccountMeta::new_readonly(deposit_authority, true)); + } Ok(Instruction { program_id: *program_id, accounts, @@ -328,7 +336,6 @@ pub fn add_validator_to_pool( program_id: &Pubkey, stake_pool: &Pubkey, staker: &Pubkey, - stake_pool_deposit: &Pubkey, stake_pool_withdraw: &Pubkey, validator_list: &Pubkey, stake_account: &Pubkey, @@ -336,7 +343,6 @@ pub fn add_validator_to_pool( let accounts = vec![ AccountMeta::new(*stake_pool, false), AccountMeta::new_readonly(*staker, true), - AccountMeta::new_readonly(*stake_pool_deposit, false), AccountMeta::new_readonly(*stake_pool_withdraw, false), AccountMeta::new(*validator_list, false), AccountMeta::new(*stake_account, false), @@ -529,25 +535,28 @@ pub fn update_stake_pool_balance( } } -/// Creates a 'Deposit' instruction. +/// Creates instructions required to deposit into a stake pool, given a stake +/// account owned by the user. pub fn deposit( program_id: &Pubkey, stake_pool: &Pubkey, validator_list_storage: &Pubkey, - stake_pool_deposit: &Pubkey, - stake_pool_withdraw: &Pubkey, - stake_to_join: &Pubkey, + stake_pool_withdraw_authority: &Pubkey, + deposit_stake_address: &Pubkey, + deposit_stake_withdraw_authority: &Pubkey, validator_stake_accont: &Pubkey, pool_tokens_to: &Pubkey, pool_mint: &Pubkey, token_program_id: &Pubkey, -) -> Result { +) -> Vec { + let stake_pool_deposit_authority = + find_deposit_authority_program_address(program_id, stake_pool).0; let accounts = vec![ AccountMeta::new(*stake_pool, false), AccountMeta::new(*validator_list_storage, false), - AccountMeta::new_readonly(*stake_pool_deposit, false), - AccountMeta::new_readonly(*stake_pool_withdraw, false), - AccountMeta::new(*stake_to_join, false), + AccountMeta::new_readonly(stake_pool_deposit_authority, false), + AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), + AccountMeta::new(*deposit_stake_address, false), AccountMeta::new(*validator_stake_accont, false), AccountMeta::new(*pool_tokens_to, false), AccountMeta::new(*pool_mint, false), @@ -556,11 +565,76 @@ pub fn deposit( AccountMeta::new_readonly(*token_program_id, false), AccountMeta::new_readonly(stake_program::id(), false), ]; - Ok(Instruction { - program_id: *program_id, - accounts, - data: StakePoolInstruction::Deposit.try_to_vec()?, - }) + vec![ + stake_program::authorize( + deposit_stake_address, + deposit_stake_withdraw_authority, + &stake_pool_deposit_authority, + stake_program::StakeAuthorize::Staker, + ), + stake_program::authorize( + deposit_stake_address, + deposit_stake_withdraw_authority, + &stake_pool_deposit_authority, + stake_program::StakeAuthorize::Withdrawer, + ), + Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::Deposit.try_to_vec().unwrap(), + }, + ] +} + +/// Creates instructions required to deposit into a stake pool, given a stake +/// account owned by the user. The difference with `deposit()` is that a deposit +/// authority must sign this instruction, which is required for private pools. +pub fn deposit_with_authority( + program_id: &Pubkey, + stake_pool: &Pubkey, + validator_list_storage: &Pubkey, + stake_pool_deposit_authority: &Pubkey, + stake_pool_withdraw_authority: &Pubkey, + deposit_stake_address: &Pubkey, + deposit_stake_withdraw_authority: &Pubkey, + validator_stake_accont: &Pubkey, + pool_tokens_to: &Pubkey, + pool_mint: &Pubkey, + token_program_id: &Pubkey, +) -> Vec { + let accounts = vec![ + AccountMeta::new(*stake_pool, false), + AccountMeta::new(*validator_list_storage, false), + AccountMeta::new_readonly(*stake_pool_deposit_authority, true), + AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), + AccountMeta::new(*deposit_stake_address, false), + AccountMeta::new(*validator_stake_accont, false), + AccountMeta::new(*pool_tokens_to, false), + AccountMeta::new(*pool_mint, false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(sysvar::stake_history::id(), false), + AccountMeta::new_readonly(*token_program_id, false), + AccountMeta::new_readonly(stake_program::id(), false), + ]; + vec![ + stake_program::authorize( + deposit_stake_address, + deposit_stake_withdraw_authority, + stake_pool_deposit_authority, + stake_program::StakeAuthorize::Staker, + ), + stake_program::authorize( + deposit_stake_address, + deposit_stake_withdraw_authority, + stake_pool_deposit_authority, + stake_program::StakeAuthorize::Withdrawer, + ), + Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::Deposit.try_to_vec().unwrap(), + }, + ] } /// Creates a 'withdraw' instruction. diff --git a/program/src/processor.rs b/program/src/processor.rs index 36bf2e1f..53515cfd 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -4,6 +4,7 @@ use { crate::{ borsh::try_from_slice_unchecked, error::StakePoolError, + find_deposit_authority_program_address, instruction::StakePoolInstruction, minimum_reserve_lamports, minimum_stake_lamports, stake_program, state::{AccountType, Fee, StakePool, ValidatorList, ValidatorStakeInfo}, @@ -203,10 +204,14 @@ impl Processor { let authority_signature_seeds = [&me_bytes[..32], authority_type, &[bump_seed]]; let signers = &[&authority_signature_seeds[..]]; - let ix = + let split_instruction = stake_program::split_only(stake_account.key, authority.key, amount, split_stake.key); - invoke_signed(&ix, &[stake_account, split_stake, authority], signers) + invoke_signed( + &split_instruction, + &[stake_account, split_stake, authority], + signers, + ) } /// Issue a stake_merge instruction. @@ -226,10 +231,11 @@ impl Processor { let authority_signature_seeds = [&me_bytes[..32], authority_type, &[bump_seed]]; let signers = &[&authority_signature_seeds[..]]; - let ix = stake_program::merge(destination_account.key, source_account.key, authority.key); + let merge_instruction = + stake_program::merge(destination_account.key, source_account.key, authority.key); invoke_signed( - &ix, + &merge_instruction, &[ destination_account, source_account, @@ -242,16 +248,53 @@ impl Processor { ) } - /// Issue a stake_set_manager instruction. - #[allow(clippy::too_many_arguments)] + /// Issue stake_program::authorize instructions to update both authorities fn stake_authorize<'a>( + stake_account: AccountInfo<'a>, + stake_authority: AccountInfo<'a>, + new_stake_authority: &Pubkey, + clock: AccountInfo<'a>, + stake_program_info: AccountInfo<'a>, + ) -> Result<(), ProgramError> { + let authorize_instruction = stake_program::authorize( + stake_account.key, + stake_authority.key, + new_stake_authority, + stake_program::StakeAuthorize::Staker, + ); + + invoke( + &authorize_instruction, + &[ + stake_account.clone(), + clock.clone(), + stake_authority.clone(), + stake_program_info.clone(), + ], + )?; + + let authorize_instruction = stake_program::authorize( + stake_account.key, + stake_authority.key, + new_stake_authority, + stake_program::StakeAuthorize::Withdrawer, + ); + + invoke( + &authorize_instruction, + &[stake_account, clock, stake_authority, stake_program_info], + ) + } + + /// Issue stake_program::authorize instructions to update both authorities + #[allow(clippy::too_many_arguments)] + fn stake_authorize_signed<'a>( stake_pool: &Pubkey, stake_account: AccountInfo<'a>, - authority: AccountInfo<'a>, + stake_authority: AccountInfo<'a>, authority_type: &[u8], bump_seed: u8, - new_staker: &Pubkey, - staker_auth: stake_program::StakeAuthorize, + new_stake_authority: &Pubkey, clock: AccountInfo<'a>, stake_program_info: AccountInfo<'a>, ) -> Result<(), ProgramError> { @@ -259,12 +302,33 @@ impl Processor { let authority_signature_seeds = [&me_bytes[..32], authority_type, &[bump_seed]]; let signers = &[&authority_signature_seeds[..]]; - let ix = - stake_program::authorize(stake_account.key, authority.key, new_staker, staker_auth); + let authorize_instruction = stake_program::authorize( + stake_account.key, + stake_authority.key, + new_stake_authority, + stake_program::StakeAuthorize::Staker, + ); invoke_signed( - &ix, - &[stake_account, clock, authority, stake_program_info], + &authorize_instruction, + &[ + stake_account.clone(), + clock.clone(), + stake_authority.clone(), + stake_program_info.clone(), + ], + signers, + )?; + + let authorize_instruction = stake_program::authorize( + stake_account.key, + stake_authority.key, + new_stake_authority, + stake_program::StakeAuthorize::Withdrawer, + ); + invoke_signed( + &authorize_instruction, + &[stake_account, clock, stake_authority, stake_program_info], signers, ) } @@ -414,8 +478,10 @@ impl Processor { return Err(StakePoolError::WrongAccountMint.into()); } - let (_, deposit_bump_seed) = - crate::find_deposit_authority_program_address(program_id, stake_pool_info.key); + let deposit_authority = match next_account_info(account_info_iter) { + Ok(deposit_authority_info) => *deposit_authority_info.key, + Err(_) => find_deposit_authority_program_address(program_id, stake_pool_info.key).0, + }; let (withdraw_authority_key, withdraw_bump_seed) = crate::find_withdraw_authority_program_address(program_id, stake_pool_info.key); @@ -475,7 +541,7 @@ impl Processor { stake_pool.manager = *manager_info.key; stake_pool.staker = *staker_info.key; stake_pool.reserve_stake = *reserve_stake_info.key; - stake_pool.deposit_bump_seed = deposit_bump_seed; + stake_pool.deposit_authority = deposit_authority; stake_pool.withdraw_bump_seed = withdraw_bump_seed; stake_pool.validator_list = *validator_list_info.key; stake_pool.pool_mint = *pool_mint_info.key; @@ -594,8 +660,7 @@ impl Processor { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; let staker_info = next_account_info(account_info_iter)?; - let deposit_info = next_account_info(account_info_iter)?; - let withdraw_info = next_account_info(account_info_iter)?; + let withdraw_authority_info = next_account_info(account_info_iter)?; let validator_list_info = next_account_info(account_info_iter)?; let stake_account_info = next_account_info(account_info_iter)?; let clock_info = next_account_info(account_info_iter)?; @@ -614,8 +679,11 @@ impl Processor { return Err(StakePoolError::InvalidState.into()); } - stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?; - stake_pool.check_authority_deposit(deposit_info.key, program_id, stake_pool_info.key)?; + stake_pool.check_authority_withdraw( + withdraw_authority_info.key, + program_id, + stake_pool_info.key, + )?; stake_pool.check_staker(staker_info)?; @@ -645,6 +713,11 @@ impl Processor { &vote_account_address, )?; + if meta.lockup != stake_program::Lockup::default() { + msg!("Validator stake account has a lockup"); + return Err(StakePoolError::WrongStakeState.into()); + } + if validator_list.contains(&vote_account_address) { return Err(StakePoolError::ValidatorAlreadyAdded.into()); } @@ -665,22 +738,13 @@ impl Processor { //Self::check_stake_activation(stake_account_info, clock, stake_history)?; // Update Withdrawer and Staker authority to the program withdraw authority - for authority in &[ - stake_program::StakeAuthorize::Withdrawer, - stake_program::StakeAuthorize::Staker, - ] { - Self::stake_authorize( - stake_pool_info.key, - stake_account_info.clone(), - deposit_info.clone(), - AUTHORITY_DEPOSIT, - stake_pool.deposit_bump_seed, - withdraw_info.key, - *authority, - clock_info.clone(), - stake_program_info.clone(), - )?; - } + Self::stake_authorize( + stake_account_info.clone(), + staker_info.clone(), + withdraw_authority_info.key, + clock_info.clone(), + stake_program_info.clone(), + )?; validator_list.validators.push(ValidatorStakeInfo { vote_account_address, @@ -700,7 +764,7 @@ impl Processor { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; let staker_info = next_account_info(account_info_iter)?; - let withdraw_info = next_account_info(account_info_iter)?; + let withdraw_authority_info = next_account_info(account_info_iter)?; let new_stake_authority_info = next_account_info(account_info_iter)?; let validator_list_info = next_account_info(account_info_iter)?; let stake_account_info = next_account_info(account_info_iter)?; @@ -717,7 +781,11 @@ impl Processor { return Err(StakePoolError::InvalidState.into()); } - stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?; + stake_pool.check_authority_withdraw( + withdraw_authority_info.key, + program_id, + stake_pool_info.key, + )?; stake_pool.check_staker(staker_info)?; if stake_pool.last_update_epoch < clock.epoch { @@ -772,22 +840,16 @@ impl Processor { return Err(StakePoolError::StakeLamportsNotEqualToMinimum.into()); } - for authority in &[ - stake_program::StakeAuthorize::Withdrawer, - stake_program::StakeAuthorize::Staker, - ] { - Self::stake_authorize( - stake_pool_info.key, - stake_account_info.clone(), - withdraw_info.clone(), - AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, - new_stake_authority_info.key, - *authority, - clock_info.clone(), - stake_program_info.clone(), - )?; - } + Self::stake_authorize_signed( + stake_pool_info.key, + stake_account_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.withdraw_bump_seed, + new_stake_authority_info.key, + clock_info.clone(), + stake_program_info.clone(), + )?; validator_list .validators @@ -1382,8 +1444,8 @@ impl Processor { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; let validator_list_info = next_account_info(account_info_iter)?; - let deposit_info = next_account_info(account_info_iter)?; - let withdraw_info = next_account_info(account_info_iter)?; + let deposit_authority_info = next_account_info(account_info_iter)?; + let withdraw_authority_info = next_account_info(account_info_iter)?; let stake_info = next_account_info(account_info_iter)?; let validator_stake_account_info = next_account_info(account_info_iter)?; let dest_user_info = next_account_info(account_info_iter)?; @@ -1406,8 +1468,12 @@ impl Processor { //Self::check_stake_activation(stake_info, clock, stake_history)?; - stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?; - stake_pool.check_authority_deposit(deposit_info.key, program_id, stake_pool_info.key)?; + stake_pool.check_authority_withdraw( + withdraw_authority_info.key, + program_id, + stake_pool_info.key, + )?; + stake_pool.check_deposit_authority(deposit_authority_info.key)?; stake_pool.check_mint(pool_mint_info)?; if stake_pool.token_program_id != *token_program_info.key { @@ -1451,34 +1517,33 @@ impl Processor { validator_stake_account_info.lamports() ); - Self::stake_authorize( - stake_pool_info.key, - stake_info.clone(), - deposit_info.clone(), - AUTHORITY_DEPOSIT, - stake_pool.deposit_bump_seed, - withdraw_info.key, - stake_program::StakeAuthorize::Withdrawer, - clock_info.clone(), - stake_program_info.clone(), - )?; - - Self::stake_authorize( - stake_pool_info.key, - stake_info.clone(), - deposit_info.clone(), - AUTHORITY_DEPOSIT, - stake_pool.deposit_bump_seed, - withdraw_info.key, - stake_program::StakeAuthorize::Staker, - clock_info.clone(), - stake_program_info.clone(), - )?; + let (deposit_authority_program_address, deposit_bump_seed) = + find_deposit_authority_program_address(program_id, stake_pool_info.key); + if *deposit_authority_info.key == deposit_authority_program_address { + Self::stake_authorize_signed( + stake_pool_info.key, + stake_info.clone(), + deposit_authority_info.clone(), + AUTHORITY_DEPOSIT, + deposit_bump_seed, + withdraw_authority_info.key, + clock_info.clone(), + stake_program_info.clone(), + )?; + } else { + Self::stake_authorize( + stake_info.clone(), + deposit_authority_info.clone(), + withdraw_authority_info.key, + clock_info.clone(), + stake_program_info.clone(), + )?; + } Self::stake_merge( stake_pool_info.key, stake_info.clone(), - withdraw_info.clone(), + withdraw_authority_info.clone(), AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, validator_stake_account_info.clone(), @@ -1492,7 +1557,7 @@ impl Processor { token_program_info.clone(), pool_mint_info.clone(), dest_user_info.clone(), - withdraw_info.clone(), + withdraw_authority_info.clone(), AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, new_pool_tokens, @@ -1530,7 +1595,7 @@ impl Processor { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; let validator_list_info = next_account_info(account_info_iter)?; - let withdraw_info = next_account_info(account_info_iter)?; + let withdraw_authority_info = next_account_info(account_info_iter)?; let stake_split_from = next_account_info(account_info_iter)?; let stake_split_to = next_account_info(account_info_iter)?; let user_stake_authority = next_account_info(account_info_iter)?; @@ -1550,8 +1615,12 @@ impl Processor { return Err(StakePoolError::InvalidState.into()); } - stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?; stake_pool.check_mint(pool_mint_info)?; + stake_pool.check_authority_withdraw( + withdraw_authority_info.key, + program_id, + stake_pool_info.key, + )?; if stake_pool.token_program_id != *token_program_info.key { return Err(ProgramError::IncorrectProgramId); @@ -1601,7 +1670,7 @@ impl Processor { token_program_info.clone(), burn_from_info.clone(), pool_mint_info.clone(), - withdraw_info.clone(), + withdraw_authority_info.clone(), AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, pool_tokens, @@ -1610,33 +1679,20 @@ impl Processor { Self::stake_split( stake_pool_info.key, stake_split_from.clone(), - withdraw_info.clone(), + withdraw_authority_info.clone(), AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, withdraw_lamports, stake_split_to.clone(), )?; - Self::stake_authorize( + Self::stake_authorize_signed( stake_pool_info.key, stake_split_to.clone(), - withdraw_info.clone(), - AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, - user_stake_authority.key, - stake_program::StakeAuthorize::Withdrawer, - clock_info.clone(), - stake_program_info.clone(), - )?; - - Self::stake_authorize( - stake_pool_info.key, - stake_split_to.clone(), - withdraw_info.clone(), + withdraw_authority_info.clone(), AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, user_stake_authority.key, - stake_program::StakeAuthorize::Staker, clock_info.clone(), stake_program_info.clone(), )?; diff --git a/program/src/state.rs b/program/src/state.rs index 94f1e317..31d8e9b2 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -39,9 +39,16 @@ pub struct StakePool { /// distribution pub staker: Pubkey, - /// Deposit authority bump seed - /// for `create_program_address(&[state::StakePool account, "deposit"])` - pub deposit_bump_seed: u8, + /// Deposit authority + /// + /// If a depositor pubkey is specified on initialization, then deposits must be + /// signed by this authority. If no deposit authority is specified, + /// then the stake pool will default to the result of: + /// `Pubkey::find_program_address( + /// &[&stake_pool_address.to_bytes()[..32], b"deposit"], + /// program_id, + /// )` + pub deposit_authority: Pubkey, /// Withdrawal authority bump seed /// for `create_program_address(&[state::StakePool account, "withdrawal"])` @@ -165,19 +172,15 @@ impl StakePool { ) } /// Checks that the deposit authority is valid - pub(crate) fn check_authority_deposit( + pub(crate) fn check_deposit_authority( &self, deposit_authority: &Pubkey, - program_id: &Pubkey, - stake_pool_address: &Pubkey, ) -> Result<(), ProgramError> { - Self::check_authority( - deposit_authority, - program_id, - stake_pool_address, - crate::AUTHORITY_DEPOSIT, - self.deposit_bump_seed, - ) + if self.deposit_authority == *deposit_authority { + Ok(()) + } else { + Err(StakePoolError::InvalidProgramAddress.into()) + } } /// Check staker validity and signature diff --git a/program/tests/decrease.rs b/program/tests/decrease.rs index c1a31fce..73c63133 100644 --- a/program/tests/decrease.rs +++ b/program/tests/decrease.rs @@ -233,10 +233,7 @@ async fn fail_with_unknown_validator() { decrease_lamports, ) = setup().await; - let unknown_stake = ValidatorStakeAccount::new_with_target_authority( - &stake_pool_accounts.deposit_authority, - &stake_pool_accounts.stake_pool.pubkey(), - ); + let unknown_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey()); unknown_stake .create_and_delegate( &mut banks_client, diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index a202e8d0..d19a9144 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -102,28 +102,6 @@ async fn test_stake_pool_deposit() { ) .await; - // Change authority to the stake pool's deposit - authorize_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake.pubkey(), - &stake_authority, - &stake_pool_accounts.deposit_authority, - stake_program::StakeAuthorize::Withdrawer, - ) - .await; - authorize_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake.pubkey(), - &stake_authority, - &stake_pool_accounts.deposit_authority, - stake_program::StakeAuthorize::Staker, - ) - .await; - // make pool token account let user_pool_account = Keypair::new(); create_token_account( @@ -163,6 +141,7 @@ async fn test_stake_pool_deposit() { &user_stake.pubkey(), &user_pool_account.pubkey(), &validator_stake_account.stake_account, + &stake_authority, ) .await .unwrap(); @@ -293,8 +272,8 @@ async fn test_stake_pool_deposit_with_wrong_token_program_id() { let user_stake = Keypair::new(); let lockup = stake_program::Lockup::default(); let authorized = stake_program::Authorized { - staker: stake_pool_accounts.deposit_authority, - withdrawer: stake_pool_accounts.deposit_authority, + staker: user.pubkey(), + withdrawer: user.pubkey(), }; create_independent_stake_account( &mut banks_client, @@ -323,22 +302,21 @@ async fn test_stake_pool_deposit_with_wrong_token_program_id() { let wrong_token_program = Keypair::new(); let mut transaction = Transaction::new_with_payer( - &[instruction::deposit( + &instruction::deposit( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.validator_list.pubkey(), - &stake_pool_accounts.deposit_authority, &stake_pool_accounts.withdraw_authority, &user_stake.pubkey(), + &user.pubkey(), &validator_stake_account.stake_account, &user_pool_account.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), &wrong_token_program.pubkey(), - ) - .unwrap()], + ), Some(&payer.pubkey()), ); - transaction.sign(&[&payer], recent_blockhash); + transaction.sign(&[&payer, &user], recent_blockhash); let transaction_error = banks_client .process_transaction(transaction) .await @@ -368,8 +346,8 @@ async fn test_stake_pool_deposit_with_wrong_validator_list_account() { let user_stake = Keypair::new(); let lockup = stake_program::Lockup::default(); let authorized = stake_program::Authorized { - staker: stake_pool_accounts.deposit_authority, - withdrawer: stake_pool_accounts.deposit_authority, + staker: user.pubkey(), + withdrawer: user.pubkey(), }; create_independent_stake_account( &mut banks_client, @@ -406,6 +384,7 @@ async fn test_stake_pool_deposit_with_wrong_validator_list_account() { &user_stake.pubkey(), &user_pool_account.pubkey(), &validator_stake_account.stake_account, + &user, ) .await .err() @@ -432,10 +411,8 @@ async fn test_stake_pool_deposit_to_unknown_validator() { .await .unwrap(); - let validator_stake_account = ValidatorStakeAccount::new_with_target_authority( - &stake_pool_accounts.deposit_authority, - &stake_pool_accounts.stake_pool.pubkey(), - ); + let validator_stake_account = + ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey()); validator_stake_account .create_and_delegate( &mut banks_client, @@ -462,8 +439,8 @@ async fn test_stake_pool_deposit_to_unknown_validator() { let user_stake = Keypair::new(); let lockup = stake_program::Lockup::default(); let authorized = stake_program::Authorized { - staker: stake_pool_accounts.deposit_authority, - withdrawer: stake_pool_accounts.deposit_authority, + staker: user.pubkey(), + withdrawer: user.pubkey(), }; create_independent_stake_account( &mut banks_client, @@ -484,6 +461,7 @@ async fn test_stake_pool_deposit_to_unknown_validator() { &user_stake.pubkey(), &user_pool_account.pubkey(), &validator_stake_account.stake_account, + &user, ) .await .err() @@ -504,7 +482,7 @@ async fn test_stake_pool_deposit_to_unknown_validator() { } #[tokio::test] -async fn test_stake_pool_deposit_with_wrong_deposit_authority() { +async fn test_stake_pool_deposit_with_wrong_withdraw_authority() { let ( mut banks_client, payer, @@ -518,8 +496,8 @@ async fn test_stake_pool_deposit_with_wrong_deposit_authority() { let user_stake = Keypair::new(); let lockup = stake_program::Lockup::default(); let authorized = stake_program::Authorized { - staker: stake_pool_accounts.deposit_authority, - withdrawer: stake_pool_accounts.deposit_authority, + staker: user.pubkey(), + withdrawer: user.pubkey(), }; create_independent_stake_account( &mut banks_client, @@ -545,7 +523,7 @@ async fn test_stake_pool_deposit_with_wrong_deposit_authority() { .await .unwrap(); - stake_pool_accounts.deposit_authority = Keypair::new().pubkey(); + stake_pool_accounts.withdraw_authority = Keypair::new().pubkey(); let transaction_error = stake_pool_accounts .deposit_stake( @@ -555,6 +533,7 @@ async fn test_stake_pool_deposit_with_wrong_deposit_authority() { &user_stake.pubkey(), &user_pool_account.pubkey(), &validator_stake_account.stake_account, + &user, ) .await .err() @@ -568,27 +547,22 @@ async fn test_stake_pool_deposit_with_wrong_deposit_authority() { let program_error = error::StakePoolError::InvalidProgramAddress as u32; assert_eq!(error_index, program_error); } - _ => panic!("Wrong error occurs while try to make a deposit with wrong deposit authority"), + _ => panic!("Wrong error occurs while try to make a deposit with wrong withdraw authority"), } } #[tokio::test] -async fn test_stake_pool_deposit_with_wrong_withdraw_authority() { - let ( - mut banks_client, - payer, - recent_blockhash, - mut stake_pool_accounts, - validator_stake_account, - ) = setup().await; +async fn test_stake_pool_deposit_with_wrong_mint_for_receiver_acc() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake_account) = + setup().await; - let user = Keypair::new(); // make stake account + let user = Keypair::new(); let user_stake = Keypair::new(); let lockup = stake_program::Lockup::default(); let authorized = stake_program::Authorized { - staker: stake_pool_accounts.deposit_authority, - withdrawer: stake_pool_accounts.deposit_authority, + staker: user.pubkey(), + withdrawer: user.pubkey(), }; create_independent_stake_account( &mut banks_client, @@ -601,20 +575,31 @@ async fn test_stake_pool_deposit_with_wrong_withdraw_authority() { ) .await; - // make pool token account - let user_pool_account = Keypair::new(); - create_token_account( + let outside_mint = Keypair::new(); + let outside_withdraw_auth = Keypair::new(); + let outside_manager = Keypair::new(); + let outside_pool_fee_acc = Keypair::new(); + + create_mint( &mut banks_client, &payer, &recent_blockhash, - &user_pool_account, - &stake_pool_accounts.pool_mint.pubkey(), - &user.pubkey(), + &outside_mint, + &outside_withdraw_auth.pubkey(), ) .await .unwrap(); - stake_pool_accounts.withdraw_authority = Keypair::new().pubkey(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &outside_pool_fee_acc, + &outside_mint.pubkey(), + &outside_manager.pubkey(), + ) + .await + .unwrap(); let transaction_error = stake_pool_accounts .deposit_stake( @@ -622,8 +607,9 @@ async fn test_stake_pool_deposit_with_wrong_withdraw_authority() { &payer, &recent_blockhash, &user_stake.pubkey(), - &user_pool_account.pubkey(), + &outside_pool_fee_acc.pubkey(), &validator_stake_account.stake_account, + &user, ) .await .err() @@ -634,27 +620,45 @@ async fn test_stake_pool_deposit_with_wrong_withdraw_authority() { _, InstructionError::Custom(error_index), )) => { - let program_error = error::StakePoolError::InvalidProgramAddress as u32; + let program_error = token_error::TokenError::MintMismatch as u32; assert_eq!(error_index, program_error); } - _ => panic!("Wrong error occurs while try to make a deposit with wrong withdraw authority"), + _ => panic!("Wrong error occurs while try to deposit with wrong mint fro receiver account"), } } #[tokio::test] -async fn test_stake_pool_deposit_with_wrong_set_deposit_authority() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake_account) = - setup().await; +async fn test_deposit_with_uninitialized_validator_list() {} // TODO + +#[tokio::test] +async fn test_deposit_with_out_of_dated_pool_balances() {} // TODO + +#[tokio::test] +async fn success_with_deposit_authority() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let deposit_authority = Keypair::new(); + let stake_pool_accounts = StakePoolAccounts::new_with_deposit_authority(deposit_authority); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .await + .unwrap(); + + let validator_stake_account = simple_add_validator_to_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + ) + .await; let user = Keypair::new(); - // make stake account let user_stake = Keypair::new(); let lockup = stake_program::Lockup::default(); let authorized = stake_program::Authorized { - staker: Keypair::new().pubkey(), - withdrawer: stake_pool_accounts.deposit_authority, + staker: user.pubkey(), + withdrawer: user.pubkey(), }; - create_independent_stake_account( + let _stake_lamports = create_independent_stake_account( &mut banks_client, &payer, &recent_blockhash, @@ -664,6 +668,25 @@ async fn test_stake_pool_deposit_with_wrong_set_deposit_authority() { TEST_STAKE_AMOUNT, ) .await; + + create_vote( + &mut banks_client, + &payer, + &recent_blockhash, + &validator_stake_account.validator, + &validator_stake_account.vote, + ) + .await; + delegate_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.pubkey(), + &user, + &validator_stake_account.vote.pubkey(), + ) + .await; + // make pool token account let user_pool_account = Keypair::new(); create_token_account( @@ -677,7 +700,7 @@ async fn test_stake_pool_deposit_with_wrong_set_deposit_authority() { .await .unwrap(); - let transaction_error = stake_pool_accounts + stake_pool_accounts .deposit_stake( &mut banks_client, &payer, @@ -685,34 +708,38 @@ async fn test_stake_pool_deposit_with_wrong_set_deposit_authority() { &user_stake.pubkey(), &user_pool_account.pubkey(), &validator_stake_account.stake_account, + &user, ) .await - .err() .unwrap(); - - match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { - assert_eq!(error, InstructionError::MissingRequiredSignature); - } - _ => { - panic!("Wrong error occurs while try to make deposit with wrong set deposit authority") - } - } } #[tokio::test] -async fn test_stake_pool_deposit_with_wrong_mint_for_receiver_acc() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake_account) = - setup().await; +async fn fail_without_deposit_authority_signature() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let deposit_authority = Keypair::new(); + let mut stake_pool_accounts = StakePoolAccounts::new_with_deposit_authority(deposit_authority); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .await + .unwrap(); - // make stake account + let validator_stake_account = simple_add_validator_to_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + ) + .await; + + let user = Keypair::new(); let user_stake = Keypair::new(); let lockup = stake_program::Lockup::default(); let authorized = stake_program::Authorized { - staker: stake_pool_accounts.deposit_authority, - withdrawer: stake_pool_accounts.deposit_authority, + staker: user.pubkey(), + withdrawer: user.pubkey(), }; - create_independent_stake_account( + let _stake_lamports = create_independent_stake_account( &mut banks_client, &payer, &recent_blockhash, @@ -723,59 +750,62 @@ async fn test_stake_pool_deposit_with_wrong_mint_for_receiver_acc() { ) .await; - let outside_mint = Keypair::new(); - let outside_withdraw_auth = Keypair::new(); - let outside_manager = Keypair::new(); - let outside_pool_fee_acc = Keypair::new(); - - create_mint( + create_vote( &mut banks_client, &payer, &recent_blockhash, - &outside_mint, - &outside_withdraw_auth.pubkey(), + &validator_stake_account.validator, + &validator_stake_account.vote, ) - .await - .unwrap(); + .await; + delegate_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.pubkey(), + &user, + &validator_stake_account.vote.pubkey(), + ) + .await; + // make pool token account + let user_pool_account = Keypair::new(); create_token_account( &mut banks_client, &payer, &recent_blockhash, - &outside_pool_fee_acc, - &outside_mint.pubkey(), - &outside_manager.pubkey(), + &user_pool_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user.pubkey(), ) .await .unwrap(); - let transaction_error = stake_pool_accounts + let wrong_depositor = Keypair::new(); + stake_pool_accounts.deposit_authority = wrong_depositor.pubkey(); + stake_pool_accounts.deposit_authority_keypair = Some(wrong_depositor); + + let error = stake_pool_accounts .deposit_stake( &mut banks_client, &payer, &recent_blockhash, &user_stake.pubkey(), - &outside_pool_fee_acc.pubkey(), + &user_pool_account.pubkey(), &validator_stake_account.stake_account, + &user, ) .await - .err() + .unwrap_err() .unwrap(); - match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError( - _, - InstructionError::Custom(error_index), - )) => { - let program_error = token_error::TokenError::MintMismatch as u32; - assert_eq!(error_index, program_error); + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + assert_eq!( + error_index, + error::StakePoolError::InvalidProgramAddress as u32 + ); } - _ => panic!("Wrong error occurs while try to deposit with wrong mint fro receiver account"), + _ => panic!("Wrong error occurs while try to make a deposit with wrong stake program ID"), } } - -#[tokio::test] -async fn test_deposit_with_uninitialized_validator_list() {} // TODO - -#[tokio::test] -async fn test_deposit_with_out_of_dated_pool_balances() {} // TODO diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 6bd6c769..1772a13e 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -210,6 +210,7 @@ pub async fn create_stake_pool( pool_token_account: &Pubkey, manager: &Keypair, staker: &Pubkey, + deposit_authority: &Option, fee: &state::Fee, max_validators: u32, ) -> Result<(), TransportError> { @@ -245,6 +246,7 @@ pub async fn create_stake_pool( pool_mint, pool_token_account, &spl_token::id(), + deposit_authority.as_ref().map(|k| k.pubkey()), *fee, max_validators, ) @@ -252,10 +254,11 @@ pub async fn create_stake_pool( ], Some(&payer.pubkey()), ); - transaction.sign( - &[payer, stake_pool, validator_list, manager], - *recent_blockhash, - ); + let mut signers = vec![payer, stake_pool, validator_list, manager]; + if let Some(deposit_authority) = deposit_authority.as_ref() { + signers.push(deposit_authority); + } + transaction.sign(&signers, *recent_blockhash); banks_client.process_transaction(transaction).await?; Ok(()) } @@ -424,14 +427,13 @@ pub async fn authorize_stake_account( pub struct ValidatorStakeAccount { pub stake_account: Pubkey, pub transient_stake_account: Pubkey, - pub target_authority: Pubkey, pub vote: Keypair, pub validator: Keypair, pub stake_pool: Pubkey, } impl ValidatorStakeAccount { - pub fn new_with_target_authority(authority: &Pubkey, stake_pool: &Pubkey) -> Self { + pub fn new(stake_pool: &Pubkey) -> Self { let validator = Keypair::new(); let vote = Keypair::new(); let (stake_account, _) = find_stake_program_address(&id(), &vote.pubkey(), stake_pool); @@ -440,7 +442,6 @@ impl ValidatorStakeAccount { ValidatorStakeAccount { stake_account, transient_stake_account, - target_authority: *authority, vote, validator, stake_pool: *stake_pool, @@ -473,28 +474,6 @@ impl ValidatorStakeAccount { &self.vote.pubkey(), ) .await; - - authorize_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &self.stake_account, - &staker, - &self.target_authority, - stake_program::StakeAuthorize::Staker, - ) - .await; - - authorize_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &self.stake_account, - &staker, - &self.target_authority, - stake_program::StakeAuthorize::Withdrawer, - ) - .await; } } @@ -508,6 +487,7 @@ pub struct StakePoolAccounts { pub staker: Keypair, pub withdraw_authority: Pubkey, pub deposit_authority: Pubkey, + pub deposit_authority_keypair: Option, pub fee: state::Fee, pub max_validators: u32, } @@ -541,6 +521,7 @@ impl StakePoolAccounts { staker, withdraw_authority, deposit_authority, + deposit_authority_keypair: None, fee: state::Fee { numerator: 1, denominator: 100, @@ -549,6 +530,13 @@ impl StakePoolAccounts { } } + pub fn new_with_deposit_authority(deposit_authority: Keypair) -> Self { + let mut stake_pool_accounts = Self::new(); + stake_pool_accounts.deposit_authority = deposit_authority.pubkey(); + stake_pool_accounts.deposit_authority_keypair = Some(deposit_authority); + stake_pool_accounts + } + pub fn calculate_fee(&self, amount: u64) -> u64 { amount * self.fee.numerator / self.fee.denominator } @@ -601,6 +589,7 @@ impl StakePoolAccounts { &self.pool_fee_account.pubkey(), &self.manager, &self.staker.pubkey(), + &self.deposit_authority_keypair, &self.fee, self.max_validators, ) @@ -608,6 +597,7 @@ impl StakePoolAccounts { Ok(()) } + #[allow(clippy::too_many_arguments)] pub async fn deposit_stake( &self, banks_client: &mut BanksClient, @@ -616,23 +606,43 @@ impl StakePoolAccounts { stake: &Pubkey, pool_account: &Pubkey, validator_stake_account: &Pubkey, + current_staker: &Keypair, ) -> Result<(), TransportError> { - let transaction = Transaction::new_signed_with_payer( - &[instruction::deposit( + let mut signers = vec![payer, current_staker]; + let instructions = if let Some(deposit_authority) = self.deposit_authority_keypair.as_ref() + { + signers.push(deposit_authority); + instruction::deposit_with_authority( &id(), &self.stake_pool.pubkey(), &self.validator_list.pubkey(), &self.deposit_authority, &self.withdraw_authority, stake, + ¤t_staker.pubkey(), validator_stake_account, pool_account, &self.pool_mint.pubkey(), &spl_token::id(), ) - .unwrap()], + } else { + instruction::deposit( + &id(), + &self.stake_pool.pubkey(), + &self.validator_list.pubkey(), + &self.withdraw_authority, + stake, + ¤t_staker.pubkey(), + validator_stake_account, + pool_account, + &self.pool_mint.pubkey(), + &spl_token::id(), + ) + }; + let transaction = Transaction::new_signed_with_payer( + &instructions, Some(&payer.pubkey()), - &[payer], + &signers, *recent_blockhash, ); banks_client.process_transaction(transaction).await?; @@ -771,7 +781,6 @@ impl StakePoolAccounts { &id(), &self.stake_pool.pubkey(), &self.staker.pubkey(), - &self.deposit_authority, &self.withdraw_authority, &self.validator_list.pubkey(), stake, @@ -874,10 +883,7 @@ pub async fn simple_add_validator_to_pool( recent_blockhash: &Hash, stake_pool_accounts: &StakePoolAccounts, ) -> ValidatorStakeAccount { - let validator_stake = ValidatorStakeAccount::new_with_target_authority( - &stake_pool_accounts.deposit_authority, - &stake_pool_accounts.stake_pool.pubkey(), - ); + let validator_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey()); validator_stake .create_and_delegate( banks_client, @@ -970,26 +976,6 @@ impl DepositStakeAccount { recent_blockhash: &Hash, stake_pool_accounts: &StakePoolAccounts, ) { - authorize_stake_account( - banks_client, - payer, - recent_blockhash, - &self.stake.pubkey(), - &self.authority, - &stake_pool_accounts.deposit_authority, - stake_program::StakeAuthorize::Staker, - ) - .await; - authorize_stake_account( - banks_client, - &payer, - &recent_blockhash, - &self.stake.pubkey(), - &self.authority, - &stake_pool_accounts.deposit_authority, - stake_program::StakeAuthorize::Withdrawer, - ) - .await; // make pool token account create_token_account( banks_client, @@ -1010,6 +996,7 @@ impl DepositStakeAccount { &self.stake.pubkey(), &self.pool_account.pubkey(), &self.validator_stake_account, + &self.authority, ) .await .unwrap(); @@ -1052,26 +1039,6 @@ pub async fn simple_deposit( &vote_account, ) .await; - authorize_stake_account( - banks_client, - payer, - recent_blockhash, - &stake.pubkey(), - &authority, - &stake_pool_accounts.deposit_authority, - stake_program::StakeAuthorize::Staker, - ) - .await; - authorize_stake_account( - banks_client, - &payer, - &recent_blockhash, - &stake.pubkey(), - &authority, - &stake_pool_accounts.deposit_authority, - stake_program::StakeAuthorize::Withdrawer, - ) - .await; // make pool token account let pool_account = Keypair::new(); create_token_account( @@ -1094,6 +1061,7 @@ pub async fn simple_deposit( &stake.pubkey(), &pool_account.pubkey(), &validator_stake_account, + &authority, ) .await .unwrap(); diff --git a/program/tests/increase.rs b/program/tests/increase.rs index 3a540348..3e155e73 100644 --- a/program/tests/increase.rs +++ b/program/tests/increase.rs @@ -233,10 +233,7 @@ async fn fail_with_unknown_validator() { reserve_lamports, ) = setup().await; - let unknown_stake = ValidatorStakeAccount::new_with_target_authority( - &stake_pool_accounts.deposit_authority, - &stake_pool_accounts.stake_pool.pubkey(), - ); + let unknown_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey()); unknown_stake .create_and_delegate( &mut banks_client, diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index 44d47a2d..3539a327 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -3,7 +3,7 @@ mod helpers; use { - borsh::BorshSerialize, + borsh::{BorshDeserialize, BorshSerialize}, helpers::*, solana_program::{ borsh::get_packed_len, @@ -226,6 +226,7 @@ async fn fail_with_wrong_max_validators() { &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), &spl_token::id(), + None, stake_pool_accounts.fee, stake_pool_accounts.max_validators, ) @@ -296,6 +297,7 @@ async fn fail_with_wrong_mint_authority() { &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.manager, &stake_pool_accounts.staker.pubkey(), + &None, &stake_pool_accounts.fee, stake_pool_accounts.max_validators, ) @@ -384,6 +386,7 @@ async fn fail_with_wrong_token_program_id() { &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), &wrong_token_program.pubkey(), + None, stake_pool_accounts.fee, stake_pool_accounts.max_validators, ) @@ -460,6 +463,7 @@ async fn fail_with_wrong_fee_account() { &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.manager, &stake_pool_accounts.staker.pubkey(), + &None, &stake_pool_accounts.fee, stake_pool_accounts.max_validators, ) @@ -547,6 +551,7 @@ async fn fail_with_not_rent_exempt_pool() { &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), &spl_token::id(), + None, stake_pool_accounts.fee, stake_pool_accounts.max_validators, ) @@ -621,6 +626,7 @@ async fn fail_with_not_rent_exempt_validator_list() { &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), &spl_token::id(), + None, stake_pool_accounts.fee, stake_pool_accounts.max_validators, ) @@ -793,6 +799,7 @@ async fn fail_with_pre_minted_pool_tokens() { &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.manager, &stake_pool_accounts.staker.pubkey(), + &None, &stake_pool_accounts.fee, stake_pool_accounts.max_validators, ) @@ -853,6 +860,7 @@ async fn fail_with_bad_reserve() { &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.manager, &stake_pool_accounts.staker.pubkey(), + &None, &stake_pool_accounts.fee, stake_pool_accounts.max_validators, ) @@ -897,6 +905,7 @@ async fn fail_with_bad_reserve() { &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.manager, &stake_pool_accounts.staker.pubkey(), + &None, &stake_pool_accounts.fee, stake_pool_accounts.max_validators, ) @@ -944,6 +953,7 @@ async fn fail_with_bad_reserve() { &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.manager, &stake_pool_accounts.staker.pubkey(), + &None, &stake_pool_accounts.fee, stake_pool_accounts.max_validators, ) @@ -991,6 +1001,7 @@ async fn fail_with_bad_reserve() { &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.manager, &stake_pool_accounts.staker.pubkey(), + &None, &stake_pool_accounts.fee, stake_pool_accounts.max_validators, ) @@ -1008,3 +1019,23 @@ async fn fail_with_bad_reserve() { ); } } + +#[tokio::test] +async fn success_with_required_deposit_authority() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let deposit_authority = Keypair::new(); + let stake_pool_accounts = StakePoolAccounts::new_with_deposit_authority(deposit_authority); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .await + .unwrap(); + + // Stake pool now exists + let stake_pool_account = + get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; + let stake_pool = state::StakePool::try_from_slice(stake_pool_account.data.as_slice()).unwrap(); + assert_eq!( + stake_pool.deposit_authority, + stake_pool_accounts.deposit_authority + ); +} diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index 460b72ac..cb011408 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -66,10 +66,7 @@ async fn setup( let mut stake_accounts: Vec = vec![]; let mut deposit_accounts: Vec = vec![]; for _ in 0..num_validators { - let stake_account = ValidatorStakeAccount::new_with_target_authority( - &stake_pool_accounts.deposit_authority, - &stake_pool_accounts.stake_pool.pubkey(), - ); + let stake_account = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey()); stake_account .create_and_delegate( &mut context.banks_client, diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index 535b6df7..d577480d 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -38,10 +38,7 @@ async fn setup() -> ( .await .unwrap(); - let user_stake = ValidatorStakeAccount::new_with_target_authority( - &stake_pool_accounts.deposit_authority, - &stake_pool_accounts.stake_pool.pubkey(), - ); + let user_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey()); user_stake .create_and_delegate( &mut banks_client, @@ -126,7 +123,6 @@ async fn fail_with_wrong_validator_list_account() { &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.staker.pubkey(), - &stake_pool_accounts.deposit_authority, &stake_pool_accounts.withdraw_authority, &wrong_validator_list.pubkey(), &user_stake.stake_account, @@ -162,10 +158,7 @@ async fn fail_too_little_stake() { .await .unwrap(); - let user_stake = ValidatorStakeAccount::new_with_target_authority( - &stake_pool_accounts.deposit_authority, - &stake_pool_accounts.stake_pool.pubkey(), - ); + let user_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey()); create_vote( &mut banks_client, &payer, @@ -203,28 +196,6 @@ async fn fail_too_little_stake() { banks_client.process_transaction(transaction).await.unwrap(); - authorize_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake.stake_account, - &stake_pool_accounts.staker, - &user_stake.target_authority, - stake_program::StakeAuthorize::Staker, - ) - .await; - - authorize_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake.stake_account, - &stake_pool_accounts.staker, - &user_stake.target_authority, - stake_program::StakeAuthorize::Withdrawer, - ) - .await; - let error = stake_pool_accounts .add_validator_to_pool( &mut banks_client, @@ -253,10 +224,7 @@ async fn fail_too_much_stake() { .await .unwrap(); - let user_stake = ValidatorStakeAccount::new_with_target_authority( - &stake_pool_accounts.deposit_authority, - &stake_pool_accounts.stake_pool.pubkey(), - ); + let user_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey()); user_stake .create_and_delegate( &mut banks_client, @@ -344,7 +312,6 @@ async fn fail_wrong_staker() { &id(), &stake_pool_accounts.stake_pool.pubkey(), &malicious.pubkey(), - &stake_pool_accounts.deposit_authority, &stake_pool_accounts.withdraw_authority, &stake_pool_accounts.validator_list.pubkey(), &user_stake.stake_account, @@ -379,7 +346,6 @@ async fn fail_without_signature() { let accounts = vec![ AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), AccountMeta::new_readonly(stake_pool_accounts.staker.pubkey(), false), - AccountMeta::new_readonly(stake_pool_accounts.deposit_authority, false), AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false), AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false), AccountMeta::new(user_stake.stake_account, false), @@ -425,7 +391,6 @@ async fn fail_with_wrong_stake_program_id() { let accounts = vec![ AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), AccountMeta::new_readonly(stake_pool_accounts.staker.pubkey(), true), - AccountMeta::new_readonly(stake_pool_accounts.deposit_authority, false), AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false), AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false), AccountMeta::new(user_stake.stake_account, false), @@ -468,10 +433,7 @@ async fn fail_add_too_many_validator_stake_accounts() { .await .unwrap(); - let user_stake = ValidatorStakeAccount::new_with_target_authority( - &stake_pool_accounts.deposit_authority, - &stake_pool_accounts.stake_pool.pubkey(), - ); + let user_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey()); user_stake .create_and_delegate( &mut banks_client, @@ -491,10 +453,7 @@ async fn fail_add_too_many_validator_stake_accounts() { .await; assert!(error.is_none()); - let user_stake = ValidatorStakeAccount::new_with_target_authority( - &stake_pool_accounts.deposit_authority, - &stake_pool_accounts.stake_pool.pubkey(), - ); + let user_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey()); user_stake .create_and_delegate( &mut banks_client, diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 8f89ef95..161d432d 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -38,10 +38,7 @@ async fn setup() -> ( .await .unwrap(); - let user_stake = ValidatorStakeAccount::new_with_target_authority( - &stake_pool_accounts.deposit_authority, - &stake_pool_accounts.stake_pool.pubkey(), - ); + let user_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey()); user_stake .create_and_delegate( &mut banks_client, diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 6250fd1a..a2233b58 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -403,10 +403,8 @@ async fn fail_with_unknown_validator() { .await .unwrap(); - let validator_stake_account = ValidatorStakeAccount::new_with_target_authority( - &stake_pool_accounts.deposit_authority, - &stake_pool_accounts.stake_pool.pubkey(), - ); + let validator_stake_account = + ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey()); validator_stake_account .create_and_delegate( &mut banks_client, @@ -416,10 +414,7 @@ async fn fail_with_unknown_validator() { ) .await; - let user_stake = ValidatorStakeAccount::new_with_target_authority( - &stake_pool_accounts.deposit_authority, - &stake_pool_accounts.stake_pool.pubkey(), - ); + let user_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey()); user_stake .create_and_delegate( &mut banks_client, From cfede38ac934a384f0814467e739ea42388beefd Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Fri, 23 Apr 2021 12:31:36 -0700 Subject: [PATCH 0091/1076] Update SPL to Solana v1.6.6 --- clients/cli/Cargo.toml | 14 +++++++------- program/Cargo.toml | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 9964da78..3bcd2de1 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -12,13 +12,13 @@ version = "2.0.1" borsh = "0.8" clap = "2.33.3" serde_json = "1.0.62" -solana-account-decoder = "1.6.2" -solana-clap-utils = "1.6.2" -solana-cli-config = "1.6.2" -solana-client = "1.6.2" -solana-logger = "1.6.2" -solana-sdk = "1.6.2" -solana-program = "1.6.2" +solana-account-decoder = "1.6.6" +solana-clap-utils = "1.6.6" +solana-cli-config = "1.6.6" +solana-client = "1.6.6" +solana-logger = "1.6.6" +solana-sdk = "1.6.6" +solana-program = "1.6.6" spl-stake-pool = { path="../program", features = [ "no-entrypoint" ] } spl-token = { path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" diff --git a/program/Cargo.toml b/program/Cargo.toml index 48c909a7..78611c27 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -19,7 +19,7 @@ num-traits = "0.2" num_enum = "0.5.1" serde = "1.0.121" serde_derive = "1.0.103" -solana-program = "1.6.2" +solana-program = "1.6.6" spl-math = { path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-token = { path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" @@ -27,9 +27,9 @@ bincode = "1.3.1" [dev-dependencies] proptest = "0.10" -solana-program-test = "1.6.2" -solana-sdk = "1.6.2" -solana-vote-program = "1.6.2" +solana-program-test = "1.6.6" +solana-sdk = "1.6.6" +solana-vote-program = "1.6.6" [lib] crate-type = ["cdylib", "lib"] From a591fd76bb7a74aeb5a67edd9c13aa6524aee2de Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 23 Apr 2021 23:55:16 +0200 Subject: [PATCH 0092/1076] stake-pool: Add ability to withdraw from reserve if no stake available (#1627) --- program/src/processor.rs | 81 ++++++++++----- program/tests/withdraw.rs | 200 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 246 insertions(+), 35 deletions(-) diff --git a/program/src/processor.rs b/program/src/processor.rs index 53515cfd..b86502d0 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1640,30 +1640,59 @@ impl Processor { return Err(StakePoolError::InvalidState.into()); } - let (meta, stake) = get_stake_state(stake_split_from)?; - let vote_account_address = stake.delegation.voter_pubkey; - check_validator_stake_address( - program_id, - stake_pool_info.key, - stake_split_from.key, - &vote_account_address, - )?; - - let validator_list_item = validator_list - .find_mut(&vote_account_address) - .ok_or(StakePoolError::ValidatorNotFound)?; - let withdraw_lamports = stake_pool .calc_lamports_withdraw_amount(pool_tokens) .ok_or(StakePoolError::CalculationFailure)?; - let required_lamports = minimum_stake_lamports(&meta); - let current_lamports = **stake_split_from.lamports.borrow(); - let remaining_lamports = current_lamports.saturating_sub(withdraw_lamports); - if remaining_lamports < required_lamports { - msg!("Attempting to withdraw {} lamports from validator account with {} lamports, {} must remain", withdraw_lamports, current_lamports, required_lamports); - return Err(StakePoolError::StakeLamportsNotEqualToMinimum.into()); - } + let validator_list_item = if *stake_split_from.key == stake_pool.reserve_stake { + // check that the validator stake accounts have no withdrawable stake + if let Some(withdrawable_entry) = validator_list + .validators + .iter() + .find(|&&x| x.stake_lamports != 0) + { + let (validator_stake_address, _) = crate::find_stake_program_address( + &program_id, + &withdrawable_entry.vote_account_address, + stake_pool_info.key, + ); + msg!("Error withdrawing from reserve: validator stake account {} has {} lamports available, please use that first.", validator_stake_address, withdrawable_entry.stake_lamports); + return Err(StakePoolError::StakeLamportsNotEqualToMinimum.into()); + } + + // check that reserve has enough (should never fail, but who knows?) + let stake_state = try_from_slice_unchecked::( + &stake_split_from.data.borrow(), + )?; + let meta = stake_state.meta().ok_or(StakePoolError::WrongStakeState)?; + stake_split_from + .lamports() + .checked_sub(minimum_reserve_lamports(&meta)) + .ok_or(StakePoolError::StakeLamportsNotEqualToMinimum)?; + None + } else { + let (meta, stake) = get_stake_state(stake_split_from)?; + let vote_account_address = stake.delegation.voter_pubkey; + check_validator_stake_address( + program_id, + stake_pool_info.key, + stake_split_from.key, + &vote_account_address, + )?; + + let validator_list_item = validator_list + .find_mut(&vote_account_address) + .ok_or(StakePoolError::ValidatorNotFound)?; + + let required_lamports = minimum_stake_lamports(&meta); + let current_lamports = stake_split_from.lamports(); + let remaining_lamports = current_lamports.saturating_sub(withdraw_lamports); + if remaining_lamports < required_lamports { + msg!("Attempting to withdraw {} lamports from validator account with {} lamports, {} must remain", withdraw_lamports, current_lamports, required_lamports); + return Err(StakePoolError::StakeLamportsNotEqualToMinimum.into()); + } + Some(validator_list_item) + }; Self::token_burn( stake_pool_info.key, @@ -1707,11 +1736,13 @@ impl Processor { .ok_or(StakePoolError::CalculationFailure)?; stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; - validator_list_item.stake_lamports = validator_list_item - .stake_lamports - .checked_sub(withdraw_lamports) - .ok_or(StakePoolError::CalculationFailure)?; - validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; + if let Some(validator_list_item) = validator_list_item { + validator_list_item.stake_lamports = validator_list_item + .stake_lamports + .checked_sub(withdraw_lamports) + .ok_or(StakePoolError::CalculationFailure)?; + validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; + } Ok(()) } diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index a2233b58..29262e1b 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -396,12 +396,7 @@ async fn fail_with_wrong_validator_list() { #[tokio::test] async fn fail_with_unknown_validator() { - let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); - stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) - .await - .unwrap(); + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, _, _, _) = setup().await; let validator_stake_account = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey()); @@ -502,13 +497,11 @@ async fn fail_with_unknown_validator() { tokens_to_burn, ) .await + .unwrap() .unwrap(); match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError( - _, - InstructionError::Custom(error_index), - )) => { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { let program_error = StakePoolError::ValidatorNotFound as u32; assert_eq!(error_index, program_error); } @@ -790,3 +783,190 @@ async fn fail_overdraw_validator() { ), ); } + +#[tokio::test] +async fn success_with_reserve() { + let mut context = program_test().start_with_context().await; + let stake_pool_accounts = StakePoolAccounts::new(); + let initial_reserve_lamports = 1; + stake_pool_accounts + .initialize_stake_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + initial_reserve_lamports, + ) + .await + .unwrap(); + + let validator_stake = simple_add_validator_to_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + ) + .await; + + let deposit_lamports = TEST_STAKE_AMOUNT; + let rent = context.banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + + let deposit_info = simple_deposit( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + &validator_stake, + deposit_lamports, + ) + .await; + + // decrease some stake + let error = stake_pool_accounts + .decrease_validator_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &validator_stake.stake_account, + &validator_stake.transient_stake_account, + deposit_lamports - 1, + ) + .await; + assert!(error.is_none()); + + // warp forward to deactivation + let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + context + .warp_to_slot(first_normal_slot + slots_per_epoch) + .unwrap(); + + // update to merge deactivated stake into reserve + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &[validator_stake.vote.pubkey()], + false, + ) + .await; + + // Delegate tokens for burning during withdraw + delegate_tokens( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &deposit_info.pool_account.pubkey(), + &deposit_info.authority, + &stake_pool_accounts.withdraw_authority, + deposit_info.pool_tokens, + ) + .await; + + // Withdraw directly from reserve, fail because some stake left + let withdraw_destination = Keypair::new(); + let withdraw_destination_authority = Pubkey::new_unique(); + let initial_stake_lamports = create_blank_stake_account( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &withdraw_destination, + ) + .await; + let error = stake_pool_accounts + .withdraw_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &withdraw_destination.pubkey(), + &deposit_info.pool_account.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), + &withdraw_destination_authority, + deposit_info.pool_tokens, + ) + .await + .unwrap() + .unwrap(); + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::StakeLamportsNotEqualToMinimum as u32) + ) + ); + + // decrease rest of stake + let error = stake_pool_accounts + .decrease_validator_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &validator_stake.stake_account, + &validator_stake.transient_stake_account, + stake_rent + 1, + ) + .await; + assert!(error.is_none()); + + // warp forward to deactivation + context + .warp_to_slot(first_normal_slot + 2 * slots_per_epoch) + .unwrap(); + + // update to merge deactivated stake into reserve + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &[validator_stake.vote.pubkey()], + false, + ) + .await; + + // now it works + let error = stake_pool_accounts + .withdraw_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &withdraw_destination.pubkey(), + &deposit_info.pool_account.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), + &withdraw_destination_authority, + deposit_info.pool_tokens, + ) + .await; + assert!(error.is_none()); + + // Check tokens burned + let user_token_balance = get_token_balance( + &mut context.banks_client, + &deposit_info.pool_account.pubkey(), + ) + .await; + assert_eq!(user_token_balance, 0); + + // Check reserve stake account balance + let reserve_stake_account = get_account( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + ) + .await; + let stake_state = + deserialize::(&reserve_stake_account.data).unwrap(); + let meta = stake_state.meta().unwrap(); + assert_eq!( + initial_reserve_lamports + meta.rent_exempt_reserve, + reserve_stake_account.lamports + ); + + // Check user recipient stake account balance + let user_stake_recipient_account = + get_account(&mut context.banks_client, &withdraw_destination.pubkey()).await; + assert_eq!( + user_stake_recipient_account.lamports, + initial_stake_lamports + deposit_info.stake_lamports + stake_rent + ); +} From 19467e7fd24d64bce19e91c659c07e67ea04b304 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 27 Apr 2021 13:24:39 +0200 Subject: [PATCH 0093/1076] stake-pool: Add ability to remove a validator that has deactivating transient stake (#1624) * Add status enum * Add ability to remove validator with transient stake * Only account validator stake if active * Fix merge conflicts --- program/src/instruction.rs | 2 +- program/src/processor.rs | 87 ++++++-- program/src/state.rs | 27 ++- program/tests/decrease.rs | 3 +- program/tests/helpers/mod.rs | 8 +- program/tests/increase.rs | 3 +- program/tests/update_stake_pool_balance.rs | 3 +- .../tests/update_validator_list_balance.rs | 139 ++++++++++++- program/tests/vsa_add.rs | 1 + program/tests/vsa_remove.rs | 191 ++++++++++++++---- program/tests/withdraw.rs | 12 +- 11 files changed, 407 insertions(+), 69 deletions(-) diff --git a/program/src/instruction.rs b/program/src/instruction.rs index ebf2bf52..1b4aa7b5 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -519,7 +519,7 @@ pub fn update_stake_pool_balance( let accounts = vec![ AccountMeta::new(*stake_pool, false), AccountMeta::new_readonly(*withdraw_authority, false), - AccountMeta::new_readonly(*validator_list_storage, false), + AccountMeta::new(*validator_list_storage, false), AccountMeta::new_readonly(*reserve_stake, false), AccountMeta::new(*manager_fee_account, false), AccountMeta::new(*stake_pool_mint, false), diff --git a/program/src/processor.rs b/program/src/processor.rs index b86502d0..74250272 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -7,7 +7,7 @@ use { find_deposit_authority_program_address, instruction::StakePoolInstruction, minimum_reserve_lamports, minimum_stake_lamports, stake_program, - state::{AccountType, Fee, StakePool, ValidatorList, ValidatorStakeInfo}, + state::{AccountType, Fee, StakePool, StakeStatus, ValidatorList, ValidatorStakeInfo}, AUTHORITY_DEPOSIT, AUTHORITY_WITHDRAW, MINIMUM_ACTIVE_STAKE, TRANSIENT_STAKE_SEED, }, borsh::{BorshDeserialize, BorshSerialize}, @@ -15,7 +15,7 @@ use { solana_program::{ account_info::next_account_info, account_info::AccountInfo, - clock::Clock, + clock::{Clock, Epoch}, decode_error::DecodeError, entrypoint::ProgramResult, msg, @@ -747,6 +747,7 @@ impl Processor { )?; validator_list.validators.push(ValidatorStakeInfo { + status: StakeStatus::Active, vote_account_address, stake_lamports: stake_lamports.saturating_sub(minimum_lamport_amount), last_update_epoch: clock.epoch, @@ -814,20 +815,16 @@ impl Processor { transient_stake_account_info.key, &vote_account_address, )?; - // check that the transient stake account doesn't exist - if get_stake_state(transient_stake_account_info).is_ok() { + + let maybe_validator_list_entry = validator_list.find_mut(&vote_account_address); + if maybe_validator_list_entry.is_none() { msg!( - "Transient stake {} exists, can't remove stake {} on validator {}", - transient_stake_account_info.key, - stake_account_info.key, + "Vote account {} not found in stake pool", vote_account_address ); - return Err(StakePoolError::WrongStakeState.into()); - } - - if !validator_list.contains(&vote_account_address) { return Err(StakePoolError::ValidatorNotFound.into()); } + let mut validator_list_entry = maybe_validator_list_entry.unwrap(); let stake_lamports = **stake_account_info.lamports.borrow(); let required_lamports = minimum_stake_lamports(&meta); @@ -840,6 +837,24 @@ impl Processor { return Err(StakePoolError::StakeLamportsNotEqualToMinimum.into()); } + // check that the transient stake account doesn't exist + let new_status = if let Ok((_meta, stake)) = get_stake_state(transient_stake_account_info) { + if stake.delegation.deactivation_epoch == Epoch::MAX { + msg!( + "Transient stake {} activating, can't remove stake {} on validator {}", + transient_stake_account_info.key, + stake_account_info.key, + vote_account_address + ); + return Err(StakePoolError::WrongStakeState.into()); + } else { + // stake is deactivating, mark the entry as such + StakeStatus::DeactivatingTransient + } + } else { + StakeStatus::ReadyForRemoval + }; + Self::stake_authorize_signed( stake_pool_info.key, stake_account_info.clone(), @@ -851,9 +866,13 @@ impl Processor { stake_program_info.clone(), )?; - validator_list - .validators - .retain(|item| item.vote_account_address != vote_account_address); + match new_status { + StakeStatus::DeactivatingTransient => validator_list_entry.status = new_status, + StakeStatus::ReadyForRemoval => validator_list + .validators + .retain(|item| item.vote_account_address != vote_account_address), + _ => unreachable!(), + } validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; Ok(()) @@ -1239,6 +1258,11 @@ impl Processor { stake_history_info.clone(), stake_program_info.clone(), )?; + if validator_stake_record.status == StakeStatus::DeactivatingTransient { + // the validator stake was previously removed, and + // now this entry can be removed totally + validator_stake_record.status = StakeStatus::ReadyForRemoval; + } } } Some(stake_program::StakeState::Stake(_, stake)) => { @@ -1257,6 +1281,11 @@ impl Processor { stake_history_info.clone(), stake_program_info.clone(), )?; + if validator_stake_record.status == StakeStatus::DeactivatingTransient { + // the validator stake was previously removed, and + // now this entry can be removed totally + validator_stake_record.status = StakeStatus::ReadyForRemoval; + } } else if stake.delegation.activation_epoch < clock.epoch { if let Some(stake_program::StakeState::Stake(_, validator_stake)) = validator_stake_state @@ -1298,15 +1327,19 @@ impl Processor { // * any other state / not a stake -> error state, but account for transient stake match validator_stake_state { Some(stake_program::StakeState::Stake(meta, _)) => { - stake_lamports += validator_stake_info - .lamports() - .saturating_sub(minimum_stake_lamports(&meta)); + if validator_stake_record.status == StakeStatus::Active { + stake_lamports += validator_stake_info + .lamports() + .saturating_sub(minimum_stake_lamports(&meta)); + } else { + msg!("Validator stake account no longer part of the pool, ignoring"); + } } Some(stake_program::StakeState::Initialized(_)) | Some(stake_program::StakeState::Uninitialized) | Some(stake_program::StakeState::RewardsPool) | None => { - msg!("Validator stake account no longer part of the pool, not considering"); + msg!("Validator stake account no longer part of the pool, ignoring"); } } @@ -1355,7 +1388,7 @@ impl Processor { return Err(ProgramError::IncorrectProgramId); } - let validator_list = + let mut validator_list = try_from_slice_unchecked::(&validator_list_info.data.borrow())?; if !validator_list.is_valid() { return Err(StakePoolError::InvalidState.into()); @@ -1375,7 +1408,7 @@ impl Processor { msg!("Reserve stake account in unknown state, aborting"); return Err(StakePoolError::WrongStakeState.into()); }; - for validator_stake_record in validator_list.validators { + for validator_stake_record in &validator_list.validators { if validator_stake_record.last_update_epoch < clock.epoch { return Err(StakePoolError::StakeListOutOfDate.into()); } @@ -1406,6 +1439,10 @@ impl Processor { .checked_add(fee) .ok_or(StakePoolError::CalculationFailure)?; } + validator_list + .validators + .retain(|item| item.status != StakeStatus::ReadyForRemoval); + validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; stake_pool.total_stake_lamports = total_stake_lamports; stake_pool.last_update_epoch = clock.epoch; stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; @@ -1507,6 +1544,11 @@ impl Processor { .find_mut(&vote_account_address) .ok_or(StakePoolError::ValidatorNotFound)?; + if validator_list_item.status != StakeStatus::Active { + msg!("Validator is marked for removal and no longer accepting deposits"); + return Err(StakePoolError::ValidatorNotFound.into()); + } + let stake_lamports = **stake_info.lamports.borrow(); let new_pool_tokens = stake_pool .calc_pool_tokens_for_deposit(stake_lamports) @@ -1684,6 +1726,11 @@ impl Processor { .find_mut(&vote_account_address) .ok_or(StakePoolError::ValidatorNotFound)?; + if validator_list_item.status != StakeStatus::Active { + msg!("Validator is marked for removal and no longer allowing withdrawals"); + return Err(StakePoolError::ValidatorNotFound.into()); + } + let required_lamports = minimum_stake_lamports(&meta); let current_lamports = stake_split_from.lamports(); let remaining_lamports = current_lamports.saturating_sub(withdraw_lamports); diff --git a/program/src/state.rs b/program/src/state.rs index 31d8e9b2..f7f5dc13 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -285,10 +285,32 @@ pub struct ValidatorList { pub validators: Vec, } +/// Status of the stake account in the validator list, for accounting +#[derive(Copy, Clone, Debug, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)] +pub enum StakeStatus { + /// Stake account is active, there may be a transient stake as well + Active, + /// Only transient stake account exists, when a transient stake is + /// deactivating during validator removal + DeactivatingTransient, + /// No more validator stake accounts exist, entry ready for removal during + /// `UpdateStakePoolBalance` + ReadyForRemoval, +} + +impl Default for StakeStatus { + fn default() -> Self { + Self::Active + } +} + /// Information about the singe validator stake account #[repr(C)] #[derive(Clone, Copy, Debug, Default, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)] pub struct ValidatorStakeInfo { + /// Status of the validator stake account + pub status: StakeStatus, + /// Validator vote account address pub vote_account_address: Pubkey, @@ -314,7 +336,7 @@ impl ValidatorList { /// Calculate the number of validator entries that fit in the provided length pub fn calculate_max_validators(buffer_length: usize) -> usize { let header_size = 1 + 4 + 4; - buffer_length.saturating_sub(header_size) / 48 + buffer_length.saturating_sub(header_size) / 49 } /// Check if contains validator with particular pubkey @@ -402,16 +424,19 @@ mod test { max_validators, validators: vec![ ValidatorStakeInfo { + status: StakeStatus::Active, vote_account_address: Pubkey::new_from_array([1; 32]), stake_lamports: 123456789, last_update_epoch: 987654321, }, ValidatorStakeInfo { + status: StakeStatus::DeactivatingTransient, vote_account_address: Pubkey::new_from_array([2; 32]), stake_lamports: 998877665544, last_update_epoch: 11223445566, }, ValidatorStakeInfo { + status: StakeStatus::ReadyForRemoval, vote_account_address: Pubkey::new_from_array([3; 32]), stake_lamports: 0, last_update_epoch: 999999999999999, diff --git a/program/tests/decrease.rs b/program/tests/decrease.rs index 73c63133..32585b31 100644 --- a/program/tests/decrease.rs +++ b/program/tests/decrease.rs @@ -49,7 +49,8 @@ async fn setup() -> ( &validator_stake_account, 100_000_000, ) - .await; + .await + .unwrap(); let lamports = deposit_info.stake_lamports / 2; diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 1772a13e..010fd29b 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -1010,7 +1010,7 @@ pub async fn simple_deposit( stake_pool_accounts: &StakePoolAccounts, validator_stake_account: &ValidatorStakeAccount, stake_lamports: u64, -) -> DepositStakeAccount { +) -> Option { let authority = Keypair::new(); // make stake account let stake = Keypair::new(); @@ -1064,11 +1064,11 @@ pub async fn simple_deposit( &authority, ) .await - .unwrap(); + .ok()?; let pool_tokens = get_token_balance(banks_client, &pool_account.pubkey()).await; - DepositStakeAccount { + Some(DepositStakeAccount { authority, stake, pool_account, @@ -1076,7 +1076,7 @@ pub async fn simple_deposit( pool_tokens, vote_account, validator_stake_account, - } + }) } pub async fn get_validator_list_sum( diff --git a/program/tests/increase.rs b/program/tests/increase.rs index 3e155e73..51942c27 100644 --- a/program/tests/increase.rs +++ b/program/tests/increase.rs @@ -54,7 +54,8 @@ async fn setup() -> ( &validator_stake_account, 5_000_000, ) - .await; + .await + .unwrap(); ( banks_client, diff --git a/program/tests/update_stake_pool_balance.rs b/program/tests/update_stake_pool_balance.rs index 33b29abe..bedb32fc 100644 --- a/program/tests/update_stake_pool_balance.rs +++ b/program/tests/update_stake_pool_balance.rs @@ -51,7 +51,8 @@ async fn setup() -> ( &validator_stake_account, TEST_STAKE_AMOUNT, ) - .await; + .await + .unwrap(); stake_accounts.push(validator_stake_account); } diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index cb011408..a6726261 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -9,7 +9,10 @@ use { solana_program_test::*, solana_sdk::signature::{Keypair, Signer}, spl_stake_pool::{ - stake_program, state::StakePool, MAX_VALIDATORS_TO_UPDATE, MINIMUM_ACTIVE_STAKE, + borsh::try_from_slice_unchecked, + stake_program, + state::{StakePool, StakeStatus, ValidatorList}, + MAX_VALIDATORS_TO_UPDATE, MINIMUM_ACTIVE_STAKE, }, }; @@ -474,7 +477,139 @@ async fn merge_into_validator_stake() { } #[tokio::test] -async fn max_validators() {} +#[ignore] +async fn merge_transient_stake_after_remove() { + let (mut context, stake_pool_accounts, stake_accounts, lamports, reserve_lamports, mut slot) = + setup(1).await; + + let rent = context.banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let deactivated_lamports = lamports + stake_rent; + let new_authority = Pubkey::new_unique(); + // Decrease and remove all validators + for stake_account in &stake_accounts { + let error = stake_pool_accounts + .decrease_validator_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_account.stake_account, + &stake_account.transient_stake_account, + deactivated_lamports, + ) + .await; + assert!(error.is_none()); + let error = stake_pool_accounts + .remove_validator_from_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &new_authority, + &stake_account.stake_account, + &stake_account.transient_stake_account, + ) + .await; + assert!(error.is_none()); + } + + // Warp forward to merge time + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + slot += slots_per_epoch; + context.warp_to_slot(slot).unwrap(); + + // Update without merge, status should be DeactivatingTransient + let error = stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + stake_accounts + .iter() + .map(|v| v.vote.pubkey()) + .collect::>() + .as_slice(), + true, + ) + .await; + assert!(error.is_none()); + + let validator_list = get_account( + &mut context.banks_client, + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + let validator_list = + try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); + assert_eq!(validator_list.validators.len(), 1); + assert_eq!( + validator_list.validators[0].status, + StakeStatus::DeactivatingTransient + ); + assert_eq!( + validator_list.validators[0].stake_lamports, + deactivated_lamports + ); + + // Update with merge, status should be ReadyForRemoval and no lamports + let error = stake_pool_accounts + .update_validator_list_balance( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + stake_accounts + .iter() + .map(|v| v.vote.pubkey()) + .collect::>() + .as_slice(), + false, + ) + .await; + assert!(error.is_none()); + + let validator_list = get_account( + &mut context.banks_client, + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + let validator_list = + try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); + assert_eq!(validator_list.validators.len(), 1); + assert_eq!( + validator_list.validators[0].status, + StakeStatus::ReadyForRemoval + ); + assert_eq!(validator_list.validators[0].stake_lamports, 0); + + let reserve_stake = context + .banks_client + .get_account(stake_pool_accounts.reserve_stake.pubkey()) + .await + .unwrap() + .unwrap(); + assert_eq!( + reserve_stake.lamports, + reserve_lamports + deactivated_lamports + stake_rent + 1 + ); + + // Update stake pool balance, should be gone + let error = stake_pool_accounts + .update_stake_pool_balance( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; + assert!(error.is_none()); + + let validator_list = get_account( + &mut context.banks_client, + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + let validator_list = + try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); + assert_eq!(validator_list.validators.len(), 0); +} #[tokio::test] async fn fail_with_uninitialized_validator_list() {} // TODO diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index d577480d..c5bc7879 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -86,6 +86,7 @@ async fn success() { account_type: state::AccountType::ValidatorList, max_validators: stake_pool_accounts.max_validators, validators: vec![state::ValidatorStakeInfo { + status: state::StakeStatus::Active, vote_account_address: user_stake.vote.pubkey(), last_update_epoch: 0, stake_lamports: 0, diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 161d432d..aafa0d2b 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -38,8 +38,8 @@ async fn setup() -> ( .await .unwrap(); - let user_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey()); - user_stake + let validator_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey()); + validator_stake .create_and_delegate( &mut banks_client, &payer, @@ -53,7 +53,7 @@ async fn setup() -> ( &mut banks_client, &payer, &recent_blockhash, - &user_stake.stake_account, + &validator_stake.stake_account, ) .await; assert!(error.is_none()); @@ -63,13 +63,13 @@ async fn setup() -> ( payer, recent_blockhash, stake_pool_accounts, - user_stake, + validator_stake, ) } #[tokio::test] async fn success() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = setup().await; let new_authority = Pubkey::new_unique(); @@ -79,8 +79,8 @@ async fn success() { &payer, &recent_blockhash, &new_authority, - &user_stake.stake_account, - &user_stake.transient_stake_account, + &validator_stake.stake_account, + &validator_stake.transient_stake_account, ) .await; assert!(error.is_none()); @@ -103,7 +103,7 @@ async fn success() { ); // Check of stake account authority has changed - let stake = get_account(&mut banks_client, &user_stake.stake_account).await; + let stake = get_account(&mut banks_client, &validator_stake.stake_account).await; let stake_state = deserialize::(&stake.data).unwrap(); match stake_state { stake_program::StakeState::Stake(meta, _) => { @@ -116,7 +116,7 @@ async fn success() { #[tokio::test] async fn fail_with_wrong_stake_program_id() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = setup().await; let wrong_stake_program = Pubkey::new_unique(); @@ -128,8 +128,8 @@ async fn fail_with_wrong_stake_program_id() { AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false), AccountMeta::new_readonly(new_authority, false), AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false), - AccountMeta::new(user_stake.stake_account, false), - AccountMeta::new_readonly(user_stake.transient_stake_account, false), + AccountMeta::new(validator_stake.stake_account, false), + AccountMeta::new_readonly(validator_stake.transient_stake_account, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(wrong_stake_program, false), ]; @@ -162,7 +162,7 @@ async fn fail_with_wrong_stake_program_id() { #[tokio::test] async fn fail_with_wrong_validator_list_account() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = setup().await; let wrong_validator_list = Keypair::new(); @@ -176,8 +176,8 @@ async fn fail_with_wrong_validator_list_account() { &stake_pool_accounts.withdraw_authority, &new_authority, &wrong_validator_list.pubkey(), - &user_stake.stake_account, - &user_stake.transient_stake_account, + &validator_stake.stake_account, + &validator_stake.transient_stake_account, ) .unwrap()], Some(&payer.pubkey()), @@ -203,14 +203,14 @@ async fn fail_with_wrong_validator_list_account() { #[tokio::test] async fn fail_not_at_minimum() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = setup().await; transfer( &mut banks_client, &payer, &recent_blockhash, - &user_stake.stake_account, + &validator_stake.stake_account, 1_000_001, ) .await; @@ -222,8 +222,8 @@ async fn fail_not_at_minimum() { &payer, &recent_blockhash, &new_authority, - &user_stake.stake_account, - &user_stake.transient_stake_account, + &validator_stake.stake_account, + &validator_stake.transient_stake_account, ) .await .unwrap() @@ -239,7 +239,7 @@ async fn fail_not_at_minimum() { #[tokio::test] async fn fail_double_remove() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = setup().await; let new_authority = Pubkey::new_unique(); @@ -249,8 +249,8 @@ async fn fail_double_remove() { &payer, &recent_blockhash, &new_authority, - &user_stake.stake_account, - &user_stake.transient_stake_account, + &validator_stake.stake_account, + &validator_stake.transient_stake_account, ) .await; assert!(error.is_none()); @@ -263,8 +263,8 @@ async fn fail_double_remove() { &payer, &latest_blockhash, &new_authority, - &user_stake.stake_account, - &user_stake.transient_stake_account, + &validator_stake.stake_account, + &validator_stake.transient_stake_account, ) .await .unwrap(); @@ -285,7 +285,7 @@ async fn fail_double_remove() { #[tokio::test] async fn fail_wrong_staker() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = setup().await; let malicious = Keypair::new(); @@ -299,8 +299,8 @@ async fn fail_wrong_staker() { &stake_pool_accounts.withdraw_authority, &new_authority, &stake_pool_accounts.validator_list.pubkey(), - &user_stake.stake_account, - &user_stake.transient_stake_account, + &validator_stake.stake_account, + &validator_stake.transient_stake_account, ) .unwrap()], Some(&payer.pubkey()), @@ -328,7 +328,7 @@ async fn fail_wrong_staker() { #[tokio::test] async fn fail_no_signature() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = setup().await; let new_authority = Pubkey::new_unique(); @@ -339,8 +339,8 @@ async fn fail_no_signature() { AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false), AccountMeta::new_readonly(new_authority, false), AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false), - AccountMeta::new(user_stake.stake_account, false), - AccountMeta::new_readonly(user_stake.transient_stake_account, false), + AccountMeta::new(validator_stake.stake_account, false), + AccountMeta::new_readonly(validator_stake.transient_stake_account, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(stake_program::id(), false), ]; @@ -378,7 +378,7 @@ async fn fail_no_signature() { #[tokio::test] async fn fail_with_activating_transient_stake() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = setup().await; // increase the validator stake @@ -387,8 +387,8 @@ async fn fail_with_activating_transient_stake() { &mut banks_client, &payer, &recent_blockhash, - &user_stake.transient_stake_account, - &user_stake.vote.pubkey(), + &validator_stake.transient_stake_account, + &validator_stake.vote.pubkey(), 2_000_000_000, ) .await; @@ -401,8 +401,8 @@ async fn fail_with_activating_transient_stake() { &payer, &recent_blockhash, &new_authority, - &user_stake.stake_account, - &user_stake.transient_stake_account, + &validator_stake.stake_account, + &validator_stake.transient_stake_account, ) .await .unwrap() @@ -419,6 +419,129 @@ async fn fail_with_activating_transient_stake() { } } +#[tokio::test] +async fn success_with_deactivating_transient_stake() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = + setup().await; + + let rent = banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let deposit_info = simple_deposit( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + &validator_stake, + TEST_STAKE_AMOUNT, + ) + .await + .unwrap(); + + // increase the validator stake + let error = stake_pool_accounts + .decrease_validator_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &validator_stake.stake_account, + &validator_stake.transient_stake_account, + TEST_STAKE_AMOUNT + stake_rent, + ) + .await; + assert!(error.is_none()); + + let new_authority = Pubkey::new_unique(); + let error = stake_pool_accounts + .remove_validator_from_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &new_authority, + &validator_stake.stake_account, + &validator_stake.transient_stake_account, + ) + .await; + assert!(error.is_none()); + + // fail deposit + let maybe_deposit = simple_deposit( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + &validator_stake, + TEST_STAKE_AMOUNT, + ) + .await; + assert!(maybe_deposit.is_none()); + + // fail withdraw + let user_stake_recipient = Keypair::new(); + create_blank_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake_recipient, + ) + .await; + + let new_authority = Pubkey::new_unique(); + let error = stake_pool_accounts + .withdraw_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake_recipient.pubkey(), + &deposit_info.pool_account.pubkey(), + &validator_stake.stake_account, + &new_authority, + 1, + ) + .await; + assert!(error.is_some()); + + // check validator has changed + let validator_list = get_account( + &mut banks_client, + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + let validator_list = + try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); + let expected_list = state::ValidatorList { + account_type: state::AccountType::ValidatorList, + max_validators: stake_pool_accounts.max_validators, + validators: vec![state::ValidatorStakeInfo { + status: state::StakeStatus::DeactivatingTransient, + vote_account_address: validator_stake.vote.pubkey(), + last_update_epoch: 0, + stake_lamports: TEST_STAKE_AMOUNT + stake_rent, + }], + }; + assert_eq!(validator_list, expected_list); + + // Update, should not change, no merges yet + let error = stake_pool_accounts + .update_all( + &mut banks_client, + &payer, + &recent_blockhash, + &[validator_stake.vote.pubkey()], + false, + ) + .await; + assert!(error.is_none()); + + let validator_list = get_account( + &mut banks_client, + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + let validator_list = + try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); + assert_eq!(validator_list, expected_list); +} + #[tokio::test] async fn fail_not_updated_stake_pool() {} // TODO diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 29262e1b..8d7a5eae 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -57,7 +57,8 @@ async fn setup() -> ( &validator_stake_account, TEST_STAKE_AMOUNT, ) - .await; + .await + .unwrap(); let tokens_to_burn = deposit_info.pool_tokens / 4; @@ -607,7 +608,8 @@ async fn fail_without_token_approval() { &validator_stake_account, TEST_STAKE_AMOUNT, ) - .await; + .await + .unwrap(); let tokens_to_burn = deposit_info.pool_tokens / 4; @@ -675,7 +677,8 @@ async fn fail_with_low_delegation() { &validator_stake_account, TEST_STAKE_AMOUNT, ) - .await; + .await + .unwrap(); let tokens_to_burn = deposit_info.pool_tokens / 4; @@ -819,7 +822,8 @@ async fn success_with_reserve() { &validator_stake, deposit_lamports, ) - .await; + .await + .unwrap(); // decrease some stake let error = stake_pool_accounts From ad19ca41314cbb6a03175a55fd3f6dfe0b159ed8 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 27 Apr 2021 14:53:46 +0200 Subject: [PATCH 0094/1076] stake-pool: Add user transfer authority on withdraw (#1640) The stake pool expects pool tokens to be delegated to the withdraw authority before performing a withdrawal. If a user delegates too many tokens to the withdraw authority, anyone else can take the rest of their tokens by doing their own withdrawal. Delegate pool tokens to an ephemeral keypair and sign with that. --- clients/cli/src/main.rs | 10 ++++-- program/src/instruction.rs | 23 ++++++++------ program/src/processor.rs | 23 +++----------- program/tests/helpers/mod.rs | 9 ++++-- program/tests/vsa_remove.rs | 12 ++++++++ program/tests/withdraw.rs | 60 ++++++++++++++++++++++++++++++------ 6 files changed, 94 insertions(+), 43 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 3532cb88..d5ce2a7c 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -877,7 +877,12 @@ fn command_withdraw( // Construct transaction to withdraw from withdraw_accounts account list let mut instructions: Vec = vec![]; - let mut signers = vec![config.fee_payer.as_ref(), config.token_owner.as_ref()]; + let user_transfer_authority = Keypair::new(); // ephemeral keypair just to do the transfer + let mut signers = vec![ + config.fee_payer.as_ref(), + config.token_owner.as_ref(), + &user_transfer_authority, + ]; let stake_receiver_account = Keypair::new(); // Will be added to signers if creating new account instructions.push( @@ -885,7 +890,7 @@ fn command_withdraw( spl_token::instruction::approve( &spl_token::id(), &withdraw_from, - &pool_withdraw_authority, + &user_transfer_authority.pubkey(), &config.token_owner.pubkey(), &[], pool_amount, @@ -948,6 +953,7 @@ fn command_withdraw( &withdraw_account.address, &stake_receiver.unwrap(), // Cannot be none at this point &config.staker.pubkey(), + &user_transfer_authority.pubkey(), &withdraw_from, &stake_pool.pool_mint, &spl_token::id(), diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 1b4aa7b5..48785a8e 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -225,12 +225,13 @@ pub enum StakePoolInstruction { /// 3. `[w]` Validator or reserve stake account to split /// 4. `[w]` Unitialized stake account to receive withdrawal /// 5. `[]` User account to set as a new withdraw authority - /// 6. `[w]` User account with pool tokens to burn from - /// 7. `[w]` Pool token mint account - /// 8. '[]' Sysvar clock account (required) - /// 9. `[]` Pool token program id - /// 10. `[]` Stake program id, - /// userdata: amount to withdraw + /// 6. `[s]` User transfer authority, for pool token account + /// 7. `[w]` User account with pool tokens to burn from + /// 8. `[w]` Pool token mint account + /// 9. `[]` Sysvar clock account (required) + /// 10. `[]` Pool token program id + /// 11. `[]` Stake program id, + /// userdata: amount of pool tokens to withdraw Withdraw(u64), /// (Manager only) Update manager @@ -645,8 +646,9 @@ pub fn withdraw( stake_pool_withdraw: &Pubkey, stake_to_split: &Pubkey, stake_to_receive: &Pubkey, - user_withdrawer: &Pubkey, - burn_from: &Pubkey, + user_stake_authority: &Pubkey, + user_transfer_authority: &Pubkey, + user_pool_token_account: &Pubkey, pool_mint: &Pubkey, token_program_id: &Pubkey, amount: u64, @@ -657,8 +659,9 @@ pub fn withdraw( AccountMeta::new_readonly(*stake_pool_withdraw, false), AccountMeta::new(*stake_to_split, false), AccountMeta::new(*stake_to_receive, false), - AccountMeta::new_readonly(*user_withdrawer, false), - AccountMeta::new(*burn_from, false), + AccountMeta::new_readonly(*user_stake_authority, false), + AccountMeta::new_readonly(*user_transfer_authority, true), + AccountMeta::new(*user_pool_token_account, false), AccountMeta::new(*pool_mint, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(*token_program_id, false), diff --git a/program/src/processor.rs b/program/src/processor.rs index 74250272..a95f3fa2 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -336,19 +336,12 @@ impl Processor { /// Issue a spl_token `Burn` instruction. #[allow(clippy::too_many_arguments)] fn token_burn<'a>( - stake_pool: &Pubkey, token_program: AccountInfo<'a>, burn_account: AccountInfo<'a>, mint: AccountInfo<'a>, authority: AccountInfo<'a>, - authority_type: &[u8], - bump_seed: u8, amount: u64, ) -> Result<(), ProgramError> { - let me_bytes = stake_pool.to_bytes(); - let authority_signature_seeds = [&me_bytes[..32], authority_type, &[bump_seed]]; - let signers = &[&authority_signature_seeds[..]]; - let ix = spl_token::instruction::burn( token_program.key, burn_account.key, @@ -358,11 +351,7 @@ impl Processor { amount, )?; - invoke_signed( - &ix, - &[burn_account, mint, authority, token_program], - signers, - ) + invoke(&ix, &[burn_account, mint, authority, token_program]) } /// Issue a spl_token `MintTo` instruction. @@ -1640,7 +1629,8 @@ impl Processor { let withdraw_authority_info = next_account_info(account_info_iter)?; let stake_split_from = next_account_info(account_info_iter)?; let stake_split_to = next_account_info(account_info_iter)?; - let user_stake_authority = next_account_info(account_info_iter)?; + let user_stake_authority_info = next_account_info(account_info_iter)?; + let user_transfer_authority_info = next_account_info(account_info_iter)?; let burn_from_info = next_account_info(account_info_iter)?; let pool_mint_info = next_account_info(account_info_iter)?; let clock_info = next_account_info(account_info_iter)?; @@ -1742,13 +1732,10 @@ impl Processor { }; Self::token_burn( - stake_pool_info.key, token_program_info.clone(), burn_from_info.clone(), pool_mint_info.clone(), - withdraw_authority_info.clone(), - AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, + user_transfer_authority_info.clone(), pool_tokens, )?; @@ -1768,7 +1755,7 @@ impl Processor { withdraw_authority_info.clone(), AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, - user_stake_authority.key, + user_stake_authority_info.key, clock_info.clone(), stake_program_info.clone(), )?; diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 010fd29b..80f4ea28 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -182,7 +182,7 @@ pub async fn delegate_tokens( delegate: &Pubkey, amount: u64, ) { - let mut transaction = Transaction::new_with_payer( + let transaction = Transaction::new_signed_with_payer( &[spl_token::instruction::approve( &spl_token::id(), &account, @@ -193,8 +193,9 @@ pub async fn delegate_tokens( ) .unwrap()], Some(&payer.pubkey()), + &[payer, manager], + *recent_blockhash, ); - transaction.sign(&[payer, manager], *recent_blockhash); banks_client.process_transaction(transaction).await.unwrap(); } @@ -656,6 +657,7 @@ impl StakePoolAccounts { payer: &Keypair, recent_blockhash: &Hash, stake_recipient: &Pubkey, + user_transfer_authority: &Keypair, pool_account: &Pubkey, validator_stake_account: &Pubkey, recipient_new_authority: &Pubkey, @@ -670,6 +672,7 @@ impl StakePoolAccounts { validator_stake_account, stake_recipient, recipient_new_authority, + &user_transfer_authority.pubkey(), pool_account, &self.pool_mint.pubkey(), &spl_token::id(), @@ -677,7 +680,7 @@ impl StakePoolAccounts { ) .unwrap()], Some(&payer.pubkey()), - &[payer], + &[payer, user_transfer_authority], *recent_blockhash, ); banks_client.process_transaction(transaction).await.err() diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index aafa0d2b..b0fdbd18 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -485,13 +485,25 @@ async fn success_with_deactivating_transient_stake() { ) .await; + let user_transfer_authority = Keypair::new(); let new_authority = Pubkey::new_unique(); + delegate_tokens( + &mut banks_client, + &payer, + &recent_blockhash, + &deposit_info.pool_account.pubkey(), + &deposit_info.authority, + &user_transfer_authority.pubkey(), + 1, + ) + .await; let error = stake_pool_accounts .withdraw_stake( &mut banks_client, &payer, &recent_blockhash, &user_stake_recipient.pubkey(), + &user_transfer_authority, &deposit_info.pool_account.pubkey(), &validator_stake.stake_account, &new_authority, diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 8d7a5eae..84b4d24d 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -32,6 +32,7 @@ async fn setup() -> ( StakePoolAccounts, ValidatorStakeAccount, DepositStakeAccount, + Keypair, u64, ) { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; @@ -63,13 +64,14 @@ async fn setup() -> ( let tokens_to_burn = deposit_info.pool_tokens / 4; // Delegate tokens for burning + let user_transfer_authority = Keypair::new(); delegate_tokens( &mut banks_client, &payer, &recent_blockhash, &deposit_info.pool_account.pubkey(), &deposit_info.authority, - &stake_pool_accounts.withdraw_authority, + &user_transfer_authority.pubkey(), tokens_to_burn, ) .await; @@ -81,6 +83,7 @@ async fn setup() -> ( stake_pool_accounts, validator_stake_account, deposit_info, + user_transfer_authority, tokens_to_burn, ) } @@ -94,6 +97,7 @@ async fn success() { stake_pool_accounts, validator_stake_account, deposit_info, + user_transfer_authority, tokens_to_burn, ) = setup().await; @@ -136,6 +140,7 @@ async fn success() { &payer, &recent_blockhash, &user_stake_recipient.pubkey(), + &user_transfer_authority, &deposit_info.pool_account.pubkey(), &validator_stake_account.stake_account, &new_authority, @@ -209,6 +214,7 @@ async fn fail_with_wrong_stake_program() { stake_pool_accounts, validator_stake_account, deposit_info, + user_transfer_authority, tokens_to_burn, ) = setup().await; @@ -225,6 +231,7 @@ async fn fail_with_wrong_stake_program() { AccountMeta::new(validator_stake_account.stake_account, false), AccountMeta::new(user_stake_recipient.pubkey(), false), AccountMeta::new_readonly(new_authority, false), + AccountMeta::new_readonly(user_transfer_authority.pubkey(), true), AccountMeta::new(deposit_info.pool_account.pubkey(), false), AccountMeta::new(stake_pool_accounts.pool_mint.pubkey(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), @@ -239,8 +246,12 @@ async fn fail_with_wrong_stake_program() { .unwrap(), }; - let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); - transaction.sign(&[&payer], recent_blockhash); + let transaction = Transaction::new_signed_with_payer( + &[instruction], + Some(&payer.pubkey()), + &[&payer, &user_transfer_authority], + recent_blockhash, + ); let transaction_error = banks_client .process_transaction(transaction) .await @@ -264,6 +275,7 @@ async fn fail_with_wrong_withdraw_authority() { mut stake_pool_accounts, validator_stake_account, deposit_info, + user_transfer_authority, tokens_to_burn, ) = setup().await; @@ -279,6 +291,7 @@ async fn fail_with_wrong_withdraw_authority() { &payer, &recent_blockhash, &user_stake_recipient.pubkey(), + &user_transfer_authority, &deposit_info.pool_account.pubkey(), &validator_stake_account.stake_account, &new_authority, @@ -308,6 +321,7 @@ async fn fail_with_wrong_token_program_id() { stake_pool_accounts, validator_stake_account, deposit_info, + user_transfer_authority, tokens_to_burn, ) = setup().await; @@ -317,7 +331,7 @@ async fn fail_with_wrong_token_program_id() { let new_authority = Pubkey::new_unique(); let wrong_token_program = Keypair::new(); - let mut transaction = Transaction::new_with_payer( + let transaction = Transaction::new_signed_with_payer( &[instruction::withdraw( &id(), &stake_pool_accounts.stake_pool.pubkey(), @@ -326,6 +340,7 @@ async fn fail_with_wrong_token_program_id() { &validator_stake_account.stake_account, &user_stake_recipient.pubkey(), &new_authority, + &user_transfer_authority.pubkey(), &deposit_info.pool_account.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), &wrong_token_program.pubkey(), @@ -333,8 +348,9 @@ async fn fail_with_wrong_token_program_id() { ) .unwrap()], Some(&payer.pubkey()), + &[&payer, &user_transfer_authority], + recent_blockhash, ); - transaction.sign(&[&payer], recent_blockhash); let transaction_error = banks_client .process_transaction(transaction) .await @@ -358,6 +374,7 @@ async fn fail_with_wrong_validator_list() { mut stake_pool_accounts, validator_stake_account, deposit_info, + user_transfer_authority, tokens_to_burn, ) = setup().await; @@ -373,6 +390,7 @@ async fn fail_with_wrong_validator_list() { &payer, &recent_blockhash, &user_stake_recipient.pubkey(), + &user_transfer_authority, &deposit_info.pool_account.pubkey(), &validator_stake_account.stake_account, &new_authority, @@ -397,7 +415,16 @@ async fn fail_with_wrong_validator_list() { #[tokio::test] async fn fail_with_unknown_validator() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, _, _, _) = setup().await; + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + _, + _, + user_transfer_authority, + _, + ) = setup().await; let validator_stake_account = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey()); @@ -476,7 +503,7 @@ async fn fail_with_unknown_validator() { &recent_blockhash, &user_pool_account, &user, - &stake_pool_accounts.withdraw_authority, + &user_transfer_authority.pubkey(), tokens_to_burn, ) .await; @@ -492,6 +519,7 @@ async fn fail_with_unknown_validator() { &payer, &recent_blockhash, &user_stake_recipient.pubkey(), + &user_transfer_authority, &user_pool_account, &validator_stake_account.stake_account, &new_authority, @@ -519,6 +547,7 @@ async fn fail_double_withdraw_to_the_same_account() { stake_pool_accounts, validator_stake_account, deposit_info, + user_transfer_authority, tokens_to_burn, ) = setup().await; @@ -539,6 +568,7 @@ async fn fail_double_withdraw_to_the_same_account() { &payer, &recent_blockhash, &user_stake_recipient.pubkey(), + &user_transfer_authority, &deposit_info.pool_account.pubkey(), &validator_stake_account.stake_account, &new_authority, @@ -556,7 +586,7 @@ async fn fail_double_withdraw_to_the_same_account() { &latest_blockhash, &deposit_info.pool_account.pubkey(), &deposit_info.authority, - &stake_pool_accounts.withdraw_authority, + &user_transfer_authority.pubkey(), tokens_to_burn, ) .await; @@ -567,6 +597,7 @@ async fn fail_double_withdraw_to_the_same_account() { &payer, &latest_blockhash, &user_stake_recipient.pubkey(), + &user_transfer_authority, &deposit_info.pool_account.pubkey(), &validator_stake_account.stake_account, &new_authority, @@ -624,12 +655,14 @@ async fn fail_without_token_approval() { .await; let new_authority = Pubkey::new_unique(); + let user_transfer_authority = Keypair::new(); let transaction_error = stake_pool_accounts .withdraw_stake( &mut banks_client, &payer, &recent_blockhash, &user_stake_recipient.pubkey(), + &user_transfer_authority, &deposit_info.pool_account.pubkey(), &validator_stake_account.stake_account, &new_authority, @@ -682,6 +715,7 @@ async fn fail_with_low_delegation() { let tokens_to_burn = deposit_info.pool_tokens / 4; + let user_transfer_authority = Keypair::new(); // Delegate tokens for burning delegate_tokens( &mut banks_client, @@ -689,7 +723,7 @@ async fn fail_with_low_delegation() { &recent_blockhash, &deposit_info.pool_account.pubkey(), &deposit_info.authority, - &stake_pool_accounts.withdraw_authority, + &user_transfer_authority.pubkey(), 1, ) .await; @@ -711,6 +745,7 @@ async fn fail_with_low_delegation() { &payer, &recent_blockhash, &user_stake_recipient.pubkey(), + &user_transfer_authority, &deposit_info.pool_account.pubkey(), &validator_stake_account.stake_account, &new_authority, @@ -742,6 +777,7 @@ async fn fail_overdraw_validator() { stake_pool_accounts, _validator_stake_account, deposit_info, + user_transfer_authority, tokens_to_burn, ) = setup().await; @@ -770,6 +806,7 @@ async fn fail_overdraw_validator() { &payer, &recent_blockhash, &user_stake_recipient.pubkey(), + &user_transfer_authority, &deposit_info.pool_account.pubkey(), &validator_stake_account.stake_account, &new_authority, @@ -857,13 +894,14 @@ async fn success_with_reserve() { .await; // Delegate tokens for burning during withdraw + let user_transfer_authority = Keypair::new(); delegate_tokens( &mut context.banks_client, &context.payer, &context.last_blockhash, &deposit_info.pool_account.pubkey(), &deposit_info.authority, - &stake_pool_accounts.withdraw_authority, + &user_transfer_authority.pubkey(), deposit_info.pool_tokens, ) .await; @@ -884,6 +922,7 @@ async fn success_with_reserve() { &context.payer, &context.last_blockhash, &withdraw_destination.pubkey(), + &user_transfer_authority, &deposit_info.pool_account.pubkey(), &stake_pool_accounts.reserve_stake.pubkey(), &withdraw_destination_authority, @@ -936,6 +975,7 @@ async fn success_with_reserve() { &context.payer, &context.last_blockhash, &withdraw_destination.pubkey(), + &user_transfer_authority, &deposit_info.pool_account.pubkey(), &stake_pool_accounts.reserve_stake.pubkey(), &withdraw_destination_authority, From 0ee0619d396a9efa723876c2e16ec8d2e5d3c62c Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Mon, 3 May 2021 11:47:24 +0200 Subject: [PATCH 0095/1076] stake-pool-cli: All sorts of fixes (#1650) While going back through the docs, I ended up doing a lot of the stake pool CLI items: * Deposit / withdraw command: Use associated token account by default * Create command: Allow passing the stake pool and mint keypair (useful for testing) * Create command: Split the transaction for pool creation (required to get under the transaction size limit) * Add / remove validator command: take a validator vote account rather than stake account, which makes integration from outside tools a lot simpler * Update command: add a `--force` flag to force the update * Update command: add a `--no-merge` flag to not merge while updating (useful to allow the pool to work, even if the transient stake accounts are unmergeable) * Withdraw: Add `--use-reserve` flag to withdraw from reserve * Withdraw: Add `--vote-account` arg to specify which validator to withdraw from --- clients/cli/Cargo.toml | 1 + clients/cli/src/main.rs | 398 +++++++++++++++++++++++++--------------- 2 files changed, 256 insertions(+), 143 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 3bcd2de1..95b21947 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -19,6 +19,7 @@ solana-client = "1.6.6" solana-logger = "1.6.6" solana-sdk = "1.6.6" solana-program = "1.6.6" +spl-associated-token-account = { path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { path="../program", features = [ "no-entrypoint" ] } spl-token = { path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index d5ce2a7c..a6418dd2 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -10,8 +10,10 @@ use { Arg, ArgGroup, SubCommand, }, solana_clap_utils::{ - input_parsers::pubkey_of, - input_validators::{is_amount, is_keypair, is_parsable, is_pubkey, is_url}, + input_parsers::{keypair_of, pubkey_of}, + input_validators::{ + is_amount, is_keypair, is_keypair_or_ask_keyword, is_parsable, is_pubkey, is_url, + }, keypair::signer_from_path, }, solana_client::rpc_client::RpcClient, @@ -25,6 +27,7 @@ use { system_instruction, transaction::Transaction, }, + spl_associated_token_account::{create_associated_token_account, get_associated_token_address}, spl_stake_pool::{ self, borsh::get_instance_packed_len, @@ -100,12 +103,14 @@ fn command_create_pool( deposit_authority: Option, fee: Fee, max_validators: u32, + stake_pool_keypair: Option, + mint_keypair: Option, ) -> CommandResult { let reserve_stake = Keypair::new(); println!("Creating reserve stake {}", reserve_stake.pubkey()); - let mint_account = Keypair::new(); - println!("Creating mint {}", mint_account.pubkey()); + let mint_keypair = mint_keypair.unwrap_or_else(Keypair::new); + println!("Creating mint {}", mint_keypair.pubkey()); let pool_fee_account = Keypair::new(); println!( @@ -113,8 +118,7 @@ fn command_create_pool( pool_fee_account.pubkey() ); - let stake_pool_keypair = Keypair::new(); - println!("Creating stake pool {}", stake_pool_keypair.pubkey()); + let stake_pool_keypair = stake_pool_keypair.unwrap_or_else(Keypair::new); let validator_list = Keypair::new(); @@ -154,7 +158,7 @@ fn command_create_pool( println!("Stake pool withdraw authority {}", withdraw_authority); } - let mut transaction = Transaction::new_with_payer( + let mut setup_transaction = Transaction::new_with_payer( &[ // Account for the stake pool reserve system_instruction::create_account( @@ -175,7 +179,7 @@ fn command_create_pool( // Account for the stake pool mint system_instruction::create_account( &config.fee_payer.pubkey(), - &mint_account.pubkey(), + &mint_keypair.pubkey(), mint_account_balance, spl_token::state::Mint::LEN as u64, &spl_token::id(), @@ -188,26 +192,10 @@ fn command_create_pool( spl_token::state::Account::LEN as u64, &spl_token::id(), ), - // Account for the stake pool - system_instruction::create_account( - &config.fee_payer.pubkey(), - &stake_pool_keypair.pubkey(), - stake_pool_account_lamports, - get_packed_len::() as u64, - &spl_stake_pool::id(), - ), - // Validator stake account list storage - system_instruction::create_account( - &config.fee_payer.pubkey(), - &validator_list.pubkey(), - validator_list_balance, - validator_list_size as u64, - &spl_stake_pool::id(), - ), // Initialize pool token mint account spl_token::instruction::initialize_mint( &spl_token::id(), - &mint_account.pubkey(), + &mint_keypair.pubkey(), &withdraw_authority, None, default_decimals, @@ -216,10 +204,32 @@ fn command_create_pool( spl_token::instruction::initialize_account( &spl_token::id(), &pool_fee_account.pubkey(), - &mint_account.pubkey(), + &mint_keypair.pubkey(), &config.manager.pubkey(), )?, - // Initialize stake pool account + ], + Some(&config.fee_payer.pubkey()), + ); + + let mut initialize_transaction = Transaction::new_with_payer( + &[ + // Validator stake account list storage + system_instruction::create_account( + &config.fee_payer.pubkey(), + &validator_list.pubkey(), + validator_list_balance, + validator_list_size as u64, + &spl_stake_pool::id(), + ), + // Account for the stake pool + system_instruction::create_account( + &config.fee_payer.pubkey(), + &stake_pool_keypair.pubkey(), + stake_pool_account_lamports, + get_packed_len::() as u64, + &spl_stake_pool::id(), + ), + // Initialize stake pool spl_stake_pool::instruction::initialize( &spl_stake_pool::id(), &stake_pool_keypair.pubkey(), @@ -227,7 +237,7 @@ fn command_create_pool( &config.staker.pubkey(), &validator_list.pubkey(), &reserve_stake.pubkey(), - &mint_account.pubkey(), + &mint_keypair.pubkey(), &pool_fee_account.pubkey(), &spl_token::id(), deposit_authority, @@ -241,19 +251,30 @@ fn command_create_pool( let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; check_fee_payer_balance( config, - total_rent_free_balances + fee_calculator.calculate_fee(&transaction.message()), + total_rent_free_balances + + fee_calculator.calculate_fee(&setup_transaction.message()) + + fee_calculator.calculate_fee(&initialize_transaction.message()), )?; - let mut signers = vec![ + let mut setup_signers = vec![ + config.fee_payer.as_ref(), + &mint_keypair, + &pool_fee_account, + &reserve_stake, + ]; + unique_signers!(setup_signers); + setup_transaction.sign(&setup_signers, recent_blockhash); + send_transaction(&config, setup_transaction)?; + + println!("Creating stake pool {}", stake_pool_keypair.pubkey()); + let mut initialize_signers = vec![ config.fee_payer.as_ref(), &stake_pool_keypair, &validator_list, - &mint_account, - &pool_fee_account, config.manager.as_ref(), ]; - unique_signers!(signers); - transaction.sign(&signers, recent_blockhash); - send_transaction(&config, transaction)?; + unique_signers!(initialize_signers); + initialize_transaction.sign(&initialize_signers, recent_blockhash); + send_transaction(&config, initialize_transaction)?; Ok(()) } @@ -292,8 +313,24 @@ fn command_vsa_create( Ok(()) } -fn command_vsa_add(config: &Config, stake_pool_address: &Pubkey, stake: &Pubkey) -> CommandResult { - let stake_state = get_stake_state(&config.rpc_client, &stake)?; +fn command_vsa_add( + config: &Config, + stake_pool_address: &Pubkey, + vote_account: &Pubkey, +) -> CommandResult { + let (stake_account_address, _) = + find_stake_program_address(&spl_stake_pool::id(), vote_account, stake_pool_address); + let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; + let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?; + if validator_list.contains(vote_account) { + println!( + "Stake pool already contains validator {}, ignoring", + vote_account + ); + return Ok(()); + } + + let stake_state = get_stake_state(&config.rpc_client, &stake_account_address)?; if let stake_program::StakeState::Stake(meta, _stake) = stake_state { if meta.authorized.withdrawer != config.staker.pubkey() { let error = format!( @@ -308,11 +345,9 @@ fn command_vsa_add(config: &Config, stake_pool_address: &Pubkey, stake: &Pubkey) } if !config.no_update { - command_update(config, stake_pool_address)?; + command_update(config, stake_pool_address, false, false)?; } - let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; - let mut instructions: Vec = vec![]; let mut signers = vec![config.fee_payer.as_ref(), config.staker.as_ref()]; @@ -328,7 +363,7 @@ fn command_vsa_add(config: &Config, stake_pool_address: &Pubkey, stake: &Pubkey) &config.staker.pubkey(), &pool_withdraw_authority, &stake_pool.validator_list, - &stake, + &stake_account_address, )?, ]); @@ -350,7 +385,7 @@ fn command_vsa_remove( new_authority: &Option, ) -> CommandResult { if !config.no_update { - command_update(config, stake_pool_address)?; + command_update(config, stake_pool_address, false, false)?; } let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; @@ -398,10 +433,11 @@ fn command_increase_validator_stake( config: &Config, stake_pool_address: &Pubkey, vote_account: &Pubkey, - lamports: u64, + amount: f64, ) -> CommandResult { + let lamports = native_token::sol_to_lamports(amount); if !config.no_update { - command_update(config, stake_pool_address)?; + command_update(config, stake_pool_address, false, false)?; } let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; @@ -442,10 +478,11 @@ fn command_decrease_validator_stake( config: &Config, stake_pool_address: &Pubkey, vote_account: &Pubkey, - lamports: u64, + amount: f64, ) -> CommandResult { + let lamports = native_token::sol_to_lamports(amount); if !config.no_update { - command_update(config, stake_pool_address)?; + command_update(config, stake_pool_address, false, false)?; } let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; @@ -483,51 +520,32 @@ fn command_decrease_validator_stake( Ok(()) } -fn unwrap_create_token_account( +fn add_associated_token_account( config: &Config, - token_optional: &Option, - keypair: &Keypair, mint: &Pubkey, instructions: &mut Vec, - handler: F, -) -> Result -where - F: FnOnce(u64), -{ - let result = match token_optional { - Some(value) => *value, - None => { - // Account for tokens not specified, creating one - println!("Creating account to receive tokens {}", keypair.pubkey()); + rent_free_balances: &mut u64, +) -> Pubkey { + // Account for tokens not specified, creating one + let account = get_associated_token_address(&config.fee_payer.pubkey(), mint); + if get_token_account(&config.rpc_client, &account, mint).is_err() { + println!("Creating account to receive tokens {}", account); + + let min_account_balance = config + .rpc_client + .get_minimum_balance_for_rent_exemption(spl_token::state::Account::LEN) + .unwrap(); - let min_account_balance = config - .rpc_client - .get_minimum_balance_for_rent_exemption(spl_token::state::Account::LEN)?; + instructions.push(create_associated_token_account( + &config.fee_payer.pubkey(), + &config.fee_payer.pubkey(), + mint, + )); - instructions.extend(vec![ - // Creating new account - system_instruction::create_account( - &config.fee_payer.pubkey(), - &keypair.pubkey(), - min_account_balance, - spl_token::state::Account::LEN as u64, - &spl_token::id(), - ), - // Initialize token receiver account - spl_token::instruction::initialize_account( - &spl_token::id(), - &keypair.pubkey(), - mint, - &config.token_owner.pubkey(), - )?, - ]); - - handler(min_account_balance); - - keypair.pubkey() - } - }; - Ok(result) + *rent_free_balances += min_account_balance; + } + + account } fn command_deposit( @@ -537,7 +555,7 @@ fn command_deposit( token_receiver: &Option, ) -> CommandResult { if !config.no_update { - command_update(config, stake_pool_address)?; + command_update(config, stake_pool_address, false, false)?; } let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; @@ -572,20 +590,13 @@ fn command_deposit( let mut total_rent_free_balances: u64 = 0; - let token_receiver_account = Keypair::new(); - // Create token account if not specified - let token_receiver = unwrap_create_token_account( + let token_receiver = token_receiver.unwrap_or(add_associated_token_account( &config, - &token_receiver, - &token_receiver_account, &stake_pool.pool_mint, &mut instructions, - |balance| { - signers.push(&token_receiver_account); - total_rent_free_balances += balance; - }, - )?; + &mut total_rent_free_balances, + )); let pool_withdraw_authority = find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; @@ -714,13 +725,22 @@ fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { Ok(()) } -fn command_update(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { +fn command_update( + config: &Config, + stake_pool_address: &Pubkey, + force: bool, + no_merge: bool, +) -> CommandResult { let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; let epoch_info = config.rpc_client.get_epoch_info()?; if stake_pool.last_update_epoch == epoch_info.epoch { - println!("Update not required"); - return Ok(()); + if force { + println!("Update not required, but --force flag specified, so doing it anyway"); + } else { + println!("Update not required"); + return Ok(()); + } } let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?; @@ -746,7 +766,7 @@ fn command_update(config: &Config, stake_pool_address: &Pubkey) -> CommandResult &stake_pool.reserve_stake, &accounts_chunk, start_index, - false, + no_merge, )); start_index += MAX_VALIDATORS_TO_UPDATE as u32; } @@ -838,12 +858,14 @@ fn prepare_withdraw_accounts( fn command_withdraw( config: &Config, stake_pool_address: &Pubkey, - pool_amount: f64, - withdraw_from: &Pubkey, + use_reserve: bool, + vote_account_address: &Option, stake_receiver_param: &Option, + pool_token_account: &Option, + pool_amount: f64, ) -> CommandResult { if !config.no_update { - command_update(config, stake_pool_address)?; + command_update(config, stake_pool_address, false, false)?; } let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; @@ -853,9 +875,15 @@ fn command_withdraw( let pool_withdraw_authority = find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; - // Check withdraw_from account type - let token_account = - get_token_account(&config.rpc_client, &withdraw_from, &stake_pool.pool_mint)?; + let pool_token_account = pool_token_account.unwrap_or(get_associated_token_address( + &config.fee_payer.pubkey(), + &stake_pool.pool_mint, + )); + let token_account = get_token_account( + &config.rpc_client, + &pool_token_account, + &stake_pool.pool_mint, + )?; // Check withdraw_from balance if token_account.amount < pool_amount { @@ -867,13 +895,41 @@ fn command_withdraw( .into()); } - // Get the list of accounts to withdraw from - let withdraw_accounts = prepare_withdraw_accounts( - &config.rpc_client, - &stake_pool, - &pool_withdraw_authority, - pool_amount, - )?; + let withdraw_accounts = if use_reserve { + vec![WithdrawAccount { + address: stake_pool.reserve_stake, + pool_amount, + }] + } else if let Some(vote_account_address) = vote_account_address { + let (stake_account_address, _) = find_stake_program_address( + &spl_stake_pool::id(), + &vote_account_address, + stake_pool_address, + ); + let stake_account = config.rpc_client.get_account(&stake_account_address)?; + let available_for_withdrawal = stake_pool + .calc_lamports_withdraw_amount(stake_account.lamports - *MIN_STAKE_BALANCE) + .unwrap(); + if available_for_withdrawal < pool_amount { + return Err(format!( + "Not enough lamports available for withdrawal from {}, {} asked, {} available", + stake_account_address, pool_amount, available_for_withdrawal + ) + .into()); + } + vec![WithdrawAccount { + address: stake_account_address, + pool_amount, + }] + } else { + // Get the list of accounts to withdraw from + prepare_withdraw_accounts( + &config.rpc_client, + &stake_pool, + &pool_withdraw_authority, + pool_amount, + )? + }; // Construct transaction to withdraw from withdraw_accounts account list let mut instructions: Vec = vec![]; @@ -889,7 +945,7 @@ fn command_withdraw( // Approve spending token spl_token::instruction::approve( &spl_token::id(), - &withdraw_from, + &pool_token_account, &user_transfer_authority.pubkey(), &config.token_owner.pubkey(), &[], @@ -954,7 +1010,7 @@ fn command_withdraw( &stake_receiver.unwrap(), // Cannot be none at this point &config.staker.pubkey(), &user_transfer_authority.pubkey(), - &withdraw_from, + &pool_token_account, &stake_pool.pool_mint, &spl_token::id(), withdraw_account.pool_amount, @@ -1218,6 +1274,23 @@ fn main() { .takes_value(true) .help("Deposit authority required to sign all deposits into the stake pool"), ) + .arg( + Arg::with_name("pool_keypair") + .long("pool-keypair") + .short("p") + .validator(is_keypair_or_ask_keyword) + .value_name("PATH") + .takes_value(true) + .help("Stake pool keypair [default: new keypair]"), + ) + .arg( + Arg::with_name("mint_keypair") + .long("mint-keypair") + .validator(is_keypair_or_ask_keyword) + .value_name("PATH") + .takes_value(true) + .help("Stake pool mint keypair [default: new keypair]"), + ) ) .subcommand(SubCommand::with_name("create-validator-stake") .about("Create a new stake account to use with the pool. Must be signed by the pool staker.") @@ -1252,13 +1325,13 @@ fn main() { .help("Stake pool address"), ) .arg( - Arg::with_name("stake_account") + Arg::with_name("vote_account") .index(2) .validator(is_pubkey) - .value_name("STAKE_ACCOUNT_ADDRESS") + .value_name("VOTE_ACCOUNT_ADDRESS") .takes_value(true) .required(true) - .help("Stake account to add to the pool"), + .help("The validator vote account that the stake is delegated to"), ) ) .subcommand(SubCommand::with_name("remove-validator") @@ -1312,12 +1385,12 @@ fn main() { .help("Vote account for the validator to increase stake to"), ) .arg( - Arg::with_name("lamports") + Arg::with_name("amount") .index(3) - .validator(is_pubkey) - .value_name("LAMPORTS") + .validator(is_amount) + .value_name("AMOUNT") .takes_value(true) - .help("Amount in lamports to add to the validator stake account. Must be at least the rent-exempt amount for a stake plus 1 SOL for merging."), + .help("Amount in SOL to add to the validator stake account. Must be at least the rent-exempt amount for a stake plus 1 SOL for merging."), ) ) .subcommand(SubCommand::with_name("decrease-validator-stake") @@ -1341,10 +1414,10 @@ fn main() { .help("Vote account for the validator to decrease stake from"), ) .arg( - Arg::with_name("lamports") + Arg::with_name("amount") .index(3) - .validator(is_pubkey) - .value_name("LAMPORTS") + .validator(is_amount) + .value_name("AMOUNT") .takes_value(true) .help("Amount in lamports to remove from the validator stake account. Must be at least the rent-exempt amount for a stake."), ) @@ -1376,7 +1449,7 @@ fn main() { .value_name("ADDRESS") .takes_value(true) .help("Account to receive pool token. Must be initialized account of the stake pool token. \ - Defaults to the new pool token account."), + Defaults to the fee payer's associated pool token account."), ) ) .subcommand(SubCommand::with_name("list") @@ -1402,6 +1475,18 @@ fn main() { .required(true) .help("Stake pool address."), ) + .arg( + Arg::with_name("force") + .long("force") + .takes_value(false) + .help("Update all balances, even if it has already been performed this epoch."), + ) + .arg( + Arg::with_name("no_merge") + .long("no-merge") + .takes_value(false) + .help("Do not automatically merge transient stakes. Useful if the stake pool is in an expected state, but the balances still need to be updated."), + ) ) .subcommand(SubCommand::with_name("withdraw") .about("Withdraw amount from the stake pool") @@ -1416,7 +1501,7 @@ fn main() { ) .arg( Arg::with_name("amount") - .long("amount") + .index(2) .validator(is_amount) .value_name("AMOUNT") .takes_value(true) @@ -1424,13 +1509,12 @@ fn main() { .help("Amount of pool tokens to withdraw for activated stake."), ) .arg( - Arg::with_name("withdraw_from") - .long("withdraw-from") + Arg::with_name("pool_account") + .long("pool-account") .validator(is_pubkey) .value_name("ADDRESS") .takes_value(true) - .required(true) - .help("Account to withdraw tokens from. Must be owned by the client."), + .help("Pool token account to withdraw tokens from. Must be owned by the fee payer. Defaults to their associated token account."), ) .arg( Arg::with_name("stake_receiver") @@ -1440,6 +1524,24 @@ fn main() { .takes_value(true) .help("Stake account to receive SOL from the stake pool. Defaults to a new stake account."), ) + .arg( + Arg::with_name("vote_account") + .long("vote-account") + .validator(is_pubkey) + .value_name("VOTE_ACCOUNT_ADDRESS") + .takes_value(true) + .help("Validator to withdraw from. Defaults to the largest validator stakes in the pool."), + ) + .arg( + Arg::with_name("use_reserve") + .long("use-reserve") + .takes_value(false) + .help("Withdraw from the stake pool's reserve. Only possible if all validator stakes are at the minimum possible amount."), + ) + .group(ArgGroup::with_name("withdraw_from") + .arg("use_reserve") + .arg("vote_account") + ) ) .subcommand(SubCommand::with_name("set-manager") .about("Change manager or fee receiver account for the stake pool. Must be signed by the current manager.") @@ -1616,6 +1718,8 @@ fn main() { let numerator = value_t_or_exit!(arg_matches, "fee_numerator", u64); let denominator = value_t_or_exit!(arg_matches, "fee_denominator", u64); let max_validators = value_t_or_exit!(arg_matches, "max_validators", u32); + let pool_keypair = keypair_of(arg_matches, "pool_keypair"); + let mint_keypair = keypair_of(arg_matches, "mint_keypair"); command_create_pool( &config, deposit_authority, @@ -1624,6 +1728,8 @@ fn main() { numerator, }, max_validators, + pool_keypair, + mint_keypair, ) } ("create-validator-stake", Some(arg_matches)) => { @@ -1633,8 +1739,8 @@ fn main() { } ("add-validator", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); - let stake_account = pubkey_of(arg_matches, "stake_account").unwrap(); - command_vsa_add(&config, &stake_pool_address, &stake_account) + let vote_account_address = pubkey_of(arg_matches, "vote_account").unwrap(); + command_vsa_add(&config, &stake_pool_address, &vote_account_address) } ("remove-validator", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); @@ -1645,14 +1751,14 @@ fn main() { ("increase-validator-stake", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); let vote_account = pubkey_of(arg_matches, "vote_account").unwrap(); - let lamports = value_t_or_exit!(arg_matches, "lamports", u64); - command_increase_validator_stake(&config, &stake_pool_address, &vote_account, lamports) + let amount = value_t_or_exit!(arg_matches, "amount", f64); + command_increase_validator_stake(&config, &stake_pool_address, &vote_account, amount) } ("decrease-validator-stake", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); let vote_account = pubkey_of(arg_matches, "vote_account").unwrap(); - let lamports = value_t_or_exit!(arg_matches, "lamports", u64); - command_decrease_validator_stake(&config, &stake_pool_address, &vote_account, lamports) + let amount = value_t_or_exit!(arg_matches, "amount", f64); + command_decrease_validator_stake(&config, &stake_pool_address, &vote_account, amount) } ("deposit", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); @@ -1671,19 +1777,25 @@ fn main() { } ("update", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); - command_update(&config, &stake_pool_address) + let no_merge = arg_matches.is_present("no_merge"); + let force = arg_matches.is_present("force"); + command_update(&config, &stake_pool_address, force, no_merge) } ("withdraw", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); - let withdraw_from = pubkey_of(arg_matches, "withdraw_from").unwrap(); + let vote_account = pubkey_of(arg_matches, "vote_account"); + let pool_account = pubkey_of(arg_matches, "pool_account"); let pool_amount = value_t_or_exit!(arg_matches, "amount", f64); - let stake_receiver: Option = pubkey_of(arg_matches, "stake_receiver"); + let stake_receiver = pubkey_of(arg_matches, "stake_receiver"); + let use_reserve = arg_matches.is_present("use_reserve"); command_withdraw( &config, &stake_pool_address, - pool_amount, - &withdraw_from, + use_reserve, + &vote_account, &stake_receiver, + &pool_account, + pool_amount, ) } ("set-manager", Some(arg_matches)) => { From 80b716698f2d4643dab4bf0d0962e1d8a2fc5519 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Mon, 3 May 2021 22:50:49 +0200 Subject: [PATCH 0096/1076] stake-pool: Update versions for crate deployment (#1657) --- clients/cli/Cargo.toml | 8 ++++---- program/Cargo.toml | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 95b21947..e2f1c883 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -6,7 +6,7 @@ homepage = "https://spl.solana.com/stake-pool" license = "Apache-2.0" name = "spl-stake-pool-cli" repository = "https://github.com/solana-labs/solana-program-library" -version = "2.0.1" +version = "0.1.0" [dependencies] borsh = "0.8" @@ -19,9 +19,9 @@ solana-client = "1.6.6" solana-logger = "1.6.6" solana-sdk = "1.6.6" solana-program = "1.6.6" -spl-associated-token-account = { path="../../associated-token-account/program", features = [ "no-entrypoint" ] } -spl-stake-pool = { path="../program", features = [ "no-entrypoint" ] } -spl-token = { path="../../token/program", features = [ "no-entrypoint" ] } +spl-associated-token-account = { version = "1.0", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } +spl-stake-pool = { version = "0.1", path="../program", features = [ "no-entrypoint" ] } +spl-token = { version = "3.1", path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" bincode = "1.3.1" lazy_static = "1.4.0" diff --git a/program/Cargo.toml b/program/Cargo.toml index 78611c27..c7cf1476 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -20,8 +20,8 @@ num_enum = "0.5.1" serde = "1.0.121" serde_derive = "1.0.103" solana-program = "1.6.6" -spl-math = { path = "../../libraries/math", features = [ "no-entrypoint" ] } -spl-token = { path = "../../token/program", features = [ "no-entrypoint" ] } +spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } +spl-token = { version = "3.1", path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" bincode = "1.3.1" From 840947822fbab43e996ddba78241f669585a3a65 Mon Sep 17 00:00:00 2001 From: Trent Nelson Date: Tue, 4 May 2021 22:03:15 -0600 Subject: [PATCH 0097/1076] Bump solana crates to v1.6.7 --- clients/cli/Cargo.toml | 14 +++++++------- program/Cargo.toml | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index e2f1c883..c663f864 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -12,13 +12,13 @@ version = "0.1.0" borsh = "0.8" clap = "2.33.3" serde_json = "1.0.62" -solana-account-decoder = "1.6.6" -solana-clap-utils = "1.6.6" -solana-cli-config = "1.6.6" -solana-client = "1.6.6" -solana-logger = "1.6.6" -solana-sdk = "1.6.6" -solana-program = "1.6.6" +solana-account-decoder = "1.6.7" +solana-clap-utils = "1.6.7" +solana-cli-config = "1.6.7" +solana-client = "1.6.7" +solana-logger = "1.6.7" +solana-sdk = "1.6.7" +solana-program = "1.6.7" spl-associated-token-account = { version = "1.0", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "0.1", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "3.1", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/program/Cargo.toml b/program/Cargo.toml index c7cf1476..d8af915b 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -19,7 +19,7 @@ num-traits = "0.2" num_enum = "0.5.1" serde = "1.0.121" serde_derive = "1.0.103" -solana-program = "1.6.6" +solana-program = "1.6.7" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-token = { version = "3.1", path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" @@ -27,9 +27,9 @@ bincode = "1.3.1" [dev-dependencies] proptest = "0.10" -solana-program-test = "1.6.6" -solana-sdk = "1.6.6" -solana-vote-program = "1.6.6" +solana-program-test = "1.6.7" +solana-sdk = "1.6.7" +solana-vote-program = "1.6.7" [lib] crate-type = ["cdylib", "lib"] From 274c486e54eee6176958dbe4b2fe9833f6dfd42d Mon Sep 17 00:00:00 2001 From: jordansexton Date: Fri, 7 May 2021 13:50:35 -0500 Subject: [PATCH 0098/1076] stake-pool: minor typo fix --- clients/cli/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index a6418dd2..fdf175e7 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -1157,7 +1157,7 @@ fn main() { .long("dry-run") .takes_value(false) .global(true) - .help("Simluate transaction instead of executing"), + .help("Simulate transaction instead of executing"), ) .arg( Arg::with_name("no_update") From 627803d00e8aa5ac02f0de9613c9e46fb7e80757 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Mon, 10 May 2021 14:33:56 +0200 Subject: [PATCH 0099/1076] stake-pool: Re-enable tests, avoid warping so much (#1687) --- program/tests/update_validator_list_balance.rs | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index a6726261..1eef712f 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -97,13 +97,8 @@ async fn setup( } // Warp forward so the stakes properly activate, and deposit - // TODO This is *bad* -- program-test needs to have some more active stake - // so we can warm up faster than this. Also, we need to do each of these - // warps by hand to get fully active stakes. - for i in 2..50 { - slot = first_normal_slot + i * slots_per_epoch; - context.warp_to_slot(slot).unwrap(); - } + slot += 2 * slots_per_epoch; + context.warp_to_slot(slot).unwrap(); stake_pool_accounts .update_all( @@ -170,7 +165,6 @@ async fn setup( } #[tokio::test] -#[ignore] async fn success() { let num_validators = 5; let ( @@ -239,7 +233,6 @@ async fn success() { } #[tokio::test] -#[ignore] async fn merge_into_reserve() { let (mut context, stake_pool_accounts, stake_accounts, lamports, _, mut slot) = setup(MAX_VALIDATORS_TO_UPDATE).await; @@ -350,7 +343,6 @@ async fn merge_into_reserve() { } #[tokio::test] -#[ignore] async fn merge_into_validator_stake() { let (mut context, stake_pool_accounts, stake_accounts, lamports, reserve_lamports, mut slot) = setup(MAX_VALIDATORS_TO_UPDATE).await; @@ -477,7 +469,6 @@ async fn merge_into_validator_stake() { } #[tokio::test] -#[ignore] async fn merge_transient_stake_after_remove() { let (mut context, stake_pool_accounts, stake_accounts, lamports, reserve_lamports, mut slot) = setup(1).await; From 889ad0fb960aa76d4ba81d42d9a859e04c017c46 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 11 May 2021 22:48:58 +0200 Subject: [PATCH 0100/1076] stake-pool: Add helper instruction creators for stake pool integration (#1706) * stake-pool: Add more instructions for easier usage * Add extra check (shouldn't be necessary, but who knows?) --- clients/cli/src/main.rs | 164 ++++++------------------ program/src/instruction.rs | 239 ++++++++++++++++++++++++++++++----- program/src/processor.rs | 5 + program/tests/helpers/mod.rs | 15 +-- program/tests/initialize.rs | 12 +- program/tests/set_manager.rs | 9 +- program/tests/set_staker.rs | 12 +- program/tests/vsa_add.rs | 6 +- program/tests/vsa_create.rs | 9 +- program/tests/vsa_remove.rs | 6 +- program/tests/withdraw.rs | 3 +- 11 files changed, 272 insertions(+), 208 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index fdf175e7..bd2e58d7 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -31,11 +31,9 @@ use { spl_stake_pool::{ self, borsh::get_instance_packed_len, - find_stake_program_address, find_transient_stake_program_address, - find_withdraw_authority_program_address, + find_stake_program_address, find_withdraw_authority_program_address, stake_program::{self, StakeState}, state::{Fee, StakePool, ValidatorList}, - MAX_VALIDATORS_TO_UPDATE, }, std::process::exit, }; @@ -243,7 +241,7 @@ fn command_create_pool( deposit_authority, fee, max_validators, - )?, + ), ], Some(&config.fee_payer.pubkey()), ); @@ -283,22 +281,17 @@ fn command_vsa_create( stake_pool_address: &Pubkey, vote_account: &Pubkey, ) -> CommandResult { - let (stake_account, _) = - find_stake_program_address(&spl_stake_pool::id(), &vote_account, &stake_pool_address); - - println!("Creating stake account {}", stake_account); + println!("Creating stake account on {}", vote_account); let mut transaction = Transaction::new_with_payer( &[ // Create new validator stake account address - spl_stake_pool::instruction::create_validator_stake_account( - &spl_stake_pool::id(), + spl_stake_pool::instruction::create_validator_stake_account_with_vote( &stake_pool_address, &config.staker.pubkey(), &config.fee_payer.pubkey(), - &stake_account, &vote_account, - )?, + ), ], Some(&config.fee_payer.pubkey()), ); @@ -348,30 +341,18 @@ fn command_vsa_add( command_update(config, stake_pool_address, false, false)?; } - let mut instructions: Vec = vec![]; - let mut signers = vec![config.fee_payer.as_ref(), config.staker.as_ref()]; - - // Calculate Withdraw stake pool authorities - let pool_withdraw_authority = - find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; - - instructions.extend(vec![ - // Add validator stake account to the pool - spl_stake_pool::instruction::add_validator_to_pool( - &spl_stake_pool::id(), - &stake_pool_address, - &config.staker.pubkey(), - &pool_withdraw_authority, - &stake_pool.validator_list, - &stake_account_address, - )?, - ]); + let instruction = spl_stake_pool::instruction::add_validator_to_pool_with_vote( + &stake_pool, + &stake_pool_address, + &vote_account, + ); let mut transaction = - Transaction::new_with_payer(&instructions, Some(&config.fee_payer.pubkey())); + Transaction::new_with_payer(&[instruction], Some(&config.fee_payer.pubkey())); let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; + let mut signers = vec![config.fee_payer.as_ref(), config.staker.as_ref()]; unique_signers!(signers); transaction.sign(&signers, recent_blockhash); send_transaction(&config, transaction)?; @@ -389,15 +370,6 @@ fn command_vsa_remove( } let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; - let pool_withdraw_authority = - find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; - let (validator_stake_account, _) = - find_stake_program_address(&spl_stake_pool::id(), &vote_account, stake_pool_address); - let (transient_stake_account, _) = find_transient_stake_program_address( - &spl_stake_pool::id(), - &vote_account, - stake_pool_address, - ); let staker_pubkey = config.staker.pubkey(); let new_authority = new_authority.as_ref().unwrap_or(&staker_pubkey); @@ -405,16 +377,12 @@ fn command_vsa_remove( let mut transaction = Transaction::new_with_payer( &[ // Create new validator stake account address - spl_stake_pool::instruction::remove_validator_from_pool( - &spl_stake_pool::id(), - &stake_pool_address, - &config.staker.pubkey(), - &pool_withdraw_authority, - &new_authority, - &stake_pool.validator_list, - &validator_stake_account, - &transient_stake_account, - )?, + spl_stake_pool::instruction::remove_validator_from_pool_with_vote( + &stake_pool, + stake_pool_address, + vote_account, + new_authority, + ), ], Some(&config.fee_payer.pubkey()), ); @@ -441,28 +409,15 @@ fn command_increase_validator_stake( } let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; - let pool_withdraw_authority = - find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; - let (transient_stake_address, _) = find_transient_stake_program_address( - &spl_stake_pool::id(), - &vote_account, + let instruction = spl_stake_pool::instruction::increase_validator_stake_with_vote( + &stake_pool, stake_pool_address, + vote_account, + lamports, ); - let mut transaction = Transaction::new_with_payer( - &[spl_stake_pool::instruction::increase_validator_stake( - &spl_stake_pool::id(), - &stake_pool_address, - &config.staker.pubkey(), - &pool_withdraw_authority, - &stake_pool.validator_list, - &stake_pool.reserve_stake, - &transient_stake_address, - &vote_account, - lamports, - )], - Some(&config.fee_payer.pubkey()), - ); + let mut transaction = + Transaction::new_with_payer(&[instruction], Some(&config.fee_payer.pubkey())); let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; @@ -486,29 +441,15 @@ fn command_decrease_validator_stake( } let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; - let pool_withdraw_authority = - find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; - let (validator_stake_address, _) = - find_stake_program_address(&spl_stake_pool::id(), &vote_account, stake_pool_address); - let (transient_stake_address, _) = find_transient_stake_program_address( - &spl_stake_pool::id(), - &vote_account, + let instruction = spl_stake_pool::instruction::decrease_validator_stake_with_vote( + &stake_pool, stake_pool_address, + vote_account, + lamports, ); - let mut transaction = Transaction::new_with_payer( - &[spl_stake_pool::instruction::decrease_validator_stake( - &spl_stake_pool::id(), - &stake_pool_address, - &config.staker.pubkey(), - &pool_withdraw_authority, - &stake_pool.validator_list, - &validator_stake_address, - &transient_stake_address, - lamports, - )], - Some(&config.fee_payer.pubkey()), - ); + let mut transaction = + Transaction::new_with_payer(&[instruction], Some(&config.fee_payer.pubkey())); let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; @@ -745,41 +686,12 @@ fn command_update( let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?; - let vote_accounts: Vec = validator_list - .validators - .iter() - .map(|item| item.vote_account_address) - .collect(); - - println!("Updating stake pool..."); - let (withdraw_authority, _) = - find_withdraw_authority_program_address(&spl_stake_pool::id(), &stake_pool_address); - - let mut instructions: Vec = vec![]; - let mut start_index = 0; - for accounts_chunk in vote_accounts.chunks(MAX_VALIDATORS_TO_UPDATE) { - instructions.push(spl_stake_pool::instruction::update_validator_list_balance( - &spl_stake_pool::id(), - stake_pool_address, - &withdraw_authority, - &stake_pool.validator_list, - &stake_pool.reserve_stake, - &accounts_chunk, - start_index, - no_merge, - )); - start_index += MAX_VALIDATORS_TO_UPDATE as u32; - } - - instructions.push(spl_stake_pool::instruction::update_stake_pool_balance( - &spl_stake_pool::id(), + let instructions = spl_stake_pool::instruction::update_stake_pool( + &stake_pool, + &validator_list, stake_pool_address, - &withdraw_authority, - &stake_pool.validator_list, - &stake_pool.reserve_stake, - &stake_pool.manager_fee_account, - &stake_pool.pool_mint, - )); + no_merge, + ); // TODO: A faster solution would be to send all the `update_validator_list_balance` instructions concurrently for instruction in instructions { @@ -1014,7 +926,7 @@ fn command_withdraw( &stake_pool.pool_mint, &spl_token::id(), withdraw_account.pool_amount, - )?); + )); } let mut transaction = @@ -1066,7 +978,7 @@ fn command_set_manager( &config.manager.pubkey(), &new_manager, &new_fee_receiver, - )?], + )], Some(&config.fee_payer.pubkey()), ); @@ -1090,7 +1002,7 @@ fn command_set_staker( &stake_pool_address, &config.manager.pubkey(), &new_staker, - )?], + )], Some(&config.fee_payer.pubkey()), ); diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 48785a8e..63bb085d 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -5,12 +5,14 @@ use { crate::{ find_deposit_authority_program_address, find_stake_program_address, - find_transient_stake_program_address, stake_program, state::Fee, + find_transient_stake_program_address, find_withdraw_authority_program_address, id, + stake_program, + state::{Fee, StakePool, ValidatorList}, + MAX_VALIDATORS_TO_UPDATE, }, borsh::{BorshDeserialize, BorshSchema, BorshSerialize}, solana_program::{ instruction::{AccountMeta, Instruction}, - program_error::ProgramError, pubkey::Pubkey, system_program, sysvar, }, @@ -275,12 +277,12 @@ pub fn initialize( deposit_authority: Option, fee: Fee, max_validators: u32, -) -> Result { +) -> Instruction { let init_data = StakePoolInstruction::Initialize { fee, max_validators, }; - let data = init_data.try_to_vec()?; + let data = init_data.try_to_vec().unwrap(); let mut accounts = vec![ AccountMeta::new(*stake_pool, true), AccountMeta::new_readonly(*manager, true), @@ -296,11 +298,11 @@ pub fn initialize( if let Some(deposit_authority) = deposit_authority { accounts.push(AccountMeta::new_readonly(deposit_authority, true)); } - Ok(Instruction { + Instruction { program_id: *program_id, accounts, data, - }) + } } /// Creates `CreateValidatorStakeAccount` instruction (create new stake account for the validator) @@ -311,7 +313,7 @@ pub fn create_validator_stake_account( funder: &Pubkey, stake_account: &Pubkey, validator: &Pubkey, -) -> Result { +) -> Instruction { let accounts = vec![ AccountMeta::new_readonly(*stake_pool, false), AccountMeta::new_readonly(*staker, true), @@ -325,11 +327,13 @@ pub fn create_validator_stake_account( AccountMeta::new_readonly(system_program::id(), false), AccountMeta::new_readonly(stake_program::id(), false), ]; - Ok(Instruction { + Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::CreateValidatorStakeAccount.try_to_vec()?, - }) + data: StakePoolInstruction::CreateValidatorStakeAccount + .try_to_vec() + .unwrap(), + } } /// Creates `AddValidatorToPool` instruction (add new validator stake account to the pool) @@ -340,7 +344,7 @@ pub fn add_validator_to_pool( stake_pool_withdraw: &Pubkey, validator_list: &Pubkey, stake_account: &Pubkey, -) -> Result { +) -> Instruction { let accounts = vec![ AccountMeta::new(*stake_pool, false), AccountMeta::new_readonly(*staker, true), @@ -351,11 +355,13 @@ pub fn add_validator_to_pool( AccountMeta::new_readonly(sysvar::stake_history::id(), false), AccountMeta::new_readonly(stake_program::id(), false), ]; - Ok(Instruction { + Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::AddValidatorToPool.try_to_vec()?, - }) + data: StakePoolInstruction::AddValidatorToPool + .try_to_vec() + .unwrap(), + } } /// Creates `RemoveValidatorFromPool` instruction (remove validator stake account from the pool) @@ -368,7 +374,7 @@ pub fn remove_validator_from_pool( validator_list: &Pubkey, stake_account: &Pubkey, transient_stake_account: &Pubkey, -) -> Result { +) -> Instruction { let accounts = vec![ AccountMeta::new(*stake_pool, false), AccountMeta::new_readonly(*staker, true), @@ -380,11 +386,13 @@ pub fn remove_validator_from_pool( AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(stake_program::id(), false), ]; - Ok(Instruction { + Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::RemoveValidatorFromPool.try_to_vec()?, - }) + data: StakePoolInstruction::RemoveValidatorFromPool + .try_to_vec() + .unwrap(), + } } /// Creates `DecreaseValidatorStake` instruction (rebalance from validator account to @@ -457,6 +465,124 @@ pub fn increase_validator_stake( } } +/// Creates `CreateValidatorStakeAccount` instruction with a vote account +pub fn create_validator_stake_account_with_vote( + stake_pool_address: &Pubkey, + staker: &Pubkey, + funder: &Pubkey, + vote_account_address: &Pubkey, +) -> Instruction { + let (stake_account, _) = + find_stake_program_address(&id(), vote_account_address, stake_pool_address); + create_validator_stake_account( + &id(), + &stake_pool_address, + staker, + funder, + &stake_account, + vote_account_address, + ) +} + +/// Create an `AddValidatorToPool` instruction given an existing stake pool and +/// vote account +pub fn add_validator_to_pool_with_vote( + stake_pool: &StakePool, + stake_pool_address: &Pubkey, + vote_account_address: &Pubkey, +) -> Instruction { + let pool_withdraw_authority = + find_withdraw_authority_program_address(&id(), stake_pool_address).0; + let (stake_account_address, _) = + find_stake_program_address(&id(), vote_account_address, stake_pool_address); + add_validator_to_pool( + &id(), + &stake_pool_address, + &stake_pool.staker, + &pool_withdraw_authority, + &stake_pool.validator_list, + &stake_account_address, + ) +} + +/// Create an `RemoveValidatorFromPool` instruction given an existing stake pool and +/// vote account +pub fn remove_validator_from_pool_with_vote( + stake_pool: &StakePool, + stake_pool_address: &Pubkey, + vote_account_address: &Pubkey, + new_stake_account_authority: &Pubkey, +) -> Instruction { + let pool_withdraw_authority = + find_withdraw_authority_program_address(&id(), stake_pool_address).0; + let (stake_account_address, _) = + find_stake_program_address(&id(), vote_account_address, stake_pool_address); + let (transient_stake_account, _) = + find_transient_stake_program_address(&id(), &vote_account_address, stake_pool_address); + remove_validator_from_pool( + &id(), + &stake_pool_address, + &stake_pool.staker, + &pool_withdraw_authority, + &new_stake_account_authority, + &stake_pool.validator_list, + &stake_account_address, + &transient_stake_account, + ) +} + +/// Create an `IncreaseValidatorStake` instruction given an existing stake pool and +/// vote account +pub fn increase_validator_stake_with_vote( + stake_pool: &StakePool, + stake_pool_address: &Pubkey, + vote_account_address: &Pubkey, + lamports: u64, +) -> Instruction { + let pool_withdraw_authority = + find_withdraw_authority_program_address(&id(), stake_pool_address).0; + let (transient_stake_address, _) = + find_transient_stake_program_address(&id(), &vote_account_address, stake_pool_address); + + increase_validator_stake( + &id(), + &stake_pool_address, + &stake_pool.staker, + &pool_withdraw_authority, + &stake_pool.validator_list, + &stake_pool.reserve_stake, + &transient_stake_address, + &vote_account_address, + lamports, + ) +} + +/// Create a `DecreaseValidatorStake` instruction given an existing stake pool and +/// vote account +pub fn decrease_validator_stake_with_vote( + stake_pool: &StakePool, + stake_pool_address: &Pubkey, + vote_account_address: &Pubkey, + lamports: u64, +) -> Instruction { + let pool_withdraw_authority = + find_withdraw_authority_program_address(&id(), stake_pool_address).0; + let (validator_stake_address, _) = + find_stake_program_address(&id(), &vote_account_address, stake_pool_address); + let (transient_stake_address, _) = + find_transient_stake_program_address(&id(), &vote_account_address, stake_pool_address); + decrease_validator_stake( + &id(), + &stake_pool_address, + &stake_pool.staker, + &pool_withdraw_authority, + &stake_pool.validator_list, + &validator_stake_address, + &transient_stake_address, + lamports, + ) +} + /// Creates `UpdateValidatorListBalance` instruction (update validator stake account balances) pub fn update_validator_list_balance( program_id: &Pubkey, @@ -536,6 +662,51 @@ pub fn update_stake_pool_balance( } } +/// Creates all `UpdateValidatorListBalance` and `UpdateStakePoolBalance` +/// instructions for fully updating a stake pool each epoch +pub fn update_stake_pool( + stake_pool: &StakePool, + validator_list: &ValidatorList, + stake_pool_address: &Pubkey, + no_merge: bool, +) -> Vec { + let vote_accounts: Vec = validator_list + .validators + .iter() + .map(|item| item.vote_account_address) + .collect(); + + let (withdraw_authority, _) = + find_withdraw_authority_program_address(&id(), &stake_pool_address); + + let mut instructions: Vec = vec![]; + let mut start_index = 0; + for accounts_chunk in vote_accounts.chunks(MAX_VALIDATORS_TO_UPDATE) { + instructions.push(update_validator_list_balance( + &id(), + stake_pool_address, + &withdraw_authority, + &stake_pool.validator_list, + &stake_pool.reserve_stake, + &accounts_chunk, + start_index, + no_merge, + )); + start_index += MAX_VALIDATORS_TO_UPDATE as u32; + } + + instructions.push(update_stake_pool_balance( + &id(), + stake_pool_address, + &withdraw_authority, + &stake_pool.validator_list, + &stake_pool.reserve_stake, + &stake_pool.manager_fee_account, + &stake_pool.pool_mint, + )); + instructions +} + /// Creates instructions required to deposit into a stake pool, given a stake /// account owned by the user. pub fn deposit( @@ -545,7 +716,7 @@ pub fn deposit( stake_pool_withdraw_authority: &Pubkey, deposit_stake_address: &Pubkey, deposit_stake_withdraw_authority: &Pubkey, - validator_stake_accont: &Pubkey, + validator_stake_account: &Pubkey, pool_tokens_to: &Pubkey, pool_mint: &Pubkey, token_program_id: &Pubkey, @@ -558,7 +729,7 @@ pub fn deposit( AccountMeta::new_readonly(stake_pool_deposit_authority, false), AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), AccountMeta::new(*deposit_stake_address, false), - AccountMeta::new(*validator_stake_accont, false), + AccountMeta::new(*validator_stake_account, false), AccountMeta::new(*pool_tokens_to, false), AccountMeta::new(*pool_mint, false), AccountMeta::new_readonly(sysvar::clock::id(), false), @@ -598,7 +769,7 @@ pub fn deposit_with_authority( stake_pool_withdraw_authority: &Pubkey, deposit_stake_address: &Pubkey, deposit_stake_withdraw_authority: &Pubkey, - validator_stake_accont: &Pubkey, + validator_stake_account: &Pubkey, pool_tokens_to: &Pubkey, pool_mint: &Pubkey, token_program_id: &Pubkey, @@ -609,7 +780,7 @@ pub fn deposit_with_authority( AccountMeta::new_readonly(*stake_pool_deposit_authority, true), AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), AccountMeta::new(*deposit_stake_address, false), - AccountMeta::new(*validator_stake_accont, false), + AccountMeta::new(*validator_stake_account, false), AccountMeta::new(*pool_tokens_to, false), AccountMeta::new(*pool_mint, false), AccountMeta::new_readonly(sysvar::clock::id(), false), @@ -652,7 +823,7 @@ pub fn withdraw( pool_mint: &Pubkey, token_program_id: &Pubkey, amount: u64, -) -> Result { +) -> Instruction { let accounts = vec![ AccountMeta::new(*stake_pool, false), AccountMeta::new(*validator_list_storage, false), @@ -667,11 +838,11 @@ pub fn withdraw( AccountMeta::new_readonly(*token_program_id, false), AccountMeta::new_readonly(stake_program::id(), false), ]; - Ok(Instruction { + Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::Withdraw(amount).try_to_vec()?, - }) + data: StakePoolInstruction::Withdraw(amount).try_to_vec().unwrap(), + } } /// Creates a 'set manager' instruction. @@ -681,18 +852,18 @@ pub fn set_manager( manager: &Pubkey, new_manager: &Pubkey, new_fee_receiver: &Pubkey, -) -> Result { +) -> Instruction { let accounts = vec![ AccountMeta::new(*stake_pool, false), AccountMeta::new_readonly(*manager, true), AccountMeta::new_readonly(*new_manager, false), AccountMeta::new_readonly(*new_fee_receiver, false), ]; - Ok(Instruction { + Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::SetManager.try_to_vec()?, - }) + data: StakePoolInstruction::SetManager.try_to_vec().unwrap(), + } } /// Creates a 'set fee' instruction. @@ -720,15 +891,15 @@ pub fn set_staker( stake_pool: &Pubkey, set_staker_authority: &Pubkey, new_staker: &Pubkey, -) -> Result { +) -> Instruction { let accounts = vec![ AccountMeta::new(*stake_pool, false), AccountMeta::new_readonly(*set_staker_authority, true), AccountMeta::new_readonly(*new_staker, false), ]; - Ok(Instruction { + Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::SetStaker.try_to_vec()?, - }) + data: StakePoolInstruction::SetStaker.try_to_vec().unwrap(), + } } diff --git a/program/src/processor.rs b/program/src/processor.rs index a95f3fa2..9c253d37 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1072,6 +1072,11 @@ impl Processor { } let mut validator_list_entry = maybe_validator_list_entry.unwrap(); + if validator_list_entry.status != StakeStatus::Active { + msg!("Validator is marked for removal and no longer allows increases"); + return Err(StakePoolError::ValidatorNotFound.into()); + } + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let minimum_lamports = MINIMUM_ACTIVE_STAKE + stake_rent; if lamports < minimum_lamports { diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 80f4ea28..3995171e 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -250,8 +250,7 @@ pub async fn create_stake_pool( deposit_authority.as_ref().map(|k| k.pubkey()), *fee, max_validators, - ) - .unwrap(), + ), ], Some(&payer.pubkey()), ); @@ -374,8 +373,7 @@ pub async fn create_validator_stake_account( &payer.pubkey(), &stake_account, &validator, - ) - .unwrap()], + )], Some(&payer.pubkey()), &[payer, staker], *recent_blockhash, @@ -677,8 +675,7 @@ impl StakePoolAccounts { &self.pool_mint.pubkey(), &spl_token::id(), amount, - ) - .unwrap()], + )], Some(&payer.pubkey()), &[payer, user_transfer_authority], *recent_blockhash, @@ -787,8 +784,7 @@ impl StakePoolAccounts { &self.withdraw_authority, &self.validator_list.pubkey(), stake, - ) - .unwrap()], + )], Some(&payer.pubkey()), &[payer, &self.staker], *recent_blockhash, @@ -815,8 +811,7 @@ impl StakePoolAccounts { &self.validator_list.pubkey(), validator_stake, transient_stake, - ) - .unwrap()], + )], Some(&payer.pubkey()), &[payer, &self.staker], *recent_blockhash, diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index 3539a327..45346665 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -229,8 +229,7 @@ async fn fail_with_wrong_max_validators() { None, stake_pool_accounts.fee, stake_pool_accounts.max_validators, - ) - .unwrap(), + ), ], Some(&payer.pubkey()), ); @@ -389,8 +388,7 @@ async fn fail_with_wrong_token_program_id() { None, stake_pool_accounts.fee, stake_pool_accounts.max_validators, - ) - .unwrap(), + ), ], Some(&payer.pubkey()), ); @@ -554,8 +552,7 @@ async fn fail_with_not_rent_exempt_pool() { None, stake_pool_accounts.fee, stake_pool_accounts.max_validators, - ) - .unwrap(), + ), ], Some(&payer.pubkey()), ); @@ -629,8 +626,7 @@ async fn fail_with_not_rent_exempt_validator_list() { None, stake_pool_accounts.fee, stake_pool_accounts.max_validators, - ) - .unwrap(), + ), ], Some(&payer.pubkey()), ); diff --git a/program/tests/set_manager.rs b/program/tests/set_manager.rs index 4b7fc86f..0009d761 100644 --- a/program/tests/set_manager.rs +++ b/program/tests/set_manager.rs @@ -67,8 +67,7 @@ async fn test_set_manager() { &stake_pool_accounts.manager.pubkey(), &new_manager.pubkey(), &new_pool_fee.pubkey(), - ) - .unwrap()], + )], Some(&payer.pubkey()), ); transaction.sign(&[&payer, &stake_pool_accounts.manager], recent_blockhash); @@ -92,8 +91,7 @@ async fn test_set_manager_by_malicious() { &new_manager.pubkey(), &new_manager.pubkey(), &new_pool_fee.pubkey(), - ) - .unwrap()], + )], Some(&payer.pubkey()), ); transaction.sign(&[&payer, &new_manager], recent_blockhash); @@ -196,8 +194,7 @@ async fn test_set_manager_with_wrong_mint_for_pool_fee_acc() { &stake_pool_accounts.manager.pubkey(), &new_manager.pubkey(), &new_pool_fee.pubkey(), - ) - .unwrap()], + )], Some(&payer.pubkey()), ); transaction.sign(&[&payer, &stake_pool_accounts.manager], recent_blockhash); diff --git a/program/tests/set_staker.rs b/program/tests/set_staker.rs index 1dac586b..2f93cbd2 100644 --- a/program/tests/set_staker.rs +++ b/program/tests/set_staker.rs @@ -47,8 +47,7 @@ async fn success_set_staker_as_manager() { &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), &new_staker.pubkey(), - ) - .unwrap()], + )], Some(&payer.pubkey()), ); transaction.sign(&[&payer, &stake_pool_accounts.manager], recent_blockhash); @@ -71,8 +70,7 @@ async fn success_set_staker_as_staker() { &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.staker.pubkey(), &new_staker.pubkey(), - ) - .unwrap()], + )], Some(&payer.pubkey()), ); transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); @@ -89,8 +87,7 @@ async fn success_set_staker_as_staker() { &stake_pool_accounts.stake_pool.pubkey(), &new_staker.pubkey(), &stake_pool_accounts.staker.pubkey(), - ) - .unwrap()], + )], Some(&payer.pubkey()), ); transaction.sign(&[&payer, &new_staker], recent_blockhash); @@ -113,8 +110,7 @@ async fn fail_wrong_manager() { &stake_pool_accounts.stake_pool.pubkey(), &new_staker.pubkey(), &new_staker.pubkey(), - ) - .unwrap()], + )], Some(&payer.pubkey()), ); transaction.sign(&[&payer, &new_staker], recent_blockhash); diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index c5bc7879..7049f3ec 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -127,8 +127,7 @@ async fn fail_with_wrong_validator_list_account() { &stake_pool_accounts.withdraw_authority, &wrong_validator_list.pubkey(), &user_stake.stake_account, - ) - .unwrap()], + )], Some(&payer.pubkey()), ); transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); @@ -316,8 +315,7 @@ async fn fail_wrong_staker() { &stake_pool_accounts.withdraw_authority, &stake_pool_accounts.validator_list.pubkey(), &user_stake.stake_account, - ) - .unwrap()], + )], Some(&payer.pubkey()), ); transaction.sign(&[&payer, &malicious], recent_blockhash); diff --git a/program/tests/vsa_create.rs b/program/tests/vsa_create.rs index 741a7cd5..2298e613 100644 --- a/program/tests/vsa_create.rs +++ b/program/tests/vsa_create.rs @@ -55,8 +55,7 @@ async fn success_create_validator_stake_account() { &payer.pubkey(), &stake_account, &vote.pubkey(), - ) - .unwrap()], + )], Some(&payer.pubkey()), ); transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); @@ -103,8 +102,7 @@ async fn fail_create_validator_stake_account_on_non_vote_account() { &payer.pubkey(), &stake_account, &validator, - ) - .unwrap()], + )], Some(&payer.pubkey()), ); transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); @@ -241,8 +239,7 @@ async fn fail_create_validator_stake_account_with_incorrect_address() { &payer.pubkey(), &stake_account.pubkey(), &validator, - ) - .unwrap()], + )], Some(&payer.pubkey()), ); transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index b0fdbd18..7e8253c2 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -178,8 +178,7 @@ async fn fail_with_wrong_validator_list_account() { &wrong_validator_list.pubkey(), &validator_stake.stake_account, &validator_stake.transient_stake_account, - ) - .unwrap()], + )], Some(&payer.pubkey()), ); transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); @@ -301,8 +300,7 @@ async fn fail_wrong_staker() { &stake_pool_accounts.validator_list.pubkey(), &validator_stake.stake_account, &validator_stake.transient_stake_account, - ) - .unwrap()], + )], Some(&payer.pubkey()), ); transaction.sign(&[&payer, &malicious], recent_blockhash); diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 84b4d24d..3070ba6d 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -345,8 +345,7 @@ async fn fail_with_wrong_token_program_id() { &stake_pool_accounts.pool_mint.pubkey(), &wrong_token_program.pubkey(), tokens_to_burn, - ) - .unwrap()], + )], Some(&payer.pubkey()), &[&payer, &user_transfer_authority], recent_blockhash, From 3c316d5c050e1119a4a43b92ab1a745638a4e10a Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 11 May 2021 23:46:49 +0200 Subject: [PATCH 0101/1076] stake-pool: Bump version for release (#1707) --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index c663f864..d178b8e1 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -20,7 +20,7 @@ solana-logger = "1.6.7" solana-sdk = "1.6.7" solana-program = "1.6.7" spl-associated-token-account = { version = "1.0", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } -spl-stake-pool = { version = "0.1", path="../program", features = [ "no-entrypoint" ] } +spl-stake-pool = { version = "0.2", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "3.1", path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" bincode = "1.3.1" diff --git a/program/Cargo.toml b/program/Cargo.toml index d8af915b..1b5fdbba 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "spl-stake-pool" -version = "0.1.0" +version = "0.2.0" description = "Solana Program Library Stake Pool" authors = ["Solana Maintainers "] repository = "https://github.com/solana-labs/solana-program-library" From d239e1adcf093873fff56cadddbb4b879f482a51 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 12 May 2021 15:20:48 +0200 Subject: [PATCH 0102/1076] stake-pool-cli: Bump version for release (#1713) * stake-pool-cli: Bump version for release * Update lock file --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index d178b8e1..850cf0f3 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -6,7 +6,7 @@ homepage = "https://spl.solana.com/stake-pool" license = "Apache-2.0" name = "spl-stake-pool-cli" repository = "https://github.com/solana-labs/solana-program-library" -version = "0.1.0" +version = "0.2.0" [dependencies] borsh = "0.8" From 896e66e8f8a6fe10c0b6577905f1e6d54578ea19 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 20 May 2021 13:53:06 +0200 Subject: [PATCH 0103/1076] stake-pool: Fix fee calculation (#1764) * stake-pool: Fix fee calculation * Remove unwraps, widen one more calc --- program/src/state.rs | 97 ++++++++++++++++++++-- program/tests/update_stake_pool_balance.rs | 21 ++--- 2 files changed, 103 insertions(+), 15 deletions(-) diff --git a/program/src/state.rs b/program/src/state.rs index f7f5dc13..cd8a293b 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -113,16 +113,24 @@ impl StakePool { ) .ok() } - /// calculate the fee in pool tokens that goes to the manager + + /// Calculate the fee in pool tokens that goes to the manager + /// + /// This function assumes that `reward_lamports` has not already been added + /// to the stake pool's `total_stake_lamports` pub fn calc_fee_amount(&self, reward_lamports: u64) -> Option { if self.fee.denominator == 0 { return Some(0); } - let pool_amount = self.calc_pool_tokens_for_deposit(reward_lamports)?; + let total_stake_lamports = + (self.total_stake_lamports as u128).checked_add(reward_lamports as u128)?; + let fee_lamports = (reward_lamports as u128) + .checked_mul(self.fee.numerator as u128)? + .checked_div(self.fee.denominator as u128)?; u64::try_from( - (pool_amount as u128) - .checked_mul(self.fee.numerator as u128)? - .checked_div(self.fee.denominator as u128)?, + (self.pool_token_supply as u128) + .checked_mul(fee_lamports)? + .checked_div(total_stake_lamports.checked_sub(fee_lamports)?)?, ) .ok() } @@ -388,6 +396,7 @@ mod test { crate::borsh::{get_instance_packed_len, try_from_slice_unchecked}, proptest::prelude::*, solana_program::borsh::get_packed_len, + solana_program::native_token::LAMPORTS_PER_SOL, }; #[test] @@ -461,4 +470,82 @@ mod test { assert_eq!(ValidatorList::calculate_max_validators(size.saturating_sub(1)), (test_amount.saturating_sub(1)) as usize); } } + + prop_compose! { + fn fee()(denominator in 1..=u16::MAX)( + denominator in Just(denominator), + numerator in 0..=denominator, + ) -> (u64, u64) { + (numerator as u64, denominator as u64) + } + } + + prop_compose! { + fn total_stake_and_rewards()(total_stake_lamports in 1..u64::MAX)( + total_stake_lamports in Just(total_stake_lamports), + rewards in 0..=total_stake_lamports, + ) -> (u64, u64) { + (total_stake_lamports - rewards, rewards) + } + } + + #[test] + fn specific_fee_calculation() { + // 10% of 10 SOL in rewards should be 1 SOL in fees + let fee = Fee { + numerator: 1, + denominator: 10, + }; + let mut stake_pool = StakePool { + total_stake_lamports: 100 * LAMPORTS_PER_SOL, + pool_token_supply: 100 * LAMPORTS_PER_SOL, + fee, + ..StakePool::default() + }; + let reward_lamports = 10 * LAMPORTS_PER_SOL; + let pool_token_fee = stake_pool.calc_fee_amount(reward_lamports).unwrap(); + + stake_pool.total_stake_lamports += reward_lamports; + stake_pool.pool_token_supply += pool_token_fee; + + let fee_lamports = stake_pool + .calc_lamports_withdraw_amount(pool_token_fee) + .unwrap(); + assert_eq!(fee_lamports, LAMPORTS_PER_SOL - 1); // lose 1 lamport of precision + } + + proptest! { + #[test] + fn fee_calculation( + (numerator, denominator) in fee(), + (total_stake_lamports, reward_lamports) in total_stake_and_rewards(), + ) { + let fee = Fee { denominator, numerator }; + let mut stake_pool = StakePool { + total_stake_lamports, + pool_token_supply: total_stake_lamports, + fee, + ..StakePool::default() + }; + let pool_token_fee = stake_pool.calc_fee_amount(reward_lamports).unwrap(); + + stake_pool.total_stake_lamports += reward_lamports; + stake_pool.pool_token_supply += pool_token_fee; + + let fee_lamports = stake_pool.calc_lamports_withdraw_amount(pool_token_fee).unwrap(); + let max_fee_lamports = u64::try_from((reward_lamports as u128) * (fee.numerator as u128) / (fee.denominator as u128)).unwrap(); + assert!(max_fee_lamports >= fee_lamports, + "Max possible fee must always be greater than or equal to what is actually withdrawn, max {} actual {}", + max_fee_lamports, + fee_lamports); + + // since we do two "flooring" conversions, the max epsilon should be + // correct up to 2 lamports (one for each floor division), plus a + // correction for huge discrepancies between rewards and total stake + let epsilon = 2 + reward_lamports / total_stake_lamports; + assert!(max_fee_lamports - fee_lamports <= epsilon, + "Max expected fee in lamports {}, actually receive {}, epsilon {}", + max_fee_lamports, fee_lamports, epsilon); + } + } } diff --git a/program/tests/update_stake_pool_balance.rs b/program/tests/update_stake_pool_balance.rs index bedb32fc..22fd5623 100644 --- a/program/tests/update_stake_pool_balance.rs +++ b/program/tests/update_stake_pool_balance.rs @@ -150,17 +150,18 @@ async fn success() { &stake_pool_accounts.pool_mint.pubkey(), ) .await; + assert_eq!(pool_token_supply - pre_token_supply, actual_fee); + + let expected_fee_lamports = + (post_balance - pre_balance) * stake_pool.fee.numerator / stake_pool.fee.denominator; + let actual_fee_lamports = stake_pool + .calc_pool_tokens_for_withdraw(actual_fee) + .unwrap(); + assert!(actual_fee_lamports <= expected_fee_lamports); + + let expected_fee = expected_fee_lamports * pool_token_supply / post_balance; + assert_eq!(expected_fee, actual_fee); - let stake_pool_info = get_account( - &mut context.banks_client, - &stake_pool_accounts.stake_pool.pubkey(), - ) - .await; - let stake_pool = StakePool::try_from_slice(&stake_pool_info.data).unwrap(); - let expected_fee = (post_balance - pre_balance) * pre_token_supply / pre_balance - * stake_pool.fee.numerator - / stake_pool.fee.denominator; - assert_eq!(actual_fee, expected_fee); assert_eq!(pool_token_supply, stake_pool.pool_token_supply); } From 1e67d3000a2c38ae7ddae5ce98e41b52aaed653a Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Fri, 21 May 2021 21:45:42 -0700 Subject: [PATCH 0104/1076] Add forward compatibility with solana-client 1.6.10 --- clients/cli/src/client.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clients/cli/src/client.rs b/clients/cli/src/client.rs index 1a06e722..d77a564c 100644 --- a/clients/cli/src/client.rs +++ b/clients/cli/src/client.rs @@ -86,6 +86,7 @@ pub(crate) fn get_stake_accounts_by_withdraw_authority( rpc_client .get_program_accounts_with_config( &stake_program::id(), + #[allow(clippy::needless_update)] // TODO: Remove after updating to solana >=1.6.10 RpcProgramAccountsConfig { filters: Some(vec![RpcFilterType::Memcmp(Memcmp { offset: 44, // 44 is Withdrawer authority offset in stake account stake @@ -96,6 +97,7 @@ pub(crate) fn get_stake_accounts_by_withdraw_authority( encoding: Some(UiAccountEncoding::Base64), ..RpcAccountInfoConfig::default() }, + ..RpcProgramAccountsConfig::default() }, ) .map(|accounts| { From 698baadea612e4b866a454943a37e637086da33c Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 28 May 2021 11:46:57 +0200 Subject: [PATCH 0105/1076] stake-pool: Add program_id to all instruction ctors (#1814) --- clients/cli/src/main.rs | 6 ++++ program/src/instruction.rs | 58 +++++++++++++++++++++----------------- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index bd2e58d7..ab89b54f 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -287,6 +287,7 @@ fn command_vsa_create( &[ // Create new validator stake account address spl_stake_pool::instruction::create_validator_stake_account_with_vote( + &spl_stake_pool::id(), &stake_pool_address, &config.staker.pubkey(), &config.fee_payer.pubkey(), @@ -342,6 +343,7 @@ fn command_vsa_add( } let instruction = spl_stake_pool::instruction::add_validator_to_pool_with_vote( + &spl_stake_pool::id(), &stake_pool, &stake_pool_address, &vote_account, @@ -378,6 +380,7 @@ fn command_vsa_remove( &[ // Create new validator stake account address spl_stake_pool::instruction::remove_validator_from_pool_with_vote( + &spl_stake_pool::id(), &stake_pool, stake_pool_address, vote_account, @@ -410,6 +413,7 @@ fn command_increase_validator_stake( let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; let instruction = spl_stake_pool::instruction::increase_validator_stake_with_vote( + &spl_stake_pool::id(), &stake_pool, stake_pool_address, vote_account, @@ -442,6 +446,7 @@ fn command_decrease_validator_stake( let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; let instruction = spl_stake_pool::instruction::decrease_validator_stake_with_vote( + &spl_stake_pool::id(), &stake_pool, stake_pool_address, vote_account, @@ -687,6 +692,7 @@ fn command_update( let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?; let instructions = spl_stake_pool::instruction::update_stake_pool( + &spl_stake_pool::id(), &stake_pool, &validator_list, stake_pool_address, diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 63bb085d..7f884c58 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -5,7 +5,7 @@ use { crate::{ find_deposit_authority_program_address, find_stake_program_address, - find_transient_stake_program_address, find_withdraw_authority_program_address, id, + find_transient_stake_program_address, find_withdraw_authority_program_address, stake_program, state::{Fee, StakePool, ValidatorList}, MAX_VALIDATORS_TO_UPDATE, @@ -467,16 +467,17 @@ pub fn increase_validator_stake( /// Creates `CreateValidatorStakeAccount` instruction with a vote account pub fn create_validator_stake_account_with_vote( + program_id: &Pubkey, stake_pool_address: &Pubkey, staker: &Pubkey, funder: &Pubkey, vote_account_address: &Pubkey, ) -> Instruction { let (stake_account, _) = - find_stake_program_address(&id(), vote_account_address, stake_pool_address); + find_stake_program_address(program_id, vote_account_address, stake_pool_address); create_validator_stake_account( - &id(), - &stake_pool_address, + program_id, + stake_pool_address, staker, funder, &stake_account, @@ -487,17 +488,18 @@ pub fn create_validator_stake_account_with_vote( /// Create an `AddValidatorToPool` instruction given an existing stake pool and /// vote account pub fn add_validator_to_pool_with_vote( + program_id: &Pubkey, stake_pool: &StakePool, stake_pool_address: &Pubkey, vote_account_address: &Pubkey, ) -> Instruction { let pool_withdraw_authority = - find_withdraw_authority_program_address(&id(), stake_pool_address).0; + find_withdraw_authority_program_address(program_id, stake_pool_address).0; let (stake_account_address, _) = - find_stake_program_address(&id(), vote_account_address, stake_pool_address); + find_stake_program_address(program_id, vote_account_address, stake_pool_address); add_validator_to_pool( - &id(), - &stake_pool_address, + program_id, + stake_pool_address, &stake_pool.staker, &pool_withdraw_authority, &stake_pool.validator_list, @@ -508,23 +510,24 @@ pub fn add_validator_to_pool_with_vote( /// Create an `RemoveValidatorFromPool` instruction given an existing stake pool and /// vote account pub fn remove_validator_from_pool_with_vote( + program_id: &Pubkey, stake_pool: &StakePool, stake_pool_address: &Pubkey, vote_account_address: &Pubkey, new_stake_account_authority: &Pubkey, ) -> Instruction { let pool_withdraw_authority = - find_withdraw_authority_program_address(&id(), stake_pool_address).0; + find_withdraw_authority_program_address(program_id, stake_pool_address).0; let (stake_account_address, _) = - find_stake_program_address(&id(), vote_account_address, stake_pool_address); + find_stake_program_address(program_id, vote_account_address, stake_pool_address); let (transient_stake_account, _) = - find_transient_stake_program_address(&id(), &vote_account_address, stake_pool_address); + find_transient_stake_program_address(program_id, &vote_account_address, stake_pool_address); remove_validator_from_pool( - &id(), - &stake_pool_address, + program_id, + stake_pool_address, &stake_pool.staker, &pool_withdraw_authority, - &new_stake_account_authority, + new_stake_account_authority, &stake_pool.validator_list, &stake_account_address, &transient_stake_account, @@ -534,25 +537,26 @@ pub fn remove_validator_from_pool_with_vote( /// Create an `IncreaseValidatorStake` instruction given an existing stake pool and /// vote account pub fn increase_validator_stake_with_vote( + program_id: &Pubkey, stake_pool: &StakePool, stake_pool_address: &Pubkey, vote_account_address: &Pubkey, lamports: u64, ) -> Instruction { let pool_withdraw_authority = - find_withdraw_authority_program_address(&id(), stake_pool_address).0; + find_withdraw_authority_program_address(program_id, stake_pool_address).0; let (transient_stake_address, _) = - find_transient_stake_program_address(&id(), &vote_account_address, stake_pool_address); + find_transient_stake_program_address(program_id, vote_account_address, stake_pool_address); increase_validator_stake( - &id(), - &stake_pool_address, + program_id, + stake_pool_address, &stake_pool.staker, &pool_withdraw_authority, &stake_pool.validator_list, &stake_pool.reserve_stake, &transient_stake_address, - &vote_account_address, + vote_account_address, lamports, ) } @@ -560,19 +564,20 @@ pub fn increase_validator_stake_with_vote( /// Create a `DecreaseValidatorStake` instruction given an existing stake pool and /// vote account pub fn decrease_validator_stake_with_vote( + program_id: &Pubkey, stake_pool: &StakePool, stake_pool_address: &Pubkey, vote_account_address: &Pubkey, lamports: u64, ) -> Instruction { let pool_withdraw_authority = - find_withdraw_authority_program_address(&id(), stake_pool_address).0; + find_withdraw_authority_program_address(program_id, stake_pool_address).0; let (validator_stake_address, _) = - find_stake_program_address(&id(), &vote_account_address, stake_pool_address); + find_stake_program_address(program_id, &vote_account_address, stake_pool_address); let (transient_stake_address, _) = - find_transient_stake_program_address(&id(), &vote_account_address, stake_pool_address); + find_transient_stake_program_address(program_id, &vote_account_address, stake_pool_address); decrease_validator_stake( - &id(), + program_id, &stake_pool_address, &stake_pool.staker, &pool_withdraw_authority, @@ -665,6 +670,7 @@ pub fn update_stake_pool_balance( /// Creates all `UpdateValidatorListBalance` and `UpdateStakePoolBalance` /// instructions for fully updating a stake pool each epoch pub fn update_stake_pool( + program_id: &Pubkey, stake_pool: &StakePool, validator_list: &ValidatorList, stake_pool_address: &Pubkey, @@ -677,13 +683,13 @@ pub fn update_stake_pool( .collect(); let (withdraw_authority, _) = - find_withdraw_authority_program_address(&id(), &stake_pool_address); + find_withdraw_authority_program_address(program_id, stake_pool_address); let mut instructions: Vec = vec![]; let mut start_index = 0; for accounts_chunk in vote_accounts.chunks(MAX_VALIDATORS_TO_UPDATE) { instructions.push(update_validator_list_balance( - &id(), + program_id, stake_pool_address, &withdraw_authority, &stake_pool.validator_list, @@ -696,7 +702,7 @@ pub fn update_stake_pool( } instructions.push(update_stake_pool_balance( - &id(), + program_id, stake_pool_address, &withdraw_authority, &stake_pool.validator_list, From 2df9abe581b2843158c185f5ad3aefa9a1ee6bc9 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 1 Jun 2021 12:45:27 +0200 Subject: [PATCH 0106/1076] stake-pool: Add preferred deposit / withdraw validator accounts (#1831) * stake-pool: Add set preferred validator instruction * Add functionality for using the preferred deposit / withdraw * Add CLI support --- clients/cli/src/main.rs | 87 +++++++ program/src/error.rs | 8 + program/src/instruction.rs | 58 +++++ program/src/processor.rs | 94 ++++++- program/src/state.rs | 20 +- program/tests/deposit.rs | 433 ++++++++++++++++----------------- program/tests/helpers/mod.rs | 44 +++- program/tests/set_fee.rs | 5 +- program/tests/set_preferred.rs | 238 ++++++++++++++++++ program/tests/vsa_add.rs | 2 + program/tests/vsa_remove.rs | 72 ++++++ program/tests/withdraw.rs | 208 ++++++++++++---- 12 files changed, 989 insertions(+), 280 deletions(-) create mode 100644 program/tests/set_preferred.rs diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index ab89b54f..b21d5ecc 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -32,6 +32,7 @@ use { self, borsh::get_instance_packed_len, find_stake_program_address, find_withdraw_authority_program_address, + instruction::PreferredValidatorType, stake_program::{self, StakeState}, state::{Fee, StakePool, ValidatorList}, }, @@ -466,6 +467,34 @@ fn command_decrease_validator_stake( Ok(()) } +fn command_set_preferred_validator( + config: &Config, + stake_pool_address: &Pubkey, + preferred_type: PreferredValidatorType, + vote_address: Option, +) -> CommandResult { + let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; + let mut transaction = Transaction::new_with_payer( + &[spl_stake_pool::instruction::set_preferred_validator( + &spl_stake_pool::id(), + &stake_pool_address, + &config.staker.pubkey(), + &stake_pool.validator_list, + preferred_type, + vote_address, + )], + Some(&config.fee_payer.pubkey()), + ); + + let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; + let mut signers = vec![config.fee_payer.as_ref(), config.staker.as_ref()]; + unique_signers!(signers); + transaction.sign(&signers, recent_blockhash); + send_transaction(&config, transaction)?; + Ok(()) +} + fn add_associated_token_account( config: &Config, mint: &Pubkey, @@ -1340,6 +1369,46 @@ fn main() { .help("Amount in lamports to remove from the validator stake account. Must be at least the rent-exempt amount for a stake."), ) ) + .subcommand(SubCommand::with_name("set-preferred-validator") + .about("Set the preferred validator for deposits or withdrawals. Must be signed by the pool staker.") + .arg( + Arg::with_name("pool") + .index(1) + .validator(is_pubkey) + .value_name("POOL_ADDRESS") + .takes_value(true) + .required(true) + .help("Stake pool address"), + ) + .arg( + Arg::with_name("preferred_type") + .index(2) + .value_name("OPERATION") + .possible_values(&["deposit", "withdraw"]) // PreferredValidatorType enum + .takes_value(true) + .required(true) + .help("Operation for which to restrict the validator"), + ) + .arg( + Arg::with_name("vote_account") + .long("vote-account") + .validator(is_pubkey) + .value_name("VOTE_ACCOUNT_ADDRESS") + .takes_value(true) + .help("Vote account for the validator that users must deposit into."), + ) + .arg( + Arg::with_name("unset") + .long("unset") + .takes_value(false) + .help("Unset the preferred validator."), + ) + .group(ArgGroup::with_name("validator") + .arg("vote_account") + .arg("unset") + .required(true) + ) + ) .subcommand(SubCommand::with_name("deposit") .about("Add stake account to the stake pool") .arg( @@ -1678,6 +1747,24 @@ fn main() { let amount = value_t_or_exit!(arg_matches, "amount", f64); command_decrease_validator_stake(&config, &stake_pool_address, &vote_account, amount) } + ("set-preferred-validator", Some(arg_matches)) => { + let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); + let preferred_type = match arg_matches.value_of("preferred_type").unwrap() { + "deposit" => PreferredValidatorType::Deposit, + "withdraw" => PreferredValidatorType::Withdraw, + _ => unreachable!(), + }; + let vote_account = pubkey_of(arg_matches, "vote_account"); + let _unset = arg_matches.is_present("unset"); + // since unset and vote_account can't both be set, if unset is set + // then vote_account will be None, which is valid for the program + command_set_preferred_validator( + &config, + &stake_pool_address, + preferred_type, + vote_account, + ) + } ("deposit", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); let stake_account = pubkey_of(arg_matches, "stake_account").unwrap(); diff --git a/program/src/error.rs b/program/src/error.rs index 7fa227e7..000b25a5 100644 --- a/program/src/error.rs +++ b/program/src/error.rs @@ -88,6 +88,14 @@ pub enum StakePoolError { /// The lamports in the validator stake account is not equal to the minimum #[error("StakeLamportsNotEqualToMinimum")] StakeLamportsNotEqualToMinimum, + /// The provided deposit stake account is not delegated to the preferred deposit vote account + #[error("IncorrectDepositVoteAddress")] + IncorrectDepositVoteAddress, + + // 25. + /// The provided withdraw stake account is not the preferred deposit vote account + #[error("IncorrectWithdrawVoteAddress")] + IncorrectWithdrawVoteAddress, } impl From for ProgramError { fn from(e: StakePoolError) -> Self { diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 7f884c58..51f2c916 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -18,6 +18,17 @@ use { }, }; +/// Defines which validator vote account is set during the +/// `SetPreferredValidator` instruction +#[repr(C)] +#[derive(Clone, Debug, PartialEq, BorshSerialize, BorshDeserialize, BorshSchema)] +pub enum PreferredValidatorType { + /// Set preferred validator for deposits + Deposit, + /// Set preferred validator for withdraws + Withdraw, +} + /// Instructions supported by the StakePool program. #[repr(C)] #[derive(Clone, Debug, PartialEq, BorshSerialize, BorshDeserialize, BorshSchema)] @@ -154,6 +165,28 @@ pub enum StakePoolInstruction { /// userdata: amount of lamports to split into the transient stake account IncreaseValidatorStake(u64), + /// (Staker only) Set the preferred deposit or withdraw stake account for the + /// stake pool + /// + /// In order to avoid users abusing the stake pool as a free conversion + /// between SOL staked on different validators, the staker can force all + /// deposits and/or withdraws to go to one chosen account, or unset that account. + /// + /// 0. `[]` Stake pool + /// 1. `[s]` Stake pool staker + /// 2. `[w]` Validator list + /// + /// Fails if the validator is not part of the stake pool. + SetPreferredValidator { + /// Affected operation (deposit or withdraw) + #[allow(dead_code)] // but it's not + validator_type: PreferredValidatorType, + /// Validator vote account that deposits or withdraws must go through, + /// unset with None + #[allow(dead_code)] // but it's not + validator_vote_address: Option, + }, + /// Updates balances of validator and transient stake accounts in the pool /// /// While going through the pairs of validator and transient stake accounts, @@ -465,6 +498,31 @@ pub fn increase_validator_stake( } } +/// Creates `SetPreferredDepositValidator` instruction +pub fn set_preferred_validator( + program_id: &Pubkey, + stake_pool_address: &Pubkey, + staker: &Pubkey, + validator_list_address: &Pubkey, + validator_type: PreferredValidatorType, + validator_vote_address: Option, +) -> Instruction { + Instruction { + program_id: *program_id, + accounts: vec![ + AccountMeta::new_readonly(*stake_pool_address, false), + AccountMeta::new_readonly(*staker, true), + AccountMeta::new(*validator_list_address, false), + ], + data: StakePoolInstruction::SetPreferredValidator { + validator_type, + validator_vote_address, + } + .try_to_vec() + .unwrap(), + } +} + /// Creates `CreateValidatorStakeAccount` instruction with a vote account pub fn create_validator_stake_account_with_vote( program_id: &Pubkey, diff --git a/program/src/processor.rs b/program/src/processor.rs index 9c253d37..57e8399f 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -5,7 +5,7 @@ use { borsh::try_from_slice_unchecked, error::StakePoolError, find_deposit_authority_program_address, - instruction::StakePoolInstruction, + instruction::{PreferredValidatorType, StakePoolInstruction}, minimum_reserve_lamports, minimum_stake_lamports, stake_program, state::{AccountType, Fee, StakePool, StakeStatus, ValidatorList, ValidatorStakeInfo}, AUTHORITY_DEPOSIT, AUTHORITY_WITHDRAW, MINIMUM_ACTIVE_STAKE, TRANSIENT_STAKE_SEED, @@ -432,6 +432,8 @@ impl Processor { return Err(StakePoolError::UnexpectedValidatorListAccountSize.into()); } validator_list.account_type = AccountType::ValidatorList; + validator_list.preferred_deposit_validator_vote_address = None; + validator_list.preferred_withdraw_validator_vote_address = None; validator_list.validators.clear(); validator_list.max_validators = max_validators; @@ -862,6 +864,13 @@ impl Processor { .retain(|item| item.vote_account_address != vote_account_address), _ => unreachable!(), } + + if validator_list.preferred_deposit_validator_vote_address == Some(vote_account_address) { + validator_list.preferred_deposit_validator_vote_address = None; + } + if validator_list.preferred_withdraw_validator_vote_address == Some(vote_account_address) { + validator_list.preferred_withdraw_validator_vote_address = None; + } validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; Ok(()) @@ -1150,6 +1159,55 @@ impl Processor { Ok(()) } + /// Process `SetPreferredValidator` instruction + fn process_set_preferred_validator( + program_id: &Pubkey, + accounts: &[AccountInfo], + validator_type: PreferredValidatorType, + vote_account_address: Option, + ) -> ProgramResult { + let account_info_iter = &mut accounts.iter(); + let stake_pool_info = next_account_info(account_info_iter)?; + let staker_info = next_account_info(account_info_iter)?; + let validator_list_info = next_account_info(account_info_iter)?; + + check_account_owner(stake_pool_info, program_id)?; + check_account_owner(validator_list_info, program_id)?; + + let stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; + if !stake_pool.is_valid() { + msg!("Expected valid stake pool"); + return Err(StakePoolError::InvalidState.into()); + } + + stake_pool.check_staker(staker_info)?; + stake_pool.check_validator_list(validator_list_info)?; + + let mut validator_list = + try_from_slice_unchecked::(&validator_list_info.data.borrow())?; + if !validator_list.is_valid() { + return Err(StakePoolError::InvalidState.into()); + } + + if let Some(vote_account_address) = vote_account_address { + if !validator_list.contains(&vote_account_address) { + msg!("Validator for {} not present in the stake pool, cannot set as preferred deposit account"); + return Err(StakePoolError::ValidatorNotFound.into()); + } + } + + match validator_type { + PreferredValidatorType::Deposit => { + validator_list.preferred_deposit_validator_vote_address = vote_account_address + } + PreferredValidatorType::Withdraw => { + validator_list.preferred_withdraw_validator_vote_address = vote_account_address + } + }; + validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; + Ok(()) + } + /// Processes `UpdateValidatorListBalance` instruction. fn process_update_validator_list_balance( program_id: &Pubkey, @@ -1484,7 +1542,6 @@ impl Processor { let clock_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(clock_info)?; let stake_history_info = next_account_info(account_info_iter)?; - //let stake_history = &StakeHistory::from_account_info(stake_history_info)?; let token_program_info = next_account_info(account_info_iter)?; let stake_program_info = next_account_info(account_info_iter)?; @@ -1533,6 +1590,11 @@ impl Processor { validator_stake_account_info.key, &vote_account_address, )?; + if let Some(preferred_deposit) = validator_list.preferred_deposit_validator_vote_address { + if preferred_deposit != vote_account_address { + return Err(StakePoolError::IncorrectDepositVoteAddress.into()); + } + } let validator_list_item = validator_list .find_mut(&vote_account_address) @@ -1717,6 +1779,20 @@ impl Processor { &vote_account_address, )?; + if let Some(preferred_withdraw_validator) = + validator_list.preferred_withdraw_validator_vote_address + { + let preferred_validator_info = validator_list + .find(&preferred_withdraw_validator) + .ok_or(StakePoolError::ValidatorNotFound)?; + if preferred_withdraw_validator != vote_account_address + && preferred_validator_info.stake_lamports > 0 + { + msg!("Validator vote address {} is preferred for withdrawals, it currently has {} lamports available. Please withdraw those before using other validator stake accounts.", preferred_withdraw_validator, preferred_validator_info.stake_lamports); + return Err(StakePoolError::IncorrectWithdrawVoteAddress.into()); + } + } + let validator_list_item = validator_list .find_mut(&vote_account_address) .ok_or(StakePoolError::ValidatorNotFound)?; @@ -1901,6 +1977,18 @@ impl Processor { msg!("Instruction: IncreaseValidatorStake"); Self::process_increase_validator_stake(program_id, accounts, amount) } + StakePoolInstruction::SetPreferredValidator { + validator_type, + validator_vote_address, + } => { + msg!("Instruction: SetPreferredValidator"); + Self::process_set_preferred_validator( + program_id, + accounts, + validator_type, + validator_vote_address, + ) + } StakePoolInstruction::UpdateValidatorListBalance { start_index, no_merge, @@ -1973,6 +2061,8 @@ impl PrintProgramError for StakePoolError { StakePoolError::WrongStaker=> msg!("Error: Wrong pool staker account"), StakePoolError::NonZeroPoolTokenSupply => msg!("Error: Pool token supply is not zero on initialization"), StakePoolError::StakeLamportsNotEqualToMinimum => msg!("Error: The lamports in the validator stake account is not equal to the minimum"), + StakePoolError::IncorrectDepositVoteAddress => msg!("Error: The provided deposit stake account is not delegated to the preferred deposit vote account"), + StakePoolError::IncorrectWithdrawVoteAddress => msg!("Error: The provided withdraw stake account is not the preferred deposit vote account"), } } } diff --git a/program/src/state.rs b/program/src/state.rs index cd8a293b..d4551f6a 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -286,6 +286,12 @@ pub struct ValidatorList { /// Account type, must be ValidatorList currently pub account_type: AccountType, + /// Preferred deposit validator vote account pubkey + pub preferred_deposit_validator_vote_address: Option, + + /// Preferred withdraw validator vote account pubkey + pub preferred_withdraw_validator_vote_address: Option, + /// Maximum allowable number of validators pub max_validators: u32, @@ -332,10 +338,12 @@ pub struct ValidatorStakeInfo { } impl ValidatorList { - /// Create an empty instance containing space for `max_validators` + /// Create an empty instance containing space for `max_validators` and preferred validator keys pub fn new(max_validators: u32) -> Self { Self { account_type: AccountType::ValidatorList, + preferred_deposit_validator_vote_address: Some(Pubkey::default()), + preferred_withdraw_validator_vote_address: Some(Pubkey::default()), max_validators, validators: vec![ValidatorStakeInfo::default(); max_validators as usize], } @@ -343,7 +351,7 @@ impl ValidatorList { /// Calculate the number of validator entries that fit in the provided length pub fn calculate_max_validators(buffer_length: usize) -> usize { - let header_size = 1 + 4 + 4; + let header_size = 1 + 4 + 4 + 33 + 33; buffer_length.saturating_sub(header_size) / 49 } @@ -406,6 +414,8 @@ mod test { // Not initialized let stake_list = ValidatorList { account_type: AccountType::Uninitialized, + preferred_deposit_validator_vote_address: None, + preferred_withdraw_validator_vote_address: None, max_validators: 0, validators: vec![], }; @@ -415,9 +425,11 @@ mod test { let stake_list_unpacked = try_from_slice_unchecked::(&byte_vec).unwrap(); assert_eq!(stake_list_unpacked, stake_list); - // Empty + // Empty, one preferred key let stake_list = ValidatorList { account_type: AccountType::ValidatorList, + preferred_deposit_validator_vote_address: Some(Pubkey::new_unique()), + preferred_withdraw_validator_vote_address: None, max_validators: 0, validators: vec![], }; @@ -430,6 +442,8 @@ mod test { // With several accounts let stake_list = ValidatorList { account_type: AccountType::ValidatorList, + preferred_deposit_validator_vote_address: Some(Pubkey::new_unique()), + preferred_withdraw_validator_vote_address: Some(Pubkey::new_unique()), max_validators, validators: vec![ ValidatorStakeInfo { diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index d19a9144..0531707c 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -32,6 +32,10 @@ async fn setup() -> ( Hash, StakePoolAccounts, ValidatorStakeAccount, + Keypair, + Pubkey, + Pubkey, + u64, ) { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); @@ -40,7 +44,7 @@ async fn setup() -> ( .await .unwrap(); - let validator_stake_account: ValidatorStakeAccount = simple_add_validator_to_pool( + let validator_stake_account = simple_add_validator_to_pool( &mut banks_client, &payer, &recent_blockhash, @@ -48,73 +52,77 @@ async fn setup() -> ( ) .await; - ( - banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - validator_stake_account, - ) -} - -#[tokio::test] -async fn test_stake_pool_deposit() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake_account) = - setup().await; - let user = Keypair::new(); // make stake account - let user_stake = Keypair::new(); + let deposit_stake = Keypair::new(); let lockup = stake_program::Lockup::default(); - let stake_authority = Keypair::new(); let authorized = stake_program::Authorized { - staker: stake_authority.pubkey(), - withdrawer: stake_authority.pubkey(), + staker: user.pubkey(), + withdrawer: user.pubkey(), }; let stake_lamports = create_independent_stake_account( &mut banks_client, &payer, &recent_blockhash, - &user_stake, + &deposit_stake, &authorized, &lockup, TEST_STAKE_AMOUNT, ) .await; - create_vote( - &mut banks_client, - &payer, - &recent_blockhash, - &validator_stake_account.validator, - &validator_stake_account.vote, - ) - .await; delegate_stake_account( &mut banks_client, &payer, &recent_blockhash, - &user_stake.pubkey(), - &stake_authority, + &deposit_stake.pubkey(), + &user, &validator_stake_account.vote.pubkey(), ) .await; // make pool token account - let user_pool_account = Keypair::new(); + let pool_token_account = Keypair::new(); create_token_account( &mut banks_client, &payer, &recent_blockhash, - &user_pool_account, + &pool_token_account, &stake_pool_accounts.pool_mint.pubkey(), &user.pubkey(), ) .await .unwrap(); + ( + banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + validator_stake_account, + user, + deposit_stake.pubkey(), + pool_token_account.pubkey(), + stake_lamports, + ) +} + +#[tokio::test] +async fn success() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + validator_stake_account, + user, + deposit_stake, + pool_token_account, + stake_lamports, + ) = setup().await; + // Save stake pool state before depositing let stake_pool_before = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; @@ -133,22 +141,22 @@ async fn test_stake_pool_deposit() { .find(&validator_stake_account.vote.pubkey()) .unwrap(); - stake_pool_accounts + let error = stake_pool_accounts .deposit_stake( &mut banks_client, &payer, &recent_blockhash, - &user_stake.pubkey(), - &user_pool_account.pubkey(), + &deposit_stake, + &pool_token_account, &validator_stake_account.stake_account, - &stake_authority, + &user, ) - .await - .unwrap(); + .await; + assert!(error.is_none()); // Original stake account should be drained assert!(banks_client - .get_account(user_stake.pubkey()) + .get_account(deposit_stake) .await .expect("get_account") .is_none()); @@ -168,8 +176,7 @@ async fn test_stake_pool_deposit() { ); // Check minted tokens - let user_token_balance = - get_token_balance(&mut banks_client, &user_pool_account.pubkey()).await; + let user_token_balance = get_token_balance(&mut banks_client, &pool_token_account).await; assert_eq!(user_token_balance, tokens_issued); // Check balances in validator stake account list storage @@ -201,26 +208,18 @@ async fn test_stake_pool_deposit() { } #[tokio::test] -async fn test_stake_pool_deposit_with_wrong_stake_program_id() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake_account) = - setup().await; - - let user = Keypair::new(); - // make stake account - let user_stake = Keypair::new(); - - // make pool token account - let user_pool_account = Keypair::new(); - create_token_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_pool_account, - &stake_pool_accounts.pool_mint.pubkey(), - &user.pubkey(), - ) - .await - .unwrap(); +async fn fail_with_wrong_stake_program_id() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + validator_stake_account, + _user, + deposit_stake, + pool_token_account, + _stake_lamports, + ) = setup().await; let wrong_stake_program = Pubkey::new_unique(); @@ -229,9 +228,9 @@ async fn test_stake_pool_deposit_with_wrong_stake_program_id() { AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false), AccountMeta::new_readonly(stake_pool_accounts.deposit_authority, false), AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false), - AccountMeta::new(user_stake.pubkey(), false), + AccountMeta::new(deposit_stake, false), AccountMeta::new(validator_stake_account.stake_account, false), - AccountMeta::new(user_pool_account.pubkey(), false), + AccountMeta::new(pool_token_account, false), AccountMeta::new(stake_pool_accounts.pool_mint.pubkey(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), @@ -263,41 +262,18 @@ async fn test_stake_pool_deposit_with_wrong_stake_program_id() { } #[tokio::test] -async fn test_stake_pool_deposit_with_wrong_token_program_id() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake_account) = - setup().await; - - let user = Keypair::new(); - // make stake account - let user_stake = Keypair::new(); - let lockup = stake_program::Lockup::default(); - let authorized = stake_program::Authorized { - staker: user.pubkey(), - withdrawer: user.pubkey(), - }; - create_independent_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake, - &authorized, - &lockup, - TEST_STAKE_AMOUNT, - ) - .await; - - // make pool token account - let user_pool_account = Keypair::new(); - create_token_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_pool_account, - &stake_pool_accounts.pool_mint.pubkey(), - &user.pubkey(), - ) - .await - .unwrap(); +async fn fail_with_wrong_token_program_id() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + validator_stake_account, + user, + deposit_stake, + pool_token_account, + _stake_lamports, + ) = setup().await; let wrong_token_program = Keypair::new(); @@ -307,10 +283,10 @@ async fn test_stake_pool_deposit_with_wrong_token_program_id() { &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.validator_list.pubkey(), &stake_pool_accounts.withdraw_authority, - &user_stake.pubkey(), + &deposit_stake, &user.pubkey(), &validator_stake_account.stake_account, - &user_pool_account.pubkey(), + &pool_token_account, &stake_pool_accounts.pool_mint.pubkey(), &wrong_token_program.pubkey(), ), @@ -332,47 +308,19 @@ async fn test_stake_pool_deposit_with_wrong_token_program_id() { } #[tokio::test] -async fn test_stake_pool_deposit_with_wrong_validator_list_account() { +async fn fail_with_wrong_validator_list_account() { let ( mut banks_client, payer, recent_blockhash, mut stake_pool_accounts, validator_stake_account, + user, + deposit_stake, + pool_token_account, + _stake_lamports, ) = setup().await; - let user = Keypair::new(); - // make stake account - let user_stake = Keypair::new(); - let lockup = stake_program::Lockup::default(); - let authorized = stake_program::Authorized { - staker: user.pubkey(), - withdrawer: user.pubkey(), - }; - create_independent_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake, - &authorized, - &lockup, - TEST_STAKE_AMOUNT, - ) - .await; - - // make pool token account - let user_pool_account = Keypair::new(); - create_token_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_pool_account, - &stake_pool_accounts.pool_mint.pubkey(), - &user.pubkey(), - ) - .await - .unwrap(); - let wrong_validator_list = Keypair::new(); stake_pool_accounts.validator_list = wrong_validator_list; @@ -381,20 +329,20 @@ async fn test_stake_pool_deposit_with_wrong_validator_list_account() { &mut banks_client, &payer, &recent_blockhash, - &user_stake.pubkey(), - &user_pool_account.pubkey(), + &deposit_stake, + &pool_token_account, &validator_stake_account.stake_account, &user, ) .await - .err() + .unwrap() .unwrap(); match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError( + TransactionError::InstructionError( _, InstructionError::Custom(error_index), - )) => { + ) => { let program_error = error::StakePoolError::InvalidValidatorStakeList as u32; assert_eq!(error_index, program_error); } @@ -403,7 +351,7 @@ async fn test_stake_pool_deposit_with_wrong_validator_list_account() { } #[tokio::test] -async fn test_stake_pool_deposit_to_unknown_validator() { +async fn fail_with_unknown_validator() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts @@ -464,14 +412,11 @@ async fn test_stake_pool_deposit_to_unknown_validator() { &user, ) .await - .err() + .unwrap() .unwrap(); match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError( - _, - InstructionError::Custom(error_index), - )) => { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { let program_error = error::StakePoolError::ValidatorNotFound as u32; assert_eq!(error_index, program_error); } @@ -482,68 +427,37 @@ async fn test_stake_pool_deposit_to_unknown_validator() { } #[tokio::test] -async fn test_stake_pool_deposit_with_wrong_withdraw_authority() { +async fn fail_with_wrong_withdraw_authority() { let ( mut banks_client, payer, recent_blockhash, mut stake_pool_accounts, validator_stake_account, + user, + deposit_stake, + pool_token_account, + _stake_lamports, ) = setup().await; - let user = Keypair::new(); - // make stake account - let user_stake = Keypair::new(); - let lockup = stake_program::Lockup::default(); - let authorized = stake_program::Authorized { - staker: user.pubkey(), - withdrawer: user.pubkey(), - }; - create_independent_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake, - &authorized, - &lockup, - TEST_STAKE_AMOUNT, - ) - .await; - - // make pool token account - let user_pool_account = Keypair::new(); - create_token_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_pool_account, - &stake_pool_accounts.pool_mint.pubkey(), - &user.pubkey(), - ) - .await - .unwrap(); - - stake_pool_accounts.withdraw_authority = Keypair::new().pubkey(); + stake_pool_accounts.withdraw_authority = Pubkey::new_unique(); let transaction_error = stake_pool_accounts .deposit_stake( &mut banks_client, &payer, &recent_blockhash, - &user_stake.pubkey(), - &user_pool_account.pubkey(), + &deposit_stake, + &pool_token_account, &validator_stake_account.stake_account, &user, ) .await - .err() + .unwrap() .unwrap(); match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError( - _, - InstructionError::Custom(error_index), - )) => { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { let program_error = error::StakePoolError::InvalidProgramAddress as u32; assert_eq!(error_index, program_error); } @@ -552,28 +466,18 @@ async fn test_stake_pool_deposit_with_wrong_withdraw_authority() { } #[tokio::test] -async fn test_stake_pool_deposit_with_wrong_mint_for_receiver_acc() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake_account) = - setup().await; - - // make stake account - let user = Keypair::new(); - let user_stake = Keypair::new(); - let lockup = stake_program::Lockup::default(); - let authorized = stake_program::Authorized { - staker: user.pubkey(), - withdrawer: user.pubkey(), - }; - create_independent_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake, - &authorized, - &lockup, - TEST_STAKE_AMOUNT, - ) - .await; +async fn fail_with_wrong_mint_for_receiver_acc() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + validator_stake_account, + user, + deposit_stake, + _pool_token_account, + _stake_lamports, + ) = setup().await; let outside_mint = Keypair::new(); let outside_withdraw_auth = Keypair::new(); @@ -606,20 +510,17 @@ async fn test_stake_pool_deposit_with_wrong_mint_for_receiver_acc() { &mut banks_client, &payer, &recent_blockhash, - &user_stake.pubkey(), + &deposit_stake, &outside_pool_fee_acc.pubkey(), &validator_stake_account.stake_account, &user, ) .await - .err() + .unwrap() .unwrap(); match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError( - _, - InstructionError::Custom(error_index), - )) => { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { let program_error = token_error::TokenError::MintMismatch as u32; assert_eq!(error_index, program_error); } @@ -628,10 +529,10 @@ async fn test_stake_pool_deposit_with_wrong_mint_for_receiver_acc() { } #[tokio::test] -async fn test_deposit_with_uninitialized_validator_list() {} // TODO +async fn fail_with_uninitialized_validator_list() {} // TODO #[tokio::test] -async fn test_deposit_with_out_of_dated_pool_balances() {} // TODO +async fn fail_with_out_of_dated_pool_balances() {} // TODO #[tokio::test] async fn success_with_deposit_authority() { @@ -700,7 +601,7 @@ async fn success_with_deposit_authority() { .await .unwrap(); - stake_pool_accounts + let error = stake_pool_accounts .deposit_stake( &mut banks_client, &payer, @@ -710,8 +611,8 @@ async fn success_with_deposit_authority() { &validator_stake_account.stake_account, &user, ) - .await - .unwrap(); + .await; + assert!(error.is_none()); } #[tokio::test] @@ -796,7 +697,7 @@ async fn fail_without_deposit_authority_signature() { &user, ) .await - .unwrap_err() + .unwrap() .unwrap(); match error { @@ -809,3 +710,97 @@ async fn fail_without_deposit_authority_signature() { _ => panic!("Wrong error occurs while try to make a deposit with wrong stake program ID"), } } + +#[tokio::test] +async fn success_with_preferred_deposit() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + validator_stake, + user, + deposit_stake, + pool_token_account, + _stake_lamports, + ) = setup().await; + + stake_pool_accounts + .set_preferred_validator( + &mut banks_client, + &payer, + &recent_blockhash, + instruction::PreferredValidatorType::Deposit, + Some(validator_stake.vote.pubkey()), + ) + .await; + + let error = stake_pool_accounts + .deposit_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &deposit_stake, + &pool_token_account, + &validator_stake.stake_account, + &user, + ) + .await; + assert!(error.is_none()); +} + +#[tokio::test] +async fn fail_with_wrong_preferred_deposit() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + validator_stake, + user, + deposit_stake, + pool_token_account, + _stake_lamports, + ) = setup().await; + + let preferred_validator = simple_add_validator_to_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + ) + .await; + + stake_pool_accounts + .set_preferred_validator( + &mut banks_client, + &payer, + &recent_blockhash, + instruction::PreferredValidatorType::Deposit, + Some(preferred_validator.vote.pubkey()), + ) + .await; + + let error = stake_pool_accounts + .deposit_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &deposit_stake, + &pool_token_account, + &validator_stake.stake_account, + &user, + ) + .await + .unwrap() + .unwrap(); + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + assert_eq!( + error_index, + error::StakePoolError::IncorrectDepositVoteAddress as u32 + ); + } + _ => panic!("Wrong error occurs while try to make a deposit with wrong stake program ID"), + } +} diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 3995171e..ee1f21ae 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -606,7 +606,7 @@ impl StakePoolAccounts { pool_account: &Pubkey, validator_stake_account: &Pubkey, current_staker: &Keypair, - ) -> Result<(), TransportError> { + ) -> Option { let mut signers = vec![payer, current_staker]; let instructions = if let Some(deposit_authority) = self.deposit_authority_keypair.as_ref() { @@ -644,8 +644,7 @@ impl StakePoolAccounts { &signers, *recent_blockhash, ); - banks_client.process_transaction(transaction).await?; - Ok(()) + banks_client.process_transaction(transaction).await.err() } #[allow(clippy::too_many_arguments)] @@ -873,6 +872,30 @@ impl StakePoolAccounts { ); banks_client.process_transaction(transaction).await.err() } + + pub async fn set_preferred_validator( + &self, + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + validator_type: instruction::PreferredValidatorType, + validator: Option, + ) -> Option { + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_preferred_validator( + &id(), + &self.stake_pool.pubkey(), + &self.staker.pubkey(), + &self.validator_list.pubkey(), + validator_type, + validator, + )], + Some(&payer.pubkey()), + &[payer, &self.staker], + *recent_blockhash, + ); + banks_client.process_transaction(transaction).await.err() + } } pub async fn simple_add_validator_to_pool( @@ -986,7 +1009,7 @@ impl DepositStakeAccount { .await .unwrap(); - stake_pool_accounts + let error = stake_pool_accounts .deposit_stake( banks_client, payer, @@ -996,8 +1019,8 @@ impl DepositStakeAccount { &self.validator_stake_account, &self.authority, ) - .await - .unwrap(); + .await; + assert!(error.is_none()); } } @@ -1051,7 +1074,7 @@ pub async fn simple_deposit( .unwrap(); let validator_stake_account = validator_stake_account.stake_account; - stake_pool_accounts + let error = stake_pool_accounts .deposit_stake( banks_client, payer, @@ -1061,8 +1084,11 @@ pub async fn simple_deposit( &validator_stake_account, &authority, ) - .await - .ok()?; + .await; + // backwards, but oh well! + if error.is_some() { + return None; + } let pool_tokens = get_token_balance(banks_client, &pool_account.pubkey()).await; diff --git a/program/tests/set_fee.rs b/program/tests/set_fee.rs index af485557..2fd6cdb9 100644 --- a/program/tests/set_fee.rs +++ b/program/tests/set_fee.rs @@ -8,8 +8,9 @@ use { solana_program::hash::Hash, solana_program_test::*, solana_sdk::{ - instruction::InstructionError, signature::Keypair, signature::Signer, - transaction::Transaction, transaction::TransactionError, + instruction::InstructionError, + signature::{Keypair, Signer}, + transaction::{Transaction, TransactionError}, }, spl_stake_pool::{ error, id, instruction, diff --git a/program/tests/set_preferred.rs b/program/tests/set_preferred.rs new file mode 100644 index 00000000..932bb255 --- /dev/null +++ b/program/tests/set_preferred.rs @@ -0,0 +1,238 @@ +#![cfg(feature = "test-bpf")] + +mod helpers; + +use { + helpers::*, + solana_program::hash::Hash, + solana_program_test::*, + solana_sdk::{ + instruction::InstructionError, + pubkey::Pubkey, + signature::{Keypair, Signer}, + transaction::{Transaction, TransactionError}, + }, + spl_stake_pool::{ + borsh::try_from_slice_unchecked, + error, id, + instruction::{self, PreferredValidatorType}, + state::ValidatorList, + }, +}; + +async fn setup() -> ( + BanksClient, + Keypair, + Hash, + StakePoolAccounts, + ValidatorStakeAccount, +) { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .await + .unwrap(); + + let validator_stake_account = simple_add_validator_to_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + ) + .await; + + ( + banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + validator_stake_account, + ) +} + +#[tokio::test] +async fn success_deposit() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake_account) = + setup().await; + + let vote_account_address = validator_stake_account.vote.pubkey(); + let error = stake_pool_accounts + .set_preferred_validator( + &mut banks_client, + &payer, + &recent_blockhash, + PreferredValidatorType::Deposit, + Some(vote_account_address), + ) + .await; + assert!(error.is_none()); + + let validator_list = get_account( + &mut banks_client, + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + let validator_list = + try_from_slice_unchecked::(&validator_list.data.as_slice()).unwrap(); + + assert_eq!( + validator_list.preferred_deposit_validator_vote_address, + Some(vote_account_address) + ); + assert_eq!( + validator_list.preferred_withdraw_validator_vote_address, + None + ); +} + +#[tokio::test] +async fn success_withdraw() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake_account) = + setup().await; + + let vote_account_address = validator_stake_account.vote.pubkey(); + + let error = stake_pool_accounts + .set_preferred_validator( + &mut banks_client, + &payer, + &recent_blockhash, + PreferredValidatorType::Withdraw, + Some(vote_account_address), + ) + .await; + assert!(error.is_none()); + + let validator_list = get_account( + &mut banks_client, + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + let validator_list = + try_from_slice_unchecked::(&validator_list.data.as_slice()).unwrap(); + + assert_eq!( + validator_list.preferred_deposit_validator_vote_address, + None + ); + assert_eq!( + validator_list.preferred_withdraw_validator_vote_address, + Some(vote_account_address) + ); +} + +#[tokio::test] +async fn success_unset() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake_account) = + setup().await; + + let vote_account_address = validator_stake_account.vote.pubkey(); + let error = stake_pool_accounts + .set_preferred_validator( + &mut banks_client, + &payer, + &recent_blockhash, + PreferredValidatorType::Withdraw, + Some(vote_account_address), + ) + .await; + assert!(error.is_none()); + + let validator_list = get_account( + &mut banks_client, + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + let validator_list = + try_from_slice_unchecked::(&validator_list.data.as_slice()).unwrap(); + + assert_eq!( + validator_list.preferred_withdraw_validator_vote_address, + Some(vote_account_address) + ); + + let error = stake_pool_accounts + .set_preferred_validator( + &mut banks_client, + &payer, + &recent_blockhash, + PreferredValidatorType::Withdraw, + None, + ) + .await; + assert!(error.is_none()); + + let validator_list = get_account( + &mut banks_client, + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + let validator_list = + try_from_slice_unchecked::(&validator_list.data.as_slice()).unwrap(); + + assert_eq!( + validator_list.preferred_withdraw_validator_vote_address, + None + ); +} + +#[tokio::test] +async fn fail_wrong_staker() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, _) = setup().await; + + let wrong_staker = Keypair::new(); + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_preferred_validator( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &wrong_staker.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + PreferredValidatorType::Withdraw, + None, + )], + Some(&payer.pubkey()), + &[&payer, &wrong_staker], + recent_blockhash, + ); + let error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = error::StakePoolError::WrongStaker as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while malicious try to set manager"), + } +} + +#[tokio::test] +async fn fail_not_present_validator() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, _) = setup().await; + + let validator_vote_address = Pubkey::new_unique(); + let error = stake_pool_accounts + .set_preferred_validator( + &mut banks_client, + &payer, + &recent_blockhash, + PreferredValidatorType::Withdraw, + Some(validator_vote_address), + ) + .await + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = error::StakePoolError::ValidatorNotFound as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while malicious try to set manager"), + } +} diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index 7049f3ec..fd403249 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -84,6 +84,8 @@ async fn success() { validator_list, state::ValidatorList { account_type: state::AccountType::ValidatorList, + preferred_deposit_validator_vote_address: None, + preferred_withdraw_validator_vote_address: None, max_validators: stake_pool_accounts.max_validators, validators: vec![state::ValidatorStakeInfo { status: state::StakeStatus::Active, diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 7e8253c2..0d94ebea 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -97,6 +97,8 @@ async fn success() { validator_list, state::ValidatorList { account_type: state::AccountType::ValidatorList, + preferred_deposit_validator_vote_address: None, + preferred_withdraw_validator_vote_address: None, max_validators: stake_pool_accounts.max_validators, validators: vec![] } @@ -520,6 +522,8 @@ async fn success_with_deactivating_transient_stake() { try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); let expected_list = state::ValidatorList { account_type: state::AccountType::ValidatorList, + preferred_deposit_validator_vote_address: None, + preferred_withdraw_validator_vote_address: None, max_validators: stake_pool_accounts.max_validators, validators: vec![state::ValidatorStakeInfo { status: state::StakeStatus::DeactivatingTransient, @@ -552,6 +556,74 @@ async fn success_with_deactivating_transient_stake() { assert_eq!(validator_list, expected_list); } +#[tokio::test] +async fn success_resets_preferred_validator() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = + setup().await; + + stake_pool_accounts + .set_preferred_validator( + &mut banks_client, + &payer, + &recent_blockhash, + instruction::PreferredValidatorType::Deposit, + Some(validator_stake.vote.pubkey()), + ) + .await; + stake_pool_accounts + .set_preferred_validator( + &mut banks_client, + &payer, + &recent_blockhash, + instruction::PreferredValidatorType::Withdraw, + Some(validator_stake.vote.pubkey()), + ) + .await; + + let new_authority = Pubkey::new_unique(); + let error = stake_pool_accounts + .remove_validator_from_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &new_authority, + &validator_stake.stake_account, + &validator_stake.transient_stake_account, + ) + .await; + assert!(error.is_none()); + + // Check if account was removed from the list of stake accounts + let validator_list = get_account( + &mut banks_client, + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + let validator_list = + try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); + assert_eq!( + validator_list, + state::ValidatorList { + account_type: state::AccountType::ValidatorList, + preferred_deposit_validator_vote_address: None, + preferred_withdraw_validator_vote_address: None, + max_validators: stake_pool_accounts.max_validators, + validators: vec![] + } + ); + + // Check of stake account authority has changed + let stake = get_account(&mut banks_client, &validator_stake.stake_account).await; + let stake_state = deserialize::(&stake.data).unwrap(); + match stake_state { + stake_program::StakeState::Stake(meta, _) => { + assert_eq!(&meta.authorized.staker, &new_authority); + assert_eq!(&meta.authorized.withdrawer, &new_authority); + } + _ => panic!(), + } +} + #[tokio::test] async fn fail_not_updated_stake_pool() {} // TODO diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 3070ba6d..2905b948 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -33,6 +33,7 @@ async fn setup() -> ( ValidatorStakeAccount, DepositStakeAccount, Keypair, + Keypair, u64, ) { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; @@ -76,6 +77,16 @@ async fn setup() -> ( ) .await; + // Create stake account to withdraw to + let user_stake_recipient = Keypair::new(); + create_blank_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake_recipient, + ) + .await; + ( banks_client, payer, @@ -84,6 +95,7 @@ async fn setup() -> ( validator_stake_account, deposit_info, user_transfer_authority, + user_stake_recipient, tokens_to_burn, ) } @@ -98,25 +110,21 @@ async fn success() { validator_stake_account, deposit_info, user_transfer_authority, + user_stake_recipient, tokens_to_burn, ) = setup().await; - // Create stake account to withdraw to - let user_stake_recipient = Keypair::new(); - let initial_stake_lamports = create_blank_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake_recipient, - ) - .await; - // Save stake pool state before withdrawal let stake_pool_before = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; let stake_pool_before = state::StakePool::try_from_slice(&stake_pool_before.data.as_slice()).unwrap(); + // Check user recipient stake account balance + let initial_stake_lamports = get_account(&mut banks_client, &user_stake_recipient.pubkey()) + .await + .lamports; + // Save validator stake account record before withdrawal let validator_list = get_account( &mut banks_client, @@ -215,12 +223,10 @@ async fn fail_with_wrong_stake_program() { validator_stake_account, deposit_info, user_transfer_authority, + user_stake_recipient, tokens_to_burn, ) = setup().await; - // Create stake account to withdraw to - let user_stake_recipient = Keypair::new(); - let new_authority = Pubkey::new_unique(); let wrong_stake_program = Pubkey::new_unique(); @@ -276,12 +282,10 @@ async fn fail_with_wrong_withdraw_authority() { validator_stake_account, deposit_info, user_transfer_authority, + user_stake_recipient, tokens_to_burn, ) = setup().await; - // Create stake account to withdraw to - let user_stake_recipient = Keypair::new(); - let new_authority = Pubkey::new_unique(); stake_pool_accounts.withdraw_authority = Keypair::new().pubkey(); @@ -322,12 +326,10 @@ async fn fail_with_wrong_token_program_id() { validator_stake_account, deposit_info, user_transfer_authority, + user_stake_recipient, tokens_to_burn, ) = setup().await; - // Create stake account to withdraw to - let user_stake_recipient = Keypair::new(); - let new_authority = Pubkey::new_unique(); let wrong_token_program = Keypair::new(); @@ -374,12 +376,10 @@ async fn fail_with_wrong_validator_list() { validator_stake_account, deposit_info, user_transfer_authority, + user_stake_recipient, tokens_to_burn, ) = setup().await; - // Create stake account to withdraw to - let user_stake_recipient = Keypair::new(); - let new_authority = Pubkey::new_unique(); stake_pool_accounts.validator_list = Keypair::new(); @@ -422,6 +422,7 @@ async fn fail_with_unknown_validator() { _, _, user_transfer_authority, + user_stake_recipient, _, ) = setup().await; @@ -507,9 +508,6 @@ async fn fail_with_unknown_validator() { ) .await; - // Create stake account to withdraw to - let user_stake_recipient = Keypair::new(); - let new_authority = Pubkey::new_unique(); let transaction_error = stake_pool_accounts @@ -547,19 +545,10 @@ async fn fail_double_withdraw_to_the_same_account() { validator_stake_account, deposit_info, user_transfer_authority, + user_stake_recipient, tokens_to_burn, ) = setup().await; - // Create stake account to withdraw to - let user_stake_recipient = Keypair::new(); - create_blank_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake_recipient, - ) - .await; - let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts .withdraw_stake( @@ -777,19 +766,10 @@ async fn fail_overdraw_validator() { _validator_stake_account, deposit_info, user_transfer_authority, + user_stake_recipient, tokens_to_burn, ) = setup().await; - // Create stake account to withdraw to - let user_stake_recipient = Keypair::new(); - let _initial_stake_lamports = create_blank_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake_recipient, - ) - .await; - let validator_stake_account = simple_add_validator_to_pool( &mut banks_client, &payer, @@ -1013,3 +993,141 @@ async fn success_with_reserve() { initial_stake_lamports + deposit_info.stake_lamports + stake_rent ); } + +#[tokio::test] +async fn success_with_preferred_validator() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + validator_stake, + deposit_info, + user_transfer_authority, + user_stake_recipient, + tokens_to_burn, + ) = setup().await; + + stake_pool_accounts + .set_preferred_validator( + &mut banks_client, + &payer, + &recent_blockhash, + instruction::PreferredValidatorType::Withdraw, + Some(validator_stake.vote.pubkey()), + ) + .await; + + let new_authority = Pubkey::new_unique(); + let error = stake_pool_accounts + .withdraw_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake_recipient.pubkey(), + &user_transfer_authority, + &deposit_info.pool_account.pubkey(), + &validator_stake.stake_account, + &new_authority, + tokens_to_burn, + ) + .await; + assert!(error.is_none()); +} + +#[tokio::test] +async fn fail_with_wrong_preferred_withdraw() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + validator_stake, + deposit_info, + user_transfer_authority, + user_stake_recipient, + tokens_to_burn, + ) = setup().await; + + let preferred_validator = simple_add_validator_to_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + ) + .await; + + stake_pool_accounts + .set_preferred_validator( + &mut banks_client, + &payer, + &recent_blockhash, + instruction::PreferredValidatorType::Withdraw, + Some(preferred_validator.vote.pubkey()), + ) + .await; + + // preferred is empty, this works + let new_authority = Pubkey::new_unique(); + let error = stake_pool_accounts + .withdraw_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake_recipient.pubkey(), + &user_transfer_authority, + &deposit_info.pool_account.pubkey(), + &validator_stake.stake_account, + &new_authority, + tokens_to_burn, + ) + .await; + assert!(error.is_none()); + + // deposit into preferred, then fail + let _preferred_deposit = simple_deposit( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + &preferred_validator, + TEST_STAKE_AMOUNT, + ) + .await + .unwrap(); + + // Create stake account to withdraw to + let user_stake_recipient = Keypair::new(); + create_blank_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake_recipient, + ) + .await; + + let error = stake_pool_accounts + .withdraw_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake_recipient.pubkey(), + &user_transfer_authority, + &deposit_info.pool_account.pubkey(), + &validator_stake.stake_account, + &new_authority, + tokens_to_burn, + ) + .await + .unwrap() + .unwrap(); + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + assert_eq!( + error_index, + StakePoolError::IncorrectWithdrawVoteAddress as u32 + ); + } + _ => panic!("Wrong error occurs while try to make a deposit with wrong stake program ID"), + } +} From e4c27054586f635394cd4394a2a187b1cafe59cd Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 4 Jun 2021 22:15:39 +0200 Subject: [PATCH 0107/1076] stake-pool: Document writability of validator list (#1867) --- program/src/instruction.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 51f2c916..459c7433 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -219,7 +219,7 @@ pub enum StakePoolInstruction { /// /// 0. `[w]` Stake pool /// 1. `[]` Stake pool withdraw authority - /// 2. `[]` Validator stake list storage account + /// 2. `[w]` Validator stake list storage account /// 3. `[]` Reserve stake account /// 4. `[w]` Account to receive pool fee tokens /// 5. `[w]` Pool mint account From f4f932d3ba2119a5787f275bb78fd5777999d993 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 4 Jun 2021 23:08:32 +0200 Subject: [PATCH 0108/1076] stake-pool: Add reserve stake check on update pool balance (#1866) --- program/src/processor.rs | 1 + program/tests/update_stake_pool_balance.rs | 26 ++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/program/src/processor.rs b/program/src/processor.rs index 57e8399f..c2af0657 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1429,6 +1429,7 @@ impl Processor { } stake_pool.check_mint(pool_mint_info)?; stake_pool.check_authority_withdraw(withdraw_info.key, program_id, stake_pool_info.key)?; + stake_pool.check_reserve_stake(reserve_stake_info)?; if stake_pool.manager_fee_account != *manager_fee_info.key { return Err(StakePoolError::InvalidFeeAccount.into()); } diff --git a/program/tests/update_stake_pool_balance.rs b/program/tests/update_stake_pool_balance.rs index 22fd5623..f4995ed8 100644 --- a/program/tests/update_stake_pool_balance.rs +++ b/program/tests/update_stake_pool_balance.rs @@ -223,6 +223,32 @@ async fn fail_with_wrong_pool_fee_account() { } } +#[tokio::test] +async fn fail_with_wrong_reserve() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let mut stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .await + .unwrap(); + + let wrong_reserve_stake = Keypair::new(); + stake_pool_accounts.reserve_stake = wrong_reserve_stake; + let error = stake_pool_accounts + .update_stake_pool_balance(&mut banks_client, &payer, &recent_blockhash) + .await + .unwrap() + .unwrap(); + + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::InvalidProgramAddress as u32), + ) + ); +} + #[tokio::test] async fn test_update_stake_pool_balance_with_uninitialized_validator_list() {} // TODO From 9751d9f527cf953664971c119086b584eb72d2ab Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 4 Jun 2021 23:45:49 +0200 Subject: [PATCH 0109/1076] stake-pool: Add explicit ownership checks (#1868) --- program/src/processor.rs | 55 +++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/program/src/processor.rs b/program/src/processor.rs index c2af0657..afa68546 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -408,12 +408,14 @@ impl Processor { return Err(StakePoolError::SignatureMissing.into()); } + check_account_owner(stake_pool_info, program_id)?; let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; if !stake_pool.is_uninitialized() { msg!("Provided stake pool already in use"); return Err(StakePoolError::AlreadyInUse.into()); } + check_account_owner(validator_list_info, program_id)?; let mut validator_list = try_from_slice_unchecked::(&validator_list_info.data.borrow())?; if !validator_list.is_uninitialized() { @@ -566,9 +568,7 @@ impl Processor { let system_program_info = next_account_info(account_info_iter)?; let stake_program_info = next_account_info(account_info_iter)?; - if stake_pool_info.owner != program_id { - return Err(ProgramError::IncorrectProgramId); - } + check_account_owner(stake_pool_info, program_id)?; let stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); @@ -662,9 +662,7 @@ impl Processor { check_stake_program(stake_program_info.key)?; - if stake_pool_info.owner != program_id { - return Err(ProgramError::IncorrectProgramId); - } + check_account_owner(stake_pool_info, program_id)?; let stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); @@ -677,15 +675,13 @@ impl Processor { )?; stake_pool.check_staker(staker_info)?; + stake_pool.check_validator_list(validator_list_info)?; if stake_pool.last_update_epoch < clock.epoch { return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); } - if *validator_list_info.key != stake_pool.validator_list { - return Err(StakePoolError::InvalidValidatorStakeList.into()); - } - + check_account_owner(validator_list_info, program_id)?; let mut validator_list = try_from_slice_unchecked::(&validator_list_info.data.borrow())?; if !validator_list.is_valid() { @@ -786,6 +782,7 @@ impl Processor { stake_pool.check_validator_list(validator_list_info)?; + check_account_owner(validator_list_info, program_id)?; let mut validator_list = try_from_slice_unchecked::(&validator_list_info.data.borrow())?; if !validator_list.is_valid() { @@ -918,7 +915,7 @@ impl Processor { } stake_pool.check_validator_list(validator_list_info)?; - + check_account_owner(validator_list_info, program_id)?; let validator_list = try_from_slice_unchecked::(&validator_list_info.data.borrow())?; if !validator_list.is_valid() { @@ -1047,6 +1044,8 @@ impl Processor { } stake_pool.check_validator_list(validator_list_info)?; + stake_pool.check_reserve_stake(reserve_stake_account_info)?; + check_account_owner(validator_list_info, program_id)?; let mut validator_list = try_from_slice_unchecked::(&validator_list_info.data.borrow())?; @@ -1054,10 +1053,7 @@ impl Processor { return Err(StakePoolError::InvalidState.into()); } - stake_pool.check_reserve_stake(reserve_stake_account_info)?; - let vote_account_address = validator_vote_account_info.key; - let transient_stake_bump_seed = check_transient_stake_address( program_id, stake_pool_info.key, @@ -1240,6 +1236,7 @@ impl Processor { stake_pool.check_reserve_stake(reserve_stake_info)?; check_stake_program(stake_program_info.key)?; + check_account_owner(validator_list_info, program_id)?; let mut validator_list = try_from_slice_unchecked::(&validator_list_info.data.borrow())?; if !validator_list.is_valid() { @@ -1423,6 +1420,7 @@ impl Processor { let clock = &Clock::from_account_info(clock_info)?; let token_program_info = next_account_info(account_info_iter)?; + check_account_owner(stake_pool_info, program_id)?; let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); @@ -1441,6 +1439,7 @@ impl Processor { return Err(ProgramError::IncorrectProgramId); } + check_account_owner(validator_list_info, program_id)?; let mut validator_list = try_from_slice_unchecked::(&validator_list_info.data.borrow())?; if !validator_list.is_valid() { @@ -1550,6 +1549,7 @@ impl Processor { return Err(ProgramError::IncorrectProgramId); } + check_account_owner(stake_pool_info, program_id)?; let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); @@ -1564,19 +1564,17 @@ impl Processor { )?; stake_pool.check_deposit_authority(deposit_authority_info.key)?; stake_pool.check_mint(pool_mint_info)?; + stake_pool.check_validator_list(validator_list_info)?; if stake_pool.token_program_id != *token_program_info.key { return Err(ProgramError::IncorrectProgramId); } - if *validator_list_info.key != stake_pool.validator_list { - return Err(StakePoolError::InvalidValidatorStakeList.into()); - } - if stake_pool.last_update_epoch < clock.epoch { return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); } + check_account_owner(validator_list_info, program_id)?; let mut validator_list = try_from_slice_unchecked::(&validator_list_info.data.borrow())?; if !validator_list.is_valid() { @@ -1706,16 +1704,15 @@ impl Processor { let token_program_info = next_account_info(account_info_iter)?; let stake_program_info = next_account_info(account_info_iter)?; - if *stake_program_info.key != stake_program::id() { - return Err(ProgramError::IncorrectProgramId); - } - + check_stake_program(stake_program_info.key)?; + check_account_owner(stake_pool_info, program_id)?; let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); } stake_pool.check_mint(pool_mint_info)?; + stake_pool.check_validator_list(validator_list_info)?; stake_pool.check_authority_withdraw( withdraw_authority_info.key, program_id, @@ -1726,14 +1723,11 @@ impl Processor { return Err(ProgramError::IncorrectProgramId); } - if *validator_list_info.key != stake_pool.validator_list { - return Err(StakePoolError::InvalidValidatorStakeList.into()); - } - if stake_pool.last_update_epoch < clock.epoch { return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); } + check_account_owner(validator_list_info, program_id)?; let mut validator_list = try_from_slice_unchecked::(&validator_list_info.data.borrow())?; if !validator_list.is_valid() { @@ -1864,13 +1858,14 @@ impl Processor { } /// Processes [SetManager](enum.Instruction.html). - fn process_set_manager(_program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { + fn process_set_manager(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; let manager_info = next_account_info(account_info_iter)?; let new_manager_info = next_account_info(account_info_iter)?; let new_manager_fee_info = next_account_info(account_info_iter)?; + check_account_owner(stake_pool_info, program_id)?; let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); @@ -1892,13 +1887,14 @@ impl Processor { } /// Processes [SetFee](enum.Instruction.html). - fn process_set_fee(_program_id: &Pubkey, accounts: &[AccountInfo], fee: Fee) -> ProgramResult { + fn process_set_fee(program_id: &Pubkey, accounts: &[AccountInfo], fee: Fee) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; let manager_info = next_account_info(account_info_iter)?; let clock_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(clock_info)?; + check_account_owner(stake_pool_info, program_id)?; let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); @@ -1926,12 +1922,13 @@ impl Processor { } /// Processes [SetManager](enum.Instruction.html). - fn process_set_staker(_program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { + fn process_set_staker(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; let set_staker_authority_info = next_account_info(account_info_iter)?; let new_staker_info = next_account_info(account_info_iter)?; + check_account_owner(stake_pool_info, program_id)?; let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); From 7fbbb69dc34c6e8256a9618a63adf7f3b88f0c53 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 11 Jun 2021 22:50:59 +0200 Subject: [PATCH 0110/1076] stake-pool: Add ability to withdraw from transient stakes (#1890) * stake-pool: Add ability to withdraw from transient stakes It's possible for a very malicious pool staker to constantly increase / decrease the stake on validators, making it impossible for people to get their SOL out. Update the accounting to know how much of the stake is active and how much is transient and allow users to withdraw from transient accounts, but only if there's no more active stake. * Remove mut ickiness --- clients/cli/src/main.rs | 2 +- program/src/instruction.rs | 6 +- program/src/processor.rs | 100 ++++++---- program/src/state.rs | 114 +++++++---- program/tests/deposit.rs | 7 +- program/tests/helpers/mod.rs | 2 +- .../tests/update_validator_list_balance.rs | 5 +- program/tests/vsa_add.rs | 3 +- program/tests/vsa_remove.rs | 3 +- program/tests/withdraw.rs | 179 +++++++++++++++++- 10 files changed, 335 insertions(+), 86 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index b21d5ecc..9310b326 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -641,7 +641,7 @@ fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { println!( "Validator Vote Account: {}\tBalance: {}\tLast Update Epoch: {}{}", validator.vote_account_address, - Sol(validator.stake_lamports), + Sol(validator.stake_lamports()), validator.last_update_epoch, if validator.last_update_epoch != epoch_info.epoch { " [UPDATE REQUIRED]" diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 459c7433..19303590 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -129,8 +129,8 @@ pub enum StakePoolInstruction { /// 0. `[]` Stake pool /// 1. `[s]` Stake pool staker /// 2. `[]` Stake pool withdraw authority - /// 3. `[]` Validator list - /// 5. `[w]` Canonical stake account to split from + /// 3. `[w]` Validator list + /// 4. `[w]` Canonical stake account to split from /// 5. `[w]` Transient stake account to receive split /// 6. `[]` Clock sysvar /// 7. `[]` Rent sysvar @@ -444,7 +444,7 @@ pub fn decrease_validator_stake( AccountMeta::new_readonly(*stake_pool, false), AccountMeta::new_readonly(*staker, true), AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), - AccountMeta::new_readonly(*validator_list, false), + AccountMeta::new(*validator_list, false), AccountMeta::new(*validator_stake, false), AccountMeta::new(*transient_stake, false), AccountMeta::new_readonly(sysvar::clock::id(), false), diff --git a/program/src/processor.rs b/program/src/processor.rs index afa68546..b42d91f2 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -736,7 +736,8 @@ impl Processor { validator_list.validators.push(ValidatorStakeInfo { status: StakeStatus::Active, vote_account_address, - stake_lamports: stake_lamports.saturating_sub(minimum_lamport_amount), + active_stake_lamports: stake_lamports.saturating_sub(minimum_lamport_amount), + transient_stake_lamports: 0, last_update_epoch: clock.epoch, }); validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; @@ -916,7 +917,7 @@ impl Processor { stake_pool.check_validator_list(validator_list_info)?; check_account_owner(validator_list_info, program_id)?; - let validator_list = + let mut validator_list = try_from_slice_unchecked::(&validator_list_info.data.borrow())?; if !validator_list.is_valid() { return Err(StakePoolError::InvalidState.into()); @@ -944,13 +945,15 @@ impl Processor { &[transient_stake_bump_seed], ]; - if !validator_list.contains(&vote_account_address) { + let maybe_validator_list_entry = validator_list.find_mut(&vote_account_address); + if maybe_validator_list_entry.is_none() { msg!( "Vote account {} not found in stake pool", vote_account_address ); return Err(StakePoolError::ValidatorNotFound.into()); } + let mut validator_list_entry = maybe_validator_list_entry.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); if lamports <= stake_rent { @@ -996,6 +999,13 @@ impl Processor { stake_pool.withdraw_bump_seed, )?; + validator_list_entry.active_stake_lamports = validator_list_entry + .active_stake_lamports + .checked_sub(lamports) + .ok_or(StakePoolError::CalculationFailure)?; + validator_list_entry.transient_stake_lamports = lamports; + validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; + Ok(()) } @@ -1146,10 +1156,7 @@ impl Processor { stake_pool.withdraw_bump_seed, )?; - validator_list_entry.stake_lamports = validator_list_entry - .stake_lamports - .checked_add(lamports) - .ok_or(StakePoolError::CalculationFailure)?; + validator_list_entry.transient_stake_lamports = lamports; validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; Ok(()) @@ -1274,7 +1281,8 @@ impl Processor { continue; }; - let mut stake_lamports = 0; + let mut active_stake_lamports = 0; + let mut transient_stake_lamports = 0; let validator_stake_state = try_from_slice_unchecked::( &validator_stake_info.data.borrow(), ) @@ -1293,7 +1301,7 @@ impl Processor { match transient_stake_state { Some(stake_program::StakeState::Initialized(_meta)) => { if no_merge { - stake_lamports += transient_stake_info.lamports(); + transient_stake_lamports = transient_stake_info.lamports(); } else { // merge into reserve Self::stake_merge( @@ -1316,7 +1324,7 @@ impl Processor { } Some(stake_program::StakeState::Stake(_, stake)) => { if no_merge { - stake_lamports += transient_stake_info.lamports(); + transient_stake_lamports = transient_stake_info.lamports(); } else if stake.delegation.deactivation_epoch < clock.epoch { // deactivated, merge into reserve Self::stake_merge( @@ -1355,15 +1363,15 @@ impl Processor { )?; } else { msg!("Stake activating or just active, not ready to merge"); - stake_lamports += transient_stake_info.lamports(); + transient_stake_lamports = transient_stake_info.lamports(); } } else { msg!("Transient stake is activating or active, but validator stake is not, need to add the validator stake account on {} back into the stake pool", stake.delegation.voter_pubkey); - stake_lamports += transient_stake_info.lamports(); + transient_stake_lamports = transient_stake_info.lamports(); } } else { msg!("Transient stake not ready to be merged anywhere"); - stake_lamports += transient_stake_info.lamports(); + transient_stake_lamports = transient_stake_info.lamports(); } } None @@ -1377,7 +1385,7 @@ impl Processor { match validator_stake_state { Some(stake_program::StakeState::Stake(meta, _)) => { if validator_stake_record.status == StakeStatus::Active { - stake_lamports += validator_stake_info + active_stake_lamports = validator_stake_info .lamports() .saturating_sub(minimum_stake_lamports(&meta)); } else { @@ -1393,7 +1401,8 @@ impl Processor { } validator_stake_record.last_update_epoch = clock.epoch; - validator_stake_record.stake_lamports = stake_lamports; + validator_stake_record.active_stake_lamports = active_stake_lamports; + validator_stake_record.transient_stake_lamports = transient_stake_lamports; changes = true; } @@ -1465,7 +1474,7 @@ impl Processor { return Err(StakePoolError::StakeListOutOfDate.into()); } total_stake_lamports = total_stake_lamports - .checked_add(validator_stake_record.stake_lamports) + .checked_add(validator_stake_record.stake_lamports()) .ok_or(StakePoolError::CalculationFailure)?; } @@ -1674,7 +1683,7 @@ impl Processor { "lamports post merge {}", validator_stake_account_info.lamports() ); - validator_list_item.stake_lamports = validator_stake_account_info + validator_list_item.active_stake_lamports = validator_stake_account_info .lamports() .checked_sub(minimum_stake_lamports(&meta)) .ok_or(StakePoolError::CalculationFailure)?; @@ -1738,19 +1747,19 @@ impl Processor { .calc_lamports_withdraw_amount(pool_tokens) .ok_or(StakePoolError::CalculationFailure)?; - let validator_list_item = if *stake_split_from.key == stake_pool.reserve_stake { + let validator_list_item_info = if *stake_split_from.key == stake_pool.reserve_stake { // check that the validator stake accounts have no withdrawable stake if let Some(withdrawable_entry) = validator_list .validators .iter() - .find(|&&x| x.stake_lamports != 0) + .find(|&&x| x.stake_lamports() != 0) { let (validator_stake_address, _) = crate::find_stake_program_address( &program_id, &withdrawable_entry.vote_account_address, stake_pool_info.key, ); - msg!("Error withdrawing from reserve: validator stake account {} has {} lamports available, please use that first.", validator_stake_address, withdrawable_entry.stake_lamports); + msg!("Error withdrawing from reserve: validator stake account {} has {} lamports available, please use that first.", validator_stake_address, withdrawable_entry.stake_lamports()); return Err(StakePoolError::StakeLamportsNotEqualToMinimum.into()); } @@ -1767,12 +1776,6 @@ impl Processor { } else { let (meta, stake) = get_stake_state(stake_split_from)?; let vote_account_address = stake.delegation.voter_pubkey; - check_validator_stake_address( - program_id, - stake_pool_info.key, - stake_split_from.key, - &vote_account_address, - )?; if let Some(preferred_withdraw_validator) = validator_list.preferred_withdraw_validator_vote_address @@ -1781,13 +1784,33 @@ impl Processor { .find(&preferred_withdraw_validator) .ok_or(StakePoolError::ValidatorNotFound)?; if preferred_withdraw_validator != vote_account_address - && preferred_validator_info.stake_lamports > 0 + && preferred_validator_info.active_stake_lamports > 0 { - msg!("Validator vote address {} is preferred for withdrawals, it currently has {} lamports available. Please withdraw those before using other validator stake accounts.", preferred_withdraw_validator, preferred_validator_info.stake_lamports); + msg!("Validator vote address {} is preferred for withdrawals, it currently has {} lamports available. Please withdraw those before using other validator stake accounts.", preferred_withdraw_validator, preferred_validator_info.active_stake_lamports); return Err(StakePoolError::IncorrectWithdrawVoteAddress.into()); } } + // if there's any active stake, we must withdraw from an active + // stake account + let withdrawing_from_transient_stake = if validator_list.has_active_stake() { + check_validator_stake_address( + program_id, + stake_pool_info.key, + stake_split_from.key, + &vote_account_address, + )?; + false + } else { + check_transient_stake_address( + program_id, + stake_pool_info.key, + stake_split_from.key, + &vote_account_address, + )?; + true + }; + let validator_list_item = validator_list .find_mut(&vote_account_address) .ok_or(StakePoolError::ValidatorNotFound)?; @@ -1804,7 +1827,7 @@ impl Processor { msg!("Attempting to withdraw {} lamports from validator account with {} lamports, {} must remain", withdraw_lamports, current_lamports, required_lamports); return Err(StakePoolError::StakeLamportsNotEqualToMinimum.into()); } - Some(validator_list_item) + Some((validator_list_item, withdrawing_from_transient_stake)) }; Self::token_burn( @@ -1846,11 +1869,20 @@ impl Processor { .ok_or(StakePoolError::CalculationFailure)?; stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; - if let Some(validator_list_item) = validator_list_item { - validator_list_item.stake_lamports = validator_list_item - .stake_lamports - .checked_sub(withdraw_lamports) - .ok_or(StakePoolError::CalculationFailure)?; + if let Some((validator_list_item, withdrawing_from_transient_stake_account)) = + validator_list_item_info + { + if withdrawing_from_transient_stake_account { + validator_list_item.transient_stake_lamports = validator_list_item + .transient_stake_lamports + .checked_sub(withdraw_lamports) + .ok_or(StakePoolError::CalculationFailure)?; + } else { + validator_list_item.active_stake_lamports = validator_list_item + .active_stake_lamports + .checked_sub(withdraw_lamports) + .ok_or(StakePoolError::CalculationFailure)?; + } validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; } diff --git a/program/src/state.rs b/program/src/state.rs index d4551f6a..9ef6493d 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -328,15 +328,29 @@ pub struct ValidatorStakeInfo { /// Validator vote account address pub vote_account_address: Pubkey, - /// Amount of stake delegated to this validator - /// Note that if `last_update_epoch` does not match the current epoch then this field may not - /// be accurate - pub stake_lamports: u64, + /// Amount of active stake delegated to this validator + /// Note that if `last_update_epoch` does not match the current epoch then + /// this field may not be accurate + pub active_stake_lamports: u64, + + /// Amount of transient stake delegated to this validator + /// Note that if `last_update_epoch` does not match the current epoch then + /// this field may not be accurate + pub transient_stake_lamports: u64, - /// Last epoch the `stake_lamports` field was updated + /// Last epoch the active and transient stake lamports fields were updated pub last_update_epoch: u64, } +impl ValidatorStakeInfo { + /// Get the total lamports delegated to this validator (active and transient) + pub fn stake_lamports(&self) -> u64 { + self.active_stake_lamports + .checked_add(self.transient_stake_lamports) + .unwrap() + } +} + impl ValidatorList { /// Create an empty instance containing space for `max_validators` and preferred validator keys pub fn new(max_validators: u32) -> Self { @@ -352,7 +366,7 @@ impl ValidatorList { /// Calculate the number of validator entries that fit in the provided length pub fn calculate_max_validators(buffer_length: usize) -> usize { let header_size = 1 + 4 + 4 + 33 + 33; - buffer_length.saturating_sub(header_size) / 49 + buffer_length.saturating_sub(header_size) / 57 } /// Check if contains validator with particular pubkey @@ -384,6 +398,11 @@ impl ValidatorList { pub fn is_uninitialized(&self) -> bool { self.account_type == AccountType::Uninitialized } + + /// Check if the list has any active stake + pub fn has_active_stake(&self) -> bool { + self.validators.iter().any(|x| x.active_stake_lamports > 0) + } } /// Fee rate as a ratio, minted on `UpdateStakePoolBalance` as a proportion of @@ -407,40 +426,18 @@ mod test { solana_program::native_token::LAMPORTS_PER_SOL, }; - #[test] - fn test_state_packing() { - let max_validators = 10_000; - let size = get_instance_packed_len(&ValidatorList::new(max_validators)).unwrap(); - // Not initialized - let stake_list = ValidatorList { + fn uninitialized_validator_list() -> ValidatorList { + ValidatorList { account_type: AccountType::Uninitialized, preferred_deposit_validator_vote_address: None, preferred_withdraw_validator_vote_address: None, max_validators: 0, validators: vec![], - }; - let mut byte_vec = vec![0u8; size]; - let mut bytes = byte_vec.as_mut_slice(); - stake_list.serialize(&mut bytes).unwrap(); - let stake_list_unpacked = try_from_slice_unchecked::(&byte_vec).unwrap(); - assert_eq!(stake_list_unpacked, stake_list); - - // Empty, one preferred key - let stake_list = ValidatorList { - account_type: AccountType::ValidatorList, - preferred_deposit_validator_vote_address: Some(Pubkey::new_unique()), - preferred_withdraw_validator_vote_address: None, - max_validators: 0, - validators: vec![], - }; - let mut byte_vec = vec![0u8; size]; - let mut bytes = byte_vec.as_mut_slice(); - stake_list.serialize(&mut bytes).unwrap(); - let stake_list_unpacked = try_from_slice_unchecked::(&byte_vec).unwrap(); - assert_eq!(stake_list_unpacked, stake_list); + } + } - // With several accounts - let stake_list = ValidatorList { + fn test_validator_list(max_validators: u32) -> ValidatorList { + ValidatorList { account_type: AccountType::ValidatorList, preferred_deposit_validator_vote_address: Some(Pubkey::new_unique()), preferred_withdraw_validator_vote_address: Some(Pubkey::new_unique()), @@ -449,28 +446,71 @@ mod test { ValidatorStakeInfo { status: StakeStatus::Active, vote_account_address: Pubkey::new_from_array([1; 32]), - stake_lamports: 123456789, + active_stake_lamports: 123456789, + transient_stake_lamports: 1111111, last_update_epoch: 987654321, }, ValidatorStakeInfo { status: StakeStatus::DeactivatingTransient, vote_account_address: Pubkey::new_from_array([2; 32]), - stake_lamports: 998877665544, + active_stake_lamports: 998877665544, + transient_stake_lamports: 222222222, last_update_epoch: 11223445566, }, ValidatorStakeInfo { status: StakeStatus::ReadyForRemoval, vote_account_address: Pubkey::new_from_array([3; 32]), - stake_lamports: 0, + active_stake_lamports: 0, + transient_stake_lamports: 0, last_update_epoch: 999999999999999, }, ], + } + } + + #[test] + fn state_packing() { + let max_validators = 10_000; + let size = get_instance_packed_len(&ValidatorList::new(max_validators)).unwrap(); + let stake_list = uninitialized_validator_list(); + let mut byte_vec = vec![0u8; size]; + let mut bytes = byte_vec.as_mut_slice(); + stake_list.serialize(&mut bytes).unwrap(); + let stake_list_unpacked = try_from_slice_unchecked::(&byte_vec).unwrap(); + assert_eq!(stake_list_unpacked, stake_list); + + // Empty, one preferred key + let stake_list = ValidatorList { + account_type: AccountType::ValidatorList, + preferred_deposit_validator_vote_address: Some(Pubkey::new_unique()), + preferred_withdraw_validator_vote_address: None, + max_validators: 0, + validators: vec![], }; let mut byte_vec = vec![0u8; size]; let mut bytes = byte_vec.as_mut_slice(); stake_list.serialize(&mut bytes).unwrap(); let stake_list_unpacked = try_from_slice_unchecked::(&byte_vec).unwrap(); assert_eq!(stake_list_unpacked, stake_list); + + // With several accounts + let stake_list = test_validator_list(max_validators); + let mut byte_vec = vec![0u8; size]; + let mut bytes = byte_vec.as_mut_slice(); + stake_list.serialize(&mut bytes).unwrap(); + let stake_list_unpacked = try_from_slice_unchecked::(&byte_vec).unwrap(); + assert_eq!(stake_list_unpacked, stake_list); + } + + #[test] + fn validator_list_active_stake() { + let max_validators = 10_000; + let mut validator_list = test_validator_list(max_validators); + assert!(validator_list.has_active_stake()); + for validator in validator_list.validators.iter_mut() { + validator.active_stake_lamports = 0; + } + assert!(!validator_list.has_active_stake()); } proptest! { diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 0531707c..1c45c3d8 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -191,8 +191,8 @@ async fn success() { .find(&validator_stake_account.vote.pubkey()) .unwrap(); assert_eq!( - validator_stake_item.stake_lamports, - validator_stake_item_before.stake_lamports + stake_lamports + validator_stake_item.stake_lamports(), + validator_stake_item_before.stake_lamports() + stake_lamports ); // Check validator stake account actual SOL balance @@ -203,8 +203,9 @@ async fn success() { let meta = stake_state.meta().unwrap(); assert_eq!( validator_stake_account.lamports - minimum_stake_lamports(&meta), - validator_stake_item.stake_lamports + validator_stake_item.stake_lamports() ); + assert_eq!(validator_stake_item.transient_stake_lamports, 0); } #[tokio::test] diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index ee1f21ae..2317e41a 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -1124,7 +1124,7 @@ pub async fn get_validator_list_sum( let validator_sum: u64 = validator_list .validators .iter() - .map(|info| info.stake_lamports) + .map(|info| info.stake_lamports()) .sum(); let rent = banks_client.get_rent().await.unwrap(); let rent = rent.minimum_balance(std::mem::size_of::()); diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index 1eef712f..b461fb62 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -536,8 +536,9 @@ async fn merge_transient_stake_after_remove() { validator_list.validators[0].status, StakeStatus::DeactivatingTransient ); + assert_eq!(validator_list.validators[0].active_stake_lamports, 0); assert_eq!( - validator_list.validators[0].stake_lamports, + validator_list.validators[0].transient_stake_lamports, deactivated_lamports ); @@ -569,7 +570,7 @@ async fn merge_transient_stake_after_remove() { validator_list.validators[0].status, StakeStatus::ReadyForRemoval ); - assert_eq!(validator_list.validators[0].stake_lamports, 0); + assert_eq!(validator_list.validators[0].stake_lamports(), 0); let reserve_stake = context .banks_client diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index fd403249..5a675453 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -91,7 +91,8 @@ async fn success() { status: state::StakeStatus::Active, vote_account_address: user_stake.vote.pubkey(), last_update_epoch: 0, - stake_lamports: 0, + active_stake_lamports: 0, + transient_stake_lamports: 0, }] } ); diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 0d94ebea..ca0437d9 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -529,7 +529,8 @@ async fn success_with_deactivating_transient_stake() { status: state::StakeStatus::DeactivatingTransient, vote_account_address: validator_stake.vote.pubkey(), last_update_epoch: 0, - stake_lamports: TEST_STAKE_AMOUNT + stake_rent, + active_stake_lamports: 0, + transient_stake_lamports: TEST_STAKE_AMOUNT + stake_rent, }], }; assert_eq!(validator_list, expected_list); diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 2905b948..5e5c7a66 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -181,8 +181,12 @@ async fn success() { .find(&validator_stake_account.vote.pubkey()) .unwrap(); assert_eq!( - validator_stake_item.stake_lamports, - validator_stake_item_before.stake_lamports - tokens_to_burn + validator_stake_item.stake_lamports(), + validator_stake_item_before.stake_lamports() - tokens_to_burn + ); + assert_eq!( + validator_stake_item.active_stake_lamports, + validator_stake_item.stake_lamports(), ); // Check tokens burned @@ -201,7 +205,7 @@ async fn success() { let meta = stake_state.meta().unwrap(); assert_eq!( validator_stake_account.lamports - minimum_stake_lamports(&meta), - validator_stake_item.stake_lamports + validator_stake_item.active_stake_lamports ); // Check user recipient stake account balance @@ -1131,3 +1135,172 @@ async fn fail_with_wrong_preferred_withdraw() { _ => panic!("Wrong error occurs while try to make a deposit with wrong stake program ID"), } } + +#[tokio::test] +async fn success_withdraw_from_transient() { + let mut context = program_test().start_with_context().await; + let stake_pool_accounts = StakePoolAccounts::new(); + let initial_reserve_lamports = 1; + stake_pool_accounts + .initialize_stake_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + initial_reserve_lamports, + ) + .await + .unwrap(); + + // add a preferred withdraw validator, keep it empty, to be sure that this works + let preferred_validator = simple_add_validator_to_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + ) + .await; + + stake_pool_accounts + .set_preferred_validator( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + instruction::PreferredValidatorType::Withdraw, + Some(preferred_validator.vote.pubkey()), + ) + .await; + + let validator_stake = simple_add_validator_to_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + ) + .await; + + let deposit_lamports = TEST_STAKE_AMOUNT; + let rent = context.banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + + let deposit_info = simple_deposit( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + &validator_stake, + deposit_lamports, + ) + .await + .unwrap(); + + // Delegate tokens for burning during withdraw + let user_transfer_authority = Keypair::new(); + delegate_tokens( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &deposit_info.pool_account.pubkey(), + &deposit_info.authority, + &user_transfer_authority.pubkey(), + deposit_info.pool_tokens, + ) + .await; + + // decrease minimum stake + let error = stake_pool_accounts + .decrease_validator_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &validator_stake.stake_account, + &validator_stake.transient_stake_account, + stake_rent + 1, + ) + .await; + assert!(error.is_none()); + + let withdraw_destination = Keypair::new(); + let withdraw_destination_authority = Pubkey::new_unique(); + let _initial_stake_lamports = create_blank_stake_account( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &withdraw_destination, + ) + .await; + + // fail withdrawing from transient, still a lamport in the validator stake account + let error = stake_pool_accounts + .withdraw_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &withdraw_destination.pubkey(), + &user_transfer_authority, + &deposit_info.pool_account.pubkey(), + &validator_stake.transient_stake_account, + &withdraw_destination_authority, + deposit_info.pool_tokens / 2, + ) + .await + .unwrap() + .unwrap(); + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::InvalidStakeAccountAddress as u32) + ) + ); + + // warp forward to deactivation + let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + context + .warp_to_slot(first_normal_slot + slots_per_epoch) + .unwrap(); + + // update to merge deactivated stake into reserve + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &[ + preferred_validator.vote.pubkey(), + validator_stake.vote.pubkey(), + ], + false, + ) + .await; + + // decrease rest of stake + let error = stake_pool_accounts + .decrease_validator_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &validator_stake.stake_account, + &validator_stake.transient_stake_account, + deposit_lamports - 1, + ) + .await; + assert!(error.is_none()); + + // nothing left in the validator stake account (or any others), so withdrawing + // from the transient account is ok! + let error = stake_pool_accounts + .withdraw_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &withdraw_destination.pubkey(), + &user_transfer_authority, + &deposit_info.pool_account.pubkey(), + &validator_stake.transient_stake_account, + &withdraw_destination_authority, + deposit_info.pool_tokens / 4, + ) + .await; + assert!(error.is_none()); +} From 1473700bea497ae389f47eedf68430713bbff672 Mon Sep 17 00:00:00 2001 From: Tyera Eulberg Date: Mon, 14 Jun 2021 14:44:58 -0600 Subject: [PATCH 0111/1076] Bump solana version --- clients/cli/Cargo.toml | 14 +++++++------- program/Cargo.toml | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 850cf0f3..e3853149 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -12,13 +12,13 @@ version = "0.2.0" borsh = "0.8" clap = "2.33.3" serde_json = "1.0.62" -solana-account-decoder = "1.6.7" -solana-clap-utils = "1.6.7" -solana-cli-config = "1.6.7" -solana-client = "1.6.7" -solana-logger = "1.6.7" -solana-sdk = "1.6.7" -solana-program = "1.6.7" +solana-account-decoder = "1.6.11" +solana-clap-utils = "1.6.11" +solana-cli-config = "1.6.11" +solana-client = "1.6.11" +solana-logger = "1.6.11" +solana-sdk = "1.6.11" +solana-program = "1.6.11" spl-associated-token-account = { version = "1.0", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "0.2", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "3.1", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/program/Cargo.toml b/program/Cargo.toml index 1b5fdbba..7b0b98a3 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -19,7 +19,7 @@ num-traits = "0.2" num_enum = "0.5.1" serde = "1.0.121" serde_derive = "1.0.103" -solana-program = "1.6.7" +solana-program = "1.6.11" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-token = { version = "3.1", path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" @@ -27,9 +27,9 @@ bincode = "1.3.1" [dev-dependencies] proptest = "0.10" -solana-program-test = "1.6.7" -solana-sdk = "1.6.7" -solana-vote-program = "1.6.7" +solana-program-test = "1.6.11" +solana-sdk = "1.6.11" +solana-vote-program = "1.6.11" [lib] crate-type = ["cdylib", "lib"] From 332357d550d91796e9f4f7c509bfc2ad312a1719 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 16 Jun 2021 01:40:14 +0200 Subject: [PATCH 0112/1076] stake-pool: Wait to apply new fee (#1922) * Add `next_epoch_fee` field and fix serde * Only update fee after the epoch is passed * Update docs --- clients/cli/src/client.rs | 6 +- clients/cli/src/main.rs | 9 +- program/src/borsh.rs | 39 ------- program/src/lib.rs | 1 - program/src/processor.rs | 40 ++++--- program/src/stake_program.rs | 2 +- program/src/state.rs | 12 ++- program/tests/deposit.rs | 13 ++- program/tests/helpers/mod.rs | 8 +- program/tests/initialize.rs | 12 +-- program/tests/set_fee.rs | 100 +++++++++++++----- program/tests/set_manager.rs | 6 +- program/tests/set_preferred.rs | 2 +- program/tests/set_staker.rs | 12 ++- program/tests/update_stake_pool_balance.rs | 9 +- .../tests/update_validator_list_balance.rs | 16 ++- program/tests/vsa_add.rs | 6 +- program/tests/vsa_remove.rs | 6 +- program/tests/withdraw.rs | 11 +- 19 files changed, 161 insertions(+), 149 deletions(-) delete mode 100644 program/src/borsh.rs diff --git a/clients/cli/src/client.rs b/clients/cli/src/client.rs index d77a564c..854dbdf2 100644 --- a/clients/cli/src/client.rs +++ b/clients/cli/src/client.rs @@ -1,6 +1,5 @@ use { bincode::deserialize, - borsh::BorshDeserialize, solana_account_decoder::UiAccountEncoding, solana_client::{ client_error::ClientError, @@ -8,9 +7,8 @@ use { rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig}, rpc_filter::{Memcmp, MemcmpEncodedBytes, RpcFilterType}, }, - solana_program::{program_pack::Pack, pubkey::Pubkey}, + solana_program::{borsh::try_from_slice_unchecked, program_pack::Pack, pubkey::Pubkey}, spl_stake_pool::{ - borsh::try_from_slice_unchecked, stake_program, state::{StakePool, ValidatorList}, }, @@ -23,7 +21,7 @@ pub fn get_stake_pool( stake_pool_address: &Pubkey, ) -> Result { let account_data = rpc_client.get_account_data(stake_pool_address)?; - let stake_pool = StakePool::try_from_slice(account_data.as_slice()) + let stake_pool = try_from_slice_unchecked::(account_data.as_slice()) .map_err(|err| format!("Invalid stake pool {}: {}", stake_pool_address, err))?; Ok(stake_pool) } diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 9310b326..b94e39ba 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -18,7 +18,10 @@ use { }, solana_client::rpc_client::RpcClient, solana_program::{ - borsh::get_packed_len, instruction::Instruction, program_pack::Pack, pubkey::Pubkey, + borsh::{get_instance_packed_len, get_packed_len}, + instruction::Instruction, + program_pack::Pack, + pubkey::Pubkey, }, solana_sdk::{ commitment_config::CommitmentConfig, @@ -29,9 +32,7 @@ use { }, spl_associated_token_account::{create_associated_token_account, get_associated_token_address}, spl_stake_pool::{ - self, - borsh::get_instance_packed_len, - find_stake_program_address, find_withdraw_authority_program_address, + self, find_stake_program_address, find_withdraw_authority_program_address, instruction::PreferredValidatorType, stake_program::{self, StakeState}, state::{Fee, StakePool, ValidatorList}, diff --git a/program/src/borsh.rs b/program/src/borsh.rs deleted file mode 100644 index e62bcbba..00000000 --- a/program/src/borsh.rs +++ /dev/null @@ -1,39 +0,0 @@ -//! Extra borsh utils -//! TODO delete once try_from_slice_unchecked has been published - -use { - borsh::{maybestd::io::Error, BorshDeserialize, BorshSerialize}, - std::io::{self, Write}, -}; - -/// Deserializes something and allows for incomplete reading -pub fn try_from_slice_unchecked(data: &[u8]) -> Result { - let mut data_mut = data; - let result = T::deserialize(&mut data_mut)?; - Ok(result) -} - -/// Helper struct which to count how much data would be written during serialization -#[derive(Default)] -struct WriteCounter { - count: usize, -} - -impl Write for WriteCounter { - fn write(&mut self, data: &[u8]) -> io::Result { - let amount = data.len(); - self.count += amount; - Ok(amount) - } - - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } -} - -/// Get the worst-case packed length for the given BorshSchema -pub fn get_instance_packed_len(instance: &T) -> Result { - let mut counter = WriteCounter::default(); - instance.serialize(&mut counter)?; - Ok(counter.count) -} diff --git a/program/src/lib.rs b/program/src/lib.rs index 333e7603..56f9e798 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -2,7 +2,6 @@ //! A program for creating and managing pools of stake -pub mod borsh; pub mod error; pub mod instruction; pub mod processor; diff --git a/program/src/processor.rs b/program/src/processor.rs index b42d91f2..3a77076d 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -2,7 +2,6 @@ use { crate::{ - borsh::try_from_slice_unchecked, error::StakePoolError, find_deposit_authority_program_address, instruction::{PreferredValidatorType, StakePoolInstruction}, @@ -15,6 +14,7 @@ use { solana_program::{ account_info::next_account_info, account_info::AccountInfo, + borsh::try_from_slice_unchecked, clock::{Clock, Epoch}, decode_error::DecodeError, entrypoint::ProgramResult, @@ -409,7 +409,7 @@ impl Processor { } check_account_owner(stake_pool_info, program_id)?; - let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; + let mut stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; if !stake_pool.is_uninitialized() { msg!("Provided stake pool already in use"); return Err(StakePoolError::AlreadyInUse.into()); @@ -541,8 +541,9 @@ impl Processor { stake_pool.manager_fee_account = *manager_fee_info.key; stake_pool.token_program_id = *token_program_info.key; stake_pool.last_update_epoch = clock.epoch; - stake_pool.fee = fee; stake_pool.total_stake_lamports = total_stake_lamports; + stake_pool.fee = fee; + stake_pool.next_epoch_fee = None; stake_pool .serialize(&mut *stake_pool_info.data.borrow_mut()) @@ -569,7 +570,7 @@ impl Processor { let stake_program_info = next_account_info(account_info_iter)?; check_account_owner(stake_pool_info, program_id)?; - let stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; + let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); } @@ -663,7 +664,7 @@ impl Processor { check_stake_program(stake_program_info.key)?; check_account_owner(stake_pool_info, program_id)?; - let stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; + let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); } @@ -765,7 +766,7 @@ impl Processor { check_stake_program(stake_program_info.key)?; check_account_owner(stake_pool_info, program_id)?; - let stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; + let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); } @@ -898,7 +899,7 @@ impl Processor { check_stake_program(stake_program_info.key)?; check_account_owner(stake_pool_info, program_id)?; - let stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; + let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { msg!("Expected valid stake pool"); return Err(StakePoolError::InvalidState.into()); @@ -1036,7 +1037,7 @@ impl Processor { check_stake_program(stake_program_info.key)?; check_account_owner(stake_pool_info, program_id)?; - let stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; + let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { msg!("Expected valid stake pool"); return Err(StakePoolError::InvalidState.into()); @@ -1177,7 +1178,7 @@ impl Processor { check_account_owner(stake_pool_info, program_id)?; check_account_owner(validator_list_info, program_id)?; - let stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; + let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { msg!("Expected valid stake pool"); return Err(StakePoolError::InvalidState.into()); @@ -1230,7 +1231,7 @@ impl Processor { let validator_stake_accounts = account_info_iter.as_slice(); check_account_owner(stake_pool_info, program_id)?; - let stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; + let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); } @@ -1430,7 +1431,7 @@ impl Processor { let token_program_info = next_account_info(account_info_iter)?; check_account_owner(stake_pool_info, program_id)?; - let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; + let mut stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); } @@ -1500,6 +1501,11 @@ impl Processor { .checked_add(fee) .ok_or(StakePoolError::CalculationFailure)?; } + + if let Some(next_epoch_fee) = stake_pool.next_epoch_fee { + stake_pool.fee = next_epoch_fee; + stake_pool.next_epoch_fee = None; + } validator_list .validators .retain(|item| item.status != StakeStatus::ReadyForRemoval); @@ -1559,7 +1565,7 @@ impl Processor { } check_account_owner(stake_pool_info, program_id)?; - let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; + let mut stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); } @@ -1715,7 +1721,7 @@ impl Processor { check_stake_program(stake_program_info.key)?; check_account_owner(stake_pool_info, program_id)?; - let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; + let mut stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); } @@ -1898,7 +1904,7 @@ impl Processor { let new_manager_fee_info = next_account_info(account_info_iter)?; check_account_owner(stake_pool_info, program_id)?; - let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; + let mut stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); } @@ -1927,7 +1933,7 @@ impl Processor { let clock = &Clock::from_account_info(clock_info)?; check_account_owner(stake_pool_info, program_id)?; - let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; + let mut stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); } @@ -1948,7 +1954,7 @@ impl Processor { return Err(StakePoolError::FeeTooHigh.into()); } - stake_pool.fee = fee; + stake_pool.next_epoch_fee = Some(fee); stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; Ok(()) } @@ -1961,7 +1967,7 @@ impl Processor { let new_staker_info = next_account_info(account_info_iter)?; check_account_owner(stake_pool_info, program_id)?; - let mut stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?; + let mut stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); } diff --git a/program/src/stake_program.rs b/program/src/stake_program.rs index daea623a..7a205bbd 100644 --- a/program/src/stake_program.rs +++ b/program/src/stake_program.rs @@ -647,7 +647,7 @@ pub fn deactivate_stake(stake_pubkey: &Pubkey, authorized_pubkey: &Pubkey) -> In #[cfg(test)] mod test { - use {super::*, crate::borsh::try_from_slice_unchecked, bincode::serialize}; + use {super::*, bincode::serialize, solana_program::borsh::try_from_slice_unchecked}; fn check_borsh_deserialization(stake: StakeState) { let serialized = serialize(&stake).unwrap(); diff --git a/program/src/state.rs b/program/src/state.rs index 9ef6493d..8d7a1e1c 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -80,8 +80,11 @@ pub struct StakePool { /// Last epoch the `total_stake_lamports` field was updated pub last_update_epoch: u64, - /// Fee applied to deposits + /// Fee taken as a proportion of rewards each epoch pub fee: Fee, + + /// Fee for next epoch + pub next_epoch_fee: Option, } impl StakePool { /// calculate the pool tokens that should be minted for a deposit of `stake_lamports` @@ -119,7 +122,7 @@ impl StakePool { /// This function assumes that `reward_lamports` has not already been added /// to the stake pool's `total_stake_lamports` pub fn calc_fee_amount(&self, reward_lamports: u64) -> Option { - if self.fee.denominator == 0 { + if self.fee.denominator == 0 || reward_lamports == 0 { return Some(0); } let total_stake_lamports = @@ -420,9 +423,10 @@ pub struct Fee { mod test { use { super::*, - crate::borsh::{get_instance_packed_len, try_from_slice_unchecked}, proptest::prelude::*, - solana_program::borsh::get_packed_len, + solana_program::borsh::{ + get_instance_packed_len, get_packed_len, try_from_slice_unchecked, + }, solana_program::native_token::LAMPORTS_PER_SOL, }; diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 1c45c3d8..2abf8e33 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -4,9 +4,10 @@ mod helpers; use { bincode::deserialize, - borsh::{BorshDeserialize, BorshSerialize}, + borsh::BorshSerialize, helpers::*, solana_program::{ + borsh::try_from_slice_unchecked, hash::Hash, instruction::{AccountMeta, Instruction, InstructionError}, pubkey::Pubkey, @@ -19,10 +20,7 @@ use { transaction::TransactionError, transport::TransportError, }, - spl_stake_pool::{ - borsh::try_from_slice_unchecked, error, id, instruction, minimum_stake_lamports, - stake_program, state, - }, + spl_stake_pool::{error, id, instruction, minimum_stake_lamports, stake_program, state}, spl_token::error as token_error, }; @@ -127,7 +125,7 @@ async fn success() { let stake_pool_before = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; let stake_pool_before = - state::StakePool::try_from_slice(&stake_pool_before.data.as_slice()).unwrap(); + try_from_slice_unchecked::(&stake_pool_before.data.as_slice()).unwrap(); // Save validator stake account record before depositing let validator_list = get_account( @@ -165,7 +163,8 @@ async fn success() { // Stake pool should add its balance to the pool balance let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; - let stake_pool = state::StakePool::try_from_slice(&stake_pool.data.as_slice()).unwrap(); + let stake_pool = + try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); assert_eq!( stake_pool.total_stake_lamports, stake_pool_before.total_stake_lamports + stake_lamports diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 2317e41a..bb67c99a 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -2,8 +2,11 @@ use { solana_program::{ - borsh::get_packed_len, hash::Hash, program_pack::Pack, pubkey::Pubkey, system_instruction, - system_program, + borsh::{get_instance_packed_len, get_packed_len, try_from_slice_unchecked}, + hash::Hash, + program_pack::Pack, + pubkey::Pubkey, + system_instruction, system_program, }, solana_program_test::*, solana_sdk::{ @@ -17,7 +20,6 @@ use { vote_state::{VoteInit, VoteState}, }, spl_stake_pool::{ - borsh::{get_instance_packed_len, try_from_slice_unchecked}, find_stake_program_address, find_transient_stake_program_address, id, instruction, processor, stake_program, state, }, diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index 45346665..d4f5ed1d 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -3,10 +3,10 @@ mod helpers; use { - borsh::{BorshDeserialize, BorshSerialize}, + borsh::BorshSerialize, helpers::*, solana_program::{ - borsh::get_packed_len, + borsh::{get_instance_packed_len, get_packed_len, try_from_slice_unchecked}, hash::Hash, instruction::{AccountMeta, Instruction}, program_pack::Pack, @@ -18,10 +18,7 @@ use { instruction::InstructionError, signature::Keypair, signature::Signer, transaction::Transaction, transaction::TransactionError, transport::TransportError, }, - spl_stake_pool::{ - borsh::{get_instance_packed_len, try_from_slice_unchecked}, - error, id, instruction, stake_program, state, - }, + spl_stake_pool::{error, id, instruction, stake_program, state}, }; async fn create_required_accounts( @@ -1029,7 +1026,8 @@ async fn success_with_required_deposit_authority() { // Stake pool now exists let stake_pool_account = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; - let stake_pool = state::StakePool::try_from_slice(stake_pool_account.data.as_slice()).unwrap(); + let stake_pool = + try_from_slice_unchecked::(stake_pool_account.data.as_slice()).unwrap(); assert_eq!( stake_pool.deposit_authority, stake_pool_accounts.deposit_authority diff --git a/program/tests/set_fee.rs b/program/tests/set_fee.rs index 2fd6cdb9..b4af165e 100644 --- a/program/tests/set_fee.rs +++ b/program/tests/set_fee.rs @@ -3,11 +3,10 @@ mod helpers; use { - borsh::BorshDeserialize, helpers::*, - solana_program::hash::Hash, solana_program_test::*, solana_sdk::{ + borsh::try_from_slice_unchecked, instruction::InstructionError, signature::{Keypair, Signer}, transaction::{Transaction, TransactionError}, @@ -18,11 +17,16 @@ use { }, }; -async fn setup() -> (BanksClient, Keypair, Hash, StakePoolAccounts, Fee) { - let (mut banks_client, payer, recent_blockhash) = program_test().start().await; +async fn setup() -> (ProgramTestContext, StakePoolAccounts, Fee) { + let mut context = program_test().start_with_context().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .initialize_stake_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + 1, + ) .await .unwrap(); let new_fee = Fee { @@ -30,18 +34,20 @@ async fn setup() -> (BanksClient, Keypair, Hash, StakePoolAccounts, Fee) { denominator: 10, }; - ( - banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - new_fee, - ) + (context, stake_pool_accounts, new_fee) } #[tokio::test] async fn success() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_fee) = setup().await; + let (mut context, stake_pool_accounts, new_fee) = setup().await; + + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + let old_fee = stake_pool.fee; let transaction = Transaction::new_signed_with_payer( &[instruction::set_fee( @@ -50,21 +56,55 @@ async fn success() { &stake_pool_accounts.manager.pubkey(), new_fee, )], - Some(&payer.pubkey()), - &[&payer, &stake_pool_accounts.manager], - recent_blockhash, + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, ); - banks_client.process_transaction(transaction).await.unwrap(); + context + .banks_client + .process_transaction(transaction) + .await + .unwrap(); + + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); - let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; - let stake_pool = StakePool::try_from_slice(&stake_pool.data.as_slice()).unwrap(); + assert_eq!(stake_pool.fee, old_fee); + assert_eq!(stake_pool.next_epoch_fee, Some(new_fee)); + let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + + context + .warp_to_slot(first_normal_slot + slots_per_epoch) + .unwrap(); + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &[], + false, + ) + .await; + + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); assert_eq!(stake_pool.fee, new_fee); + assert_eq!(stake_pool.next_epoch_fee, None); } #[tokio::test] async fn fail_wrong_manager() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_fee) = setup().await; + let (mut context, stake_pool_accounts, new_fee) = setup().await; let wrong_manager = Keypair::new(); let transaction = Transaction::new_signed_with_payer( @@ -74,11 +114,12 @@ async fn fail_wrong_manager() { &wrong_manager.pubkey(), new_fee, )], - Some(&payer.pubkey()), - &[&payer, &wrong_manager], - recent_blockhash, + Some(&context.payer.pubkey()), + &[&context.payer, &wrong_manager], + context.last_blockhash, ); - let error = banks_client + let error = context + .banks_client .process_transaction(transaction) .await .err() @@ -96,7 +137,7 @@ async fn fail_wrong_manager() { #[tokio::test] async fn fail_bad_fee() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, _new_fee) = setup().await; + let (mut context, stake_pool_accounts, _new_fee) = setup().await; let new_fee = Fee { numerator: 11, @@ -109,11 +150,12 @@ async fn fail_bad_fee() { &stake_pool_accounts.manager.pubkey(), new_fee, )], - Some(&payer.pubkey()), - &[&payer, &stake_pool_accounts.manager], - recent_blockhash, + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, ); - let error = banks_client + let error = context + .banks_client .process_transaction(transaction) .await .err() diff --git a/program/tests/set_manager.rs b/program/tests/set_manager.rs index 0009d761..d50d2f5f 100644 --- a/program/tests/set_manager.rs +++ b/program/tests/set_manager.rs @@ -3,9 +3,10 @@ mod helpers; use { - borsh::{BorshDeserialize, BorshSerialize}, + borsh::BorshSerialize, helpers::*, solana_program::{ + borsh::try_from_slice_unchecked, hash::Hash, instruction::{AccountMeta, Instruction}, }, @@ -74,7 +75,8 @@ async fn test_set_manager() { banks_client.process_transaction(transaction).await.unwrap(); let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; - let stake_pool = state::StakePool::try_from_slice(&stake_pool.data.as_slice()).unwrap(); + let stake_pool = + try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); assert_eq!(stake_pool.manager, new_manager.pubkey()); } diff --git a/program/tests/set_preferred.rs b/program/tests/set_preferred.rs index 932bb255..338caa92 100644 --- a/program/tests/set_preferred.rs +++ b/program/tests/set_preferred.rs @@ -7,13 +7,13 @@ use { solana_program::hash::Hash, solana_program_test::*, solana_sdk::{ + borsh::try_from_slice_unchecked, instruction::InstructionError, pubkey::Pubkey, signature::{Keypair, Signer}, transaction::{Transaction, TransactionError}, }, spl_stake_pool::{ - borsh::try_from_slice_unchecked, error, id, instruction::{self, PreferredValidatorType}, state::ValidatorList, diff --git a/program/tests/set_staker.rs b/program/tests/set_staker.rs index 2f93cbd2..2425f4d1 100644 --- a/program/tests/set_staker.rs +++ b/program/tests/set_staker.rs @@ -3,9 +3,10 @@ mod helpers; use { - borsh::{BorshDeserialize, BorshSerialize}, + borsh::BorshSerialize, helpers::*, solana_program::{ + borsh::try_from_slice_unchecked, hash::Hash, instruction::{AccountMeta, Instruction}, }, @@ -54,7 +55,8 @@ async fn success_set_staker_as_manager() { banks_client.process_transaction(transaction).await.unwrap(); let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; - let stake_pool = state::StakePool::try_from_slice(&stake_pool.data.as_slice()).unwrap(); + let stake_pool = + try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); assert_eq!(stake_pool.staker, new_staker.pubkey()); } @@ -77,7 +79,8 @@ async fn success_set_staker_as_staker() { banks_client.process_transaction(transaction).await.unwrap(); let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; - let stake_pool = state::StakePool::try_from_slice(&stake_pool.data.as_slice()).unwrap(); + let stake_pool = + try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); assert_eq!(stake_pool.staker, new_staker.pubkey()); @@ -94,7 +97,8 @@ async fn success_set_staker_as_staker() { banks_client.process_transaction(transaction).await.unwrap(); let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; - let stake_pool = state::StakePool::try_from_slice(&stake_pool.data.as_slice()).unwrap(); + let stake_pool = + try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); assert_eq!(stake_pool.staker, stake_pool_accounts.staker.pubkey()); } diff --git a/program/tests/update_stake_pool_balance.rs b/program/tests/update_stake_pool_balance.rs index f4995ed8..6046e9b4 100644 --- a/program/tests/update_stake_pool_balance.rs +++ b/program/tests/update_stake_pool_balance.rs @@ -3,9 +3,10 @@ mod helpers; use { - borsh::BorshDeserialize, helpers::*, - solana_program::{instruction::InstructionError, pubkey::Pubkey}, + solana_program::{ + borsh::try_from_slice_unchecked, instruction::InstructionError, pubkey::Pubkey, + }, solana_program_test::*, solana_sdk::{ signature::{Keypair, Signer}, @@ -75,7 +76,7 @@ async fn success() { &stake_pool_accounts.stake_pool.pubkey(), ) .await; - let stake_pool = StakePool::try_from_slice(&stake_pool.data.as_slice()).unwrap(); + let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); assert_eq!(pre_balance, stake_pool.total_stake_lamports); let pre_token_supply = get_token_supply( @@ -137,7 +138,7 @@ async fn success() { &stake_pool_accounts.stake_pool.pubkey(), ) .await; - let stake_pool = StakePool::try_from_slice(&stake_pool.data.as_slice()).unwrap(); + let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); assert_eq!(post_balance, stake_pool.total_stake_lamports); let actual_fee = get_token_balance( diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index b461fb62..0f0ff5db 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -3,13 +3,11 @@ mod helpers; use { - borsh::BorshDeserialize, helpers::*, - solana_program::pubkey::Pubkey, + solana_program::{borsh::try_from_slice_unchecked, pubkey::Pubkey}, solana_program_test::*, solana_sdk::signature::{Keypair, Signer}, spl_stake_pool::{ - borsh::try_from_slice_unchecked, stake_program, state::{StakePool, StakeStatus, ValidatorList}, MAX_VALIDATORS_TO_UPDATE, MINIMUM_ACTIVE_STAKE, @@ -228,7 +226,7 @@ async fn success() { &stake_pool_accounts.stake_pool.pubkey(), ) .await; - let stake_pool = StakePool::try_from_slice(&stake_pool_info.data).unwrap(); + let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data).unwrap(); assert_eq!(new_lamports, stake_pool.total_stake_lamports); } @@ -295,7 +293,7 @@ async fn merge_into_reserve() { &stake_pool_accounts.stake_pool.pubkey(), ) .await; - let stake_pool = StakePool::try_from_slice(&stake_pool_info.data).unwrap(); + let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data).unwrap(); assert_eq!(expected_lamports, stake_pool.total_stake_lamports); // Warp one more epoch so the stakes deactivate @@ -338,7 +336,7 @@ async fn merge_into_reserve() { &stake_pool_accounts.stake_pool.pubkey(), ) .await; - let stake_pool = StakePool::try_from_slice(&stake_pool_info.data).unwrap(); + let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data).unwrap(); assert_eq!(expected_lamports, stake_pool.total_stake_lamports); } @@ -401,7 +399,7 @@ async fn merge_into_validator_stake() { &stake_pool_accounts.stake_pool.pubkey(), ) .await; - let stake_pool = StakePool::try_from_slice(&stake_pool_info.data).unwrap(); + let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data).unwrap(); assert_eq!(expected_lamports, stake_pool.total_stake_lamports); let stake_pool_info = get_account( @@ -409,7 +407,7 @@ async fn merge_into_validator_stake() { &stake_pool_accounts.stake_pool.pubkey(), ) .await; - let stake_pool = StakePool::try_from_slice(&stake_pool_info.data).unwrap(); + let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data).unwrap(); assert_eq!(expected_lamports, stake_pool.total_stake_lamports); // Warp one more epoch so the stakes activate, ready to merge @@ -442,7 +440,7 @@ async fn merge_into_validator_stake() { &stake_pool_accounts.stake_pool.pubkey(), ) .await; - let stake_pool = StakePool::try_from_slice(&stake_pool_info.data).unwrap(); + let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data).unwrap(); assert_eq!(current_lamports, stake_pool.total_stake_lamports); // Check that transient accounts are gone diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index 5a675453..e72dd75d 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -7,6 +7,7 @@ use { borsh::BorshSerialize, helpers::*, solana_program::{ + borsh::try_from_slice_unchecked, hash::Hash, instruction::{AccountMeta, Instruction, InstructionError}, pubkey::Pubkey, @@ -18,10 +19,7 @@ use { transaction::{Transaction, TransactionError}, transport::TransportError, }, - spl_stake_pool::{ - borsh::try_from_slice_unchecked, error::StakePoolError, id, instruction, stake_program, - state, - }, + spl_stake_pool::{error::StakePoolError, id, instruction, stake_program, state}, }; async fn setup() -> ( diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index ca0437d9..54e34e11 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -7,6 +7,7 @@ use { borsh::BorshSerialize, helpers::*, solana_program::{ + borsh::try_from_slice_unchecked, hash::Hash, instruction::{AccountMeta, Instruction, InstructionError}, pubkey::Pubkey, @@ -18,10 +19,7 @@ use { transaction::{Transaction, TransactionError}, transport::TransportError, }, - spl_stake_pool::{ - borsh::try_from_slice_unchecked, error::StakePoolError, id, instruction, stake_program, - state, - }, + spl_stake_pool::{error::StakePoolError, id, instruction, stake_program, state}, }; async fn setup() -> ( diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 5e5c7a66..c7b918c7 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -4,9 +4,10 @@ mod helpers; use { bincode::deserialize, - borsh::{BorshDeserialize, BorshSerialize}, + borsh::BorshSerialize, helpers::*, solana_program::{ + borsh::try_from_slice_unchecked, hash::Hash, instruction::{AccountMeta, Instruction, InstructionError}, pubkey::Pubkey, @@ -19,8 +20,7 @@ use { transport::TransportError, }, spl_stake_pool::{ - borsh::try_from_slice_unchecked, error::StakePoolError, id, instruction, - minimum_stake_lamports, stake_program, state, + error::StakePoolError, id, instruction, minimum_stake_lamports, stake_program, state, }, spl_token::error::TokenError, }; @@ -118,7 +118,7 @@ async fn success() { let stake_pool_before = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; let stake_pool_before = - state::StakePool::try_from_slice(&stake_pool_before.data.as_slice()).unwrap(); + try_from_slice_unchecked::(&stake_pool_before.data.as_slice()).unwrap(); // Check user recipient stake account balance let initial_stake_lamports = get_account(&mut banks_client, &user_stake_recipient.pubkey()) @@ -159,7 +159,8 @@ async fn success() { // Check pool stats let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; - let stake_pool = state::StakePool::try_from_slice(&stake_pool.data.as_slice()).unwrap(); + let stake_pool = + try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); assert_eq!( stake_pool.total_stake_lamports, stake_pool_before.total_stake_lamports - tokens_to_burn From b9feed9bca01c39a88146835619f503b884d7d4b Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 22 Jun 2021 23:38:08 +0200 Subject: [PATCH 0113/1076] stake-pool: Fail initializing if mint has a freeze authority (#1949) --- program/src/error.rs | 3 ++ program/src/processor.rs | 5 +++ program/tests/initialize.rs | 83 +++++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+) diff --git a/program/src/error.rs b/program/src/error.rs index 000b25a5..37add414 100644 --- a/program/src/error.rs +++ b/program/src/error.rs @@ -96,6 +96,9 @@ pub enum StakePoolError { /// The provided withdraw stake account is not the preferred deposit vote account #[error("IncorrectWithdrawVoteAddress")] IncorrectWithdrawVoteAddress, + /// The mint has an invalid freeze authority + #[error("InvalidMintFreezeAuthority")] + InvalidMintFreezeAuthority, } impl From for ProgramError { fn from(e: StakePoolError) -> Self { diff --git a/program/src/processor.rs b/program/src/processor.rs index 3a77076d..e1f693f8 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -488,6 +488,10 @@ impl Processor { return Err(StakePoolError::WrongMintingAuthority.into()); } + if pool_mint.freeze_authority.is_some() { + return Err(StakePoolError::InvalidMintFreezeAuthority.into()); + } + if *reserve_stake_info.owner != stake_program::id() { msg!("Reserve stake account not owned by stake program"); return Err(ProgramError::IncorrectProgramId); @@ -2099,6 +2103,7 @@ impl PrintProgramError for StakePoolError { StakePoolError::StakeLamportsNotEqualToMinimum => msg!("Error: The lamports in the validator stake account is not equal to the minimum"), StakePoolError::IncorrectDepositVoteAddress => msg!("Error: The provided deposit stake account is not delegated to the preferred deposit vote account"), StakePoolError::IncorrectWithdrawVoteAddress => msg!("Error: The provided withdraw stake account is not the preferred deposit vote account"), + StakePoolError::InvalidMintFreezeAuthority => msg!("Error: The mint has an invalid freeze authority"), } } } diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index d4f5ed1d..41e2a437 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -313,6 +313,89 @@ async fn fail_with_wrong_mint_authority() { } } +#[tokio::test] +async fn fail_with_freeze_authority() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + + create_required_accounts( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + ) + .await; + + // create mint with freeze authority + let wrong_mint = Keypair::new(); + let rent = banks_client.get_rent().await.unwrap(); + let mint_rent = rent.minimum_balance(spl_token::state::Mint::LEN); + + let transaction = Transaction::new_signed_with_payer( + &[ + system_instruction::create_account( + &payer.pubkey(), + &wrong_mint.pubkey(), + mint_rent, + spl_token::state::Mint::LEN as u64, + &spl_token::id(), + ), + spl_token::instruction::initialize_mint( + &spl_token::id(), + &wrong_mint.pubkey(), + &stake_pool_accounts.withdraw_authority, + Some(&stake_pool_accounts.withdraw_authority), + 0, + ) + .unwrap(), + ], + Some(&payer.pubkey()), + &[&payer, &wrong_mint], + recent_blockhash, + ); + banks_client.process_transaction(transaction).await.unwrap(); + + let pool_fee_account = Keypair::new(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &pool_fee_account, + &wrong_mint.pubkey(), + &stake_pool_accounts.manager.pubkey(), + ) + .await + .unwrap(); + + let error = create_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.stake_pool, + &stake_pool_accounts.validator_list, + &stake_pool_accounts.reserve_stake.pubkey(), + &wrong_mint.pubkey(), + &pool_fee_account.pubkey(), + &stake_pool_accounts.manager, + &stake_pool_accounts.staker.pubkey(), + &None, + &stake_pool_accounts.fee, + stake_pool_accounts.max_validators, + ) + .await + .err() + .unwrap() + .unwrap(); + + assert_eq!( + error, + TransactionError::InstructionError( + 2, + InstructionError::Custom(error::StakePoolError::InvalidMintFreezeAuthority as u32), + ) + ); +} + #[tokio::test] async fn fail_with_wrong_token_program_id() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; From a86defb1464a23bdedd7de74ffb0eab3b25a3e95 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 22 Jun 2021 23:45:47 +0200 Subject: [PATCH 0114/1076] stake-pool: Split transient stake account creation (#1950) --- program/src/processor.rs | 54 ++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/program/src/processor.rs b/program/src/processor.rs index e1f693f8..685b2b1f 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -132,6 +132,30 @@ fn check_account_owner( } } +/// Create a transient stake account without transferring lamports +fn create_transient_stake_account<'a>( + transient_stake_account_info: AccountInfo<'a>, + transient_stake_account_signer_seeds: &[&[u8]], + system_program_info: AccountInfo<'a>, +) -> Result<(), ProgramError> { + invoke_signed( + &system_instruction::allocate( + transient_stake_account_info.key, + std::mem::size_of::() as u64, + ), + &[ + transient_stake_account_info.clone(), + system_program_info.clone(), + ], + &[&transient_stake_account_signer_seeds], + )?; + invoke_signed( + &system_instruction::assign(transient_stake_account_info.key, &stake_program::id()), + &[transient_stake_account_info, system_program_info], + &[&transient_stake_account_signer_seeds], + ) +} + /// Program state handler. pub struct Processor {} impl Processor { @@ -970,17 +994,10 @@ impl Processor { return Err(ProgramError::AccountNotRentExempt); } - // create transient stake account - invoke_signed( - &system_instruction::create_account( - &transient_stake_account_info.key, // doesn't matter since no lamports are transferred - &transient_stake_account_info.key, - 0, - std::mem::size_of::() as u64, - &stake_program::id(), - ), - &[transient_stake_account_info.clone()], - &[&transient_stake_account_signer_seeds], + create_transient_stake_account( + transient_stake_account_info.clone(), + &transient_stake_account_signer_seeds, + system_program_info.clone(), )?; // split into transient stake account @@ -1124,17 +1141,10 @@ impl Processor { return Err(ProgramError::InsufficientFunds); } - // create transient stake account - invoke_signed( - &system_instruction::create_account( - &transient_stake_account_info.key, // doesn't matter since no lamports are transferred - &transient_stake_account_info.key, - 0, - std::mem::size_of::() as u64, - &stake_program::id(), - ), - &[transient_stake_account_info.clone()], - &[&transient_stake_account_signer_seeds], + create_transient_stake_account( + transient_stake_account_info.clone(), + &transient_stake_account_signer_seeds, + system_program_info.clone(), )?; // split into transient stake account From 99dee0c6b2d874fd94db87791e58721b802d098d Mon Sep 17 00:00:00 2001 From: Lieu Zheng Hong Date: Wed, 23 Jun 2021 20:18:45 +0800 Subject: [PATCH 0115/1076] stake-pool: Stake pool deserializer (#1656) * first commit * add schema for stakepool accounts * got imports working * add typescript support * fix schema * Change to use PublicKey type * change to camelCase instead * add type annotations to typescript classes * add readme * Add prettier linting * add instructions to run * add test section * prettier clean up schema.ts * convert index.js to index.ts * actually use decode method available in Assignable * rename stakepoolaccount so i can have a wrapper class * add new class StakePool and change return type of getStakePoolAccounts * remove extraneous .js files * update schema to incorporate jon's comments * remove unnecessary comments * add helper functions to get individual accounts; cleaned up code * add Fee, change denominator/numerator to BN * Add enums so we can check what type an accountType is * Remove name and ticker in StakePool class * fix borshjs import * change outdir to dist/ folder * Edit package.json * add toBuffer for schema.PublicKey * add exports and default exports to index.ts * fix trailing comma on tsconfig.json * get mocha test harness working with ts-node, ts-mocha, esm * fix borsh import * clean up imports * add working test script * remove unneeded borshjs import * add unit tests for both decodes (WIP) * no need to console.log in testOnDevnet since we now have a test suite * Add tests for ValidatorListAccount.decode * add schema.decode.StakePoolAccount test * Finish up * reduce dependencies in package.json * Add lint command to package.json * Lint with prettier * Update README.md with new commands * Write explanatory comments in index.js * Small linting change * feat: introduce new borshjs deserializeUnchecked import * lint: npm lint * refactor: upgrade web3js version * refactor: refactor type names * refactor: npm run lint * refactor: improve tsconfig.json * feat: add declaration and declarationMap to tsconfig.json * feat: allow getStakePoolAccounts to more robustly handle errors * Update stake-pool/js/.gitignore Co-authored-by: Jon Cinque * Update stake-pool/js/package.json Co-authored-by: Jon Cinque * Update stake-pool/js/package.json Co-authored-by: Jon Cinque * Update stake-pool/js/package.json Co-authored-by: Jon Cinque * Update stake-pool/js/package.json Co-authored-by: Jon Cinque * refactor: modify `constructStakePoolSchema` to mutate in place * lint: remove webpack.config.js * lint: npm run lint * lint: add comments above index.ts * lint: lowercase schema * feat: add full deserialization test * Update stake-pool/js/package.json Co-authored-by: Jon Cinque * refactor: remove try-catch block in getStakePoolAccounts * lint: lint * refactor: use web3js pubkey * refactor: move integration tests to separate file * refactor: change test.js to do encode-decode loop Co-authored-by: Jon Cinque --- clients/js-legacy/.gitignore | 1 + clients/js-legacy/.prettierrc.yaml | 7 + clients/js-legacy/README.md | 47 + clients/js-legacy/package-lock.json | 3694 +++++++++++++++++++++ clients/js-legacy/package.json | 27 + clients/js-legacy/src/index.ts | 156 + clients/js-legacy/src/integration_test.ts | 65 + clients/js-legacy/src/schema.ts | 139 + clients/js-legacy/src/test.ts | 215 ++ clients/js-legacy/tsconfig.json | 14 + 10 files changed, 4365 insertions(+) create mode 100644 clients/js-legacy/.gitignore create mode 100644 clients/js-legacy/.prettierrc.yaml create mode 100644 clients/js-legacy/README.md create mode 100644 clients/js-legacy/package-lock.json create mode 100644 clients/js-legacy/package.json create mode 100644 clients/js-legacy/src/index.ts create mode 100644 clients/js-legacy/src/integration_test.ts create mode 100644 clients/js-legacy/src/schema.ts create mode 100644 clients/js-legacy/src/test.ts create mode 100644 clients/js-legacy/tsconfig.json diff --git a/clients/js-legacy/.gitignore b/clients/js-legacy/.gitignore new file mode 100644 index 00000000..1521c8b7 --- /dev/null +++ b/clients/js-legacy/.gitignore @@ -0,0 +1 @@ +dist diff --git a/clients/js-legacy/.prettierrc.yaml b/clients/js-legacy/.prettierrc.yaml new file mode 100644 index 00000000..8deef5dd --- /dev/null +++ b/clients/js-legacy/.prettierrc.yaml @@ -0,0 +1,7 @@ +arrowParens: "avoid" +bracketSpacing: false +jsxBracketSameLine: false +semi: true +singleQuote: true +tabWidth: 2 +trailingComma: "all" diff --git a/clients/js-legacy/README.md b/clients/js-legacy/README.md new file mode 100644 index 00000000..ae7fccbf --- /dev/null +++ b/clients/js-legacy/README.md @@ -0,0 +1,47 @@ +# TypeScript bindings for stake-pool program + +For use with both node.js and in-browser. + +## Installation + +``` +npm install +``` + +## Build and run + +In the `js` folder: + +``` +npm run compile +npm run lint +node dist/index.js +``` + +## Test + +``` +npm run compile +npm test +``` + +Sample output: + +``` +> stake-pool-js@0.0.1 test +> ./node_modules/mocha/bin/mocha -p ./dist + + + schema.decode + StakePoolAccount + ✓ should successfully decode StakePoolAccount account data + ValidatorListAccount + ✓ should successfully decode ValidatorListAccount account data + ✓ should successfully decode ValidatorListAccount with nonempty ValidatorInfo + + index.ts/PrettyPrintPubkey + ✓ should successfully pretty print a pubkey + + + 4 passing (610ms) + ``` \ No newline at end of file diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json new file mode 100644 index 00000000..49ac49c2 --- /dev/null +++ b/clients/js-legacy/package-lock.json @@ -0,0 +1,3694 @@ +{ + "name": "stake-pool-js", + "version": "0.0.1", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "stake-pool-js", + "version": "0.0.1", + "license": "ISC", + "dependencies": { + "@solana/web3.js": "^1.18.0", + "assert": "^2.0.0", + "borsh": "^0.4.0", + "buffer": "^6.0.1", + "process": "^0.11.10" + }, + "devDependencies": { + "@types/mocha": "^8.2.2", + "mocha": "^8.4.0", + "prettier": "^2.2.1", + "typescript": "^4.2.4" + } + }, + "../../../solana-repos/borsh-js": { + "name": "borsh", + "version": "0.3.1", + "extraneous": true, + "license": "Apache-2.0", + "dependencies": { + "@types/bn.js": "^4.11.5", + "bn.js": "^5.0.0", + "bs58": "^4.0.0", + "text-encoding-utf-8": "^1.0.2" + }, + "devDependencies": { + "@types/babel__core": "^7.1.2", + "@types/babel__template": "^7.0.2", + "@types/node": "^12.7.3", + "@typescript-eslint/eslint-plugin": "^2.18.0", + "@typescript-eslint/parser": "^2.18.0", + "bs58": "^4.0.0", + "eslint": "^6.5.1", + "jest": "^26.0.1", + "js-sha256": "^0.9.0", + "jsfuzz": "^1.0.14", + "typescript": "^3.6.2" + } + }, + "node_modules/@babel/runtime": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz", + "integrity": "sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==", + "dependencies": { + "regenerator-runtime": "^0.13.4" + } + }, + "node_modules/@solana/web3.js": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.18.0.tgz", + "integrity": "sha512-ijAoRd4Sje1QYoPAwDr7KYlDK40FE7tAUa2V3wT4PGKatWf4ETDXoyYlW89J6vrqOT+mV3GUuaVC76tOFlrXyA==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "bn.js": "^5.0.0", + "borsh": "^0.4.0", + "bs58": "^4.0.1", + "buffer": "6.0.1", + "buffer-layout": "^1.2.0", + "crypto-hash": "^1.2.2", + "jayson": "^3.4.4", + "js-sha3": "^0.8.0", + "node-fetch": "^2.6.1", + "rpc-websockets": "^7.4.2", + "secp256k1": "^4.0.2", + "superstruct": "^0.14.2", + "tweetnacl": "^1.0.0" + } + }, + "node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.34", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz", + "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.19.tgz", + "integrity": "sha512-DJOSHzX7pCiSElWaGR8kCprwibCB/3yW6vcT8VG3P0SJjnv19gnWG/AZMfM60Xj/YJIp/YCaDHyvzsFVeniARA==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "node_modules/@types/lodash": { + "version": "4.14.168", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.168.tgz", + "integrity": "sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q==" + }, + "node_modules/@types/mocha": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.2.tgz", + "integrity": "sha512-Lwh0lzzqT5Pqh6z61P3c3P5nm6fzQK/MMHl9UKeneAeInVflBSz1O2EkX6gM6xfJd7FBXBY5purtLx7fUiZ7Hw==", + "dev": true + }, + "node_modules/@types/node": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.1.tgz", + "integrity": "sha512-TMkXt0Ck1y0KKsGr9gJtWGjttxlZnnvDtphxUOSd0bfaR6Q1jle+sPvrzNR1urqYTWMinoKvjKfXUGsumaO1PA==" + }, + "node_modules/@types/qs": { + "version": "6.9.6", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.6.tgz", + "integrity": "sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==" + }, + "node_modules/@types/range-parser": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", + "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==" + }, + "node_modules/@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "node_modules/101": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/101/-/101-1.6.3.tgz", + "integrity": "sha512-4dmQ45yY0Dx24Qxp+zAsNLlMF6tteCyfVzgbulvSyC7tCyd3V8sW76sS0tHq8NpcbXfWTKasfyfzU1Kd86oKzw==", + "dependencies": { + "clone": "^1.0.2", + "deep-eql": "^0.1.3", + "keypather": "^1.10.2" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/array-filter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz", + "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=" + }, + "node_modules/assert": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", + "integrity": "sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==", + "dependencies": { + "es6-object-assign": "^1.1.0", + "is-nan": "^1.2.1", + "object-is": "^1.0.1", + "util": "^0.12.0" + } + }, + "node_modules/assert-args": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/assert-args/-/assert-args-1.2.1.tgz", + "integrity": "sha1-QEEDoUUqMv53iYgR5U5ZCoqTc70=", + "dependencies": { + "101": "^1.2.0", + "compound-subject": "0.0.1", + "debug": "^2.2.0", + "get-prototype-of": "0.0.0", + "is-capitalized": "^1.0.0", + "is-class": "0.0.4" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz", + "integrity": "sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ==", + "dependencies": { + "array-filter": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base-x": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", + "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" + }, + "node_modules/borsh": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/borsh/-/borsh-0.4.0.tgz", + "integrity": "sha512-aX6qtLya3K0AkT66CmYWCCDr77qsE9arV05OmdFpmat9qu8Pg9J5tBUPDztAW5fNh/d/MyVG/OYziP52Ndzx1g==", + "dependencies": { + "@types/bn.js": "^4.11.5", + "bn.js": "^5.0.0", + "bs58": "^4.0.0", + "text-encoding-utf-8": "^1.0.2" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/buffer": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.1.tgz", + "integrity": "sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-layout": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/buffer-layout/-/buffer-layout-1.2.1.tgz", + "integrity": "sha512-RUTGEYG1vX0Zp1dStQFl8yeU/LEBPXVtHwzzDbPWkE5zq+Prt9fkFLKNiwmaeHg6BBiRMcQAgj4cynazO6eekw==", + "engines": { + "node": ">=4.5" + } + }, + "node_modules/bufferutil": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.3.tgz", + "integrity": "sha512-yEYTwGndELGvfXsImMBLop58eaGW+YdONi1fNjTINSY98tmMmFijBG6WXgdkfuLNt4imzQNtIE+eBp1PVpMCSw==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "node-gyp-build": "^4.2.0" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chokidar": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.1" + } + }, + "node_modules/circular-json": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.9.tgz", + "integrity": "sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ==", + "deprecated": "CircularJSON is in maintenance only, flatted is its successor." + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/compound-subject": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/compound-subject/-/compound-subject-0.0.1.tgz", + "integrity": "sha1-JxVUaYoVrmCLHfyv0wt7oeqJLEs=" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/crypto-hash": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/crypto-hash/-/crypto-hash-1.3.0.tgz", + "integrity": "sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-eql": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", + "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", + "dependencies": { + "type-detect": "0.1.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/es-abstract": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz", + "integrity": "sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==", + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.2", + "is-string": "^1.0.5", + "object-inspect": "^1.9.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es6-object-assign": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", + "integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=" + }, + "node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, + "node_modules/es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "dependencies": { + "es6-promise": "^4.0.3" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "node_modules/eyes": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=", + "engines": { + "node": "> 0.1.90" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-prototype-of": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/get-prototype-of/-/get-prototype-of-0.0.0.tgz", + "integrity": "sha1-mHcr0QcW0W3rSzIlFsRp78oorEQ=" + }, + "node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true, + "engines": { + "node": ">=4.x" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/is-arguments": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", + "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", + "dependencies": { + "call-bind": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.1.tgz", + "integrity": "sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz", + "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==", + "dependencies": { + "call-bind": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-capitalized": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-capitalized/-/is-capitalized-1.0.0.tgz", + "integrity": "sha1-TIRktNkdPk7rRIid0s2PGwrEwTY=" + }, + "node_modules/is-class": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/is-class/-/is-class-0.0.4.tgz", + "integrity": "sha1-4FdFFwW7NOOePjNZjJOpg3KWtzY=" + }, + "node_modules/is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/is-generator-function": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.8.tgz", + "integrity": "sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-nan": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", + "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", + "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-regex": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", + "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", + "dependencies": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "dependencies": { + "has-symbols": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.5.tgz", + "integrity": "sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug==", + "dependencies": { + "available-typed-arrays": "^1.0.2", + "call-bind": "^1.0.2", + "es-abstract": "^1.18.0-next.2", + "foreach": "^2.0.5", + "has-symbols": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/jayson": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/jayson/-/jayson-3.6.2.tgz", + "integrity": "sha512-hbl+x2xH6FT7nckw+Pq3lKOIJaMBKOgNJEVfvloDBWB8iSfzn/1U2igj1A5rplqNMFN/OnnaTNw8qPKVmoq83Q==", + "dependencies": { + "@types/connect": "^3.4.33", + "@types/express-serve-static-core": "^4.17.9", + "@types/lodash": "^4.14.159", + "@types/node": "^12.12.54", + "commander": "^2.20.3", + "es6-promisify": "^5.0.0", + "eyes": "^0.1.8", + "json-stringify-safe": "^5.0.1", + "JSONStream": "^1.3.5", + "lodash": "^4.17.20", + "uuid": "^3.4.0" + }, + "bin": { + "jayson": "bin/jayson.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jayson/node_modules/@types/node": { + "version": "12.20.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.11.tgz", + "integrity": "sha512-gema+apZ6qLQK7k7F0dGkGCWQYsL0qqKORWOQO6tq46q+x+1C0vbOiOqOwRVlh4RAdbQwV/j/ryr3u5NOG1fPQ==" + }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + }, + "node_modules/js-yaml": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", + "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "engines": [ + "node >= 0.2.0" + ] + }, + "node_modules/JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/keypather": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/keypather/-/keypather-1.10.2.tgz", + "integrity": "sha1-4ESWMtSz5RbyHMAUznxWRP3c5hQ=", + "dependencies": { + "101": "^1.0.0" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/log-symbols": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mocha": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz", + "integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==", + "dev": true, + "dependencies": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.1", + "debug": "4.3.1", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.6", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.0.0", + "log-symbols": "4.0.0", + "minimatch": "3.0.4", + "ms": "2.1.3", + "nanoid": "3.1.20", + "serialize-javascript": "5.0.1", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "wide-align": "1.1.3", + "workerpool": "6.1.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 10.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/mocha/node_modules/debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mocha/node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/mocha/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/mocha/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/nanoid": { + "version": "3.1.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", + "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + }, + "node_modules/node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "engines": { + "node": "4.x || >=6.0.0" + } + }, + "node_modules/node-gyp-build": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", + "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.2.tgz", + "integrity": "sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prettier": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", + "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rpc-websockets": { + "version": "7.4.11", + "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.4.11.tgz", + "integrity": "sha512-/6yKCkRrEEb+TlJb6Q/pNBD4WdO/tFxE22rQYBl1YyIgz3SpzQDQ/0qAMWWksjFkDayiq3xVxmkP8e/tL422ZA==", + "dependencies": { + "@babel/runtime": "^7.11.2", + "assert-args": "^1.2.1", + "circular-json": "^0.5.9", + "eventemitter3": "^4.0.7", + "uuid": "^8.3.0", + "ws": "^7.3.1" + }, + "funding": { + "type": "paypal", + "url": "https://paypal.me/kozjak" + }, + "optionalDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + } + }, + "node_modules/rpc-websockets/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/secp256k1": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", + "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", + "hasInstallScript": true, + "dependencies": { + "elliptic": "^6.5.2", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/superstruct": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-0.14.2.tgz", + "integrity": "sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==" + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-encoding-utf-8": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz", + "integrity": "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==" + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + }, + "node_modules/type-detect": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", + "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=", + "engines": { + "node": "*" + } + }, + "node_modules/typescript": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", + "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dependencies": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/utf-8-validate": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.4.tgz", + "integrity": "sha512-MEF05cPSq3AwJ2C7B7sHAA6i53vONoZbMGX8My5auEVm6W+dJ2Jd/TZPyGJ5CH42V2XtbI5FD28HeHeqlPzZ3Q==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "node-gyp-build": "^4.2.0" + } + }, + "node_modules/util": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.3.tgz", + "integrity": "sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog==", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "safe-buffer": "^5.1.2", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz", + "integrity": "sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==", + "dependencies": { + "available-typed-arrays": "^1.0.2", + "call-bind": "^1.0.0", + "es-abstract": "^1.18.0-next.1", + "foreach": "^2.0.5", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.1", + "is-typed-array": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "dependencies": { + "string-width": "^1.0.2 || 2" + } + }, + "node_modules/workerpool": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", + "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/ws": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", + "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "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" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "101": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/101/-/101-1.6.3.tgz", + "integrity": "sha512-4dmQ45yY0Dx24Qxp+zAsNLlMF6tteCyfVzgbulvSyC7tCyd3V8sW76sS0tHq8NpcbXfWTKasfyfzU1Kd86oKzw==", + "requires": { + "clone": "^1.0.2", + "deep-eql": "^0.1.3", + "keypather": "^1.10.2" + } + }, + "@babel/runtime": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz", + "integrity": "sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@solana/web3.js": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.18.0.tgz", + "integrity": "sha512-ijAoRd4Sje1QYoPAwDr7KYlDK40FE7tAUa2V3wT4PGKatWf4ETDXoyYlW89J6vrqOT+mV3GUuaVC76tOFlrXyA==", + "requires": { + "@babel/runtime": "^7.12.5", + "bn.js": "^5.0.0", + "borsh": "^0.4.0", + "bs58": "^4.0.1", + "buffer": "6.0.1", + "buffer-layout": "^1.2.0", + "crypto-hash": "^1.2.2", + "jayson": "^3.4.4", + "js-sha3": "^0.8.0", + "node-fetch": "^2.6.1", + "rpc-websockets": "^7.4.2", + "secp256k1": "^4.0.2", + "superstruct": "^0.14.2", + "tweetnacl": "^1.0.0" + } + }, + "@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "requires": { + "@types/node": "*" + } + }, + "@types/connect": { + "version": "3.4.34", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz", + "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.19.tgz", + "integrity": "sha512-DJOSHzX7pCiSElWaGR8kCprwibCB/3yW6vcT8VG3P0SJjnv19gnWG/AZMfM60Xj/YJIp/YCaDHyvzsFVeniARA==", + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "@types/lodash": { + "version": "4.14.168", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.168.tgz", + "integrity": "sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q==" + }, + "@types/mocha": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.2.tgz", + "integrity": "sha512-Lwh0lzzqT5Pqh6z61P3c3P5nm6fzQK/MMHl9UKeneAeInVflBSz1O2EkX6gM6xfJd7FBXBY5purtLx7fUiZ7Hw==", + "dev": true + }, + "@types/node": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.1.tgz", + "integrity": "sha512-TMkXt0Ck1y0KKsGr9gJtWGjttxlZnnvDtphxUOSd0bfaR6Q1jle+sPvrzNR1urqYTWMinoKvjKfXUGsumaO1PA==" + }, + "@types/qs": { + "version": "6.9.6", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.6.tgz", + "integrity": "sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==" + }, + "@types/range-parser": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", + "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==" + }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "array-filter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz", + "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=" + }, + "assert": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", + "integrity": "sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==", + "requires": { + "es6-object-assign": "^1.1.0", + "is-nan": "^1.2.1", + "object-is": "^1.0.1", + "util": "^0.12.0" + } + }, + "assert-args": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/assert-args/-/assert-args-1.2.1.tgz", + "integrity": "sha1-QEEDoUUqMv53iYgR5U5ZCoqTc70=", + "requires": { + "101": "^1.2.0", + "compound-subject": "0.0.1", + "debug": "^2.2.0", + "get-prototype-of": "0.0.0", + "is-capitalized": "^1.0.0", + "is-class": "0.0.4" + } + }, + "available-typed-arrays": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz", + "integrity": "sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ==", + "requires": { + "array-filter": "^1.0.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "base-x": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", + "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" + }, + "borsh": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/borsh/-/borsh-0.4.0.tgz", + "integrity": "sha512-aX6qtLya3K0AkT66CmYWCCDr77qsE9arV05OmdFpmat9qu8Pg9J5tBUPDztAW5fNh/d/MyVG/OYziP52Ndzx1g==", + "requires": { + "@types/bn.js": "^4.11.5", + "bn.js": "^5.0.0", + "bs58": "^4.0.0", + "text-encoding-utf-8": "^1.0.2" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", + "requires": { + "base-x": "^3.0.2" + } + }, + "buffer": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.1.tgz", + "integrity": "sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "buffer-layout": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/buffer-layout/-/buffer-layout-1.2.1.tgz", + "integrity": "sha512-RUTGEYG1vX0Zp1dStQFl8yeU/LEBPXVtHwzzDbPWkE5zq+Prt9fkFLKNiwmaeHg6BBiRMcQAgj4cynazO6eekw==" + }, + "bufferutil": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.3.tgz", + "integrity": "sha512-yEYTwGndELGvfXsImMBLop58eaGW+YdONi1fNjTINSY98tmMmFijBG6WXgdkfuLNt4imzQNtIE+eBp1PVpMCSw==", + "optional": true, + "requires": { + "node-gyp-build": "^4.2.0" + } + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "chokidar": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.3.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, + "circular-json": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.9.tgz", + "integrity": "sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ==" + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=" + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "compound-subject": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/compound-subject/-/compound-subject-0.0.1.tgz", + "integrity": "sha1-JxVUaYoVrmCLHfyv0wt7oeqJLEs=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "crypto-hash": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/crypto-hash/-/crypto-hash-1.3.0.tgz", + "integrity": "sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg==" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + }, + "deep-eql": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", + "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", + "requires": { + "type-detect": "0.1.1" + } + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + } + }, + "diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true + }, + "elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + } + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "es-abstract": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz", + "integrity": "sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==", + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.2", + "is-string": "^1.0.5", + "object-inspect": "^1.9.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.0" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es6-object-assign": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", + "integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=" + }, + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "requires": { + "es6-promise": "^4.0.3" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "eyes": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=" + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "get-prototype-of": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/get-prototype-of/-/get-prototype-of-0.0.0.tgz", + "integrity": "sha1-mHcr0QcW0W3rSzIlFsRp78oorEQ=" + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "is-arguments": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", + "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", + "requires": { + "call-bind": "^1.0.0" + } + }, + "is-bigint": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.1.tgz", + "integrity": "sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg==" + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-boolean-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz", + "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==", + "requires": { + "call-bind": "^1.0.0" + } + }, + "is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==" + }, + "is-capitalized": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-capitalized/-/is-capitalized-1.0.0.tgz", + "integrity": "sha1-TIRktNkdPk7rRIid0s2PGwrEwTY=" + }, + "is-class": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/is-class/-/is-class-0.0.4.tgz", + "integrity": "sha1-4FdFFwW7NOOePjNZjJOpg3KWtzY=" + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-generator-function": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.8.tgz", + "integrity": "sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ==" + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-nan": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", + "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } + }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==" + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-number-object": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", + "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==" + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + }, + "is-regex": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", + "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.1" + } + }, + "is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==" + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-typed-array": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.5.tgz", + "integrity": "sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug==", + "requires": { + "available-typed-arrays": "^1.0.2", + "call-bind": "^1.0.2", + "es-abstract": "^1.18.0-next.2", + "foreach": "^2.0.5", + "has-symbols": "^1.0.1" + } + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "jayson": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/jayson/-/jayson-3.6.2.tgz", + "integrity": "sha512-hbl+x2xH6FT7nckw+Pq3lKOIJaMBKOgNJEVfvloDBWB8iSfzn/1U2igj1A5rplqNMFN/OnnaTNw8qPKVmoq83Q==", + "requires": { + "@types/connect": "^3.4.33", + "@types/express-serve-static-core": "^4.17.9", + "@types/lodash": "^4.14.159", + "@types/node": "^12.12.54", + "commander": "^2.20.3", + "es6-promisify": "^5.0.0", + "eyes": "^0.1.8", + "json-stringify-safe": "^5.0.1", + "JSONStream": "^1.3.5", + "lodash": "^4.17.20", + "uuid": "^3.4.0" + }, + "dependencies": { + "@types/node": { + "version": "12.20.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.11.tgz", + "integrity": "sha512-gema+apZ6qLQK7k7F0dGkGCWQYsL0qqKORWOQO6tq46q+x+1C0vbOiOqOwRVlh4RAdbQwV/j/ryr3u5NOG1fPQ==" + } + } + }, + "js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + }, + "js-yaml": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", + "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=" + }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "keypather": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/keypather/-/keypather-1.10.2.tgz", + "integrity": "sha1-4ESWMtSz5RbyHMAUznxWRP3c5hQ=", + "requires": { + "101": "^1.0.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "log-symbols": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "dev": true, + "requires": { + "chalk": "^4.0.0" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "mocha": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz", + "integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==", + "dev": true, + "requires": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.1", + "debug": "4.3.1", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.6", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.0.0", + "log-symbols": "4.0.0", + "minimatch": "3.0.4", + "ms": "2.1.3", + "nanoid": "3.1.20", + "serialize-javascript": "5.0.1", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "wide-align": "1.1.3", + "workerpool": "6.1.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "nanoid": { + "version": "3.1.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", + "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", + "dev": true + }, + "node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + }, + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + }, + "node-gyp-build": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", + "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==" + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "object-inspect": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.2.tgz", + "integrity": "sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA==" + }, + "object-is": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + }, + "prettier": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", + "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", + "dev": true + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "rpc-websockets": { + "version": "7.4.11", + "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.4.11.tgz", + "integrity": "sha512-/6yKCkRrEEb+TlJb6Q/pNBD4WdO/tFxE22rQYBl1YyIgz3SpzQDQ/0qAMWWksjFkDayiq3xVxmkP8e/tL422ZA==", + "requires": { + "@babel/runtime": "^7.11.2", + "assert-args": "^1.2.1", + "bufferutil": "^4.0.1", + "circular-json": "^0.5.9", + "eventemitter3": "^4.0.7", + "utf-8-validate": "^5.0.2", + "uuid": "^8.3.0", + "ws": "^7.3.1" + }, + "dependencies": { + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + } + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "secp256k1": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", + "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", + "requires": { + "elliptic": "^6.5.2", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + } + }, + "serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "superstruct": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-0.14.2.tgz", + "integrity": "sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "text-encoding-utf-8": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz", + "integrity": "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==" + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + }, + "type-detect": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", + "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=" + }, + "typescript": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", + "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==", + "dev": true + }, + "unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "requires": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + } + }, + "utf-8-validate": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.4.tgz", + "integrity": "sha512-MEF05cPSq3AwJ2C7B7sHAA6i53vONoZbMGX8My5auEVm6W+dJ2Jd/TZPyGJ5CH42V2XtbI5FD28HeHeqlPzZ3Q==", + "optional": true, + "requires": { + "node-gyp-build": "^4.2.0" + } + }, + "util": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.3.tgz", + "integrity": "sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog==", + "requires": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "safe-buffer": "^5.1.2", + "which-typed-array": "^1.1.2" + } + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "which-typed-array": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz", + "integrity": "sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==", + "requires": { + "available-typed-arrays": "^1.0.2", + "call-bind": "^1.0.0", + "es-abstract": "^1.18.0-next.1", + "foreach": "^2.0.5", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.1", + "is-typed-array": "^1.1.3" + } + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "workerpool": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", + "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "ws": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", + "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==", + "requires": {} + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true + }, + "yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + } + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + } + } +} diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json new file mode 100644 index 00000000..227e0e5f --- /dev/null +++ b/clients/js-legacy/package.json @@ -0,0 +1,27 @@ +{ + "name": "@solana/spl-stake-pool", + "version": "0.1.0", + "description": "SPL Stake Pool Program JS API", + "scripts": { + "lint": "npx prettier src/*.ts -w", + "build": "tsc", + "test": "./node_modules/mocha/bin/mocha -p ./dist" + }, + "keywords": [], + "author": "Lieu Zheng Hong", + "license": "ISC", + "devDependencies": { + "@types/mocha": "^8.2.2", + "mocha": "^8.4.0", + "prettier": "^2.2.1", + "typescript": "^4.2.4" + }, + "dependencies": { + "@solana/web3.js": "^1.18.0", + "assert": "^2.0.0", + "borsh": "^0.4.0", + "buffer": "^6.0.1", + "process": "^0.11.10" + }, + "type": "module" +} diff --git a/clients/js-legacy/src/index.ts b/clients/js-legacy/src/index.ts new file mode 100644 index 00000000..1a03605e --- /dev/null +++ b/clients/js-legacy/src/index.ts @@ -0,0 +1,156 @@ +import * as schema from './schema.js'; +import solanaWeb3 from '@solana/web3.js'; +import assert from 'assert'; + +export class StakePoolAccounts { + /** + * Wrapper class for a stake pool. + * Each stake pool has a stake pool account and a validator list account. + */ + stakePool: StakePoolAccount; + validatorList: ValidatorListAccount; +} + +export interface StakePoolAccount { + pubkey: solanaWeb3.PublicKey; + account: solanaWeb3.AccountInfo; +} + +export interface ValidatorListAccount { + pubkey: solanaWeb3.PublicKey; + account: solanaWeb3.AccountInfo; +} + +/** + * Retrieves and deserializes a StakePool account using a web3js connection and the stake pool address. + * @param connection: An active web3js connection. + * @param stakePoolPubKey: The public key (address) of the stake pool account. + */ +export async function getStakePoolAccount( + connection: solanaWeb3.Connection, + stakePoolPubKey: solanaWeb3.PublicKey, +): Promise { + const account = await connection.getAccountInfo(stakePoolPubKey); + + return { + pubkey: stakePoolPubKey, + account: { + data: schema.StakePool.decode(account.data), + executable: account.executable, + lamports: account.lamports, + owner: account.owner, + }, + }; +} + +/** + * Retrieves and deserializes a ValidatorList account using a web3js connection and the validator list address. + * @param connection: An active web3js connection. + * @param validatorListPubKey: The public key (address) of the validator list account. + */ +export async function getValidatorListAccount( + connection: solanaWeb3.Connection, + validatorListPubKey: solanaWeb3.PublicKey, +): Promise { + try { + const account = await connection.getAccountInfo(validatorListPubKey); + + return { + pubkey: validatorListPubKey, + account: { + data: schema.ValidatorList.decodeUnchecked(account.data), + executable: account.executable, + lamports: account.lamports, + owner: account.owner, + }, + }; + } catch (error) { + console.log(error); + } +} + +/** + * Retrieves all StakePool and ValidatorList accounts that are running a particular StakePool program. + * @param connection: An active web3js connection. + * @param stakePoolProgramAddress: The public key (address) of the StakePool program. + */ +export async function getStakePoolAccounts( + connection: solanaWeb3.Connection, + stakePoolProgramAddress: solanaWeb3.PublicKey, +): Promise<(StakePoolAccount | ValidatorListAccount)[]> { + try { + let response = await connection.getProgramAccounts(stakePoolProgramAddress); + + const stakePoolAccounts = response.map(a => { + let decodedData; + + if (a.account.data.readUInt8() === 1) { + try { + decodedData = schema.StakePool.decode(a.account.data); + } catch (error) { + console.log('Could not decode StakeAccount. Error:', error); + decodedData = undefined; + } + } else if (a.account.data.readUInt8() === 2) { + try { + decodedData = schema.ValidatorList.decodeUnchecked(a.account.data); + } catch (error) { + console.log('Could not decode ValidatorList. Error:', error); + decodedData = undefined; + } + } else { + console.error( + `Could not decode. StakePoolAccount Enum is ${a.account.data.readUInt8()}, expected 1 or 2!`, + ); + decodedData = undefined; + } + + return { + pubkey: a.pubkey, + account: { + data: decodedData, + executable: a.account.executable, + lamports: a.account.lamports, + owner: a.account.owner, + }, + }; + }); + + return stakePoolAccounts; + } catch (error) { + console.log(error); + } +} + +/** + * Helper function to pretty print a schema.PublicKey + * Pretty prints a PublicKey in base58 format */ +export function prettyPrintPubKey(pubKey: solanaWeb3.PublicKey): string { + return new solanaWeb3.PublicKey( + new solanaWeb3.PublicKey(pubKey.toBuffer()).toBytes().reverse(), + ).toString(); +} + +/** + * Helper function to pretty print a decoded account + */ +export function prettyPrintAccount( + account: ValidatorListAccount | StakePoolAccount, +): void { + console.log('Address:', account.pubkey.toString()); + const sp = account.account.data; + if (typeof sp === 'undefined') { + console.log('Account could not be decoded'); + } + + for (const val in sp) { + if (sp[val] instanceof solanaWeb3.PublicKey) { + console.log(val, prettyPrintPubKey(sp[val])); + } else { + console.log(val, sp[val]); + } + } + console.log('Executable?:', account.account.executable); + console.log('Lamports:', account.account.lamports); + console.log('Owner PubKey:', account.account.owner.toString()); +} diff --git a/clients/js-legacy/src/integration_test.ts b/clients/js-legacy/src/integration_test.ts new file mode 100644 index 00000000..4102b3cb --- /dev/null +++ b/clients/js-legacy/src/integration_test.ts @@ -0,0 +1,65 @@ +import * as index from './index.js'; +import * as schema from './schema.js'; +import BN from 'bn.js'; +import assert, {deepStrictEqual} from 'assert'; +import {SOLANA_SCHEMA, PublicKey, Connection} from '@solana/web3.js'; + +// First populate schema +schema.addStakePoolSchema(SOLANA_SCHEMA); + +describe('Integration test', () => { + it('should successfully decode all validators from devnet', async () => { + /** + * Full integration test: + * Makes a connection to devnet, gets all stake pool accounts there, + * decodes them, and prints their details. + */ + const connection = new Connection( + 'https://api.devnet.solana.com/', + 'confirmed', + ); + const STAKE_POOL_PROGRAM_ADDR = new PublicKey( + 'poo1B9L9nR3CrcaziKVYVpRX6A9Y1LAXYasjjfCbApj', + ); + + const accounts = await index.getStakePoolAccounts( + connection, + STAKE_POOL_PROGRAM_ADDR, + ); + + console.log('Number of stake pool accounts in devnet: ', accounts.length); + + accounts.map(account => { + index.prettyPrintAccount(account); + console.log('\n'); + }); + }); + + it('should successfully decode all validators from testnet', async () => { + /** + * Full integration test: + * Makes a connection to testnet, gets all stake pool accounts there, + * decodes them, and prints their details. + * Testnet presents a greater challenge due to the presence of old stake pool program accounts + */ + const connection = new Connection( + 'https://api.testnet.solana.com/', + 'confirmed', + ); + const STAKE_POOL_PROGRAM_ADDR = new PublicKey( + 'poo1B9L9nR3CrcaziKVYVpRX6A9Y1LAXYasjjfCbApj', + ); + + const accounts = await index.getStakePoolAccounts( + connection, + STAKE_POOL_PROGRAM_ADDR, + ); + + console.log('Number of stake pool accounts in testnet: ', accounts.length); + + accounts.map(account => { + index.prettyPrintAccount(account); + console.log('\n'); + }); + }); +}); diff --git a/clients/js-legacy/src/schema.ts b/clients/js-legacy/src/schema.ts new file mode 100644 index 00000000..f4a4954c --- /dev/null +++ b/clients/js-legacy/src/schema.ts @@ -0,0 +1,139 @@ +import {Schema, serialize, deserializeUnchecked} from 'borsh'; +import BN from 'bn.js'; +import {Struct, Enum, PublicKey} from '@solana/web3.js'; + +export class Fee extends Struct { + denominator: BN; + numerator: BN; +} + +export class AccountType extends Enum {} + +export class AccountTypeEnum extends Struct {} + +export enum AccountTypeKind { + Uninitialized = 'Uninitialized', + StakePool = 'StakePool', + ValidatorList = 'ValidatorList', +} + +export class StakePool extends Struct { + accountType: AccountType; + manager: PublicKey; + staker: PublicKey; + depositAuthority: PublicKey; + withdrawBumpSeed: number; + validatorList: PublicKey; + reserveStake: PublicKey; + poolMint: PublicKey; + managerFeeAccount: PublicKey; + totalStakeLamports: BN; + poolTokenSupply: BN; + lastUpdateEpoch: BN; + fee: Fee; +} + +export class ValidatorList extends Struct { + accountType: AccountType; + maxValidators: number; + validators: [ValidatorStakeInfo]; +} +export class ValidatorStakeInfo extends Struct { + status: StakeStatus; + voteAccountAddress: PublicKey; + stakeLamports: BN; + lastUpdateEpoch: BN; +} +export class StakeStatus extends Enum {} + +export class StakeStatusEnum extends Struct {} + +export enum StakeStatusKind { + Active = 'Active', + DeactivatingTransient = 'DeactivatingTransient', + ReadyForRemoval = 'ReadyForRemoval', +} + +export function addStakePoolSchema(schema: Schema): void { + /** + * Borsh requires something called a Schema, + * which is a Map (key-value pairs) that tell borsh how to deserialise the raw data + * This function adds a new schema to an existing schema object. + */ + schema.set(PublicKey, { + kind: 'struct', + fields: [['_bn', 'u256']], + }); + + schema.set(Fee, { + kind: 'struct', + fields: [ + ['denominator', 'u64'], + ['numerator', 'u64'], + ], + }); + + schema.set(AccountType, { + kind: 'enum', + field: 'enum', + values: [ + // if the account has not been initialized, the enum will be 0 + [AccountTypeKind.Uninitialized, AccountTypeEnum], + [AccountTypeKind.StakePool, AccountTypeEnum], + [AccountTypeKind.ValidatorList, AccountTypeEnum], + ], + }); + + schema.set(AccountTypeEnum, {kind: 'struct', fields: []}); + + schema.set(StakePool, { + kind: 'struct', + fields: [ + ['accountType', AccountType], + ['manager', PublicKey], + ['staker', PublicKey], + ['depositAuthority', PublicKey], + ['withdrawBumpSeed', 'u8'], + ['validatorList', PublicKey], + ['reserveStake', PublicKey], + ['poolMint', PublicKey], + ['managerFeeAccount', PublicKey], + ['tokenProgramId', PublicKey], + ['totalStakeLamports', 'u64'], + ['poolTokenSupply', 'u64'], + ['lastUpdateEpoch', 'u64'], + ['fee', Fee], + ], + }); + + schema.set(ValidatorList, { + kind: 'struct', + fields: [ + ['accountType', AccountType], + ['maxValidators', 'u32'], + ['validators', [ValidatorStakeInfo]], + ], + }); + + schema.set(StakeStatus, { + kind: 'enum', + field: 'enum', + values: [ + [StakeStatusKind.Active, StakeStatusEnum], + [StakeStatusKind.DeactivatingTransient, StakeStatusEnum], + [StakeStatusKind.ReadyForRemoval, StakeStatusEnum], + ], + }); + + schema.set(StakeStatusEnum, {kind: 'struct', fields: []}); + + schema.set(ValidatorStakeInfo, { + kind: 'struct', + fields: [ + ['status', StakeStatus], + ['voteAccountAddress', PublicKey], + ['stakeLamports', 'u64'], + ['lastUpdateEpoch', 'u64'], + ], + }); +} diff --git a/clients/js-legacy/src/test.ts b/clients/js-legacy/src/test.ts new file mode 100644 index 00000000..293b9f8a --- /dev/null +++ b/clients/js-legacy/src/test.ts @@ -0,0 +1,215 @@ +import * as index from './index.js'; +import * as schema from './schema.js'; +import BN from 'bn.js'; +import assert, {deepStrictEqual} from 'assert'; +import {SOLANA_SCHEMA, PublicKey, Connection} from '@solana/web3.js'; + +// First populate schema +schema.addStakePoolSchema(SOLANA_SCHEMA); + +function deepStrictEqualBN(decodedData: object, expectedData: object) { + /** + * Helper function to do deep equality check because BNs are not equal. + * TODO: write this function recursively. For now, sufficient. + */ + for (const key in decodedData) { + if (expectedData[key] instanceof BN) { + assert.ok(expectedData[key].eq(decodedData[key])); + } else { + if (decodedData[key] instanceof Object) { + for (const subkey in decodedData[key]) { + if (decodedData[key][subkey] instanceof Object) { + if (decodedData[key][subkey] instanceof BN) { + assert.ok(decodedData[key][subkey].eq(expectedData[key][subkey])); + } else { + for (const subsubkey in decodedData[key][subkey]) { + console.log(decodedData[key][subkey][subsubkey]); + if (decodedData[key][subkey][subsubkey] instanceof BN) { + assert.ok( + decodedData[key][subkey][subsubkey].eq( + expectedData[key][subkey][subsubkey], + ), + ); + } else { + assert.deepStrictEqual( + expectedData[key][subkey][subsubkey], + decodedData[key][subkey][subsubkey], + ); + } + } + } + } else { + assert.strictEqual( + decodedData[key][subkey], + expectedData[key][subkey], + ); + } + } + } else { + assert.strictEqual(decodedData[key], expectedData[key]); + } + } + } +} + +describe('schema.decode', () => { + describe('StakePoolAccount', () => { + it('should successfully decode StakePoolAccount account data', () => { + const expectedData = new schema.StakePool({ + accountType: new schema.AccountType({ + StakePool: new schema.AccountTypeEnum({}), + }), + manager: new PublicKey( + new BN( + 'dc23cda2ad09ddec126f89ed7f67d06a4d167cca996503f1a1b3b5a13625964f', + 'hex', + ), + ), + staker: new PublicKey( + new BN( + 'dc23cda2ad09ddec126f89ed7f67d06a4d167cca996503f1a1b3b5a13625964f', + 'hex', + ), + ), + depositAuthority: new PublicKey( + new BN( + new Buffer( + '5911e7451a1a854fdc9e495081790f293eba623f8ec7e2b9d34a5fd25c7009bb', + 'hex', + ), + ), + ), + withdrawBumpSeed: 255, + validatorList: new PublicKey( + new BN( + '7103ba4895b8804263197364da9e791db96ec8f0c8ca184dd666e69013838610', + 'hex', + ), + ), + reserveStake: new PublicKey( + new BN( + '74a5b1ab8442103baa8bd39ab8494eb034e96035ac664e1693bb3eef458761ee', + 'hex', + ), + ), + poolMint: new PublicKey( + new BN( + '8722bf107b95d2620008d256b18c13fa3a46ab7f643c24cf7656f57267563e00', + 'hex', + ), + ), + managerFeeAccount: new PublicKey( + new BN( + new Buffer( + 'b783b4dcd341cbca22e781bbd49b2d16908a844a21b98e26b69d44fc50e1db0f', + 'hex', + ), + ), + ), + tokenProgramId: new PublicKey( + new BN( + 'a900ff7e85f58c3a91375b5fed85b41cac79ebce46e1cbd993a165d7e1f6dd06', + 'hex', + ), + ), + totalStakeLamports: new BN('0', 'hex'), + poolTokenSupply: new BN('0', 'hex'), + lastUpdateEpoch: new BN('7c', 'hex'), + fee: new schema.Fee({ + denominator: new BN('3e8', 'hex'), + numerator: new BN('38', 'hex'), + }), + }); + + const decodedData = schema.StakePool.decode(expectedData.encode()); + + deepStrictEqualBN(decodedData, expectedData); + }); + }); + + describe('ValidatorListAccount', () => { + it('should successfully decode ValidatorListAccount account data', () => { + const expectedData = new schema.ValidatorList({ + accountType: new schema.AccountType({ + ValidatorList: new schema.AccountTypeEnum({}), + }), + maxValidators: 10, + validators: [], + }); + + const decodedData = schema.ValidatorList.decode(expectedData.encode()); + assert.deepStrictEqual(decodedData, expectedData); + }); + + it('should successfully decode ValidatorListAccount with nonempty ValidatorInfo', () => { + // TODO also test for decoding ValidatorListAccount with actual ValidatorInfo + // Do this once we have a stake pool with validators deployed on testnet + + const expectedData = new schema.ValidatorList({ + accountType: new schema.AccountType({ + ValidatorList: new schema.AccountTypeEnum({}), + }), + maxValidators: 100, + validators: [ + new schema.ValidatorStakeInfo({ + status: new schema.StakeStatus({ + Active: new schema.StakeStatusEnum({}), + }), + voteAccountAddress: new PublicKey( + new BN( + 'a9946a889af14fd3c9b33d5df309489d9699271a6b09ff3190fcb41cf21a2f8c', + 'hex', + ), + ), + stakeLamports: new BN('0', 'hex'), + lastUpdateEpoch: new BN('c3', 'hex'), + }), + new schema.ValidatorStakeInfo({ + status: new schema.StakeStatus({ + Active: new schema.StakeStatusEnum({}), + }), + voteAccountAddress: new PublicKey( + new BN( + '3796d40645ee07e3c64117e3f73430471d4c40465f696ebc9b034c1fc06a9f7d', + 'hex', + ), + ), + stakeLamports: new BN('0', 'hex'), + lastUpdateEpoch: new BN('c3', 'hex'), + }), + new schema.ValidatorStakeInfo({ + status: new schema.StakeStatus({ + Active: new schema.StakeStatusEnum({}), + }), + voteAccountAddress: new PublicKey( + new BN( + 'e4e37d6f2e80c0bb0f3da8a06304e57be5cda6efa2825b86780aa320d9784cf8', + 'hex', + ), + ), + stakeLamports: new BN('0', 'hex'), + lastUpdateEpoch: new BN('c3', 'hex'), + }), + ], + }); + + const decodedData = schema.ValidatorList.decode(expectedData.encode()); + deepStrictEqualBN(decodedData, expectedData); + }); + }); +}); + +describe('index.ts/PrettyPrintPubkey', () => { + it('should successfully pretty print a pubkey', () => { + assert.equal( + index.prettyPrintPubKey( + new PublicKey( + new BN( + '99572085579321386496717000324290408927851378839748241098946587626478579848783', + ), + ), + ), + '6MfzrQUzB2mozveRWU9a77zMoQzSrYa4Gq46KswjupQB', + ); + }); +}); diff --git a/clients/js-legacy/tsconfig.json b/clients/js-legacy/tsconfig.json new file mode 100644 index 00000000..39f1d962 --- /dev/null +++ b/clients/js-legacy/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "ES6", + "module": "ES6", + "esModuleInterop": true, + "moduleResolution": "Node", + "outDir": "dist", + "declaration": true, + "declarationMap": true, + }, + "include": [ + "src/**/*.ts" + ] +} \ No newline at end of file From 6c2f06ab2948056894819814541becd57a75c141 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 24 Jun 2021 20:30:59 +0200 Subject: [PATCH 0116/1076] stake-pool: Use `delegation.stake` for accounting (#1934) * stake-pool: Use `delegation.stake` for accounting * Clippy * Improve test and remove spl-math dependency * Address smaller review comments * Fix calculation, improve tests * Clippy * Remove esm from mocha * Revert "Remove esm from mocha" This reverts commit c0f25ab543c808a1daf3474df4ef851bc994fc6c. --- clients/cli/src/main.rs | 2 + program/Cargo.toml | 1 - program/src/instruction.rs | 9 +- program/src/processor.rs | 139 +++++++--- program/src/stake_program.rs | 23 ++ program/src/state.rs | 8 - program/tests/deposit.rs | 253 ++++++++++-------- program/tests/helpers/mod.rs | 2 + program/tests/initialize.rs | 2 +- program/tests/update_stake_pool_balance.rs | 100 ++++++- .../tests/update_validator_list_balance.rs | 44 ++- 11 files changed, 390 insertions(+), 193 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index b94e39ba..102b5f3b 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -597,6 +597,7 @@ fn command_deposit( &stake, &config.staker.pubkey(), &validator_stake_account, + &stake_pool.reserve_stake, &token_receiver, &stake_pool.pool_mint, &spl_token::id(), @@ -610,6 +611,7 @@ fn command_deposit( &stake, &config.staker.pubkey(), &validator_stake_account, + &stake_pool.reserve_stake, &token_receiver, &stake_pool.pool_mint, &spl_token::id(), diff --git a/program/Cargo.toml b/program/Cargo.toml index 7b0b98a3..f701ee71 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -20,7 +20,6 @@ num_enum = "0.5.1" serde = "1.0.121" serde_derive = "1.0.103" solana-program = "1.6.11" -spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-token = { version = "3.1", path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" bincode = "1.3.1" diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 19303590..57cfe658 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -236,9 +236,10 @@ pub enum StakePoolInstruction { /// 3. `[]` Stake pool withdraw authority /// 4. `[w]` Stake account to join the pool (withdraw authority for the stake account should be first set to the stake pool deposit authority) /// 5. `[w]` Validator stake account for the stake account to be merged with - /// 6. `[w]` User account to receive pool tokens + /// 6. `[w]` Reserve stake account, to withdraw rent exempt reserve + /// 7. `[w]` User account to receive pool tokens /// 8. `[w]` Pool token mint account - /// 9. '[]' Sysvar clock account (required) + /// 9. '[]' Sysvar clock account /// 10. '[]' Sysvar stake history account /// 11. `[]` Pool token program id, /// 12. `[]` Stake program id, @@ -781,6 +782,7 @@ pub fn deposit( deposit_stake_address: &Pubkey, deposit_stake_withdraw_authority: &Pubkey, validator_stake_account: &Pubkey, + reserve_stake_account: &Pubkey, pool_tokens_to: &Pubkey, pool_mint: &Pubkey, token_program_id: &Pubkey, @@ -794,6 +796,7 @@ pub fn deposit( AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), AccountMeta::new(*deposit_stake_address, false), AccountMeta::new(*validator_stake_account, false), + AccountMeta::new(*reserve_stake_account, false), AccountMeta::new(*pool_tokens_to, false), AccountMeta::new(*pool_mint, false), AccountMeta::new_readonly(sysvar::clock::id(), false), @@ -834,6 +837,7 @@ pub fn deposit_with_authority( deposit_stake_address: &Pubkey, deposit_stake_withdraw_authority: &Pubkey, validator_stake_account: &Pubkey, + reserve_stake_account: &Pubkey, pool_tokens_to: &Pubkey, pool_mint: &Pubkey, token_program_id: &Pubkey, @@ -845,6 +849,7 @@ pub fn deposit_with_authority( AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), AccountMeta::new(*deposit_stake_address, false), AccountMeta::new(*validator_stake_account, false), + AccountMeta::new(*reserve_stake_account, false), AccountMeta::new(*pool_tokens_to, false), AccountMeta::new(*pool_mint, false), AccountMeta::new_readonly(sysvar::clock::id(), false), diff --git a/program/src/processor.rs b/program/src/processor.rs index 685b2b1f..f23d0e1c 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -357,6 +357,47 @@ impl Processor { ) } + /// Issue stake_program::withdraw instruction to move additional lamports + #[allow(clippy::too_many_arguments)] + fn stake_withdraw<'a>( + stake_pool: &Pubkey, + source_account: AccountInfo<'a>, + authority: AccountInfo<'a>, + authority_type: &[u8], + bump_seed: u8, + destination_account: AccountInfo<'a>, + clock: AccountInfo<'a>, + stake_history: AccountInfo<'a>, + stake_program_info: AccountInfo<'a>, + lamports: u64, + ) -> Result<(), ProgramError> { + let me_bytes = stake_pool.to_bytes(); + let authority_signature_seeds = [&me_bytes[..32], authority_type, &[bump_seed]]; + let signers = &[&authority_signature_seeds[..]]; + let custodian_pubkey = None; + + let withdraw_instruction = stake_program::withdraw( + source_account.key, + authority.key, + destination_account.key, + lamports, + custodian_pubkey, + ); + + invoke_signed( + &withdraw_instruction, + &[ + source_account, + destination_account, + clock, + stake_history, + authority, + stake_program_info, + ], + signers, + ) + } + /// Issue a spl_token `Burn` instruction. #[allow(clippy::too_many_arguments)] fn token_burn<'a>( @@ -1337,9 +1378,13 @@ impl Processor { } } } - Some(stake_program::StakeState::Stake(_, stake)) => { + Some(stake_program::StakeState::Stake(meta, stake)) => { + let account_stake = meta + .rent_exempt_reserve + .checked_add(stake.delegation.stake) + .ok_or(StakePoolError::CalculationFailure)?; if no_merge { - transient_stake_lamports = transient_stake_info.lamports(); + transient_stake_lamports = account_stake; } else if stake.delegation.deactivation_epoch < clock.epoch { // deactivated, merge into reserve Self::stake_merge( @@ -1378,15 +1423,15 @@ impl Processor { )?; } else { msg!("Stake activating or just active, not ready to merge"); - transient_stake_lamports = transient_stake_info.lamports(); + transient_stake_lamports = account_stake; } } else { msg!("Transient stake is activating or active, but validator stake is not, need to add the validator stake account on {} back into the stake pool", stake.delegation.voter_pubkey); - transient_stake_lamports = transient_stake_info.lamports(); + transient_stake_lamports = account_stake; } } else { msg!("Transient stake not ready to be merged anywhere"); - transient_stake_lamports = transient_stake_info.lamports(); + transient_stake_lamports = account_stake; } } None @@ -1398,11 +1443,13 @@ impl Processor { // * active -> do everything // * any other state / not a stake -> error state, but account for transient stake match validator_stake_state { - Some(stake_program::StakeState::Stake(meta, _)) => { + Some(stake_program::StakeState::Stake(_, stake)) => { if validator_stake_record.status == StakeStatus::Active { - active_stake_lamports = validator_stake_info - .lamports() - .saturating_sub(minimum_stake_lamports(&meta)); + active_stake_lamports = stake + .delegation + .stake + .checked_sub(MINIMUM_ACTIVE_STAKE) + .ok_or(StakePoolError::CalculationFailure)?; } else { msg!("Validator stake account no longer part of the pool, ignoring"); } @@ -1566,6 +1613,7 @@ impl Processor { let withdraw_authority_info = next_account_info(account_info_iter)?; let stake_info = next_account_info(account_info_iter)?; let validator_stake_account_info = next_account_info(account_info_iter)?; + let reserve_stake_account_info = next_account_info(account_info_iter)?; let dest_user_info = next_account_info(account_info_iter)?; let pool_mint_info = next_account_info(account_info_iter)?; let clock_info = next_account_info(account_info_iter)?; @@ -1594,6 +1642,7 @@ impl Processor { stake_pool.check_deposit_authority(deposit_authority_info.key)?; stake_pool.check_mint(pool_mint_info)?; stake_pool.check_validator_list(validator_list_info)?; + stake_pool.check_reserve_stake(reserve_stake_account_info)?; if stake_pool.token_program_id != *token_program_info.key { return Err(ProgramError::IncorrectProgramId); @@ -1610,8 +1659,9 @@ impl Processor { return Err(StakePoolError::InvalidState.into()); } - let (meta, stake) = get_stake_state(validator_stake_account_info)?; - let vote_account_address = stake.delegation.voter_pubkey; + let (_, validator_stake) = get_stake_state(validator_stake_account_info)?; + let pre_all_validator_lamports = validator_stake_account_info.lamports(); + let vote_account_address = validator_stake.delegation.voter_pubkey; check_validator_stake_address( program_id, stake_pool_info.key, @@ -1633,15 +1683,7 @@ impl Processor { return Err(StakePoolError::ValidatorNotFound.into()); } - let stake_lamports = **stake_info.lamports.borrow(); - let new_pool_tokens = stake_pool - .calc_pool_tokens_for_deposit(stake_lamports) - .ok_or(StakePoolError::CalculationFailure)?; - - msg!( - "lamports pre merge {}", - validator_stake_account_info.lamports() - ); + msg!("Stake pre merge {}", validator_stake.delegation.stake); let (deposit_authority_program_address, deposit_bump_seed) = find_deposit_authority_program_address(program_id, stake_pool_info.key); @@ -1678,6 +1720,21 @@ impl Processor { stake_program_info.clone(), )?; + let (_, post_validator_stake) = get_stake_state(validator_stake_account_info)?; + let post_all_validator_lamports = validator_stake_account_info.lamports(); + msg!("Stake post merge {}", post_validator_stake.delegation.stake); + let all_deposit_lamports = post_all_validator_lamports + .checked_sub(pre_all_validator_lamports) + .ok_or(StakePoolError::CalculationFailure)?; + let stake_deposit_lamports = post_validator_stake + .delegation + .stake + .checked_sub(validator_stake.delegation.stake) + .ok_or(StakePoolError::CalculationFailure)?; + let new_pool_tokens = stake_pool + .calc_pool_tokens_for_deposit(all_deposit_lamports) + .ok_or(StakePoolError::CalculationFailure)?; + Self::token_mint_to( stake_pool_info.key, token_program_info.clone(), @@ -1689,23 +1746,39 @@ impl Processor { new_pool_tokens, )?; + // withdraw additional lamports to the reserve + let additional_lamports = all_deposit_lamports + .checked_sub(stake_deposit_lamports) + .ok_or(StakePoolError::CalculationFailure)?; + if additional_lamports > 0 { + Self::stake_withdraw( + stake_pool_info.key, + validator_stake_account_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.withdraw_bump_seed, + reserve_stake_account_info.clone(), + clock_info.clone(), + stake_history_info.clone(), + stake_program_info.clone(), + additional_lamports, + )?; + } + stake_pool.pool_token_supply = stake_pool .pool_token_supply .checked_add(new_pool_tokens) .ok_or(StakePoolError::CalculationFailure)?; stake_pool.total_stake_lamports = stake_pool .total_stake_lamports - .checked_add(stake_lamports) + .checked_add(all_deposit_lamports) .ok_or(StakePoolError::CalculationFailure)?; stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; - msg!( - "lamports post merge {}", - validator_stake_account_info.lamports() - ); - validator_list_item.active_stake_lamports = validator_stake_account_info - .lamports() - .checked_sub(minimum_stake_lamports(&meta)) + validator_list_item.active_stake_lamports = post_validator_stake + .delegation + .stake + .checked_sub(MINIMUM_ACTIVE_STAKE) .ok_or(StakePoolError::CalculationFailure)?; validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; @@ -1794,7 +1867,7 @@ impl Processor { .ok_or(StakePoolError::StakeLamportsNotEqualToMinimum)?; None } else { - let (meta, stake) = get_stake_state(stake_split_from)?; + let (_, stake) = get_stake_state(stake_split_from)?; let vote_account_address = stake.delegation.voter_pubkey; if let Some(preferred_withdraw_validator) = @@ -1840,11 +1913,9 @@ impl Processor { return Err(StakePoolError::ValidatorNotFound.into()); } - let required_lamports = minimum_stake_lamports(&meta); - let current_lamports = stake_split_from.lamports(); - let remaining_lamports = current_lamports.saturating_sub(withdraw_lamports); - if remaining_lamports < required_lamports { - msg!("Attempting to withdraw {} lamports from validator account with {} lamports, {} must remain", withdraw_lamports, current_lamports, required_lamports); + let remaining_lamports = stake.delegation.stake.saturating_sub(withdraw_lamports); + if remaining_lamports < MINIMUM_ACTIVE_STAKE { + msg!("Attempting to withdraw {} lamports from validator account with {} stake lamports, {} must remain", withdraw_lamports, stake.delegation.stake, MINIMUM_ACTIVE_STAKE); return Err(StakePoolError::StakeLamportsNotEqualToMinimum.into()); } Some((validator_list_item, withdrawing_from_transient_stake)) diff --git a/program/src/stake_program.rs b/program/src/stake_program.rs index 7a205bbd..cc8cfea1 100644 --- a/program/src/stake_program.rs +++ b/program/src/stake_program.rs @@ -645,6 +645,29 @@ pub fn deactivate_stake(stake_pubkey: &Pubkey, authorized_pubkey: &Pubkey) -> In Instruction::new_with_bincode(id(), &StakeInstruction::Deactivate, account_metas) } +/// FIXME copied from the stake program +pub fn withdraw( + stake_pubkey: &Pubkey, + withdrawer_pubkey: &Pubkey, + to_pubkey: &Pubkey, + lamports: u64, + custodian_pubkey: Option<&Pubkey>, +) -> Instruction { + let mut account_metas = vec![ + AccountMeta::new(*stake_pubkey, false), + AccountMeta::new(*to_pubkey, false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(sysvar::stake_history::id(), false), + AccountMeta::new_readonly(*withdrawer_pubkey, true), + ]; + + if let Some(custodian_pubkey) = custodian_pubkey { + account_metas.push(AccountMeta::new_readonly(*custodian_pubkey, true)); + } + + Instruction::new_with_bincode(id(), &StakeInstruction::Withdraw(lamports), account_metas) +} + #[cfg(test)] mod test { use {super::*, bincode::serialize, solana_program::borsh::try_from_slice_unchecked}; diff --git a/program/src/state.rs b/program/src/state.rs index 8d7a1e1c..d92052d4 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -4,7 +4,6 @@ use { crate::error::StakePoolError, borsh::{BorshDeserialize, BorshSchema, BorshSerialize}, solana_program::{account_info::AccountInfo, msg, program_error::ProgramError, pubkey::Pubkey}, - spl_math::checked_ceil_div::CheckedCeilDiv, std::convert::TryFrom, }; @@ -99,13 +98,6 @@ impl StakePool { ) .ok() } - /// calculate the pool tokens that should be burned for a withdrawal of `stake_lamports` - pub fn calc_pool_tokens_for_withdraw(&self, stake_lamports: u64) -> Option { - let (quotient, _) = (stake_lamports as u128) - .checked_mul(self.pool_token_supply as u128)? - .checked_ceil_div(self.total_stake_lamports as u128)?; - u64::try_from(quotient).ok() - } /// calculate lamports amount on withdrawal pub fn calc_lamports_withdraw_amount(&self, pool_tokens: u64) -> Option { diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 2abf8e33..7308760a 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -8,7 +8,6 @@ use { helpers::*, solana_program::{ borsh::try_from_slice_unchecked, - hash::Hash, instruction::{AccountMeta, Instruction, InstructionError}, pubkey::Pubkey, sysvar, @@ -25,9 +24,7 @@ use { }; async fn setup() -> ( - BanksClient, - Keypair, - Hash, + ProgramTestContext, StakePoolAccounts, ValidatorStakeAccount, Keypair, @@ -35,21 +32,32 @@ async fn setup() -> ( Pubkey, u64, ) { - let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let mut context = program_test().start_with_context().await; + let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .initialize_stake_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + 1, + ) .await .unwrap(); let validator_stake_account = simple_add_validator_to_pool( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &stake_pool_accounts, ) .await; + let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + let mut slot = first_normal_slot; + context.warp_to_slot(slot).unwrap(); + let user = Keypair::new(); // make stake account let deposit_stake = Keypair::new(); @@ -61,9 +69,9 @@ async fn setup() -> ( }; let stake_lamports = create_independent_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &deposit_stake, &authorized, &lockup, @@ -72,21 +80,33 @@ async fn setup() -> ( .await; delegate_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &deposit_stake.pubkey(), &user, &validator_stake_account.vote.pubkey(), ) .await; + slot += 2 * slots_per_epoch; + context.warp_to_slot(slot).unwrap(); + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &[validator_stake_account.vote.pubkey()], + false, + ) + .await; + // make pool token account let pool_token_account = Keypair::new(); create_token_account( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &pool_token_account, &stake_pool_accounts.pool_mint.pubkey(), &user.pubkey(), @@ -95,9 +115,7 @@ async fn setup() -> ( .unwrap(); ( - banks_client, - payer, - recent_blockhash, + context, stake_pool_accounts, validator_stake_account, user, @@ -110,9 +128,7 @@ async fn setup() -> ( #[tokio::test] async fn success() { let ( - mut banks_client, - payer, - recent_blockhash, + mut context, stake_pool_accounts, validator_stake_account, user, @@ -121,29 +137,43 @@ async fn success() { stake_lamports, ) = setup().await; + let rent = context.banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + // Save stake pool state before depositing - let stake_pool_before = - get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; - let stake_pool_before = - try_from_slice_unchecked::(&stake_pool_before.data.as_slice()).unwrap(); + let pre_stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let pre_stake_pool = + try_from_slice_unchecked::(&pre_stake_pool.data.as_slice()).unwrap(); // Save validator stake account record before depositing let validator_list = get_account( - &mut banks_client, + &mut context.banks_client, &stake_pool_accounts.validator_list.pubkey(), ) .await; let validator_list = try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); - let validator_stake_item_before = validator_list + let pre_validator_stake_item = validator_list .find(&validator_stake_account.vote.pubkey()) .unwrap(); + // Save reserve state before depositing + let pre_reserve_lamports = get_account( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + ) + .await + .lamports; + let error = stake_pool_accounts .deposit_stake( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &deposit_stake, &pool_token_account, &validator_stake_account.stake_account, @@ -153,7 +183,8 @@ async fn success() { assert!(error.is_none()); // Original stake account should be drained - assert!(banks_client + assert!(context + .banks_client .get_account(deposit_stake) .await .expect("get_account") @@ -162,57 +193,72 @@ async fn success() { let tokens_issued = stake_lamports; // For now tokens are 1:1 to stake // Stake pool should add its balance to the pool balance - let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; - let stake_pool = - try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + let post_stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let post_stake_pool = + try_from_slice_unchecked::(&post_stake_pool.data.as_slice()).unwrap(); assert_eq!( - stake_pool.total_stake_lamports, - stake_pool_before.total_stake_lamports + stake_lamports + post_stake_pool.total_stake_lamports, + pre_stake_pool.total_stake_lamports + stake_lamports ); assert_eq!( - stake_pool.pool_token_supply, - stake_pool_before.pool_token_supply + tokens_issued + post_stake_pool.pool_token_supply, + pre_stake_pool.pool_token_supply + tokens_issued ); // Check minted tokens - let user_token_balance = get_token_balance(&mut banks_client, &pool_token_account).await; + let user_token_balance = + get_token_balance(&mut context.banks_client, &pool_token_account).await; assert_eq!(user_token_balance, tokens_issued); // Check balances in validator stake account list storage let validator_list = get_account( - &mut banks_client, + &mut context.banks_client, &stake_pool_accounts.validator_list.pubkey(), ) .await; let validator_list = try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); - let validator_stake_item = validator_list + let post_validator_stake_item = validator_list .find(&validator_stake_account.vote.pubkey()) .unwrap(); assert_eq!( - validator_stake_item.stake_lamports(), - validator_stake_item_before.stake_lamports() + stake_lamports + post_validator_stake_item.stake_lamports(), + pre_validator_stake_item.stake_lamports() + stake_lamports - stake_rent, ); // Check validator stake account actual SOL balance - let validator_stake_account = - get_account(&mut banks_client, &validator_stake_account.stake_account).await; + let validator_stake_account = get_account( + &mut context.banks_client, + &validator_stake_account.stake_account, + ) + .await; let stake_state = deserialize::(&validator_stake_account.data).unwrap(); let meta = stake_state.meta().unwrap(); assert_eq!( validator_stake_account.lamports - minimum_stake_lamports(&meta), - validator_stake_item.stake_lamports() + post_validator_stake_item.stake_lamports() ); - assert_eq!(validator_stake_item.transient_stake_lamports, 0); + assert_eq!(post_validator_stake_item.transient_stake_lamports, 0); + + // Check reserve + let post_reserve_lamports = get_account( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + ) + .await + .lamports; + assert_eq!(post_reserve_lamports, pre_reserve_lamports + stake_rent); } #[tokio::test] async fn fail_with_wrong_stake_program_id() { let ( - mut banks_client, - payer, - recent_blockhash, + mut context, stake_pool_accounts, validator_stake_account, _user, @@ -230,6 +276,7 @@ async fn fail_with_wrong_stake_program_id() { AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false), AccountMeta::new(deposit_stake, false), AccountMeta::new(validator_stake_account.stake_account, false), + AccountMeta::new(stake_pool_accounts.reserve_stake.pubkey(), false), AccountMeta::new(pool_token_account, false), AccountMeta::new(stake_pool_accounts.pool_mint.pubkey(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), @@ -245,9 +292,11 @@ async fn fail_with_wrong_stake_program_id() { .unwrap(), }; - let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); - transaction.sign(&[&payer], recent_blockhash); - let transaction_error = banks_client + let mut transaction = + Transaction::new_with_payer(&[instruction], Some(&context.payer.pubkey())); + transaction.sign(&[&context.payer], context.last_blockhash); + let transaction_error = context + .banks_client .process_transaction(transaction) .await .err() @@ -264,9 +313,7 @@ async fn fail_with_wrong_stake_program_id() { #[tokio::test] async fn fail_with_wrong_token_program_id() { let ( - mut banks_client, - payer, - recent_blockhash, + mut context, stake_pool_accounts, validator_stake_account, user, @@ -286,14 +333,16 @@ async fn fail_with_wrong_token_program_id() { &deposit_stake, &user.pubkey(), &validator_stake_account.stake_account, + &stake_pool_accounts.reserve_stake.pubkey(), &pool_token_account, &stake_pool_accounts.pool_mint.pubkey(), &wrong_token_program.pubkey(), ), - Some(&payer.pubkey()), + Some(&context.payer.pubkey()), ); - transaction.sign(&[&payer, &user], recent_blockhash); - let transaction_error = banks_client + transaction.sign(&[&context.payer, &user], context.last_blockhash); + let transaction_error = context + .banks_client .process_transaction(transaction) .await .err() @@ -310,9 +359,7 @@ async fn fail_with_wrong_token_program_id() { #[tokio::test] async fn fail_with_wrong_validator_list_account() { let ( - mut banks_client, - payer, - recent_blockhash, + mut context, mut stake_pool_accounts, validator_stake_account, user, @@ -326,9 +373,9 @@ async fn fail_with_wrong_validator_list_account() { let transaction_error = stake_pool_accounts .deposit_stake( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &deposit_stake, &pool_token_account, &validator_stake_account.stake_account, @@ -429,9 +476,7 @@ async fn fail_with_unknown_validator() { #[tokio::test] async fn fail_with_wrong_withdraw_authority() { let ( - mut banks_client, - payer, - recent_blockhash, + mut context, mut stake_pool_accounts, validator_stake_account, user, @@ -444,9 +489,9 @@ async fn fail_with_wrong_withdraw_authority() { let transaction_error = stake_pool_accounts .deposit_stake( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &deposit_stake, &pool_token_account, &validator_stake_account.stake_account, @@ -468,9 +513,7 @@ async fn fail_with_wrong_withdraw_authority() { #[tokio::test] async fn fail_with_wrong_mint_for_receiver_acc() { let ( - mut banks_client, - payer, - recent_blockhash, + mut context, stake_pool_accounts, validator_stake_account, user, @@ -485,9 +528,9 @@ async fn fail_with_wrong_mint_for_receiver_acc() { let outside_pool_fee_acc = Keypair::new(); create_mint( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &outside_mint, &outside_withdraw_auth.pubkey(), ) @@ -495,9 +538,9 @@ async fn fail_with_wrong_mint_for_receiver_acc() { .unwrap(); create_token_account( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &outside_pool_fee_acc, &outside_mint.pubkey(), &outside_manager.pubkey(), @@ -507,9 +550,9 @@ async fn fail_with_wrong_mint_for_receiver_acc() { let transaction_error = stake_pool_accounts .deposit_stake( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &deposit_stake, &outside_pool_fee_acc.pubkey(), &validator_stake_account.stake_account, @@ -714,9 +757,7 @@ async fn fail_without_deposit_authority_signature() { #[tokio::test] async fn success_with_preferred_deposit() { let ( - mut banks_client, - payer, - recent_blockhash, + mut context, stake_pool_accounts, validator_stake, user, @@ -727,9 +768,9 @@ async fn success_with_preferred_deposit() { stake_pool_accounts .set_preferred_validator( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, instruction::PreferredValidatorType::Deposit, Some(validator_stake.vote.pubkey()), ) @@ -737,9 +778,9 @@ async fn success_with_preferred_deposit() { let error = stake_pool_accounts .deposit_stake( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &deposit_stake, &pool_token_account, &validator_stake.stake_account, @@ -752,9 +793,7 @@ async fn success_with_preferred_deposit() { #[tokio::test] async fn fail_with_wrong_preferred_deposit() { let ( - mut banks_client, - payer, - recent_blockhash, + mut context, stake_pool_accounts, validator_stake, user, @@ -764,18 +803,18 @@ async fn fail_with_wrong_preferred_deposit() { ) = setup().await; let preferred_validator = simple_add_validator_to_pool( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &stake_pool_accounts, ) .await; stake_pool_accounts .set_preferred_validator( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, instruction::PreferredValidatorType::Deposit, Some(preferred_validator.vote.pubkey()), ) @@ -783,9 +822,9 @@ async fn fail_with_wrong_preferred_deposit() { let error = stake_pool_accounts .deposit_stake( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &deposit_stake, &pool_token_account, &validator_stake.stake_account, diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index bb67c99a..a9bb39d3 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -622,6 +622,7 @@ impl StakePoolAccounts { stake, ¤t_staker.pubkey(), validator_stake_account, + &self.reserve_stake.pubkey(), pool_account, &self.pool_mint.pubkey(), &spl_token::id(), @@ -635,6 +636,7 @@ impl StakePoolAccounts { stake, ¤t_staker.pubkey(), validator_stake_account, + &self.reserve_stake.pubkey(), pool_account, &self.pool_mint.pubkey(), &spl_token::id(), diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index 41e2a437..7a20379d 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -85,7 +85,7 @@ async fn success() { .await; let validator_list = try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); - assert_eq!(validator_list.is_valid(), true); + assert!(validator_list.is_valid()); } #[tokio::test] diff --git a/program/tests/update_stake_pool_balance.rs b/program/tests/update_stake_pool_balance.rs index 6046e9b4..98b9f87f 100644 --- a/program/tests/update_stake_pool_balance.rs +++ b/program/tests/update_stake_pool_balance.rs @@ -94,17 +94,10 @@ async fn success() { .await; assert!(error.is_none()); - // Add extra funds, simulating rewards - const EXTRA_STAKE_AMOUNT: u64 = 1_000_000; + // Increment vote credits to earn rewards + const VOTE_CREDITS: u64 = 1_000; for stake_account in &stake_accounts { - transfer( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_account.stake_account, - EXTRA_STAKE_AMOUNT, - ) - .await; + context.increment_vote_account_credits(&stake_account.vote.pubkey(), VOTE_CREDITS); } // Update epoch @@ -155,10 +148,8 @@ async fn success() { let expected_fee_lamports = (post_balance - pre_balance) * stake_pool.fee.numerator / stake_pool.fee.denominator; - let actual_fee_lamports = stake_pool - .calc_pool_tokens_for_withdraw(actual_fee) - .unwrap(); - assert!(actual_fee_lamports <= expected_fee_lamports); + let actual_fee_lamports = stake_pool.calc_pool_tokens_for_deposit(actual_fee).unwrap(); + assert_eq!(actual_fee_lamports, expected_fee_lamports); let expected_fee = expected_fee_lamports * pool_token_supply / post_balance; assert_eq!(expected_fee, actual_fee); @@ -166,6 +157,87 @@ async fn success() { assert_eq!(pool_token_supply, stake_pool.pool_token_supply); } +#[tokio::test] +async fn success_ignoring_extra_lamports() { + let (mut context, stake_pool_accounts, stake_accounts) = setup().await; + + let pre_balance = get_validator_list_sum( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + assert_eq!(pre_balance, stake_pool.total_stake_lamports); + + let pre_token_supply = get_token_supply( + &mut context.banks_client, + &stake_pool_accounts.pool_mint.pubkey(), + ) + .await; + + let error = stake_pool_accounts + .update_stake_pool_balance( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; + assert!(error.is_none()); + + // Transfer extra funds, should not be taken into account + const EXTRA_STAKE_AMOUNT: u64 = 1_000_000; + for stake_account in &stake_accounts { + transfer( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_account.stake_account, + EXTRA_STAKE_AMOUNT, + ) + .await; + } + + // Update epoch + context.warp_to_slot(50_000).unwrap(); + + // Update list and pool + let error = stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + stake_accounts + .iter() + .map(|v| v.vote.pubkey()) + .collect::>() + .as_slice(), + false, + ) + .await; + assert!(error.is_none()); + + // Check fee + let post_balance = get_validator_list_sum( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + assert_eq!(post_balance, pre_balance); + let pool_token_supply = get_token_supply( + &mut context.banks_client, + &stake_pool_accounts.pool_mint.pubkey(), + ) + .await; + assert_eq!(pool_token_supply, pre_token_supply); +} + #[tokio::test] async fn fail_with_wrong_validator_list() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index 0f0ff5db..e266ce7c 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -6,7 +6,7 @@ use { helpers::*, solana_program::{borsh::try_from_slice_unchecked, pubkey::Pubkey}, solana_program_test::*, - solana_sdk::signature::{Keypair, Signer}, + solana_sdk::signature::Signer, spl_stake_pool::{ stake_program, state::{StakePool, StakeStatus, ValidatorList}, @@ -42,27 +42,6 @@ async fn setup( .await .unwrap(); - // so warmups / cooldowns go faster - let validator = Keypair::new(); - let vote = Keypair::new(); - create_vote( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &validator, - &vote, - ) - .await; - let deposit_account = - DepositStakeAccount::new_with_vote(vote.pubkey(), validator.pubkey(), 100_000_000_000); - deposit_account - .create_and_delegate( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - ) - .await; - // Add several accounts with some stake let mut stake_accounts: Vec = vec![]; let mut deposit_accounts: Vec = vec![]; @@ -454,16 +433,29 @@ async fn merge_into_validator_stake() { } // Check validator stake accounts have the expected balance now: - // validator stake account minimum + deposited lamports + 2 rents + increased lamports + // validator stake account minimum + deposited lamports + rents + increased lamports + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let expected_lamports = MINIMUM_ACTIVE_STAKE + lamports + reserve_lamports / stake_accounts.len() as u64 - + 2 * rent.minimum_balance(std::mem::size_of::()); + + stake_rent; for stake_account in &stake_accounts { let validator_stake = get_account(&mut context.banks_client, &stake_account.stake_account).await; assert_eq!(validator_stake.lamports, expected_lamports); } + + // Check reserve stake accounts for expected balance: + // own rent, other account rents, and 1 extra lamport + let reserve_stake = get_account( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + ) + .await; + assert_eq!( + reserve_stake.lamports, + 1 + stake_rent * (1 + stake_accounts.len() as u64) + ); } #[tokio::test] @@ -473,7 +465,7 @@ async fn merge_transient_stake_after_remove() { let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); - let deactivated_lamports = lamports + stake_rent; + let deactivated_lamports = lamports; let new_authority = Pubkey::new_unique(); // Decrease and remove all validators for stake_account in &stake_accounts { @@ -578,7 +570,7 @@ async fn merge_transient_stake_after_remove() { .unwrap(); assert_eq!( reserve_stake.lamports, - reserve_lamports + deactivated_lamports + stake_rent + 1 + reserve_lamports + deactivated_lamports + 2 * stake_rent + 1 ); // Update stake pool balance, should be gone From fa9742c79bc204b37f5ac7748d0b970bc13f0415 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 25 Jun 2021 00:39:08 +0200 Subject: [PATCH 0117/1076] Update all solana dependencies to 1.7.3, fix issues (#1958) * Update all dependencies to 1.7.3, fix issues * Remove esm from mocha * Fix missed token test * Also update rust version * token-swap: update tolerance on sim test * Run `cargo clippy --fix` for needless_borrow errors * Rerun cargo fmt --- clients/cli/Cargo.toml | 14 +++--- clients/cli/src/client.rs | 2 +- clients/cli/src/main.rs | 94 +++++++++++++++++++------------------- program/Cargo.toml | 8 ++-- program/src/instruction.rs | 10 ++-- program/src/processor.rs | 48 +++++++++---------- program/tests/decrease.rs | 2 +- program/tests/increase.rs | 2 +- 8 files changed, 87 insertions(+), 93 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index e3853149..6b964089 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -12,13 +12,13 @@ version = "0.2.0" borsh = "0.8" clap = "2.33.3" serde_json = "1.0.62" -solana-account-decoder = "1.6.11" -solana-clap-utils = "1.6.11" -solana-cli-config = "1.6.11" -solana-client = "1.6.11" -solana-logger = "1.6.11" -solana-sdk = "1.6.11" -solana-program = "1.6.11" +solana-account-decoder = "1.7.3" +solana-clap-utils = "1.7.3" +solana-cli-config = "1.7.3" +solana-client = "1.7.3" +solana-logger = "1.7.3" +solana-sdk = "1.7.3" +solana-program = "1.7.3" spl-associated-token-account = { version = "1.0", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "0.2", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "3.1", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/clients/cli/src/client.rs b/clients/cli/src/client.rs index 854dbdf2..229807ce 100644 --- a/clients/cli/src/client.rs +++ b/clients/cli/src/client.rs @@ -31,7 +31,7 @@ pub fn get_validator_list( validator_list_address: &Pubkey, ) -> Result { let account_data = rpc_client.get_account_data(validator_list_address)?; - let validator_list = try_from_slice_unchecked::(&account_data.as_slice()) + let validator_list = try_from_slice_unchecked::(account_data.as_slice()) .map_err(|err| format!("Invalid validator list {}: {}", validator_list_address, err))?; Ok(validator_list) } diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 102b5f3b..613d0f0c 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -252,8 +252,8 @@ fn command_create_pool( check_fee_payer_balance( config, total_rent_free_balances - + fee_calculator.calculate_fee(&setup_transaction.message()) - + fee_calculator.calculate_fee(&initialize_transaction.message()), + + fee_calculator.calculate_fee(setup_transaction.message()) + + fee_calculator.calculate_fee(initialize_transaction.message()), )?; let mut setup_signers = vec![ config.fee_payer.as_ref(), @@ -263,7 +263,7 @@ fn command_create_pool( ]; unique_signers!(setup_signers); setup_transaction.sign(&setup_signers, recent_blockhash); - send_transaction(&config, setup_transaction)?; + send_transaction(config, setup_transaction)?; println!("Creating stake pool {}", stake_pool_keypair.pubkey()); let mut initialize_signers = vec![ @@ -274,7 +274,7 @@ fn command_create_pool( ]; unique_signers!(initialize_signers); initialize_transaction.sign(&initialize_signers, recent_blockhash); - send_transaction(&config, initialize_transaction)?; + send_transaction(config, initialize_transaction)?; Ok(()) } @@ -290,22 +290,22 @@ fn command_vsa_create( // Create new validator stake account address spl_stake_pool::instruction::create_validator_stake_account_with_vote( &spl_stake_pool::id(), - &stake_pool_address, + stake_pool_address, &config.staker.pubkey(), &config.fee_payer.pubkey(), - &vote_account, + vote_account, ), ], Some(&config.fee_payer.pubkey()), ); let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; + check_fee_payer_balance(config, fee_calculator.calculate_fee(transaction.message()))?; transaction.sign( &[config.fee_payer.as_ref(), config.staker.as_ref()], recent_blockhash, ); - send_transaction(&config, transaction)?; + send_transaction(config, transaction)?; Ok(()) } @@ -347,19 +347,19 @@ fn command_vsa_add( let instruction = spl_stake_pool::instruction::add_validator_to_pool_with_vote( &spl_stake_pool::id(), &stake_pool, - &stake_pool_address, - &vote_account, + stake_pool_address, + vote_account, ); let mut transaction = Transaction::new_with_payer(&[instruction], Some(&config.fee_payer.pubkey())); let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; + check_fee_payer_balance(config, fee_calculator.calculate_fee(transaction.message()))?; let mut signers = vec![config.fee_payer.as_ref(), config.staker.as_ref()]; unique_signers!(signers); transaction.sign(&signers, recent_blockhash); - send_transaction(&config, transaction)?; + send_transaction(config, transaction)?; Ok(()) } @@ -393,12 +393,12 @@ fn command_vsa_remove( ); let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; + check_fee_payer_balance(config, fee_calculator.calculate_fee(transaction.message()))?; transaction.sign( &[config.fee_payer.as_ref(), config.staker.as_ref()], recent_blockhash, ); - send_transaction(&config, transaction)?; + send_transaction(config, transaction)?; Ok(()) } @@ -426,12 +426,12 @@ fn command_increase_validator_stake( Transaction::new_with_payer(&[instruction], Some(&config.fee_payer.pubkey())); let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; + check_fee_payer_balance(config, fee_calculator.calculate_fee(transaction.message()))?; transaction.sign( &[config.fee_payer.as_ref(), config.staker.as_ref()], recent_blockhash, ); - send_transaction(&config, transaction)?; + send_transaction(config, transaction)?; Ok(()) } @@ -459,12 +459,12 @@ fn command_decrease_validator_stake( Transaction::new_with_payer(&[instruction], Some(&config.fee_payer.pubkey())); let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; + check_fee_payer_balance(config, fee_calculator.calculate_fee(transaction.message()))?; transaction.sign( &[config.fee_payer.as_ref(), config.staker.as_ref()], recent_blockhash, ); - send_transaction(&config, transaction)?; + send_transaction(config, transaction)?; Ok(()) } @@ -478,7 +478,7 @@ fn command_set_preferred_validator( let mut transaction = Transaction::new_with_payer( &[spl_stake_pool::instruction::set_preferred_validator( &spl_stake_pool::id(), - &stake_pool_address, + stake_pool_address, &config.staker.pubkey(), &stake_pool.validator_list, preferred_type, @@ -488,11 +488,11 @@ fn command_set_preferred_validator( ); let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; + check_fee_payer_balance(config, fee_calculator.calculate_fee(transaction.message()))?; let mut signers = vec![config.fee_payer.as_ref(), config.staker.as_ref()]; unique_signers!(signers); transaction.sign(&signers, recent_blockhash); - send_transaction(&config, transaction)?; + send_transaction(config, transaction)?; Ok(()) } @@ -535,7 +535,7 @@ fn command_deposit( } let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; - let stake_state = get_stake_state(&config.rpc_client, &stake)?; + let stake_state = get_stake_state(&config.rpc_client, stake)?; if config.verbose { println!("Depositing stake account {:?}", stake_state); @@ -568,7 +568,7 @@ fn command_deposit( // Create token account if not specified let token_receiver = token_receiver.unwrap_or(add_associated_token_account( - &config, + config, &stake_pool.pool_mint, &mut instructions, &mut total_rent_free_balances, @@ -590,11 +590,11 @@ fn command_deposit( spl_stake_pool::instruction::deposit_with_authority( &spl_stake_pool::id(), - &stake_pool_address, + stake_pool_address, &stake_pool.validator_list, &deposit_authority.pubkey(), &pool_withdraw_authority, - &stake, + stake, &config.staker.pubkey(), &validator_stake_account, &stake_pool.reserve_stake, @@ -605,10 +605,10 @@ fn command_deposit( } else { spl_stake_pool::instruction::deposit( &spl_stake_pool::id(), - &stake_pool_address, + stake_pool_address, &stake_pool.validator_list, &pool_withdraw_authority, - &stake, + stake, &config.staker.pubkey(), &validator_stake_account, &stake_pool.reserve_stake, @@ -626,11 +626,11 @@ fn command_deposit( let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; check_fee_payer_balance( config, - total_rent_free_balances + fee_calculator.calculate_fee(&transaction.message()), + total_rent_free_balances + fee_calculator.calculate_fee(transaction.message()), )?; unique_signers!(signers); transaction.sign(&signers, recent_blockhash); - send_transaction(&config, transaction)?; + send_transaction(config, transaction)?; Ok(()) } @@ -737,9 +737,9 @@ fn command_update( Transaction::new_with_payer(&[instruction], Some(&config.fee_payer.pubkey())); let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; + check_fee_payer_balance(config, fee_calculator.calculate_fee(transaction.message()))?; transaction.sign(&[config.fee_payer.as_ref()], recent_blockhash); - send_transaction(&config, transaction)?; + send_transaction(config, transaction)?; } Ok(()) } @@ -757,7 +757,7 @@ fn prepare_withdraw_accounts( pool_amount: u64, ) -> Result, Error> { let mut accounts = - get_stake_accounts_by_withdraw_authority(rpc_client, &pool_withdraw_authority)?; + get_stake_accounts_by_withdraw_authority(rpc_client, pool_withdraw_authority)?; if accounts.is_empty() { return Err("No accounts found.".to_string().into()); } @@ -853,7 +853,7 @@ fn command_withdraw( } else if let Some(vote_account_address) = vote_account_address { let (stake_account_address, _) = find_stake_program_address( &spl_stake_pool::id(), - &vote_account_address, + vote_account_address, stake_pool_address, ); let stake_account = config.rpc_client.get_account(&stake_account_address)?; @@ -953,7 +953,7 @@ fn command_withdraw( instructions.push(spl_stake_pool::instruction::withdraw( &spl_stake_pool::id(), - &stake_pool_address, + stake_pool_address, &stake_pool.validator_list, &pool_withdraw_authority, &withdraw_account.address, @@ -973,11 +973,11 @@ fn command_withdraw( let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; check_fee_payer_balance( config, - total_rent_free_balances + fee_calculator.calculate_fee(&transaction.message()), + total_rent_free_balances + fee_calculator.calculate_fee(transaction.message()), )?; unique_signers!(signers); transaction.sign(&signers, recent_blockhash); - send_transaction(&config, transaction)?; + send_transaction(config, transaction)?; Ok(()) } @@ -1012,7 +1012,7 @@ fn command_set_manager( let mut transaction = Transaction::new_with_payer( &[spl_stake_pool::instruction::set_manager( &spl_stake_pool::id(), - &stake_pool_address, + stake_pool_address, &config.manager.pubkey(), &new_manager, &new_fee_receiver, @@ -1021,11 +1021,11 @@ fn command_set_manager( ); let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; + check_fee_payer_balance(config, fee_calculator.calculate_fee(transaction.message()))?; let mut signers = vec![config.fee_payer.as_ref(), config.manager.as_ref()]; unique_signers!(signers); transaction.sign(&signers, recent_blockhash); - send_transaction(&config, transaction)?; + send_transaction(config, transaction)?; Ok(()) } @@ -1037,19 +1037,19 @@ fn command_set_staker( let mut transaction = Transaction::new_with_payer( &[spl_stake_pool::instruction::set_staker( &spl_stake_pool::id(), - &stake_pool_address, + stake_pool_address, &config.manager.pubkey(), - &new_staker, + new_staker, )], Some(&config.fee_payer.pubkey()), ); let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; + check_fee_payer_balance(config, fee_calculator.calculate_fee(transaction.message()))?; let mut signers = vec![config.fee_payer.as_ref(), config.manager.as_ref()]; unique_signers!(signers); transaction.sign(&signers, recent_blockhash); - send_transaction(&config, transaction)?; + send_transaction(config, transaction)?; Ok(()) } @@ -1057,7 +1057,7 @@ fn command_set_fee(config: &Config, stake_pool_address: &Pubkey, new_fee: Fee) - let mut transaction = Transaction::new_with_payer( &[spl_stake_pool::instruction::set_fee( &spl_stake_pool::id(), - &stake_pool_address, + stake_pool_address, &config.manager.pubkey(), new_fee, )], @@ -1065,11 +1065,11 @@ fn command_set_fee(config: &Config, stake_pool_address: &Pubkey, new_fee: Fee) - ); let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?; + check_fee_payer_balance(config, fee_calculator.calculate_fee(transaction.message()))?; let mut signers = vec![config.fee_payer.as_ref(), config.manager.as_ref()]; unique_signers!(signers); transaction.sign(&signers, recent_blockhash); - send_transaction(&config, transaction)?; + send_transaction(config, transaction)?; Ok(()) } @@ -1089,7 +1089,7 @@ fn main() { .global(true) .help("Configuration file to use"); if let Some(ref config_file) = *solana_cli_config::CONFIG_FILE { - arg.default_value(&config_file) + arg.default_value(config_file) } else { arg } diff --git a/program/Cargo.toml b/program/Cargo.toml index f701ee71..46c48a06 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -19,16 +19,16 @@ num-traits = "0.2" num_enum = "0.5.1" serde = "1.0.121" serde_derive = "1.0.103" -solana-program = "1.6.11" +solana-program = "1.7.3" spl-token = { version = "3.1", path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" bincode = "1.3.1" [dev-dependencies] proptest = "0.10" -solana-program-test = "1.6.11" -solana-sdk = "1.6.11" -solana-vote-program = "1.6.11" +solana-program-test = "1.7.3" +solana-sdk = "1.7.3" +solana-vote-program = "1.7.3" [lib] crate-type = ["cdylib", "lib"] diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 57cfe658..de310887 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -580,7 +580,7 @@ pub fn remove_validator_from_pool_with_vote( let (stake_account_address, _) = find_stake_program_address(program_id, vote_account_address, stake_pool_address); let (transient_stake_account, _) = - find_transient_stake_program_address(program_id, &vote_account_address, stake_pool_address); + find_transient_stake_program_address(program_id, vote_account_address, stake_pool_address); remove_validator_from_pool( program_id, stake_pool_address, @@ -632,12 +632,12 @@ pub fn decrease_validator_stake_with_vote( let pool_withdraw_authority = find_withdraw_authority_program_address(program_id, stake_pool_address).0; let (validator_stake_address, _) = - find_stake_program_address(program_id, &vote_account_address, stake_pool_address); + find_stake_program_address(program_id, vote_account_address, stake_pool_address); let (transient_stake_address, _) = - find_transient_stake_program_address(program_id, &vote_account_address, stake_pool_address); + find_transient_stake_program_address(program_id, vote_account_address, stake_pool_address); decrease_validator_stake( program_id, - &stake_pool_address, + stake_pool_address, &stake_pool.staker, &pool_withdraw_authority, &stake_pool.validator_list, @@ -753,7 +753,7 @@ pub fn update_stake_pool( &withdraw_authority, &stake_pool.validator_list, &stake_pool.reserve_stake, - &accounts_chunk, + accounts_chunk, start_index, no_merge, )); diff --git a/program/src/processor.rs b/program/src/processor.rs index f23d0e1c..7778e27b 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -53,7 +53,7 @@ fn check_validator_stake_address( ) -> Result<(), ProgramError> { // Check stake account address validity let (validator_stake_address, _) = - crate::find_stake_program_address(&program_id, &vote_address, &stake_pool_address); + crate::find_stake_program_address(program_id, vote_address, stake_pool_address); if validator_stake_address != *stake_account_address { msg!( "Incorrect stake account address for vote {}, expected {}, received {}", @@ -75,11 +75,8 @@ fn check_transient_stake_address( vote_address: &Pubkey, ) -> Result { // Check stake account address validity - let (transient_stake_address, bump_seed) = crate::find_transient_stake_program_address( - &program_id, - &vote_address, - &stake_pool_address, - ); + let (transient_stake_address, bump_seed) = + crate::find_transient_stake_program_address(program_id, vote_address, stake_pool_address); if transient_stake_address != *stake_account_address { Err(StakePoolError::InvalidStakeAccountAddress.into()) } else { @@ -147,12 +144,12 @@ fn create_transient_stake_account<'a>( transient_stake_account_info.clone(), system_program_info.clone(), ], - &[&transient_stake_account_signer_seeds], + &[transient_stake_account_signer_seeds], )?; invoke_signed( &system_instruction::assign(transient_stake_account_info.key, &stake_program::id()), &[transient_stake_account_info, system_program_info], - &[&transient_stake_account_signer_seeds], + &[transient_stake_account_signer_seeds], ) } @@ -648,11 +645,8 @@ impl Processor { check_system_program(system_program_info.key)?; check_stake_program(stake_program_info.key)?; - let (stake_address, bump_seed) = crate::find_stake_program_address( - &program_id, - &validator_info.key, - &stake_pool_info.key, - ); + let (stake_address, bump_seed) = + crate::find_stake_program_address(program_id, validator_info.key, stake_pool_info.key); if stake_address != *stake_account_info.key { return Err(StakePoolError::InvalidStakeAccountAddress.into()); } @@ -670,19 +664,19 @@ impl Processor { // Create new stake account invoke_signed( &system_instruction::create_account( - &funder_info.key, - &stake_account_info.key, + funder_info.key, + stake_account_info.key, required_lamports, std::mem::size_of::() as u64, &stake_program::id(), ), &[funder_info.clone(), stake_account_info.clone()], - &[&stake_account_signer_seeds], + &[stake_account_signer_seeds], )?; invoke( &stake_program::initialize( - &stake_account_info.key, + stake_account_info.key, &stake_program::Authorized { staker: *staker_info.key, withdrawer: *staker_info.key, @@ -698,9 +692,9 @@ impl Processor { invoke( &stake_program::delegate_stake( - &stake_account_info.key, - &staker_info.key, - &validator_info.key, + stake_account_info.key, + staker_info.key, + validator_info.key, ), &[ stake_account_info.clone(), @@ -1037,7 +1031,7 @@ impl Processor { create_transient_stake_account( transient_stake_account_info.clone(), - &transient_stake_account_signer_seeds, + transient_stake_account_signer_seeds, system_program_info.clone(), )?; @@ -1131,7 +1125,7 @@ impl Processor { program_id, stake_pool_info.key, transient_stake_account_info.key, - &vote_account_address, + vote_account_address, )?; let transient_stake_account_signer_seeds: &[&[_]] = &[ TRANSIENT_STAKE_SEED, @@ -1140,7 +1134,7 @@ impl Processor { &[transient_stake_bump_seed], ]; - let maybe_validator_list_entry = validator_list.find_mut(&vote_account_address); + let maybe_validator_list_entry = validator_list.find_mut(vote_account_address); if maybe_validator_list_entry.is_none() { msg!( "Vote account {} not found in stake pool", @@ -1184,7 +1178,7 @@ impl Processor { create_transient_stake_account( transient_stake_account_info.clone(), - &transient_stake_account_signer_seeds, + transient_stake_account_signer_seeds, system_program_info.clone(), )?; @@ -1290,7 +1284,7 @@ impl Processor { if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); } - stake_pool.check_validator_list(&validator_list_info)?; + stake_pool.check_validator_list(validator_list_info)?; stake_pool.check_authority_withdraw( withdraw_authority_info.key, program_id, @@ -1848,7 +1842,7 @@ impl Processor { .find(|&&x| x.stake_lamports() != 0) { let (validator_stake_address, _) = crate::find_stake_program_address( - &program_id, + program_id, &withdrawable_entry.vote_account_address, stake_pool_info.key, ); @@ -1863,7 +1857,7 @@ impl Processor { let meta = stake_state.meta().ok_or(StakePoolError::WrongStakeState)?; stake_split_from .lamports() - .checked_sub(minimum_reserve_lamports(&meta)) + .checked_sub(minimum_reserve_lamports(meta)) .ok_or(StakePoolError::StakeLamportsNotEqualToMinimum)?; None } else { diff --git a/program/tests/decrease.rs b/program/tests/decrease.rs index 32585b31..f6a182fb 100644 --- a/program/tests/decrease.rs +++ b/program/tests/decrease.rs @@ -349,7 +349,7 @@ async fn fail_with_small_lamport_amount() { .unwrap(); match error { - TransactionError::InstructionError(_, InstructionError::InvalidError) => {} + TransactionError::InstructionError(_, InstructionError::AccountNotRentExempt) => {} _ => panic!("Wrong error occurs while try to decrease small stake"), } } diff --git a/program/tests/increase.rs b/program/tests/increase.rs index 51942c27..191c10a6 100644 --- a/program/tests/increase.rs +++ b/program/tests/increase.rs @@ -348,7 +348,7 @@ async fn fail_with_small_lamport_amount() { .unwrap(); match error { - TransactionError::InstructionError(_, InstructionError::InvalidError) => {} + TransactionError::InstructionError(_, InstructionError::AccountNotRentExempt) => {} _ => panic!("Wrong error"), } } From ecbc8a41d1ad067d02507a6b2e0529bbd7691aa9 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 25 Jun 2021 23:34:48 +0200 Subject: [PATCH 0118/1076] stake-pool: Update version for crate publish (#1967) Finalize the stake pool struct for when a lockup will eventually be present. --- clients/cli/Cargo.toml | 18 +++++++++--------- program/Cargo.toml | 2 +- program/program-id.md | 2 +- program/src/lib.rs | 2 +- program/src/state.rs | 5 ++++- 5 files changed, 16 insertions(+), 13 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 6b964089..a620968d 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -6,21 +6,21 @@ homepage = "https://spl.solana.com/stake-pool" license = "Apache-2.0" name = "spl-stake-pool-cli" repository = "https://github.com/solana-labs/solana-program-library" -version = "0.2.0" +version = "0.3.0" [dependencies] borsh = "0.8" clap = "2.33.3" serde_json = "1.0.62" -solana-account-decoder = "1.7.3" -solana-clap-utils = "1.7.3" -solana-cli-config = "1.7.3" -solana-client = "1.7.3" -solana-logger = "1.7.3" -solana-sdk = "1.7.3" -solana-program = "1.7.3" +solana-account-decoder = "=1.7.3" +solana-clap-utils = "=1.7.3" +solana-cli-config = "=1.7.3" +solana-client = "=1.7.3" +solana-logger = "=1.7.3" +solana-sdk = "=1.7.3" +solana-program = "=1.7.3" spl-associated-token-account = { version = "1.0", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } -spl-stake-pool = { version = "0.2", path="../program", features = [ "no-entrypoint" ] } +spl-stake-pool = { version = "0.3", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "3.1", path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" bincode = "1.3.1" diff --git a/program/Cargo.toml b/program/Cargo.toml index 46c48a06..18c34b61 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "spl-stake-pool" -version = "0.2.0" +version = "0.3.0" description = "Solana Program Library Stake Pool" authors = ["Solana Maintainers "] repository = "https://github.com/solana-labs/solana-program-library" diff --git a/program/program-id.md b/program/program-id.md index 26d3f434..fc9290e5 100644 --- a/program/program-id.md +++ b/program/program-id.md @@ -1 +1 @@ -poo1B9L9nR3CrcaziKVYVpRX6A9Y1LAXYasjjfCbApj +SPoo1XJbrC5pXDfg5NQAXo2RKyfimXKm6KpqicGvpbo diff --git a/program/src/lib.rs b/program/src/lib.rs index 56f9e798..f1b539e1 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -101,4 +101,4 @@ pub fn find_transient_stake_program_address( ) } -solana_program::declare_id!("poo1B9L9nR3CrcaziKVYVpRX6A9Y1LAXYasjjfCbApj"); +solana_program::declare_id!("SPoo1XJbrC5pXDfg5NQAXo2RKyfimXKm6KpqicGvpbo"); diff --git a/program/src/state.rs b/program/src/state.rs index d92052d4..36ee0988 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -1,7 +1,7 @@ //! State transition types use { - crate::error::StakePoolError, + crate::{error::StakePoolError, stake_program::Lockup}, borsh::{BorshDeserialize, BorshSchema, BorshSerialize}, solana_program::{account_info::AccountInfo, msg, program_error::ProgramError, pubkey::Pubkey}, std::convert::TryFrom, @@ -79,6 +79,9 @@ pub struct StakePool { /// Last epoch the `total_stake_lamports` field was updated pub last_update_epoch: u64, + /// Lockup that all stakes in the pool must have + pub lockup: Lockup, + /// Fee taken as a proportion of rewards each epoch pub fee: Fee, From 0cc16bd9fb846b4f76bafb62ca3a682cb16a44d3 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 29 Jun 2021 00:51:54 +0200 Subject: [PATCH 0119/1076] stake-pool: Fixup accounting on increase transient account (#1985) --- clients/cli/src/main.rs | 30 ++++++++++--- program/src/instruction.rs | 6 ++- program/src/lib.rs | 2 +- program/src/processor.rs | 42 +++++++++++++++---- program/tests/increase.rs | 17 ++++---- .../tests/update_validator_list_balance.rs | 8 ---- 6 files changed, 74 insertions(+), 31 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 613d0f0c..96917d87 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -105,9 +105,10 @@ fn command_create_pool( max_validators: u32, stake_pool_keypair: Option, mint_keypair: Option, + reserve_keypair: Option, ) -> CommandResult { - let reserve_stake = Keypair::new(); - println!("Creating reserve stake {}", reserve_stake.pubkey()); + let reserve_keypair = reserve_keypair.unwrap_or_else(Keypair::new); + println!("Creating reserve stake {}", reserve_keypair.pubkey()); let mint_keypair = mint_keypair.unwrap_or_else(Keypair::new); println!("Creating mint {}", mint_keypair.pubkey()); @@ -163,13 +164,13 @@ fn command_create_pool( // Account for the stake pool reserve system_instruction::create_account( &config.fee_payer.pubkey(), - &reserve_stake.pubkey(), + &reserve_keypair.pubkey(), reserve_stake_balance, STAKE_STATE_LEN as u64, &stake_program::id(), ), stake_program::initialize( - &reserve_stake.pubkey(), + &reserve_keypair.pubkey(), &stake_program::Authorized { staker: withdraw_authority, withdrawer: withdraw_authority, @@ -236,7 +237,7 @@ fn command_create_pool( &config.manager.pubkey(), &config.staker.pubkey(), &validator_list.pubkey(), - &reserve_stake.pubkey(), + &reserve_keypair.pubkey(), &mint_keypair.pubkey(), &pool_fee_account.pubkey(), &spl_token::id(), @@ -259,7 +260,7 @@ fn command_create_pool( config.fee_payer.as_ref(), &mint_keypair, &pool_fee_account, - &reserve_stake, + &reserve_keypair, ]; unique_signers!(setup_signers); setup_transaction.sign(&setup_signers, recent_blockhash); @@ -640,6 +641,13 @@ fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { let pool_mint = get_token_mint(&config.rpc_client, &stake_pool.pool_mint)?; let epoch_info = config.rpc_client.get_epoch_info()?; + let reserve_stake = config.rpc_client.get_account(&stake_pool.reserve_stake)?; + println!( + "Reserve Account: {}\tBalance: {}", + stake_pool.reserve_stake, + Sol(reserve_stake.lamports), + ); + for validator in validator_list.validators { println!( "Validator Vote Account: {}\tBalance: {}\tLast Update Epoch: {}{}", @@ -1241,6 +1249,14 @@ fn main() { .takes_value(true) .help("Stake pool mint keypair [default: new keypair]"), ) + .arg( + Arg::with_name("reserve_keypair") + .long("reserve-keypair") + .validator(is_keypair_or_ask_keyword) + .value_name("PATH") + .takes_value(true) + .help("Stake pool reserve keypair [default: new keypair]"), + ) ) .subcommand(SubCommand::with_name("create-validator-stake") .about("Create a new stake account to use with the pool. Must be signed by the pool staker.") @@ -1710,6 +1726,7 @@ fn main() { let max_validators = value_t_or_exit!(arg_matches, "max_validators", u32); let pool_keypair = keypair_of(arg_matches, "pool_keypair"); let mint_keypair = keypair_of(arg_matches, "mint_keypair"); + let reserve_keypair = keypair_of(arg_matches, "reserve_keypair"); command_create_pool( &config, deposit_authority, @@ -1720,6 +1737,7 @@ fn main() { max_validators, pool_keypair, mint_keypair, + reserve_keypair, ) } ("create-validator-stake", Some(arg_matches)) => { diff --git a/program/src/instruction.rs b/program/src/instruction.rs index de310887..ee6426f5 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -162,7 +162,11 @@ pub enum StakePoolInstruction { /// 10. `[]` Stake Config sysvar /// 11. `[]` System program /// 12. `[]` Stake program - /// userdata: amount of lamports to split into the transient stake account + /// userdata: amount of lamports to increase on the given validator. + /// The actual amount split into the transient stake account is: + /// `lamports + stake_rent_exemption` + /// The rent-exemption of the stake account is withdrawn back to the reserve + /// after it is merged. IncreaseValidatorStake(u64), /// (Staker only) Set the preferred deposit or withdraw stake account for the diff --git a/program/src/lib.rs b/program/src/lib.rs index f1b539e1..98a8bc1c 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -33,7 +33,7 @@ pub const MINIMUM_ACTIVE_STAKE: u64 = LAMPORTS_PER_SOL; /// Maximum amount of validator stake accounts to update per /// `UpdateValidatorListBalance` instruction, based on compute limits -pub const MAX_VALIDATORS_TO_UPDATE: usize = 10; +pub const MAX_VALIDATORS_TO_UPDATE: usize = 9; /// Get the stake amount under consideration when calculating pool token /// conversions diff --git a/program/src/processor.rs b/program/src/processor.rs index 7778e27b..acc1ee0a 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1150,19 +1150,21 @@ impl Processor { } let stake_rent = rent.minimum_balance(std::mem::size_of::()); - let minimum_lamports = MINIMUM_ACTIVE_STAKE + stake_rent; - if lamports < minimum_lamports { + if lamports < MINIMUM_ACTIVE_STAKE { msg!( "Need more than {} lamports for transient stake to be rent-exempt and mergeable, {} provided", - minimum_lamports, + MINIMUM_ACTIVE_STAKE, lamports ); return Err(ProgramError::AccountNotRentExempt); } + // the stake account rent exemption is withdrawn after the merge, so + let total_lamports = lamports.saturating_add(stake_rent); + if reserve_stake_account_info .lamports() - .saturating_sub(lamports) + .saturating_sub(total_lamports) <= stake_rent { let max_split_amount = reserve_stake_account_info @@ -1189,7 +1191,7 @@ impl Processor { withdraw_authority_info.clone(), AUTHORITY_WITHDRAW, stake_pool.withdraw_bump_seed, - lamports, + total_lamports, transient_stake_account_info.clone(), )?; @@ -1206,7 +1208,7 @@ impl Processor { stake_pool.withdraw_bump_seed, )?; - validator_list_entry.transient_stake_lamports = lamports; + validator_list_entry.transient_stake_lamports = total_lamports; validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; Ok(()) @@ -1404,6 +1406,9 @@ impl Processor { if stake_program::active_stakes_can_merge(&stake, &validator_stake) .is_ok() { + let additional_lamports = transient_stake_info + .lamports() + .saturating_sub(stake.delegation.stake); Self::stake_merge( stake_pool_info.key, transient_stake_info.clone(), @@ -1415,6 +1420,23 @@ impl Processor { stake_history_info.clone(), stake_program_info.clone(), )?; + + // post merge of two active stakes, withdraw + // the extra back to the reserve + if additional_lamports > 0 { + Self::stake_withdraw( + stake_pool_info.key, + validator_stake_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.withdraw_bump_seed, + reserve_stake_info.clone(), + clock_info.clone(), + stake_history_info.clone(), + stake_program_info.clone(), + additional_lamports, + )?; + } } else { msg!("Stake activating or just active, not ready to merge"); transient_stake_lamports = account_stake; @@ -1436,6 +1458,10 @@ impl Processor { // Status for validator stake // * active -> do everything // * any other state / not a stake -> error state, but account for transient stake + let validator_stake_state = try_from_slice_unchecked::( + &validator_stake_info.data.borrow(), + ) + .ok(); match validator_stake_state { Some(stake_program::StakeState::Stake(_, stake)) => { if validator_stake_record.status == StakeStatus::Active { @@ -1782,8 +1808,8 @@ impl Processor { /// Processes [Withdraw](enum.Instruction.html). fn process_withdraw( program_id: &Pubkey, - pool_tokens: u64, accounts: &[AccountInfo], + pool_tokens: u64, ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; @@ -2126,7 +2152,7 @@ impl Processor { } StakePoolInstruction::Withdraw(amount) => { msg!("Instruction: Withdraw"); - Self::process_withdraw(program_id, amount, accounts) + Self::process_withdraw(program_id, accounts, amount) } StakePoolInstruction::SetManager => { msg!("Instruction: SetManager"); diff --git a/program/tests/increase.rs b/program/tests/increase.rs index 191c10a6..b6727352 100644 --- a/program/tests/increase.rs +++ b/program/tests/increase.rs @@ -93,8 +93,8 @@ async fn success() { assert!(transient_account.is_none()); let rent = banks_client.get_rent().await.unwrap(); - let lamports = rent.minimum_balance(std::mem::size_of::()); - let reserve_lamports = reserve_lamports - lamports; + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let increase_amount = reserve_lamports - stake_rent - 1; let error = stake_pool_accounts .increase_validator_stake( &mut banks_client, @@ -102,7 +102,7 @@ async fn success() { &recent_blockhash, &validator_stake.transient_stake_account, &validator_stake.vote.pubkey(), - reserve_lamports, + increase_amount, ) .await; assert!(error.is_none()); @@ -116,7 +116,7 @@ async fn success() { let reserve_stake_state = deserialize::(&reserve_stake_account.data).unwrap(); assert_eq!( - pre_reserve_stake_account.lamports - reserve_lamports, + pre_reserve_stake_account.lamports - increase_amount - stake_rent, reserve_stake_account.lamports ); assert!(reserve_stake_state.delegation().is_none()); @@ -126,7 +126,10 @@ async fn success() { get_account(&mut banks_client, &validator_stake.transient_stake_account).await; let transient_stake_state = deserialize::(&transient_stake_account.data).unwrap(); - assert_eq!(transient_stake_account.lamports, reserve_lamports); + assert_eq!( + transient_stake_account.lamports, + increase_amount + stake_rent + ); assert_ne!( transient_stake_state.delegation().unwrap().activation_epoch, Epoch::MAX @@ -332,7 +335,7 @@ async fn fail_with_small_lamport_amount() { ) = setup().await; let rent = banks_client.get_rent().await.unwrap(); - let lamports = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let error = stake_pool_accounts .increase_validator_stake( @@ -341,7 +344,7 @@ async fn fail_with_small_lamport_amount() { &recent_blockhash, &validator_stake.transient_stake_account, &validator_stake.vote.pubkey(), - lamports, + stake_rent, ) .await .unwrap() diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index e266ce7c..b5e46dc7 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -381,14 +381,6 @@ async fn merge_into_validator_stake() { let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data).unwrap(); assert_eq!(expected_lamports, stake_pool.total_stake_lamports); - let stake_pool_info = get_account( - &mut context.banks_client, - &stake_pool_accounts.stake_pool.pubkey(), - ) - .await; - let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data).unwrap(); - assert_eq!(expected_lamports, stake_pool.total_stake_lamports); - // Warp one more epoch so the stakes activate, ready to merge let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; slot += slots_per_epoch; From 1c4034252e6b29f68320898224e00d2f4389ba5c Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 29 Jun 2021 23:11:08 +0200 Subject: [PATCH 0120/1076] stake-pool: Add helper scripts for setting up a pool (#1994) --- clients/cli/README.md | 57 ++++++++++++++++++- clients/cli/scripts/deposit-withdraw.sh | 74 +++++++++++++++++++++++++ clients/cli/scripts/setup-local.sh | 56 +++++++++++++++++++ clients/cli/scripts/setup-stake-pool.sh | 70 +++++++++++++++++++++++ 4 files changed, 256 insertions(+), 1 deletion(-) create mode 100755 clients/cli/scripts/deposit-withdraw.sh create mode 100755 clients/cli/scripts/setup-local.sh create mode 100755 clients/cli/scripts/setup-stake-pool.sh diff --git a/clients/cli/README.md b/clients/cli/README.md index 1016e9e4..13b1ead3 100644 --- a/clients/cli/README.md +++ b/clients/cli/README.md @@ -1,3 +1,58 @@ # SPL Stake Pool program command-line utility -A basic command-line for creating and using SPL Stake Pools. See https://spl.solana.com/stake-pool for more details +A basic command-line for creating and using SPL Stake Pools. See https://spl.solana.com/stake-pool for more details. + +## Scripts for setting up a stake pool + +Under `./scripts`, this repo also contains some bash scripts that are useful for +setting up your own stake pool. These scripts require the Solana CLI tool suite, +which can be downloaded by following the instructions at +(https://docs.solana.com/cli/install-solana-cli-tools). Additionally, you must +have a usable keypair, created at the default location using `solana-keygen new`. + +### setup-local.sh + +Builds the stake pool program and sets up a `solana-test-validator` with some +new validator vote accounts. + +The only input it accepts is a number, for the number of vote accounts to create, e.g.: + +```bash +$ ./setup-local.sh 100 +``` + +#### Important notes on local network + +If you are using epochs of 32 slots, there is a good chance +that you will pass an epoch while using one of the stake pool commands, causing +it to fail with: `Custom program error: 0x11`. This is totally normal, and will +not happen on a normal network. + +Since there is no voting activity on the test validator network, you will +need to use the `--force` flag with `solana delegate-stake`, ie: + +```bash +$ solana delegate-stake --force stake.json CzDy6uxLTko5Jjcdm46AozMmrARY6R2aDBagdemiBuiT +``` + +### setup-stake-pool.sh + +Creates a new stake pool with the parameters hardcoded in the script: + +* fee numerator +* fee denominator +* maximum number of validators +* list of validator vote accounts + +```bash +$ ./setup-stake-pool.sh 100 validator_list.txt +``` + +### deposit-withdraw.sh + +Creates new stakes to deposit into each of the stake accounts in the pool, given +the stake pool, mint, and validator list. + +```bash +$ ./deposit-withdraw.sh keys/stake-pool.json validator_list.txt +``` diff --git a/clients/cli/scripts/deposit-withdraw.sh b/clients/cli/scripts/deposit-withdraw.sh new file mode 100755 index 00000000..f8508135 --- /dev/null +++ b/clients/cli/scripts/deposit-withdraw.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash + +# Script to deposit and withdraw stakes from a pool, given stake pool public key +# and a list of validators + +cd "$(dirname "$0")" +stake_pool_keyfile=$1 +validator_list=$2 + +stake_pool_pubkey=$(solana-keygen pubkey $stake_pool_keyfile) + +sol_amount=2 +half_sol_amount=1 +keys_dir=keys +spl_stake_pool=../../../target/debug/spl-stake-pool + +mkdir -p $keys_dir + +create_keypair () { + if test ! -f $1 + then + solana-keygen new --no-passphrase -s -o $1 + fi +} + +create_user_stakes () { + validator_list=$1 + sol_amount=$2 + for validator in $(cat $validator_list) + do + create_keypair $keys_dir/stake_$validator.json + solana create-stake-account $keys_dir/stake_$validator.json $sol_amount + done +} + +delegate_user_stakes () { + validator_list=$1 + for validator in $(cat $validator_list) + do + solana delegate-stake --force $keys_dir/stake_$validator.json $validator + done +} + +deposit_stakes () { + stake_pool_pubkey=$1 + validator_list=$2 + for validator in $(cat $validator_list) + do + stake=$(solana-keygen pubkey $keys_dir/stake_$validator.json) + $spl_stake_pool deposit $stake_pool_pubkey $stake + done +} + +withdraw_stakes () { + stake_pool_pubkey=$1 + validator_list=$2 + pool_amount=$3 + for validator in $(cat $validator_list) + do + $spl_stake_pool withdraw $stake_pool_pubkey $pool_amount --vote-account $validator + done +} + +echo "Creating user stake accounts" +create_user_stakes $validator_list $sol_amount +echo "Delegating user stakes" +delegate_user_stakes $validator_list +echo "Waiting for stakes to activate, this may take awhile depending on the network!" +echo "If you are running on localnet with 32 slots per epoch, wait 24 seconds..." +sleep 24 +echo "Depositing stakes into stake pool" +deposit_stakes $stake_pool_pubkey $validator_list +echo "Withdrawing stakes from stake pool" +withdraw_stakes $stake_pool_pubkey $validator_list $half_sol_amount diff --git a/clients/cli/scripts/setup-local.sh b/clients/cli/scripts/setup-local.sh new file mode 100755 index 00000000..1aeb2474 --- /dev/null +++ b/clients/cli/scripts/setup-local.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash + +# Script to setup a local solana-test-validator with the stake pool program + +cd "$(dirname "$0")" +max_validators=$1 +validator_list=$2 + +keys_dir=keys +mkdir -p $keys_dir +if test -f $validator_list +then + rm $validator_list +fi + +create_keypair () { + if test ! -f $1 + then + solana-keygen new --no-passphrase -s -o $1 + fi +} + +build_program () { + cargo build-bpf --manifest-path ../../program/Cargo.toml +} + +setup_validator() { + solana-test-validator --bpf-program SPoo1XJbrC5pXDfg5NQAXo2RKyfimXKm6KpqicGvpbo ../../../target/deploy/spl_stake_pool.so --quiet --reset --slots-per-epoch 32 & + pid=$! + solana config set --url http://127.0.0.1:8899 + solana config set --commitment confirmed + echo "waiting for solana-test-validator, pid: $pid" + sleep 5 +} + +create_vote_accounts () { + max_validators=$1 + validator_list=$2 + for number in $(seq 1 $max_validators) + do + create_keypair $keys_dir/identity_$number.json + create_keypair $keys_dir/vote_$number.json + solana create-vote-account $keys_dir/vote_$number.json $keys_dir/identity_$number.json --commission 1 + vote_pubkey=$(solana-keygen pubkey $keys_dir/vote_$number.json) + echo $vote_pubkey >> $validator_list + done +} + +echo "Building on-chain program" +build_program + +echo "Setting up local validator" +setup_validator + +echo "Creating vote accounts" +create_vote_accounts $max_validators $validator_list diff --git a/clients/cli/scripts/setup-stake-pool.sh b/clients/cli/scripts/setup-stake-pool.sh new file mode 100755 index 00000000..f0b8c349 --- /dev/null +++ b/clients/cli/scripts/setup-stake-pool.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash + +# Script to setup a stake pool, add new validators from a list + +cd "$(dirname "$0")" +max_validators=$1 +validator_list=$2 + +keys_dir=keys +spl_stake_pool=../../../target/debug/spl-stake-pool + +mkdir -p $keys_dir + +build_cli () { + cargo build --manifest-path ../Cargo.toml +} + +create_keypair () { + if test ! -f $1 + then + solana-keygen new --no-passphrase -s -o $1 + fi +} + +setup_pool () { + max_validators=$1 + stake_pool_keyfile=$2 + mint_keyfile=$3 + mkdir -p $keys_dir + create_keypair $stake_pool_keyfile + create_keypair $mint_keyfile + + $spl_stake_pool create-pool --fee-numerator 3 --fee-denominator 100 \ + --max-validators $max_validators \ + --pool-keypair $stake_pool_keyfile \ + --mint-keypair $mint_keyfile +} + +create_validator_stakes() { + pool=$1 + validator_list=$2 + for validator in $(cat $validator_list) + do + $spl_stake_pool create-validator-stake $pool $validator + done +} + +add_validator_stakes () { + pool=$1 + validator_list=$2 + for validator in $(cat $validator_list) + do + $spl_stake_pool add-validator $pool $validator + done +} + +stake_pool_keyfile=$keys_dir/stake-pool.json +mint_keyfile=$keys_dir/mint.json + +echo "Building CLI" +build_cli +echo "Creating pool" +setup_pool $max_validators $stake_pool_keyfile $mint_keyfile + +stake_pool_pubkey=$(solana-keygen pubkey $stake_pool_keyfile) + +echo "Creating validator stake accounts" +create_validator_stakes $stake_pool_pubkey $validator_list +echo "Adding validator stake accounts to the pool" +add_validator_stakes $stake_pool_pubkey $validator_list From 67122bfd00f1423a412c8e0df0e0278e191ff32c Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 30 Jun 2021 12:59:23 +0200 Subject: [PATCH 0121/1076] stake-pool-cli: Add small optimizations for updating faster (#1995) * stake-pool-cli: Add small optimizations for updating faster * Cargo fmt * Light refactor * Refactor transaction creation / checking * Rename function --- clients/cli/src/main.rs | 266 +++++++++++++++++++++---------------- program/src/instruction.rs | 12 +- program/src/lib.rs | 2 +- 3 files changed, 157 insertions(+), 123 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 96917d87..ff9340de 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -27,6 +27,7 @@ use { commitment_config::CommitmentConfig, native_token::{self, Sol}, signature::{Keypair, Signer}, + signers::Signers, system_instruction, transaction::Transaction, }, @@ -82,6 +83,20 @@ fn check_fee_payer_balance(config: &Config, required_balance: u64) -> Result<(), } } +fn send_transaction_no_wait( + config: &Config, + transaction: Transaction, +) -> solana_client::client_error::Result<()> { + if config.dry_run { + let result = config.rpc_client.simulate_transaction(&transaction)?; + println!("Simulate result: {:?}", result); + } else { + let signature = config.rpc_client.send_transaction(&transaction)?; + println!("Signature: {}", signature); + } + Ok(()) +} + fn send_transaction( config: &Config, transaction: Transaction, @@ -98,6 +113,23 @@ fn send_transaction( Ok(()) } +fn checked_transaction_with_signers( + config: &Config, + instructions: &[Instruction], + signers: &T, +) -> Result { + let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + let transaction = Transaction::new_signed_with_payer( + instructions, + Some(&config.fee_payer.pubkey()), + signers, + recent_blockhash, + ); + + check_fee_payer_balance(config, fee_calculator.calculate_fee(transaction.message()))?; + Ok(transaction) +} + fn command_create_pool( config: &Config, deposit_authority: Option, @@ -285,8 +317,8 @@ fn command_vsa_create( vote_account: &Pubkey, ) -> CommandResult { println!("Creating stake account on {}", vote_account); - - let mut transaction = Transaction::new_with_payer( + let transaction = checked_transaction_with_signers( + config, &[ // Create new validator stake account address spl_stake_pool::instruction::create_validator_stake_account_with_vote( @@ -297,15 +329,8 @@ fn command_vsa_create( vote_account, ), ], - Some(&config.fee_payer.pubkey()), - ); - - let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_fee_payer_balance(config, fee_calculator.calculate_fee(transaction.message()))?; - transaction.sign( &[config.fee_payer.as_ref(), config.staker.as_ref()], - recent_blockhash, - ); + )?; send_transaction(config, transaction)?; Ok(()) } @@ -345,21 +370,21 @@ fn command_vsa_add( command_update(config, stake_pool_address, false, false)?; } - let instruction = spl_stake_pool::instruction::add_validator_to_pool_with_vote( - &spl_stake_pool::id(), - &stake_pool, - stake_pool_address, - vote_account, - ); - - let mut transaction = - Transaction::new_with_payer(&[instruction], Some(&config.fee_payer.pubkey())); - - let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_fee_payer_balance(config, fee_calculator.calculate_fee(transaction.message()))?; let mut signers = vec![config.fee_payer.as_ref(), config.staker.as_ref()]; unique_signers!(signers); - transaction.sign(&signers, recent_blockhash); + let transaction = checked_transaction_with_signers( + config, + &[ + spl_stake_pool::instruction::add_validator_to_pool_with_vote( + &spl_stake_pool::id(), + &stake_pool, + stake_pool_address, + vote_account, + ), + ], + &signers, + )?; + send_transaction(config, transaction)?; Ok(()) } @@ -379,7 +404,10 @@ fn command_vsa_remove( let staker_pubkey = config.staker.pubkey(); let new_authority = new_authority.as_ref().unwrap_or(&staker_pubkey); - let mut transaction = Transaction::new_with_payer( + let mut signers = vec![config.fee_payer.as_ref(), config.staker.as_ref()]; + unique_signers!(signers); + let transaction = checked_transaction_with_signers( + config, &[ // Create new validator stake account address spl_stake_pool::instruction::remove_validator_from_pool_with_vote( @@ -390,15 +418,8 @@ fn command_vsa_remove( new_authority, ), ], - Some(&config.fee_payer.pubkey()), - ); - - let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_fee_payer_balance(config, fee_calculator.calculate_fee(transaction.message()))?; - transaction.sign( - &[config.fee_payer.as_ref(), config.staker.as_ref()], - recent_blockhash, - ); + &signers, + )?; send_transaction(config, transaction)?; Ok(()) } @@ -415,23 +436,22 @@ fn command_increase_validator_stake( } let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; - let instruction = spl_stake_pool::instruction::increase_validator_stake_with_vote( - &spl_stake_pool::id(), - &stake_pool, - stake_pool_address, - vote_account, - lamports, - ); - let mut transaction = - Transaction::new_with_payer(&[instruction], Some(&config.fee_payer.pubkey())); - - let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_fee_payer_balance(config, fee_calculator.calculate_fee(transaction.message()))?; - transaction.sign( - &[config.fee_payer.as_ref(), config.staker.as_ref()], - recent_blockhash, - ); + let mut signers = vec![config.fee_payer.as_ref(), config.staker.as_ref()]; + unique_signers!(signers); + let transaction = checked_transaction_with_signers( + config, + &[ + spl_stake_pool::instruction::increase_validator_stake_with_vote( + &spl_stake_pool::id(), + &stake_pool, + stake_pool_address, + vote_account, + lamports, + ), + ], + &signers, + )?; send_transaction(config, transaction)?; Ok(()) } @@ -448,23 +468,22 @@ fn command_decrease_validator_stake( } let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; - let instruction = spl_stake_pool::instruction::decrease_validator_stake_with_vote( - &spl_stake_pool::id(), - &stake_pool, - stake_pool_address, - vote_account, - lamports, - ); - let mut transaction = - Transaction::new_with_payer(&[instruction], Some(&config.fee_payer.pubkey())); - - let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_fee_payer_balance(config, fee_calculator.calculate_fee(transaction.message()))?; - transaction.sign( - &[config.fee_payer.as_ref(), config.staker.as_ref()], - recent_blockhash, - ); + let mut signers = vec![config.fee_payer.as_ref(), config.staker.as_ref()]; + unique_signers!(signers); + let transaction = checked_transaction_with_signers( + config, + &[ + spl_stake_pool::instruction::decrease_validator_stake_with_vote( + &spl_stake_pool::id(), + &stake_pool, + stake_pool_address, + vote_account, + lamports, + ), + ], + &signers, + )?; send_transaction(config, transaction)?; Ok(()) } @@ -476,7 +495,10 @@ fn command_set_preferred_validator( vote_address: Option, ) -> CommandResult { let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; - let mut transaction = Transaction::new_with_payer( + let mut signers = vec![config.fee_payer.as_ref(), config.staker.as_ref()]; + unique_signers!(signers); + let transaction = checked_transaction_with_signers( + config, &[spl_stake_pool::instruction::set_preferred_validator( &spl_stake_pool::id(), stake_pool_address, @@ -485,14 +507,8 @@ fn command_set_preferred_validator( preferred_type, vote_address, )], - Some(&config.fee_payer.pubkey()), - ); - - let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_fee_payer_balance(config, fee_calculator.calculate_fee(transaction.message()))?; - let mut signers = vec![config.fee_payer.as_ref(), config.staker.as_ref()]; - unique_signers!(signers); - transaction.sign(&signers, recent_blockhash); + &signers, + )?; send_transaction(config, transaction)?; Ok(()) } @@ -648,7 +664,7 @@ fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { Sol(reserve_stake.lamports), ); - for validator in validator_list.validators { + for validator in &validator_list.validators { println!( "Validator Vote Account: {}\tBalance: {}\tLast Update Epoch: {}{}", validator.vote_account_address, @@ -675,6 +691,14 @@ fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { "Total Pool Tokens: {}", spl_token::amount_to_ui_amount(stake_pool.pool_token_supply, pool_mint.decimals) ); + println!( + "Total number of validators: {}", + validator_list.validators.len() + ); + println!( + "Max number of validators: {}", + validator_list.max_validators + ); if config.verbose { println!(); @@ -731,24 +755,43 @@ fn command_update( let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?; - let instructions = spl_stake_pool::instruction::update_stake_pool( - &spl_stake_pool::id(), - &stake_pool, - &validator_list, - stake_pool_address, - no_merge, - ); + let (mut update_list_instructions, update_balance_instruction) = + spl_stake_pool::instruction::update_stake_pool( + &spl_stake_pool::id(), + &stake_pool, + &validator_list, + stake_pool_address, + no_merge, + ); - // TODO: A faster solution would be to send all the `update_validator_list_balance` instructions concurrently - for instruction in instructions { - let mut transaction = - Transaction::new_with_payer(&[instruction], Some(&config.fee_payer.pubkey())); + let update_list_instructions_len = update_list_instructions.len(); + if update_list_instructions_len > 0 { + let last_instruction = update_list_instructions.split_off(update_list_instructions_len - 1); + // send the first ones without waiting + for instruction in update_list_instructions { + let transaction = checked_transaction_with_signers( + config, + &[instruction], + &[config.fee_payer.as_ref()], + )?; + send_transaction_no_wait(config, transaction)?; + } - let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_fee_payer_balance(config, fee_calculator.calculate_fee(transaction.message()))?; - transaction.sign(&[config.fee_payer.as_ref()], recent_blockhash); + // wait on the last one + let transaction = checked_transaction_with_signers( + config, + &last_instruction, + &[config.fee_payer.as_ref()], + )?; send_transaction(config, transaction)?; } + let transaction = checked_transaction_with_signers( + config, + &[update_balance_instruction], + &[config.fee_payer.as_ref()], + )?; + send_transaction(config, transaction)?; + Ok(()) } @@ -1017,7 +1060,10 @@ fn command_set_manager( } }; - let mut transaction = Transaction::new_with_payer( + let mut signers = vec![config.fee_payer.as_ref(), config.manager.as_ref()]; + unique_signers!(signers); + let transaction = checked_transaction_with_signers( + config, &[spl_stake_pool::instruction::set_manager( &spl_stake_pool::id(), stake_pool_address, @@ -1025,14 +1071,8 @@ fn command_set_manager( &new_manager, &new_fee_receiver, )], - Some(&config.fee_payer.pubkey()), - ); - - let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_fee_payer_balance(config, fee_calculator.calculate_fee(transaction.message()))?; - let mut signers = vec![config.fee_payer.as_ref(), config.manager.as_ref()]; - unique_signers!(signers); - transaction.sign(&signers, recent_blockhash); + &signers, + )?; send_transaction(config, transaction)?; Ok(()) } @@ -1042,41 +1082,35 @@ fn command_set_staker( stake_pool_address: &Pubkey, new_staker: &Pubkey, ) -> CommandResult { - let mut transaction = Transaction::new_with_payer( + let mut signers = vec![config.fee_payer.as_ref(), config.manager.as_ref()]; + unique_signers!(signers); + let transaction = checked_transaction_with_signers( + config, &[spl_stake_pool::instruction::set_staker( &spl_stake_pool::id(), stake_pool_address, &config.manager.pubkey(), new_staker, )], - Some(&config.fee_payer.pubkey()), - ); - - let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_fee_payer_balance(config, fee_calculator.calculate_fee(transaction.message()))?; - let mut signers = vec![config.fee_payer.as_ref(), config.manager.as_ref()]; - unique_signers!(signers); - transaction.sign(&signers, recent_blockhash); + &signers, + )?; send_transaction(config, transaction)?; Ok(()) } fn command_set_fee(config: &Config, stake_pool_address: &Pubkey, new_fee: Fee) -> CommandResult { - let mut transaction = Transaction::new_with_payer( + let mut signers = vec![config.fee_payer.as_ref(), config.manager.as_ref()]; + unique_signers!(signers); + let transaction = checked_transaction_with_signers( + config, &[spl_stake_pool::instruction::set_fee( &spl_stake_pool::id(), stake_pool_address, &config.manager.pubkey(), new_fee, )], - Some(&config.fee_payer.pubkey()), - ); - - let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_fee_payer_balance(config, fee_calculator.calculate_fee(transaction.message()))?; - let mut signers = vec![config.fee_payer.as_ref(), config.manager.as_ref()]; - unique_signers!(signers); - transaction.sign(&signers, recent_blockhash); + &signers, + )?; send_transaction(config, transaction)?; Ok(()) } diff --git a/program/src/instruction.rs b/program/src/instruction.rs index ee6426f5..a1b013cc 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -738,7 +738,7 @@ pub fn update_stake_pool( validator_list: &ValidatorList, stake_pool_address: &Pubkey, no_merge: bool, -) -> Vec { +) -> (Vec, Instruction) { let vote_accounts: Vec = validator_list .validators .iter() @@ -748,10 +748,10 @@ pub fn update_stake_pool( let (withdraw_authority, _) = find_withdraw_authority_program_address(program_id, stake_pool_address); - let mut instructions: Vec = vec![]; + let mut update_list_instructions: Vec = vec![]; let mut start_index = 0; for accounts_chunk in vote_accounts.chunks(MAX_VALIDATORS_TO_UPDATE) { - instructions.push(update_validator_list_balance( + update_list_instructions.push(update_validator_list_balance( program_id, stake_pool_address, &withdraw_authority, @@ -764,7 +764,7 @@ pub fn update_stake_pool( start_index += MAX_VALIDATORS_TO_UPDATE as u32; } - instructions.push(update_stake_pool_balance( + let update_balance_instruction = update_stake_pool_balance( program_id, stake_pool_address, &withdraw_authority, @@ -772,8 +772,8 @@ pub fn update_stake_pool( &stake_pool.reserve_stake, &stake_pool.manager_fee_account, &stake_pool.pool_mint, - )); - instructions + ); + (update_list_instructions, update_balance_instruction) } /// Creates instructions required to deposit into a stake pool, given a stake diff --git a/program/src/lib.rs b/program/src/lib.rs index 98a8bc1c..6ac5c788 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -33,7 +33,7 @@ pub const MINIMUM_ACTIVE_STAKE: u64 = LAMPORTS_PER_SOL; /// Maximum amount of validator stake accounts to update per /// `UpdateValidatorListBalance` instruction, based on compute limits -pub const MAX_VALIDATORS_TO_UPDATE: usize = 9; +pub const MAX_VALIDATORS_TO_UPDATE: usize = 5; /// Get the stake amount under consideration when calculating pool token /// conversions From 1716532debd808a1e6046570800f4f4163d8f003 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Jul 2021 11:44:21 +0000 Subject: [PATCH 0122/1076] build(deps): bump proptest from 0.10.1 to 1.0.0 (#2007) Bumps [proptest](https://github.com/altsysrq/proptest) from 0.10.1 to 1.0.0. - [Release notes](https://github.com/altsysrq/proptest/releases) - [Changelog](https://github.com/AltSysrq/proptest/blob/master/CHANGELOG.md) - [Commits](https://github.com/altsysrq/proptest/compare/v0.10.1...1.0.0) --- updated-dependencies: - dependency-name: proptest dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 18c34b61..dc410d07 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -25,7 +25,7 @@ thiserror = "1.0" bincode = "1.3.1" [dev-dependencies] -proptest = "0.10" +proptest = "1.0" solana-program-test = "1.7.3" solana-sdk = "1.7.3" solana-vote-program = "1.7.3" From 39a681b3b03f2f7e5312481716274e7d5bdb781f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Jul 2021 11:57:51 +0000 Subject: [PATCH 0123/1076] build(deps): bump serde from 1.0.125 to 1.0.126 (#2008) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.125 to 1.0.126. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.125...v1.0.126) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index dc410d07..16b7c075 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,7 +17,7 @@ borsh = "0.8" num-derive = "0.3" num-traits = "0.2" num_enum = "0.5.1" -serde = "1.0.121" +serde = "1.0.126" serde_derive = "1.0.103" solana-program = "1.7.3" spl-token = { version = "3.1", path = "../../token/program", features = [ "no-entrypoint" ] } From e5f5acb5079d63718447a221fd99be4c0c7d5ffd Mon Sep 17 00:00:00 2001 From: Tyera Eulberg Date: Fri, 2 Jul 2021 10:53:41 -0600 Subject: [PATCH 0124/1076] Bump solana and borsh crates (#2015) --- clients/cli/Cargo.toml | 16 ++++++++-------- program/Cargo.toml | 10 +++++----- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index a620968d..c1e59502 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -9,16 +9,16 @@ repository = "https://github.com/solana-labs/solana-program-library" version = "0.3.0" [dependencies] -borsh = "0.8" +borsh = "0.9" clap = "2.33.3" serde_json = "1.0.62" -solana-account-decoder = "=1.7.3" -solana-clap-utils = "=1.7.3" -solana-cli-config = "=1.7.3" -solana-client = "=1.7.3" -solana-logger = "=1.7.3" -solana-sdk = "=1.7.3" -solana-program = "=1.7.3" +solana-account-decoder = "=1.7.4" +solana-clap-utils = "=1.7.4" +solana-cli-config = "=1.7.4" +solana-client = "=1.7.4" +solana-logger = "=1.7.4" +solana-sdk = "=1.7.4" +solana-program = "=1.7.4" spl-associated-token-account = { version = "1.0", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "0.3", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "3.1", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/program/Cargo.toml b/program/Cargo.toml index 16b7c075..6ecddf58 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -13,22 +13,22 @@ test-bpf = [] [dependencies] arrayref = "0.3.6" -borsh = "0.8" +borsh = "0.9" num-derive = "0.3" num-traits = "0.2" num_enum = "0.5.1" serde = "1.0.126" serde_derive = "1.0.103" -solana-program = "1.7.3" +solana-program = "1.7.4" spl-token = { version = "3.1", path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" bincode = "1.3.1" [dev-dependencies] proptest = "1.0" -solana-program-test = "1.7.3" -solana-sdk = "1.7.3" -solana-vote-program = "1.7.3" +solana-program-test = "1.7.4" +solana-sdk = "1.7.4" +solana-vote-program = "1.7.4" [lib] crate-type = ["cdylib", "lib"] From 8f67bed7b121f15e10c68da5b29d181a4e4b30e6 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 8 Jul 2021 22:50:28 +0200 Subject: [PATCH 0125/1076] stake-pool: Optimizations for 4k validators (#2041) * In-place serde * Add cleanup instruction * Add BigVec tests, clarify lifetimes --- clients/cli/src/main.rs | 6 +- program/src/big_vec.rs | 375 ++++++++++ program/src/instruction.rs | 62 +- program/src/lib.rs | 1 + program/src/processor.rs | 282 ++++--- program/src/state.rs | 252 ++++++- program/tests/helpers/mod.rs | 24 + program/tests/huge_pool.rs | 704 ++++++++++++++++++ program/tests/initialize.rs | 2 +- program/tests/set_preferred.rs | 59 +- .../tests/update_validator_list_balance.rs | 23 +- program/tests/vsa_add.rs | 8 +- program/tests/vsa_remove.rs | 39 +- 13 files changed, 1602 insertions(+), 235 deletions(-) create mode 100644 program/src/big_vec.rs create mode 100644 program/tests/huge_pool.rs diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index ff9340de..fc377694 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -697,7 +697,7 @@ fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { ); println!( "Max number of validators: {}", - validator_list.max_validators + validator_list.header.max_validators ); if config.verbose { @@ -755,7 +755,7 @@ fn command_update( let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?; - let (mut update_list_instructions, update_balance_instruction) = + let (mut update_list_instructions, final_instructions) = spl_stake_pool::instruction::update_stake_pool( &spl_stake_pool::id(), &stake_pool, @@ -787,7 +787,7 @@ fn command_update( } let transaction = checked_transaction_with_signers( config, - &[update_balance_instruction], + &final_instructions, &[config.fee_payer.as_ref()], )?; send_transaction(config, transaction)?; diff --git a/program/src/big_vec.rs b/program/src/big_vec.rs new file mode 100644 index 00000000..0c0f81a6 --- /dev/null +++ b/program/src/big_vec.rs @@ -0,0 +1,375 @@ +//! Big vector type, used with vectors that can't be serde'd + +use { + arrayref::array_ref, + borsh::{BorshDeserialize, BorshSerialize}, + solana_program::{ + program_error::ProgramError, program_memory::sol_memmove, program_pack::Pack, + }, + std::marker::PhantomData, +}; + +/// Contains easy to use utilities for a big vector of Borsh-compatible types, +/// to avoid managing the entire struct on-chain and blow through stack limits. +pub struct BigVec<'data> { + /// Underlying data buffer, pieces of which are serialized + pub data: &'data mut [u8], +} + +const VEC_SIZE_BYTES: usize = 4; + +impl<'data> BigVec<'data> { + /// Get the length of the vector + pub fn len(&self) -> u32 { + let vec_len = array_ref![self.data, 0, VEC_SIZE_BYTES]; + u32::from_le_bytes(*vec_len) + } + + /// Find out if the vector has no contents (as demanded by clippy) + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + /// Retain all elements that match the provided function, discard all others + pub fn retain(&mut self, predicate: fn(&[u8]) -> bool) -> Result<(), ProgramError> { + let mut vec_len = self.len(); + let mut removals_found = 0; + let mut dst_start_index = 0; + + let data_start_index = VEC_SIZE_BYTES; + let data_end_index = + data_start_index.saturating_add((vec_len as usize).saturating_mul(T::LEN)); + for start_index in (data_start_index..data_end_index).step_by(T::LEN) { + let end_index = start_index + T::LEN; + let slice = &self.data[start_index..end_index]; + if !predicate(slice) { + let gap = removals_found * T::LEN; + if removals_found > 0 { + // In case the compute budget is ever bumped up, allowing us + // to use this safe code instead: + // self.data.copy_within(dst_start_index + gap..start_index, dst_start_index); + unsafe { + sol_memmove( + self.data[dst_start_index..start_index - gap].as_mut_ptr(), + self.data[dst_start_index + gap..start_index].as_mut_ptr(), + start_index - gap - dst_start_index, + ); + } + } + dst_start_index = start_index - gap; + removals_found += 1; + vec_len -= 1; + } + } + + // final memmove + if removals_found > 0 { + let gap = removals_found * T::LEN; + // In case the compute budget is ever bumped up, allowing us + // to use this safe code instead: + //self.data.copy_within(dst_start_index + gap..data_end_index, dst_start_index); + unsafe { + sol_memmove( + self.data[dst_start_index..data_end_index - gap].as_mut_ptr(), + self.data[dst_start_index + gap..data_end_index].as_mut_ptr(), + data_end_index - gap - dst_start_index, + ); + } + } + + let mut vec_len_ref = &mut self.data[0..VEC_SIZE_BYTES]; + vec_len.serialize(&mut vec_len_ref)?; + + Ok(()) + } + + /// Extracts a slice of the data types + pub fn deserialize_mut_slice( + &mut self, + skip: usize, + len: usize, + ) -> Result, ProgramError> { + let vec_len = self.len(); + if skip + len > vec_len as usize { + return Err(ProgramError::AccountDataTooSmall); + } + + let start_index = VEC_SIZE_BYTES.saturating_add(skip.saturating_mul(T::LEN)); + let end_index = start_index.saturating_add(len.saturating_mul(T::LEN)); + let mut deserialized = vec![]; + for slice in self.data[start_index..end_index].chunks_exact_mut(T::LEN) { + deserialized.push(unsafe { &mut *(slice.as_ptr() as *mut T) }); + } + Ok(deserialized) + } + + /// Add new element to the end + pub fn push(&mut self, element: T) -> Result<(), ProgramError> { + let mut vec_len_ref = &mut self.data[0..VEC_SIZE_BYTES]; + let mut vec_len = u32::try_from_slice(vec_len_ref)?; + + let start_index = VEC_SIZE_BYTES + vec_len as usize * T::LEN; + let end_index = start_index + T::LEN; + + vec_len += 1; + vec_len.serialize(&mut vec_len_ref)?; + + if self.data.len() < end_index { + return Err(ProgramError::AccountDataTooSmall); + } + let mut element_ref = &mut self.data[start_index..start_index + T::LEN]; + element.pack_into_slice(&mut element_ref); + Ok(()) + } + + /// Get an iterator for the type provided + pub fn iter<'vec, T: Pack>(&'vec self) -> Iter<'data, 'vec, T> { + Iter { + len: self.len() as usize, + current: 0, + current_index: VEC_SIZE_BYTES, + inner: self, + phantom: PhantomData, + } + } + + /// Get a mutable iterator for the type provided + pub fn iter_mut<'vec, T: Pack>(&'vec mut self) -> IterMut<'data, 'vec, T> { + IterMut { + len: self.len() as usize, + current: 0, + current_index: VEC_SIZE_BYTES, + inner: self, + phantom: PhantomData, + } + } + + /// Find matching data in the array + pub fn find(&self, data: &[u8], predicate: fn(&[u8], &[u8]) -> bool) -> Option<&T> { + let len = self.len() as usize; + let mut current = 0; + let mut current_index = VEC_SIZE_BYTES; + while current != len { + let end_index = current_index + T::LEN; + let current_slice = &self.data[current_index..end_index]; + if predicate(current_slice, data) { + return Some(unsafe { &*(current_slice.as_ptr() as *const T) }); + } + current_index = end_index; + current += 1; + } + None + } + + /// Find matching data in the array + pub fn find_mut( + &mut self, + data: &[u8], + predicate: fn(&[u8], &[u8]) -> bool, + ) -> Option<&mut T> { + let len = self.len() as usize; + let mut current = 0; + let mut current_index = VEC_SIZE_BYTES; + while current != len { + let end_index = current_index + T::LEN; + let current_slice = &self.data[current_index..end_index]; + if predicate(current_slice, data) { + return Some(unsafe { &mut *(current_slice.as_ptr() as *mut T) }); + } + current_index = end_index; + current += 1; + } + None + } +} + +/// Iterator wrapper over a BigVec +pub struct Iter<'data, 'vec, T> { + len: usize, + current: usize, + current_index: usize, + inner: &'vec BigVec<'data>, + phantom: PhantomData, +} + +impl<'data, 'vec, T: Pack + 'data> Iterator for Iter<'data, 'vec, T> { + type Item = &'data T; + + fn next(&mut self) -> Option { + if self.current == self.len { + None + } else { + let end_index = self.current_index + T::LEN; + let value = Some(unsafe { + &*(self.inner.data[self.current_index..end_index].as_ptr() as *const T) + }); + self.current += 1; + self.current_index = end_index; + value + } + } +} + +/// Iterator wrapper over a BigVec +pub struct IterMut<'data, 'vec, T> { + len: usize, + current: usize, + current_index: usize, + inner: &'vec mut BigVec<'data>, + phantom: PhantomData, +} + +impl<'data, 'vec, T: Pack + 'data> Iterator for IterMut<'data, 'vec, T> { + type Item = &'data mut T; + + fn next(&mut self) -> Option { + if self.current == self.len { + None + } else { + let end_index = self.current_index + T::LEN; + let value = Some(unsafe { + &mut *(self.inner.data[self.current_index..end_index].as_ptr() as *mut T) + }); + self.current += 1; + self.current_index = end_index; + value + } + } +} + +#[cfg(test)] +mod tests { + use { + super::*, + solana_program::{program_memory::sol_memcmp, program_pack::Sealed}, + }; + + #[derive(Debug, PartialEq)] + struct TestStruct { + value: u64, + } + + impl Sealed for TestStruct {} + + impl Pack for TestStruct { + const LEN: usize = 8; + fn pack_into_slice(&self, data: &mut [u8]) { + let mut data = data; + self.value.serialize(&mut data).unwrap(); + } + fn unpack_from_slice(src: &[u8]) -> Result { + Ok(TestStruct { + value: u64::try_from_slice(src).unwrap(), + }) + } + } + + impl TestStruct { + fn new(value: u64) -> Self { + Self { value } + } + } + + fn from_slice<'data, 'other>(data: &'data mut [u8], vec: &'other [u64]) -> BigVec<'data> { + let mut big_vec = BigVec { data }; + for element in vec { + big_vec.push(TestStruct::new(*element)).unwrap(); + } + big_vec + } + + fn check_big_vec_eq(big_vec: &BigVec, slice: &[u64]) { + assert!(big_vec + .iter::() + .map(|x| &x.value) + .zip(slice.iter()) + .all(|(a, b)| a == b)); + } + + #[test] + fn push() { + let mut data = [0u8; 4 + 8 * 3]; + let mut v = BigVec { data: &mut data }; + v.push(TestStruct::new(1)).unwrap(); + check_big_vec_eq(&v, &[1]); + v.push(TestStruct::new(2)).unwrap(); + check_big_vec_eq(&v, &[1, 2]); + v.push(TestStruct::new(3)).unwrap(); + check_big_vec_eq(&v, &[1, 2, 3]); + assert_eq!( + v.push(TestStruct::new(4)).unwrap_err(), + ProgramError::AccountDataTooSmall + ); + } + + #[test] + fn retain() { + fn mod_2_predicate(data: &[u8]) -> bool { + u64::try_from_slice(data).unwrap() % 2 == 0 + } + + let mut data = [0u8; 4 + 8 * 4]; + let mut v = from_slice(&mut data, &[1, 2, 3, 4]); + v.retain::(mod_2_predicate).unwrap(); + check_big_vec_eq(&v, &[2, 4]); + } + + fn find_predicate(a: &[u8], b: &[u8]) -> bool { + if a.len() != b.len() { + false + } else { + sol_memcmp(a, b, a.len()) == 0 + } + } + + #[test] + fn find() { + let mut data = [0u8; 4 + 8 * 4]; + let v = from_slice(&mut data, &[1, 2, 3, 4]); + assert_eq!( + v.find::(&1u64.to_le_bytes(), find_predicate), + Some(&TestStruct::new(1)) + ); + assert_eq!( + v.find::(&4u64.to_le_bytes(), find_predicate), + Some(&TestStruct::new(4)) + ); + assert_eq!( + v.find::(&5u64.to_le_bytes(), find_predicate), + None + ); + } + + #[test] + fn find_mut() { + let mut data = [0u8; 4 + 8 * 4]; + let mut v = from_slice(&mut data, &[1, 2, 3, 4]); + let mut test_struct = v + .find_mut::(&1u64.to_le_bytes(), find_predicate) + .unwrap(); + test_struct.value = 0; + check_big_vec_eq(&v, &[0, 2, 3, 4]); + assert_eq!( + v.find_mut::(&5u64.to_le_bytes(), find_predicate), + None + ); + } + + #[test] + fn deserialize_mut_slice() { + let mut data = [0u8; 4 + 8 * 4]; + let mut v = from_slice(&mut data, &[1, 2, 3, 4]); + let mut slice = v.deserialize_mut_slice::(1, 2).unwrap(); + slice[0].value = 10; + slice[1].value = 11; + check_big_vec_eq(&v, &[1, 10, 11, 4]); + assert_eq!( + v.deserialize_mut_slice::(1, 4).unwrap_err(), + ProgramError::AccountDataTooSmall + ); + assert_eq!( + v.deserialize_mut_slice::(4, 1).unwrap_err(), + ProgramError::AccountDataTooSmall + ); + } +} diff --git a/program/src/instruction.rs b/program/src/instruction.rs index a1b013cc..0e2e6dc8 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -176,9 +176,9 @@ pub enum StakePoolInstruction { /// between SOL staked on different validators, the staker can force all /// deposits and/or withdraws to go to one chosen account, or unset that account. /// - /// 0. `[]` Stake pool + /// 0. `[w]` Stake pool /// 1. `[s]` Stake pool staker - /// 2. `[w]` Validator list + /// 2. `[]` Validator list /// /// Fails if the validator is not part of the stake pool. SetPreferredValidator { @@ -231,6 +231,12 @@ pub enum StakePoolInstruction { /// 7. `[]` Pool token program UpdateStakePoolBalance, + /// Cleans up validator stake account entries marked as `ReadyForRemoval` + /// + /// 0. `[]` Stake pool + /// 1. `[w]` Validator stake list storage account + CleanupRemovedValidatorEntries, + /// Deposit some stake into the pool. The output is a "pool" token representing ownership /// into the pool. Inputs are converted to the current ratio. /// @@ -515,9 +521,9 @@ pub fn set_preferred_validator( Instruction { program_id: *program_id, accounts: vec![ - AccountMeta::new_readonly(*stake_pool_address, false), + AccountMeta::new(*stake_pool_address, false), AccountMeta::new_readonly(*staker, true), - AccountMeta::new(*validator_list_address, false), + AccountMeta::new_readonly(*validator_list_address, false), ], data: StakePoolInstruction::SetPreferredValidator { validator_type, @@ -730,6 +736,25 @@ pub fn update_stake_pool_balance( } } +/// Creates `CleanupRemovedValidatorEntries` instruction (removes entries from the validator list) +pub fn cleanup_removed_validator_entries( + program_id: &Pubkey, + stake_pool: &Pubkey, + validator_list_storage: &Pubkey, +) -> Instruction { + let accounts = vec![ + AccountMeta::new_readonly(*stake_pool, false), + AccountMeta::new(*validator_list_storage, false), + ]; + Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::CleanupRemovedValidatorEntries + .try_to_vec() + .unwrap(), + } +} + /// Creates all `UpdateValidatorListBalance` and `UpdateStakePoolBalance` /// instructions for fully updating a stake pool each epoch pub fn update_stake_pool( @@ -738,7 +763,7 @@ pub fn update_stake_pool( validator_list: &ValidatorList, stake_pool_address: &Pubkey, no_merge: bool, -) -> (Vec, Instruction) { +) -> (Vec, Vec) { let vote_accounts: Vec = validator_list .validators .iter() @@ -764,16 +789,23 @@ pub fn update_stake_pool( start_index += MAX_VALIDATORS_TO_UPDATE as u32; } - let update_balance_instruction = update_stake_pool_balance( - program_id, - stake_pool_address, - &withdraw_authority, - &stake_pool.validator_list, - &stake_pool.reserve_stake, - &stake_pool.manager_fee_account, - &stake_pool.pool_mint, - ); - (update_list_instructions, update_balance_instruction) + let final_instructions = vec![ + update_stake_pool_balance( + program_id, + stake_pool_address, + &withdraw_authority, + &stake_pool.validator_list, + &stake_pool.reserve_stake, + &stake_pool.manager_fee_account, + &stake_pool.pool_mint, + ), + cleanup_removed_validator_entries( + program_id, + stake_pool_address, + &stake_pool.validator_list, + ), + ]; + (update_list_instructions, final_instructions) } /// Creates instructions required to deposit into a stake pool, given a stake diff --git a/program/src/lib.rs b/program/src/lib.rs index 6ac5c788..fbbd05c5 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -2,6 +2,7 @@ //! A program for creating and managing pools of stake +pub mod big_vec; pub mod error; pub mod instruction; pub mod processor; diff --git a/program/src/processor.rs b/program/src/processor.rs index acc1ee0a..674ea2d3 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -6,7 +6,10 @@ use { find_deposit_authority_program_address, instruction::{PreferredValidatorType, StakePoolInstruction}, minimum_reserve_lamports, minimum_stake_lamports, stake_program, - state::{AccountType, Fee, StakePool, StakeStatus, ValidatorList, ValidatorStakeInfo}, + state::{ + AccountType, Fee, StakePool, StakeStatus, ValidatorList, ValidatorListHeader, + ValidatorStakeInfo, + }, AUTHORITY_DEPOSIT, AUTHORITY_WITHDRAW, MINIMUM_ACTIVE_STAKE, TRANSIENT_STAKE_SEED, }, borsh::{BorshDeserialize, BorshSerialize}, @@ -480,7 +483,7 @@ impl Processor { check_account_owner(validator_list_info, program_id)?; let mut validator_list = try_from_slice_unchecked::(&validator_list_info.data.borrow())?; - if !validator_list.is_uninitialized() { + if !validator_list.header.is_uninitialized() { msg!("Provided validator list already in use"); return Err(StakePoolError::AlreadyInUse.into()); } @@ -495,11 +498,9 @@ impl Processor { ); return Err(StakePoolError::UnexpectedValidatorListAccountSize.into()); } - validator_list.account_type = AccountType::ValidatorList; - validator_list.preferred_deposit_validator_vote_address = None; - validator_list.preferred_withdraw_validator_vote_address = None; + validator_list.header.account_type = AccountType::ValidatorList; + validator_list.header.max_validators = max_validators; validator_list.validators.clear(); - validator_list.max_validators = max_validators; if !rent.is_exempt(stake_pool_info.lamports(), stake_pool_info.data_len()) { msg!("Stake pool not rent-exempt"); @@ -610,6 +611,8 @@ impl Processor { stake_pool.total_stake_lamports = total_stake_lamports; stake_pool.fee = fee; stake_pool.next_epoch_fee = None; + stake_pool.preferred_deposit_validator_vote_address = None; + stake_pool.preferred_withdraw_validator_vote_address = None; stake_pool .serialize(&mut *stake_pool_info.data.borrow_mut()) @@ -746,12 +749,13 @@ impl Processor { } check_account_owner(validator_list_info, program_id)?; - let mut validator_list = - try_from_slice_unchecked::(&validator_list_info.data.borrow())?; - if !validator_list.is_valid() { + let mut validator_list_data = validator_list_info.data.borrow_mut(); + let (header, mut validator_list) = + ValidatorListHeader::deserialize_vec(&mut validator_list_data)?; + if !header.is_valid() { return Err(StakePoolError::InvalidState.into()); } - if validator_list.max_validators as usize == validator_list.validators.len() { + if header.max_validators == validator_list.len() { return Err(ProgramError::AccountDataTooSmall); } @@ -769,7 +773,11 @@ impl Processor { return Err(StakePoolError::WrongStakeState.into()); } - if validator_list.contains(&vote_account_address) { + let maybe_validator_stake_info = validator_list.find::( + vote_account_address.as_ref(), + ValidatorStakeInfo::memcmp_pubkey, + ); + if maybe_validator_stake_info.is_some() { return Err(StakePoolError::ValidatorAlreadyAdded.into()); } @@ -797,14 +805,13 @@ impl Processor { stake_program_info.clone(), )?; - validator_list.validators.push(ValidatorStakeInfo { + validator_list.push(ValidatorStakeInfo { status: StakeStatus::Active, vote_account_address, active_stake_lamports: stake_lamports.saturating_sub(minimum_lamport_amount), transient_stake_lamports: 0, last_update_epoch: clock.epoch, - }); - validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; + })?; Ok(()) } @@ -829,7 +836,7 @@ impl Processor { check_stake_program(stake_program_info.key)?; check_account_owner(stake_pool_info, program_id)?; - let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; + let mut stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); } @@ -848,9 +855,10 @@ impl Processor { stake_pool.check_validator_list(validator_list_info)?; check_account_owner(validator_list_info, program_id)?; - let mut validator_list = - try_from_slice_unchecked::(&validator_list_info.data.borrow())?; - if !validator_list.is_valid() { + let mut validator_list_data = validator_list_info.data.borrow_mut(); + let (header, mut validator_list) = + ValidatorListHeader::deserialize_vec(&mut validator_list_data)?; + if !header.is_valid() { return Err(StakePoolError::InvalidState.into()); } @@ -869,15 +877,17 @@ impl Processor { &vote_account_address, )?; - let maybe_validator_list_entry = validator_list.find_mut(&vote_account_address); - if maybe_validator_list_entry.is_none() { + let maybe_validator_stake_info = validator_list.find_mut::( + vote_account_address.as_ref(), + ValidatorStakeInfo::memcmp_pubkey, + ); + if maybe_validator_stake_info.is_none() { msg!( "Vote account {} not found in stake pool", vote_account_address ); return Err(StakePoolError::ValidatorNotFound.into()); } - let mut validator_list_entry = maybe_validator_list_entry.unwrap(); let stake_lamports = **stake_account_info.lamports.borrow(); let required_lamports = minimum_stake_lamports(&meta); @@ -919,21 +929,16 @@ impl Processor { stake_program_info.clone(), )?; - match new_status { - StakeStatus::DeactivatingTransient => validator_list_entry.status = new_status, - StakeStatus::ReadyForRemoval => validator_list - .validators - .retain(|item| item.vote_account_address != vote_account_address), - _ => unreachable!(), - } + let mut validator_stake_info = maybe_validator_stake_info.unwrap(); + validator_stake_info.status = new_status; - if validator_list.preferred_deposit_validator_vote_address == Some(vote_account_address) { - validator_list.preferred_deposit_validator_vote_address = None; + if stake_pool.preferred_deposit_validator_vote_address == Some(vote_account_address) { + stake_pool.preferred_deposit_validator_vote_address = None; } - if validator_list.preferred_withdraw_validator_vote_address == Some(vote_account_address) { - validator_list.preferred_withdraw_validator_vote_address = None; + if stake_pool.preferred_withdraw_validator_vote_address == Some(vote_account_address) { + stake_pool.preferred_withdraw_validator_vote_address = None; } - validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; + stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; Ok(()) } @@ -981,9 +986,10 @@ impl Processor { stake_pool.check_validator_list(validator_list_info)?; check_account_owner(validator_list_info, program_id)?; - let mut validator_list = - try_from_slice_unchecked::(&validator_list_info.data.borrow())?; - if !validator_list.is_valid() { + let validator_list_data = &mut *validator_list_info.data.borrow_mut(); + let (validator_list_header, mut validator_list) = + ValidatorListHeader::deserialize_vec(validator_list_data)?; + if !validator_list_header.is_valid() { return Err(StakePoolError::InvalidState.into()); } @@ -1009,15 +1015,18 @@ impl Processor { &[transient_stake_bump_seed], ]; - let maybe_validator_list_entry = validator_list.find_mut(&vote_account_address); - if maybe_validator_list_entry.is_none() { + let maybe_validator_stake_info = validator_list.find_mut::( + vote_account_address.as_ref(), + ValidatorStakeInfo::memcmp_pubkey, + ); + if maybe_validator_stake_info.is_none() { msg!( "Vote account {} not found in stake pool", vote_account_address ); return Err(StakePoolError::ValidatorNotFound.into()); } - let mut validator_list_entry = maybe_validator_list_entry.unwrap(); + let mut validator_stake_info = maybe_validator_stake_info.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); if lamports <= stake_rent { @@ -1056,12 +1065,11 @@ impl Processor { stake_pool.withdraw_bump_seed, )?; - validator_list_entry.active_stake_lamports = validator_list_entry + validator_stake_info.active_stake_lamports = validator_stake_info .active_stake_lamports .checked_sub(lamports) .ok_or(StakePoolError::CalculationFailure)?; - validator_list_entry.transient_stake_lamports = lamports; - validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; + validator_stake_info.transient_stake_lamports = lamports; Ok(()) } @@ -1114,9 +1122,10 @@ impl Processor { stake_pool.check_reserve_stake(reserve_stake_account_info)?; check_account_owner(validator_list_info, program_id)?; - let mut validator_list = - try_from_slice_unchecked::(&validator_list_info.data.borrow())?; - if !validator_list.is_valid() { + let mut validator_list_data = validator_list_info.data.borrow_mut(); + let (header, mut validator_list) = + ValidatorListHeader::deserialize_vec(&mut validator_list_data)?; + if !header.is_valid() { return Err(StakePoolError::InvalidState.into()); } @@ -1134,17 +1143,20 @@ impl Processor { &[transient_stake_bump_seed], ]; - let maybe_validator_list_entry = validator_list.find_mut(vote_account_address); - if maybe_validator_list_entry.is_none() { + let maybe_validator_stake_info = validator_list.find_mut::( + vote_account_address.as_ref(), + ValidatorStakeInfo::memcmp_pubkey, + ); + if maybe_validator_stake_info.is_none() { msg!( "Vote account {} not found in stake pool", vote_account_address ); return Err(StakePoolError::ValidatorNotFound.into()); } - let mut validator_list_entry = maybe_validator_list_entry.unwrap(); + let mut validator_stake_info = maybe_validator_stake_info.unwrap(); - if validator_list_entry.status != StakeStatus::Active { + if validator_stake_info.status != StakeStatus::Active { msg!("Validator is marked for removal and no longer allows increases"); return Err(StakePoolError::ValidatorNotFound.into()); } @@ -1208,8 +1220,7 @@ impl Processor { stake_pool.withdraw_bump_seed, )?; - validator_list_entry.transient_stake_lamports = total_lamports; - validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; + validator_stake_info.transient_stake_lamports = total_lamports; Ok(()) } @@ -1229,7 +1240,7 @@ impl Processor { check_account_owner(stake_pool_info, program_id)?; check_account_owner(validator_list_info, program_id)?; - let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; + let mut stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { msg!("Expected valid stake pool"); return Err(StakePoolError::InvalidState.into()); @@ -1238,14 +1249,19 @@ impl Processor { stake_pool.check_staker(staker_info)?; stake_pool.check_validator_list(validator_list_info)?; - let mut validator_list = - try_from_slice_unchecked::(&validator_list_info.data.borrow())?; - if !validator_list.is_valid() { + let mut validator_list_data = validator_list_info.data.borrow_mut(); + let (header, validator_list) = + ValidatorListHeader::deserialize_vec(&mut validator_list_data)?; + if !header.is_valid() { return Err(StakePoolError::InvalidState.into()); } if let Some(vote_account_address) = vote_account_address { - if !validator_list.contains(&vote_account_address) { + let maybe_validator_stake_info = validator_list.find::( + vote_account_address.as_ref(), + ValidatorStakeInfo::memcmp_pubkey, + ); + if maybe_validator_stake_info.is_none() { msg!("Validator for {} not present in the stake pool, cannot set as preferred deposit account"); return Err(StakePoolError::ValidatorNotFound.into()); } @@ -1253,13 +1269,13 @@ impl Processor { match validator_type { PreferredValidatorType::Deposit => { - validator_list.preferred_deposit_validator_vote_address = vote_account_address + stake_pool.preferred_deposit_validator_vote_address = vote_account_address } PreferredValidatorType::Withdraw => { - validator_list.preferred_withdraw_validator_vote_address = vote_account_address + stake_pool.preferred_withdraw_validator_vote_address = vote_account_address } }; - validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; + stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; Ok(()) } @@ -1296,17 +1312,20 @@ impl Processor { check_stake_program(stake_program_info.key)?; check_account_owner(validator_list_info, program_id)?; - let mut validator_list = - try_from_slice_unchecked::(&validator_list_info.data.borrow())?; - if !validator_list.is_valid() { + let mut validator_list_data = validator_list_info.data.borrow_mut(); + let (validator_list_header, mut validator_slice) = + ValidatorListHeader::deserialize_mut_slice( + &mut validator_list_data, + start_index as usize, + validator_stake_accounts.len() / 2, + )?; + + if !validator_list_header.is_valid() { return Err(StakePoolError::InvalidState.into()); } - let mut changes = false; - let validator_iter = &mut validator_list - .validators + let validator_iter = &mut validator_slice .iter_mut() - .skip(start_index as usize) .zip(validator_stake_accounts.chunks_exact(2)); for (validator_stake_record, validator_stakes) in validator_iter { // chunks_exact means that we always get 2 elements, making this safe @@ -1485,11 +1504,6 @@ impl Processor { validator_stake_record.last_update_epoch = clock.epoch; validator_stake_record.active_stake_lamports = active_stake_lamports; validator_stake_record.transient_stake_lamports = transient_stake_lamports; - changes = true; - } - - if changes { - validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; } Ok(()) @@ -1531,9 +1545,10 @@ impl Processor { } check_account_owner(validator_list_info, program_id)?; - let mut validator_list = - try_from_slice_unchecked::(&validator_list_info.data.borrow())?; - if !validator_list.is_valid() { + let mut validator_list_data = validator_list_info.data.borrow_mut(); + let (header, validator_list) = + ValidatorListHeader::deserialize_vec(&mut validator_list_data)?; + if !header.is_valid() { return Err(StakePoolError::InvalidState.into()); } @@ -1551,7 +1566,7 @@ impl Processor { msg!("Reserve stake account in unknown state, aborting"); return Err(StakePoolError::WrongStakeState.into()); }; - for validator_stake_record in &validator_list.validators { + for validator_stake_record in validator_list.iter::() { if validator_stake_record.last_update_epoch < clock.epoch { return Err(StakePoolError::StakeListOutOfDate.into()); } @@ -1587,10 +1602,6 @@ impl Processor { stake_pool.fee = next_epoch_fee; stake_pool.next_epoch_fee = None; } - validator_list - .validators - .retain(|item| item.status != StakeStatus::ReadyForRemoval); - validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; stake_pool.total_stake_lamports = total_stake_lamports; stake_pool.last_update_epoch = clock.epoch; stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; @@ -1598,6 +1609,35 @@ impl Processor { Ok(()) } + /// Processes the `CleanupRemovedValidatorEntries` instruction + fn process_cleanup_removed_validator_entries( + program_id: &Pubkey, + accounts: &[AccountInfo], + ) -> ProgramResult { + let account_info_iter = &mut accounts.iter(); + let stake_pool_info = next_account_info(account_info_iter)?; + let validator_list_info = next_account_info(account_info_iter)?; + + check_account_owner(stake_pool_info, program_id)?; + let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; + if !stake_pool.is_valid() { + return Err(StakePoolError::InvalidState.into()); + } + stake_pool.check_validator_list(validator_list_info)?; + + check_account_owner(validator_list_info, program_id)?; + let mut validator_list_data = validator_list_info.data.borrow_mut(); + let (header, mut validator_list) = + ValidatorListHeader::deserialize_vec(&mut validator_list_data)?; + if !header.is_valid() { + return Err(StakePoolError::InvalidState.into()); + } + + validator_list.retain::(ValidatorStakeInfo::is_not_removed)?; + + Ok(()) + } + /// Check stake activation status #[allow(clippy::unnecessary_wraps)] fn _check_stake_activation( @@ -1673,9 +1713,10 @@ impl Processor { } check_account_owner(validator_list_info, program_id)?; - let mut validator_list = - try_from_slice_unchecked::(&validator_list_info.data.borrow())?; - if !validator_list.is_valid() { + let mut validator_list_data = validator_list_info.data.borrow_mut(); + let (header, mut validator_list) = + ValidatorListHeader::deserialize_vec(&mut validator_list_data)?; + if !header.is_valid() { return Err(StakePoolError::InvalidState.into()); } @@ -1688,17 +1729,25 @@ impl Processor { validator_stake_account_info.key, &vote_account_address, )?; - if let Some(preferred_deposit) = validator_list.preferred_deposit_validator_vote_address { + if let Some(preferred_deposit) = stake_pool.preferred_deposit_validator_vote_address { if preferred_deposit != vote_account_address { + msg!( + "Incorrect deposit address, expected {}, received {}", + preferred_deposit, + vote_account_address + ); return Err(StakePoolError::IncorrectDepositVoteAddress.into()); } } - let validator_list_item = validator_list - .find_mut(&vote_account_address) + let mut validator_stake_info = validator_list + .find_mut::( + vote_account_address.as_ref(), + ValidatorStakeInfo::memcmp_pubkey, + ) .ok_or(StakePoolError::ValidatorNotFound)?; - if validator_list_item.status != StakeStatus::Active { + if validator_stake_info.status != StakeStatus::Active { msg!("Validator is marked for removal and no longer accepting deposits"); return Err(StakePoolError::ValidatorNotFound.into()); } @@ -1795,12 +1844,11 @@ impl Processor { .ok_or(StakePoolError::CalculationFailure)?; stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; - validator_list_item.active_stake_lamports = post_validator_stake + validator_stake_info.active_stake_lamports = post_validator_stake .delegation .stake .checked_sub(MINIMUM_ACTIVE_STAKE) .ok_or(StakePoolError::CalculationFailure)?; - validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; Ok(()) } @@ -1850,9 +1898,10 @@ impl Processor { } check_account_owner(validator_list_info, program_id)?; - let mut validator_list = - try_from_slice_unchecked::(&validator_list_info.data.borrow())?; - if !validator_list.is_valid() { + let mut validator_list_data = validator_list_info.data.borrow_mut(); + let (header, mut validator_list) = + ValidatorListHeader::deserialize_vec(&mut validator_list_data)?; + if !header.is_valid() { return Err(StakePoolError::InvalidState.into()); } @@ -1860,19 +1909,23 @@ impl Processor { .calc_lamports_withdraw_amount(pool_tokens) .ok_or(StakePoolError::CalculationFailure)?; + let has_active_stake = validator_list + .find::( + &0u64.to_le_bytes(), + ValidatorStakeInfo::memcmp_active_lamports, + ) + .is_some(); + let validator_list_item_info = if *stake_split_from.key == stake_pool.reserve_stake { // check that the validator stake accounts have no withdrawable stake - if let Some(withdrawable_entry) = validator_list - .validators - .iter() - .find(|&&x| x.stake_lamports() != 0) - { - let (validator_stake_address, _) = crate::find_stake_program_address( - program_id, - &withdrawable_entry.vote_account_address, - stake_pool_info.key, - ); - msg!("Error withdrawing from reserve: validator stake account {} has {} lamports available, please use that first.", validator_stake_address, withdrawable_entry.stake_lamports()); + let has_transient_stake = validator_list + .find::( + &0u64.to_le_bytes(), + ValidatorStakeInfo::memcmp_transient_lamports, + ) + .is_some(); + if has_transient_stake || has_active_stake { + msg!("Error withdrawing from reserve: validator stake accounts have lamports available, please use those first."); return Err(StakePoolError::StakeLamportsNotEqualToMinimum.into()); } @@ -1891,10 +1944,13 @@ impl Processor { let vote_account_address = stake.delegation.voter_pubkey; if let Some(preferred_withdraw_validator) = - validator_list.preferred_withdraw_validator_vote_address + stake_pool.preferred_withdraw_validator_vote_address { let preferred_validator_info = validator_list - .find(&preferred_withdraw_validator) + .find::( + preferred_withdraw_validator.as_ref(), + ValidatorStakeInfo::memcmp_pubkey, + ) .ok_or(StakePoolError::ValidatorNotFound)?; if preferred_withdraw_validator != vote_account_address && preferred_validator_info.active_stake_lamports > 0 @@ -1906,7 +1962,7 @@ impl Processor { // if there's any active stake, we must withdraw from an active // stake account - let withdrawing_from_transient_stake = if validator_list.has_active_stake() { + let withdrawing_from_transient_stake = if has_active_stake { check_validator_stake_address( program_id, stake_pool_info.key, @@ -1924,11 +1980,14 @@ impl Processor { true }; - let validator_list_item = validator_list - .find_mut(&vote_account_address) + let validator_stake_info = validator_list + .find_mut::( + vote_account_address.as_ref(), + ValidatorStakeInfo::memcmp_pubkey, + ) .ok_or(StakePoolError::ValidatorNotFound)?; - if validator_list_item.status != StakeStatus::Active { + if validator_stake_info.status != StakeStatus::Active { msg!("Validator is marked for removal and no longer allowing withdrawals"); return Err(StakePoolError::ValidatorNotFound.into()); } @@ -1938,7 +1997,7 @@ impl Processor { msg!("Attempting to withdraw {} lamports from validator account with {} stake lamports, {} must remain", withdraw_lamports, stake.delegation.stake, MINIMUM_ACTIVE_STAKE); return Err(StakePoolError::StakeLamportsNotEqualToMinimum.into()); } - Some((validator_list_item, withdrawing_from_transient_stake)) + Some((validator_stake_info, withdrawing_from_transient_stake)) }; Self::token_burn( @@ -1994,7 +2053,6 @@ impl Processor { .checked_sub(withdraw_lamports) .ok_or(StakePoolError::CalculationFailure)?; } - validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; } Ok(()) @@ -2146,6 +2204,10 @@ impl Processor { msg!("Instruction: UpdateStakePoolBalance"); Self::process_update_stake_pool_balance(program_id, accounts) } + StakePoolInstruction::CleanupRemovedValidatorEntries => { + msg!("Instruction: CleanupRemovedValidatorEntries"); + Self::process_cleanup_removed_validator_entries(program_id, accounts) + } StakePoolInstruction::Deposit => { msg!("Instruction: Deposit"); Self::process_deposit(program_id, accounts) diff --git a/program/src/state.rs b/program/src/state.rs index 36ee0988..a547b89f 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -1,9 +1,19 @@ //! State transition types use { - crate::{error::StakePoolError, stake_program::Lockup}, + crate::{big_vec::BigVec, error::StakePoolError, stake_program::Lockup}, borsh::{BorshDeserialize, BorshSchema, BorshSerialize}, - solana_program::{account_info::AccountInfo, msg, program_error::ProgramError, pubkey::Pubkey}, + num_derive::FromPrimitive, + num_traits::FromPrimitive, + solana_program::{ + account_info::AccountInfo, + borsh::get_instance_packed_len, + msg, + program_error::ProgramError, + program_memory::sol_memcmp, + program_pack::{Pack, Sealed}, + pubkey::{Pubkey, PUBKEY_BYTES}, + }, std::convert::TryFrom, }; @@ -87,6 +97,12 @@ pub struct StakePool { /// Fee for next epoch pub next_epoch_fee: Option, + + /// Preferred deposit validator vote account pubkey + pub preferred_deposit_validator_vote_address: Option, + + /// Preferred withdraw validator vote account pubkey + pub preferred_withdraw_validator_vote_address: Option, } impl StakePool { /// calculate the pool tokens that should be minted for a deposit of `stake_lamports` @@ -281,24 +297,28 @@ impl StakePool { #[repr(C)] #[derive(Clone, Debug, Default, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)] pub struct ValidatorList { - /// Account type, must be ValidatorList currently - pub account_type: AccountType, + /// Data outside of the validator list, separated out for cheaper deserializations + pub header: ValidatorListHeader, - /// Preferred deposit validator vote account pubkey - pub preferred_deposit_validator_vote_address: Option, + /// List of stake info for each validator in the pool + pub validators: Vec, +} - /// Preferred withdraw validator vote account pubkey - pub preferred_withdraw_validator_vote_address: Option, +/// Helper type to deserialize just the start of a ValidatorList +#[repr(C)] +#[derive(Clone, Debug, Default, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)] +pub struct ValidatorListHeader { + /// Account type, must be ValidatorList currently + pub account_type: AccountType, /// Maximum allowable number of validators pub max_validators: u32, - - /// List of stake info for each validator in the pool - pub validators: Vec, } /// Status of the stake account in the validator list, for accounting -#[derive(Copy, Clone, Debug, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)] +#[derive( + FromPrimitive, Copy, Clone, Debug, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema, +)] pub enum StakeStatus { /// Stake account is active, there may be a transient stake as well Active, @@ -316,10 +336,10 @@ impl Default for StakeStatus { } } -/// Information about the singe validator stake account -#[repr(C)] -#[derive(Clone, Copy, Debug, Default, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)] -pub struct ValidatorStakeInfo { +/// Packed version of the validator stake info, for use with pointer casts +#[repr(packed)] +#[derive(Clone, Copy, Debug, Default, PartialEq)] +pub struct ValidatorStakeInfoPacked { /// Status of the validator stake account pub status: StakeStatus, @@ -340,6 +360,37 @@ pub struct ValidatorStakeInfo { pub last_update_epoch: u64, } +/// Information about a validator in the pool +/// +/// NOTE: ORDER IS VERY IMPORTANT HERE, PLEASE DO NOT RE-ORDER THE FIELDS UNLESS +/// THERE'S AN EXTREMELY GOOD REASON. +/// +/// To save on BPF instructions, the serialized bytes are reinterpreted with an +/// unsafe pointer cast, which means that this structure cannot have any +/// undeclared alignment-padding in its representation. +#[repr(C)] +#[derive(Clone, Copy, Debug, Default, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)] +pub struct ValidatorStakeInfo { + /// Amount of active stake delegated to this validator + /// Note that if `last_update_epoch` does not match the current epoch then + /// this field may not be accurate + pub active_stake_lamports: u64, + + /// Amount of transient stake delegated to this validator + /// Note that if `last_update_epoch` does not match the current epoch then + /// this field may not be accurate + pub transient_stake_lamports: u64, + + /// Last epoch the active and transient stake lamports fields were updated + pub last_update_epoch: u64, + + /// Status of the validator stake account + pub status: StakeStatus, + + /// Validator vote account address + pub vote_account_address: Pubkey, +} + impl ValidatorStakeInfo { /// Get the total lamports delegated to this validator (active and transient) pub fn stake_lamports(&self) -> u64 { @@ -347,24 +398,65 @@ impl ValidatorStakeInfo { .checked_add(self.transient_stake_lamports) .unwrap() } + + /// Performs a very cheap comparison, for checking if this validator stake + /// info matches the vote account address + pub fn memcmp_pubkey(data: &[u8], vote_address_bytes: &[u8]) -> bool { + sol_memcmp( + &data[25..25 + PUBKEY_BYTES], + vote_address_bytes, + PUBKEY_BYTES, + ) == 0 + } + + /// Performs a very cheap comparison, for checking if this validator stake + /// info has active lamports equal to the given bytes + pub fn memcmp_active_lamports(data: &[u8], lamports_le_bytes: &[u8]) -> bool { + sol_memcmp(&data[0..8], lamports_le_bytes, 8) != 0 + } + + /// Performs a very cheap comparison, for checking if this validator stake + /// info has lamports equal to the given bytes + pub fn memcmp_transient_lamports(data: &[u8], lamports_le_bytes: &[u8]) -> bool { + sol_memcmp(&data[8..16], lamports_le_bytes, 8) != 0 + } + + /// Check that the validator stake info is valid + pub fn is_not_removed(data: &[u8]) -> bool { + FromPrimitive::from_u8(data[24]) != Some(StakeStatus::ReadyForRemoval) + } +} + +impl Sealed for ValidatorStakeInfo {} + +impl Pack for ValidatorStakeInfo { + const LEN: usize = 57; + fn pack_into_slice(&self, data: &mut [u8]) { + let mut data = data; + self.serialize(&mut data).unwrap(); + } + fn unpack_from_slice(src: &[u8]) -> Result { + let unpacked = Self::try_from_slice(src)?; + Ok(unpacked) + } } impl ValidatorList { /// Create an empty instance containing space for `max_validators` and preferred validator keys pub fn new(max_validators: u32) -> Self { Self { - account_type: AccountType::ValidatorList, - preferred_deposit_validator_vote_address: Some(Pubkey::default()), - preferred_withdraw_validator_vote_address: Some(Pubkey::default()), - max_validators, + header: ValidatorListHeader { + account_type: AccountType::ValidatorList, + max_validators, + }, validators: vec![ValidatorStakeInfo::default(); max_validators as usize], } } /// Calculate the number of validator entries that fit in the provided length pub fn calculate_max_validators(buffer_length: usize) -> usize { - let header_size = 1 + 4 + 4 + 33 + 33; - buffer_length.saturating_sub(header_size) / 57 + let header_size = ValidatorListHeader::LEN + 4; + buffer_length.saturating_sub(header_size) / ValidatorStakeInfo::LEN } /// Check if contains validator with particular pubkey @@ -387,6 +479,15 @@ impl ValidatorList { .find(|x| x.vote_account_address == *vote_account_address) } + /// Check if the list has any active stake + pub fn has_active_stake(&self) -> bool { + self.validators.iter().any(|x| x.active_stake_lamports > 0) + } +} + +impl ValidatorListHeader { + const LEN: usize = 1 + 4; + /// Check if validator stake list is actually initialized as a validator stake list pub fn is_valid(&self) -> bool { self.account_type == AccountType::ValidatorList @@ -397,9 +498,28 @@ impl ValidatorList { self.account_type == AccountType::Uninitialized } - /// Check if the list has any active stake - pub fn has_active_stake(&self) -> bool { - self.validators.iter().any(|x| x.active_stake_lamports > 0) + /// Extracts a slice of ValidatorStakeInfo types from the vec part + /// of the ValidatorList + pub fn deserialize_mut_slice( + data: &mut [u8], + skip: usize, + len: usize, + ) -> Result<(Self, Vec<&mut ValidatorStakeInfo>), ProgramError> { + let (header, mut big_vec) = Self::deserialize_vec(data)?; + let validator_list = big_vec.deserialize_mut_slice::(skip, len)?; + Ok((header, validator_list)) + } + + /// Extracts the validator list into its header and internal BigVec + pub fn deserialize_vec(data: &mut [u8]) -> Result<(Self, BigVec), ProgramError> { + let mut data_mut = &data[..]; + let header = ValidatorListHeader::deserialize(&mut data_mut)?; + let length = get_instance_packed_len(&header)?; + + let big_vec = BigVec { + data: &mut data[length..], + }; + Ok((header, big_vec)) } } @@ -427,20 +547,20 @@ mod test { fn uninitialized_validator_list() -> ValidatorList { ValidatorList { - account_type: AccountType::Uninitialized, - preferred_deposit_validator_vote_address: None, - preferred_withdraw_validator_vote_address: None, - max_validators: 0, + header: ValidatorListHeader { + account_type: AccountType::Uninitialized, + max_validators: 0, + }, validators: vec![], } } fn test_validator_list(max_validators: u32) -> ValidatorList { ValidatorList { - account_type: AccountType::ValidatorList, - preferred_deposit_validator_vote_address: Some(Pubkey::new_unique()), - preferred_withdraw_validator_vote_address: Some(Pubkey::new_unique()), - max_validators, + header: ValidatorListHeader { + account_type: AccountType::ValidatorList, + max_validators, + }, validators: vec![ ValidatorStakeInfo { status: StakeStatus::Active, @@ -480,10 +600,10 @@ mod test { // Empty, one preferred key let stake_list = ValidatorList { - account_type: AccountType::ValidatorList, - preferred_deposit_validator_vote_address: Some(Pubkey::new_unique()), - preferred_withdraw_validator_vote_address: None, - max_validators: 0, + header: ValidatorListHeader { + account_type: AccountType::ValidatorList, + max_validators: 0, + }, validators: vec![], }; let mut byte_vec = vec![0u8; size]; @@ -512,6 +632,64 @@ mod test { assert!(!validator_list.has_active_stake()); } + #[test] + fn validator_list_deserialize_mut_slice() { + let max_validators = 10; + let stake_list = test_validator_list(max_validators); + let mut serialized = stake_list.try_to_vec().unwrap(); + let (header, list) = ValidatorListHeader::deserialize_mut_slice( + &mut serialized, + 0, + stake_list.validators.len(), + ) + .unwrap(); + assert_eq!(header.account_type, AccountType::ValidatorList); + assert_eq!(header.max_validators, max_validators); + assert!(list + .iter() + .zip(stake_list.validators.iter()) + .all(|(a, b)| *a == b)); + + let (_, list) = ValidatorListHeader::deserialize_mut_slice(&mut serialized, 1, 2).unwrap(); + assert!(list + .iter() + .zip(stake_list.validators[1..].iter()) + .all(|(a, b)| *a == b)); + let (_, list) = ValidatorListHeader::deserialize_mut_slice(&mut serialized, 2, 1).unwrap(); + assert!(list + .iter() + .zip(stake_list.validators[2..].iter()) + .all(|(a, b)| *a == b)); + let (_, list) = ValidatorListHeader::deserialize_mut_slice(&mut serialized, 0, 2).unwrap(); + assert!(list + .iter() + .zip(stake_list.validators[..2].iter()) + .all(|(a, b)| *a == b)); + + assert_eq!( + ValidatorListHeader::deserialize_mut_slice(&mut serialized, 0, 4).unwrap_err(), + ProgramError::AccountDataTooSmall + ); + assert_eq!( + ValidatorListHeader::deserialize_mut_slice(&mut serialized, 1, 3).unwrap_err(), + ProgramError::AccountDataTooSmall + ); + } + + #[test] + fn validator_list_iter() { + let max_validators = 10; + let stake_list = test_validator_list(max_validators); + let mut serialized = stake_list.try_to_vec().unwrap(); + let (_, big_vec) = ValidatorListHeader::deserialize_vec(&mut serialized).unwrap(); + for (a, b) in big_vec + .iter::() + .zip(stake_list.validators.iter()) + { + assert_eq!(a, b); + } + } + proptest! { #[test] fn stake_list_size_calculation(test_amount in 0..=100_000_u32) { diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index a9bb39d3..3d561b07 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -735,6 +735,25 @@ impl StakePoolAccounts { banks_client.process_transaction(transaction).await.err() } + pub async fn cleanup_removed_validator_entries( + &self, + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + ) -> Option { + let transaction = Transaction::new_signed_with_payer( + &[instruction::cleanup_removed_validator_entries( + &id(), + &self.stake_pool.pubkey(), + &self.validator_list.pubkey(), + )], + Some(&payer.pubkey()), + &[payer], + *recent_blockhash, + ); + banks_client.process_transaction(transaction).await.err() + } + pub async fn update_all( &self, banks_client: &mut BanksClient, @@ -764,6 +783,11 @@ impl StakePoolAccounts { &self.pool_fee_account.pubkey(), &self.pool_mint.pubkey(), ), + instruction::cleanup_removed_validator_entries( + &id(), + &self.stake_pool.pubkey(), + &self.validator_list.pubkey(), + ), ], Some(&payer.pubkey()), &[payer], diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs new file mode 100644 index 00000000..e3199281 --- /dev/null +++ b/program/tests/huge_pool.rs @@ -0,0 +1,704 @@ +#![cfg(feature = "test-bpf")] + +mod helpers; + +use { + bincode, + borsh::BorshSerialize, + helpers::*, + solana_program::{ + borsh::try_from_slice_unchecked, program_option::COption, program_pack::Pack, + pubkey::Pubkey, + }, + solana_program_test::*, + solana_sdk::{ + account::{Account, WritableAccount}, + clock::{Clock, Epoch}, + signature::{Keypair, Signer}, + transaction::Transaction, + }, + solana_vote_program::{ + self, + vote_state::{VoteInit, VoteState, VoteStateVersions}, + }, + spl_stake_pool::{ + find_stake_program_address, find_transient_stake_program_address, + find_withdraw_authority_program_address, id, + instruction::{self, PreferredValidatorType}, + stake_program, + state::{AccountType, StakePool, StakeStatus, ValidatorList, ValidatorStakeInfo}, + MAX_VALIDATORS_TO_UPDATE, MINIMUM_ACTIVE_STAKE, + }, + spl_token::state::{Account as SplAccount, AccountState as SplAccountState, Mint}, +}; + +const HUGE_POOL_SIZE: u32 = 4_000; +const ACCOUNT_RENT_EXEMPTION: u64 = 1_000_000_000; // go with something big to be safe +const STAKE_AMOUNT: u64 = 200_000_000_000; +const STAKE_ACCOUNT_RENT_EXEMPTION: u64 = 2_282_880; + +async fn setup( + max_validators: u32, + num_validators: u32, + stake_amount: u64, +) -> ( + ProgramTestContext, + StakePoolAccounts, + Vec, + Pubkey, + Keypair, + Pubkey, + Pubkey, +) { + let mut program_test = program_test(); + let mut vote_account_pubkeys = vec![]; + let mut stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts.max_validators = max_validators; + + let stake_pool_pubkey = stake_pool_accounts.stake_pool.pubkey(); + let (_, withdraw_bump_seed) = + find_withdraw_authority_program_address(&id(), &stake_pool_pubkey); + + let mut stake_pool = StakePool { + account_type: AccountType::StakePool, + manager: stake_pool_accounts.manager.pubkey(), + staker: stake_pool_accounts.staker.pubkey(), + deposit_authority: stake_pool_accounts.deposit_authority, + withdraw_bump_seed, + validator_list: stake_pool_accounts.validator_list.pubkey(), + reserve_stake: stake_pool_accounts.reserve_stake.pubkey(), + pool_mint: stake_pool_accounts.pool_mint.pubkey(), + manager_fee_account: stake_pool_accounts.pool_fee_account.pubkey(), + token_program_id: spl_token::id(), + total_stake_lamports: 0, + pool_token_supply: 0, + last_update_epoch: 0, + lockup: stake_program::Lockup::default(), + fee: stake_pool_accounts.fee, + next_epoch_fee: None, + preferred_deposit_validator_vote_address: None, + preferred_withdraw_validator_vote_address: None, + }; + + let mut validator_list = ValidatorList::new(max_validators); + validator_list.validators = vec![]; + + let authorized_voter = Pubkey::new_unique(); + let authorized_withdrawer = Pubkey::new_unique(); + let commission = 1; + + let meta = stake_program::Meta { + rent_exempt_reserve: STAKE_ACCOUNT_RENT_EXEMPTION, + authorized: stake_program::Authorized { + staker: stake_pool_accounts.withdraw_authority, + withdrawer: stake_pool_accounts.withdraw_authority, + }, + lockup: stake_program::Lockup::default(), + }; + + for _ in 0..max_validators { + // create vote account + let vote_pubkey = Pubkey::new_unique(); + vote_account_pubkeys.push(vote_pubkey); + let node_pubkey = Pubkey::new_unique(); + let vote_state = VoteStateVersions::new_current(VoteState::new( + &VoteInit { + node_pubkey, + authorized_voter, + authorized_withdrawer, + commission, + }, + &Clock::default(), + )); + let vote_account = Account::create( + ACCOUNT_RENT_EXEMPTION, + bincode::serialize::(&vote_state).unwrap(), + solana_vote_program::id(), + false, + Epoch::default(), + ); + program_test.add_account(vote_pubkey, vote_account); + } + + for i in 0..num_validators as usize { + let vote_account_address = vote_account_pubkeys[i]; + + // create validator stake account + let stake = stake_program::Stake { + delegation: stake_program::Delegation { + voter_pubkey: vote_account_address, + stake: stake_amount, + activation_epoch: 0, + deactivation_epoch: u64::MAX, + warmup_cooldown_rate: 0.25, // default + }, + credits_observed: 0, + }; + + let stake_account = Account::create( + stake_amount + STAKE_ACCOUNT_RENT_EXEMPTION, + bincode::serialize::(&stake_program::StakeState::Stake( + meta, stake, + )) + .unwrap(), + stake_program::id(), + false, + Epoch::default(), + ); + + let (stake_address, _) = + find_stake_program_address(&id(), &vote_account_address, &stake_pool_pubkey); + program_test.add_account(stake_address, stake_account); + let active_stake_lamports = stake_amount - MINIMUM_ACTIVE_STAKE; + // add to validator list + validator_list.validators.push(ValidatorStakeInfo { + status: StakeStatus::Active, + vote_account_address, + active_stake_lamports, + transient_stake_lamports: 0, + last_update_epoch: 0, + }); + + stake_pool.total_stake_lamports += active_stake_lamports; + stake_pool.pool_token_supply += active_stake_lamports; + } + + let mut validator_list_bytes = validator_list.try_to_vec().unwrap(); + + // add extra room if needed + for _ in num_validators..max_validators { + validator_list_bytes.append(&mut ValidatorStakeInfo::default().try_to_vec().unwrap()); + } + + let reserve_stake_account = Account::create( + stake_amount + STAKE_ACCOUNT_RENT_EXEMPTION, + bincode::serialize::(&stake_program::StakeState::Initialized( + meta, + )) + .unwrap(), + stake_program::id(), + false, + Epoch::default(), + ); + program_test.add_account( + stake_pool_accounts.reserve_stake.pubkey(), + reserve_stake_account, + ); + + let mut stake_pool_bytes = stake_pool.try_to_vec().unwrap(); + // more room for optionals + stake_pool_bytes.extend_from_slice(&Pubkey::default().to_bytes()); + stake_pool_bytes.extend_from_slice(&Pubkey::default().to_bytes()); + let stake_pool_account = Account::create( + ACCOUNT_RENT_EXEMPTION, + stake_pool_bytes, + id(), + false, + Epoch::default(), + ); + program_test.add_account(stake_pool_pubkey, stake_pool_account); + + let validator_list_account = Account::create( + ACCOUNT_RENT_EXEMPTION, + validator_list_bytes, + id(), + false, + Epoch::default(), + ); + program_test.add_account( + stake_pool_accounts.validator_list.pubkey(), + validator_list_account, + ); + + let mut mint_vec = vec![0u8; Mint::LEN]; + let mint = Mint { + mint_authority: COption::Some(stake_pool_accounts.withdraw_authority), + supply: stake_pool.pool_token_supply, + decimals: 9, + is_initialized: true, + freeze_authority: COption::None, + }; + Pack::pack(mint, &mut mint_vec).unwrap(); + let stake_pool_mint = Account::create( + ACCOUNT_RENT_EXEMPTION, + mint_vec, + spl_token::id(), + false, + Epoch::default(), + ); + program_test.add_account(stake_pool_accounts.pool_mint.pubkey(), stake_pool_mint); + + let mut fee_account_vec = vec![0u8; SplAccount::LEN]; + let fee_account_data = SplAccount { + mint: stake_pool_accounts.pool_mint.pubkey(), + owner: stake_pool_accounts.manager.pubkey(), + amount: 0, + delegate: COption::None, + state: SplAccountState::Initialized, + is_native: COption::None, + delegated_amount: 0, + close_authority: COption::None, + }; + Pack::pack(fee_account_data, &mut fee_account_vec).unwrap(); + let fee_account = Account::create( + ACCOUNT_RENT_EXEMPTION, + fee_account_vec, + spl_token::id(), + false, + Epoch::default(), + ); + program_test.add_account(stake_pool_accounts.pool_fee_account.pubkey(), fee_account); + + let mut context = program_test.start_with_context().await; + + let vote_pubkey = vote_account_pubkeys[HUGE_POOL_SIZE as usize - 1]; + // make stake account + let user = Keypair::new(); + let deposit_stake = Keypair::new(); + let lockup = stake_program::Lockup::default(); + + let authorized = stake_program::Authorized { + staker: user.pubkey(), + withdrawer: user.pubkey(), + }; + + let _stake_lamports = create_independent_stake_account( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &deposit_stake, + &authorized, + &lockup, + stake_amount, + ) + .await; + + delegate_stake_account( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &deposit_stake.pubkey(), + &user, + &vote_pubkey, + ) + .await; + + // make pool token account + let pool_token_account = Keypair::new(); + create_token_account( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &pool_token_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user.pubkey(), + ) + .await + .unwrap(); + + ( + context, + stake_pool_accounts, + vote_account_pubkeys, + vote_pubkey, + user, + deposit_stake.pubkey(), + pool_token_account.pubkey(), + ) +} + +#[tokio::test] +async fn update() { + let (mut context, stake_pool_accounts, vote_account_pubkeys, _, _, _, _) = + setup(HUGE_POOL_SIZE, HUGE_POOL_SIZE, STAKE_AMOUNT).await; + + let transaction = Transaction::new_signed_with_payer( + &[ + instruction::update_validator_list_balance( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), + &vote_account_pubkeys[0..MAX_VALIDATORS_TO_UPDATE], + 0, + /* no_merge = */ false, + ), + instruction::update_stake_pool_balance( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.pool_fee_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + ), + instruction::cleanup_removed_validator_entries( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + ), + ], + Some(&context.payer.pubkey()), + &[&context.payer], + context.last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err(); + assert!(error.is_none()); +} + +#[tokio::test] +async fn remove_validator_from_pool() { + let (mut context, stake_pool_accounts, vote_account_pubkeys, _, _, _, _) = + setup(HUGE_POOL_SIZE, HUGE_POOL_SIZE, MINIMUM_ACTIVE_STAKE).await; + + let first_vote = vote_account_pubkeys[0]; + let (stake_address, _) = + find_stake_program_address(&id(), &first_vote, &stake_pool_accounts.stake_pool.pubkey()); + let (transient_stake_address, _) = find_transient_stake_program_address( + &id(), + &first_vote, + &stake_pool_accounts.stake_pool.pubkey(), + ); + + let new_authority = Pubkey::new_unique(); + let error = stake_pool_accounts + .remove_validator_from_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &new_authority, + &stake_address, + &transient_stake_address, + ) + .await; + assert!(error.is_none()); + + let middle_index = HUGE_POOL_SIZE as usize / 2; + let middle_vote = vote_account_pubkeys[middle_index]; + let (stake_address, _) = find_stake_program_address( + &id(), + &middle_vote, + &stake_pool_accounts.stake_pool.pubkey(), + ); + let (transient_stake_address, _) = find_transient_stake_program_address( + &id(), + &middle_vote, + &stake_pool_accounts.stake_pool.pubkey(), + ); + + let new_authority = Pubkey::new_unique(); + let error = stake_pool_accounts + .remove_validator_from_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &new_authority, + &stake_address, + &transient_stake_address, + ) + .await; + assert!(error.is_none()); + + let last_index = HUGE_POOL_SIZE as usize - 1; + let last_vote = vote_account_pubkeys[last_index]; + let (stake_address, _) = + find_stake_program_address(&id(), &last_vote, &stake_pool_accounts.stake_pool.pubkey()); + let (transient_stake_address, _) = find_transient_stake_program_address( + &id(), + &last_vote, + &stake_pool_accounts.stake_pool.pubkey(), + ); + + let new_authority = Pubkey::new_unique(); + let error = stake_pool_accounts + .remove_validator_from_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &new_authority, + &stake_address, + &transient_stake_address, + ) + .await; + assert!(error.is_none()); + + let validator_list = get_account( + &mut context.banks_client, + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + let validator_list = + try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); + let first_element = &validator_list.validators[0]; + assert_eq!(first_element.status, StakeStatus::ReadyForRemoval); + assert_eq!(first_element.active_stake_lamports, 0); + assert_eq!(first_element.transient_stake_lamports, 0); + + let middle_element = &validator_list.validators[middle_index]; + assert_eq!(middle_element.status, StakeStatus::ReadyForRemoval); + assert_eq!(middle_element.active_stake_lamports, 0); + assert_eq!(middle_element.transient_stake_lamports, 0); + + let last_element = &validator_list.validators[last_index]; + assert_eq!(last_element.status, StakeStatus::ReadyForRemoval); + assert_eq!(last_element.active_stake_lamports, 0); + assert_eq!(last_element.transient_stake_lamports, 0); + + let transaction = Transaction::new_signed_with_payer( + &[instruction::cleanup_removed_validator_entries( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + )], + Some(&context.payer.pubkey()), + &[&context.payer], + context.last_blockhash, + ); + + let error = context + .banks_client + .process_transaction(transaction) + .await + .err(); + assert!(error.is_none()); + + let validator_list = get_account( + &mut context.banks_client, + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + let validator_list = + try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); + assert_eq!(validator_list.validators.len() as u32, HUGE_POOL_SIZE - 3); + // assert they're gone + assert!(!validator_list + .validators + .iter() + .any(|x| x.vote_account_address == first_vote)); + assert!(!validator_list + .validators + .iter() + .any(|x| x.vote_account_address == middle_vote)); + assert!(!validator_list + .validators + .iter() + .any(|x| x.vote_account_address == last_vote)); + + // but that we didn't remove too many + assert!(validator_list + .validators + .iter() + .any(|x| x.vote_account_address == vote_account_pubkeys[1])); + assert!(validator_list + .validators + .iter() + .any(|x| x.vote_account_address == vote_account_pubkeys[middle_index - 1])); + assert!(validator_list + .validators + .iter() + .any(|x| x.vote_account_address == vote_account_pubkeys[middle_index + 1])); + assert!(validator_list + .validators + .iter() + .any(|x| x.vote_account_address == vote_account_pubkeys[last_index - 1])); +} + +#[tokio::test] +async fn add_validator_to_pool() { + let (mut context, stake_pool_accounts, _, test_vote_address, _, _, _) = + setup(HUGE_POOL_SIZE, HUGE_POOL_SIZE - 1, STAKE_AMOUNT).await; + + let last_index = HUGE_POOL_SIZE as usize - 1; + let stake_pool_pubkey = stake_pool_accounts.stake_pool.pubkey(); + let (stake_address, _) = + find_stake_program_address(&id(), &test_vote_address, &stake_pool_pubkey); + + create_validator_stake_account( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_pubkey, + &stake_pool_accounts.staker, + &stake_address, + &test_vote_address, + ) + .await; + + let error = stake_pool_accounts + .add_validator_to_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_address, + ) + .await; + assert!(error.is_none()); + + let validator_list = get_account( + &mut context.banks_client, + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + let validator_list = + try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); + assert_eq!(validator_list.validators.len(), last_index + 1); + let last_element = validator_list.validators[last_index]; + assert_eq!(last_element.status, StakeStatus::Active); + assert_eq!(last_element.active_stake_lamports, 0); + assert_eq!(last_element.transient_stake_lamports, 0); + assert_eq!(last_element.vote_account_address, test_vote_address); + + let (transient_stake_address, _) = + find_transient_stake_program_address(&id(), &test_vote_address, &stake_pool_pubkey); + let increase_amount = MINIMUM_ACTIVE_STAKE; + let error = stake_pool_accounts + .increase_validator_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &transient_stake_address, + &test_vote_address, + increase_amount, + ) + .await; + assert!(error.is_none()); + + let validator_list = get_account( + &mut context.banks_client, + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + let validator_list = + try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); + let last_element = validator_list.validators[last_index]; + assert_eq!(last_element.status, StakeStatus::Active); + assert_eq!(last_element.active_stake_lamports, 0); + assert_eq!( + last_element.transient_stake_lamports, + increase_amount + STAKE_ACCOUNT_RENT_EXEMPTION + ); + assert_eq!(last_element.vote_account_address, test_vote_address); +} + +#[tokio::test] +async fn set_preferred() { + let (mut context, stake_pool_accounts, _, vote_account_address, _, _, _) = + setup(HUGE_POOL_SIZE, HUGE_POOL_SIZE, STAKE_AMOUNT).await; + + let error = stake_pool_accounts + .set_preferred_validator( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + PreferredValidatorType::Deposit, + Some(vote_account_address), + ) + .await; + assert!(error.is_none()); + let error = stake_pool_accounts + .set_preferred_validator( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + PreferredValidatorType::Withdraw, + Some(vote_account_address), + ) + .await; + assert!(error.is_none()); + + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + + assert_eq!( + stake_pool.preferred_deposit_validator_vote_address, + Some(vote_account_address) + ); + assert_eq!( + stake_pool.preferred_withdraw_validator_vote_address, + Some(vote_account_address) + ); +} + +#[tokio::test] +async fn deposit() { + let (mut context, stake_pool_accounts, _, vote_pubkey, user, stake_pubkey, pool_account_pubkey) = + setup(HUGE_POOL_SIZE, HUGE_POOL_SIZE, STAKE_AMOUNT).await; + + let (stake_address, _) = find_stake_program_address( + &id(), + &vote_pubkey, + &stake_pool_accounts.stake_pool.pubkey(), + ); + + let error = stake_pool_accounts + .deposit_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pubkey, + &pool_account_pubkey, + &stake_address, + &user, + ) + .await; + assert!(error.is_none()); +} + +#[tokio::test] +async fn withdraw() { + let (mut context, stake_pool_accounts, _, vote_pubkey, user, stake_pubkey, pool_account_pubkey) = + setup(HUGE_POOL_SIZE, HUGE_POOL_SIZE, STAKE_AMOUNT).await; + + let (stake_address, _) = find_stake_program_address( + &id(), + &vote_pubkey, + &stake_pool_accounts.stake_pool.pubkey(), + ); + + let error = stake_pool_accounts + .deposit_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pubkey, + &pool_account_pubkey, + &stake_address, + &user, + ) + .await; + assert!(error.is_none()); + + // Create stake account to withdraw to + let user_stake_recipient = Keypair::new(); + create_blank_stake_account( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user_stake_recipient, + ) + .await; + + let error = stake_pool_accounts + .withdraw_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user_stake_recipient.pubkey(), + &user, + &pool_account_pubkey, + &stake_address, + &user.pubkey(), + STAKE_AMOUNT, + ) + .await; + assert!(error.is_none()); +} diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index 7a20379d..0117d461 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -85,7 +85,7 @@ async fn success() { .await; let validator_list = try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); - assert!(validator_list.is_valid()); + assert!(validator_list.header.is_valid()); } #[tokio::test] diff --git a/program/tests/set_preferred.rs b/program/tests/set_preferred.rs index 338caa92..3400e9a0 100644 --- a/program/tests/set_preferred.rs +++ b/program/tests/set_preferred.rs @@ -16,7 +16,7 @@ use { spl_stake_pool::{ error, id, instruction::{self, PreferredValidatorType}, - state::ValidatorList, + state::StakePool, }, }; @@ -68,22 +68,14 @@ async fn success_deposit() { .await; assert!(error.is_none()); - let validator_list = get_account( - &mut banks_client, - &stake_pool_accounts.validator_list.pubkey(), - ) - .await; - let validator_list = - try_from_slice_unchecked::(&validator_list.data.as_slice()).unwrap(); + let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; + let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); assert_eq!( - validator_list.preferred_deposit_validator_vote_address, + stake_pool.preferred_deposit_validator_vote_address, Some(vote_account_address) ); - assert_eq!( - validator_list.preferred_withdraw_validator_vote_address, - None - ); + assert_eq!(stake_pool.preferred_withdraw_validator_vote_address, None); } #[tokio::test] @@ -104,20 +96,12 @@ async fn success_withdraw() { .await; assert!(error.is_none()); - let validator_list = get_account( - &mut banks_client, - &stake_pool_accounts.validator_list.pubkey(), - ) - .await; - let validator_list = - try_from_slice_unchecked::(&validator_list.data.as_slice()).unwrap(); + let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; + let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + assert_eq!(stake_pool.preferred_deposit_validator_vote_address, None); assert_eq!( - validator_list.preferred_deposit_validator_vote_address, - None - ); - assert_eq!( - validator_list.preferred_withdraw_validator_vote_address, + stake_pool.preferred_withdraw_validator_vote_address, Some(vote_account_address) ); } @@ -139,16 +123,11 @@ async fn success_unset() { .await; assert!(error.is_none()); - let validator_list = get_account( - &mut banks_client, - &stake_pool_accounts.validator_list.pubkey(), - ) - .await; - let validator_list = - try_from_slice_unchecked::(&validator_list.data.as_slice()).unwrap(); + let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; + let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); assert_eq!( - validator_list.preferred_withdraw_validator_vote_address, + stake_pool.preferred_withdraw_validator_vote_address, Some(vote_account_address) ); @@ -163,18 +142,10 @@ async fn success_unset() { .await; assert!(error.is_none()); - let validator_list = get_account( - &mut banks_client, - &stake_pool_accounts.validator_list.pubkey(), - ) - .await; - let validator_list = - try_from_slice_unchecked::(&validator_list.data.as_slice()).unwrap(); + let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; + let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); - assert_eq!( - validator_list.preferred_withdraw_validator_vote_address, - None - ); + assert_eq!(stake_pool.preferred_withdraw_validator_vote_address, None); } #[tokio::test] diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index b5e46dc7..f11095f8 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -82,11 +82,7 @@ async fn setup( &mut context.banks_client, &context.payer, &context.last_blockhash, - stake_accounts - .iter() - .map(|v| v.vote.pubkey()) - .collect::>() - .as_slice(), + &[], false, ) .await; @@ -229,7 +225,7 @@ async fn merge_into_reserve() { .unwrap(); let pre_reserve_lamports = reserve_stake.lamports; - // Decrease from all validators + println!("Decrease from all validators"); for stake_account in &stake_accounts { let error = stake_pool_accounts .decrease_validator_stake( @@ -244,7 +240,7 @@ async fn merge_into_reserve() { assert!(error.is_none()); } - // Update, should not change, no merges yet + println!("Update, should not change, no merges yet"); stake_pool_accounts .update_all( &mut context.banks_client, @@ -275,7 +271,7 @@ async fn merge_into_reserve() { let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data).unwrap(); assert_eq!(expected_lamports, stake_pool.total_stake_lamports); - // Warp one more epoch so the stakes deactivate + println!("Warp one more epoch so the stakes deactivate"); let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; slot += slots_per_epoch; context.warp_to_slot(slot).unwrap(); @@ -565,7 +561,7 @@ async fn merge_transient_stake_after_remove() { reserve_lamports + deactivated_lamports + 2 * stake_rent + 1 ); - // Update stake pool balance, should be gone + // Update stake pool balance and cleanup, should be gone let error = stake_pool_accounts .update_stake_pool_balance( &mut context.banks_client, @@ -575,6 +571,15 @@ async fn merge_transient_stake_after_remove() { .await; assert!(error.is_none()); + let error = stake_pool_accounts + .cleanup_removed_validator_entries( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; + assert!(error.is_none()); + let validator_list = get_account( &mut context.banks_client, &stake_pool_accounts.validator_list.pubkey(), diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index e72dd75d..8927b392 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -81,10 +81,10 @@ async fn success() { assert_eq!( validator_list, state::ValidatorList { - account_type: state::AccountType::ValidatorList, - preferred_deposit_validator_vote_address: None, - preferred_withdraw_validator_vote_address: None, - max_validators: stake_pool_accounts.max_validators, + header: state::ValidatorListHeader { + account_type: state::AccountType::ValidatorList, + max_validators: stake_pool_accounts.max_validators, + }, validators: vec![state::ValidatorStakeInfo { status: state::StakeStatus::Active, vote_account_address: user_stake.vote.pubkey(), diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 54e34e11..743cf888 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -83,6 +83,11 @@ async fn success() { .await; assert!(error.is_none()); + let error = stake_pool_accounts + .cleanup_removed_validator_entries(&mut banks_client, &payer, &recent_blockhash) + .await; + assert!(error.is_none()); + // Check if account was removed from the list of stake accounts let validator_list = get_account( &mut banks_client, @@ -94,10 +99,10 @@ async fn success() { assert_eq!( validator_list, state::ValidatorList { - account_type: state::AccountType::ValidatorList, - preferred_deposit_validator_vote_address: None, - preferred_withdraw_validator_vote_address: None, - max_validators: stake_pool_accounts.max_validators, + header: state::ValidatorListHeader { + account_type: state::AccountType::ValidatorList, + max_validators: stake_pool_accounts.max_validators, + }, validators: vec![] } ); @@ -254,6 +259,11 @@ async fn fail_double_remove() { .await; assert!(error.is_none()); + let error = stake_pool_accounts + .cleanup_removed_validator_entries(&mut banks_client, &payer, &recent_blockhash) + .await; + assert!(error.is_none()); + let latest_blockhash = banks_client.get_recent_blockhash().await.unwrap(); let transaction_error = stake_pool_accounts @@ -519,10 +529,10 @@ async fn success_with_deactivating_transient_stake() { let validator_list = try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); let expected_list = state::ValidatorList { - account_type: state::AccountType::ValidatorList, - preferred_deposit_validator_vote_address: None, - preferred_withdraw_validator_vote_address: None, - max_validators: stake_pool_accounts.max_validators, + header: state::ValidatorListHeader { + account_type: state::AccountType::ValidatorList, + max_validators: stake_pool_accounts.max_validators, + }, validators: vec![state::ValidatorStakeInfo { status: state::StakeStatus::DeactivatingTransient, vote_account_address: validator_stake.vote.pubkey(), @@ -592,6 +602,11 @@ async fn success_resets_preferred_validator() { .await; assert!(error.is_none()); + let error = stake_pool_accounts + .cleanup_removed_validator_entries(&mut banks_client, &payer, &recent_blockhash) + .await; + assert!(error.is_none()); + // Check if account was removed from the list of stake accounts let validator_list = get_account( &mut banks_client, @@ -603,10 +618,10 @@ async fn success_resets_preferred_validator() { assert_eq!( validator_list, state::ValidatorList { - account_type: state::AccountType::ValidatorList, - preferred_deposit_validator_vote_address: None, - preferred_withdraw_validator_vote_address: None, - max_validators: stake_pool_accounts.max_validators, + header: state::ValidatorListHeader { + account_type: state::AccountType::ValidatorList, + max_validators: stake_pool_accounts.max_validators, + }, validators: vec![] } ); From 156e5e7687a972e390abba1aeb88d337d262a4ca Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 9 Jul 2021 23:56:41 +0200 Subject: [PATCH 0126/1076] stake-pool-cli: Address feedback (#2057) * Fix signer parameters (staker, manager, depositor, fee-payer, and token-owner) * On deposit / withdraw / add / remove validator, show the validator stake account and where the stake is going to --- clients/cli/Cargo.toml | 3 +- clients/cli/src/main.rs | 165 +++++++++++++++++++++++----------------- 2 files changed, 99 insertions(+), 69 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index c1e59502..4104f43e 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -17,8 +17,9 @@ solana-clap-utils = "=1.7.4" solana-cli-config = "=1.7.4" solana-client = "=1.7.4" solana-logger = "=1.7.4" -solana-sdk = "=1.7.4" solana-program = "=1.7.4" +solana-remote-wallet = "=1.7.4" +solana-sdk = "=1.7.4" spl-associated-token-account = { version = "1.0", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "0.3", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "3.1", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index fc377694..ee6095fd 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -7,7 +7,7 @@ use { crate::client::*, clap::{ crate_description, crate_name, crate_version, value_t, value_t_or_exit, App, AppSettings, - Arg, ArgGroup, SubCommand, + Arg, ArgGroup, ArgMatches, SubCommand, }, solana_clap_utils::{ input_parsers::{keypair_of, pubkey_of}, @@ -23,6 +23,7 @@ use { program_pack::Pack, pubkey::Pubkey, }, + solana_remote_wallet::remote_wallet::RemoteWalletManager, solana_sdk::{ commitment_config::CommitmentConfig, native_token::{self, Sol}, @@ -38,7 +39,7 @@ use { stake_program::{self, StakeState}, state::{Fee, StakePool, ValidatorList}, }, - std::process::exit, + std::{process::exit, sync::Arc}, }; struct Config { @@ -83,6 +84,24 @@ fn check_fee_payer_balance(config: &Config, required_balance: u64) -> Result<(), } } +fn get_signer( + matches: &ArgMatches<'_>, + keypair_name: &str, + keypair_path: &str, + wallet_manager: &mut Option>, +) -> Box { + signer_from_path( + matches, + matches.value_of(keypair_name).unwrap_or(keypair_path), + keypair_name, + wallet_manager, + ) + .unwrap_or_else(|e| { + eprintln!("error: {}", e); + exit(1); + }) +} + fn send_transaction_no_wait( config: &Config, transaction: Transaction, @@ -316,16 +335,22 @@ fn command_vsa_create( stake_pool_address: &Pubkey, vote_account: &Pubkey, ) -> CommandResult { - println!("Creating stake account on {}", vote_account); + let (stake_account, _) = + find_stake_program_address(&spl_stake_pool::id(), vote_account, stake_pool_address); + println!( + "Creating stake account {}, delegated to {}", + stake_account, vote_account + ); let transaction = checked_transaction_with_signers( config, &[ // Create new validator stake account address - spl_stake_pool::instruction::create_validator_stake_account_with_vote( + spl_stake_pool::instruction::create_validator_stake_account( &spl_stake_pool::id(), stake_pool_address, &config.staker.pubkey(), &config.fee_payer.pubkey(), + &stake_account, vote_account, ), ], @@ -342,6 +367,10 @@ fn command_vsa_add( ) -> CommandResult { let (stake_account_address, _) = find_stake_program_address(&spl_stake_pool::id(), vote_account, stake_pool_address); + println!( + "Adding stake account {}, delegated to {}", + stake_account_address, vote_account + ); let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?; if validator_list.contains(vote_account) { @@ -399,6 +428,13 @@ fn command_vsa_remove( command_update(config, stake_pool_address, false, false)?; } + let (stake_account_address, _) = + find_stake_program_address(&spl_stake_pool::id(), vote_account, stake_pool_address); + println!( + "Removing stake account {}, delegated to {}", + stake_account_address, vote_account + ); + let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; let staker_pubkey = config.staker.pubkey(); @@ -522,7 +558,7 @@ fn add_associated_token_account( // Account for tokens not specified, creating one let account = get_associated_token_address(&config.fee_payer.pubkey(), mint); if get_token_account(&config.rpc_client, &account, mint).is_err() { - println!("Creating account to receive tokens {}", account); + println!("Creating associated token account {} to receive stake pool tokens of mint {}, owned by {}", account, mint, config.fee_payer.pubkey()); let min_account_balance = config .rpc_client @@ -536,6 +572,8 @@ fn add_associated_token_account( )); *rent_free_balances += min_account_balance; + } else { + println!("Using existing associated token account {} to receive stake pool tokens of mint {}, owned by {}", account, mint, config.fee_payer.pubkey()); } account @@ -573,7 +611,10 @@ fn command_deposit( find_stake_program_address(&spl_stake_pool::id(), &vote_account, stake_pool_address); let validator_stake_state = get_stake_state(&config.rpc_client, &validator_stake_account)?; - println!("Depositing into stake account {}", validator_stake_account); + println!( + "Depositing stake {} into stake pool account {}", + stake, validator_stake_account + ); if config.verbose { println!("{:?}", validator_stake_state); } @@ -797,7 +838,8 @@ fn command_update( #[derive(PartialEq, Debug)] struct WithdrawAccount { - address: Pubkey, + stake_address: Pubkey, + vote_address: Option, pool_amount: u64, } @@ -823,7 +865,7 @@ fn prepare_withdraw_accounts( let mut remaining_amount = pool_amount; // Go through available accounts and withdraw from largest to smallest - for (address, lamports, _) in accounts { + for (stake_address, lamports, stake) in accounts { if lamports <= min_balance { continue; } @@ -834,7 +876,8 @@ fn prepare_withdraw_accounts( // Those accounts will be withdrawn completely with `claim` instruction withdraw_from.push(WithdrawAccount { - address, + stake_address, + vote_address: stake.delegation().map(|x| x.voter_pubkey), pool_amount, }); remaining_amount -= pool_amount; @@ -898,7 +941,8 @@ fn command_withdraw( let withdraw_accounts = if use_reserve { vec![WithdrawAccount { - address: stake_pool.reserve_stake, + stake_address: stake_pool.reserve_stake, + vote_address: None, pool_amount, }] } else if let Some(vote_account_address) = vote_account_address { @@ -919,7 +963,8 @@ fn command_withdraw( .into()); } vec![WithdrawAccount { - address: stake_account_address, + stake_address: stake_account_address, + vote_address: Some(*vote_account_address), pool_amount, }] } else { @@ -940,7 +985,7 @@ fn command_withdraw( config.token_owner.as_ref(), &user_transfer_authority, ]; - let stake_receiver_account = Keypair::new(); // Will be added to signers if creating new account + let mut new_stake_keypairs = vec![]; instructions.push( // Approve spending token @@ -954,9 +999,6 @@ fn command_withdraw( )?, ); - // Use separate mutable variable because withdraw might create a new account - let mut stake_receiver: Option = *stake_receiver_param; - let mut total_rent_free_balances = 0; // Go through prepared accounts and withdraw/claim them @@ -967,48 +1009,52 @@ fn command_withdraw( .unwrap(); println!( - "Withdrawing from account {}, amount {}, {} pool tokens", - withdraw_account.address, + "Withdrawing {}, or {} pool tokens, from stake account {}, delegated to {:?}, stake / withdraw authority {}", Sol(sol_withdraw_amount), spl_token::amount_to_ui_amount(withdraw_account.pool_amount, pool_mint.decimals), + withdraw_account.stake_address, + withdraw_account.vote_address, + config.staker.pubkey(), ); - if stake_receiver.is_none() { + // Use separate mutable variable because withdraw might create a new account + let stake_receiver = stake_receiver_param.unwrap_or_else(|| { // Account for tokens not specified, creating one + let stake_receiver_account = Keypair::new(); // Will be added to signers if creating new account + let stake_receiver_pubkey = stake_receiver_account.pubkey(); println!( "Creating account to receive stake {}", - stake_receiver_account.pubkey() + stake_receiver_pubkey ); let stake_receiver_account_balance = config .rpc_client - .get_minimum_balance_for_rent_exemption(STAKE_STATE_LEN)?; + .get_minimum_balance_for_rent_exemption(STAKE_STATE_LEN) + .unwrap(); instructions.push( // Creating new account system_instruction::create_account( &config.fee_payer.pubkey(), - &stake_receiver_account.pubkey(), + &stake_receiver_pubkey, stake_receiver_account_balance, STAKE_STATE_LEN as u64, &stake_program::id(), ), ); - signers.push(&stake_receiver_account); - total_rent_free_balances += stake_receiver_account_balance; - - stake_receiver = Some(stake_receiver_account.pubkey()); - } + new_stake_keypairs.push(stake_receiver_account); + stake_receiver_pubkey + }); instructions.push(spl_stake_pool::instruction::withdraw( &spl_stake_pool::id(), stake_pool_address, &stake_pool.validator_list, &pool_withdraw_authority, - &withdraw_account.address, - &stake_receiver.unwrap(), // Cannot be none at this point + &withdraw_account.stake_address, + &stake_receiver, &config.staker.pubkey(), &user_transfer_authority.pubkey(), &pool_token_account, @@ -1026,6 +1072,9 @@ fn command_withdraw( config, total_rent_free_balances + fee_calculator.calculate_fee(transaction.message()), )?; + for new_stake_keypair in &new_stake_keypairs { + signers.push(new_stake_keypair); + } unique_signers!(signers); transaction.sign(&signers, recent_blockhash); send_transaction(config, transaction)?; @@ -1562,6 +1611,7 @@ fn main() { .validator(is_pubkey) .value_name("STAKE_ACCOUNT_ADDRESS") .takes_value(true) + .requires("withdraw_from") .help("Stake account to receive SOL from the stake pool. Defaults to a new stake account."), ) .arg( @@ -1679,62 +1729,41 @@ fn main() { let json_rpc_url = value_t!(matches, "json_rpc_url", String) .unwrap_or_else(|_| cli_config.json_rpc_url.clone()); - let staker = signer_from_path( + let staker = get_signer( &matches, - &cli_config.keypair_path, "staker", + &cli_config.keypair_path, &mut wallet_manager, - ) - .unwrap_or_else(|e| { - eprintln!("error: {}", e); - exit(1); - }); + ); + let depositor = if matches.is_present("depositor") { - Some( - signer_from_path( - &matches, - &cli_config.keypair_path, - "depositor", - &mut wallet_manager, - ) - .unwrap_or_else(|e| { - eprintln!("error: {}", e); - exit(1); - }), - ) + Some(get_signer( + &matches, + "depositor", + &cli_config.keypair_path, + &mut wallet_manager, + )) } else { None }; - let manager = signer_from_path( + let manager = get_signer( &matches, - &cli_config.keypair_path, "manager", + &cli_config.keypair_path, &mut wallet_manager, - ) - .unwrap_or_else(|e| { - eprintln!("error: {}", e); - exit(1); - }); - let token_owner = signer_from_path( + ); + let token_owner = get_signer( &matches, - &cli_config.keypair_path, "token_owner", + &cli_config.keypair_path, &mut wallet_manager, - ) - .unwrap_or_else(|e| { - eprintln!("error: {}", e); - exit(1); - }); - let fee_payer = signer_from_path( + ); + let fee_payer = get_signer( &matches, - &cli_config.keypair_path, "fee_payer", + &cli_config.keypair_path, &mut wallet_manager, - ) - .unwrap_or_else(|e| { - eprintln!("error: {}", e); - exit(1); - }); + ); let verbose = matches.is_present("verbose"); let dry_run = matches.is_present("dry_run"); let no_update = matches.is_present("no_update"); From 0b078c024fa0b149c392b4c45057ee8c974cde80 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Sat, 10 Jul 2021 00:24:24 +0200 Subject: [PATCH 0127/1076] stake-pool: Increase version for crate release, update program id (#2059) --- clients/cli/Cargo.toml | 4 ++-- clients/cli/scripts/setup-local.sh | 2 +- program/Cargo.toml | 2 +- program/program-id.md | 2 +- program/src/lib.rs | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 4104f43e..5d57ed60 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -6,7 +6,7 @@ homepage = "https://spl.solana.com/stake-pool" license = "Apache-2.0" name = "spl-stake-pool-cli" repository = "https://github.com/solana-labs/solana-program-library" -version = "0.3.0" +version = "0.4.0" [dependencies] borsh = "0.9" @@ -21,7 +21,7 @@ solana-program = "=1.7.4" solana-remote-wallet = "=1.7.4" solana-sdk = "=1.7.4" spl-associated-token-account = { version = "1.0", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } -spl-stake-pool = { version = "0.3", path="../program", features = [ "no-entrypoint" ] } +spl-stake-pool = { version = "0.4", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "3.1", path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" bincode = "1.3.1" diff --git a/clients/cli/scripts/setup-local.sh b/clients/cli/scripts/setup-local.sh index 1aeb2474..422b7944 100755 --- a/clients/cli/scripts/setup-local.sh +++ b/clients/cli/scripts/setup-local.sh @@ -25,7 +25,7 @@ build_program () { } setup_validator() { - solana-test-validator --bpf-program SPoo1XJbrC5pXDfg5NQAXo2RKyfimXKm6KpqicGvpbo ../../../target/deploy/spl_stake_pool.so --quiet --reset --slots-per-epoch 32 & + solana-test-validator --bpf-program SPoo1xuN9wGpxNjGnPNbRPtpQ7mHgKM8d9BeFC549Jy ../../../target/deploy/spl_stake_pool.so --quiet --reset --slots-per-epoch 32 & pid=$! solana config set --url http://127.0.0.1:8899 solana config set --commitment confirmed diff --git a/program/Cargo.toml b/program/Cargo.toml index 6ecddf58..546b9074 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "spl-stake-pool" -version = "0.3.0" +version = "0.4.0" description = "Solana Program Library Stake Pool" authors = ["Solana Maintainers "] repository = "https://github.com/solana-labs/solana-program-library" diff --git a/program/program-id.md b/program/program-id.md index fc9290e5..cd9b26d3 100644 --- a/program/program-id.md +++ b/program/program-id.md @@ -1 +1 @@ -SPoo1XJbrC5pXDfg5NQAXo2RKyfimXKm6KpqicGvpbo +SPoo1xuN9wGpxNjGnPNbRPtpQ7mHgKM8d9BeFC549Jy diff --git a/program/src/lib.rs b/program/src/lib.rs index fbbd05c5..f9c5d57d 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -102,4 +102,4 @@ pub fn find_transient_stake_program_address( ) } -solana_program::declare_id!("SPoo1XJbrC5pXDfg5NQAXo2RKyfimXKm6KpqicGvpbo"); +solana_program::declare_id!("SPoo1xuN9wGpxNjGnPNbRPtpQ7mHgKM8d9BeFC549Jy"); From 8e4c838c6e9ca2183ddea6115c0af9a378a2c34a Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Mon, 12 Jul 2021 12:50:28 +0200 Subject: [PATCH 0128/1076] Convert `checked_add` to `saturating_add` to fix downstream build (#2055) --- program/src/processor.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/program/src/processor.rs b/program/src/processor.rs index 674ea2d3..a3521285 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1396,8 +1396,7 @@ impl Processor { Some(stake_program::StakeState::Stake(meta, stake)) => { let account_stake = meta .rent_exempt_reserve - .checked_add(stake.delegation.stake) - .ok_or(StakePoolError::CalculationFailure)?; + .saturating_add(stake.delegation.stake); if no_merge { transient_stake_lamports = account_stake; } else if stake.delegation.deactivation_epoch < clock.epoch { From d6fb4aa517dbee913606f81eaee6971ea19a36af Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 13 Jul 2021 20:11:39 +0200 Subject: [PATCH 0129/1076] stake-pool: Add check for delegation stake in add / remove (#2076) --- program/src/processor.rs | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/program/src/processor.rs b/program/src/processor.rs index a3521285..1984702b 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -793,6 +793,15 @@ impl Processor { return Err(StakePoolError::StakeLamportsNotEqualToMinimum.into()); } + if stake.delegation.stake != MINIMUM_ACTIVE_STAKE { + msg!( + "Error: attempting to add stake with delegation of {} lamports, must have {} lamports", + stake.delegation.stake, + MINIMUM_ACTIVE_STAKE + ); + return Err(StakePoolError::StakeLamportsNotEqualToMinimum.into()); + } + // Check if stake is warmed up //Self::check_stake_activation(stake_account_info, clock, stake_history)?; @@ -808,7 +817,7 @@ impl Processor { validator_list.push(ValidatorStakeInfo { status: StakeStatus::Active, vote_account_address, - active_stake_lamports: stake_lamports.saturating_sub(minimum_lamport_amount), + active_stake_lamports: 0, transient_stake_lamports: 0, last_update_epoch: clock.epoch, })?; @@ -900,6 +909,15 @@ impl Processor { return Err(StakePoolError::StakeLamportsNotEqualToMinimum.into()); } + if stake.delegation.stake != MINIMUM_ACTIVE_STAKE { + msg!( + "Error: attempting to remove stake with delegation of {} lamports, must have {} lamports", + stake.delegation.stake, + MINIMUM_ACTIVE_STAKE + ); + return Err(StakePoolError::StakeLamportsNotEqualToMinimum.into()); + } + // check that the transient stake account doesn't exist let new_status = if let Ok((_meta, stake)) = get_stake_state(transient_stake_account_info) { if stake.delegation.deactivation_epoch == Epoch::MAX { @@ -1181,7 +1199,7 @@ impl Processor { { let max_split_amount = reserve_stake_account_info .lamports() - .saturating_sub(stake_rent); + .saturating_sub(2 * stake_rent); msg!( "Reserve stake does not have enough lamports for increase, must be less than {}, {} requested", max_split_amount, From fe7599b0547172488a31f26a195e3dea796acc39 Mon Sep 17 00:00:00 2001 From: Jack May Date: Wed, 14 Jul 2021 10:26:31 -0700 Subject: [PATCH 0130/1076] Breakup stake-pool update test transactions (#2084) * Breakup stake-pool update test transactions * nudge --- program/tests/huge_pool.rs | 74 ++++++++++++++++++++++++-------------- 1 file changed, 48 insertions(+), 26 deletions(-) diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index e3199281..6b54a2c1 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -313,32 +313,54 @@ async fn update() { setup(HUGE_POOL_SIZE, HUGE_POOL_SIZE, STAKE_AMOUNT).await; let transaction = Transaction::new_signed_with_payer( - &[ - instruction::update_validator_list_balance( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.withdraw_authority, - &stake_pool_accounts.validator_list.pubkey(), - &stake_pool_accounts.reserve_stake.pubkey(), - &vote_account_pubkeys[0..MAX_VALIDATORS_TO_UPDATE], - 0, - /* no_merge = */ false, - ), - instruction::update_stake_pool_balance( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.withdraw_authority, - &stake_pool_accounts.validator_list.pubkey(), - &stake_pool_accounts.reserve_stake.pubkey(), - &stake_pool_accounts.pool_fee_account.pubkey(), - &stake_pool_accounts.pool_mint.pubkey(), - ), - instruction::cleanup_removed_validator_entries( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.validator_list.pubkey(), - ), - ], + &[instruction::update_validator_list_balance( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), + &vote_account_pubkeys[0..MAX_VALIDATORS_TO_UPDATE], + 0, + /* no_merge = */ false, + )], + Some(&context.payer.pubkey()), + &[&context.payer], + context.last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err(); + assert!(error.is_none()); + + let transaction = Transaction::new_signed_with_payer( + &[instruction::update_stake_pool_balance( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.pool_fee_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + )], + Some(&context.payer.pubkey()), + &[&context.payer], + context.last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err(); + assert!(error.is_none()); + + let transaction = Transaction::new_signed_with_payer( + &[instruction::cleanup_removed_validator_entries( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + )], Some(&context.payer.pubkey()), &[&context.payer], context.last_blockhash, From 4a302dd597ab7031c2614fd56b0f1e5c688eeee3 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 15 Jul 2021 17:58:37 -0500 Subject: [PATCH 0131/1076] Eliminate doc warnings (#2058) * Add URL autolinks to docs in spl-math * Autolink URLs in doc comments * Surround 'account references' doc items with code spans to avoid warnings --- program/src/stake_program.rs | 64 ++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/program/src/stake_program.rs b/program/src/stake_program.rs index cc8cfea1..ffe21d29 100644 --- a/program/src/stake_program.rs +++ b/program/src/stake_program.rs @@ -32,8 +32,8 @@ pub enum StakeInstruction { /// Initialize a stake with lockup and authorization information /// /// # Account references - /// 0. [WRITE] Uninitialized stake account - /// 1. [] Rent sysvar + /// 0. `[WRITE]` Uninitialized stake account + /// 1. `[]` Rent sysvar /// /// Authorized carries pubkeys that must sign staker transactions /// and withdrawer transactions. @@ -43,20 +43,20 @@ pub enum StakeInstruction { /// Authorize a key to manage stake or withdrawal /// /// # Account references - /// 0. [WRITE] Stake account to be updated - /// 1. [] (reserved for future use) Clock sysvar - /// 2. [SIGNER] The stake or withdraw authority + /// 0. `[WRITE]` Stake account to be updated + /// 1. `[]` (reserved for future use) Clock sysvar + /// 2. `[SIGNER]` The stake or withdraw authority Authorize(Pubkey, StakeAuthorize), /// Delegate a stake to a particular vote account /// /// # Account references - /// 0. [WRITE] Initialized stake account to be delegated - /// 1. [] Vote account to which this stake will be delegated - /// 2. [] Clock sysvar - /// 3. [] Stake history sysvar that carries stake warmup/cooldown history - /// 4. [] Address of config account that carries stake config - /// 5. [SIGNER] Stake authority + /// 0. `[WRITE]` Initialized stake account to be delegated + /// 1. `[]` Vote account to which this stake will be delegated + /// 2. `[]` Clock sysvar + /// 3. `[]` Stake history sysvar that carries stake warmup/cooldown history + /// 4. `[]` Address of config account that carries stake config + /// 5. `[SIGNER]` Stake authority /// /// The entire balance of the staking account is staked. DelegateStake /// can be called multiple times, but re-delegation is delayed @@ -66,20 +66,20 @@ pub enum StakeInstruction { /// Split u64 tokens and stake off a stake account into another stake account. /// /// # Account references - /// 0. [WRITE] Stake account to be split; must be in the Initialized or Stake state - /// 1. [WRITE] Uninitialized stake account that will take the split-off amount - /// 2. [SIGNER] Stake authority + /// 0. `[WRITE]` Stake account to be split; must be in the Initialized or Stake state + /// 1. `[WRITE]` Uninitialized stake account that will take the split-off amount + /// 2. `[SIGNER]` Stake authority Split(u64), /// Withdraw unstaked lamports from the stake account /// /// # Account references - /// 0. [WRITE] Stake account from which to withdraw - /// 1. [WRITE] Recipient account - /// 2. [] Clock sysvar - /// 3. [] Stake history sysvar that carries stake warmup/cooldown history - /// 4. [SIGNER] Withdraw authority - /// 5. Optional: [SIGNER] Lockup authority, if before lockup expiration + /// 0. `[WRITE]` Stake account from which to withdraw + /// 1. `[WRITE]` Recipient account + /// 2. `[]` Clock sysvar + /// 3. `[]` Stake history sysvar that carries stake warmup/cooldown history + /// 4. `[SIGNER]` Withdraw authority + /// 5. Optional: `[SIGNER]` Lockup authority, if before lockup expiration /// /// The u64 is the portion of the stake account balance to be withdrawn, /// must be `<= ValidatorStakeAccount.lamports - staked_lamports`. @@ -88,34 +88,34 @@ pub enum StakeInstruction { /// Deactivates the stake in the account /// /// # Account references - /// 0. [WRITE] Delegated stake account - /// 1. [] Clock sysvar - /// 2. [SIGNER] Stake authority + /// 0. `[WRITE]` Delegated stake account + /// 1. `[]` Clock sysvar + /// 2. `[SIGNER]` Stake authority Deactivate, /// Set stake lockup /// /// # Account references - /// 0. [WRITE] Initialized stake account - /// 1. [SIGNER] Lockup authority + /// 0. `[WRITE]` Initialized stake account + /// 1. `[SIGNER]` Lockup authority SetLockup, /// Merge two stake accounts. Both accounts must be deactivated and have identical lockup and /// authority keys. /// /// # Account references - /// 0. [WRITE] Destination stake account for the merge - /// 1. [WRITE] Source stake account for to merge. This account will be drained - /// 2. [] Clock sysvar - /// 3. [] Stake history sysvar that carries stake warmup/cooldown history - /// 4. [SIGNER] Stake authority + /// 0. `[WRITE]` Destination stake account for the merge + /// 1. `[WRITE]` Source stake account for to merge. This account will be drained + /// 2. `[]` Clock sysvar + /// 3. `[]` Stake history sysvar that carries stake warmup/cooldown history + /// 4. `[SIGNER]` Stake authority Merge, /// Authorize a key to manage stake or withdrawal with a derived key /// /// # Account references - /// 0. [WRITE] Stake account to be updated - /// 1. [SIGNER] Base key of stake or withdraw authority + /// 0. `[WRITE]` Stake account to be updated + /// 1. `[SIGNER]` Base key of stake or withdraw authority AuthorizeWithSeed, } From 1cd4be10496ce68f1341c75ee9c730cb5ea70f6f Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Sat, 17 Jul 2021 21:11:53 +0200 Subject: [PATCH 0132/1076] stake-pool-cli: Integrate user feedback (#2100) * Add ATA for pool fee account and more pool info * stake-pool-cli: Integrate user feedback * Add more output for `list` command, `-v` gives more info * Default to the manager's associated token account when creating a pool --- clients/cli/src/main.rs | 273 ++++++++++++++++++++++------------------ 1 file changed, 151 insertions(+), 122 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index ee6095fd..40886c9e 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -34,7 +34,8 @@ use { }, spl_associated_token_account::{create_associated_token_account, get_associated_token_address}, spl_stake_pool::{ - self, find_stake_program_address, find_withdraw_authority_program_address, + self, find_stake_program_address, find_transient_stake_program_address, + find_withdraw_authority_program_address, instruction::PreferredValidatorType, stake_program::{self, StakeState}, state::{Fee, StakePool, ValidatorList}, @@ -164,12 +165,6 @@ fn command_create_pool( let mint_keypair = mint_keypair.unwrap_or_else(Keypair::new); println!("Creating mint {}", mint_keypair.pubkey()); - let pool_fee_account = Keypair::new(); - println!( - "Creating pool fee collection account {}", - pool_fee_account.pubkey() - ); - let stake_pool_keypair = stake_pool_keypair.unwrap_or_else(Keypair::new); let validator_list = Keypair::new(); @@ -192,7 +187,7 @@ fn command_create_pool( let validator_list_balance = config .rpc_client .get_minimum_balance_for_rent_exemption(validator_list_size)?; - let total_rent_free_balances = reserve_stake_balance + let mut total_rent_free_balances = reserve_stake_balance + mint_account_balance + pool_fee_account_balance + stake_pool_account_lamports @@ -210,58 +205,52 @@ fn command_create_pool( println!("Stake pool withdraw authority {}", withdraw_authority); } - let mut setup_transaction = Transaction::new_with_payer( - &[ - // Account for the stake pool reserve - system_instruction::create_account( - &config.fee_payer.pubkey(), - &reserve_keypair.pubkey(), - reserve_stake_balance, - STAKE_STATE_LEN as u64, - &stake_program::id(), - ), - stake_program::initialize( - &reserve_keypair.pubkey(), - &stake_program::Authorized { - staker: withdraw_authority, - withdrawer: withdraw_authority, - }, - &stake_program::Lockup::default(), - ), - // Account for the stake pool mint - system_instruction::create_account( - &config.fee_payer.pubkey(), - &mint_keypair.pubkey(), - mint_account_balance, - spl_token::state::Mint::LEN as u64, - &spl_token::id(), - ), - // Account for the pool fee accumulation - system_instruction::create_account( - &config.fee_payer.pubkey(), - &pool_fee_account.pubkey(), - pool_fee_account_balance, - spl_token::state::Account::LEN as u64, - &spl_token::id(), - ), - // Initialize pool token mint account - spl_token::instruction::initialize_mint( - &spl_token::id(), - &mint_keypair.pubkey(), - &withdraw_authority, - None, - default_decimals, - )?, - // Initialize fee receiver account - spl_token::instruction::initialize_account( - &spl_token::id(), - &pool_fee_account.pubkey(), - &mint_keypair.pubkey(), - &config.manager.pubkey(), - )?, - ], - Some(&config.fee_payer.pubkey()), + let mut instructions = vec![ + // Account for the stake pool reserve + system_instruction::create_account( + &config.fee_payer.pubkey(), + &reserve_keypair.pubkey(), + reserve_stake_balance, + STAKE_STATE_LEN as u64, + &stake_program::id(), + ), + stake_program::initialize( + &reserve_keypair.pubkey(), + &stake_program::Authorized { + staker: withdraw_authority, + withdrawer: withdraw_authority, + }, + &stake_program::Lockup::default(), + ), + // Account for the stake pool mint + system_instruction::create_account( + &config.fee_payer.pubkey(), + &mint_keypair.pubkey(), + mint_account_balance, + spl_token::state::Mint::LEN as u64, + &spl_token::id(), + ), + // Initialize pool token mint account + spl_token::instruction::initialize_mint( + &spl_token::id(), + &mint_keypair.pubkey(), + &withdraw_authority, + None, + default_decimals, + )?, + ]; + + let pool_fee_account = add_associated_token_account( + config, + &mint_keypair.pubkey(), + &config.manager.pubkey(), + &mut instructions, + &mut total_rent_free_balances, ); + println!("Creating pool fee collection account {}", pool_fee_account); + + let mut setup_transaction = + Transaction::new_with_payer(&instructions, Some(&config.fee_payer.pubkey())); let mut initialize_transaction = Transaction::new_with_payer( &[ @@ -290,7 +279,7 @@ fn command_create_pool( &validator_list.pubkey(), &reserve_keypair.pubkey(), &mint_keypair.pubkey(), - &pool_fee_account.pubkey(), + &pool_fee_account, &spl_token::id(), deposit_authority, fee, @@ -307,12 +296,7 @@ fn command_create_pool( + fee_calculator.calculate_fee(setup_transaction.message()) + fee_calculator.calculate_fee(initialize_transaction.message()), )?; - let mut setup_signers = vec![ - config.fee_payer.as_ref(), - &mint_keypair, - &pool_fee_account, - &reserve_keypair, - ]; + let mut setup_signers = vec![config.fee_payer.as_ref(), &mint_keypair, &reserve_keypair]; unique_signers!(setup_signers); setup_transaction.sign(&setup_signers, recent_blockhash); send_transaction(config, setup_transaction)?; @@ -552,13 +536,14 @@ fn command_set_preferred_validator( fn add_associated_token_account( config: &Config, mint: &Pubkey, + owner: &Pubkey, instructions: &mut Vec, rent_free_balances: &mut u64, ) -> Pubkey { // Account for tokens not specified, creating one - let account = get_associated_token_address(&config.fee_payer.pubkey(), mint); + let account = get_associated_token_address(owner, mint); if get_token_account(&config.rpc_client, &account, mint).is_err() { - println!("Creating associated token account {} to receive stake pool tokens of mint {}, owned by {}", account, mint, config.fee_payer.pubkey()); + println!("Creating associated token account {} to receive stake pool tokens of mint {}, owned by {}", account, mint, owner); let min_account_balance = config .rpc_client @@ -567,13 +552,13 @@ fn add_associated_token_account( instructions.push(create_associated_token_account( &config.fee_payer.pubkey(), - &config.fee_payer.pubkey(), + owner, mint, )); *rent_free_balances += min_account_balance; } else { - println!("Using existing associated token account {} to receive stake pool tokens of mint {}, owned by {}", account, mint, config.fee_payer.pubkey()); + println!("Using existing associated token account {} to receive stake pool tokens of mint {}, owned by {}", account, mint, owner); } account @@ -628,6 +613,7 @@ fn command_deposit( let token_receiver = token_receiver.unwrap_or(add_associated_token_account( config, &stake_pool.pool_mint, + &config.token_owner.pubkey(), &mut instructions, &mut total_rent_free_balances, )); @@ -697,28 +683,102 @@ fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?; let pool_mint = get_token_mint(&config.rpc_client, &stake_pool.pool_mint)?; let epoch_info = config.rpc_client.get_epoch_info()?; + let pool_withdraw_authority = + find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; + if config.verbose { + println!("Stake Pool Info"); + println!("==============="); + println!("Stake Pool: {}", stake_pool_address); + println!("Validator List: {}", stake_pool.validator_list); + println!("Manager: {}", stake_pool.manager); + println!("Staker: {}", stake_pool.staker); + println!("Depositor: {}", stake_pool.deposit_authority); + println!("Withdraw Authority: {}", pool_withdraw_authority); + println!("Pool Token Mint: {}", stake_pool.pool_mint); + println!("Fee Account: {}", stake_pool.manager_fee_account); + } else { + println!("Stake Pool: {}", stake_pool_address); + println!("Pool Token Mint: {}", stake_pool.pool_mint); + } + + if let Some(preferred_deposit_validator) = stake_pool.preferred_deposit_validator_vote_address { + println!( + "Preferred Deposit Validator: {}", + preferred_deposit_validator + ); + } + if let Some(preferred_withdraw_validator) = stake_pool.preferred_withdraw_validator_vote_address + { + println!( + "Preferred Withraw Validator: {}", + preferred_withdraw_validator + ); + } + if stake_pool.fee.numerator > 0 { + println!( + "Fee: {}/{} of epoch rewards", + stake_pool.fee.numerator, stake_pool.fee.denominator + ); + } else { + println!("Fee: none"); + } + + if config.verbose { + println!(); + println!("Stake Accounts"); + println!("--------------"); + } let reserve_stake = config.rpc_client.get_account(&stake_pool.reserve_stake)?; + let minimum_reserve_stake_balance = config + .rpc_client + .get_minimum_balance_for_rent_exemption(STAKE_STATE_LEN)? + + 1; println!( - "Reserve Account: {}\tBalance: {}", + "Reserve Account: {}\tAvailable Balance: {}", stake_pool.reserve_stake, - Sol(reserve_stake.lamports), + Sol(reserve_stake.lamports - minimum_reserve_stake_balance), ); for validator in &validator_list.validators { - println!( - "Validator Vote Account: {}\tBalance: {}\tLast Update Epoch: {}{}", - validator.vote_account_address, - Sol(validator.stake_lamports()), - validator.last_update_epoch, - if validator.last_update_epoch != epoch_info.epoch { - " [UPDATE REQUIRED]" - } else { - "" - } - ); + if config.verbose { + let (stake_account_address, _) = find_stake_program_address( + &spl_stake_pool::id(), + &validator.vote_account_address, + stake_pool_address, + ); + let (transient_stake_account_address, _) = find_transient_stake_program_address( + &spl_stake_pool::id(), + &validator.vote_account_address, + stake_pool_address, + ); + println!( + "Vote Account: {}\tStake Account: {}\tActive Balance: {}\tTransient Stake Account: {}\tTransient Balance: {}\tLast Update Epoch: {}{}", + validator.vote_account_address, + stake_account_address, + Sol(validator.active_stake_lamports), + transient_stake_account_address, + Sol(validator.transient_stake_lamports), + validator.last_update_epoch, + if validator.last_update_epoch != epoch_info.epoch { + " [UPDATE REQUIRED]" + } else { + "" + } + ); + } else { + println!( + "Vote Account: {}\tBalance: {}\tLast Update Epoch: {}", + validator.vote_account_address, + Sol(validator.stake_lamports()), + validator.last_update_epoch, + ); + } } + if config.verbose { + println!(); + } println!( "Total Pool Stake: {}{}", Sol(stake_pool.total_stake_lamports), @@ -733,46 +793,14 @@ fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { spl_token::amount_to_ui_amount(stake_pool.pool_token_supply, pool_mint.decimals) ); println!( - "Total number of validators: {}", + "Current Number of Validators: {}", validator_list.validators.len() ); println!( - "Max number of validators: {}", + "Max Number of Validators: {}", validator_list.header.max_validators ); - if config.verbose { - println!(); - - let pool_withdraw_authority = - find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; - - let accounts = - get_stake_accounts_by_withdraw_authority(&config.rpc_client, &pool_withdraw_authority)?; - if accounts.is_empty() { - return Err(format!("No stake accounts found for {}", pool_withdraw_authority).into()); - } - - let mut total_stake_lamports: u64 = 0; - for (pubkey, stake_lamports, stake_state) in accounts { - total_stake_lamports += stake_lamports; - println!( - "Stake Account: {}\tVote Account: {}\t{}", - pubkey, - stake_state.delegation().expect("delegation").voter_pubkey, - Sol(stake_lamports) - ); - } - println!("Total Stake Account Balance: {}", Sol(total_stake_lamports)); - - if pool_mint.supply != stake_pool.pool_token_supply { - println!( - "BUG! Pool Tokens supply mismatch. Pool mint reports {}", - spl_token::amount_to_ui_amount(pool_mint.supply, pool_mint.decimals) - ); - } - } - Ok(()) } @@ -920,7 +948,7 @@ fn command_withdraw( find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; let pool_token_account = pool_token_account.unwrap_or(get_associated_token_address( - &config.fee_payer.pubkey(), + &config.token_owner.pubkey(), &stake_pool.pool_mint, )); let token_account = get_token_account( @@ -1410,7 +1438,7 @@ fn main() { .value_name("ADDRESS") .takes_value(true) .help("New authority to set as Staker and Withdrawer in the stake account removed from the pool. - Defaults to the wallet owner pubkey."), + Defaults to the client keypair."), ) ) .subcommand(SubCommand::with_name("increase-validator-stake") @@ -1537,8 +1565,9 @@ fn main() { .validator(is_pubkey) .value_name("ADDRESS") .takes_value(true) - .help("Account to receive pool token. Must be initialized account of the stake pool token. \ - Defaults to the fee payer's associated pool token account."), + .help("Account to receive the minted pool tokens. \ + Defaults to the token-owner's associated pool token account. \ + Creates the account if it does not exist."), ) ) .subcommand(SubCommand::with_name("list") @@ -1603,7 +1632,7 @@ fn main() { .validator(is_pubkey) .value_name("ADDRESS") .takes_value(true) - .help("Pool token account to withdraw tokens from. Must be owned by the fee payer. Defaults to their associated token account."), + .help("Pool token account to withdraw tokens from. Defaults to the token-owner's associated token account."), ) .arg( Arg::with_name("stake_receiver") From d1bc96cbfed7c893a0afc6fabc71b3123c8b0393 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 20 Jul 2021 00:36:08 +0200 Subject: [PATCH 0133/1076] stake-pool: Update pool token supply on update, in case of burns (#2108) --- program/src/processor.rs | 4 + program/tests/helpers/mod.rs | 30 ++++++- .../tests/update_validator_list_balance.rs | 83 +++++++++++++++++-- 3 files changed, 111 insertions(+), 6 deletions(-) diff --git a/program/src/processor.rs b/program/src/processor.rs index 1984702b..780dc444 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1621,6 +1621,10 @@ impl Processor { } stake_pool.total_stake_lamports = total_stake_lamports; stake_pool.last_update_epoch = clock.epoch; + + let pool_mint = Mint::unpack_from_slice(&pool_mint_info.data.borrow())?; + stake_pool.pool_token_supply = pool_mint.supply; + stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; Ok(()) diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 3d561b07..04641414 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -161,6 +161,33 @@ pub async fn mint_tokens( Ok(()) } +pub async fn burn_tokens( + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + mint: &Pubkey, + account: &Pubkey, + authority: &Keypair, + amount: u64, +) -> Result<(), TransportError> { + let transaction = Transaction::new_signed_with_payer( + &[spl_token::instruction::burn( + &spl_token::id(), + account, + mint, + &authority.pubkey(), + &[], + amount, + ) + .unwrap()], + Some(&payer.pubkey()), + &[payer, authority], + *recent_blockhash, + ); + banks_client.process_transaction(transaction).await?; + Ok(()) +} + pub async fn get_token_balance(banks_client: &mut BanksClient, token: &Pubkey) -> u64 { let token_account = banks_client.get_account(*token).await.unwrap().unwrap(); let account_info: spl_token::state::Account = @@ -1019,7 +1046,7 @@ impl DepositStakeAccount { } pub async fn deposit( - &self, + &mut self, banks_client: &mut BanksClient, payer: &Keypair, recent_blockhash: &Hash, @@ -1048,6 +1075,7 @@ impl DepositStakeAccount { &self.authority, ) .await; + self.pool_tokens = get_token_balance(banks_client, &self.pool_account.pubkey()).await; assert!(error.is_none()); } } diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index f11095f8..c8326183 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -4,7 +4,7 @@ mod helpers; use { helpers::*, - solana_program::{borsh::try_from_slice_unchecked, pubkey::Pubkey}, + solana_program::{borsh::try_from_slice_unchecked, program_pack::Pack, pubkey::Pubkey}, solana_program_test::*, solana_sdk::signature::Signer, spl_stake_pool::{ @@ -12,6 +12,7 @@ use { state::{StakePool, StakeStatus, ValidatorList}, MAX_VALIDATORS_TO_UPDATE, MINIMUM_ACTIVE_STAKE, }, + spl_token::state::Mint, }; async fn setup( @@ -20,6 +21,7 @@ async fn setup( ProgramTestContext, StakePoolAccounts, Vec, + Vec, u64, u64, u64, @@ -99,7 +101,7 @@ async fn setup( assert!(error.is_none()); } - for deposit_account in &deposit_accounts { + for deposit_account in &mut deposit_accounts { deposit_account .deposit( &mut context.banks_client, @@ -131,6 +133,7 @@ async fn setup( context, stake_pool_accounts, stake_accounts, + deposit_accounts, TEST_STAKE_AMOUNT, reserve_stake_amount, slot, @@ -144,6 +147,7 @@ async fn success() { mut context, stake_pool_accounts, stake_accounts, + _, validator_lamports, reserve_lamports, mut slot, @@ -207,7 +211,7 @@ async fn success() { #[tokio::test] async fn merge_into_reserve() { - let (mut context, stake_pool_accounts, stake_accounts, lamports, _, mut slot) = + let (mut context, stake_pool_accounts, stake_accounts, _, lamports, _, mut slot) = setup(MAX_VALIDATORS_TO_UPDATE).await; let pre_lamports = get_validator_list_sum( @@ -317,7 +321,7 @@ async fn merge_into_reserve() { #[tokio::test] async fn merge_into_validator_stake() { - let (mut context, stake_pool_accounts, stake_accounts, lamports, reserve_lamports, mut slot) = + let (mut context, stake_pool_accounts, stake_accounts, _, lamports, reserve_lamports, mut slot) = setup(MAX_VALIDATORS_TO_UPDATE).await; let rent = context.banks_client.get_rent().await.unwrap(); @@ -448,7 +452,7 @@ async fn merge_into_validator_stake() { #[tokio::test] async fn merge_transient_stake_after_remove() { - let (mut context, stake_pool_accounts, stake_accounts, lamports, reserve_lamports, mut slot) = + let (mut context, stake_pool_accounts, stake_accounts, _, lamports, reserve_lamports, mut slot) = setup(1).await; let rent = context.banks_client.get_rent().await.unwrap(); @@ -590,6 +594,75 @@ async fn merge_transient_stake_after_remove() { assert_eq!(validator_list.validators.len(), 0); } +#[tokio::test] +async fn success_with_burned_tokens() { + let num_validators = 5; + let (mut context, stake_pool_accounts, stake_accounts, deposit_accounts, _, _, mut slot) = + setup(num_validators).await; + + let mint_info = get_account( + &mut context.banks_client, + &stake_pool_accounts.pool_mint.pubkey(), + ) + .await; + let mint = Mint::unpack(&mint_info.data).unwrap(); + + let stake_pool_info = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data).unwrap(); + assert_eq!(mint.supply, stake_pool.pool_token_supply); + + burn_tokens( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts.pool_mint.pubkey(), + &deposit_accounts[0].pool_account.pubkey(), + &deposit_accounts[0].authority, + deposit_accounts[0].pool_tokens, + ) + .await + .unwrap(); + + let mint_info = get_account( + &mut context.banks_client, + &stake_pool_accounts.pool_mint.pubkey(), + ) + .await; + let mint = Mint::unpack(&mint_info.data).unwrap(); + assert_ne!(mint.supply, stake_pool.pool_token_supply); + + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + slot += slots_per_epoch; + context.warp_to_slot(slot).unwrap(); + + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + stake_accounts + .iter() + .map(|v| v.vote.pubkey()) + .collect::>() + .as_slice(), + false, + ) + .await; + + let stake_pool_info = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data).unwrap(); + + assert_eq!(mint.supply, stake_pool.pool_token_supply); +} + #[tokio::test] async fn fail_with_uninitialized_validator_list() {} // TODO From cb937eed4770830cfc743a45060a08cc7aab5158 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 20 Jul 2021 23:40:32 +0200 Subject: [PATCH 0134/1076] token: Bump to 3.2.0 everywhere (#2116) --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 5d57ed60..61076a55 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -22,7 +22,7 @@ solana-remote-wallet = "=1.7.4" solana-sdk = "=1.7.4" spl-associated-token-account = { version = "1.0", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "0.4", path="../program", features = [ "no-entrypoint" ] } -spl-token = { version = "3.1", path="../../token/program", features = [ "no-entrypoint" ] } +spl-token = { version = "3.2", path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" bincode = "1.3.1" lazy_static = "1.4.0" diff --git a/program/Cargo.toml b/program/Cargo.toml index 546b9074..1423795f 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -20,7 +20,7 @@ num_enum = "0.5.1" serde = "1.0.126" serde_derive = "1.0.103" solana-program = "1.7.4" -spl-token = { version = "3.1", path = "../../token/program", features = [ "no-entrypoint" ] } +spl-token = { version = "3.2", path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" bincode = "1.3.1" From 0859ee0d2b75835cab9e7a02d50fe7272e6595f1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Jul 2021 23:02:28 +0000 Subject: [PATCH 0135/1076] build(deps): bump num_enum from 0.5.1 to 0.5.2 (#2119) Bumps [num_enum](https://github.com/illicitonion/num_enum) from 0.5.1 to 0.5.2. - [Release notes](https://github.com/illicitonion/num_enum/releases) - [Commits](https://github.com/illicitonion/num_enum/compare/0.5.1...0.5.2) --- updated-dependencies: - dependency-name: num_enum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 1423795f..1462258b 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -16,7 +16,7 @@ arrayref = "0.3.6" borsh = "0.9" num-derive = "0.3" num-traits = "0.2" -num_enum = "0.5.1" +num_enum = "0.5.2" serde = "1.0.126" serde_derive = "1.0.103" solana-program = "1.7.4" From 3fbeba84ccba33e0a0a0a138352c2d08cec9cb04 Mon Sep 17 00:00:00 2001 From: Tyera Eulberg Date: Fri, 23 Jul 2021 10:47:06 -0600 Subject: [PATCH 0136/1076] Bump solana crates (#2139) --- clients/cli/Cargo.toml | 16 ++++++++-------- program/Cargo.toml | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 61076a55..9192d4f5 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -12,14 +12,14 @@ version = "0.4.0" borsh = "0.9" clap = "2.33.3" serde_json = "1.0.62" -solana-account-decoder = "=1.7.4" -solana-clap-utils = "=1.7.4" -solana-cli-config = "=1.7.4" -solana-client = "=1.7.4" -solana-logger = "=1.7.4" -solana-program = "=1.7.4" -solana-remote-wallet = "=1.7.4" -solana-sdk = "=1.7.4" +solana-account-decoder = "=1.7.7" +solana-clap-utils = "=1.7.7" +solana-cli-config = "=1.7.7" +solana-client = "=1.7.7" +solana-logger = "=1.7.7" +solana-program = "=1.7.7" +solana-remote-wallet = "=1.7.7" +solana-sdk = "=1.7.7" spl-associated-token-account = { version = "1.0", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "0.4", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "3.2", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/program/Cargo.toml b/program/Cargo.toml index 1462258b..62793d14 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -19,16 +19,16 @@ num-traits = "0.2" num_enum = "0.5.2" serde = "1.0.126" serde_derive = "1.0.103" -solana-program = "1.7.4" +solana-program = "1.7.7" spl-token = { version = "3.2", path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" bincode = "1.3.1" [dev-dependencies] proptest = "1.0" -solana-program-test = "1.7.4" -solana-sdk = "1.7.4" -solana-vote-program = "1.7.4" +solana-program-test = "1.7.7" +solana-sdk = "1.7.7" +solana-vote-program = "1.7.7" [lib] crate-type = ["cdylib", "lib"] From 5e4d2bea842ad1700c74af4c6ae6778e8943d9e4 Mon Sep 17 00:00:00 2001 From: jon-chuang <9093549+jon-chuang@users.noreply.github.com> Date: Mon, 26 Jul 2021 08:08:16 +0800 Subject: [PATCH 0137/1076] Stake pool/withdrawal fee (#2107) * stake-pool: Add new fee fields for liquid staking and arbitrage * incorporate withdrawal fee to withdrawal instruction, refactor calculating fees into Fee method * update withdraw instruction to take manager fee account, revert divide by 0 edge-case removal * initialize with withdrawal fee, modify integration tests to incorporate withdrawal fee * extra safety check, prevent divide by 0 * patch Initialize for other tests * decrease HUGE_POOL_SIZE to fit compute budget * set_withdrawal_fee, initialize conditions * Handle current withdrawal fee = 0 case * add tests for withdrawal fees * baseline fee increase is explicit constant * withdrawal_fee for cli for initialize * fmt, fix cli * obey clippy * clean up cli, add increase from 0 tests. * add cli: set-withdraw-fee * apply suggestions for code review * remove 1_000_000 denom limit * remove denom limit tests, inline, checked muls * apply suggestions for code review * referral fee * tests: use local copy to calculate_withdrawal_fee instead of fetching from chain Co-authored-by: Jon Cinque Co-authored-by: dhy1996 --- clients/cli/scripts/setup-stake-pool.sh | 1 + clients/cli/src/main.rs | 88 +++++ program/src/error.rs | 3 + program/src/instruction.rs | 49 ++- program/src/lib.rs | 15 +- program/src/processor.rs | 144 ++++++++- program/src/state.rs | 43 ++- program/tests/helpers/mod.rs | 13 + program/tests/huge_pool.rs | 8 +- program/tests/initialize.rs | 41 +++ program/tests/set_fee.rs | 6 +- program/tests/set_withdrawal_fee.rs | 407 ++++++++++++++++++++++++ program/tests/withdraw.rs | 63 +++- 13 files changed, 845 insertions(+), 36 deletions(-) create mode 100644 program/tests/set_withdrawal_fee.rs diff --git a/clients/cli/scripts/setup-stake-pool.sh b/clients/cli/scripts/setup-stake-pool.sh index f0b8c349..5a9fe3ad 100755 --- a/clients/cli/scripts/setup-stake-pool.sh +++ b/clients/cli/scripts/setup-stake-pool.sh @@ -31,6 +31,7 @@ setup_pool () { create_keypair $mint_keyfile $spl_stake_pool create-pool --fee-numerator 3 --fee-denominator 100 \ + --withdrawal-fee-numerator 5 --withdrawal-fee-denominator 1000 \ --max-validators $max_validators \ --pool-keypair $stake_pool_keyfile \ --mint-keypair $mint_keyfile diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 40886c9e..cb3e1c1f 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -150,10 +150,12 @@ fn checked_transaction_with_signers( Ok(transaction) } +#[allow(clippy::too_many_arguments)] fn command_create_pool( config: &Config, deposit_authority: Option, fee: Fee, + withdrawal_fee: Fee, max_validators: u32, stake_pool_keypair: Option, mint_keypair: Option, @@ -283,6 +285,7 @@ fn command_create_pool( &spl_token::id(), deposit_authority, fee, + withdrawal_fee, max_validators, ), ], @@ -1086,6 +1089,7 @@ fn command_withdraw( &config.staker.pubkey(), &user_transfer_authority.pubkey(), &pool_token_account, + &stake_pool.manager_fee_account, &stake_pool.pool_mint, &spl_token::id(), withdraw_account.pool_amount, @@ -1192,6 +1196,27 @@ fn command_set_fee(config: &Config, stake_pool_address: &Pubkey, new_fee: Fee) - Ok(()) } +fn command_set_withdrawal_fee( + config: &Config, + stake_pool_address: &Pubkey, + new_fee: Fee, +) -> CommandResult { + let mut signers = vec![config.fee_payer.as_ref(), config.manager.as_ref()]; + unique_signers!(signers); + let transaction = checked_transaction_with_signers( + config, + &[spl_stake_pool::instruction::set_withdrawal_fee( + &spl_stake_pool::id(), + stake_pool_address, + &config.manager.pubkey(), + new_fee, + )], + &signers, + )?; + send_transaction(config, transaction)?; + Ok(()) +} + fn main() { solana_logger::setup_with_default("solana=info"); @@ -1324,6 +1349,23 @@ fn main() { .required(true) .help("Fee denominator, fee amount is numerator divided by denominator."), ) + .arg( + Arg::with_name("withdrawal_fee_numerator") + .long("withdrawal-fee-numerator") + .validator(is_parsable::) + .value_name("NUMERATOR") + .takes_value(true) + .requires("withdrawal_fee_denominator") + .help("Withdrawal fee numerator, fee amount is numerator divided by denominator [default: 0]"), + ).arg( + Arg::with_name("withdrawal_fee_denominator") + .long("withdrawal-fee-denominator") + .validator(is_parsable::) + .value_name("DENOMINATOR") + .takes_value(true) + .requires("withdrawal_fee_numerator") + .help("Withdrawal fee denominator, fee amount is numerator divided by denominator [default: 0]"), + ) .arg( Arg::with_name("max_validators") .long("max-validators") @@ -1746,6 +1788,36 @@ fn main() { .help("Fee denominator, fee amount is numerator divided by denominator."), ) ) + .subcommand(SubCommand::with_name("set-withdrawal-fee") + .about("Change the withdrawal fee assessed by the stake pool. Must be signed by the manager.") + .arg( + Arg::with_name("pool") + .index(1) + .validator(is_pubkey) + .value_name("POOL_ADDRESS") + .takes_value(true) + .required(true) + .help("Stake pool address."), + ) + .arg( + Arg::with_name("fee_numerator") + .index(2) + .validator(is_parsable::) + .value_name("NUMERATOR") + .takes_value(true) + .required(true) + .help("Fee numerator, fee amount is numerator divided by denominator."), + ) + .arg( + Arg::with_name("fee_denominator") + .index(3) + .validator(is_parsable::) + .value_name("DENOMINATOR") + .takes_value(true) + .required(true) + .help("Fee denominator, fee amount is numerator divided by denominator."), + ) + ) .get_matches(); let mut wallet_manager = None; @@ -1815,6 +1887,8 @@ fn main() { let deposit_authority = pubkey_of(arg_matches, "deposit_authority"); let numerator = value_t_or_exit!(arg_matches, "fee_numerator", u64); let denominator = value_t_or_exit!(arg_matches, "fee_denominator", u64); + let w_numerator = value_t!(arg_matches, "withdrawal_fee_numerator", u64); + let w_denominator = value_t!(arg_matches, "withdrawal_fee_denominator", u64); let max_validators = value_t_or_exit!(arg_matches, "max_validators", u32); let pool_keypair = keypair_of(arg_matches, "pool_keypair"); let mint_keypair = keypair_of(arg_matches, "mint_keypair"); @@ -1826,6 +1900,10 @@ fn main() { denominator, numerator, }, + Fee { + numerator: w_numerator.unwrap_or(0), + denominator: w_denominator.unwrap_or(0), + }, max_validators, pool_keypair, mint_keypair, @@ -1942,6 +2020,16 @@ fn main() { }; command_set_fee(&config, &stake_pool_address, new_fee) } + ("set-withdrawal-fee", Some(arg_matches)) => { + let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); + let numerator = value_t_or_exit!(arg_matches, "fee_numerator", u64); + let denominator = value_t_or_exit!(arg_matches, "fee_denominator", u64); + let new_fee = Fee { + denominator, + numerator, + }; + command_set_withdrawal_fee(&config, &stake_pool_address, new_fee) + } _ => unreachable!(), } .map_err(|err| { diff --git a/program/src/error.rs b/program/src/error.rs index 37add414..c0edb105 100644 --- a/program/src/error.rs +++ b/program/src/error.rs @@ -99,6 +99,9 @@ pub enum StakePoolError { /// The mint has an invalid freeze authority #[error("InvalidMintFreezeAuthority")] InvalidMintFreezeAuthority, + /// Proposed fee increase exceeds stipulated ratio + #[error("FeeIncreaseTooHigh")] + FeeIncreaseTooHigh, } impl From for ProgramError { fn from(e: StakePoolError) -> Self { diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 0e2e6dc8..ab35ef66 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -1,7 +1,6 @@ //! Instruction types #![allow(clippy::too_many_arguments)] - use { crate::{ find_deposit_authority_program_address, find_stake_program_address, @@ -53,6 +52,9 @@ pub enum StakePoolInstruction { /// Fee assessed as percentage of perceived rewards #[allow(dead_code)] // but it's not fee: Fee, + /// Fee charged per withdrawal as percentage of withdrawal + #[allow(dead_code)] // but it's not + withdrawal_fee: Fee, /// Maximum expected number of validators #[allow(dead_code)] // but it's not max_validators: u32, @@ -273,10 +275,11 @@ pub enum StakePoolInstruction { /// 5. `[]` User account to set as a new withdraw authority /// 6. `[s]` User transfer authority, for pool token account /// 7. `[w]` User account with pool tokens to burn from - /// 8. `[w]` Pool token mint account - /// 9. `[]` Sysvar clock account (required) - /// 10. `[]` Pool token program id - /// 11. `[]` Stake program id, + /// 8. `[w]` Account to receive pool fee tokens + /// 9. `[w]` Pool token mint account + /// 10. `[]` Sysvar clock account (required) + /// 11. `[]` Pool token program id + /// 12. `[]` Stake program id, /// userdata: amount of pool tokens to withdraw Withdraw(u64), @@ -305,6 +308,17 @@ pub enum StakePoolInstruction { /// 1. `[s]` Manager or current staker /// 2. '[]` New staker pubkey SetStaker, + + /// (Manager only) Update Withdrawal fee for next epoch + /// + /// 0. `[w]` StakePool + /// 1. `[s]` Manager + /// 2. `[]` Sysvar clock + SetWithdrawalFee { + /// Fee assessed as percentage of perceived rewards + #[allow(dead_code)] // but it's not + fee: Fee, + }, } /// Creates an 'initialize' instruction. @@ -320,10 +334,12 @@ pub fn initialize( token_program_id: &Pubkey, deposit_authority: Option, fee: Fee, + withdrawal_fee: Fee, max_validators: u32, ) -> Instruction { let init_data = StakePoolInstruction::Initialize { fee, + withdrawal_fee, max_validators, }; let data = init_data.try_to_vec().unwrap(); @@ -925,6 +941,7 @@ pub fn withdraw( user_stake_authority: &Pubkey, user_transfer_authority: &Pubkey, user_pool_token_account: &Pubkey, + manager_fee_account: &Pubkey, pool_mint: &Pubkey, token_program_id: &Pubkey, amount: u64, @@ -938,6 +955,7 @@ pub fn withdraw( AccountMeta::new_readonly(*user_stake_authority, false), AccountMeta::new_readonly(*user_transfer_authority, true), AccountMeta::new(*user_pool_token_account, false), + AccountMeta::new(*manager_fee_account, false), AccountMeta::new(*pool_mint, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(*token_program_id, false), @@ -990,6 +1008,27 @@ pub fn set_fee( } } +/// Creates a 'set fee' instruction. +pub fn set_withdrawal_fee( + program_id: &Pubkey, + stake_pool: &Pubkey, + manager: &Pubkey, + fee: Fee, +) -> Instruction { + let accounts = vec![ + AccountMeta::new(*stake_pool, false), + AccountMeta::new_readonly(*manager, true), + AccountMeta::new_readonly(sysvar::clock::id(), false), + ]; + Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::SetWithdrawalFee { fee } + .try_to_vec() + .unwrap(), + } +} + /// Creates a 'set staker' instruction. pub fn set_staker( program_id: &Pubkey, diff --git a/program/src/lib.rs b/program/src/lib.rs index f9c5d57d..4ba5cf4d 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -15,7 +15,7 @@ pub mod entrypoint; // Export current sdk types for downstream users building with a different sdk version pub use solana_program; use { - crate::stake_program::Meta, + crate::{stake_program::Meta, state::Fee}, solana_program::{native_token::LAMPORTS_PER_SOL, pubkey::Pubkey}, }; @@ -36,6 +36,19 @@ pub const MINIMUM_ACTIVE_STAKE: u64 = LAMPORTS_PER_SOL; /// `UpdateValidatorListBalance` instruction, based on compute limits pub const MAX_VALIDATORS_TO_UPDATE: usize = 5; +/// Maximum factor by which a withdrawal fee can be increased per epoch +/// protecting stakers from malicious users. +/// If current fee is 0, WITHDRAWAL_BASELINE_FEE is used as the baseline +pub const MAX_WITHDRAWAL_FEE_INCREASE: Fee = Fee { + numerator: 3, + denominator: 2, +}; +/// Drop-in baseline fee when evaluating withdrawal fee increases when fee is 0 +pub const WITHDRAWAL_BASELINE_FEE: Fee = Fee { + numerator: 1, + denominator: 1000, +}; + /// Get the stake amount under consideration when calculating pool token /// conversions pub fn minimum_stake_lamports(meta: &Meta) -> u64 { diff --git a/program/src/processor.rs b/program/src/processor.rs index 780dc444..afa97a7e 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -10,7 +10,8 @@ use { AccountType, Fee, StakePool, StakeStatus, ValidatorList, ValidatorListHeader, ValidatorStakeInfo, }, - AUTHORITY_DEPOSIT, AUTHORITY_WITHDRAW, MINIMUM_ACTIVE_STAKE, TRANSIENT_STAKE_SEED, + AUTHORITY_DEPOSIT, AUTHORITY_WITHDRAW, MAX_WITHDRAWAL_FEE_INCREASE, MINIMUM_ACTIVE_STAKE, + TRANSIENT_STAKE_SEED, WITHDRAWAL_BASELINE_FEE, }, borsh::{BorshDeserialize, BorshSerialize}, num_traits::FromPrimitive, @@ -447,11 +448,32 @@ impl Processor { invoke_signed(&ix, &[mint, destination, authority, token_program], signers) } + /// Issue a spl_token `Transfer` instruction. + #[allow(clippy::too_many_arguments)] + fn token_transfer<'a>( + token_program: AccountInfo<'a>, + source: AccountInfo<'a>, + destination: AccountInfo<'a>, + authority: AccountInfo<'a>, + amount: u64, + ) -> Result<(), ProgramError> { + let ix = spl_token::instruction::transfer( + token_program.key, + source.key, + destination.key, + authority.key, + &[], + amount, + )?; + invoke(&ix, &[source, destination, authority, token_program]) + } + /// Processes `Initialize` instruction. fn process_initialize( program_id: &Pubkey, accounts: &[AccountInfo], fee: Fee, + withdrawal_fee: Fee, max_validators: u32, ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); @@ -594,6 +616,10 @@ impl Processor { msg!("Reserve stake account not in intialized state"); return Err(StakePoolError::WrongStakeState.into()); }; + // Numerator should be smaller than or equal to denominator (fee <= 1) + if withdrawal_fee.numerator > withdrawal_fee.denominator { + return Err(StakePoolError::FeeTooHigh.into()); + } validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; @@ -613,6 +639,9 @@ impl Processor { stake_pool.next_epoch_fee = None; stake_pool.preferred_deposit_validator_vote_address = None; stake_pool.preferred_withdraw_validator_vote_address = None; + stake_pool.deposit_fee = Fee::default(); + stake_pool.withdrawal_fee = withdrawal_fee; + stake_pool.next_withdrawal_fee = None; stake_pool .serialize(&mut *stake_pool_info.data.borrow_mut()) @@ -1619,6 +1648,10 @@ impl Processor { stake_pool.fee = next_epoch_fee; stake_pool.next_epoch_fee = None; } + if let Some(next_withdrawal_fee) = stake_pool.next_withdrawal_fee { + stake_pool.withdrawal_fee = next_withdrawal_fee; + stake_pool.next_withdrawal_fee = None; + } stake_pool.total_stake_lamports = total_stake_lamports; stake_pool.last_update_epoch = clock.epoch; @@ -1889,6 +1922,7 @@ impl Processor { let user_stake_authority_info = next_account_info(account_info_iter)?; let user_transfer_authority_info = next_account_info(account_info_iter)?; let burn_from_info = next_account_info(account_info_iter)?; + let manager_fee_info = next_account_info(account_info_iter)?; let pool_mint_info = next_account_info(account_info_iter)?; let clock_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(clock_info)?; @@ -1910,6 +1944,9 @@ impl Processor { stake_pool_info.key, )?; + if stake_pool.manager_fee_account != *manager_fee_info.key { + return Err(StakePoolError::InvalidFeeAccount.into()); + } if stake_pool.token_program_id != *token_program_info.key { return Err(ProgramError::IncorrectProgramId); } @@ -1926,8 +1963,15 @@ impl Processor { return Err(StakePoolError::InvalidState.into()); } + let pool_tokens_fee = stake_pool + .calc_pool_tokens_withdrawal_fee(pool_tokens) + .ok_or(StakePoolError::CalculationFailure)?; + let pool_tokens_burnt = pool_tokens + .checked_sub(pool_tokens_fee) + .ok_or(StakePoolError::CalculationFailure)?; + let withdraw_lamports = stake_pool - .calc_lamports_withdraw_amount(pool_tokens) + .calc_lamports_withdraw_amount(pool_tokens_burnt) .ok_or(StakePoolError::CalculationFailure)?; let has_active_stake = validator_list @@ -2026,7 +2070,7 @@ impl Processor { burn_from_info.clone(), pool_mint_info.clone(), user_transfer_authority_info.clone(), - pool_tokens, + pool_tokens_burnt, )?; Self::stake_split( @@ -2050,9 +2094,19 @@ impl Processor { stake_program_info.clone(), )?; + if pool_tokens_fee > 0 { + Self::token_transfer( + token_program_info.clone(), + burn_from_info.clone(), + manager_fee_info.clone(), + user_transfer_authority_info.clone(), + pool_tokens_fee, + )?; + } + stake_pool.pool_token_supply = stake_pool .pool_token_supply - .checked_sub(pool_tokens) + .checked_sub(pool_tokens_burnt) .ok_or(StakePoolError::CalculationFailure)?; stake_pool.total_stake_lamports = stake_pool .total_stake_lamports @@ -2166,16 +2220,91 @@ impl Processor { Ok(()) } + /// Processes [SetWithdrawalFee](enum.Instruction.html). + fn process_set_withdrawal_fee( + program_id: &Pubkey, + accounts: &[AccountInfo], + fee: Fee, + ) -> ProgramResult { + let account_info_iter = &mut accounts.iter(); + let stake_pool_info = next_account_info(account_info_iter)?; + let manager_info = next_account_info(account_info_iter)?; + let clock_info = next_account_info(account_info_iter)?; + let clock = &Clock::from_account_info(clock_info)?; + + check_account_owner(stake_pool_info, program_id)?; + let mut stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; + if !stake_pool.is_valid() { + return Err(StakePoolError::InvalidState.into()); + } + + stake_pool.check_manager(manager_info)?; + + if stake_pool.last_update_epoch < clock.epoch { + return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); + } + + // Numerator should be smaller than or equal to denominator (fee <= 1) + if fee.numerator > fee.denominator { + msg!( + "Fee greater than 100%, numerator {}, denominator {}", + fee.numerator, + fee.denominator + ); + return Err(StakePoolError::FeeTooHigh.into()); + } + + // If the previous withdrawal fee was 0, we allow the fee to be set to a + // maximum of (WITHDRAWAL_BASELINE_FEE * MAX_WITHDRAWAL_FEE_INCREASE) + let (old_num, old_denom) = if stake_pool.withdrawal_fee.denominator == 0 + || stake_pool.withdrawal_fee.numerator == 0 + { + ( + WITHDRAWAL_BASELINE_FEE.numerator, + WITHDRAWAL_BASELINE_FEE.denominator, + ) + } else { + ( + stake_pool.withdrawal_fee.numerator, + stake_pool.withdrawal_fee.denominator, + ) + }; + + // Check that new_fee / old_fee <= MAX_WITHDRAWAL_FEE_INCREASE + // Program fails if provided numerator or denominator is too large, resulting in overflow + if (old_num as u128) + .checked_mul(fee.denominator as u128) + .map(|x| x.checked_mul(MAX_WITHDRAWAL_FEE_INCREASE.numerator as u128)) + .ok_or(StakePoolError::CalculationFailure)? + < (fee.numerator as u128) + .checked_mul(old_denom as u128) + .map(|x| x.checked_mul(MAX_WITHDRAWAL_FEE_INCREASE.denominator as u128)) + .ok_or(StakePoolError::CalculationFailure)? + { + msg!( + "Fee increase exceeds maximum allowed, proposed increase factor ({} / {})", + fee.numerator * old_denom, + old_num * fee.denominator, + ); + return Err(StakePoolError::FeeIncreaseTooHigh.into()); + } + + stake_pool.next_withdrawal_fee = Some(fee); + stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; + Ok(()) + } + /// Processes [Instruction](enum.Instruction.html). pub fn process(program_id: &Pubkey, accounts: &[AccountInfo], input: &[u8]) -> ProgramResult { let instruction = StakePoolInstruction::try_from_slice(input)?; match instruction { StakePoolInstruction::Initialize { fee, + withdrawal_fee, max_validators, } => { msg!("Instruction: Initialize stake pool"); - Self::process_initialize(program_id, accounts, fee, max_validators) + Self::process_initialize(program_id, accounts, fee, withdrawal_fee, max_validators) } StakePoolInstruction::CreateValidatorStakeAccount => { msg!("Instruction: CreateValidatorStakeAccount"); @@ -2249,6 +2378,10 @@ impl Processor { msg!("Instruction: SetStaker"); Self::process_set_staker(program_id, accounts) } + StakePoolInstruction::SetWithdrawalFee { fee } => { + msg!("Instruction: SetWithdrawalFee"); + Self::process_set_withdrawal_fee(program_id, accounts, fee) + } } } } @@ -2288,6 +2421,7 @@ impl PrintProgramError for StakePoolError { StakePoolError::IncorrectDepositVoteAddress => msg!("Error: The provided deposit stake account is not delegated to the preferred deposit vote account"), StakePoolError::IncorrectWithdrawVoteAddress => msg!("Error: The provided withdraw stake account is not the preferred deposit vote account"), StakePoolError::InvalidMintFreezeAuthority => msg!("Error: The mint has an invalid freeze authority"), + StakePoolError::FeeIncreaseTooHigh => msg!("Error: The fee cannot increase by a factor exceeding the stipulated ratio"), } } } diff --git a/program/src/state.rs b/program/src/state.rs index a547b89f..13ddb0e7 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -103,6 +103,21 @@ pub struct StakePool { /// Preferred withdraw validator vote account pubkey pub preferred_withdraw_validator_vote_address: Option, + + /// Fee assessed on deposits + pub deposit_fee: Fee, + + /// Fee assessed on withdrawals + pub withdrawal_fee: Fee, + + /// Future withdrawal fee, to be set for the following epoch + pub next_withdrawal_fee: Option, + + /// Fees paid out to referrers on referred deposits. + /// Expressed as a percentage (0 - 100) of deposit fees. + /// i.e. `deposit_fee`% is collected as deposit fees for every deposit + /// and `referral_fee`% of the collected deposit fees is paid out to the referrer + pub referral_fee: u8, } impl StakePool { /// calculate the pool tokens that should be minted for a deposit of `stake_lamports` @@ -128,19 +143,22 @@ impl StakePool { .ok() } + /// calculate pool tokens to be deducted as withdrawal fees + pub fn calc_pool_tokens_withdrawal_fee(&self, pool_tokens: u64) -> Option { + u64::try_from(self.withdrawal_fee.apply(pool_tokens)?).ok() + } + /// Calculate the fee in pool tokens that goes to the manager /// /// This function assumes that `reward_lamports` has not already been added /// to the stake pool's `total_stake_lamports` pub fn calc_fee_amount(&self, reward_lamports: u64) -> Option { - if self.fee.denominator == 0 || reward_lamports == 0 { + if reward_lamports == 0 { return Some(0); } let total_stake_lamports = (self.total_stake_lamports as u128).checked_add(reward_lamports as u128)?; - let fee_lamports = (reward_lamports as u128) - .checked_mul(self.fee.numerator as u128)? - .checked_div(self.fee.denominator as u128)?; + let fee_lamports = self.fee.apply(reward_lamports)?; u64::try_from( (self.pool_token_supply as u128) .checked_mul(fee_lamports)? @@ -525,6 +543,7 @@ impl ValidatorListHeader { /// Fee rate as a ratio, minted on `UpdateStakePoolBalance` as a proportion of /// the rewards +/// If either the numerator or the denominator is 0, the fee is considered to be 0 #[repr(C)] #[derive(Clone, Copy, Debug, Default, PartialEq, BorshSerialize, BorshDeserialize, BorshSchema)] pub struct Fee { @@ -534,6 +553,22 @@ pub struct Fee { pub numerator: u64, } +impl Fee { + /// Applies the Fee's rates to a given amount, `amt` + /// returning the amount to be subtracted from it as fees + /// (0 if denominator is 0 or amt is 0), + /// or None if overflow occurs + #[inline] + pub fn apply(&self, amt: u64) -> Option { + if self.denominator == 0 { + return Some(0); + } + (amt as u128) + .checked_mul(self.numerator as u128)? + .checked_div(self.denominator as u128) + } +} + #[cfg(test)] mod test { use { diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 04641414..12afc10b 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -242,6 +242,7 @@ pub async fn create_stake_pool( staker: &Pubkey, deposit_authority: &Option, fee: &state::Fee, + withdrawal_fee: &state::Fee, max_validators: u32, ) -> Result<(), TransportError> { let rent = banks_client.get_rent().await.unwrap(); @@ -278,6 +279,7 @@ pub async fn create_stake_pool( &spl_token::id(), deposit_authority.as_ref().map(|k| k.pubkey()), *fee, + *withdrawal_fee, max_validators, ), ], @@ -517,6 +519,7 @@ pub struct StakePoolAccounts { pub deposit_authority: Pubkey, pub deposit_authority_keypair: Option, pub fee: state::Fee, + pub withdrawal_fee: state::Fee, pub max_validators: u32, } @@ -554,6 +557,10 @@ impl StakePoolAccounts { numerator: 1, denominator: 100, }, + withdrawal_fee: state::Fee { + numerator: 3, + denominator: 1000, + }, max_validators: MAX_TEST_VALIDATORS, } } @@ -569,6 +576,10 @@ impl StakePoolAccounts { amount * self.fee.numerator / self.fee.denominator } + pub fn calculate_withdrawal_fee(&self, pool_tokens: u64) -> u64 { + pool_tokens * self.withdrawal_fee.numerator / self.withdrawal_fee.denominator + } + pub async fn initialize_stake_pool( &self, mut banks_client: &mut BanksClient, @@ -619,6 +630,7 @@ impl StakePoolAccounts { &self.staker.pubkey(), &self.deposit_authority_keypair, &self.fee, + &self.withdrawal_fee, self.max_validators, ) .await?; @@ -702,6 +714,7 @@ impl StakePoolAccounts { recipient_new_authority, &user_transfer_authority.pubkey(), pool_account, + &self.pool_fee_account.pubkey(), &self.pool_mint.pubkey(), &spl_token::id(), amount, diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index 6b54a2c1..84925443 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -26,7 +26,7 @@ use { find_withdraw_authority_program_address, id, instruction::{self, PreferredValidatorType}, stake_program, - state::{AccountType, StakePool, StakeStatus, ValidatorList, ValidatorStakeInfo}, + state::{AccountType, Fee, StakePool, StakeStatus, ValidatorList, ValidatorStakeInfo}, MAX_VALIDATORS_TO_UPDATE, MINIMUM_ACTIVE_STAKE, }, spl_token::state::{Account as SplAccount, AccountState as SplAccountState, Mint}, @@ -78,6 +78,10 @@ async fn setup( next_epoch_fee: None, preferred_deposit_validator_vote_address: None, preferred_withdraw_validator_vote_address: None, + deposit_fee: Fee::default(), + withdrawal_fee: Fee::default(), + next_withdrawal_fee: None, + referral_fee: 0, }; let mut validator_list = ValidatorList::new(max_validators); @@ -722,5 +726,5 @@ async fn withdraw() { STAKE_AMOUNT, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); } diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index 0117d461..d6cb05a3 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -176,6 +176,34 @@ async fn fail_with_high_fee() { } } +#[tokio::test] +async fn fail_with_high_withdrawal_fee() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let mut stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts.withdrawal_fee = state::Fee { + numerator: 100_001, + denominator: 100_000, + }; + + let transaction_error = stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .await + .err() + .unwrap(); + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::FeeTooHigh as u32; + assert_eq!(error_index, program_error); + } + _ => { + panic!("Wrong error occurs while try to initialize stake pool with high withdrawal fee") + } + } +} + #[tokio::test] async fn fail_with_wrong_max_validators() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; @@ -225,6 +253,7 @@ async fn fail_with_wrong_max_validators() { &spl_token::id(), None, stake_pool_accounts.fee, + stake_pool_accounts.withdrawal_fee, stake_pool_accounts.max_validators, ), ], @@ -295,6 +324,7 @@ async fn fail_with_wrong_mint_authority() { &stake_pool_accounts.staker.pubkey(), &None, &stake_pool_accounts.fee, + &stake_pool_accounts.withdrawal_fee, stake_pool_accounts.max_validators, ) .await @@ -380,6 +410,7 @@ async fn fail_with_freeze_authority() { &stake_pool_accounts.staker.pubkey(), &None, &stake_pool_accounts.fee, + &stake_pool_accounts.withdrawal_fee, stake_pool_accounts.max_validators, ) .await @@ -467,6 +498,7 @@ async fn fail_with_wrong_token_program_id() { &wrong_token_program.pubkey(), None, stake_pool_accounts.fee, + stake_pool_accounts.withdrawal_fee, stake_pool_accounts.max_validators, ), ], @@ -543,6 +575,7 @@ async fn fail_with_wrong_fee_account() { &stake_pool_accounts.staker.pubkey(), &None, &stake_pool_accounts.fee, + &stake_pool_accounts.withdrawal_fee, stake_pool_accounts.max_validators, ) .await @@ -631,6 +664,7 @@ async fn fail_with_not_rent_exempt_pool() { &spl_token::id(), None, stake_pool_accounts.fee, + stake_pool_accounts.withdrawal_fee, stake_pool_accounts.max_validators, ), ], @@ -705,6 +739,7 @@ async fn fail_with_not_rent_exempt_validator_list() { &spl_token::id(), None, stake_pool_accounts.fee, + stake_pool_accounts.withdrawal_fee, stake_pool_accounts.max_validators, ), ], @@ -756,6 +791,7 @@ async fn fail_without_manager_signature() { let init_data = instruction::StakePoolInstruction::Initialize { fee: stake_pool_accounts.fee, + withdrawal_fee: stake_pool_accounts.withdrawal_fee, max_validators: stake_pool_accounts.max_validators, }; let data = init_data.try_to_vec().unwrap(); @@ -877,6 +913,7 @@ async fn fail_with_pre_minted_pool_tokens() { &stake_pool_accounts.staker.pubkey(), &None, &stake_pool_accounts.fee, + &stake_pool_accounts.withdrawal_fee, stake_pool_accounts.max_validators, ) .await @@ -938,6 +975,7 @@ async fn fail_with_bad_reserve() { &stake_pool_accounts.staker.pubkey(), &None, &stake_pool_accounts.fee, + &stake_pool_accounts.withdrawal_fee, stake_pool_accounts.max_validators, ) .await @@ -983,6 +1021,7 @@ async fn fail_with_bad_reserve() { &stake_pool_accounts.staker.pubkey(), &None, &stake_pool_accounts.fee, + &stake_pool_accounts.withdrawal_fee, stake_pool_accounts.max_validators, ) .await @@ -1031,6 +1070,7 @@ async fn fail_with_bad_reserve() { &stake_pool_accounts.staker.pubkey(), &None, &stake_pool_accounts.fee, + &stake_pool_accounts.withdrawal_fee, stake_pool_accounts.max_validators, ) .await @@ -1079,6 +1119,7 @@ async fn fail_with_bad_reserve() { &stake_pool_accounts.staker.pubkey(), &None, &stake_pool_accounts.fee, + &stake_pool_accounts.withdrawal_fee, stake_pool_accounts.max_validators, ) .await diff --git a/program/tests/set_fee.rs b/program/tests/set_fee.rs index b4af165e..fb5adb58 100644 --- a/program/tests/set_fee.rs +++ b/program/tests/set_fee.rs @@ -136,7 +136,7 @@ async fn fail_wrong_manager() { } #[tokio::test] -async fn fail_bad_fee() { +async fn fail_high_fee() { let (mut context, stake_pool_accounts, _new_fee) = setup().await; let new_fee = Fee { @@ -167,7 +167,7 @@ async fn fail_bad_fee() { let program_error = error::StakePoolError::FeeTooHigh as u32; assert_eq!(error_index, program_error); } - _ => panic!("Wrong error occurs while malicious try to set manager"), + _ => panic!("Wrong error occurs when setting fee too high"), } } @@ -216,6 +216,6 @@ async fn fail_not_updated() { let program_error = error::StakePoolError::StakeListAndPoolOutOfDate as u32; assert_eq!(error_index, program_error); } - _ => panic!("Wrong error occurs while malicious try to set manager"), + _ => panic!("Wrong error occurs when stake pool out of date"), } } diff --git a/program/tests/set_withdrawal_fee.rs b/program/tests/set_withdrawal_fee.rs new file mode 100644 index 00000000..fac2ce4b --- /dev/null +++ b/program/tests/set_withdrawal_fee.rs @@ -0,0 +1,407 @@ +#![cfg(feature = "test-bpf")] + +mod helpers; + +use { + helpers::*, + solana_program_test::*, + solana_sdk::{ + borsh::try_from_slice_unchecked, + instruction::InstructionError, + signature::{Keypair, Signer}, + transaction::{Transaction, TransactionError}, + }, + spl_stake_pool::{ + error, id, instruction, + state::{Fee, StakePool}, + }, +}; + +async fn setup(fee: Option) -> (ProgramTestContext, StakePoolAccounts, Fee) { + let mut context = program_test().start_with_context().await; + let mut stake_pool_accounts = StakePoolAccounts::new(); + if let Some(fee) = fee { + stake_pool_accounts.withdrawal_fee = fee; + } + stake_pool_accounts + .initialize_stake_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + 1, + ) + .await + .unwrap(); + let new_withdrawal_fee = Fee { + numerator: 4, + denominator: 1000, + }; + + (context, stake_pool_accounts, new_withdrawal_fee) +} + +#[tokio::test] +async fn success() { + let (mut context, stake_pool_accounts, new_withdrawal_fee) = setup(None).await; + + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + let old_withdrawal_fee = stake_pool.withdrawal_fee; + + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_withdrawal_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + new_withdrawal_fee, + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + context + .banks_client + .process_transaction(transaction) + .await + .unwrap(); + + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + + assert_eq!(stake_pool.withdrawal_fee, old_withdrawal_fee); + assert_eq!(stake_pool.next_withdrawal_fee, Some(new_withdrawal_fee)); + + let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + + context + .warp_to_slot(first_normal_slot + slots_per_epoch) + .unwrap(); + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &[], + false, + ) + .await; + + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + assert_eq!(stake_pool.withdrawal_fee, new_withdrawal_fee); + assert_eq!(stake_pool.next_withdrawal_fee, None); +} + +#[tokio::test] +async fn success_increase_fee_from_0() { + let (mut context, stake_pool_accounts, _) = setup(Some(Fee { + numerator: 0, + denominator: 1, + })) + .await; + let new_withdrawal_fee = Fee { + numerator: 15, + denominator: 10000, + }; + + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + let old_withdrawal_fee = stake_pool.withdrawal_fee; + + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_withdrawal_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + new_withdrawal_fee, + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + context + .banks_client + .process_transaction(transaction) + .await + .unwrap(); + + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + + assert_eq!(stake_pool.withdrawal_fee, old_withdrawal_fee); + assert_eq!(stake_pool.next_withdrawal_fee, Some(new_withdrawal_fee)); + + let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + + context + .warp_to_slot(first_normal_slot + slots_per_epoch) + .unwrap(); + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &[], + false, + ) + .await; + + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + assert_eq!(stake_pool.withdrawal_fee, new_withdrawal_fee); + assert_eq!(stake_pool.next_withdrawal_fee, None); +} + +#[tokio::test] +async fn fail_wrong_manager() { + let (mut context, stake_pool_accounts, new_withdrawal_fee) = setup(None).await; + + let wrong_manager = Keypair::new(); + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_withdrawal_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &wrong_manager.pubkey(), + new_withdrawal_fee, + )], + Some(&context.payer.pubkey()), + &[&context.payer, &wrong_manager], + context.last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = error::StakePoolError::WrongManager as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while signing with the wrong manager"), + } +} + +#[tokio::test] +async fn fail_high_withdrawal_fee() { + let (mut context, stake_pool_accounts, _new_withdrawal_fee) = setup(None).await; + + let new_withdrawal_fee = Fee { + numerator: 11, + denominator: 10, + }; + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_withdrawal_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + new_withdrawal_fee, + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = error::StakePoolError::FeeTooHigh as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs when setting fee too high"), + } +} + +#[tokio::test] +async fn fail_high_withdrawal_fee_increase() { + let (mut context, stake_pool_accounts, _new_withdrawal_fee) = setup(None).await; + let new_withdrawal_fee = Fee { + numerator: 46, + denominator: 10_000, + }; + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_withdrawal_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + new_withdrawal_fee, + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = error::StakePoolError::FeeIncreaseTooHigh as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs when increasing fee by too large a factor"), + } +} + +#[tokio::test] +async fn fail_high_withdrawal_fee_increase_from_0() { + let (mut context, stake_pool_accounts, _new_withdrawal_fee) = setup(Some(Fee { + numerator: 0, + denominator: 1, + })) + .await; + let new_withdrawal_fee = Fee { + numerator: 16, + denominator: 10_000, + }; + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_withdrawal_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + new_withdrawal_fee, + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = error::StakePoolError::FeeIncreaseTooHigh as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs when increasing fee by too large a factor"), + } +} + +#[tokio::test] +async fn fail_bad_fee() { + let (mut context, stake_pool_accounts, _new_fee) = setup(None).await; + + let new_withdrawal_fee = Fee { + numerator: 11, + denominator: 10, + }; + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_withdrawal_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + new_withdrawal_fee, + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = error::StakePoolError::FeeTooHigh as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs when setting fee too high"), + } +} + +#[tokio::test] +async fn fail_not_updated() { + let mut context = program_test().start_with_context().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + 1, + ) + .await + .unwrap(); + let new_withdrawal_fee = Fee { + numerator: 11, + denominator: 100, + }; + + // move forward so an update is required + context.warp_to_slot(50_000).unwrap(); + + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_withdrawal_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + new_withdrawal_fee, + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = error::StakePoolError::StakeListAndPoolOutOfDate as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs when stake pool out of date"), + } +} diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index c7b918c7..84d8f5d0 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -62,9 +62,9 @@ async fn setup() -> ( .await .unwrap(); - let tokens_to_burn = deposit_info.pool_tokens / 4; + let tokens_to_withdraw = deposit_info.pool_tokens / 4; - // Delegate tokens for burning + // Delegate tokens for withdrawing let user_transfer_authority = Keypair::new(); delegate_tokens( &mut banks_client, @@ -73,7 +73,7 @@ async fn setup() -> ( &deposit_info.pool_account.pubkey(), &deposit_info.authority, &user_transfer_authority.pubkey(), - tokens_to_burn, + tokens_to_withdraw, ) .await; @@ -96,7 +96,7 @@ async fn setup() -> ( deposit_info, user_transfer_authority, user_stake_recipient, - tokens_to_burn, + tokens_to_withdraw, ) } @@ -111,7 +111,7 @@ async fn success() { deposit_info, user_transfer_authority, user_stake_recipient, - tokens_to_burn, + tokens_to_withdraw, ) = setup().await; // Save stake pool state before withdrawal @@ -141,6 +141,13 @@ async fn success() { let user_token_balance_before = get_token_balance(&mut banks_client, &deposit_info.pool_account.pubkey()).await; + // Save pool fee token balance + let pool_fee_balance_before = get_token_balance( + &mut banks_client, + &stake_pool_accounts.pool_fee_account.pubkey(), + ) + .await; + let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts .withdraw_stake( @@ -152,7 +159,7 @@ async fn success() { &deposit_info.pool_account.pubkey(), &validator_stake_account.stake_account, &new_authority, - tokens_to_burn, + tokens_to_withdraw, ) .await; assert!(error.is_none()); @@ -161,13 +168,27 @@ async fn success() { let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + // first and only deposit, lamports:pool 1:1 + let tokens_withdrawal_fee = stake_pool_accounts.calculate_withdrawal_fee(tokens_to_withdraw); + let tokens_burnt = tokens_to_withdraw - tokens_withdrawal_fee; assert_eq!( stake_pool.total_stake_lamports, - stake_pool_before.total_stake_lamports - tokens_to_burn + stake_pool_before.total_stake_lamports - tokens_burnt ); assert_eq!( stake_pool.pool_token_supply, - stake_pool_before.pool_token_supply - tokens_to_burn + stake_pool_before.pool_token_supply - tokens_burnt + ); + + // Check manager received withdrawal fee + let pool_fee_balance = get_token_balance( + &mut banks_client, + &stake_pool_accounts.pool_fee_account.pubkey(), + ) + .await; + assert_eq!( + pool_fee_balance, + pool_fee_balance_before + tokens_withdrawal_fee, ); // Check validator stake list storage @@ -183,19 +204,19 @@ async fn success() { .unwrap(); assert_eq!( validator_stake_item.stake_lamports(), - validator_stake_item_before.stake_lamports() - tokens_to_burn + validator_stake_item_before.stake_lamports() - tokens_burnt ); assert_eq!( validator_stake_item.active_stake_lamports, validator_stake_item.stake_lamports(), ); - // Check tokens burned + // Check tokens used let user_token_balance = get_token_balance(&mut banks_client, &deposit_info.pool_account.pubkey()).await; assert_eq!( user_token_balance, - user_token_balance_before - tokens_to_burn + user_token_balance_before - tokens_to_withdraw ); // Check validator stake account balance @@ -214,7 +235,7 @@ async fn success() { get_account(&mut banks_client, &user_stake_recipient.pubkey()).await; assert_eq!( user_stake_recipient_account.lamports, - initial_stake_lamports + tokens_to_burn + initial_stake_lamports + tokens_burnt ); } @@ -244,6 +265,7 @@ async fn fail_with_wrong_stake_program() { AccountMeta::new_readonly(new_authority, false), AccountMeta::new_readonly(user_transfer_authority.pubkey(), true), AccountMeta::new(deposit_info.pool_account.pubkey(), false), + AccountMeta::new(stake_pool_accounts.pool_fee_account.pubkey(), false), AccountMeta::new(stake_pool_accounts.pool_mint.pubkey(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(spl_token::id(), false), @@ -349,6 +371,7 @@ async fn fail_with_wrong_token_program_id() { &new_authority, &user_transfer_authority.pubkey(), &deposit_info.pool_account.pubkey(), + &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), &wrong_token_program.pubkey(), tokens_to_burn, @@ -877,7 +900,7 @@ async fn success_with_reserve() { ) .await; - // Delegate tokens for burning during withdraw + // Delegate tokens for using for withdrawal let user_transfer_authority = Keypair::new(); delegate_tokens( &mut context.banks_client, @@ -968,7 +991,15 @@ async fn success_with_reserve() { .await; assert!(error.is_none()); - // Check tokens burned + // first and only deposit, lamports:pool 1:1 + let tokens_withdrawal_fee = + stake_pool_accounts.calculate_withdrawal_fee(deposit_info.pool_tokens); + assert_eq!( + deposit_info.stake_lamports + stake_rent, + deposit_info.pool_tokens, + ); + + // Check tokens used let user_token_balance = get_token_balance( &mut context.banks_client, &deposit_info.pool_account.pubkey(), @@ -986,7 +1017,7 @@ async fn success_with_reserve() { deserialize::(&reserve_stake_account.data).unwrap(); let meta = stake_state.meta().unwrap(); assert_eq!( - initial_reserve_lamports + meta.rent_exempt_reserve, + initial_reserve_lamports + meta.rent_exempt_reserve + tokens_withdrawal_fee, reserve_stake_account.lamports ); @@ -995,7 +1026,7 @@ async fn success_with_reserve() { get_account(&mut context.banks_client, &withdraw_destination.pubkey()).await; assert_eq!( user_stake_recipient_account.lamports, - initial_stake_lamports + deposit_info.stake_lamports + stake_rent + initial_stake_lamports + deposit_info.stake_lamports + stake_rent - tokens_withdrawal_fee ); } From d3c689e0d14d9d38bf511c8f7a5fd74dc38a5646 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Jul 2021 11:47:23 +0000 Subject: [PATCH 0138/1076] build(deps): bump serde_json from 1.0.64 to 1.0.65 (#2160) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.64 to 1.0.65. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.64...v1.0.65) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 9192d4f5..46f95162 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "0.4.0" [dependencies] borsh = "0.9" clap = "2.33.3" -serde_json = "1.0.62" +serde_json = "1.0.65" solana-account-decoder = "=1.7.7" solana-clap-utils = "=1.7.7" solana-cli-config = "=1.7.7" From 7a76674fddcad90f7e893403d307213e01671c21 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 29 Jul 2021 14:40:02 -0400 Subject: [PATCH 0139/1076] stake-pool-cli: Fixup help message for decrease-validator-stake (#2179) --- clients/cli/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index cb3e1c1f..fa42aa9c 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -1538,7 +1538,7 @@ fn main() { .validator(is_amount) .value_name("AMOUNT") .takes_value(true) - .help("Amount in lamports to remove from the validator stake account. Must be at least the rent-exempt amount for a stake."), + .help("Amount in SOL to remove from the validator stake account. Must be at least the rent-exempt amount for a stake."), ) ) .subcommand(SubCommand::with_name("set-preferred-validator") From e844906da2befc4d012209081b97b90ac8b6429c Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 29 Jul 2021 17:56:50 -0400 Subject: [PATCH 0140/1076] stake-pool: Don't assess withdrawal fee from fee account (#2180) --- program/src/processor.rs | 10 ++++-- program/tests/helpers/mod.rs | 26 ++++++++++++++ program/tests/withdraw.rs | 69 ++++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 3 deletions(-) diff --git a/program/src/processor.rs b/program/src/processor.rs index afa97a7e..c215e900 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1963,9 +1963,13 @@ impl Processor { return Err(StakePoolError::InvalidState.into()); } - let pool_tokens_fee = stake_pool - .calc_pool_tokens_withdrawal_fee(pool_tokens) - .ok_or(StakePoolError::CalculationFailure)?; + let pool_tokens_fee = if stake_pool.manager_fee_account == *burn_from_info.key { + 0 + } else { + stake_pool + .calc_pool_tokens_withdrawal_fee(pool_tokens) + .ok_or(StakePoolError::CalculationFailure)? + }; let pool_tokens_burnt = pool_tokens .checked_sub(pool_tokens_fee) .ok_or(StakePoolError::CalculationFailure)?; diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 12afc10b..03675567 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -99,6 +99,32 @@ pub async fn transfer( banks_client.process_transaction(transaction).await.unwrap(); } +pub async fn transfer_spl_tokens( + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + source: &Pubkey, + destination: &Pubkey, + authority: &Keypair, + amount: u64, +) { + let transaction = Transaction::new_signed_with_payer( + &[spl_token::instruction::transfer( + &spl_token::id(), + source, + destination, + &authority.pubkey(), + &[], + amount, + ) + .unwrap()], + Some(&payer.pubkey()), + &[payer, authority], + *recent_blockhash, + ); + banks_client.process_transaction(transaction).await.unwrap(); +} + pub async fn create_token_account( banks_client: &mut BanksClient, payer: &Keypair, diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 84d8f5d0..291e7f0e 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -1336,3 +1336,72 @@ async fn success_withdraw_from_transient() { .await; assert!(error.is_none()); } + +#[tokio::test] +async fn success_withdraw_all_fee_tokens() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + validator_stake_account, + deposit_info, + user_transfer_authority, + user_stake_recipient, + tokens_to_withdraw, + ) = setup().await; + + // move tokens to fee account + transfer_spl_tokens( + &mut banks_client, + &payer, + &recent_blockhash, + &deposit_info.pool_account.pubkey(), + &stake_pool_accounts.pool_fee_account.pubkey(), + &user_transfer_authority, + tokens_to_withdraw, + ) + .await; + + let fee_tokens = get_token_balance( + &mut banks_client, + &stake_pool_accounts.pool_fee_account.pubkey(), + ) + .await; + + let user_transfer_authority = Keypair::new(); + delegate_tokens( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.pool_fee_account.pubkey(), + &stake_pool_accounts.manager, + &user_transfer_authority.pubkey(), + fee_tokens, + ) + .await; + + let new_authority = Pubkey::new_unique(); + let error = stake_pool_accounts + .withdraw_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake_recipient.pubkey(), + &user_transfer_authority, + &stake_pool_accounts.pool_fee_account.pubkey(), + &validator_stake_account.stake_account, + &new_authority, + fee_tokens, + ) + .await; + assert!(error.is_none()); + + // Check balance is 0 + let fee_tokens = get_token_balance( + &mut banks_client, + &stake_pool_accounts.pool_fee_account.pubkey(), + ) + .await; + assert_eq!(fee_tokens, 0); +} From dc4378be71d957bbdf4ddff73469948cb0680a66 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 30 Jul 2021 11:13:27 +0000 Subject: [PATCH 0141/1076] build(deps): bump serde_json from 1.0.65 to 1.0.66 (#2187) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.65 to 1.0.66. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.65...v1.0.66) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 46f95162..6bd750a5 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "0.4.0" [dependencies] borsh = "0.9" clap = "2.33.3" -serde_json = "1.0.65" +serde_json = "1.0.66" solana-account-decoder = "=1.7.7" solana-clap-utils = "=1.7.7" solana-cli-config = "=1.7.7" From 2b3fea9c46885c69b89e26b7d60ed63e677a8249 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Aug 2021 11:15:36 +0000 Subject: [PATCH 0142/1076] build(deps): bump serde from 1.0.126 to 1.0.127 (#2200) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.126 to 1.0.127. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.126...v1.0.127) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 62793d14..9c62d781 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,7 +17,7 @@ borsh = "0.9" num-derive = "0.3" num-traits = "0.2" num_enum = "0.5.2" -serde = "1.0.126" +serde = "1.0.127" serde_derive = "1.0.103" solana-program = "1.7.7" spl-token = { version = "3.2", path = "../../token/program", features = [ "no-entrypoint" ] } From f2e9e56767d5319080436bc3eba8978028cf2ca2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Aug 2021 11:16:44 +0000 Subject: [PATCH 0143/1076] build(deps): bump num_enum from 0.5.2 to 0.5.3 (#2207) Bumps [num_enum](https://github.com/illicitonion/num_enum) from 0.5.2 to 0.5.3. - [Release notes](https://github.com/illicitonion/num_enum/releases) - [Commits](https://github.com/illicitonion/num_enum/compare/0.5.2...0.5.3) --- updated-dependencies: - dependency-name: num_enum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 9c62d781..6205103c 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -16,7 +16,7 @@ arrayref = "0.3.6" borsh = "0.9" num-derive = "0.3" num-traits = "0.2" -num_enum = "0.5.2" +num_enum = "0.5.3" serde = "1.0.127" serde_derive = "1.0.103" solana-program = "1.7.7" From 3a0a0f10f462760c47fd0716ef0d8da425f894a3 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 5 Aug 2021 10:25:37 -0400 Subject: [PATCH 0144/1076] stake-pool: Make it impossible to leech value (#2218) --- program/Cargo.toml | 1 + program/src/error.rs | 6 ++++ program/src/processor.rs | 10 ++++++ program/src/state.rs | 73 ++++++++++++++++++++++++++++++++------- program/tests/withdraw.rs | 70 +++---------------------------------- 5 files changed, 81 insertions(+), 79 deletions(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 6205103c..70c29823 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -20,6 +20,7 @@ num_enum = "0.5.3" serde = "1.0.127" serde_derive = "1.0.103" solana-program = "1.7.7" +spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-token = { version = "3.2", path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" bincode = "1.3.1" diff --git a/program/src/error.rs b/program/src/error.rs index c0edb105..55e45b7e 100644 --- a/program/src/error.rs +++ b/program/src/error.rs @@ -102,6 +102,12 @@ pub enum StakePoolError { /// Proposed fee increase exceeds stipulated ratio #[error("FeeIncreaseTooHigh")] FeeIncreaseTooHigh, + /// Not enough pool tokens provided to withdraw stake with one lamport + #[error("WithdrawalTooSmall")] + WithdrawalTooSmall, + /// Not enough lamports provided for deposit to result in one pool token + #[error("DepositTooSmall")] + DepositTooSmall, } impl From for ProgramError { fn from(e: StakePoolError) -> Self { diff --git a/program/src/processor.rs b/program/src/processor.rs index c215e900..4a3e10a8 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1858,6 +1858,10 @@ impl Processor { .calc_pool_tokens_for_deposit(all_deposit_lamports) .ok_or(StakePoolError::CalculationFailure)?; + if new_pool_tokens == 0 { + return Err(StakePoolError::DepositTooSmall.into()); + } + Self::token_mint_to( stake_pool_info.key, token_program_info.clone(), @@ -1978,6 +1982,10 @@ impl Processor { .calc_lamports_withdraw_amount(pool_tokens_burnt) .ok_or(StakePoolError::CalculationFailure)?; + if withdraw_lamports == 0 { + return Err(StakePoolError::WithdrawalTooSmall.into()); + } + let has_active_stake = validator_list .find::( &0u64.to_le_bytes(), @@ -2426,6 +2434,8 @@ impl PrintProgramError for StakePoolError { StakePoolError::IncorrectWithdrawVoteAddress => msg!("Error: The provided withdraw stake account is not the preferred deposit vote account"), StakePoolError::InvalidMintFreezeAuthority => msg!("Error: The mint has an invalid freeze authority"), StakePoolError::FeeIncreaseTooHigh => msg!("Error: The fee cannot increase by a factor exceeding the stipulated ratio"), + StakePoolError::WithdrawalTooSmall => msg!("Error: Not enough pool tokens provided to withdraw 1-lamport stake"), + StakePoolError::DepositTooSmall => msg!("Error: Not enough lamports provided for deposit to result in one pool token"), } } } diff --git a/program/src/state.rs b/program/src/state.rs index 13ddb0e7..13faef5f 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -14,6 +14,7 @@ use { program_pack::{Pack, Sealed}, pubkey::{Pubkey, PUBKEY_BYTES}, }, + spl_math::checked_ceil_div::CheckedCeilDiv, std::convert::TryFrom, }; @@ -135,12 +136,10 @@ impl StakePool { /// calculate lamports amount on withdrawal pub fn calc_lamports_withdraw_amount(&self, pool_tokens: u64) -> Option { - u64::try_from( - (pool_tokens as u128) - .checked_mul(self.total_stake_lamports as u128)? - .checked_div(self.pool_token_supply as u128)?, - ) - .ok() + let (quotient, _) = (pool_tokens as u128) + .checked_mul(self.total_stake_lamports as u128)? + .checked_ceil_div(self.pool_token_supply as u128)?; + u64::try_from(quotient).ok() } /// calculate pool tokens to be deducted as withdrawal fees @@ -159,12 +158,16 @@ impl StakePool { let total_stake_lamports = (self.total_stake_lamports as u128).checked_add(reward_lamports as u128)?; let fee_lamports = self.fee.apply(reward_lamports)?; - u64::try_from( - (self.pool_token_supply as u128) - .checked_mul(fee_lamports)? - .checked_div(total_stake_lamports.checked_sub(fee_lamports)?)?, - ) - .ok() + if total_stake_lamports == fee_lamports || self.pool_token_supply == 0 { + Some(reward_lamports) + } else { + u64::try_from( + (self.pool_token_supply as u128) + .checked_mul(fee_lamports)? + .checked_div(total_stake_lamports.checked_sub(fee_lamports)?)?, + ) + .ok() + } } /// Checks that the withdraw or deposit authority is valid @@ -777,7 +780,22 @@ mod test { let fee_lamports = stake_pool .calc_lamports_withdraw_amount(pool_token_fee) .unwrap(); - assert_eq!(fee_lamports, LAMPORTS_PER_SOL - 1); // lose 1 lamport of precision + assert_eq!(fee_lamports, LAMPORTS_PER_SOL); + } + + #[test] + fn divide_by_zero_fee() { + let stake_pool = StakePool { + total_stake_lamports: 0, + fee: Fee { + numerator: 1, + denominator: 10, + }, + ..StakePool::default() + }; + let rewards = 10; + let fee = stake_pool.calc_fee_amount(rewards).unwrap(); + assert_eq!(fee, rewards); } proptest! { @@ -814,4 +832,33 @@ mod test { max_fee_lamports, fee_lamports, epsilon); } } + + prop_compose! { + fn total_tokens_and_deposit()(total_lamports in 1..u64::MAX)( + total_lamports in Just(total_lamports), + pool_token_supply in 1..=total_lamports, + deposit_lamports in 1..total_lamports, + ) -> (u64, u64, u64) { + (total_lamports - deposit_lamports, pool_token_supply.saturating_sub(deposit_lamports).max(1), deposit_lamports) + } + } + + proptest! { + #[test] + fn deposit_and_withdraw( + (total_stake_lamports, pool_token_supply, deposit_stake) in total_tokens_and_deposit() + ) { + let mut stake_pool = StakePool { + total_stake_lamports, + pool_token_supply, + ..StakePool::default() + }; + let deposit_result = stake_pool.calc_pool_tokens_for_deposit(deposit_stake).unwrap(); + prop_assume!(deposit_result > 0); + stake_pool.total_stake_lamports += deposit_stake; + stake_pool.pool_token_supply += deposit_result; + let withdraw_result = stake_pool.calc_lamports_withdraw_amount(deposit_result).unwrap(); + assert!(withdraw_result <= deposit_stake); + } + } } diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 291e7f0e..9c496e38 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -448,10 +448,10 @@ async fn fail_with_unknown_validator() { recent_blockhash, stake_pool_accounts, _, - _, + deposit_info, user_transfer_authority, user_stake_recipient, - _, + tokens_to_withdraw, ) = setup().await; let validator_stake_account = @@ -475,69 +475,7 @@ async fn fail_with_unknown_validator() { ) .await; - let user_pool_account = Keypair::new(); - let user = Keypair::new(); - create_token_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_pool_account, - &stake_pool_accounts.pool_mint.pubkey(), - &user.pubkey(), - ) - .await - .unwrap(); - - let user = Keypair::new(); - // make stake account - let user_stake = Keypair::new(); - let lockup = stake_program::Lockup::default(); - let authorized = stake_program::Authorized { - staker: stake_pool_accounts.deposit_authority, - withdrawer: stake_pool_accounts.deposit_authority, - }; - create_independent_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake, - &authorized, - &lockup, - TEST_STAKE_AMOUNT, - ) - .await; - // make pool token account - let user_pool_account = Keypair::new(); - create_token_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_pool_account, - &stake_pool_accounts.pool_mint.pubkey(), - &user.pubkey(), - ) - .await - .unwrap(); - - let user_pool_account = user_pool_account.pubkey(); - let pool_tokens = get_token_balance(&mut banks_client, &user_pool_account).await; - - let tokens_to_burn = pool_tokens / 4; - - // Delegate tokens for burning - delegate_tokens( - &mut banks_client, - &payer, - &recent_blockhash, - &user_pool_account, - &user, - &user_transfer_authority.pubkey(), - tokens_to_burn, - ) - .await; - let new_authority = Pubkey::new_unique(); - let transaction_error = stake_pool_accounts .withdraw_stake( &mut banks_client, @@ -545,10 +483,10 @@ async fn fail_with_unknown_validator() { &recent_blockhash, &user_stake_recipient.pubkey(), &user_transfer_authority, - &user_pool_account, + &deposit_info.pool_account.pubkey(), &validator_stake_account.stake_account, &new_authority, - tokens_to_burn, + tokens_to_withdraw, ) .await .unwrap() From a0c2137e69ddcd9edc0d63525f284b123f94666c Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 10 Aug 2021 15:56:20 -0400 Subject: [PATCH 0145/1076] stake-pool: Fix zero withdraw calculation (#2251) --- program/src/state.rs | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/program/src/state.rs b/program/src/state.rs index 13faef5f..e765aafa 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -136,10 +136,17 @@ impl StakePool { /// calculate lamports amount on withdrawal pub fn calc_lamports_withdraw_amount(&self, pool_tokens: u64) -> Option { - let (quotient, _) = (pool_tokens as u128) - .checked_mul(self.total_stake_lamports as u128)? - .checked_ceil_div(self.pool_token_supply as u128)?; - u64::try_from(quotient).ok() + // `checked_ceil_div` returns `None` for a 0 quotient result, but in this + // case, a return of 0 is valid for small amounts of pool tokens. So + // we check for that separately + let numerator = (pool_tokens as u128).checked_mul(self.total_stake_lamports as u128)?; + let denominator = self.pool_token_supply as u128; + if numerator < denominator || denominator == 0 { + Some(0) + } else { + let (quotient, _) = numerator.checked_ceil_div(denominator)?; + u64::try_from(quotient).ok() + } } /// calculate pool tokens to be deducted as withdrawal fees @@ -783,6 +790,20 @@ mod test { assert_eq!(fee_lamports, LAMPORTS_PER_SOL); } + #[test] + fn zero_withdraw_calculation() { + let fee = Fee { + numerator: 0, + denominator: 1, + }; + let stake_pool = StakePool { + fee, + ..StakePool::default() + }; + let fee_lamports = stake_pool.calc_lamports_withdraw_amount(0).unwrap(); + assert_eq!(fee_lamports, 0); + } + #[test] fn divide_by_zero_fee() { let stake_pool = StakePool { From 72383abf8894b1e6626d4bac6f7f14f9bdcec79f Mon Sep 17 00:00:00 2001 From: jon-chuang <9093549+jon-chuang@users.noreply.github.com> Date: Wed, 11 Aug 2021 12:15:45 +0800 Subject: [PATCH 0146/1076] Stake pool/liquid deposits (rebased on new master) (#2141) * rename staking instructions * modify DepositStake te to include manager fees and referrer, continue _stake refactor, referral fees WIP * initialize with fees, fee application, checks * inline functions * temporarily substitute u8 for bool until borsh gets it's * straight * set deposit fee * apply deposit and referral fee to liquid deposit_sol too * add set-deposit-fee, unify cli interface * set-referral-fee * full feature set for liquid deposits (?) * add tests/set_referral_fee.rs * fix missing serialization in process_set_referral_fee * remove duplicated test case in tests/set_withdrawal_fee.rs * tests WIP, numbers dont add up after non-zero deposit fee * fix error, fix tests * deposit_sol tests. Requires additional changes to work properly * simplify deposit_sol tests, add referral fee tests for deposit and deposit_sol * add `sol_deposit_authority`. * split deposit_sol() & deposit_sol_with_authority(), cli sol_deposit --from, minor cleanup * cli deposit-sol from argument should take keypair instead * commands: set-sol-deposit-authority, show * cli: pretty print stake pool struct * chore: comments/naming * fmt, clippy * add args for `create-pool` * mistake in the cli * `system_prog` is `read_only`, require sig from `stake_deposit_auth` * change deposit-sol-authority arg to optional acount, rename instruction::withdraw->withdraw_stake, remove unnecesary sys_prog arg for withdraw_stake * resolve simple nits and suggestions * cli: change default referrer to user's token receiver account instead of pool manager * cli: remove show command, add fees to list command, rename pool -> epoch * update tests for removed unnecessary referral fee account owner check and deposit sol * cli changes: create ephemeral account for deposit_sol * specify pool token type for account info name * add check for manager fee acc in deposit_sol * Apply suggestions from code review Co-authored-by: Jon Cinque * fix non-rebased bug * SetDepositStakeAuthority * refactor + tests + cli * fmt * clippy * remove unnecessary comment * ASK keyword * unset deposit auth * combine set fee instructions * clippy * applying suggestions * apply out-of-date check only for FeeTypes that need it * add fee + user = new tokens check * Fix test * Unify `SetDepositAuthority` instruction * fmt Co-authored-by: dhy1996 Co-authored-by: Jesse Y. Cho Co-authored-by: Jon Cinque --- clients/cli/scripts/deposit-withdraw.sh | 4 +- clients/cli/src/main.rs | 580 +++++++++++++++--- program/src/error.rs | 8 + program/src/instruction.rs | 313 ++++++++-- program/src/lib.rs | 2 + program/src/processor.rs | 457 +++++++++----- program/src/state.rs | 223 ++++++- program/tests/decrease.rs | 2 +- program/tests/deposit.rs | 148 ++++- program/tests/deposit_sol.rs | 493 +++++++++++++++ program/tests/helpers/mod.rs | 136 +++- program/tests/huge_pool.rs | 19 +- program/tests/increase.rs | 2 +- program/tests/initialize.rs | 37 +- program/tests/set_deposit_authority.rs | 359 +++++++++++ program/tests/set_deposit_fee.rs | 274 +++++++++ program/tests/set_fee.rs | 8 +- program/tests/set_referral_fee.rs | 258 ++++++++ program/tests/set_withdrawal_fee.rs | 36 -- program/tests/update_stake_pool_balance.rs | 11 +- .../tests/update_validator_list_balance.rs | 2 +- program/tests/vsa_remove.rs | 4 +- program/tests/withdraw.rs | 91 ++- 23 files changed, 3076 insertions(+), 391 deletions(-) create mode 100644 program/tests/deposit_sol.rs create mode 100644 program/tests/set_deposit_authority.rs create mode 100644 program/tests/set_deposit_fee.rs create mode 100644 program/tests/set_referral_fee.rs diff --git a/clients/cli/scripts/deposit-withdraw.sh b/clients/cli/scripts/deposit-withdraw.sh index f8508135..318cee52 100755 --- a/clients/cli/scripts/deposit-withdraw.sh +++ b/clients/cli/scripts/deposit-withdraw.sh @@ -47,7 +47,7 @@ deposit_stakes () { for validator in $(cat $validator_list) do stake=$(solana-keygen pubkey $keys_dir/stake_$validator.json) - $spl_stake_pool deposit $stake_pool_pubkey $stake + $spl_stake_pool deposit-stake $stake_pool_pubkey $stake done } @@ -57,7 +57,7 @@ withdraw_stakes () { pool_amount=$3 for validator in $(cat $validator_list) do - $spl_stake_pool withdraw $stake_pool_pubkey $pool_amount --vote-account $validator + $spl_stake_pool withdraw-stake $stake_pool_pubkey $pool_amount --vote-account $validator done } diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index fa42aa9c..41386b35 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -13,6 +13,7 @@ use { input_parsers::{keypair_of, pubkey_of}, input_validators::{ is_amount, is_keypair, is_keypair_or_ask_keyword, is_parsable, is_pubkey, is_url, + is_valid_percentage, }, keypair::signer_from_path, }, @@ -38,7 +39,7 @@ use { find_withdraw_authority_program_address, instruction::PreferredValidatorType, stake_program::{self, StakeState}, - state::{Fee, StakePool, ValidatorList}, + state::{Fee, FeeType, StakePool, ValidatorList}, }, std::{process::exit, sync::Arc}, }; @@ -49,6 +50,7 @@ struct Config { manager: Box, staker: Box, depositor: Option>, + sol_depositor: Option>, token_owner: Box, fee_payer: Box, dry_run: bool, @@ -153,9 +155,11 @@ fn checked_transaction_with_signers( #[allow(clippy::too_many_arguments)] fn command_create_pool( config: &Config, - deposit_authority: Option, + stake_deposit_authority: Option, fee: Fee, withdrawal_fee: Fee, + stake_deposit_fee: Fee, + stake_referral_fee: u8, max_validators: u32, stake_pool_keypair: Option, mint_keypair: Option, @@ -283,9 +287,11 @@ fn command_create_pool( &mint_keypair.pubkey(), &pool_fee_account, &spl_token::id(), - deposit_authority, + stake_deposit_authority.as_ref().map(|x| x.pubkey()), fee, withdrawal_fee, + stake_deposit_fee, + stake_referral_fee, max_validators, ), ], @@ -311,8 +317,15 @@ fn command_create_pool( &validator_list, config.manager.as_ref(), ]; - unique_signers!(initialize_signers); - initialize_transaction.sign(&initialize_signers, recent_blockhash); + if let Some(stake_deposit_authority) = stake_deposit_authority { + let mut initialize_signers = initialize_signers.clone(); + initialize_signers.push(&stake_deposit_authority); + unique_signers!(initialize_signers); + initialize_transaction.sign(&initialize_signers, recent_blockhash); + } else { + unique_signers!(initialize_signers); + initialize_transaction.sign(&initialize_signers, recent_blockhash); + } send_transaction(config, initialize_transaction)?; Ok(()) } @@ -567,11 +580,12 @@ fn add_associated_token_account( account } -fn command_deposit( +fn command_deposit_stake( config: &Config, stake_pool_address: &Pubkey, stake: &Pubkey, - token_receiver: &Option, + pool_token_receiver_account: &Option, + referrer_token_account: &Option, ) -> CommandResult { if !config.no_update { command_update(config, stake_pool_address, false, false)?; @@ -613,44 +627,50 @@ fn command_deposit( let mut total_rent_free_balances: u64 = 0; // Create token account if not specified - let token_receiver = token_receiver.unwrap_or(add_associated_token_account( - config, - &stake_pool.pool_mint, - &config.token_owner.pubkey(), - &mut instructions, - &mut total_rent_free_balances, - )); + let pool_token_receiver_account = + pool_token_receiver_account.unwrap_or(add_associated_token_account( + config, + &stake_pool.pool_mint, + &config.token_owner.pubkey(), + &mut instructions, + &mut total_rent_free_balances, + )); + + let referrer_token_account = referrer_token_account.unwrap_or(pool_token_receiver_account); let pool_withdraw_authority = find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; - let mut deposit_instructions = if let Some(deposit_authority) = config.depositor.as_ref() { - signers.push(deposit_authority.as_ref()); - if deposit_authority.pubkey() != stake_pool.deposit_authority { + let mut deposit_instructions = if let Some(stake_deposit_authority) = config.depositor.as_ref() + { + signers.push(stake_deposit_authority.as_ref()); + if stake_deposit_authority.pubkey() != stake_pool.stake_deposit_authority { let error = format!( "Invalid deposit authority specified, expected {}, received {}", - stake_pool.deposit_authority, - deposit_authority.pubkey() + stake_pool.stake_deposit_authority, + stake_deposit_authority.pubkey() ); return Err(error.into()); } - spl_stake_pool::instruction::deposit_with_authority( + spl_stake_pool::instruction::deposit_stake_with_authority( &spl_stake_pool::id(), stake_pool_address, &stake_pool.validator_list, - &deposit_authority.pubkey(), + &stake_deposit_authority.pubkey(), &pool_withdraw_authority, stake, &config.staker.pubkey(), &validator_stake_account, &stake_pool.reserve_stake, - &token_receiver, + &pool_token_receiver_account, + &stake_pool.manager_fee_account, + &referrer_token_account, &stake_pool.pool_mint, &spl_token::id(), ) } else { - spl_stake_pool::instruction::deposit( + spl_stake_pool::instruction::deposit_stake( &spl_stake_pool::id(), stake_pool_address, &stake_pool.validator_list, @@ -659,7 +679,9 @@ fn command_deposit( &config.staker.pubkey(), &validator_stake_account, &stake_pool.reserve_stake, - &token_receiver, + &pool_token_receiver_account, + &stake_pool.manager_fee_account, + &referrer_token_account, &stake_pool.pool_mint, &spl_token::id(), ) @@ -681,6 +703,136 @@ fn command_deposit( Ok(()) } +fn command_deposit_sol( + config: &Config, + stake_pool_address: &Pubkey, + from: &Option, + pool_token_receiver_account: &Option, + referrer_token_account: &Option, + amount: f64, +) -> CommandResult { + if !config.no_update { + command_update(config, stake_pool_address, false, false)?; + } + + let amount = native_token::sol_to_lamports(amount); + + // Check withdraw_from balance + let from_pubkey = from.as_ref().map_or_else( + || config.fee_payer.try_pubkey().unwrap(), + |keypair| keypair.try_pubkey().unwrap(), + ); + let from_balance = config.rpc_client.get_balance(&from_pubkey)?; + if from_balance < amount { + return Err(format!( + "Not enough SOL to deposit into pool: {}.\nMaximum deposit amount is {} SOL.", + Sol(amount), + Sol(from_balance) + ) + .into()); + } + + let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; + + let mut instructions: Vec = vec![]; + + // ephemeral SOL account just to do the transfer + let user_sol_transfer = Keypair::new(); + let mut signers = vec![ + config.fee_payer.as_ref(), + config.staker.as_ref(), + &user_sol_transfer, + ]; + if let Some(keypair) = from.as_ref() { + signers.push(keypair) + } + + let mut total_rent_free_balances: u64 = 0; + + // Create the ephemeral SOL account + instructions.push(system_instruction::transfer( + &from_pubkey, + &user_sol_transfer.pubkey(), + amount, + )); + + // Create token account if not specified + let pool_token_receiver_account = + pool_token_receiver_account.unwrap_or(add_associated_token_account( + config, + &stake_pool.pool_mint, + &config.token_owner.pubkey(), + &mut instructions, + &mut total_rent_free_balances, + )); + + let referrer_token_account = referrer_token_account.unwrap_or(pool_token_receiver_account); + + let pool_withdraw_authority = + find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; + + let mut deposit_instructions = if let Some(sol_deposit_authority) = + config.sol_depositor.as_ref() + { + let expected_sol_deposit_authority = stake_pool.sol_deposit_authority.ok_or_else(|| { + "SOL deposit authority specified in arguments but stake pool has none".to_string() + })?; + signers.push(sol_deposit_authority.as_ref()); + if sol_deposit_authority.pubkey() != expected_sol_deposit_authority { + let error = format!( + "Invalid deposit authority specified, expected {}, received {}", + expected_sol_deposit_authority, + sol_deposit_authority.pubkey() + ); + return Err(error.into()); + } + + spl_stake_pool::instruction::deposit_sol_with_authority( + &spl_stake_pool::id(), + stake_pool_address, + &sol_deposit_authority.pubkey(), + &pool_withdraw_authority, + &stake_pool.reserve_stake, + &user_sol_transfer.pubkey(), + &pool_token_receiver_account, + &stake_pool.manager_fee_account, + &referrer_token_account, + &stake_pool.pool_mint, + &spl_token::id(), + amount, + ) + } else { + spl_stake_pool::instruction::deposit_sol( + &spl_stake_pool::id(), + stake_pool_address, + &pool_withdraw_authority, + &stake_pool.reserve_stake, + &user_sol_transfer.pubkey(), + &pool_token_receiver_account, + &stake_pool.manager_fee_account, + &referrer_token_account, + &stake_pool.pool_mint, + &spl_token::id(), + amount, + ) + }; + + instructions.append(&mut deposit_instructions); + + let mut transaction = + Transaction::new_with_payer(&instructions, Some(&config.fee_payer.pubkey())); + + let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + check_fee_payer_balance( + config, + total_rent_free_balances + fee_calculator.calculate_fee(transaction.message()), + )?; + unique_signers!(signers); + transaction.sign(&signers, recent_blockhash); + send_transaction(config, transaction)?; + Ok(()) +} + fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?; @@ -688,6 +840,9 @@ fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { let epoch_info = config.rpc_client.get_epoch_info()?; let pool_withdraw_authority = find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; + let sol_deposit_authority = stake_pool + .sol_deposit_authority + .map_or("None".into(), |pubkey| pubkey.to_string()); if config.verbose { println!("Stake Pool Info"); @@ -696,7 +851,8 @@ fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { println!("Validator List: {}", stake_pool.validator_list); println!("Manager: {}", stake_pool.manager); println!("Staker: {}", stake_pool.staker); - println!("Depositor: {}", stake_pool.deposit_authority); + println!("Depositor: {}", stake_pool.stake_deposit_authority); + println!("SOL Deposit Authority: {}", sol_deposit_authority); println!("Withdraw Authority: {}", pool_withdraw_authority); println!("Pool Token Mint: {}", stake_pool.pool_mint); println!("Fee Account: {}", stake_pool.manager_fee_account); @@ -718,13 +874,52 @@ fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { preferred_withdraw_validator ); } - if stake_pool.fee.numerator > 0 { + + // Display fees information + if stake_pool.fee.numerator > 0 && stake_pool.fee.denominator > 0 { + println!("Epoch Fee: {} of epoch rewards", stake_pool.fee); + } else { + println!("Epoch Fee: none"); + } + if stake_pool.withdrawal_fee.numerator > 0 && stake_pool.withdrawal_fee.denominator > 0 { + println!( + "Withdrawal Fee: {} of withdrawal amount", + stake_pool.withdrawal_fee + ); + } else { + println!("Withdrawal Fee: none"); + } + if stake_pool.stake_deposit_fee.numerator > 0 && stake_pool.stake_deposit_fee.denominator > 0 { println!( - "Fee: {}/{} of epoch rewards", - stake_pool.fee.numerator, stake_pool.fee.denominator + "Stake Deposit Fee: {} of staked amount", + stake_pool.stake_deposit_fee ); } else { - println!("Fee: none"); + println!("Stake Deposit Fee: none"); + } + if stake_pool.sol_deposit_fee.numerator > 0 && stake_pool.sol_deposit_fee.denominator > 0 { + println!( + "SOL Deposit Fee: {} of deposit amount", + stake_pool.sol_deposit_fee + ); + } else { + println!("SOL Deposit Fee: none"); + } + if stake_pool.sol_referral_fee > 0 { + println!( + "SOL Deposit Referral Fee: {}% of SOL Deposit Fee", + stake_pool.sol_referral_fee + ); + } else { + println!("SOL Deposit Referral Fee: none"); + } + if stake_pool.stake_referral_fee > 0 { + println!( + "Stake Deposit Referral Fee: {}% of Stake Deposit Fee", + stake_pool.stake_referral_fee + ); + } else { + println!("Stake Deposit Referral Fee: none"); } if config.verbose { @@ -1079,7 +1274,7 @@ fn command_withdraw( stake_receiver_pubkey }); - instructions.push(spl_stake_pool::instruction::withdraw( + instructions.push(spl_stake_pool::instruction::withdraw_stake( &spl_stake_pool::id(), stake_pool_address, &stake_pool.validator_list, @@ -1179,16 +1374,22 @@ fn command_set_staker( Ok(()) } -fn command_set_fee(config: &Config, stake_pool_address: &Pubkey, new_fee: Fee) -> CommandResult { +fn command_set_deposit_authority( + config: &Config, + stake_pool_address: &Pubkey, + new_sol_deposit_authority: Option, + for_stake_deposit: bool, +) -> CommandResult { let mut signers = vec![config.fee_payer.as_ref(), config.manager.as_ref()]; unique_signers!(signers); let transaction = checked_transaction_with_signers( config, - &[spl_stake_pool::instruction::set_fee( + &[spl_stake_pool::instruction::set_deposit_authority( &spl_stake_pool::id(), stake_pool_address, &config.manager.pubkey(), - new_fee, + new_sol_deposit_authority.as_ref(), + for_stake_deposit, )], &signers, )?; @@ -1196,16 +1397,16 @@ fn command_set_fee(config: &Config, stake_pool_address: &Pubkey, new_fee: Fee) - Ok(()) } -fn command_set_withdrawal_fee( +fn command_set_fee( config: &Config, stake_pool_address: &Pubkey, - new_fee: Fee, + new_fee: FeeType, ) -> CommandResult { let mut signers = vec![config.fee_payer.as_ref(), config.manager.as_ref()]; unique_signers!(signers); let transaction = checked_transaction_with_signers( config, - &[spl_stake_pool::instruction::set_withdrawal_fee( + &[spl_stake_pool::instruction::set_fee( &spl_stake_pool::id(), stake_pool_address, &config.manager.pubkey(), @@ -1366,6 +1567,31 @@ fn main() { .requires("withdrawal_fee_numerator") .help("Withdrawal fee denominator, fee amount is numerator divided by denominator [default: 0]"), ) + .arg( + Arg::with_name("deposit_fee_numerator") + .long("deposit-fee-numerator") + .validator(is_parsable::) + .value_name("NUMERATOR") + .takes_value(true) + .requires("deposit_fee_denominator") + .help("Deposit fee numerator, fee amount is numerator divided by denominator [default: 0]"), + ).arg( + Arg::with_name("deposit_fee_denominator") + .long("deposit-fee-denominator") + .validator(is_parsable::) + .value_name("DENOMINATOR") + .takes_value(true) + .requires("deposit_fee_numerator") + .help("Deposit fee denominator, fee amount is numerator divided by denominator [default: 0]"), + ) + .arg( + Arg::with_name("referral_fee") + .long("referral-fee") + .validator(is_valid_percentage) + .value_name("FEE_PERCENTAGE") + .takes_value(true) + .help("Referral fee percentage, maximum 100"), + ) .arg( Arg::with_name("max_validators") .long("max-validators") @@ -1377,11 +1603,11 @@ fn main() { .help("Max number of validators included in the stake pool"), ) .arg( - Arg::with_name("deposit_authority") - .long("deposit-authority") + Arg::with_name("stake_deposit_authority") + .long("stake-deposit-authority") .short("a") - .validator(is_pubkey) - .value_name("DEPOSIT_AUTHORITY_ADDRESS") + .validator(is_keypair_or_ask_keyword) + .value_name("STAKE_DEPOSIT_AUTHORITY_KEYPAIR") .takes_value(true) .help("Deposit authority required to sign all deposits into the stake pool"), ) @@ -1581,8 +1807,8 @@ fn main() { .required(true) ) ) - .subcommand(SubCommand::with_name("deposit") - .about("Add stake account to the stake pool") + .subcommand(SubCommand::with_name("deposit-stake") + .about("Deposit active stake account into the stake pool in exchange for pool tokens") .arg( Arg::with_name("pool") .index(1) @@ -1611,6 +1837,61 @@ fn main() { Defaults to the token-owner's associated pool token account. \ Creates the account if it does not exist."), ) + .arg( + Arg::with_name("referrer") + .validator(is_pubkey) + .value_name("ADDRESS") + .takes_value(true) + .help("Pool token account to receive the referral fees for deposits. \ + Defaults to the token receiver."), + ) + ) + .subcommand(SubCommand::with_name("deposit-sol") + .about("Deposit SOL into the stake pool in exchange for pool tokens") + .arg( + Arg::with_name("pool") + .index(1) + .validator(is_pubkey) + .value_name("POOL_ADDRESS") + .takes_value(true) + .required(true) + .help("Stake pool address"), + ).arg( + Arg::with_name("amount") + .index(2) + .validator(is_amount) + .value_name("AMOUNT") + .takes_value(true) + .help("Amount in SOL to deposit into the stake pool reserve account."), + ) + .arg( + Arg::with_name("from") + .long("from") + .validator(is_keypair_or_ask_keyword) + .value_name("KEYPAIR") + .takes_value(true) + .help("Source account of funds. \ + Defaults to the fee payer."), + ) + .arg( + Arg::with_name("token_receiver") + .long("token-receiver") + .validator(is_pubkey) + .value_name("POOL_TOKEN_RECEIVER_ADDRESS") + .takes_value(true) + .help("Account to receive the minted pool tokens. \ + Defaults to the token-owner's associated pool token account. \ + Creates the account if it does not exist."), + ) + .arg( + Arg::with_name("referrer") + .long("referrer") + .validator(is_pubkey) + .value_name("REFERRER_TOKEN_ADDRESS") + .takes_value(true) + .help("Account to receive the referral fees for deposits. \ + Defaults to the token receiver."), + ) ) .subcommand(SubCommand::with_name("list") .about("List stake accounts managed by this pool") @@ -1648,7 +1929,7 @@ fn main() { .help("Do not automatically merge transient stakes. Useful if the stake pool is in an expected state, but the balances still need to be updated."), ) ) - .subcommand(SubCommand::with_name("withdraw") + .subcommand(SubCommand::with_name("withdraw-stake") .about("Withdraw amount from the stake pool") .arg( Arg::with_name("pool") @@ -1758,8 +2039,70 @@ fn main() { .help("Public key for the new stake pool staker."), ) ) + .subcommand(SubCommand::with_name("set-sol-deposit-authority") + .about("Change sol deposit authority account for the stake pool. Must be signed by the manager.") + .arg( + Arg::with_name("pool") + .index(1) + .validator(is_pubkey) + .value_name("POOL_ADDRESS") + .takes_value(true) + .required(true) + .help("Stake pool address."), + ) + .arg( + Arg::with_name("new_sol_deposit_authority") + .index(2) + .validator(is_pubkey) + .value_name("ADDRESS") + .takes_value(true) + .help("The public key for the new stake pool sol deposit authority."), + ) + .arg( + Arg::with_name("unset") + .long("unset") + .takes_value(false) + .help("Unset the sol deposit authority.") + ) + .group(ArgGroup::with_name("validator") + .arg("new_sol_deposit_authority") + .arg("unset") + .required(true) + ) + ) + .subcommand(SubCommand::with_name("set-stake-deposit-authority") + .about("Change stake deposit authority account for the stake pool. Must be signed by the manager.") + .arg( + Arg::with_name("pool") + .index(1) + .validator(is_pubkey) + .value_name("POOL_ADDRESS") + .takes_value(true) + .required(true) + .help("Stake pool address."), + ) + .arg( + Arg::with_name("new_stake_deposit_authority") + .index(2) + .validator(is_pubkey) + .value_name("ADDRESS_OR_NONE") + .takes_value(true) + .help("'none', or a public key for the new stake pool sol deposit authority."), + ) + .arg( + Arg::with_name("unset") + .long("unset") + .takes_value(false) + .help("Unset the stake deposit authority. The program will use a program derived address.") + ) + .group(ArgGroup::with_name("validator") + .arg("new_stake_deposit_authority") + .arg("unset") + .required(true) + ) + ) .subcommand(SubCommand::with_name("set-fee") - .about("Change the fee assessed by the stake pool. Must be signed by the manager.") + .about("Change the [management/withdrawal/stake deposit/sol deposit] fee assessed by the stake pool. Must be signed by the manager.") .arg( Arg::with_name("pool") .index(1) @@ -1769,9 +2112,17 @@ fn main() { .required(true) .help("Stake pool address."), ) + .arg(Arg::with_name("fee_type") + .index(2) + .value_name("FEE_TYPE") + .possible_values(&["epoch", "stake-deposit", "sol-deposit", "withdrawal"]) // PreferredValidatorType enum + .takes_value(true) + .required(true) + .help("Fee type to be updated."), + ) .arg( Arg::with_name("fee_numerator") - .index(2) + .index(3) .validator(is_parsable::) .value_name("NUMERATOR") .takes_value(true) @@ -1780,7 +2131,7 @@ fn main() { ) .arg( Arg::with_name("fee_denominator") - .index(3) + .index(4) .validator(is_parsable::) .value_name("DENOMINATOR") .takes_value(true) @@ -1788,8 +2139,8 @@ fn main() { .help("Fee denominator, fee amount is numerator divided by denominator."), ) ) - .subcommand(SubCommand::with_name("set-withdrawal-fee") - .about("Change the withdrawal fee assessed by the stake pool. Must be signed by the manager.") + .subcommand(SubCommand::with_name("set-stake-referral-fee") + .about("Change the referral fee assessed by the stake pool for stake deposits. Must be signed by the manager.") .arg( Arg::with_name("pool") .index(1) @@ -1800,22 +2151,33 @@ fn main() { .help("Stake pool address."), ) .arg( - Arg::with_name("fee_numerator") + Arg::with_name("fee") .index(2) - .validator(is_parsable::) - .value_name("NUMERATOR") + .validator(is_valid_percentage) + .value_name("FEE_PERCENTAGE") .takes_value(true) .required(true) - .help("Fee numerator, fee amount is numerator divided by denominator."), + .help("Fee percentage, maximum 100"), ) + ).subcommand(SubCommand::with_name("set-sol-referral-fee") + .about("Change the referral fee assessed by the stake pool for SOL deposits. Must be signed by the manager.") .arg( - Arg::with_name("fee_denominator") - .index(3) - .validator(is_parsable::) - .value_name("DENOMINATOR") + Arg::with_name("pool") + .index(1) + .validator(is_pubkey) + .value_name("POOL_ADDRESS") .takes_value(true) .required(true) - .help("Fee denominator, fee amount is numerator divided by denominator."), + .help("Stake pool address."), + ) + .arg( + Arg::with_name("fee") + .index(2) + .validator(is_valid_percentage) + .value_name("FEE_PERCENTAGE") + .takes_value(true) + .required(true) + .help("Fee percentage, maximum 100"), ) ) .get_matches(); @@ -1847,6 +2209,16 @@ fn main() { } else { None }; + let sol_depositor = if matches.is_present("sol_depositor") { + Some(get_signer( + &matches, + "sol_depositor", + &cli_config.keypair_path, + &mut wallet_manager, + )) + } else { + None + }; let manager = get_signer( &matches, "manager", @@ -1875,6 +2247,7 @@ fn main() { manager, staker, depositor, + sol_depositor, token_owner, fee_payer, dry_run, @@ -1884,18 +2257,21 @@ fn main() { let _ = match matches.subcommand() { ("create-pool", Some(arg_matches)) => { - let deposit_authority = pubkey_of(arg_matches, "deposit_authority"); + let stake_deposit_authority = keypair_of(arg_matches, "stake_deposit_authority"); let numerator = value_t_or_exit!(arg_matches, "fee_numerator", u64); let denominator = value_t_or_exit!(arg_matches, "fee_denominator", u64); let w_numerator = value_t!(arg_matches, "withdrawal_fee_numerator", u64); let w_denominator = value_t!(arg_matches, "withdrawal_fee_denominator", u64); + let d_numerator = value_t!(arg_matches, "deposit_fee_numerator", u64); + let d_denominator = value_t!(arg_matches, "deposit_fee_denominator", u64); + let referral_fee = value_t!(arg_matches, "referral_fee", u8); let max_validators = value_t_or_exit!(arg_matches, "max_validators", u32); let pool_keypair = keypair_of(arg_matches, "pool_keypair"); let mint_keypair = keypair_of(arg_matches, "mint_keypair"); let reserve_keypair = keypair_of(arg_matches, "reserve_keypair"); command_create_pool( &config, - deposit_authority, + stake_deposit_authority, Fee { denominator, numerator, @@ -1904,6 +2280,11 @@ fn main() { numerator: w_numerator.unwrap_or(0), denominator: w_denominator.unwrap_or(0), }, + Fee { + numerator: d_numerator.unwrap_or(0), + denominator: d_denominator.unwrap_or(0), + }, + referral_fee.unwrap_or(0), max_validators, pool_keypair, mint_keypair, @@ -1956,15 +2337,32 @@ fn main() { vote_account, ) } - ("deposit", Some(arg_matches)) => { + ("deposit-stake", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); let stake_account = pubkey_of(arg_matches, "stake_account").unwrap(); let token_receiver: Option = pubkey_of(arg_matches, "token_receiver"); - command_deposit( + let referrer: Option = pubkey_of(arg_matches, "referrer"); + command_deposit_stake( &config, &stake_pool_address, &stake_account, &token_receiver, + &referrer, + ) + } + ("deposit-sol", Some(arg_matches)) => { + let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); + let token_receiver: Option = pubkey_of(arg_matches, "token_receiver"); + let referrer: Option = pubkey_of(arg_matches, "referrer"); + let from = keypair_of(arg_matches, "from"); + let amount = value_t_or_exit!(arg_matches, "amount", f64); + command_deposit_sol( + &config, + &stake_pool_address, + &from, + &token_receiver, + &referrer, + amount, ) } ("list", Some(arg_matches)) => { @@ -1977,7 +2375,7 @@ fn main() { let force = arg_matches.is_present("force"); command_update(&config, &stake_pool_address, force, no_merge) } - ("withdraw", Some(arg_matches)) => { + ("withdraw-stake", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); let vote_account = pubkey_of(arg_matches, "vote_account"); let pool_account = pubkey_of(arg_matches, "pool_account"); @@ -2010,6 +2408,28 @@ fn main() { let new_staker = pubkey_of(arg_matches, "new_staker").unwrap(); command_set_staker(&config, &stake_pool_address, &new_staker) } + ("set-stake-deposit-authority", Some(arg_matches)) => { + let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); + let new_stake_deposit_authority = pubkey_of(arg_matches, "new_stake_deposit_authority"); + let _unset = arg_matches.is_present("unset"); + command_set_deposit_authority( + &config, + &stake_pool_address, + new_stake_deposit_authority, + true, + ) + } + ("set-sol-deposit-authority", Some(arg_matches)) => { + let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); + let new_sol_deposit_authority = pubkey_of(arg_matches, "new_sol_deposit_authority"); + let _unset = arg_matches.is_present("unset"); + command_set_deposit_authority( + &config, + &stake_pool_address, + new_sol_deposit_authority, + false, + ) + } ("set-fee", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); let numerator = value_t_or_exit!(arg_matches, "fee_numerator", u64); @@ -2018,17 +2438,35 @@ fn main() { denominator, numerator, }; - command_set_fee(&config, &stake_pool_address, new_fee) + match arg_matches.value_of("fee_type").unwrap() { + "epoch" => command_set_fee(&config, &stake_pool_address, FeeType::Epoch(new_fee)), + "stake-deposit" => { + command_set_fee(&config, &stake_pool_address, FeeType::StakeDeposit(new_fee)) + } + "sol-deposit" => { + command_set_fee(&config, &stake_pool_address, FeeType::SolDeposit(new_fee)) + } + "withdrawal" => { + command_set_fee(&config, &stake_pool_address, FeeType::Withdrawal(new_fee)) + } + _ => unreachable!(), + } } - ("set-withdrawal-fee", Some(arg_matches)) => { + ("set-stake-referral-fee", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); - let numerator = value_t_or_exit!(arg_matches, "fee_numerator", u64); - let denominator = value_t_or_exit!(arg_matches, "fee_denominator", u64); - let new_fee = Fee { - denominator, - numerator, - }; - command_set_withdrawal_fee(&config, &stake_pool_address, new_fee) + let fee = value_t_or_exit!(arg_matches, "fee", u8); + if fee > 100u8 { + panic!("Invalid fee {}%. Fee needs to be in range [0-100]", fee); + } + command_set_fee(&config, &stake_pool_address, FeeType::StakeReferral(fee)) + } + ("set-sol-referral-fee", Some(arg_matches)) => { + let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); + let fee = value_t_or_exit!(arg_matches, "fee", u8); + if fee > 100u8 { + panic!("Invalid fee {}%. Fee needs to be in range [0-100]", fee); + } + command_set_fee(&config, &stake_pool_address, FeeType::SolReferral(fee)) } _ => unreachable!(), } diff --git a/program/src/error.rs b/program/src/error.rs index 55e45b7e..c526b4b1 100644 --- a/program/src/error.rs +++ b/program/src/error.rs @@ -108,6 +108,14 @@ pub enum StakePoolError { /// Not enough lamports provided for deposit to result in one pool token #[error("DepositTooSmall")] DepositTooSmall, + + // 30. + /// Provided stake deposit authority does not match the program's + #[error("FeeIncreaseTooHigh")] + InvalidStakeDepositAuthority, + /// Provided sol deposit authority does not match the program's + #[error("InvalidSolDepositAuthority")] + InvalidSolDepositAuthority, } impl From for ProgramError { fn from(e: StakePoolError) -> Self { diff --git a/program/src/instruction.rs b/program/src/instruction.rs index ab35ef66..0eecffa2 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -6,7 +6,7 @@ use { find_deposit_authority_program_address, find_stake_program_address, find_transient_stake_program_address, find_withdraw_authority_program_address, stake_program, - state::{Fee, StakePool, ValidatorList}, + state::{Fee, FeeType, StakePool, ValidatorList}, MAX_VALIDATORS_TO_UPDATE, }, borsh::{BorshDeserialize, BorshSchema, BorshSerialize}, @@ -28,6 +28,17 @@ pub enum PreferredValidatorType { Withdraw, } +/// Defines which validator vote account is set during the +/// `SetPreferredValidator` instruction +#[repr(C)] +#[derive(Clone, Debug, PartialEq, BorshSerialize, BorshDeserialize, BorshSchema)] +pub enum DepositType { + /// Set preferred validator for deposits + Stake, + /// Set preferred validator for withdraws + Sol, +} + /// Instructions supported by the StakePool program. #[repr(C)] #[derive(Clone, Debug, PartialEq, BorshSerialize, BorshDeserialize, BorshSchema)] @@ -55,6 +66,12 @@ pub enum StakePoolInstruction { /// Fee charged per withdrawal as percentage of withdrawal #[allow(dead_code)] // but it's not withdrawal_fee: Fee, + /// Fee charged per deposit as percentage of deposit + #[allow(dead_code)] // but it's not + deposit_fee: Fee, + /// Percentage [0-100] of deposit_fee that goes to referrer + #[allow(dead_code)] // but it's not + referral_fee: u8, /// Maximum expected number of validators #[allow(dead_code)] // but it's not max_validators: u32, @@ -244,18 +261,20 @@ pub enum StakePoolInstruction { /// /// 0. `[w]` Stake pool /// 1. `[w]` Validator stake list storage account - /// 2. `[]` Stake pool deposit authority + /// 2. `[s]/[]` Stake pool deposit authority /// 3. `[]` Stake pool withdraw authority /// 4. `[w]` Stake account to join the pool (withdraw authority for the stake account should be first set to the stake pool deposit authority) /// 5. `[w]` Validator stake account for the stake account to be merged with /// 6. `[w]` Reserve stake account, to withdraw rent exempt reserve /// 7. `[w]` User account to receive pool tokens - /// 8. `[w]` Pool token mint account - /// 9. '[]' Sysvar clock account - /// 10. '[]' Sysvar stake history account - /// 11. `[]` Pool token program id, - /// 12. `[]` Stake program id, - Deposit, + /// 8. `[w]` Account to receive pool fee tokens + /// 9. `[w]` Account to receive a portion of pool fee tokens as referral fees + /// 10. `[w]` Pool token mint account + /// 11. '[]' Sysvar clock account + /// 12. '[]' Sysvar stake history account + /// 13. `[]` Pool token program id, + /// 14. `[]` Stake program id, + DepositStake, /// Withdraw the token from the pool at the current ratio. /// @@ -281,7 +300,7 @@ pub enum StakePoolInstruction { /// 11. `[]` Pool token program id /// 12. `[]` Stake program id, /// userdata: amount of pool tokens to withdraw - Withdraw(u64), + WithdrawStake(u64), /// (Manager only) Update manager /// @@ -297,9 +316,9 @@ pub enum StakePoolInstruction { /// 1. `[s]` Manager /// 2. `[]` Sysvar clock SetFee { - /// Fee assessed as percentage of perceived rewards + /// Type of fee to update and value to update it to #[allow(dead_code)] // but it's not - fee: Fee, + fee: FeeType, }, /// (Manager or staker only) Update staker @@ -309,16 +328,29 @@ pub enum StakePoolInstruction { /// 2. '[]` New staker pubkey SetStaker, - /// (Manager only) Update Withdrawal fee for next epoch + /// Deposit SOL directly into the pool's reserve account. The output is a "pool" token + /// representing ownership into the pool. Inputs are converted to the current ratio. + /// + /// 0. `[w]` Stake pool + /// 1. `[s]/[]` Stake pool sol deposit authority. + /// 2. `[]` Stake pool withdraw authority + /// 3. `[w]` Reserve stake account, to withdraw rent exempt reserve + /// 4. `[s]` Account providing the lamports to be deposited into the pool + /// 5. `[w]` User account to receive pool tokens + /// 6. `[w]` Account to receive pool fee tokens + /// 7. `[w]` Account to receive a portion of pool fee tokens as referral fees + /// 8. `[w]` Pool token mint account + /// 9. '[]' Sysvar clock account + /// 10 `[]` System program account + /// 11. `[]` Pool token program id, + DepositSol(u64), + + /// (Manager only) Update SOL deposit authority /// /// 0. `[w]` StakePool /// 1. `[s]` Manager - /// 2. `[]` Sysvar clock - SetWithdrawalFee { - /// Fee assessed as percentage of perceived rewards - #[allow(dead_code)] // but it's not - fee: Fee, - }, + /// 2. '[]` New sol_deposit_authority pubkey or none + SetDepositAuthority(DepositType), } /// Creates an 'initialize' instruction. @@ -335,11 +367,15 @@ pub fn initialize( deposit_authority: Option, fee: Fee, withdrawal_fee: Fee, + deposit_fee: Fee, + referral_fee: u8, max_validators: u32, ) -> Instruction { let init_data = StakePoolInstruction::Initialize { fee, withdrawal_fee, + deposit_fee, + referral_fee, max_validators, }; let data = init_data.try_to_vec().unwrap(); @@ -826,7 +862,7 @@ pub fn update_stake_pool( /// Creates instructions required to deposit into a stake pool, given a stake /// account owned by the user. -pub fn deposit( +pub fn deposit_stake( program_id: &Pubkey, stake_pool: &Pubkey, validator_list_storage: &Pubkey, @@ -836,6 +872,8 @@ pub fn deposit( validator_stake_account: &Pubkey, reserve_stake_account: &Pubkey, pool_tokens_to: &Pubkey, + manager_fee_account: &Pubkey, + referrer_pool_tokens_account: &Pubkey, pool_mint: &Pubkey, token_program_id: &Pubkey, ) -> Vec { @@ -850,6 +888,8 @@ pub fn deposit( AccountMeta::new(*validator_stake_account, false), AccountMeta::new(*reserve_stake_account, false), AccountMeta::new(*pool_tokens_to, false), + AccountMeta::new(*manager_fee_account, false), + AccountMeta::new(*referrer_pool_tokens_account, false), AccountMeta::new(*pool_mint, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), @@ -872,7 +912,7 @@ pub fn deposit( Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::Deposit.try_to_vec().unwrap(), + data: StakePoolInstruction::DepositStake.try_to_vec().unwrap(), }, ] } @@ -880,7 +920,7 @@ pub fn deposit( /// Creates instructions required to deposit into a stake pool, given a stake /// account owned by the user. The difference with `deposit()` is that a deposit /// authority must sign this instruction, which is required for private pools. -pub fn deposit_with_authority( +pub fn deposit_stake_with_authority( program_id: &Pubkey, stake_pool: &Pubkey, validator_list_storage: &Pubkey, @@ -891,6 +931,8 @@ pub fn deposit_with_authority( validator_stake_account: &Pubkey, reserve_stake_account: &Pubkey, pool_tokens_to: &Pubkey, + manager_fee_account: &Pubkey, + referrer_pool_tokens_account: &Pubkey, pool_mint: &Pubkey, token_program_id: &Pubkey, ) -> Vec { @@ -903,6 +945,8 @@ pub fn deposit_with_authority( AccountMeta::new(*validator_stake_account, false), AccountMeta::new(*reserve_stake_account, false), AccountMeta::new(*pool_tokens_to, false), + AccountMeta::new(*manager_fee_account, false), + AccountMeta::new(*referrer_pool_tokens_account, false), AccountMeta::new(*pool_mint, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), @@ -925,13 +969,91 @@ pub fn deposit_with_authority( Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::Deposit.try_to_vec().unwrap(), + data: StakePoolInstruction::DepositStake.try_to_vec().unwrap(), }, ] } -/// Creates a 'withdraw' instruction. -pub fn withdraw( +/// Creates instructions required to deposit SOL directly into a stake pool. +pub fn deposit_sol( + program_id: &Pubkey, + stake_pool: &Pubkey, + stake_pool_withdraw_authority: &Pubkey, + reserve_stake_account: &Pubkey, + lamports_from: &Pubkey, + pool_tokens_to: &Pubkey, + manager_fee_account: &Pubkey, + referrer_pool_tokens_account: &Pubkey, + pool_mint: &Pubkey, + token_program_id: &Pubkey, + amount: u64, +) -> Vec { + let accounts = vec![ + AccountMeta::new(*stake_pool, false), + AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), + AccountMeta::new(*reserve_stake_account, false), + AccountMeta::new(*lamports_from, true), + AccountMeta::new(*pool_tokens_to, false), + AccountMeta::new(*manager_fee_account, false), + AccountMeta::new(*referrer_pool_tokens_account, false), + AccountMeta::new(*pool_mint, false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(system_program::id(), false), + AccountMeta::new_readonly(*token_program_id, false), + ]; + vec![Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::DepositSol(amount) + .try_to_vec() + .unwrap(), + }] +} + +/// Creates instructions required to deposit SOL directly into a stake pool. +/// The difference with `deposit_sol()` is that a deposit +/// authority must sign this instruction, which is required for private pools. +/// `require_deposit_authority` should be false only if +/// `sol_deposit_authority == None` +pub fn deposit_sol_with_authority( + program_id: &Pubkey, + stake_pool: &Pubkey, + sol_deposit_authority: &Pubkey, + stake_pool_withdraw_authority: &Pubkey, + reserve_stake_account: &Pubkey, + lamports_from: &Pubkey, + pool_tokens_to: &Pubkey, + manager_fee_account: &Pubkey, + referrer_pool_tokens_account: &Pubkey, + pool_mint: &Pubkey, + token_program_id: &Pubkey, + amount: u64, +) -> Vec { + let accounts = vec![ + AccountMeta::new(*stake_pool, false), + AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), + AccountMeta::new(*reserve_stake_account, false), + AccountMeta::new(*lamports_from, true), + AccountMeta::new(*pool_tokens_to, false), + AccountMeta::new(*manager_fee_account, false), + AccountMeta::new(*referrer_pool_tokens_account, false), + AccountMeta::new(*pool_mint, false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(system_program::id(), false), + AccountMeta::new_readonly(*token_program_id, false), + AccountMeta::new_readonly(*sol_deposit_authority, true), + ]; + vec![Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::DepositSol(amount) + .try_to_vec() + .unwrap(), + }] +} + +/// Creates a 'WithdrawStake' instruction. +pub fn withdraw_stake( program_id: &Pubkey, stake_pool: &Pubkey, validator_list_storage: &Pubkey, @@ -964,7 +1086,9 @@ pub fn withdraw( Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::Withdraw(amount).try_to_vec().unwrap(), + data: StakePoolInstruction::WithdrawStake(amount) + .try_to_vec() + .unwrap(), } } @@ -994,7 +1118,7 @@ pub fn set_fee( program_id: &Pubkey, stake_pool: &Pubkey, manager: &Pubkey, - fee: Fee, + fee: FeeType, ) -> Instruction { let accounts = vec![ AccountMeta::new(*stake_pool, false), @@ -1008,42 +1132,157 @@ pub fn set_fee( } } -/// Creates a 'set fee' instruction. +/// Creates a 'set fee' instruction for setting the epoch fee +pub fn set_epoch_fee( + program_id: &Pubkey, + stake_pool: &Pubkey, + manager: &Pubkey, + fee: Fee, +) -> Instruction { + set_fee(program_id, stake_pool, manager, FeeType::Epoch(fee)) +} + +/// Creates a 'set fee' instruction for setting withdrawal fee pub fn set_withdrawal_fee( program_id: &Pubkey, stake_pool: &Pubkey, manager: &Pubkey, fee: Fee, +) -> Instruction { + set_fee(program_id, stake_pool, manager, FeeType::Withdrawal(fee)) +} + +/// Creates a 'set fee' instruction for setting SOL deposit fee +pub fn set_sol_deposit_fee( + program_id: &Pubkey, + stake_pool: &Pubkey, + manager: &Pubkey, + fee: Fee, +) -> Instruction { + set_fee(program_id, stake_pool, manager, FeeType::SolDeposit(fee)) +} + +/// Creates a 'set fee' instruction for setting stake deposit fee +pub fn set_stake_deposit_fee( + program_id: &Pubkey, + stake_pool: &Pubkey, + manager: &Pubkey, + fee: Fee, +) -> Instruction { + set_fee(program_id, stake_pool, manager, FeeType::StakeDeposit(fee)) +} + +/// Creates a 'set fee' instruction for setting SOL referral fee +pub fn set_sol_referral_fee( + program_id: &Pubkey, + stake_pool: &Pubkey, + manager: &Pubkey, + fee: u8, +) -> Instruction { + set_fee(program_id, stake_pool, manager, FeeType::SolReferral(fee)) +} + +/// Creates a 'set fee' instruction for setting stake referral fee +pub fn set_stake_referral_fee( + program_id: &Pubkey, + stake_pool: &Pubkey, + manager: &Pubkey, + fee: u8, +) -> Instruction { + set_fee(program_id, stake_pool, manager, FeeType::StakeReferral(fee)) +} + +/// Creates a 'set staker' instruction. +pub fn set_staker( + program_id: &Pubkey, + stake_pool: &Pubkey, + set_staker_authority: &Pubkey, + new_staker: &Pubkey, ) -> Instruction { let accounts = vec![ + AccountMeta::new(*stake_pool, false), + AccountMeta::new_readonly(*set_staker_authority, true), + AccountMeta::new_readonly(*new_staker, false), + ]; + Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::SetStaker.try_to_vec().unwrap(), + } +} + +/// Creates a 'set sol deposit authority' instruction. +pub fn set_deposit_authority( + program_id: &Pubkey, + stake_pool: &Pubkey, + manager: &Pubkey, + new_sol_deposit_authority: Option<&Pubkey>, + for_stake_deposit: bool, +) -> Instruction { + let mut accounts = vec![ AccountMeta::new(*stake_pool, false), AccountMeta::new_readonly(*manager, true), - AccountMeta::new_readonly(sysvar::clock::id(), false), ]; + if let Some(auth) = new_sol_deposit_authority { + accounts.push(AccountMeta::new_readonly(*auth, false)) + } Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::SetWithdrawalFee { fee } + data: if for_stake_deposit { + StakePoolInstruction::SetDepositAuthority(DepositType::Stake) + .try_to_vec() + .unwrap() + } else { + StakePoolInstruction::SetDepositAuthority(DepositType::Sol) + .try_to_vec() + .unwrap() + }, + } +} + +/// Creates a 'set stake deposit authority' instruction. +pub fn set_stake_deposit_authority( + program_id: &Pubkey, + stake_pool: &Pubkey, + manager: &Pubkey, + new_stake_deposit_authority: Option<&Pubkey>, +) -> Instruction { + let mut accounts = vec![ + AccountMeta::new(*stake_pool, false), + AccountMeta::new_readonly(*manager, true), + ]; + if let Some(auth) = new_stake_deposit_authority { + accounts.push(AccountMeta::new_readonly(*auth, false)) + } + Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::SetDepositAuthority(DepositType::Stake) .try_to_vec() .unwrap(), } } -/// Creates a 'set staker' instruction. -pub fn set_staker( +/// Creates a 'set stake deposit authority' instruction. +pub fn set_sol_deposit_authority( program_id: &Pubkey, stake_pool: &Pubkey, - set_staker_authority: &Pubkey, - new_staker: &Pubkey, + manager: &Pubkey, + new_stake_deposit_authority: Option<&Pubkey>, ) -> Instruction { - let accounts = vec![ + let mut accounts = vec![ AccountMeta::new(*stake_pool, false), - AccountMeta::new_readonly(*set_staker_authority, true), - AccountMeta::new_readonly(*new_staker, false), + AccountMeta::new_readonly(*manager, true), ]; + if let Some(auth) = new_stake_deposit_authority { + accounts.push(AccountMeta::new_readonly(*auth, false)) + } Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::SetStaker.try_to_vec().unwrap(), + data: StakePoolInstruction::SetDepositAuthority(DepositType::Sol) + .try_to_vec() + .unwrap(), } } diff --git a/program/src/lib.rs b/program/src/lib.rs index 4ba5cf4d..0c71bb41 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -51,6 +51,7 @@ pub const WITHDRAWAL_BASELINE_FEE: Fee = Fee { /// Get the stake amount under consideration when calculating pool token /// conversions +#[inline] pub fn minimum_stake_lamports(meta: &Meta) -> u64 { meta.rent_exempt_reserve .saturating_add(MINIMUM_ACTIVE_STAKE) @@ -58,6 +59,7 @@ pub fn minimum_stake_lamports(meta: &Meta) -> u64 { /// Get the stake amount under consideration when calculating pool token /// conversions +#[inline] pub fn minimum_reserve_lamports(meta: &Meta) -> u64 { meta.rent_exempt_reserve.saturating_add(1) } diff --git a/program/src/processor.rs b/program/src/processor.rs index 4a3e10a8..15cd4719 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1,5 +1,6 @@ //! Program state processor +use crate::instruction::DepositType; use { crate::{ error::StakePoolError, @@ -7,11 +8,10 @@ use { instruction::{PreferredValidatorType, StakePoolInstruction}, minimum_reserve_lamports, minimum_stake_lamports, stake_program, state::{ - AccountType, Fee, StakePool, StakeStatus, ValidatorList, ValidatorListHeader, + AccountType, Fee, FeeType, StakePool, StakeStatus, ValidatorList, ValidatorListHeader, ValidatorStakeInfo, }, - AUTHORITY_DEPOSIT, AUTHORITY_WITHDRAW, MAX_WITHDRAWAL_FEE_INCREASE, MINIMUM_ACTIVE_STAKE, - TRANSIENT_STAKE_SEED, WITHDRAWAL_BASELINE_FEE, + AUTHORITY_DEPOSIT, AUTHORITY_WITHDRAW, MINIMUM_ACTIVE_STAKE, TRANSIENT_STAKE_SEED, }, borsh::{BorshDeserialize, BorshSerialize}, num_traits::FromPrimitive, @@ -468,12 +468,24 @@ impl Processor { invoke(&ix, &[source, destination, authority, token_program]) } + fn sol_transfer<'a>( + source: AccountInfo<'a>, + destination: AccountInfo<'a>, + system_program: AccountInfo<'a>, + amount: u64, + ) -> Result<(), ProgramError> { + let ix = solana_program::system_instruction::transfer(source.key, destination.key, amount); + invoke(&ix, &[source, destination, system_program]) + } + /// Processes `Initialize` instruction. fn process_initialize( program_id: &Pubkey, accounts: &[AccountInfo], fee: Fee, withdrawal_fee: Fee, + stake_deposit_fee: Fee, + stake_referral_fee: u8, max_validators: u32, ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); @@ -538,7 +550,11 @@ impl Processor { } // Numerator should be smaller than or equal to denominator (fee <= 1) - if fee.numerator > fee.denominator { + if fee.numerator > fee.denominator + || withdrawal_fee.numerator > withdrawal_fee.denominator + || stake_deposit_fee.numerator > stake_deposit_fee.denominator + || stake_referral_fee > 100u8 + { return Err(StakePoolError::FeeTooHigh.into()); } @@ -556,11 +572,11 @@ impl Processor { return Err(StakePoolError::WrongAccountMint.into()); } - let deposit_authority = match next_account_info(account_info_iter) { - Ok(deposit_authority_info) => *deposit_authority_info.key, + let stake_deposit_authority = match next_account_info(account_info_iter) { + Ok(stake_deposit_authority_info) => *stake_deposit_authority_info.key, Err(_) => find_deposit_authority_program_address(program_id, stake_pool_info.key).0, }; - let (withdraw_authority_key, withdraw_bump_seed) = + let (withdraw_authority_key, stake_withdraw_bump_seed) = crate::find_withdraw_authority_program_address(program_id, stake_pool_info.key); let pool_mint = Mint::unpack_from_slice(&pool_mint_info.data.borrow())?; @@ -616,10 +632,6 @@ impl Processor { msg!("Reserve stake account not in intialized state"); return Err(StakePoolError::WrongStakeState.into()); }; - // Numerator should be smaller than or equal to denominator (fee <= 1) - if withdrawal_fee.numerator > withdrawal_fee.denominator { - return Err(StakePoolError::FeeTooHigh.into()); - } validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; @@ -627,8 +639,8 @@ impl Processor { stake_pool.manager = *manager_info.key; stake_pool.staker = *staker_info.key; stake_pool.reserve_stake = *reserve_stake_info.key; - stake_pool.deposit_authority = deposit_authority; - stake_pool.withdraw_bump_seed = withdraw_bump_seed; + stake_pool.stake_deposit_authority = stake_deposit_authority; + stake_pool.stake_withdraw_bump_seed = stake_withdraw_bump_seed; stake_pool.validator_list = *validator_list_info.key; stake_pool.pool_mint = *pool_mint_info.key; stake_pool.manager_fee_account = *manager_fee_info.key; @@ -639,9 +651,11 @@ impl Processor { stake_pool.next_epoch_fee = None; stake_pool.preferred_deposit_validator_vote_address = None; stake_pool.preferred_withdraw_validator_vote_address = None; - stake_pool.deposit_fee = Fee::default(); + stake_pool.stake_deposit_fee = stake_deposit_fee; stake_pool.withdrawal_fee = withdrawal_fee; stake_pool.next_withdrawal_fee = None; + stake_pool.stake_referral_fee = stake_referral_fee; + stake_pool.sol_deposit_authority = None; stake_pool .serialize(&mut *stake_pool_info.data.borrow_mut()) @@ -798,7 +812,7 @@ impl Processor { )?; if meta.lockup != stake_program::Lockup::default() { - msg!("Validator stake account has a lockup"); + msg!("Stake account has a lockup"); return Err(StakePoolError::WrongStakeState.into()); } @@ -813,20 +827,13 @@ impl Processor { // Check amount of lamports let stake_lamports = **stake_account_info.lamports.borrow(); let minimum_lamport_amount = minimum_stake_lamports(&meta); - if stake_lamports != minimum_lamport_amount { + if stake_lamports != minimum_lamport_amount + || stake.delegation.stake != MINIMUM_ACTIVE_STAKE + { msg!( - "Error: attempting to add stake with {} lamports, must have {} lamports", + "Error: attempting to add (stake: {}, delegation: {}), below minimum", stake_lamports, - minimum_lamport_amount - ); - return Err(StakePoolError::StakeLamportsNotEqualToMinimum.into()); - } - - if stake.delegation.stake != MINIMUM_ACTIVE_STAKE { - msg!( - "Error: attempting to add stake with delegation of {} lamports, must have {} lamports", stake.delegation.stake, - MINIMUM_ACTIVE_STAKE ); return Err(StakePoolError::StakeLamportsNotEqualToMinimum.into()); } @@ -970,7 +977,7 @@ impl Processor { stake_account_info.clone(), withdraw_authority_info.clone(), AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, + stake_pool.stake_withdraw_bump_seed, new_stake_authority_info.key, clock_info.clone(), stake_program_info.clone(), @@ -1097,7 +1104,7 @@ impl Processor { validator_stake_account_info.clone(), withdraw_authority_info.clone(), AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, + stake_pool.stake_withdraw_bump_seed, lamports, transient_stake_account_info.clone(), )?; @@ -1109,7 +1116,7 @@ impl Processor { withdraw_authority_info.clone(), stake_pool_info.key, AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, + stake_pool.stake_withdraw_bump_seed, )?; validator_stake_info.active_stake_lamports = validator_stake_info @@ -1249,7 +1256,7 @@ impl Processor { reserve_stake_account_info.clone(), withdraw_authority_info.clone(), AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, + stake_pool.stake_withdraw_bump_seed, total_lamports, transient_stake_account_info.clone(), )?; @@ -1264,7 +1271,7 @@ impl Processor { withdraw_authority_info.clone(), stake_pool_info.key, AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, + stake_pool.stake_withdraw_bump_seed, )?; validator_stake_info.transient_stake_lamports = total_lamports; @@ -1427,7 +1434,7 @@ impl Processor { transient_stake_info.clone(), withdraw_authority_info.clone(), AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, + stake_pool.stake_withdraw_bump_seed, reserve_stake_info.clone(), clock_info.clone(), stake_history_info.clone(), @@ -1453,7 +1460,7 @@ impl Processor { transient_stake_info.clone(), withdraw_authority_info.clone(), AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, + stake_pool.stake_withdraw_bump_seed, reserve_stake_info.clone(), clock_info.clone(), stake_history_info.clone(), @@ -1479,7 +1486,7 @@ impl Processor { transient_stake_info.clone(), withdraw_authority_info.clone(), AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, + stake_pool.stake_withdraw_bump_seed, validator_stake_info.clone(), clock_info.clone(), stake_history_info.clone(), @@ -1494,7 +1501,7 @@ impl Processor { validator_stake_info.clone(), withdraw_authority_info.clone(), AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, + stake_pool.stake_withdraw_bump_seed, reserve_stake_info.clone(), clock_info.clone(), stake_history_info.clone(), @@ -1623,7 +1630,7 @@ impl Processor { let reward_lamports = total_stake_lamports.saturating_sub(previous_lamports); let fee = stake_pool - .calc_fee_amount(reward_lamports) + .calc_epoch_fee_amount(reward_lamports) .ok_or(StakePoolError::CalculationFailure)?; if fee > 0 { @@ -1634,7 +1641,7 @@ impl Processor { manager_fee_info.clone(), withdraw_info.clone(), AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, + stake_pool.stake_withdraw_bump_seed, fee, )?; @@ -1718,17 +1725,19 @@ impl Processor { Ok(()) } - /// Processes [Deposit](enum.Instruction.html). - fn process_deposit(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { + /// Processes [DepositStake](enum.Instruction.html). + fn process_deposit_stake(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; let validator_list_info = next_account_info(account_info_iter)?; - let deposit_authority_info = next_account_info(account_info_iter)?; + let stake_deposit_authority_info = next_account_info(account_info_iter)?; let withdraw_authority_info = next_account_info(account_info_iter)?; let stake_info = next_account_info(account_info_iter)?; let validator_stake_account_info = next_account_info(account_info_iter)?; let reserve_stake_account_info = next_account_info(account_info_iter)?; - let dest_user_info = next_account_info(account_info_iter)?; + let dest_user_pool_info = next_account_info(account_info_iter)?; + let manager_fee_info = next_account_info(account_info_iter)?; + let referrer_fee_info = next_account_info(account_info_iter)?; let pool_mint_info = next_account_info(account_info_iter)?; let clock_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(clock_info)?; @@ -1753,7 +1762,7 @@ impl Processor { program_id, stake_pool_info.key, )?; - stake_pool.check_deposit_authority(deposit_authority_info.key)?; + stake_pool.check_stake_deposit_authority(stake_deposit_authority_info.key)?; stake_pool.check_mint(pool_mint_info)?; stake_pool.check_validator_list(validator_list_info)?; stake_pool.check_reserve_stake(reserve_stake_account_info)?; @@ -1762,6 +1771,10 @@ impl Processor { return Err(ProgramError::IncorrectProgramId); } + if stake_pool.manager_fee_account != *manager_fee_info.key { + return Err(StakePoolError::InvalidFeeAccount.into()); + } + if stake_pool.last_update_epoch < clock.epoch { return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); } @@ -1808,13 +1821,13 @@ impl Processor { msg!("Stake pre merge {}", validator_stake.delegation.stake); - let (deposit_authority_program_address, deposit_bump_seed) = + let (stake_deposit_authority_program_address, deposit_bump_seed) = find_deposit_authority_program_address(program_id, stake_pool_info.key); - if *deposit_authority_info.key == deposit_authority_program_address { + if *stake_deposit_authority_info.key == stake_deposit_authority_program_address { Self::stake_authorize_signed( stake_pool_info.key, stake_info.clone(), - deposit_authority_info.clone(), + stake_deposit_authority_info.clone(), AUTHORITY_DEPOSIT, deposit_bump_seed, withdraw_authority_info.key, @@ -1824,7 +1837,7 @@ impl Processor { } else { Self::stake_authorize( stake_info.clone(), - deposit_authority_info.clone(), + stake_deposit_authority_info.clone(), withdraw_authority_info.key, clock_info.clone(), stake_program_info.clone(), @@ -1836,7 +1849,7 @@ impl Processor { stake_info.clone(), withdraw_authority_info.clone(), AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, + stake_pool.stake_withdraw_bump_seed, validator_stake_account_info.clone(), clock_info.clone(), stake_history_info.clone(), @@ -1854,24 +1867,71 @@ impl Processor { .stake .checked_sub(validator_stake.delegation.stake) .ok_or(StakePoolError::CalculationFailure)?; + let new_pool_tokens = stake_pool .calc_pool_tokens_for_deposit(all_deposit_lamports) .ok_or(StakePoolError::CalculationFailure)?; + let pool_tokens_stake_deposit_fee = stake_pool + .calc_pool_tokens_stake_deposit_fee(new_pool_tokens) + .ok_or(StakePoolError::CalculationFailure)?; + let pool_tokens_user = new_pool_tokens + .checked_sub(pool_tokens_stake_deposit_fee) + .ok_or(StakePoolError::CalculationFailure)?; + + let pool_tokens_referral_fee = stake_pool + .calc_pool_tokens_stake_referral_fee(pool_tokens_stake_deposit_fee) + .ok_or(StakePoolError::CalculationFailure)?; + let pool_tokens_manager_deposit_fee = pool_tokens_stake_deposit_fee + .checked_sub(pool_tokens_referral_fee) + .ok_or(StakePoolError::CalculationFailure)?; + + if pool_tokens_user + pool_tokens_manager_deposit_fee + pool_tokens_referral_fee + != new_pool_tokens + { + return Err(StakePoolError::CalculationFailure.into()); + } + if new_pool_tokens == 0 { return Err(StakePoolError::DepositTooSmall.into()); } - Self::token_mint_to( - stake_pool_info.key, - token_program_info.clone(), - pool_mint_info.clone(), - dest_user_info.clone(), - withdraw_authority_info.clone(), - AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, - new_pool_tokens, - )?; + if pool_tokens_user > 0 { + Self::token_mint_to( + stake_pool_info.key, + token_program_info.clone(), + pool_mint_info.clone(), + dest_user_pool_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + pool_tokens_user, + )?; + } + if pool_tokens_manager_deposit_fee > 0 { + Self::token_mint_to( + stake_pool_info.key, + token_program_info.clone(), + pool_mint_info.clone(), + manager_fee_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + pool_tokens_manager_deposit_fee, + )?; + } + if pool_tokens_referral_fee > 0 { + Self::token_mint_to( + stake_pool_info.key, + token_program_info.clone(), + pool_mint_info.clone(), + referrer_fee_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + pool_tokens_referral_fee, + )?; + } // withdraw additional lamports to the reserve let additional_lamports = all_deposit_lamports @@ -1883,7 +1943,7 @@ impl Processor { validator_stake_account_info.clone(), withdraw_authority_info.clone(), AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, + stake_pool.stake_withdraw_bump_seed, reserve_stake_account_info.clone(), clock_info.clone(), stake_history_info.clone(), @@ -1911,8 +1971,146 @@ impl Processor { Ok(()) } - /// Processes [Withdraw](enum.Instruction.html). - fn process_withdraw( + /// Processes [DepositStake](enum.Instruction.html). + fn process_deposit_sol( + program_id: &Pubkey, + accounts: &[AccountInfo], + deposit_lamports: u64, + ) -> ProgramResult { + let account_info_iter = &mut accounts.iter(); + let stake_pool_info = next_account_info(account_info_iter)?; + let withdraw_authority_info = next_account_info(account_info_iter)?; + let reserve_stake_account_info = next_account_info(account_info_iter)?; + let from_user_lamports_info = next_account_info(account_info_iter)?; + let dest_user_pool_info = next_account_info(account_info_iter)?; + let manager_fee_info = next_account_info(account_info_iter)?; + let referrer_fee_info = next_account_info(account_info_iter)?; + let pool_mint_info = next_account_info(account_info_iter)?; + let clock_info = next_account_info(account_info_iter)?; + let clock = &Clock::from_account_info(clock_info)?; + let system_program_info = next_account_info(account_info_iter)?; + let token_program_info = next_account_info(account_info_iter)?; + let sol_deposit_authority_info = next_account_info(account_info_iter).ok(); + + check_account_owner(stake_pool_info, program_id)?; + let mut stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; + if !stake_pool.is_valid() { + return Err(StakePoolError::InvalidState.into()); + } + + // Self::check_stake_activation(stake_info, clock, stake_history)?; + + stake_pool.check_authority_withdraw( + withdraw_authority_info.key, + program_id, + stake_pool_info.key, + )?; + if let Some(sol_deposit_authority) = sol_deposit_authority_info { + stake_pool.check_sol_deposit_authority(sol_deposit_authority)?; + } + stake_pool.check_mint(pool_mint_info)?; + stake_pool.check_reserve_stake(reserve_stake_account_info)?; + + if stake_pool.token_program_id != *token_program_info.key { + return Err(ProgramError::IncorrectProgramId); + } + check_system_program(system_program_info.key)?; + + if stake_pool.manager_fee_account != *manager_fee_info.key { + return Err(StakePoolError::InvalidFeeAccount.into()); + } + + // We want this to hold to ensure that deposit_sol mints pool tokens + // at the right price + if stake_pool.last_update_epoch < clock.epoch { + return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); + } + + let new_pool_tokens = stake_pool + .calc_pool_tokens_for_deposit(deposit_lamports) + .ok_or(StakePoolError::CalculationFailure)?; + + let pool_tokens_sol_deposit_fee = stake_pool + .calc_pool_tokens_sol_deposit_fee(new_pool_tokens) + .ok_or(StakePoolError::CalculationFailure)?; + let pool_tokens_user = new_pool_tokens + .checked_sub(pool_tokens_sol_deposit_fee) + .ok_or(StakePoolError::CalculationFailure)?; + + let pool_tokens_referral_fee = stake_pool + .calc_pool_tokens_sol_referral_fee(pool_tokens_sol_deposit_fee) + .ok_or(StakePoolError::CalculationFailure)?; + let pool_tokens_manager_deposit_fee = pool_tokens_sol_deposit_fee + .checked_sub(pool_tokens_referral_fee) + .ok_or(StakePoolError::CalculationFailure)?; + + if pool_tokens_user + pool_tokens_manager_deposit_fee + pool_tokens_referral_fee + != new_pool_tokens + { + return Err(StakePoolError::CalculationFailure.into()); + } + + Self::sol_transfer( + from_user_lamports_info.clone(), + reserve_stake_account_info.clone(), + system_program_info.clone(), + deposit_lamports, + )?; + + if pool_tokens_user > 0 { + Self::token_mint_to( + stake_pool_info.key, + token_program_info.clone(), + pool_mint_info.clone(), + dest_user_pool_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + pool_tokens_user, + )?; + } + + if pool_tokens_manager_deposit_fee > 0 { + Self::token_mint_to( + stake_pool_info.key, + token_program_info.clone(), + pool_mint_info.clone(), + manager_fee_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + pool_tokens_manager_deposit_fee, + )?; + } + + if pool_tokens_referral_fee > 0 { + Self::token_mint_to( + stake_pool_info.key, + token_program_info.clone(), + pool_mint_info.clone(), + referrer_fee_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + pool_tokens_referral_fee, + )?; + } + + stake_pool.pool_token_supply = stake_pool + .pool_token_supply + .checked_add(new_pool_tokens) + .ok_or(StakePoolError::CalculationFailure)?; + stake_pool.total_stake_lamports = stake_pool + .total_stake_lamports + .checked_add(deposit_lamports) + .ok_or(StakePoolError::CalculationFailure)?; + stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; + + Ok(()) + } + + /// Processes [WithdrawStake](enum.Instruction.html). + fn process_withdraw_stake( program_id: &Pubkey, accounts: &[AccountInfo], pool_tokens: u64, @@ -1925,7 +2123,7 @@ impl Processor { let stake_split_to = next_account_info(account_info_iter)?; let user_stake_authority_info = next_account_info(account_info_iter)?; let user_transfer_authority_info = next_account_info(account_info_iter)?; - let burn_from_info = next_account_info(account_info_iter)?; + let burn_from_pool_info = next_account_info(account_info_iter)?; let manager_fee_info = next_account_info(account_info_iter)?; let pool_mint_info = next_account_info(account_info_iter)?; let clock_info = next_account_info(account_info_iter)?; @@ -1967,7 +2165,7 @@ impl Processor { return Err(StakePoolError::InvalidState.into()); } - let pool_tokens_fee = if stake_pool.manager_fee_account == *burn_from_info.key { + let pool_tokens_fee = if stake_pool.manager_fee_account == *burn_from_pool_info.key { 0 } else { stake_pool @@ -2079,7 +2277,7 @@ impl Processor { Self::token_burn( token_program_info.clone(), - burn_from_info.clone(), + burn_from_pool_info.clone(), pool_mint_info.clone(), user_transfer_authority_info.clone(), pool_tokens_burnt, @@ -2090,7 +2288,7 @@ impl Processor { stake_split_from.clone(), withdraw_authority_info.clone(), AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, + stake_pool.stake_withdraw_bump_seed, withdraw_lamports, stake_split_to.clone(), )?; @@ -2100,7 +2298,7 @@ impl Processor { stake_split_to.clone(), withdraw_authority_info.clone(), AUTHORITY_WITHDRAW, - stake_pool.withdraw_bump_seed, + stake_pool.stake_withdraw_bump_seed, user_stake_authority_info.key, clock_info.clone(), stake_program_info.clone(), @@ -2109,7 +2307,7 @@ impl Processor { if pool_tokens_fee > 0 { Self::token_transfer( token_program_info.clone(), - burn_from_info.clone(), + burn_from_pool_info.clone(), manager_fee_info.clone(), user_transfer_authority_info.clone(), pool_tokens_fee, @@ -2175,7 +2373,11 @@ impl Processor { } /// Processes [SetFee](enum.Instruction.html). - fn process_set_fee(program_id: &Pubkey, accounts: &[AccountInfo], fee: Fee) -> ProgramResult { + fn process_set_fee( + program_id: &Pubkey, + accounts: &[AccountInfo], + fee: FeeType, + ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; let manager_info = next_account_info(account_info_iter)?; @@ -2190,21 +2392,14 @@ impl Processor { stake_pool.check_manager(manager_info)?; - if stake_pool.last_update_epoch < clock.epoch { + if fee.can_only_change_next_epoch() && stake_pool.last_update_epoch < clock.epoch { return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); } - // Numerator should be smaller than or equal to denominator (fee <= 1) - if fee.numerator > fee.denominator { - msg!( - "Fee greater than 100%, numerator {}, denominator {}", - fee.numerator, - fee.denominator - ); - return Err(StakePoolError::FeeTooHigh.into()); - } + fee.check_too_high()?; + fee.check_withdrawal(&stake_pool.withdrawal_fee)?; - stake_pool.next_epoch_fee = Some(fee); + stake_pool.update_fee(&fee); stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; Ok(()) } @@ -2232,76 +2427,34 @@ impl Processor { Ok(()) } - /// Processes [SetWithdrawalFee](enum.Instruction.html). - fn process_set_withdrawal_fee( + /// Processes [SetStakeDepositAuthority/SetSolDepositAuthority](enum.Instruction.html). + fn process_set_deposit_authority( program_id: &Pubkey, accounts: &[AccountInfo], - fee: Fee, + deposit_type: DepositType, ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; let manager_info = next_account_info(account_info_iter)?; - let clock_info = next_account_info(account_info_iter)?; - let clock = &Clock::from_account_info(clock_info)?; + + let new_sol_deposit_authority = next_account_info(account_info_iter).ok().map( + |new_sol_deposit_authority_account_info| *new_sol_deposit_authority_account_info.key, + ); check_account_owner(stake_pool_info, program_id)?; let mut stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); } - stake_pool.check_manager(manager_info)?; - - if stake_pool.last_update_epoch < clock.epoch { - return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); - } - - // Numerator should be smaller than or equal to denominator (fee <= 1) - if fee.numerator > fee.denominator { - msg!( - "Fee greater than 100%, numerator {}, denominator {}", - fee.numerator, - fee.denominator - ); - return Err(StakePoolError::FeeTooHigh.into()); - } - - // If the previous withdrawal fee was 0, we allow the fee to be set to a - // maximum of (WITHDRAWAL_BASELINE_FEE * MAX_WITHDRAWAL_FEE_INCREASE) - let (old_num, old_denom) = if stake_pool.withdrawal_fee.denominator == 0 - || stake_pool.withdrawal_fee.numerator == 0 - { - ( - WITHDRAWAL_BASELINE_FEE.numerator, - WITHDRAWAL_BASELINE_FEE.denominator, - ) - } else { - ( - stake_pool.withdrawal_fee.numerator, - stake_pool.withdrawal_fee.denominator, - ) - }; - - // Check that new_fee / old_fee <= MAX_WITHDRAWAL_FEE_INCREASE - // Program fails if provided numerator or denominator is too large, resulting in overflow - if (old_num as u128) - .checked_mul(fee.denominator as u128) - .map(|x| x.checked_mul(MAX_WITHDRAWAL_FEE_INCREASE.numerator as u128)) - .ok_or(StakePoolError::CalculationFailure)? - < (fee.numerator as u128) - .checked_mul(old_denom as u128) - .map(|x| x.checked_mul(MAX_WITHDRAWAL_FEE_INCREASE.denominator as u128)) - .ok_or(StakePoolError::CalculationFailure)? - { - msg!( - "Fee increase exceeds maximum allowed, proposed increase factor ({} / {})", - fee.numerator * old_denom, - old_num * fee.denominator, - ); - return Err(StakePoolError::FeeIncreaseTooHigh.into()); + match deposit_type { + DepositType::Stake => { + stake_pool.stake_deposit_authority = new_sol_deposit_authority.unwrap_or( + find_deposit_authority_program_address(program_id, stake_pool_info.key).0, + ); + } + DepositType::Sol => stake_pool.sol_deposit_authority = new_sol_deposit_authority, } - - stake_pool.next_withdrawal_fee = Some(fee); stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; Ok(()) } @@ -2313,10 +2466,20 @@ impl Processor { StakePoolInstruction::Initialize { fee, withdrawal_fee, + deposit_fee, + referral_fee, max_validators, } => { msg!("Instruction: Initialize stake pool"); - Self::process_initialize(program_id, accounts, fee, withdrawal_fee, max_validators) + Self::process_initialize( + program_id, + accounts, + fee, + withdrawal_fee, + deposit_fee, + referral_fee, + max_validators, + ) } StakePoolInstruction::CreateValidatorStakeAccount => { msg!("Instruction: CreateValidatorStakeAccount"); @@ -2370,13 +2533,13 @@ impl Processor { msg!("Instruction: CleanupRemovedValidatorEntries"); Self::process_cleanup_removed_validator_entries(program_id, accounts) } - StakePoolInstruction::Deposit => { - msg!("Instruction: Deposit"); - Self::process_deposit(program_id, accounts) + StakePoolInstruction::DepositStake => { + msg!("Instruction: DepositStake"); + Self::process_deposit_stake(program_id, accounts) } - StakePoolInstruction::Withdraw(amount) => { - msg!("Instruction: Withdraw"); - Self::process_withdraw(program_id, accounts, amount) + StakePoolInstruction::WithdrawStake(amount) => { + msg!("Instruction: WithdrawStake"); + Self::process_withdraw_stake(program_id, accounts, amount) } StakePoolInstruction::SetManager => { msg!("Instruction: SetManager"); @@ -2390,9 +2553,13 @@ impl Processor { msg!("Instruction: SetStaker"); Self::process_set_staker(program_id, accounts) } - StakePoolInstruction::SetWithdrawalFee { fee } => { - msg!("Instruction: SetWithdrawalFee"); - Self::process_set_withdrawal_fee(program_id, accounts, fee) + StakePoolInstruction::DepositSol(lamports) => { + msg!("Instruction: DepositSol"); + Self::process_deposit_sol(program_id, accounts, lamports) + } + StakePoolInstruction::SetDepositAuthority(deposit_type) => { + msg!("Instruction: SetDepositAuthority"); + Self::process_set_deposit_authority(program_id, accounts, deposit_type) } } } @@ -2436,6 +2603,8 @@ impl PrintProgramError for StakePoolError { StakePoolError::FeeIncreaseTooHigh => msg!("Error: The fee cannot increase by a factor exceeding the stipulated ratio"), StakePoolError::WithdrawalTooSmall => msg!("Error: Not enough pool tokens provided to withdraw 1-lamport stake"), StakePoolError::DepositTooSmall => msg!("Error: Not enough lamports provided for deposit to result in one pool token"), + StakePoolError::InvalidStakeDepositAuthority => msg!("Error: Provided stake deposit authority does not match the program's"), + StakePoolError::InvalidSolDepositAuthority => msg!("Error: Provided sol deposit authority does not match the program's"), } } } diff --git a/program/src/state.rs b/program/src/state.rs index e765aafa..996c69bd 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -1,7 +1,10 @@ //! State transition types use { - crate::{big_vec::BigVec, error::StakePoolError, stake_program::Lockup}, + crate::{ + big_vec::BigVec, error::StakePoolError, stake_program::Lockup, MAX_WITHDRAWAL_FEE_INCREASE, + WITHDRAWAL_BASELINE_FEE, + }, borsh::{BorshDeserialize, BorshSchema, BorshSerialize}, num_derive::FromPrimitive, num_traits::FromPrimitive, @@ -16,6 +19,7 @@ use { }, spl_math::checked_ceil_div::CheckedCeilDiv, std::convert::TryFrom, + std::{fmt, matches}, }; /// Enum representing the account type managed by the program @@ -49,7 +53,7 @@ pub struct StakePool { /// distribution pub staker: Pubkey, - /// Deposit authority + /// Stake deposit authority /// /// If a depositor pubkey is specified on initialization, then deposits must be /// signed by this authority. If no deposit authority is specified, @@ -58,11 +62,11 @@ pub struct StakePool { /// &[&stake_pool_address.to_bytes()[..32], b"deposit"], /// program_id, /// )` - pub deposit_authority: Pubkey, + pub stake_deposit_authority: Pubkey, - /// Withdrawal authority bump seed + /// Stake withdrawal authority bump seed /// for `create_program_address(&[state::StakePool account, "withdrawal"])` - pub withdraw_bump_seed: u8, + pub stake_withdraw_bump_seed: u8, /// Validator stake list storage account pub validator_list: Pubkey, @@ -105,8 +109,8 @@ pub struct StakePool { /// Preferred withdraw validator vote account pubkey pub preferred_withdraw_validator_vote_address: Option, - /// Fee assessed on deposits - pub deposit_fee: Fee, + /// Fee assessed on stake deposits + pub stake_deposit_fee: Fee, /// Fee assessed on withdrawals pub withdrawal_fee: Fee, @@ -114,14 +118,28 @@ pub struct StakePool { /// Future withdrawal fee, to be set for the following epoch pub next_withdrawal_fee: Option, - /// Fees paid out to referrers on referred deposits. + /// Fees paid out to referrers on referred stake deposits. /// Expressed as a percentage (0 - 100) of deposit fees. - /// i.e. `deposit_fee`% is collected as deposit fees for every deposit - /// and `referral_fee`% of the collected deposit fees is paid out to the referrer - pub referral_fee: u8, + /// i.e. `stake_deposit_fee`% of stake deposited is collected as deposit fees for every deposit + /// and `stake_referral_fee`% of the collected stake deposit fees is paid out to the referrer + pub stake_referral_fee: u8, + + /// Toggles whether the `DepositSol` instruction requires a signature from + /// the `deposit_authority` + pub sol_deposit_authority: Option, + + /// Fee assessed on SOL deposits + pub sol_deposit_fee: Fee, + + /// Fees paid out to referrers on referred SOL deposits. + /// Expressed as a percentage (0 - 100) of SOL deposit fees. + /// i.e. `sol_deposit_fee`% of SOL deposited is collected as deposit fees for every deposit + /// and `sol_referral_fee`% of the collected SOL deposit fees is paid out to the referrer + pub sol_referral_fee: u8, } impl StakePool { /// calculate the pool tokens that should be minted for a deposit of `stake_lamports` + #[inline] pub fn calc_pool_tokens_for_deposit(&self, stake_lamports: u64) -> Option { if self.total_stake_lamports == 0 || self.pool_token_supply == 0 { return Some(stake_lamports); @@ -135,6 +153,7 @@ impl StakePool { } /// calculate lamports amount on withdrawal + #[inline] pub fn calc_lamports_withdraw_amount(&self, pool_tokens: u64) -> Option { // `checked_ceil_div` returns `None` for a 0 quotient result, but in this // case, a return of 0 is valid for small amounts of pool tokens. So @@ -150,15 +169,51 @@ impl StakePool { } /// calculate pool tokens to be deducted as withdrawal fees + #[inline] pub fn calc_pool_tokens_withdrawal_fee(&self, pool_tokens: u64) -> Option { u64::try_from(self.withdrawal_fee.apply(pool_tokens)?).ok() } + /// calculate pool tokens to be deducted as stake deposit fees + #[inline] + pub fn calc_pool_tokens_stake_deposit_fee(&self, pool_tokens_minted: u64) -> Option { + u64::try_from(self.stake_deposit_fee.apply(pool_tokens_minted)?).ok() + } + + /// calculate pool tokens to be deducted from deposit fees as referral fees + #[inline] + pub fn calc_pool_tokens_stake_referral_fee(&self, stake_deposit_fee: u64) -> Option { + u64::try_from( + (stake_deposit_fee as u128) + .checked_mul(self.stake_referral_fee as u128)? + .checked_div(100u128)?, + ) + .ok() + } + + /// calculate pool tokens to be deducted as SOL deposit fees + #[inline] + pub fn calc_pool_tokens_sol_deposit_fee(&self, pool_tokens_minted: u64) -> Option { + u64::try_from(self.sol_deposit_fee.apply(pool_tokens_minted)?).ok() + } + + /// calculate pool tokens to be deducted from SOL deposit fees as referral fees + #[inline] + pub fn calc_pool_tokens_sol_referral_fee(&self, sol_deposit_fee: u64) -> Option { + u64::try_from( + (sol_deposit_fee as u128) + .checked_mul(self.sol_referral_fee as u128)? + .checked_div(100u128)?, + ) + .ok() + } + /// Calculate the fee in pool tokens that goes to the manager /// /// This function assumes that `reward_lamports` has not already been added /// to the stake pool's `total_stake_lamports` - pub fn calc_fee_amount(&self, reward_lamports: u64) -> Option { + #[inline] + pub fn calc_epoch_fee_amount(&self, reward_lamports: u64) -> Option { if reward_lamports == 0 { return Some(0); } @@ -178,7 +233,7 @@ impl StakePool { } /// Checks that the withdraw or deposit authority is valid - fn check_authority( + fn check_program_derived_authority( authority_address: &Pubkey, program_id: &Pubkey, stake_pool_address: &Pubkey, @@ -207,33 +262,55 @@ impl StakePool { } /// Checks that the withdraw authority is valid + #[inline] pub(crate) fn check_authority_withdraw( &self, withdraw_authority: &Pubkey, program_id: &Pubkey, stake_pool_address: &Pubkey, ) -> Result<(), ProgramError> { - Self::check_authority( + Self::check_program_derived_authority( withdraw_authority, program_id, stake_pool_address, crate::AUTHORITY_WITHDRAW, - self.withdraw_bump_seed, + self.stake_withdraw_bump_seed, ) } /// Checks that the deposit authority is valid - pub(crate) fn check_deposit_authority( + #[inline] + pub(crate) fn check_stake_deposit_authority( &self, - deposit_authority: &Pubkey, + stake_deposit_authority: &Pubkey, ) -> Result<(), ProgramError> { - if self.deposit_authority == *deposit_authority { + if self.stake_deposit_authority == *stake_deposit_authority { Ok(()) } else { - Err(StakePoolError::InvalidProgramAddress.into()) + Err(StakePoolError::InvalidStakeDepositAuthority.into()) + } + } + + /// Checks that the deposit authority is valid + /// Does nothing if `sol_deposit_authority` is currently not set + #[inline] + pub(crate) fn check_sol_deposit_authority( + &self, + sol_deposit_authority: &AccountInfo, + ) -> Result<(), ProgramError> { + if let Some(auth) = self.sol_deposit_authority { + if auth != *sol_deposit_authority.key { + return Err(StakePoolError::InvalidSolDepositAuthority.into()); + } + if !sol_deposit_authority.is_signer { + msg!("SOL Deposit authority signature missing"); + return Err(StakePoolError::SignatureMissing.into()); + } } + Ok(()) } /// Check staker validity and signature + #[inline] pub(crate) fn check_mint(&self, mint_info: &AccountInfo) -> Result<(), ProgramError> { if *mint_info.key != self.pool_mint { Err(StakePoolError::WrongPoolMint.into()) @@ -319,6 +396,18 @@ impl StakePool { pub fn is_uninitialized(&self) -> bool { self.account_type == AccountType::Uninitialized } + + /// Updates one of the StakePool's fees. + pub fn update_fee(&mut self, fee: &FeeType) { + match fee { + FeeType::SolReferral(new_fee) => self.sol_referral_fee = *new_fee, + FeeType::StakeReferral(new_fee) => self.stake_referral_fee = *new_fee, + FeeType::Epoch(new_fee) => self.next_epoch_fee = Some(*new_fee), + FeeType::Withdrawal(new_fee) => self.next_withdrawal_fee = Some(*new_fee), + FeeType::SolDeposit(new_fee) => self.sol_deposit_fee = *new_fee, + FeeType::StakeDeposit(new_fee) => self.stake_deposit_fee = *new_fee, + } + } } /// Storage list for all validator stake accounts in the pool. @@ -579,6 +668,96 @@ impl Fee { } } +impl fmt::Display for Fee { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}/{}", self.numerator, self.denominator) + } +} + +/// The type of fees that can be set on the stake pool +#[derive(Clone, Debug, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)] +pub enum FeeType { + /// Referral fees for SOL deposits + SolReferral(u8), + /// Referral fees for stake deposits + StakeReferral(u8), + /// Management fee paid per epoch + Epoch(Fee), + /// Withdrawal fee + Withdrawal(Fee), + /// Deposit fee for SOL deposits + SolDeposit(Fee), + /// Deposit fee for stake deposits + StakeDeposit(Fee), +} + +impl FeeType { + /// Checks if the provided fee is too high, returning an error if so + pub fn check_too_high(&self) -> Result<(), StakePoolError> { + let too_high = match self { + Self::SolReferral(pct) => *pct > 100u8, + Self::StakeReferral(pct) => *pct > 100u8, + Self::Epoch(fee) => fee.numerator > fee.denominator, + Self::Withdrawal(fee) => fee.numerator > fee.denominator, + Self::SolDeposit(fee) => fee.numerator > fee.denominator, + Self::StakeDeposit(fee) => fee.numerator > fee.denominator, + }; + if too_high { + msg!("Fee greater than 100%: {:?}", self); + return Err(StakePoolError::FeeTooHigh); + } + Ok(()) + } + + /// Withdrawal fees have some additional restrictions, + /// this fn checks if those are met, returning an error if not. + /// Does nothing and returns Ok if fee type is not withdrawal + pub fn check_withdrawal(&self, old_withdrawal_fee: &Fee) -> Result<(), StakePoolError> { + let fee = match self { + Self::Withdrawal(fee) => fee, + _ => return Ok(()), + }; + + // If the previous withdrawal fee was 0, we allow the fee to be set to a + // maximum of (WITHDRAWAL_BASELINE_FEE * MAX_WITHDRAWAL_FEE_INCREASE) + let (old_num, old_denom) = + if old_withdrawal_fee.denominator == 0 || old_withdrawal_fee.numerator == 0 { + ( + WITHDRAWAL_BASELINE_FEE.numerator, + WITHDRAWAL_BASELINE_FEE.denominator, + ) + } else { + (old_withdrawal_fee.numerator, old_withdrawal_fee.denominator) + }; + + // Check that new_fee / old_fee <= MAX_WITHDRAWAL_FEE_INCREASE + // Program fails if provided numerator or denominator is too large, resulting in overflow + if (old_num as u128) + .checked_mul(fee.denominator as u128) + .map(|x| x.checked_mul(MAX_WITHDRAWAL_FEE_INCREASE.numerator as u128)) + .ok_or(StakePoolError::CalculationFailure)? + < (fee.numerator as u128) + .checked_mul(old_denom as u128) + .map(|x| x.checked_mul(MAX_WITHDRAWAL_FEE_INCREASE.denominator as u128)) + .ok_or(StakePoolError::CalculationFailure)? + { + msg!( + "Fee increase exceeds maximum allowed, proposed increase factor ({} / {})", + fee.numerator * old_denom, + old_num * fee.denominator, + ); + return Err(StakePoolError::FeeIncreaseTooHigh); + } + Ok(()) + } + + /// Returns if the contained fee can only be updated earliest on the next epoch + #[inline] + pub fn can_only_change_next_epoch(&self) -> bool { + matches!(self, Self::Withdrawal(_) | Self::Epoch(_)) + } +} + #[cfg(test)] mod test { use { @@ -779,7 +958,7 @@ mod test { ..StakePool::default() }; let reward_lamports = 10 * LAMPORTS_PER_SOL; - let pool_token_fee = stake_pool.calc_fee_amount(reward_lamports).unwrap(); + let pool_token_fee = stake_pool.calc_epoch_fee_amount(reward_lamports).unwrap(); stake_pool.total_stake_lamports += reward_lamports; stake_pool.pool_token_supply += pool_token_fee; @@ -815,7 +994,7 @@ mod test { ..StakePool::default() }; let rewards = 10; - let fee = stake_pool.calc_fee_amount(rewards).unwrap(); + let fee = stake_pool.calc_epoch_fee_amount(rewards).unwrap(); assert_eq!(fee, rewards); } @@ -832,7 +1011,7 @@ mod test { fee, ..StakePool::default() }; - let pool_token_fee = stake_pool.calc_fee_amount(reward_lamports).unwrap(); + let pool_token_fee = stake_pool.calc_epoch_fee_amount(reward_lamports).unwrap(); stake_pool.total_stake_lamports += reward_lamports; stake_pool.pool_token_supply += pool_token_fee; diff --git a/program/tests/decrease.rs b/program/tests/decrease.rs index f6a182fb..31530ace 100644 --- a/program/tests/decrease.rs +++ b/program/tests/decrease.rs @@ -41,7 +41,7 @@ async fn setup() -> ( ) .await; - let deposit_info = simple_deposit( + let deposit_info = simple_deposit_stake( &mut banks_client, &payer, &recent_blockhash, diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 7308760a..03f1eb01 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -212,7 +212,9 @@ async fn success() { // Check minted tokens let user_token_balance = get_token_balance(&mut context.banks_client, &pool_token_account).await; - assert_eq!(user_token_balance, tokens_issued); + let tokens_issued_user = + tokens_issued - stake_pool_accounts.calculate_deposit_fee(tokens_issued); + assert_eq!(user_token_balance, tokens_issued_user); // Check balances in validator stake account list storage let validator_list = get_account( @@ -272,12 +274,14 @@ async fn fail_with_wrong_stake_program_id() { let accounts = vec![ AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false), - AccountMeta::new_readonly(stake_pool_accounts.deposit_authority, false), + AccountMeta::new_readonly(stake_pool_accounts.stake_deposit_authority, false), AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false), AccountMeta::new(deposit_stake, false), AccountMeta::new(validator_stake_account.stake_account, false), AccountMeta::new(stake_pool_accounts.reserve_stake.pubkey(), false), AccountMeta::new(pool_token_account, false), + AccountMeta::new(stake_pool_accounts.pool_fee_account.pubkey(), false), + AccountMeta::new(stake_pool_accounts.pool_fee_account.pubkey(), false), AccountMeta::new(stake_pool_accounts.pool_mint.pubkey(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), @@ -287,7 +291,7 @@ async fn fail_with_wrong_stake_program_id() { let instruction = Instruction { program_id: id(), accounts, - data: instruction::StakePoolInstruction::Deposit + data: instruction::StakePoolInstruction::DepositStake .try_to_vec() .unwrap(), }; @@ -325,7 +329,7 @@ async fn fail_with_wrong_token_program_id() { let wrong_token_program = Keypair::new(); let mut transaction = Transaction::new_with_payer( - &instruction::deposit( + &instruction::deposit_stake( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.validator_list.pubkey(), @@ -335,6 +339,8 @@ async fn fail_with_wrong_token_program_id() { &validator_stake_account.stake_account, &stake_pool_accounts.reserve_stake.pubkey(), &pool_token_account, + &stake_pool_accounts.pool_fee_account.pubkey(), + &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), &wrong_token_program.pubkey(), ), @@ -567,7 +573,9 @@ async fn fail_with_wrong_mint_for_receiver_acc() { let program_error = token_error::TokenError::MintMismatch as u32; assert_eq!(error_index, program_error); } - _ => panic!("Wrong error occurs while try to deposit with wrong mint fro receiver account"), + _ => { + panic!("Wrong error occurs while try to deposit with wrong mint from receiver account") + } } } @@ -578,10 +586,11 @@ async fn fail_with_uninitialized_validator_list() {} // TODO async fn fail_with_out_of_dated_pool_balances() {} // TODO #[tokio::test] -async fn success_with_deposit_authority() { +async fn success_with_stake_deposit_authority() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let deposit_authority = Keypair::new(); - let stake_pool_accounts = StakePoolAccounts::new_with_deposit_authority(deposit_authority); + let stake_deposit_authority = Keypair::new(); + let stake_pool_accounts = + StakePoolAccounts::new_with_stake_deposit_authority(stake_deposit_authority); stake_pool_accounts .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await @@ -659,10 +668,11 @@ async fn success_with_deposit_authority() { } #[tokio::test] -async fn fail_without_deposit_authority_signature() { +async fn fail_without_stake_deposit_authority_signature() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let deposit_authority = Keypair::new(); - let mut stake_pool_accounts = StakePoolAccounts::new_with_deposit_authority(deposit_authority); + let stake_deposit_authority = Keypair::new(); + let mut stake_pool_accounts = + StakePoolAccounts::new_with_stake_deposit_authority(stake_deposit_authority); stake_pool_accounts .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await @@ -726,8 +736,8 @@ async fn fail_without_deposit_authority_signature() { .unwrap(); let wrong_depositor = Keypair::new(); - stake_pool_accounts.deposit_authority = wrong_depositor.pubkey(); - stake_pool_accounts.deposit_authority_keypair = Some(wrong_depositor); + stake_pool_accounts.stake_deposit_authority = wrong_depositor.pubkey(); + stake_pool_accounts.stake_deposit_authority_keypair = Some(wrong_depositor); let error = stake_pool_accounts .deposit_stake( @@ -747,7 +757,7 @@ async fn fail_without_deposit_authority_signature() { TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { assert_eq!( error_index, - error::StakePoolError::InvalidProgramAddress as u32 + error::StakePoolError::InvalidStakeDepositAuthority as u32 ); } _ => panic!("Wrong error occurs while try to make a deposit with wrong stake program ID"), @@ -843,3 +853,113 @@ async fn fail_with_wrong_preferred_deposit() { _ => panic!("Wrong error occurs while try to make a deposit with wrong stake program ID"), } } + +#[tokio::test] +async fn success_with_referral_fee() { + let ( + mut context, + stake_pool_accounts, + validator_stake_account, + user, + deposit_stake, + pool_token_account, + stake_lamports, + ) = setup().await; + + let referrer = Keypair::new(); + let referrer_token_account = Keypair::new(); + create_token_account( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &referrer_token_account, + &stake_pool_accounts.pool_mint.pubkey(), + &referrer.pubkey(), + ) + .await + .unwrap(); + + let referrer_balance_pre = + get_token_balance(&mut context.banks_client, &referrer_token_account.pubkey()).await; + + let mut transaction = Transaction::new_with_payer( + &instruction::deposit_stake( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.withdraw_authority, + &deposit_stake, + &user.pubkey(), + &validator_stake_account.stake_account, + &stake_pool_accounts.reserve_stake.pubkey(), + &pool_token_account, + &stake_pool_accounts.pool_fee_account.pubkey(), + &referrer_token_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &spl_token::id(), + ), + Some(&context.payer.pubkey()), + ); + transaction.sign(&[&context.payer, &user], context.last_blockhash); + context + .banks_client + .process_transaction(transaction) + .await + .unwrap(); + + let referrer_balance_post = + get_token_balance(&mut context.banks_client, &referrer_token_account.pubkey()).await; + let referral_fee = stake_pool_accounts + .calculate_referral_fee(stake_pool_accounts.calculate_deposit_fee(stake_lamports)); + assert!(referral_fee > 0); + assert_eq!(referrer_balance_pre + referral_fee, referrer_balance_post); +} + +#[tokio::test] +async fn fail_with_invalid_referrer() { + let ( + mut context, + stake_pool_accounts, + validator_stake_account, + user, + deposit_stake, + pool_token_account, + _stake_lamports, + ) = setup().await; + + let invalid_token_account = Keypair::new(); + + let mut transaction = Transaction::new_with_payer( + &instruction::deposit_stake( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.withdraw_authority, + &deposit_stake, + &user.pubkey(), + &validator_stake_account.stake_account, + &stake_pool_accounts.reserve_stake.pubkey(), + &pool_token_account, + &stake_pool_accounts.pool_fee_account.pubkey(), + &invalid_token_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &spl_token::id(), + ), + Some(&context.payer.pubkey()), + ); + transaction.sign(&[&context.payer, &user], context.last_blockhash); + let transaction_error = context + .banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match transaction_error { + TransactionError::InstructionError(_, InstructionError::InvalidAccountData) => (), + _ => panic!( + "Wrong error occurs while try to make a deposit with an invalid referrer account" + ), + } +} diff --git a/program/tests/deposit_sol.rs b/program/tests/deposit_sol.rs new file mode 100644 index 00000000..f4c0bc65 --- /dev/null +++ b/program/tests/deposit_sol.rs @@ -0,0 +1,493 @@ +#![cfg(feature = "test-bpf")] + +mod helpers; + +use { + helpers::*, + solana_program::{ + borsh::try_from_slice_unchecked, instruction::InstructionError, pubkey::Pubkey, + }, + solana_program_test::*, + solana_sdk::{ + signature::{Keypair, Signer}, + transaction::Transaction, + transaction::TransactionError, + transport::TransportError, + }, + spl_stake_pool::{error, id, instruction, state}, + spl_token::error as token_error, +}; + +async fn setup() -> (ProgramTestContext, StakePoolAccounts, Keypair, Pubkey) { + let mut context = program_test().start_with_context().await; + + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + 1, + ) + .await + .unwrap(); + + let user = Keypair::new(); + + // make pool token account for user + let pool_token_account = Keypair::new(); + create_token_account( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &pool_token_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user.pubkey(), + ) + .await + .unwrap(); + let mut transaction = Transaction::new_with_payer( + &[ + instruction::set_sol_deposit_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + stake_pool_accounts.deposit_fee, + ), + instruction::set_sol_referral_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + stake_pool_accounts.referral_fee, + ), + ], + Some(&context.payer.pubkey()), + ); + + transaction.sign( + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + context + .banks_client + .process_transaction(transaction) + .await + .unwrap(); + + ( + context, + stake_pool_accounts, + user, + pool_token_account.pubkey(), + ) +} + +#[tokio::test] +async fn success() { + let (mut context, stake_pool_accounts, _user, pool_token_account) = setup().await; + + // Save stake pool state before depositing + let pre_stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let pre_stake_pool = + try_from_slice_unchecked::(&pre_stake_pool.data.as_slice()).unwrap(); + + // Save reserve state before depositing + let pre_reserve_lamports = get_account( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + ) + .await + .lamports; + + let error = stake_pool_accounts + .deposit_sol( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &pool_token_account, + TEST_STAKE_AMOUNT, + None, + ) + .await; + assert!(error.is_none()); + + let tokens_issued = TEST_STAKE_AMOUNT; // For now tokens are 1:1 to stake + + // Stake pool should add its balance to the pool balance + let post_stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let post_stake_pool = + try_from_slice_unchecked::(&post_stake_pool.data.as_slice()).unwrap(); + assert_eq!( + post_stake_pool.total_stake_lamports, + pre_stake_pool.total_stake_lamports + TEST_STAKE_AMOUNT + ); + assert_eq!( + post_stake_pool.pool_token_supply, + pre_stake_pool.pool_token_supply + tokens_issued + ); + + // Check minted tokens + let user_token_balance = + get_token_balance(&mut context.banks_client, &pool_token_account).await; + let tokens_issued_user = + tokens_issued - stake_pool_accounts.calculate_deposit_fee(tokens_issued); + assert_eq!(user_token_balance, tokens_issued_user); + + // Check reserve + let post_reserve_lamports = get_account( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + ) + .await + .lamports; + assert_eq!( + post_reserve_lamports, + pre_reserve_lamports + TEST_STAKE_AMOUNT + ); +} + +#[tokio::test] +async fn fail_with_wrong_token_program_id() { + let (mut context, stake_pool_accounts, _user, pool_token_account) = setup().await; + + let wrong_token_program = Keypair::new(); + + let mut transaction = Transaction::new_with_payer( + &instruction::deposit_sol( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts.reserve_stake.pubkey(), + &context.payer.pubkey(), + &pool_token_account, + &stake_pool_accounts.pool_fee_account.pubkey(), + &stake_pool_accounts.pool_fee_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &wrong_token_program.pubkey(), + TEST_STAKE_AMOUNT, + ), + Some(&context.payer.pubkey()), + ); + transaction.sign(&[&context.payer], context.last_blockhash); + let transaction_error = context + .banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { + assert_eq!(error, InstructionError::IncorrectProgramId); + } + _ => panic!("Wrong error occurs while try to make a deposit with wrong token program ID"), + } +} + +#[tokio::test] +async fn fail_with_wrong_withdraw_authority() { + let (mut context, mut stake_pool_accounts, _user, pool_token_account) = setup().await; + + stake_pool_accounts.withdraw_authority = Pubkey::new_unique(); + + let transaction_error = stake_pool_accounts + .deposit_sol( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &pool_token_account, + TEST_STAKE_AMOUNT, + None, + ) + .await + .unwrap() + .unwrap(); + + match transaction_error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = error::StakePoolError::InvalidProgramAddress as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while try to make a deposit with wrong withdraw authority"), + } +} + +#[tokio::test] +async fn fail_with_wrong_mint_for_receiver_acc() { + let (mut context, stake_pool_accounts, _user, _pool_token_account) = setup().await; + + let outside_mint = Keypair::new(); + let outside_withdraw_auth = Keypair::new(); + let outside_manager = Keypair::new(); + let outside_pool_fee_acc = Keypair::new(); + + create_mint( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &outside_mint, + &outside_withdraw_auth.pubkey(), + ) + .await + .unwrap(); + + create_token_account( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &outside_pool_fee_acc, + &outside_mint.pubkey(), + &outside_manager.pubkey(), + ) + .await + .unwrap(); + + let transaction_error = stake_pool_accounts + .deposit_sol( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &outside_pool_fee_acc.pubkey(), + TEST_STAKE_AMOUNT, + None, + ) + .await + .unwrap() + .unwrap(); + + match transaction_error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = token_error::TokenError::MintMismatch as u32; + assert_eq!(error_index, program_error); + } + _ => { + panic!("Wrong error occurs while try to deposit with wrong mint from receiver account") + } + } +} + +#[tokio::test] +async fn success_with_sol_deposit_authority() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .await + .unwrap(); + + let user = Keypair::new(); + + // make pool token account + let user_pool_account = Keypair::new(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user.pubkey(), + ) + .await + .unwrap(); + + let error = stake_pool_accounts + .deposit_sol( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account.pubkey(), + TEST_STAKE_AMOUNT, + None, + ) + .await; + assert!(error.is_none()); + + let sol_deposit_authority = Keypair::new(); + + let mut transaction = Transaction::new_with_payer( + &[instruction::set_deposit_authority( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + Some(&sol_deposit_authority.pubkey()), + false, + )], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &stake_pool_accounts.manager], recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); + + let error = stake_pool_accounts + .deposit_sol( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account.pubkey(), + TEST_STAKE_AMOUNT, + Some(&sol_deposit_authority), + ) + .await; + assert!(error.is_none()); +} + +#[tokio::test] +async fn fail_without_sol_deposit_authority_signature() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let sol_deposit_authority = Keypair::new(); + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .await + .unwrap(); + + let user = Keypair::new(); + + // make pool token account + let user_pool_account = Keypair::new(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user.pubkey(), + ) + .await + .unwrap(); + + let mut transaction = Transaction::new_with_payer( + &[instruction::set_deposit_authority( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + Some(&sol_deposit_authority.pubkey()), + false, + )], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &stake_pool_accounts.manager], recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); + + let wrong_depositor = Keypair::new(); + + let error = stake_pool_accounts + .deposit_sol( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account.pubkey(), + TEST_STAKE_AMOUNT, + Some(&wrong_depositor), + ) + .await + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + assert_eq!( + error_index, + error::StakePoolError::InvalidSolDepositAuthority as u32 + ); + } + _ => panic!("Wrong error occurs while trying to make a deposit without SOL deposit authority signature"), + } +} + +#[tokio::test] +async fn success_with_referral_fee() { + let (mut context, stake_pool_accounts, _user, pool_token_account) = setup().await; + + let referrer = Keypair::new(); + let referrer_token_account = Keypair::new(); + create_token_account( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &referrer_token_account, + &stake_pool_accounts.pool_mint.pubkey(), + &referrer.pubkey(), + ) + .await + .unwrap(); + + let referrer_balance_pre = + get_token_balance(&mut context.banks_client, &referrer_token_account.pubkey()).await; + + let mut transaction = Transaction::new_with_payer( + &instruction::deposit_sol( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts.reserve_stake.pubkey(), + &context.payer.pubkey(), + &pool_token_account, + &stake_pool_accounts.pool_fee_account.pubkey(), + &referrer_token_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &spl_token::id(), + TEST_STAKE_AMOUNT, + ), + Some(&context.payer.pubkey()), + ); + transaction.sign(&[&context.payer], context.last_blockhash); + context + .banks_client + .process_transaction(transaction) + .await + .unwrap(); + + let referrer_balance_post = + get_token_balance(&mut context.banks_client, &referrer_token_account.pubkey()).await; + let referral_fee = stake_pool_accounts + .calculate_referral_fee(stake_pool_accounts.calculate_deposit_fee(TEST_STAKE_AMOUNT)); + assert!(referral_fee > 0); + assert_eq!(referrer_balance_pre + referral_fee, referrer_balance_post); +} + +#[tokio::test] +async fn fail_with_invalid_referrer() { + let (mut context, stake_pool_accounts, _user, pool_token_account) = setup().await; + + let invalid_token_account = Keypair::new(); + + let mut transaction = Transaction::new_with_payer( + &instruction::deposit_sol( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts.reserve_stake.pubkey(), + &context.payer.pubkey(), + &pool_token_account, + &stake_pool_accounts.pool_fee_account.pubkey(), + &invalid_token_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &spl_token::id(), + TEST_STAKE_AMOUNT, + ), + Some(&context.payer.pubkey()), + ); + transaction.sign(&[&context.payer], context.last_blockhash); + let transaction_error = context + .banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match transaction_error { + TransactionError::InstructionError(_, InstructionError::InvalidAccountData) => (), + _ => panic!( + "Wrong error occurs while try to make a deposit with an invalid referrer account" + ), + } +} diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 03675567..b1899334 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -266,9 +266,11 @@ pub async fn create_stake_pool( pool_token_account: &Pubkey, manager: &Keypair, staker: &Pubkey, - deposit_authority: &Option, + stake_deposit_authority: &Option, fee: &state::Fee, withdrawal_fee: &state::Fee, + deposit_fee: &state::Fee, + referral_fee: u8, max_validators: u32, ) -> Result<(), TransportError> { let rent = banks_client.get_rent().await.unwrap(); @@ -303,17 +305,19 @@ pub async fn create_stake_pool( pool_mint, pool_token_account, &spl_token::id(), - deposit_authority.as_ref().map(|k| k.pubkey()), + stake_deposit_authority.as_ref().map(|k| k.pubkey()), *fee, *withdrawal_fee, + *deposit_fee, + referral_fee, max_validators, ), ], Some(&payer.pubkey()), ); let mut signers = vec![payer, stake_pool, validator_list, manager]; - if let Some(deposit_authority) = deposit_authority.as_ref() { - signers.push(deposit_authority); + if let Some(stake_deposit_authority) = stake_deposit_authority.as_ref() { + signers.push(stake_deposit_authority); } transaction.sign(&signers, *recent_blockhash); banks_client.process_transaction(transaction).await?; @@ -542,10 +546,12 @@ pub struct StakePoolAccounts { pub manager: Keypair, pub staker: Keypair, pub withdraw_authority: Pubkey, - pub deposit_authority: Pubkey, - pub deposit_authority_keypair: Option, + pub stake_deposit_authority: Pubkey, + pub stake_deposit_authority_keypair: Option, pub fee: state::Fee, pub withdrawal_fee: state::Fee, + pub deposit_fee: state::Fee, + pub referral_fee: u8, pub max_validators: u32, } @@ -558,7 +564,7 @@ impl StakePoolAccounts { &[&stake_pool_address.to_bytes()[..32], b"withdraw"], &id(), ); - let (deposit_authority, _) = Pubkey::find_program_address( + let (stake_deposit_authority, _) = Pubkey::find_program_address( &[&stake_pool_address.to_bytes()[..32], b"deposit"], &id(), ); @@ -577,8 +583,8 @@ impl StakePoolAccounts { manager, staker, withdraw_authority, - deposit_authority, - deposit_authority_keypair: None, + stake_deposit_authority, + stake_deposit_authority_keypair: None, fee: state::Fee { numerator: 1, denominator: 100, @@ -587,14 +593,19 @@ impl StakePoolAccounts { numerator: 3, denominator: 1000, }, + deposit_fee: state::Fee { + numerator: 1, + denominator: 1000, + }, + referral_fee: 25, max_validators: MAX_TEST_VALIDATORS, } } - pub fn new_with_deposit_authority(deposit_authority: Keypair) -> Self { + pub fn new_with_stake_deposit_authority(stake_deposit_authority: Keypair) -> Self { let mut stake_pool_accounts = Self::new(); - stake_pool_accounts.deposit_authority = deposit_authority.pubkey(); - stake_pool_accounts.deposit_authority_keypair = Some(deposit_authority); + stake_pool_accounts.stake_deposit_authority = stake_deposit_authority.pubkey(); + stake_pool_accounts.stake_deposit_authority_keypair = Some(stake_deposit_authority); stake_pool_accounts } @@ -606,6 +617,14 @@ impl StakePoolAccounts { pool_tokens * self.withdrawal_fee.numerator / self.withdrawal_fee.denominator } + pub fn calculate_deposit_fee(&self, pool_tokens: u64) -> u64 { + pool_tokens * self.deposit_fee.numerator / self.deposit_fee.denominator + } + + pub fn calculate_referral_fee(&self, deposit_fee_collected: u64) -> u64 { + deposit_fee_collected * self.referral_fee as u64 / 100 + } + pub async fn initialize_stake_pool( &self, mut banks_client: &mut BanksClient, @@ -654,9 +673,11 @@ impl StakePoolAccounts { &self.pool_fee_account.pubkey(), &self.manager, &self.staker.pubkey(), - &self.deposit_authority_keypair, + &self.stake_deposit_authority_keypair, &self.fee, &self.withdrawal_fee, + &self.deposit_fee, + self.referral_fee, self.max_validators, ) .await?; @@ -675,36 +696,91 @@ impl StakePoolAccounts { current_staker: &Keypair, ) -> Option { let mut signers = vec![payer, current_staker]; - let instructions = if let Some(deposit_authority) = self.deposit_authority_keypair.as_ref() - { - signers.push(deposit_authority); - instruction::deposit_with_authority( + let instructions = + if let Some(stake_deposit_authority) = self.stake_deposit_authority_keypair.as_ref() { + signers.push(stake_deposit_authority); + instruction::deposit_stake_with_authority( + &id(), + &self.stake_pool.pubkey(), + &self.validator_list.pubkey(), + &self.stake_deposit_authority, + &self.withdraw_authority, + stake, + ¤t_staker.pubkey(), + validator_stake_account, + &self.reserve_stake.pubkey(), + pool_account, + &self.pool_fee_account.pubkey(), + &self.pool_fee_account.pubkey(), + &self.pool_mint.pubkey(), + &spl_token::id(), + ) + } else { + instruction::deposit_stake( + &id(), + &self.stake_pool.pubkey(), + &self.validator_list.pubkey(), + &self.withdraw_authority, + stake, + ¤t_staker.pubkey(), + validator_stake_account, + &self.reserve_stake.pubkey(), + pool_account, + &self.pool_fee_account.pubkey(), + &self.pool_fee_account.pubkey(), + &self.pool_mint.pubkey(), + &spl_token::id(), + ) + }; + let transaction = Transaction::new_signed_with_payer( + &instructions, + Some(&payer.pubkey()), + &signers, + *recent_blockhash, + ); + banks_client.process_transaction(transaction).await.err() + } + + #[allow(clippy::too_many_arguments)] + pub async fn deposit_sol( + &self, + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + pool_account: &Pubkey, + amount: u64, + sol_deposit_authority: Option<&Keypair>, + ) -> Option { + let mut signers = vec![payer]; + let instructions = if let Some(sol_deposit_authority) = sol_deposit_authority { + signers.push(sol_deposit_authority); + instruction::deposit_sol_with_authority( &id(), &self.stake_pool.pubkey(), - &self.validator_list.pubkey(), - &self.deposit_authority, + &sol_deposit_authority.pubkey(), &self.withdraw_authority, - stake, - ¤t_staker.pubkey(), - validator_stake_account, &self.reserve_stake.pubkey(), + &payer.pubkey(), pool_account, + &self.pool_fee_account.pubkey(), + &self.pool_fee_account.pubkey(), &self.pool_mint.pubkey(), &spl_token::id(), + amount, ) } else { - instruction::deposit( + instruction::deposit_sol( &id(), &self.stake_pool.pubkey(), - &self.validator_list.pubkey(), &self.withdraw_authority, - stake, - ¤t_staker.pubkey(), - validator_stake_account, &self.reserve_stake.pubkey(), + &payer.pubkey(), pool_account, + &self.pool_fee_account.pubkey(), + &self.pool_fee_account.pubkey(), &self.pool_mint.pubkey(), &spl_token::id(), + amount, ) }; let transaction = Transaction::new_signed_with_payer( @@ -730,7 +806,7 @@ impl StakePoolAccounts { amount: u64, ) -> Option { let transaction = Transaction::new_signed_with_payer( - &[instruction::withdraw( + &[instruction::withdraw_stake( &id(), &self.stake_pool.pubkey(), &self.validator_list.pubkey(), @@ -1084,7 +1160,7 @@ impl DepositStakeAccount { .await; } - pub async fn deposit( + pub async fn deposit_stake( &mut self, banks_client: &mut BanksClient, payer: &Keypair, @@ -1119,7 +1195,7 @@ impl DepositStakeAccount { } } -pub async fn simple_deposit( +pub async fn simple_deposit_stake( banks_client: &mut BanksClient, payer: &Keypair, recent_blockhash: &Hash, diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index 84925443..baa5b1d1 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -32,7 +32,7 @@ use { spl_token::state::{Account as SplAccount, AccountState as SplAccountState, Mint}, }; -const HUGE_POOL_SIZE: u32 = 4_000; +const HUGE_POOL_SIZE: u32 = 3_950; const ACCOUNT_RENT_EXEMPTION: u64 = 1_000_000_000; // go with something big to be safe const STAKE_AMOUNT: u64 = 200_000_000_000; const STAKE_ACCOUNT_RENT_EXEMPTION: u64 = 2_282_880; @@ -56,15 +56,15 @@ async fn setup( stake_pool_accounts.max_validators = max_validators; let stake_pool_pubkey = stake_pool_accounts.stake_pool.pubkey(); - let (_, withdraw_bump_seed) = + let (_, stake_withdraw_bump_seed) = find_withdraw_authority_program_address(&id(), &stake_pool_pubkey); let mut stake_pool = StakePool { account_type: AccountType::StakePool, manager: stake_pool_accounts.manager.pubkey(), staker: stake_pool_accounts.staker.pubkey(), - deposit_authority: stake_pool_accounts.deposit_authority, - withdraw_bump_seed, + stake_deposit_authority: stake_pool_accounts.stake_deposit_authority, + stake_withdraw_bump_seed, validator_list: stake_pool_accounts.validator_list.pubkey(), reserve_stake: stake_pool_accounts.reserve_stake.pubkey(), pool_mint: stake_pool_accounts.pool_mint.pubkey(), @@ -78,10 +78,13 @@ async fn setup( next_epoch_fee: None, preferred_deposit_validator_vote_address: None, preferred_withdraw_validator_vote_address: None, - deposit_fee: Fee::default(), + stake_deposit_fee: Fee::default(), + sol_deposit_fee: Fee::default(), withdrawal_fee: Fee::default(), next_withdrawal_fee: None, - referral_fee: 0, + stake_referral_fee: 0, + sol_referral_fee: 0, + sol_deposit_authority: None, }; let mut validator_list = ValidatorList::new(max_validators); @@ -592,7 +595,7 @@ async fn add_validator_to_pool() { increase_amount, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let validator_list = get_account( &mut context.banks_client, @@ -655,7 +658,7 @@ async fn set_preferred() { } #[tokio::test] -async fn deposit() { +async fn deposit_stake() { let (mut context, stake_pool_accounts, _, vote_pubkey, user, stake_pubkey, pool_account_pubkey) = setup(HUGE_POOL_SIZE, HUGE_POOL_SIZE, STAKE_AMOUNT).await; diff --git a/program/tests/increase.rs b/program/tests/increase.rs index b6727352..bd091c33 100644 --- a/program/tests/increase.rs +++ b/program/tests/increase.rs @@ -46,7 +46,7 @@ async fn setup() -> ( ) .await; - let _deposit_info = simple_deposit( + let _deposit_info = simple_deposit_stake( &mut banks_client, &payer, &recent_blockhash, diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index d6cb05a3..6d028c27 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -254,6 +254,8 @@ async fn fail_with_wrong_max_validators() { None, stake_pool_accounts.fee, stake_pool_accounts.withdrawal_fee, + stake_pool_accounts.deposit_fee, + stake_pool_accounts.referral_fee, stake_pool_accounts.max_validators, ), ], @@ -325,6 +327,8 @@ async fn fail_with_wrong_mint_authority() { &None, &stake_pool_accounts.fee, &stake_pool_accounts.withdrawal_fee, + &stake_pool_accounts.deposit_fee, + stake_pool_accounts.referral_fee, stake_pool_accounts.max_validators, ) .await @@ -411,6 +415,8 @@ async fn fail_with_freeze_authority() { &None, &stake_pool_accounts.fee, &stake_pool_accounts.withdrawal_fee, + &stake_pool_accounts.deposit_fee, + stake_pool_accounts.referral_fee, stake_pool_accounts.max_validators, ) .await @@ -499,6 +505,8 @@ async fn fail_with_wrong_token_program_id() { None, stake_pool_accounts.fee, stake_pool_accounts.withdrawal_fee, + stake_pool_accounts.deposit_fee, + stake_pool_accounts.referral_fee, stake_pool_accounts.max_validators, ), ], @@ -576,6 +584,8 @@ async fn fail_with_wrong_fee_account() { &None, &stake_pool_accounts.fee, &stake_pool_accounts.withdrawal_fee, + &stake_pool_accounts.deposit_fee, + stake_pool_accounts.referral_fee, stake_pool_accounts.max_validators, ) .await @@ -665,6 +675,8 @@ async fn fail_with_not_rent_exempt_pool() { None, stake_pool_accounts.fee, stake_pool_accounts.withdrawal_fee, + stake_pool_accounts.deposit_fee, + stake_pool_accounts.referral_fee, stake_pool_accounts.max_validators, ), ], @@ -740,6 +752,8 @@ async fn fail_with_not_rent_exempt_validator_list() { None, stake_pool_accounts.fee, stake_pool_accounts.withdrawal_fee, + stake_pool_accounts.deposit_fee, + stake_pool_accounts.referral_fee, stake_pool_accounts.max_validators, ), ], @@ -792,6 +806,8 @@ async fn fail_without_manager_signature() { let init_data = instruction::StakePoolInstruction::Initialize { fee: stake_pool_accounts.fee, withdrawal_fee: stake_pool_accounts.withdrawal_fee, + deposit_fee: stake_pool_accounts.deposit_fee, + referral_fee: stake_pool_accounts.referral_fee, max_validators: stake_pool_accounts.max_validators, }; let data = init_data.try_to_vec().unwrap(); @@ -914,6 +930,8 @@ async fn fail_with_pre_minted_pool_tokens() { &None, &stake_pool_accounts.fee, &stake_pool_accounts.withdrawal_fee, + &stake_pool_accounts.deposit_fee, + stake_pool_accounts.referral_fee, stake_pool_accounts.max_validators, ) .await @@ -976,6 +994,8 @@ async fn fail_with_bad_reserve() { &None, &stake_pool_accounts.fee, &stake_pool_accounts.withdrawal_fee, + &stake_pool_accounts.deposit_fee, + stake_pool_accounts.referral_fee, stake_pool_accounts.max_validators, ) .await @@ -1022,6 +1042,8 @@ async fn fail_with_bad_reserve() { &None, &stake_pool_accounts.fee, &stake_pool_accounts.withdrawal_fee, + &stake_pool_accounts.deposit_fee, + stake_pool_accounts.referral_fee, stake_pool_accounts.max_validators, ) .await @@ -1071,6 +1093,8 @@ async fn fail_with_bad_reserve() { &None, &stake_pool_accounts.fee, &stake_pool_accounts.withdrawal_fee, + &stake_pool_accounts.deposit_fee, + stake_pool_accounts.referral_fee, stake_pool_accounts.max_validators, ) .await @@ -1120,6 +1144,8 @@ async fn fail_with_bad_reserve() { &None, &stake_pool_accounts.fee, &stake_pool_accounts.withdrawal_fee, + &stake_pool_accounts.deposit_fee, + stake_pool_accounts.referral_fee, stake_pool_accounts.max_validators, ) .await @@ -1138,10 +1164,11 @@ async fn fail_with_bad_reserve() { } #[tokio::test] -async fn success_with_required_deposit_authority() { +async fn success_with_required_stake_deposit_authority() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let deposit_authority = Keypair::new(); - let stake_pool_accounts = StakePoolAccounts::new_with_deposit_authority(deposit_authority); + let stake_deposit_authority = Keypair::new(); + let stake_pool_accounts = + StakePoolAccounts::new_with_stake_deposit_authority(stake_deposit_authority); stake_pool_accounts .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await @@ -1153,7 +1180,7 @@ async fn success_with_required_deposit_authority() { let stake_pool = try_from_slice_unchecked::(stake_pool_account.data.as_slice()).unwrap(); assert_eq!( - stake_pool.deposit_authority, - stake_pool_accounts.deposit_authority + stake_pool.stake_deposit_authority, + stake_pool_accounts.stake_deposit_authority ); } diff --git a/program/tests/set_deposit_authority.rs b/program/tests/set_deposit_authority.rs new file mode 100644 index 00000000..ddded681 --- /dev/null +++ b/program/tests/set_deposit_authority.rs @@ -0,0 +1,359 @@ +#![cfg(feature = "test-bpf")] + +mod helpers; + +use { + borsh::BorshSerialize, + helpers::*, + solana_program::{ + borsh::try_from_slice_unchecked, + hash::Hash, + instruction::{AccountMeta, Instruction}, + }, + solana_program_test::*, + solana_sdk::{ + instruction::InstructionError, signature::Keypair, signature::Signer, + transaction::Transaction, transaction::TransactionError, transport::TransportError, + }, + spl_stake_pool::{error, find_deposit_authority_program_address, id, instruction, state}, +}; + +async fn setup() -> (BanksClient, Keypair, Hash, StakePoolAccounts, Keypair) { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .await + .unwrap(); + + let new_deposit_authority = Keypair::new(); + + ( + banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + new_deposit_authority, + ) +} + +#[tokio::test] +async fn success_set_stake_deposit_authority() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + new_stake_deposit_authority, + ) = setup().await; + + let mut transaction = Transaction::new_with_payer( + &[instruction::set_deposit_authority( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + Some(&new_stake_deposit_authority.pubkey()), + true, + )], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &stake_pool_accounts.manager], recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); + + let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; + let stake_pool = + try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + + assert_eq!( + stake_pool.stake_deposit_authority, + new_stake_deposit_authority.pubkey() + ); +} + +#[tokio::test] +async fn success_set_stake_deposit_authority_to_none() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + new_stake_deposit_authority, + ) = setup().await; + + let mut transaction = Transaction::new_with_payer( + &[instruction::set_deposit_authority( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + Some(&new_stake_deposit_authority.pubkey()), + true, + )], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &stake_pool_accounts.manager], recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); + + let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; + let stake_pool = + try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + + assert_eq!( + stake_pool.stake_deposit_authority, + new_stake_deposit_authority.pubkey() + ); + + let mut transaction = Transaction::new_with_payer( + &[instruction::set_deposit_authority( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + None, + true, + )], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &stake_pool_accounts.manager], recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); + + let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; + let stake_pool = + try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + + assert_eq!( + stake_pool.stake_deposit_authority, + find_deposit_authority_program_address(&id(), &stake_pool_accounts.stake_pool.pubkey()).0 + ); +} + +#[tokio::test] +async fn fail_stake_wrong_manager() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + new_stake_deposit_authority, + ) = setup().await; + + let mut transaction = Transaction::new_with_payer( + &[instruction::set_deposit_authority( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &new_stake_deposit_authority.pubkey(), + Some(&new_stake_deposit_authority.pubkey()), + true, + )], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &new_stake_deposit_authority], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::WrongManager as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while malicious try to set manager"), + } +} + +#[tokio::test] +async fn fail_set_stake_deposit_authority_without_signature() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + new_stake_deposit_authority, + ) = setup().await; + + let data = + instruction::StakePoolInstruction::SetDepositAuthority(instruction::DepositType::Stake) + .try_to_vec() + .unwrap(); + let accounts = vec![ + AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), + AccountMeta::new_readonly(stake_pool_accounts.manager.pubkey(), false), + AccountMeta::new_readonly(new_stake_deposit_authority.pubkey(), false), + ]; + let instruction = Instruction { + program_id: id(), + accounts, + data, + }; + + let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); + transaction.sign(&[&payer], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::SignatureMissing as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while try to set new manager without signature"), + } +} + +#[tokio::test] +async fn success_set_sol_deposit_authority() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_sol_deposit_authority) = + setup().await; + + let mut transaction = Transaction::new_with_payer( + &[instruction::set_deposit_authority( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + Some(&new_sol_deposit_authority.pubkey()), + false, + )], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &stake_pool_accounts.manager], recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); + + let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; + let stake_pool = + try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + + assert_eq!( + stake_pool.sol_deposit_authority, + Some(new_sol_deposit_authority.pubkey()) + ); +} + +#[tokio::test] +async fn success_set_sol_deposit_authority_to_none() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_sol_deposit_authority) = + setup().await; + + let mut transaction = Transaction::new_with_payer( + &[instruction::set_deposit_authority( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + Some(&new_sol_deposit_authority.pubkey()), + false, + )], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &stake_pool_accounts.manager], recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); + + let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; + let stake_pool = + try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + + assert_eq!( + stake_pool.sol_deposit_authority, + Some(new_sol_deposit_authority.pubkey()) + ); + + let mut transaction = Transaction::new_with_payer( + &[instruction::set_deposit_authority( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + None, + false, + )], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &stake_pool_accounts.manager], recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); + + let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; + let stake_pool = + try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + + assert_eq!(stake_pool.sol_deposit_authority, None); +} + +#[tokio::test] +async fn fail_sol_wrong_manager() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_sol_deposit_authority) = + setup().await; + + let mut transaction = Transaction::new_with_payer( + &[instruction::set_deposit_authority( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &new_sol_deposit_authority.pubkey(), + Some(&new_sol_deposit_authority.pubkey()), + false, + )], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &new_sol_deposit_authority], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::WrongManager as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while malicious try to set manager"), + } +} + +#[tokio::test] +async fn fail_set_sol_deposit_authority_without_signature() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_sol_deposit_authority) = + setup().await; + + let data = + instruction::StakePoolInstruction::SetDepositAuthority(instruction::DepositType::Sol) + .try_to_vec() + .unwrap(); + let accounts = vec![ + AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), + AccountMeta::new_readonly(stake_pool_accounts.manager.pubkey(), false), + AccountMeta::new_readonly(new_sol_deposit_authority.pubkey(), false), + ]; + let instruction = Instruction { + program_id: id(), + accounts, + data, + }; + + let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); + transaction.sign(&[&payer], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::SignatureMissing as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while try to set new manager without signature"), + } +} diff --git a/program/tests/set_deposit_fee.rs b/program/tests/set_deposit_fee.rs new file mode 100644 index 00000000..f99f7cc9 --- /dev/null +++ b/program/tests/set_deposit_fee.rs @@ -0,0 +1,274 @@ +#![cfg(feature = "test-bpf")] + +mod helpers; + +use { + helpers::*, + solana_program_test::*, + solana_sdk::{ + borsh::try_from_slice_unchecked, + instruction::InstructionError, + signature::{Keypair, Signer}, + transaction::{Transaction, TransactionError}, + }, + spl_stake_pool::{error, id, instruction, state::Fee, state::StakePool}, +}; + +async fn setup(fee: Option) -> (ProgramTestContext, StakePoolAccounts, Fee) { + let mut context = program_test().start_with_context().await; + let mut stake_pool_accounts = StakePoolAccounts::new(); + if let Some(fee) = fee { + stake_pool_accounts.deposit_fee = fee; + } + stake_pool_accounts + .initialize_stake_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + 1, + ) + .await + .unwrap(); + let new_deposit_fee = Fee { + numerator: 823, + denominator: 1000, + }; + + (context, stake_pool_accounts, new_deposit_fee) +} + +#[tokio::test] +async fn success_stake() { + let (mut context, stake_pool_accounts, new_deposit_fee) = setup(None).await; + + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_stake_deposit_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + new_deposit_fee, + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + context + .banks_client + .process_transaction(transaction) + .await + .unwrap(); + + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + assert_eq!(stake_pool.stake_deposit_fee, new_deposit_fee); +} + +#[tokio::test] +async fn success_stake_increase_fee_from_0() { + let (mut context, stake_pool_accounts, _) = setup(Some(Fee { + numerator: 0, + denominator: 0, + })) + .await; + let new_deposit_fee = Fee { + numerator: 324, + denominator: 1234, + }; + + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_stake_deposit_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + new_deposit_fee, + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + context + .banks_client + .process_transaction(transaction) + .await + .unwrap(); + + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + assert_eq!(stake_pool.stake_deposit_fee, new_deposit_fee); +} + +#[tokio::test] +async fn fail_stake_wrong_manager() { + let (mut context, stake_pool_accounts, new_deposit_fee) = setup(None).await; + + let wrong_manager = Keypair::new(); + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_stake_deposit_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &wrong_manager.pubkey(), + new_deposit_fee, + )], + Some(&context.payer.pubkey()), + &[&context.payer, &wrong_manager], + context.last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = error::StakePoolError::WrongManager as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while signing with the wrong manager"), + } +} + +#[tokio::test] +async fn fail_stake_high_deposit_fee() { + let (mut context, stake_pool_accounts, _new_deposit_fee) = setup(None).await; + + let new_deposit_fee = Fee { + numerator: 100001, + denominator: 100000, + }; + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_stake_deposit_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + new_deposit_fee, + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = error::StakePoolError::FeeTooHigh as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs when setting fee too high"), + } +} + +#[tokio::test] +async fn success_sol() { + let (mut context, stake_pool_accounts, new_deposit_fee) = setup(None).await; + + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_sol_deposit_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + new_deposit_fee, + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + context + .banks_client + .process_transaction(transaction) + .await + .unwrap(); + + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + assert_eq!(stake_pool.sol_deposit_fee, new_deposit_fee); +} + +#[tokio::test] +async fn fail_sol_wrong_manager() { + let (mut context, stake_pool_accounts, new_deposit_fee) = setup(None).await; + + let wrong_manager = Keypair::new(); + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_sol_deposit_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &wrong_manager.pubkey(), + new_deposit_fee, + )], + Some(&context.payer.pubkey()), + &[&context.payer, &wrong_manager], + context.last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = error::StakePoolError::WrongManager as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while signing with the wrong manager"), + } +} + +#[tokio::test] +async fn fail_sol_high_deposit_fee() { + let (mut context, stake_pool_accounts, _new_deposit_fee) = setup(None).await; + + let new_deposit_fee = Fee { + numerator: 100001, + denominator: 100000, + }; + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_sol_deposit_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + new_deposit_fee, + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = error::StakePoolError::FeeTooHigh as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs when setting fee too high"), + } +} diff --git a/program/tests/set_fee.rs b/program/tests/set_fee.rs index fb5adb58..00585ad8 100644 --- a/program/tests/set_fee.rs +++ b/program/tests/set_fee.rs @@ -50,7 +50,7 @@ async fn success() { let old_fee = stake_pool.fee; let transaction = Transaction::new_signed_with_payer( - &[instruction::set_fee( + &[instruction::set_epoch_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), @@ -108,7 +108,7 @@ async fn fail_wrong_manager() { let wrong_manager = Keypair::new(); let transaction = Transaction::new_signed_with_payer( - &[instruction::set_fee( + &[instruction::set_epoch_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &wrong_manager.pubkey(), @@ -144,7 +144,7 @@ async fn fail_high_fee() { denominator: 10, }; let transaction = Transaction::new_signed_with_payer( - &[instruction::set_fee( + &[instruction::set_epoch_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), @@ -193,7 +193,7 @@ async fn fail_not_updated() { context.warp_to_slot(50_000).unwrap(); let transaction = Transaction::new_signed_with_payer( - &[instruction::set_fee( + &[instruction::set_epoch_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), diff --git a/program/tests/set_referral_fee.rs b/program/tests/set_referral_fee.rs new file mode 100644 index 00000000..cda1a7b4 --- /dev/null +++ b/program/tests/set_referral_fee.rs @@ -0,0 +1,258 @@ +#![cfg(feature = "test-bpf")] + +mod helpers; + +use { + helpers::*, + solana_program_test::*, + solana_sdk::{ + borsh::try_from_slice_unchecked, + instruction::InstructionError, + signature::{Keypair, Signer}, + transaction::{Transaction, TransactionError}, + }, + spl_stake_pool::{error, id, instruction, state::StakePool}, +}; + +async fn setup(fee: Option) -> (ProgramTestContext, StakePoolAccounts, u8) { + let mut context = program_test().start_with_context().await; + let mut stake_pool_accounts = StakePoolAccounts::new(); + if let Some(fee) = fee { + stake_pool_accounts.referral_fee = fee; + } + stake_pool_accounts + .initialize_stake_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + 1, + ) + .await + .unwrap(); + let new_referral_fee = 15u8; + + (context, stake_pool_accounts, new_referral_fee) +} + +#[tokio::test] +async fn success_stake() { + let (mut context, stake_pool_accounts, new_referral_fee) = setup(None).await; + + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_stake_referral_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + new_referral_fee, + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + context + .banks_client + .process_transaction(transaction) + .await + .unwrap(); + + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + assert_eq!(stake_pool.stake_referral_fee, new_referral_fee); +} + +#[tokio::test] +async fn success_stake_increase_fee_from_0() { + let (mut context, stake_pool_accounts, _) = setup(Some(0u8)).await; + let new_referral_fee = 30u8; + + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_stake_referral_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + new_referral_fee, + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + context + .banks_client + .process_transaction(transaction) + .await + .unwrap(); + + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + assert_eq!(stake_pool.stake_referral_fee, new_referral_fee); +} + +#[tokio::test] +async fn fail_stake_wrong_manager() { + let (mut context, stake_pool_accounts, new_referral_fee) = setup(None).await; + + let wrong_manager = Keypair::new(); + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_stake_referral_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &wrong_manager.pubkey(), + new_referral_fee, + )], + Some(&context.payer.pubkey()), + &[&context.payer, &wrong_manager], + context.last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = error::StakePoolError::WrongManager as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while signing with the wrong manager"), + } +} + +#[tokio::test] +async fn fail_stake_high_referral_fee() { + let (mut context, stake_pool_accounts, _new_referral_fee) = setup(None).await; + + let new_referral_fee = 110u8; + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_stake_referral_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + new_referral_fee, + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = error::StakePoolError::FeeTooHigh as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs when setting fee too high"), + } +} + +#[tokio::test] +async fn success_sol() { + let (mut context, stake_pool_accounts, new_referral_fee) = setup(None).await; + + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_sol_referral_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + new_referral_fee, + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + context + .banks_client + .process_transaction(transaction) + .await + .unwrap(); + + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + assert_eq!(stake_pool.sol_referral_fee, new_referral_fee); +} + +#[tokio::test] +async fn fail_sol_wrong_manager() { + let (mut context, stake_pool_accounts, new_referral_fee) = setup(None).await; + + let wrong_manager = Keypair::new(); + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_sol_referral_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &wrong_manager.pubkey(), + new_referral_fee, + )], + Some(&context.payer.pubkey()), + &[&context.payer, &wrong_manager], + context.last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = error::StakePoolError::WrongManager as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while signing with the wrong manager"), + } +} + +#[tokio::test] +async fn fail_sol_high_referral_fee() { + let (mut context, stake_pool_accounts, _new_referral_fee) = setup(None).await; + + let new_referral_fee = 110u8; + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_sol_referral_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + new_referral_fee, + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = error::StakePoolError::FeeTooHigh as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs when setting fee too high"), + } +} diff --git a/program/tests/set_withdrawal_fee.rs b/program/tests/set_withdrawal_fee.rs index fac2ce4b..395f3f9d 100644 --- a/program/tests/set_withdrawal_fee.rs +++ b/program/tests/set_withdrawal_fee.rs @@ -321,42 +321,6 @@ async fn fail_high_withdrawal_fee_increase_from_0() { } } -#[tokio::test] -async fn fail_bad_fee() { - let (mut context, stake_pool_accounts, _new_fee) = setup(None).await; - - let new_withdrawal_fee = Fee { - numerator: 11, - denominator: 10, - }; - let transaction = Transaction::new_signed_with_payer( - &[instruction::set_withdrawal_fee( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.manager.pubkey(), - new_withdrawal_fee, - )], - Some(&context.payer.pubkey()), - &[&context.payer, &stake_pool_accounts.manager], - context.last_blockhash, - ); - let error = context - .banks_client - .process_transaction(transaction) - .await - .err() - .unwrap() - .unwrap(); - - match error { - TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { - let program_error = error::StakePoolError::FeeTooHigh as u32; - assert_eq!(error_index, program_error); - } - _ => panic!("Wrong error occurs when setting fee too high"), - } -} - #[tokio::test] async fn fail_not_updated() { let mut context = program_test().start_with_context().await; diff --git a/program/tests/update_stake_pool_balance.rs b/program/tests/update_stake_pool_balance.rs index 98b9f87f..aa1a2272 100644 --- a/program/tests/update_stake_pool_balance.rs +++ b/program/tests/update_stake_pool_balance.rs @@ -44,7 +44,7 @@ async fn setup() -> ( ) .await; - let _deposit_info = simple_deposit( + let _deposit_info = simple_deposit_stake( &mut context.banks_client, &context.payer, &context.last_blockhash, @@ -65,6 +65,12 @@ async fn setup() -> ( async fn success() { let (mut context, stake_pool_accounts, stake_accounts) = setup().await; + let pre_fee = get_token_balance( + &mut context.banks_client, + &stake_pool_accounts.pool_fee_account.pubkey(), + ) + .await; + let pre_balance = get_validator_list_sum( &mut context.banks_client, &stake_pool_accounts.reserve_stake.pubkey(), @@ -134,7 +140,7 @@ async fn success() { let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); assert_eq!(post_balance, stake_pool.total_stake_lamports); - let actual_fee = get_token_balance( + let post_fee = get_token_balance( &mut context.banks_client, &stake_pool_accounts.pool_fee_account.pubkey(), ) @@ -144,6 +150,7 @@ async fn success() { &stake_pool_accounts.pool_mint.pubkey(), ) .await; + let actual_fee = post_fee - pre_fee; assert_eq!(pool_token_supply - pre_token_supply, actual_fee); let expected_fee_lamports = diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index c8326183..f761aa0f 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -103,7 +103,7 @@ async fn setup( for deposit_account in &mut deposit_accounts { deposit_account - .deposit( + .deposit_stake( &mut context.banks_client, &context.payer, &context.last_blockhash, diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 743cf888..c27d9c54 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -434,7 +434,7 @@ async fn success_with_deactivating_transient_stake() { let rent = banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); - let deposit_info = simple_deposit( + let deposit_info = simple_deposit_stake( &mut banks_client, &payer, &recent_blockhash, @@ -472,7 +472,7 @@ async fn success_with_deactivating_transient_stake() { assert!(error.is_none()); // fail deposit - let maybe_deposit = simple_deposit( + let maybe_deposit = simple_deposit_stake( &mut banks_client, &payer, &recent_blockhash, diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 9c496e38..1af022bf 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -51,7 +51,7 @@ async fn setup() -> ( ) .await; - let deposit_info = simple_deposit( + let deposit_info = simple_deposit_stake( &mut banks_client, &payer, &recent_blockhash, @@ -274,7 +274,7 @@ async fn fail_with_wrong_stake_program() { let instruction = Instruction { program_id: id(), accounts, - data: instruction::StakePoolInstruction::Withdraw(tokens_to_burn) + data: instruction::StakePoolInstruction::WithdrawStake(tokens_to_burn) .try_to_vec() .unwrap(), }; @@ -361,7 +361,7 @@ async fn fail_with_wrong_token_program_id() { let wrong_token_program = Keypair::new(); let transaction = Transaction::new_signed_with_payer( - &[instruction::withdraw( + &[instruction::withdraw_stake( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.validator_list.pubkey(), @@ -475,6 +475,67 @@ async fn fail_with_unknown_validator() { ) .await; + let user_pool_account = Keypair::new(); + let user = Keypair::new(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user.pubkey(), + ) + .await + .unwrap(); + + let user = Keypair::new(); + // make stake account + let user_stake = Keypair::new(); + let lockup = stake_program::Lockup::default(); + let authorized = stake_program::Authorized { + staker: stake_pool_accounts.stake_deposit_authority, + withdrawer: stake_pool_accounts.stake_deposit_authority, + }; + create_independent_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake, + &authorized, + &lockup, + TEST_STAKE_AMOUNT, + ) + .await; + // make pool token account + let user_pool_account = Keypair::new(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user.pubkey(), + ) + .await + .unwrap(); + + let user_pool_account = user_pool_account.pubkey(); + let pool_tokens = get_token_balance(&mut banks_client, &user_pool_account).await; + + let tokens_to_burn = pool_tokens / 4; + + // Delegate tokens for burning + delegate_tokens( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account, + &user, + &user_transfer_authority.pubkey(), + tokens_to_burn, + ) + .await; + let new_authority = Pubkey::new_unique(); let transaction_error = stake_pool_accounts .withdraw_stake( @@ -585,7 +646,7 @@ async fn fail_without_token_approval() { ) .await; - let deposit_info = simple_deposit( + let deposit_info = simple_deposit_stake( &mut banks_client, &payer, &recent_blockhash, @@ -656,7 +717,7 @@ async fn fail_with_low_delegation() { ) .await; - let deposit_info = simple_deposit( + let deposit_info = simple_deposit_stake( &mut banks_client, &payer, &recent_blockhash, @@ -796,7 +857,7 @@ async fn success_with_reserve() { let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); - let deposit_info = simple_deposit( + let deposit_info = simple_deposit_stake( &mut context.banks_client, &context.payer, &context.last_blockhash, @@ -930,10 +991,12 @@ async fn success_with_reserve() { assert!(error.is_none()); // first and only deposit, lamports:pool 1:1 + let tokens_deposit_fee = + stake_pool_accounts.calculate_deposit_fee(deposit_info.stake_lamports + stake_rent); let tokens_withdrawal_fee = stake_pool_accounts.calculate_withdrawal_fee(deposit_info.pool_tokens); assert_eq!( - deposit_info.stake_lamports + stake_rent, + deposit_info.stake_lamports + stake_rent - tokens_deposit_fee, deposit_info.pool_tokens, ); @@ -954,8 +1017,12 @@ async fn success_with_reserve() { let stake_state = deserialize::(&reserve_stake_account.data).unwrap(); let meta = stake_state.meta().unwrap(); + // TODO: these numbers dont add up even with +tokens_deposit_fee assert_eq!( - initial_reserve_lamports + meta.rent_exempt_reserve + tokens_withdrawal_fee, + initial_reserve_lamports + + meta.rent_exempt_reserve + + tokens_withdrawal_fee + + tokens_deposit_fee, reserve_stake_account.lamports ); @@ -964,7 +1031,9 @@ async fn success_with_reserve() { get_account(&mut context.banks_client, &withdraw_destination.pubkey()).await; assert_eq!( user_stake_recipient_account.lamports, - initial_stake_lamports + deposit_info.stake_lamports + stake_rent - tokens_withdrawal_fee + initial_stake_lamports + deposit_info.stake_lamports + stake_rent + - tokens_withdrawal_fee + - tokens_deposit_fee ); } @@ -1059,7 +1128,7 @@ async fn fail_with_wrong_preferred_withdraw() { assert!(error.is_none()); // deposit into preferred, then fail - let _preferred_deposit = simple_deposit( + let _preferred_deposit = simple_deposit_stake( &mut banks_client, &payer, &recent_blockhash, @@ -1152,7 +1221,7 @@ async fn success_withdraw_from_transient() { let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); - let deposit_info = simple_deposit( + let deposit_info = simple_deposit_stake( &mut context.banks_client, &context.payer, &context.last_blockhash, From 733f9e2a12bed26895a9448a3ffa44b13b995072 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 11 Aug 2021 01:33:06 -0400 Subject: [PATCH 0147/1076] stake-pool: Address a few points post-liquid staking (#2252) --- clients/cli/src/main.rs | 111 +++++++--------------- program/src/instruction.rs | 126 ++----------------------- program/src/processor.rs | 20 ++-- program/src/state.rs | 3 +- program/tests/deposit_sol.rs | 18 ++-- program/tests/set_deposit_authority.rs | 22 +++-- program/tests/set_deposit_fee.rs | 34 ++++--- program/tests/set_fee.rs | 18 ++-- program/tests/set_referral_fee.rs | 33 ++++--- program/tests/set_withdrawal_fee.rs | 30 +++--- 10 files changed, 141 insertions(+), 274 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 41386b35..5d4c6e7c 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -37,7 +37,7 @@ use { spl_stake_pool::{ self, find_stake_program_address, find_transient_stake_program_address, find_withdraw_authority_program_address, - instruction::PreferredValidatorType, + instruction::{DepositType, PreferredValidatorType}, stake_program::{self, StakeState}, state::{Fee, FeeType, StakePool, ValidatorList}, }, @@ -1378,7 +1378,7 @@ fn command_set_deposit_authority( config: &Config, stake_pool_address: &Pubkey, new_sol_deposit_authority: Option, - for_stake_deposit: bool, + deposit_type: DepositType, ) -> CommandResult { let mut signers = vec![config.fee_payer.as_ref(), config.manager.as_ref()]; unique_signers!(signers); @@ -1389,7 +1389,7 @@ fn command_set_deposit_authority( stake_pool_address, &config.manager.pubkey(), new_sol_deposit_authority.as_ref(), - for_stake_deposit, + deposit_type, )], &signers, )?; @@ -2039,8 +2039,8 @@ fn main() { .help("Public key for the new stake pool staker."), ) ) - .subcommand(SubCommand::with_name("set-sol-deposit-authority") - .about("Change sol deposit authority account for the stake pool. Must be signed by the manager.") + .subcommand(SubCommand::with_name("set-deposit-authority") + .about("Change deposit authority account for the stake pool. Must be signed by the manager.") .arg( Arg::with_name("pool") .index(1) @@ -2051,39 +2051,17 @@ fn main() { .help("Stake pool address."), ) .arg( - Arg::with_name("new_sol_deposit_authority") + Arg::with_name("deposit_type") .index(2) - .validator(is_pubkey) - .value_name("ADDRESS") - .takes_value(true) - .help("The public key for the new stake pool sol deposit authority."), - ) - .arg( - Arg::with_name("unset") - .long("unset") - .takes_value(false) - .help("Unset the sol deposit authority.") - ) - .group(ArgGroup::with_name("validator") - .arg("new_sol_deposit_authority") - .arg("unset") - .required(true) - ) - ) - .subcommand(SubCommand::with_name("set-stake-deposit-authority") - .about("Change stake deposit authority account for the stake pool. Must be signed by the manager.") - .arg( - Arg::with_name("pool") - .index(1) - .validator(is_pubkey) - .value_name("POOL_ADDRESS") + .value_name("DEPOSIT_TYPE") + .possible_values(&["stake", "sol"]) // DepositType enum .takes_value(true) .required(true) - .help("Stake pool address."), + .help("Deposit type to be updated."), ) .arg( Arg::with_name("new_stake_deposit_authority") - .index(2) + .index(3) .validator(is_pubkey) .value_name("ADDRESS_OR_NONE") .takes_value(true) @@ -2115,7 +2093,7 @@ fn main() { .arg(Arg::with_name("fee_type") .index(2) .value_name("FEE_TYPE") - .possible_values(&["epoch", "stake-deposit", "sol-deposit", "withdrawal"]) // PreferredValidatorType enum + .possible_values(&["epoch", "stake-deposit", "sol-deposit", "withdrawal"]) // FeeType enum .takes_value(true) .required(true) .help("Fee type to be updated."), @@ -2139,7 +2117,7 @@ fn main() { .help("Fee denominator, fee amount is numerator divided by denominator."), ) ) - .subcommand(SubCommand::with_name("set-stake-referral-fee") + .subcommand(SubCommand::with_name("set-referral-fee") .about("Change the referral fee assessed by the stake pool for stake deposits. Must be signed by the manager.") .arg( Arg::with_name("pool") @@ -2150,29 +2128,17 @@ fn main() { .required(true) .help("Stake pool address."), ) - .arg( - Arg::with_name("fee") - .index(2) - .validator(is_valid_percentage) - .value_name("FEE_PERCENTAGE") - .takes_value(true) - .required(true) - .help("Fee percentage, maximum 100"), - ) - ).subcommand(SubCommand::with_name("set-sol-referral-fee") - .about("Change the referral fee assessed by the stake pool for SOL deposits. Must be signed by the manager.") - .arg( - Arg::with_name("pool") - .index(1) - .validator(is_pubkey) - .value_name("POOL_ADDRESS") - .takes_value(true) - .required(true) - .help("Stake pool address."), + .arg(Arg::with_name("fee_type") + .index(2) + .value_name("FEE_TYPE") + .possible_values(&["stake", "sol"]) // FeeType enum, kind of + .takes_value(true) + .required(true) + .help("Fee type to be updated."), ) .arg( Arg::with_name("fee") - .index(2) + .index(3) .validator(is_valid_percentage) .value_name("FEE_PERCENTAGE") .takes_value(true) @@ -2408,26 +2374,20 @@ fn main() { let new_staker = pubkey_of(arg_matches, "new_staker").unwrap(); command_set_staker(&config, &stake_pool_address, &new_staker) } - ("set-stake-deposit-authority", Some(arg_matches)) => { + ("set-deposit-authority", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); let new_stake_deposit_authority = pubkey_of(arg_matches, "new_stake_deposit_authority"); + let deposit_type = match arg_matches.value_of("deposit_type").unwrap() { + "sol" => DepositType::Sol, + "stake" => DepositType::Stake, + _ => unreachable!(), + }; let _unset = arg_matches.is_present("unset"); command_set_deposit_authority( &config, &stake_pool_address, new_stake_deposit_authority, - true, - ) - } - ("set-sol-deposit-authority", Some(arg_matches)) => { - let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); - let new_sol_deposit_authority = pubkey_of(arg_matches, "new_sol_deposit_authority"); - let _unset = arg_matches.is_present("unset"); - command_set_deposit_authority( - &config, - &stake_pool_address, - new_sol_deposit_authority, - false, + deposit_type, ) } ("set-fee", Some(arg_matches)) => { @@ -2452,21 +2412,18 @@ fn main() { _ => unreachable!(), } } - ("set-stake-referral-fee", Some(arg_matches)) => { + ("set-referral-fee", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); let fee = value_t_or_exit!(arg_matches, "fee", u8); if fee > 100u8 { panic!("Invalid fee {}%. Fee needs to be in range [0-100]", fee); } - command_set_fee(&config, &stake_pool_address, FeeType::StakeReferral(fee)) - } - ("set-sol-referral-fee", Some(arg_matches)) => { - let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); - let fee = value_t_or_exit!(arg_matches, "fee", u8); - if fee > 100u8 { - panic!("Invalid fee {}%. Fee needs to be in range [0-100]", fee); - } - command_set_fee(&config, &stake_pool_address, FeeType::SolReferral(fee)) + let fee_type = match arg_matches.value_of("fee_type").unwrap() { + "sol" => FeeType::SolReferral(fee), + "stake" => FeeType::StakeReferral(fee), + _ => unreachable!(), + }; + command_set_fee(&config, &stake_pool_address, fee_type) } _ => unreachable!(), } diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 0eecffa2..ecb89525 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -28,14 +28,14 @@ pub enum PreferredValidatorType { Withdraw, } -/// Defines which validator vote account is set during the -/// `SetPreferredValidator` instruction +/// Defines which deposit authority to update in the `SetDepositAuthority` +/// instruction #[repr(C)] #[derive(Clone, Debug, PartialEq, BorshSerialize, BorshDeserialize, BorshSchema)] pub enum DepositType { - /// Set preferred validator for deposits + /// Sets the stake deposit authority Stake, - /// Set preferred validator for withdraws + /// Sets the SOL deposit authority Sol, } @@ -1132,66 +1132,6 @@ pub fn set_fee( } } -/// Creates a 'set fee' instruction for setting the epoch fee -pub fn set_epoch_fee( - program_id: &Pubkey, - stake_pool: &Pubkey, - manager: &Pubkey, - fee: Fee, -) -> Instruction { - set_fee(program_id, stake_pool, manager, FeeType::Epoch(fee)) -} - -/// Creates a 'set fee' instruction for setting withdrawal fee -pub fn set_withdrawal_fee( - program_id: &Pubkey, - stake_pool: &Pubkey, - manager: &Pubkey, - fee: Fee, -) -> Instruction { - set_fee(program_id, stake_pool, manager, FeeType::Withdrawal(fee)) -} - -/// Creates a 'set fee' instruction for setting SOL deposit fee -pub fn set_sol_deposit_fee( - program_id: &Pubkey, - stake_pool: &Pubkey, - manager: &Pubkey, - fee: Fee, -) -> Instruction { - set_fee(program_id, stake_pool, manager, FeeType::SolDeposit(fee)) -} - -/// Creates a 'set fee' instruction for setting stake deposit fee -pub fn set_stake_deposit_fee( - program_id: &Pubkey, - stake_pool: &Pubkey, - manager: &Pubkey, - fee: Fee, -) -> Instruction { - set_fee(program_id, stake_pool, manager, FeeType::StakeDeposit(fee)) -} - -/// Creates a 'set fee' instruction for setting SOL referral fee -pub fn set_sol_referral_fee( - program_id: &Pubkey, - stake_pool: &Pubkey, - manager: &Pubkey, - fee: u8, -) -> Instruction { - set_fee(program_id, stake_pool, manager, FeeType::SolReferral(fee)) -} - -/// Creates a 'set fee' instruction for setting stake referral fee -pub fn set_stake_referral_fee( - program_id: &Pubkey, - stake_pool: &Pubkey, - manager: &Pubkey, - fee: u8, -) -> Instruction { - set_fee(program_id, stake_pool, manager, FeeType::StakeReferral(fee)) -} - /// Creates a 'set staker' instruction. pub fn set_staker( program_id: &Pubkey, @@ -1211,13 +1151,13 @@ pub fn set_staker( } } -/// Creates a 'set sol deposit authority' instruction. +/// Creates a 'set deposit authority' instruction. pub fn set_deposit_authority( program_id: &Pubkey, stake_pool: &Pubkey, manager: &Pubkey, new_sol_deposit_authority: Option<&Pubkey>, - for_stake_deposit: bool, + deposit_type: DepositType, ) -> Instruction { let mut accounts = vec![ AccountMeta::new(*stake_pool, false), @@ -1229,59 +1169,7 @@ pub fn set_deposit_authority( Instruction { program_id: *program_id, accounts, - data: if for_stake_deposit { - StakePoolInstruction::SetDepositAuthority(DepositType::Stake) - .try_to_vec() - .unwrap() - } else { - StakePoolInstruction::SetDepositAuthority(DepositType::Sol) - .try_to_vec() - .unwrap() - }, - } -} - -/// Creates a 'set stake deposit authority' instruction. -pub fn set_stake_deposit_authority( - program_id: &Pubkey, - stake_pool: &Pubkey, - manager: &Pubkey, - new_stake_deposit_authority: Option<&Pubkey>, -) -> Instruction { - let mut accounts = vec![ - AccountMeta::new(*stake_pool, false), - AccountMeta::new_readonly(*manager, true), - ]; - if let Some(auth) = new_stake_deposit_authority { - accounts.push(AccountMeta::new_readonly(*auth, false)) - } - Instruction { - program_id: *program_id, - accounts, - data: StakePoolInstruction::SetDepositAuthority(DepositType::Stake) - .try_to_vec() - .unwrap(), - } -} - -/// Creates a 'set stake deposit authority' instruction. -pub fn set_sol_deposit_authority( - program_id: &Pubkey, - stake_pool: &Pubkey, - manager: &Pubkey, - new_stake_deposit_authority: Option<&Pubkey>, -) -> Instruction { - let mut accounts = vec![ - AccountMeta::new(*stake_pool, false), - AccountMeta::new_readonly(*manager, true), - ]; - if let Some(auth) = new_stake_deposit_authority { - accounts.push(AccountMeta::new_readonly(*auth, false)) - } - Instruction { - program_id: *program_id, - accounts, - data: StakePoolInstruction::SetDepositAuthority(DepositType::Sol) + data: StakePoolInstruction::SetDepositAuthority(deposit_type) .try_to_vec() .unwrap(), } diff --git a/program/src/processor.rs b/program/src/processor.rs index 15cd4719..09073659 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1886,13 +1886,15 @@ impl Processor { .checked_sub(pool_tokens_referral_fee) .ok_or(StakePoolError::CalculationFailure)?; - if pool_tokens_user + pool_tokens_manager_deposit_fee + pool_tokens_referral_fee + if pool_tokens_user + .saturating_add(pool_tokens_manager_deposit_fee) + .saturating_add(pool_tokens_referral_fee) != new_pool_tokens { return Err(StakePoolError::CalculationFailure.into()); } - if new_pool_tokens == 0 { + if pool_tokens_user == 0 { return Err(StakePoolError::DepositTooSmall.into()); } @@ -1990,7 +1992,7 @@ impl Processor { let clock = &Clock::from_account_info(clock_info)?; let system_program_info = next_account_info(account_info_iter)?; let token_program_info = next_account_info(account_info_iter)?; - let sol_deposit_authority_info = next_account_info(account_info_iter).ok(); + let sol_deposit_authority_info = next_account_info(account_info_iter); check_account_owner(stake_pool_info, program_id)?; let mut stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; @@ -2005,9 +2007,7 @@ impl Processor { program_id, stake_pool_info.key, )?; - if let Some(sol_deposit_authority) = sol_deposit_authority_info { - stake_pool.check_sol_deposit_authority(sol_deposit_authority)?; - } + stake_pool.check_sol_deposit_authority(sol_deposit_authority_info)?; stake_pool.check_mint(pool_mint_info)?; stake_pool.check_reserve_stake(reserve_stake_account_info)?; @@ -2044,12 +2044,18 @@ impl Processor { .checked_sub(pool_tokens_referral_fee) .ok_or(StakePoolError::CalculationFailure)?; - if pool_tokens_user + pool_tokens_manager_deposit_fee + pool_tokens_referral_fee + if pool_tokens_user + .saturating_add(pool_tokens_manager_deposit_fee) + .saturating_add(pool_tokens_referral_fee) != new_pool_tokens { return Err(StakePoolError::CalculationFailure.into()); } + if pool_tokens_user == 0 { + return Err(StakePoolError::DepositTooSmall.into()); + } + Self::sol_transfer( from_user_lamports_info.clone(), reserve_stake_account_info.clone(), diff --git a/program/src/state.rs b/program/src/state.rs index 996c69bd..6271f2d8 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -295,9 +295,10 @@ impl StakePool { #[inline] pub(crate) fn check_sol_deposit_authority( &self, - sol_deposit_authority: &AccountInfo, + maybe_sol_deposit_authority: Result<&AccountInfo, ProgramError>, ) -> Result<(), ProgramError> { if let Some(auth) = self.sol_deposit_authority { + let sol_deposit_authority = maybe_sol_deposit_authority?; if auth != *sol_deposit_authority.key { return Err(StakePoolError::InvalidSolDepositAuthority.into()); } diff --git a/program/tests/deposit_sol.rs b/program/tests/deposit_sol.rs index f4c0bc65..edf4e141 100644 --- a/program/tests/deposit_sol.rs +++ b/program/tests/deposit_sol.rs @@ -14,7 +14,11 @@ use { transaction::TransactionError, transport::TransportError, }, - spl_stake_pool::{error, id, instruction, state}, + spl_stake_pool::{ + error, id, + instruction::{self, DepositType}, + state, + }, spl_token::error as token_error, }; @@ -48,17 +52,17 @@ async fn setup() -> (ProgramTestContext, StakePoolAccounts, Keypair, Pubkey) { .unwrap(); let mut transaction = Transaction::new_with_payer( &[ - instruction::set_sol_deposit_fee( + instruction::set_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - stake_pool_accounts.deposit_fee, + state::FeeType::SolDeposit(stake_pool_accounts.deposit_fee), ), - instruction::set_sol_referral_fee( + instruction::set_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - stake_pool_accounts.referral_fee, + state::FeeType::SolReferral(stake_pool_accounts.referral_fee), ), ], Some(&context.payer.pubkey()), @@ -318,7 +322,7 @@ async fn success_with_sol_deposit_authority() { &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), Some(&sol_deposit_authority.pubkey()), - false, + DepositType::Sol, )], Some(&payer.pubkey()), ); @@ -369,7 +373,7 @@ async fn fail_without_sol_deposit_authority_signature() { &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), Some(&sol_deposit_authority.pubkey()), - false, + DepositType::Sol, )], Some(&payer.pubkey()), ); diff --git a/program/tests/set_deposit_authority.rs b/program/tests/set_deposit_authority.rs index ddded681..61a098c6 100644 --- a/program/tests/set_deposit_authority.rs +++ b/program/tests/set_deposit_authority.rs @@ -15,7 +15,11 @@ use { instruction::InstructionError, signature::Keypair, signature::Signer, transaction::Transaction, transaction::TransactionError, transport::TransportError, }, - spl_stake_pool::{error, find_deposit_authority_program_address, id, instruction, state}, + spl_stake_pool::{ + error, find_deposit_authority_program_address, id, + instruction::{self, DepositType}, + state, + }, }; async fn setup() -> (BanksClient, Keypair, Hash, StakePoolAccounts, Keypair) { @@ -53,7 +57,7 @@ async fn success_set_stake_deposit_authority() { &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), Some(&new_stake_deposit_authority.pubkey()), - true, + DepositType::Stake, )], Some(&payer.pubkey()), ); @@ -86,7 +90,7 @@ async fn success_set_stake_deposit_authority_to_none() { &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), Some(&new_stake_deposit_authority.pubkey()), - true, + DepositType::Stake, )], Some(&payer.pubkey()), ); @@ -108,7 +112,7 @@ async fn success_set_stake_deposit_authority_to_none() { &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), None, - true, + DepositType::Stake, )], Some(&payer.pubkey()), ); @@ -141,7 +145,7 @@ async fn fail_stake_wrong_manager() { &stake_pool_accounts.stake_pool.pubkey(), &new_stake_deposit_authority.pubkey(), Some(&new_stake_deposit_authority.pubkey()), - true, + DepositType::Stake, )], Some(&payer.pubkey()), ); @@ -220,7 +224,7 @@ async fn success_set_sol_deposit_authority() { &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), Some(&new_sol_deposit_authority.pubkey()), - false, + DepositType::Sol, )], Some(&payer.pubkey()), ); @@ -248,7 +252,7 @@ async fn success_set_sol_deposit_authority_to_none() { &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), Some(&new_sol_deposit_authority.pubkey()), - false, + DepositType::Sol, )], Some(&payer.pubkey()), ); @@ -270,7 +274,7 @@ async fn success_set_sol_deposit_authority_to_none() { &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), None, - false, + DepositType::Sol, )], Some(&payer.pubkey()), ); @@ -295,7 +299,7 @@ async fn fail_sol_wrong_manager() { &stake_pool_accounts.stake_pool.pubkey(), &new_sol_deposit_authority.pubkey(), Some(&new_sol_deposit_authority.pubkey()), - false, + DepositType::Sol, )], Some(&payer.pubkey()), ); diff --git a/program/tests/set_deposit_fee.rs b/program/tests/set_deposit_fee.rs index f99f7cc9..37508341 100644 --- a/program/tests/set_deposit_fee.rs +++ b/program/tests/set_deposit_fee.rs @@ -11,7 +11,11 @@ use { signature::{Keypair, Signer}, transaction::{Transaction, TransactionError}, }, - spl_stake_pool::{error, id, instruction, state::Fee, state::StakePool}, + spl_stake_pool::{ + error, id, instruction, + state::StakePool, + state::{Fee, FeeType}, + }, }; async fn setup(fee: Option) -> (ProgramTestContext, StakePoolAccounts, Fee) { @@ -42,11 +46,11 @@ async fn success_stake() { let (mut context, stake_pool_accounts, new_deposit_fee) = setup(None).await; let transaction = Transaction::new_signed_with_payer( - &[instruction::set_stake_deposit_fee( + &[instruction::set_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - new_deposit_fee, + FeeType::StakeDeposit(new_deposit_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &stake_pool_accounts.manager], @@ -80,11 +84,11 @@ async fn success_stake_increase_fee_from_0() { }; let transaction = Transaction::new_signed_with_payer( - &[instruction::set_stake_deposit_fee( + &[instruction::set_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - new_deposit_fee, + FeeType::StakeDeposit(new_deposit_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &stake_pool_accounts.manager], @@ -111,11 +115,11 @@ async fn fail_stake_wrong_manager() { let wrong_manager = Keypair::new(); let transaction = Transaction::new_signed_with_payer( - &[instruction::set_stake_deposit_fee( + &[instruction::set_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &wrong_manager.pubkey(), - new_deposit_fee, + FeeType::StakeDeposit(new_deposit_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &wrong_manager], @@ -147,11 +151,11 @@ async fn fail_stake_high_deposit_fee() { denominator: 100000, }; let transaction = Transaction::new_signed_with_payer( - &[instruction::set_stake_deposit_fee( + &[instruction::set_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - new_deposit_fee, + FeeType::StakeDeposit(new_deposit_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &stake_pool_accounts.manager], @@ -179,11 +183,11 @@ async fn success_sol() { let (mut context, stake_pool_accounts, new_deposit_fee) = setup(None).await; let transaction = Transaction::new_signed_with_payer( - &[instruction::set_sol_deposit_fee( + &[instruction::set_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - new_deposit_fee, + FeeType::SolDeposit(new_deposit_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &stake_pool_accounts.manager], @@ -210,11 +214,11 @@ async fn fail_sol_wrong_manager() { let wrong_manager = Keypair::new(); let transaction = Transaction::new_signed_with_payer( - &[instruction::set_sol_deposit_fee( + &[instruction::set_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &wrong_manager.pubkey(), - new_deposit_fee, + FeeType::SolDeposit(new_deposit_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &wrong_manager], @@ -246,11 +250,11 @@ async fn fail_sol_high_deposit_fee() { denominator: 100000, }; let transaction = Transaction::new_signed_with_payer( - &[instruction::set_sol_deposit_fee( + &[instruction::set_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - new_deposit_fee, + FeeType::SolDeposit(new_deposit_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &stake_pool_accounts.manager], diff --git a/program/tests/set_fee.rs b/program/tests/set_fee.rs index 00585ad8..1dcbdcfe 100644 --- a/program/tests/set_fee.rs +++ b/program/tests/set_fee.rs @@ -13,7 +13,7 @@ use { }, spl_stake_pool::{ error, id, instruction, - state::{Fee, StakePool}, + state::{Fee, FeeType, StakePool}, }, }; @@ -50,11 +50,11 @@ async fn success() { let old_fee = stake_pool.fee; let transaction = Transaction::new_signed_with_payer( - &[instruction::set_epoch_fee( + &[instruction::set_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - new_fee, + FeeType::Epoch(new_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &stake_pool_accounts.manager], @@ -108,11 +108,11 @@ async fn fail_wrong_manager() { let wrong_manager = Keypair::new(); let transaction = Transaction::new_signed_with_payer( - &[instruction::set_epoch_fee( + &[instruction::set_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &wrong_manager.pubkey(), - new_fee, + FeeType::Epoch(new_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &wrong_manager], @@ -144,11 +144,11 @@ async fn fail_high_fee() { denominator: 10, }; let transaction = Transaction::new_signed_with_payer( - &[instruction::set_epoch_fee( + &[instruction::set_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - new_fee, + FeeType::Epoch(new_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &stake_pool_accounts.manager], @@ -193,11 +193,11 @@ async fn fail_not_updated() { context.warp_to_slot(50_000).unwrap(); let transaction = Transaction::new_signed_with_payer( - &[instruction::set_epoch_fee( + &[instruction::set_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - new_fee, + FeeType::Epoch(new_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &stake_pool_accounts.manager], diff --git a/program/tests/set_referral_fee.rs b/program/tests/set_referral_fee.rs index cda1a7b4..f9bb2d3e 100644 --- a/program/tests/set_referral_fee.rs +++ b/program/tests/set_referral_fee.rs @@ -11,7 +11,10 @@ use { signature::{Keypair, Signer}, transaction::{Transaction, TransactionError}, }, - spl_stake_pool::{error, id, instruction, state::StakePool}, + spl_stake_pool::{ + error, id, instruction, + state::{FeeType, StakePool}, + }, }; async fn setup(fee: Option) -> (ProgramTestContext, StakePoolAccounts, u8) { @@ -39,11 +42,11 @@ async fn success_stake() { let (mut context, stake_pool_accounts, new_referral_fee) = setup(None).await; let transaction = Transaction::new_signed_with_payer( - &[instruction::set_stake_referral_fee( + &[instruction::set_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - new_referral_fee, + FeeType::StakeReferral(new_referral_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &stake_pool_accounts.manager], @@ -70,11 +73,11 @@ async fn success_stake_increase_fee_from_0() { let new_referral_fee = 30u8; let transaction = Transaction::new_signed_with_payer( - &[instruction::set_stake_referral_fee( + &[instruction::set_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - new_referral_fee, + FeeType::StakeReferral(new_referral_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &stake_pool_accounts.manager], @@ -101,11 +104,11 @@ async fn fail_stake_wrong_manager() { let wrong_manager = Keypair::new(); let transaction = Transaction::new_signed_with_payer( - &[instruction::set_stake_referral_fee( + &[instruction::set_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &wrong_manager.pubkey(), - new_referral_fee, + FeeType::StakeReferral(new_referral_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &wrong_manager], @@ -134,11 +137,11 @@ async fn fail_stake_high_referral_fee() { let new_referral_fee = 110u8; let transaction = Transaction::new_signed_with_payer( - &[instruction::set_stake_referral_fee( + &[instruction::set_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - new_referral_fee, + FeeType::StakeReferral(new_referral_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &stake_pool_accounts.manager], @@ -166,11 +169,11 @@ async fn success_sol() { let (mut context, stake_pool_accounts, new_referral_fee) = setup(None).await; let transaction = Transaction::new_signed_with_payer( - &[instruction::set_sol_referral_fee( + &[instruction::set_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - new_referral_fee, + FeeType::SolReferral(new_referral_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &stake_pool_accounts.manager], @@ -197,11 +200,11 @@ async fn fail_sol_wrong_manager() { let wrong_manager = Keypair::new(); let transaction = Transaction::new_signed_with_payer( - &[instruction::set_sol_referral_fee( + &[instruction::set_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &wrong_manager.pubkey(), - new_referral_fee, + FeeType::SolReferral(new_referral_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &wrong_manager], @@ -230,11 +233,11 @@ async fn fail_sol_high_referral_fee() { let new_referral_fee = 110u8; let transaction = Transaction::new_signed_with_payer( - &[instruction::set_sol_referral_fee( + &[instruction::set_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - new_referral_fee, + FeeType::SolReferral(new_referral_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &stake_pool_accounts.manager], diff --git a/program/tests/set_withdrawal_fee.rs b/program/tests/set_withdrawal_fee.rs index 395f3f9d..9142028e 100644 --- a/program/tests/set_withdrawal_fee.rs +++ b/program/tests/set_withdrawal_fee.rs @@ -13,7 +13,7 @@ use { }, spl_stake_pool::{ error, id, instruction, - state::{Fee, StakePool}, + state::{Fee, FeeType, StakePool}, }, }; @@ -53,11 +53,11 @@ async fn success() { let old_withdrawal_fee = stake_pool.withdrawal_fee; let transaction = Transaction::new_signed_with_payer( - &[instruction::set_withdrawal_fee( + &[instruction::set_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - new_withdrawal_fee, + FeeType::Withdrawal(new_withdrawal_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &stake_pool_accounts.manager], @@ -126,11 +126,11 @@ async fn success_increase_fee_from_0() { let old_withdrawal_fee = stake_pool.withdrawal_fee; let transaction = Transaction::new_signed_with_payer( - &[instruction::set_withdrawal_fee( + &[instruction::set_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - new_withdrawal_fee, + FeeType::Withdrawal(new_withdrawal_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &stake_pool_accounts.manager], @@ -184,11 +184,11 @@ async fn fail_wrong_manager() { let wrong_manager = Keypair::new(); let transaction = Transaction::new_signed_with_payer( - &[instruction::set_withdrawal_fee( + &[instruction::set_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &wrong_manager.pubkey(), - new_withdrawal_fee, + FeeType::Withdrawal(new_withdrawal_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &wrong_manager], @@ -220,11 +220,11 @@ async fn fail_high_withdrawal_fee() { denominator: 10, }; let transaction = Transaction::new_signed_with_payer( - &[instruction::set_withdrawal_fee( + &[instruction::set_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - new_withdrawal_fee, + FeeType::Withdrawal(new_withdrawal_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &stake_pool_accounts.manager], @@ -255,11 +255,11 @@ async fn fail_high_withdrawal_fee_increase() { denominator: 10_000, }; let transaction = Transaction::new_signed_with_payer( - &[instruction::set_withdrawal_fee( + &[instruction::set_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - new_withdrawal_fee, + FeeType::Withdrawal(new_withdrawal_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &stake_pool_accounts.manager], @@ -294,11 +294,11 @@ async fn fail_high_withdrawal_fee_increase_from_0() { denominator: 10_000, }; let transaction = Transaction::new_signed_with_payer( - &[instruction::set_withdrawal_fee( + &[instruction::set_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - new_withdrawal_fee, + FeeType::Withdrawal(new_withdrawal_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &stake_pool_accounts.manager], @@ -343,11 +343,11 @@ async fn fail_not_updated() { context.warp_to_slot(50_000).unwrap(); let transaction = Transaction::new_signed_with_payer( - &[instruction::set_withdrawal_fee( + &[instruction::set_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - new_withdrawal_fee, + FeeType::Withdrawal(new_withdrawal_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &stake_pool_accounts.manager], From c113dbce742cc63d6bff7e052e33fc8e544f8dce Mon Sep 17 00:00:00 2001 From: jon-chuang <9093549+jon-chuang@users.noreply.github.com> Date: Sat, 14 Aug 2021 12:09:33 +0800 Subject: [PATCH 0148/1076] stake-pool: Update fee changes only once per epoch (#2269) * fix * test for withdrawal fee * merge conflict changes --- program/src/processor.rs | 18 +++-- program/tests/set_withdrawal_fee.rs | 111 ++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 8 deletions(-) diff --git a/program/src/processor.rs b/program/src/processor.rs index 09073659..1d87c739 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1651,16 +1651,18 @@ impl Processor { .ok_or(StakePoolError::CalculationFailure)?; } - if let Some(next_epoch_fee) = stake_pool.next_epoch_fee { - stake_pool.fee = next_epoch_fee; - stake_pool.next_epoch_fee = None; - } - if let Some(next_withdrawal_fee) = stake_pool.next_withdrawal_fee { - stake_pool.withdrawal_fee = next_withdrawal_fee; - stake_pool.next_withdrawal_fee = None; + if stake_pool.last_update_epoch < clock.epoch { + if let Some(next_epoch_fee) = stake_pool.next_epoch_fee { + stake_pool.fee = next_epoch_fee; + stake_pool.next_epoch_fee = None; + } + if let Some(next_withdrawal_fee) = stake_pool.next_withdrawal_fee { + stake_pool.withdrawal_fee = next_withdrawal_fee; + stake_pool.next_withdrawal_fee = None; + } + stake_pool.last_update_epoch = clock.epoch; } stake_pool.total_stake_lamports = total_stake_lamports; - stake_pool.last_update_epoch = clock.epoch; let pool_mint = Mint::unpack_from_slice(&pool_mint_info.data.borrow())?; stake_pool.pool_token_supply = pool_mint.supply; diff --git a/program/tests/set_withdrawal_fee.rs b/program/tests/set_withdrawal_fee.rs index 9142028e..bd2ec094 100644 --- a/program/tests/set_withdrawal_fee.rs +++ b/program/tests/set_withdrawal_fee.rs @@ -105,6 +105,117 @@ async fn success() { assert_eq!(stake_pool.next_withdrawal_fee, None); } +#[tokio::test] +async fn success_fee_cannot_increase_more_than_once() { + let (mut context, stake_pool_accounts, new_withdrawal_fee) = setup(None).await; + + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + let old_withdrawal_fee = stake_pool.withdrawal_fee; + + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + FeeType::Withdrawal(new_withdrawal_fee), + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + context + .banks_client + .process_transaction(transaction) + .await + .unwrap(); + + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + + assert_eq!(stake_pool.withdrawal_fee, old_withdrawal_fee); + assert_eq!(stake_pool.next_withdrawal_fee, Some(new_withdrawal_fee)); + + let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + + context + .warp_to_slot(first_normal_slot + slots_per_epoch) + .unwrap(); + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &[], + false, + ) + .await; + + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + assert_eq!(stake_pool.withdrawal_fee, new_withdrawal_fee); + assert_eq!(stake_pool.next_withdrawal_fee, None); + + // try setting to the old fee in the same epoch + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + FeeType::Withdrawal(old_withdrawal_fee), + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + context + .banks_client + .process_transaction(transaction) + .await + .unwrap(); + + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + assert_eq!(stake_pool.withdrawal_fee, new_withdrawal_fee); + assert_eq!(stake_pool.next_withdrawal_fee, Some(old_withdrawal_fee)); + + let error = stake_pool_accounts + .update_stake_pool_balance( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; + assert!(error.is_none()); + + // Check that nothing has changed after updating the stake pool + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + assert_eq!(stake_pool.withdrawal_fee, new_withdrawal_fee); + assert_eq!(stake_pool.next_withdrawal_fee, Some(old_withdrawal_fee)); +} + #[tokio::test] async fn success_increase_fee_from_0() { let (mut context, stake_pool_accounts, _) = setup(Some(Fee { From 861463ad84d9bf2363fca3d5bb146e316557ab26 Mon Sep 17 00:00:00 2001 From: Han Yang Date: Fri, 13 Aug 2021 21:16:43 -0700 Subject: [PATCH 0149/1076] fix: stake-pool require signature in SetManager (#2273) * add check for new_manager's signature in SetManager * cli arg edit --- clients/cli/src/main.rs | 23 ++++++++------ program/src/instruction.rs | 2 +- program/src/processor.rs | 6 +++- program/tests/set_manager.rs | 60 +++++++++++++++++++++++++++++++++--- 4 files changed, 74 insertions(+), 17 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 5d4c6e7c..061d5f20 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -1311,15 +1311,15 @@ fn command_withdraw( fn command_set_manager( config: &Config, stake_pool_address: &Pubkey, - new_manager: &Option, + new_manager: &Option, new_fee_receiver: &Option, ) -> CommandResult { let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; // If new accounts are missing in the arguments use the old ones - let new_manager = match new_manager { - None => stake_pool.manager, - Some(value) => *value, + let (new_manager_pubkey, mut signers): (Pubkey, Vec<&dyn Signer>) = match new_manager { + None => (stake_pool.manager, vec![]), + Some(value) => (value.pubkey(), vec![value]), }; let new_fee_receiver = match new_fee_receiver { None => stake_pool.manager_fee_account, @@ -1336,7 +1336,10 @@ fn command_set_manager( } }; - let mut signers = vec![config.fee_payer.as_ref(), config.manager.as_ref()]; + signers.append(&mut vec![ + config.fee_payer.as_ref(), + config.manager.as_ref(), + ]); unique_signers!(signers); let transaction = checked_transaction_with_signers( config, @@ -1344,7 +1347,7 @@ fn command_set_manager( &spl_stake_pool::id(), stake_pool_address, &config.manager.pubkey(), - &new_manager, + &new_manager_pubkey, &new_fee_receiver, )], &signers, @@ -1999,10 +2002,10 @@ fn main() { .arg( Arg::with_name("new_manager") .long("new-manager") - .validator(is_pubkey) - .value_name("ADDRESS") + .validator(is_keypair) + .value_name("KEYPAIR") .takes_value(true) - .help("Public key for the new stake pool manager."), + .help("Keypair for the new stake pool manager."), ) .arg( Arg::with_name("new_fee_receiver") @@ -2360,7 +2363,7 @@ fn main() { } ("set-manager", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); - let new_manager: Option = pubkey_of(arg_matches, "new_manager"); + let new_manager: Option = keypair_of(arg_matches, "new_manager"); let new_fee_receiver: Option = pubkey_of(arg_matches, "new_fee_receiver"); command_set_manager( &config, diff --git a/program/src/instruction.rs b/program/src/instruction.rs index ecb89525..a7633e9f 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -1103,7 +1103,7 @@ pub fn set_manager( let accounts = vec![ AccountMeta::new(*stake_pool, false), AccountMeta::new_readonly(*manager, true), - AccountMeta::new_readonly(*new_manager, false), + AccountMeta::new_readonly(*new_manager, true), AccountMeta::new_readonly(*new_fee_receiver, false), ]; Instruction { diff --git a/program/src/processor.rs b/program/src/processor.rs index 1d87c739..23fbd62d 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -2366,6 +2366,10 @@ impl Processor { } stake_pool.check_manager(manager_info)?; + if !new_manager_info.is_signer { + msg!("New manager signature missing"); + return Err(StakePoolError::SignatureMissing.into()); + } if stake_pool.pool_mint != spl_token::state::Account::unpack_from_slice(&new_manager_fee_info.data.borrow())? @@ -2412,7 +2416,7 @@ impl Processor { Ok(()) } - /// Processes [SetManager](enum.Instruction.html). + /// Processes [SetStaker](enum.Instruction.html). fn process_set_staker(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; diff --git a/program/tests/set_manager.rs b/program/tests/set_manager.rs index d50d2f5f..9909486a 100644 --- a/program/tests/set_manager.rs +++ b/program/tests/set_manager.rs @@ -71,7 +71,10 @@ async fn test_set_manager() { )], Some(&payer.pubkey()), ); - transaction.sign(&[&payer, &stake_pool_accounts.manager], recent_blockhash); + transaction.sign( + &[&payer, &stake_pool_accounts.manager, &new_manager], + recent_blockhash, + ); banks_client.process_transaction(transaction).await.unwrap(); let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; @@ -116,7 +119,7 @@ async fn test_set_manager_by_malicious() { } #[tokio::test] -async fn test_set_manager_without_signature() { +async fn test_set_manager_without_existing_signature() { let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_pool_fee, new_manager) = setup().await; @@ -126,6 +129,48 @@ async fn test_set_manager_without_signature() { let accounts = vec![ AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), AccountMeta::new_readonly(stake_pool_accounts.manager.pubkey(), false), + AccountMeta::new_readonly(new_manager.pubkey(), true), + AccountMeta::new_readonly(new_pool_fee.pubkey(), false), + ]; + let instruction = Instruction { + program_id: id(), + accounts, + data, + }; + + let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); + transaction.sign(&[&payer, &new_manager], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = error::StakePoolError::SignatureMissing as u32; + assert_eq!(error_index, program_error); + } + _ => panic!( + "Wrong error occurs while try to set new manager without existing manager signature" + ), + } +} + +#[tokio::test] +async fn test_set_manager_without_new_signature() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_pool_fee, new_manager) = + setup().await; + + let data = instruction::StakePoolInstruction::SetManager + .try_to_vec() + .unwrap(); + let accounts = vec![ + AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), + AccountMeta::new_readonly(stake_pool_accounts.manager.pubkey(), true), AccountMeta::new_readonly(new_manager.pubkey(), false), AccountMeta::new_readonly(new_pool_fee.pubkey(), false), ]; @@ -136,7 +181,7 @@ async fn test_set_manager_without_signature() { }; let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); - transaction.sign(&[&payer], recent_blockhash); + transaction.sign(&[&payer, &stake_pool_accounts.manager], recent_blockhash); let transaction_error = banks_client .process_transaction(transaction) .await @@ -151,7 +196,9 @@ async fn test_set_manager_without_signature() { let program_error = error::StakePoolError::SignatureMissing as u32; assert_eq!(error_index, program_error); } - _ => panic!("Wrong error occurs while try to set new manager without signature"), + _ => { + panic!("Wrong error occurs while try to set new manager without new manager signature") + } } } @@ -199,7 +246,10 @@ async fn test_set_manager_with_wrong_mint_for_pool_fee_acc() { )], Some(&payer.pubkey()), ); - transaction.sign(&[&payer, &stake_pool_accounts.manager], recent_blockhash); + transaction.sign( + &[&payer, &stake_pool_accounts.manager, &new_manager], + recent_blockhash, + ); let transaction_error = banks_client .process_transaction(transaction) .await From 7924d0a76126edb3e0858ddfde26e74fb518e3b5 Mon Sep 17 00:00:00 2001 From: jon-chuang <9093549+jon-chuang@users.noreply.github.com> Date: Sat, 14 Aug 2021 12:30:37 +0800 Subject: [PATCH 0150/1076] fix (#2278) --- program/src/processor.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/program/src/processor.rs b/program/src/processor.rs index 23fbd62d..d511d942 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -507,6 +507,11 @@ impl Processor { return Err(StakePoolError::SignatureMissing.into()); } + if stake_pool_info.key == validator_list_info.key { + msg!("Cannot use same account for stake pool and validator list"); + return Err(StakePoolError::AlreadyInUse.into()); + } + check_account_owner(stake_pool_info, program_id)?; let mut stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; if !stake_pool.is_uninitialized() { From 0c1d9e3b5e06daf9b8eff5095ad09c9a53e5e1a1 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Sat, 14 Aug 2021 01:15:50 -0400 Subject: [PATCH 0151/1076] stake-pool: Cleanup comments and rename functions (#2283) --- program/src/processor.rs | 4 ++-- program/src/state.rs | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/program/src/processor.rs b/program/src/processor.rs index d511d942..0cb7a475 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -2200,7 +2200,7 @@ impl Processor { let has_active_stake = validator_list .find::( &0u64.to_le_bytes(), - ValidatorStakeInfo::memcmp_active_lamports, + ValidatorStakeInfo::active_lamports_not_equal, ) .is_some(); @@ -2209,7 +2209,7 @@ impl Processor { let has_transient_stake = validator_list .find::( &0u64.to_le_bytes(), - ValidatorStakeInfo::memcmp_transient_lamports, + ValidatorStakeInfo::transient_lamports_not_equal, ) .is_some(); if has_transient_stake || has_active_stake { diff --git a/program/src/state.rs b/program/src/state.rs index 6271f2d8..96b5c853 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -310,7 +310,7 @@ impl StakePool { Ok(()) } - /// Check staker validity and signature + /// Check mint is correct #[inline] pub(crate) fn check_mint(&self, mint_info: &AccountInfo) -> Result<(), ProgramError> { if *mint_info.key != self.pool_mint { @@ -371,7 +371,7 @@ impl StakePool { } } - /// Check the validator list is valid + /// Check the reserve stake is valid pub fn check_reserve_stake( &self, reserve_stake_info: &AccountInfo, @@ -528,14 +528,14 @@ impl ValidatorStakeInfo { } /// Performs a very cheap comparison, for checking if this validator stake - /// info has active lamports equal to the given bytes - pub fn memcmp_active_lamports(data: &[u8], lamports_le_bytes: &[u8]) -> bool { + /// info does not have active lamports equal to the given bytes + pub fn active_lamports_not_equal(data: &[u8], lamports_le_bytes: &[u8]) -> bool { sol_memcmp(&data[0..8], lamports_le_bytes, 8) != 0 } /// Performs a very cheap comparison, for checking if this validator stake - /// info has lamports equal to the given bytes - pub fn memcmp_transient_lamports(data: &[u8], lamports_le_bytes: &[u8]) -> bool { + /// info does not have lamports equal to the given bytes + pub fn transient_lamports_not_equal(data: &[u8], lamports_le_bytes: &[u8]) -> bool { sol_memcmp(&data[8..16], lamports_le_bytes, 8) != 0 } From 2f9b2b11778bb4209e230e4def7df0e37b633a70 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Aug 2021 11:15:31 +0000 Subject: [PATCH 0152/1076] build(deps): bump num_enum from 0.5.3 to 0.5.4 (#2293) Bumps [num_enum](https://github.com/illicitonion/num_enum) from 0.5.3 to 0.5.4. - [Release notes](https://github.com/illicitonion/num_enum/releases) - [Commits](https://github.com/illicitonion/num_enum/compare/0.5.3...0.5.4) --- updated-dependencies: - dependency-name: num_enum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 70c29823..b32192f1 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -16,7 +16,7 @@ arrayref = "0.3.6" borsh = "0.9" num-derive = "0.3" num-traits = "0.2" -num_enum = "0.5.3" +num_enum = "0.5.4" serde = "1.0.127" serde_derive = "1.0.103" solana-program = "1.7.7" From 77c1a412926bd9ed37d20af25823b31ea4b9f5d4 Mon Sep 17 00:00:00 2001 From: Han Yang Date: Tue, 17 Aug 2021 13:02:02 -0700 Subject: [PATCH 0153/1076] fix stake-pool: preferred validator can be set to validator not part of the pool (#2272) * deny set preferred validator if validator is about to be removed, add tests * fix copy paste error * only allow Active validators to be set to preferred validator Co-authored-by: Jon Cinque Co-authored-by: Jon Cinque --- program/src/error.rs | 3 +++ program/src/processor.rs | 15 ++++++++--- program/tests/set_preferred.rs | 48 +++++++++++++++++++++++++++++++++- 3 files changed, 62 insertions(+), 4 deletions(-) diff --git a/program/src/error.rs b/program/src/error.rs index c526b4b1..bc471ec6 100644 --- a/program/src/error.rs +++ b/program/src/error.rs @@ -116,6 +116,9 @@ pub enum StakePoolError { /// Provided sol deposit authority does not match the program's #[error("InvalidSolDepositAuthority")] InvalidSolDepositAuthority, + /// Provided preferred validator is invalid + #[error("InvalidPreferredValidator")] + InvalidPreferredValidator, } impl From for ProgramError { fn from(e: StakePoolError) -> Self { diff --git a/program/src/processor.rs b/program/src/processor.rs index 0cb7a475..5dc28fa0 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1320,9 +1320,17 @@ impl Processor { vote_account_address.as_ref(), ValidatorStakeInfo::memcmp_pubkey, ); - if maybe_validator_stake_info.is_none() { - msg!("Validator for {} not present in the stake pool, cannot set as preferred deposit account"); - return Err(StakePoolError::ValidatorNotFound.into()); + match maybe_validator_stake_info { + Some(vsi) => { + if vsi.status != StakeStatus::Active { + msg!("Validator for {:?} about to be removed, cannot set as preferred deposit account", validator_type); + return Err(StakePoolError::InvalidPreferredValidator.into()); + } + } + None => { + msg!("Validator for {:?} not present in the stake pool, cannot set as preferred deposit account", validator_type); + return Err(StakePoolError::ValidatorNotFound.into()); + } } } @@ -2622,6 +2630,7 @@ impl PrintProgramError for StakePoolError { StakePoolError::DepositTooSmall => msg!("Error: Not enough lamports provided for deposit to result in one pool token"), StakePoolError::InvalidStakeDepositAuthority => msg!("Error: Provided stake deposit authority does not match the program's"), StakePoolError::InvalidSolDepositAuthority => msg!("Error: Provided sol deposit authority does not match the program's"), + StakePoolError::InvalidPreferredValidator => msg!("Error: Provided preferred validator is invalid"), } } } diff --git a/program/tests/set_preferred.rs b/program/tests/set_preferred.rs index 3400e9a0..05c3c481 100644 --- a/program/tests/set_preferred.rs +++ b/program/tests/set_preferred.rs @@ -14,7 +14,7 @@ use { transaction::{Transaction, TransactionError}, }, spl_stake_pool::{ - error, id, + error, find_transient_stake_program_address, id, instruction::{self, PreferredValidatorType}, state::StakePool, }, @@ -207,3 +207,49 @@ async fn fail_not_present_validator() { _ => panic!("Wrong error occurs while malicious try to set manager"), } } + +#[tokio::test] +async fn fail_ready_for_removal() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake_account) = + setup().await; + let validator_vote_address = validator_stake_account.vote.pubkey(); + + // Mark validator as ready for removal + let (transient_stake_address, _) = find_transient_stake_program_address( + &id(), + &validator_vote_address, + &stake_pool_accounts.stake_pool.pubkey(), + ); + let new_authority = Pubkey::new_unique(); + let remove_err = stake_pool_accounts + .remove_validator_from_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &new_authority, + &validator_stake_account.stake_account, + &transient_stake_address, + ) + .await; + assert!(remove_err.is_none()); + + let error = stake_pool_accounts + .set_preferred_validator( + &mut banks_client, + &payer, + &recent_blockhash, + PreferredValidatorType::Withdraw, + Some(validator_vote_address), + ) + .await + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = error::StakePoolError::InvalidPreferredValidator as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while trying to set ReadyForRemoval validator"), + } +} From e16b7355adda5a823d0cc6a047c8c9c3c5540806 Mon Sep 17 00:00:00 2001 From: jon-chuang <9093549+jon-chuang@users.noreply.github.com> Date: Wed, 18 Aug 2021 04:27:50 +0800 Subject: [PATCH 0154/1076] stake-pool: `DepositStake` only issues tokens for `delegation.stake` + `min(undelegated_stake_rent, additional_lamports)` (#2270) * charge fees for `sol_deposit_lamports` in `DepositStake` separately * do not add extra lamports beyond rent * change name: `additional_lamports` * fix: put `meta_exempt_reserve` limit on additional lamports instead * debugging tools * saturating_add * make rent quota conditional * eagerly update total_stake_lamports * fix tests to reflect increase in `total_staked_lamports` --- program/src/processor.rs | 27 ++++- program/tests/deposit.rs | 217 +++++++++++++++++++++++++++++++++++ program/tests/helpers/mod.rs | 63 +++++++++- program/tests/initialize.rs | 16 +++ 4 files changed, 316 insertions(+), 7 deletions(-) diff --git a/program/src/processor.rs b/program/src/processor.rs index 5dc28fa0..1ccb1a3a 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1822,6 +1822,16 @@ impl Processor { } } + let (meta, stake) = get_stake_state(stake_info)?; + + // If the stake account is mergeable (full-activated), `meta.rent_exempt_reserve` + // will not be merged into `stake.delegation.stake` + let unactivated_stake_rent = if stake.delegation.activation_epoch < clock.epoch { + meta.rent_exempt_reserve + } else { + 0 + }; + let mut validator_stake_info = validator_list .find_mut::( vote_account_address.as_ref(), @@ -1874,6 +1884,7 @@ impl Processor { let (_, post_validator_stake) = get_stake_state(validator_stake_account_info)?; let post_all_validator_lamports = validator_stake_account_info.lamports(); msg!("Stake post merge {}", post_validator_stake.delegation.stake); + let all_deposit_lamports = post_all_validator_lamports .checked_sub(pre_all_validator_lamports) .ok_or(StakePoolError::CalculationFailure)?; @@ -1882,14 +1893,21 @@ impl Processor { .stake .checked_sub(validator_stake.delegation.stake) .ok_or(StakePoolError::CalculationFailure)?; + let additional_lamports = all_deposit_lamports + .checked_sub(stake_deposit_lamports) + .ok_or(StakePoolError::CalculationFailure)?; + let credited_additional_lamports = additional_lamports.min(unactivated_stake_rent); + let credited_deposit_lamports = + stake_deposit_lamports.saturating_add(credited_additional_lamports); let new_pool_tokens = stake_pool - .calc_pool_tokens_for_deposit(all_deposit_lamports) + .calc_pool_tokens_for_deposit(credited_deposit_lamports) .ok_or(StakePoolError::CalculationFailure)?; let pool_tokens_stake_deposit_fee = stake_pool .calc_pool_tokens_stake_deposit_fee(new_pool_tokens) .ok_or(StakePoolError::CalculationFailure)?; + let pool_tokens_user = new_pool_tokens .checked_sub(pool_tokens_stake_deposit_fee) .ok_or(StakePoolError::CalculationFailure)?; @@ -1897,6 +1915,7 @@ impl Processor { let pool_tokens_referral_fee = stake_pool .calc_pool_tokens_stake_referral_fee(pool_tokens_stake_deposit_fee) .ok_or(StakePoolError::CalculationFailure)?; + let pool_tokens_manager_deposit_fee = pool_tokens_stake_deposit_fee .checked_sub(pool_tokens_referral_fee) .ok_or(StakePoolError::CalculationFailure)?; @@ -1951,9 +1970,7 @@ impl Processor { } // withdraw additional lamports to the reserve - let additional_lamports = all_deposit_lamports - .checked_sub(stake_deposit_lamports) - .ok_or(StakePoolError::CalculationFailure)?; + if additional_lamports > 0 { Self::stake_withdraw( stake_pool_info.key, @@ -1973,6 +1990,8 @@ impl Processor { .pool_token_supply .checked_add(new_pool_tokens) .ok_or(StakePoolError::CalculationFailure)?; + // We treat the extra lamports as though they were + // transferred directly to the reserve stake account. stake_pool.total_stake_lamports = stake_pool .total_stake_lamports .checked_add(all_deposit_lamports) diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 03f1eb01..6dd07b51 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -257,6 +257,204 @@ async fn success() { assert_eq!(post_reserve_lamports, pre_reserve_lamports + stake_rent); } +#[tokio::test] +async fn success_with_extra_stake_lamports() { + let ( + mut context, + stake_pool_accounts, + validator_stake_account, + user, + deposit_stake, + pool_token_account, + stake_lamports, + ) = setup().await; + + let extra_lamports = TEST_STAKE_AMOUNT * 3 + 1; + + transfer( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &deposit_stake, + extra_lamports, + ) + .await; + + let referrer = Keypair::new(); + let referrer_token_account = Keypair::new(); + create_token_account( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &referrer_token_account, + &stake_pool_accounts.pool_mint.pubkey(), + &referrer.pubkey(), + ) + .await + .unwrap(); + + let referrer_balance_pre = + get_token_balance(&mut context.banks_client, &referrer_token_account.pubkey()).await; + + let manager_pool_balance_pre = get_token_balance( + &mut context.banks_client, + &stake_pool_accounts.pool_fee_account.pubkey(), + ) + .await; + + let rent = context.banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + + // Save stake pool state before depositing + let pre_stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let pre_stake_pool = + try_from_slice_unchecked::(&pre_stake_pool.data.as_slice()).unwrap(); + + // Save validator stake account record before depositing + let validator_list = get_account( + &mut context.banks_client, + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + let validator_list = + try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); + let pre_validator_stake_item = validator_list + .find(&validator_stake_account.vote.pubkey()) + .unwrap(); + + // Save reserve state before depositing + let pre_reserve_lamports = get_account( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + ) + .await + .lamports; + + let error = stake_pool_accounts + .deposit_stake_with_referral( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &deposit_stake, + &pool_token_account, + &validator_stake_account.stake_account, + &user, + &referrer_token_account.pubkey(), + ) + .await; + assert!(error.is_none()); + + // Original stake account should be drained + assert!(context + .banks_client + .get_account(deposit_stake) + .await + .expect("get_account") + .is_none()); + + let tokens_issued = stake_lamports; + // For now tokens are 1:1 to stake + + // Stake pool should add its balance to the pool balance + + // The extra lamports will not get recorded in total stake lamports unless + // update_stake_pool_balance is called + let post_stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + + let post_stake_pool = + try_from_slice_unchecked::(&post_stake_pool.data.as_slice()).unwrap(); + assert_eq!( + post_stake_pool.total_stake_lamports, + pre_stake_pool.total_stake_lamports + extra_lamports + stake_lamports + ); + assert_eq!( + post_stake_pool.pool_token_supply, + pre_stake_pool.pool_token_supply + tokens_issued + ); + + // Check minted tokens + let user_token_balance = + get_token_balance(&mut context.banks_client, &pool_token_account).await; + + let tokens_issued_user = + tokens_issued - stake_pool_accounts.calculate_deposit_fee(tokens_issued); + assert_eq!(user_token_balance, tokens_issued_user); + + let referrer_balance_post = + get_token_balance(&mut context.banks_client, &referrer_token_account.pubkey()).await; + + let tokens_issued_fees = stake_pool_accounts.calculate_deposit_fee(tokens_issued); + let tokens_issued_referral_fee = stake_pool_accounts + .calculate_referral_fee(stake_pool_accounts.calculate_deposit_fee(tokens_issued)); + let tokens_issued_manager_fee = tokens_issued_fees - tokens_issued_referral_fee; + + assert_eq!( + referrer_balance_post - referrer_balance_pre, + tokens_issued_referral_fee + ); + + let manager_pool_balance_post = get_token_balance( + &mut context.banks_client, + &stake_pool_accounts.pool_fee_account.pubkey(), + ) + .await; + assert_eq!( + manager_pool_balance_post - manager_pool_balance_pre, + tokens_issued_manager_fee + ); + + // Check balances in validator stake account list storage + let validator_list = get_account( + &mut context.banks_client, + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + let validator_list = + try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); + let post_validator_stake_item = validator_list + .find(&validator_stake_account.vote.pubkey()) + .unwrap(); + assert_eq!( + post_validator_stake_item.stake_lamports(), + pre_validator_stake_item.stake_lamports() + stake_lamports - stake_rent, + ); + + // Check validator stake account actual SOL balance + let validator_stake_account = get_account( + &mut context.banks_client, + &validator_stake_account.stake_account, + ) + .await; + let stake_state = + deserialize::(&validator_stake_account.data).unwrap(); + let meta = stake_state.meta().unwrap(); + assert_eq!( + validator_stake_account.lamports - minimum_stake_lamports(&meta), + post_validator_stake_item.stake_lamports() + ); + assert_eq!(post_validator_stake_item.transient_stake_lamports, 0); + + // Check reserve + let post_reserve_lamports = get_account( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + ) + .await + .lamports; + assert_eq!( + post_reserve_lamports, + pre_reserve_lamports + stake_rent + extra_lamports + ); +} + #[tokio::test] async fn fail_with_wrong_stake_program_id() { let ( @@ -284,6 +482,7 @@ async fn fail_with_wrong_stake_program_id() { AccountMeta::new(stake_pool_accounts.pool_fee_account.pubkey(), false), AccountMeta::new(stake_pool_accounts.pool_mint.pubkey(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(sysvar::rent::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), AccountMeta::new_readonly(spl_token::id(), false), AccountMeta::new_readonly(wrong_stake_program, false), @@ -453,6 +652,24 @@ async fn fail_with_unknown_validator() { TEST_STAKE_AMOUNT, ) .await; + let random_vote_account = Keypair::new(); + create_vote( + &mut banks_client, + &payer, + &recent_blockhash, + &Keypair::new(), + &random_vote_account, + ) + .await; + delegate_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.pubkey(), + &user, + &random_vote_account.pubkey(), + ) + .await; let transaction_error = stake_pool_accounts .deposit_stake( diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index b1899334..e95ae5c4 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -21,7 +21,7 @@ use { }, spl_stake_pool::{ find_stake_program_address, find_transient_stake_program_address, id, instruction, - processor, stake_program, state, + processor, stake_program, state, state::FeeType, }, }; @@ -271,6 +271,8 @@ pub async fn create_stake_pool( withdrawal_fee: &state::Fee, deposit_fee: &state::Fee, referral_fee: u8, + sol_deposit_fee: &state::Fee, + sol_referral_fee: u8, max_validators: u32, ) -> Result<(), TransportError> { let rent = banks_client.get_rent().await.unwrap(); @@ -312,6 +314,18 @@ pub async fn create_stake_pool( referral_fee, max_validators, ), + instruction::set_fee( + &id(), + &stake_pool.pubkey(), + &manager.pubkey(), + FeeType::SolDeposit(*sol_deposit_fee), + ), + instruction::set_fee( + &id(), + &stake_pool.pubkey(), + &manager.pubkey(), + FeeType::SolReferral(sol_referral_fee), + ), ], Some(&payer.pubkey()), ); @@ -552,6 +566,8 @@ pub struct StakePoolAccounts { pub withdrawal_fee: state::Fee, pub deposit_fee: state::Fee, pub referral_fee: u8, + pub sol_deposit_fee: state::Fee, + pub sol_referral_fee: u8, pub max_validators: u32, } @@ -598,6 +614,11 @@ impl StakePoolAccounts { denominator: 1000, }, referral_fee: 25, + sol_deposit_fee: state::Fee { + numerator: 3, + denominator: 100, + }, + sol_referral_fee: 50, max_validators: MAX_TEST_VALIDATORS, } } @@ -625,6 +646,14 @@ impl StakePoolAccounts { deposit_fee_collected * self.referral_fee as u64 / 100 } + pub fn calculate_sol_deposit_fee(&self, pool_tokens: u64) -> u64 { + pool_tokens * self.sol_deposit_fee.numerator / self.sol_deposit_fee.denominator + } + + pub fn calculate_sol_referral_fee(&self, deposit_fee_collected: u64) -> u64 { + deposit_fee_collected * self.sol_referral_fee as u64 / 100 + } + pub async fn initialize_stake_pool( &self, mut banks_client: &mut BanksClient, @@ -678,9 +707,12 @@ impl StakePoolAccounts { &self.withdrawal_fee, &self.deposit_fee, self.referral_fee, + &self.sol_deposit_fee, + self.sol_referral_fee, self.max_validators, ) .await?; + Ok(()) } @@ -694,6 +726,31 @@ impl StakePoolAccounts { pool_account: &Pubkey, validator_stake_account: &Pubkey, current_staker: &Keypair, + ) -> Option { + self.deposit_stake_with_referral( + banks_client, + payer, + recent_blockhash, + stake, + pool_account, + validator_stake_account, + current_staker, + &self.pool_fee_account.pubkey(), + ) + .await + } + + #[allow(clippy::too_many_arguments)] + pub async fn deposit_stake_with_referral( + &self, + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + stake: &Pubkey, + pool_account: &Pubkey, + validator_stake_account: &Pubkey, + current_staker: &Keypair, + referrer: &Pubkey, ) -> Option { let mut signers = vec![payer, current_staker]; let instructions = @@ -711,7 +768,7 @@ impl StakePoolAccounts { &self.reserve_stake.pubkey(), pool_account, &self.pool_fee_account.pubkey(), - &self.pool_fee_account.pubkey(), + referrer, &self.pool_mint.pubkey(), &spl_token::id(), ) @@ -727,7 +784,7 @@ impl StakePoolAccounts { &self.reserve_stake.pubkey(), pool_account, &self.pool_fee_account.pubkey(), - &self.pool_fee_account.pubkey(), + &referrer, &self.pool_mint.pubkey(), &spl_token::id(), ) diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index 6d028c27..652d2274 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -329,6 +329,8 @@ async fn fail_with_wrong_mint_authority() { &stake_pool_accounts.withdrawal_fee, &stake_pool_accounts.deposit_fee, stake_pool_accounts.referral_fee, + &stake_pool_accounts.sol_deposit_fee, + stake_pool_accounts.sol_referral_fee, stake_pool_accounts.max_validators, ) .await @@ -417,6 +419,8 @@ async fn fail_with_freeze_authority() { &stake_pool_accounts.withdrawal_fee, &stake_pool_accounts.deposit_fee, stake_pool_accounts.referral_fee, + &stake_pool_accounts.sol_deposit_fee, + stake_pool_accounts.sol_referral_fee, stake_pool_accounts.max_validators, ) .await @@ -586,6 +590,8 @@ async fn fail_with_wrong_fee_account() { &stake_pool_accounts.withdrawal_fee, &stake_pool_accounts.deposit_fee, stake_pool_accounts.referral_fee, + &stake_pool_accounts.sol_deposit_fee, + stake_pool_accounts.sol_referral_fee, stake_pool_accounts.max_validators, ) .await @@ -932,6 +938,8 @@ async fn fail_with_pre_minted_pool_tokens() { &stake_pool_accounts.withdrawal_fee, &stake_pool_accounts.deposit_fee, stake_pool_accounts.referral_fee, + &stake_pool_accounts.sol_deposit_fee, + stake_pool_accounts.sol_referral_fee, stake_pool_accounts.max_validators, ) .await @@ -996,6 +1004,8 @@ async fn fail_with_bad_reserve() { &stake_pool_accounts.withdrawal_fee, &stake_pool_accounts.deposit_fee, stake_pool_accounts.referral_fee, + &stake_pool_accounts.sol_deposit_fee, + stake_pool_accounts.sol_referral_fee, stake_pool_accounts.max_validators, ) .await @@ -1044,6 +1054,8 @@ async fn fail_with_bad_reserve() { &stake_pool_accounts.withdrawal_fee, &stake_pool_accounts.deposit_fee, stake_pool_accounts.referral_fee, + &stake_pool_accounts.sol_deposit_fee, + stake_pool_accounts.sol_referral_fee, stake_pool_accounts.max_validators, ) .await @@ -1095,6 +1107,8 @@ async fn fail_with_bad_reserve() { &stake_pool_accounts.withdrawal_fee, &stake_pool_accounts.deposit_fee, stake_pool_accounts.referral_fee, + &stake_pool_accounts.sol_deposit_fee, + stake_pool_accounts.sol_referral_fee, stake_pool_accounts.max_validators, ) .await @@ -1146,6 +1160,8 @@ async fn fail_with_bad_reserve() { &stake_pool_accounts.withdrawal_fee, &stake_pool_accounts.deposit_fee, stake_pool_accounts.referral_fee, + &stake_pool_accounts.sol_deposit_fee, + stake_pool_accounts.sol_referral_fee, stake_pool_accounts.max_validators, ) .await From ec903c14b63a704e14a567b5d3e33a7613d7b2a2 Mon Sep 17 00:00:00 2001 From: jon-chuang <9093549+jon-chuang@users.noreply.github.com> Date: Wed, 18 Aug 2021 04:32:47 +0800 Subject: [PATCH 0155/1076] stake-pool: skip manager fee if invalid account, check new manager fee owned by `spl_token` (#2277) * fix * add check if new manager fee is spl token program * Convert manager fee info check to fail only inside `Result` box * update also checks validity of manager fee info * clippy --- program/src/processor.rs | 19 +++++-- program/src/state.rs | 18 +++++++ program/tests/helpers/mod.rs | 48 ++++++++++++++++++ program/tests/withdraw.rs | 97 ++++++++++++++++++++++++++++++++---- 4 files changed, 167 insertions(+), 15 deletions(-) diff --git a/program/src/processor.rs b/program/src/processor.rs index 1ccb1a3a..e4186f12 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1642,9 +1642,15 @@ impl Processor { } let reward_lamports = total_stake_lamports.saturating_sub(previous_lamports); - let fee = stake_pool - .calc_epoch_fee_amount(reward_lamports) - .ok_or(StakePoolError::CalculationFailure)?; + + // If the manager fee info is invalid, they don't deserve to receive the fee. + let fee = if stake_pool.check_manager_fee_info(manager_fee_info).is_ok() { + stake_pool + .calc_epoch_fee_amount(reward_lamports) + .ok_or(StakePoolError::CalculationFailure)? + } else { + 0 + }; if fee > 0 { Self::token_mint_to( @@ -2205,7 +2211,11 @@ impl Processor { return Err(StakePoolError::InvalidState.into()); } - let pool_tokens_fee = if stake_pool.manager_fee_account == *burn_from_pool_info.key { + // To prevent a faulty manager fee account from preventing withdrawals + // if the token program does not own the account, or if the account is not initialized + let pool_tokens_fee = if stake_pool.manager_fee_account == *burn_from_pool_info.key + || stake_pool.check_manager_fee_info(manager_fee_info).is_err() + { 0 } else { stake_pool @@ -2393,6 +2403,7 @@ impl Processor { check_account_owner(stake_pool_info, program_id)?; let mut stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; + check_account_owner(new_manager_fee_info, &stake_pool.token_program_id)?; if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); } diff --git a/program/src/state.rs b/program/src/state.rs index 96b5c853..e7ec27b8 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -1,5 +1,6 @@ //! State transition types +use spl_token::state::{Account, AccountState}; use { crate::{ big_vec::BigVec, error::StakePoolError, stake_program::Lockup, MAX_WITHDRAWAL_FEE_INCREASE, @@ -261,6 +262,23 @@ impl StakePool { } } + /// Check if the manager fee info is a valid token program account + /// capable of receiving tokens from the mint. + pub(crate) fn check_manager_fee_info( + &self, + manager_fee_info: &AccountInfo, + ) -> Result<(), ProgramError> { + let token_account = Account::unpack(&manager_fee_info.data.borrow())?; + if manager_fee_info.owner != &self.token_program_id + || token_account.state != AccountState::Initialized + || token_account.mint != self.pool_mint + { + msg!("Manager fee account is not owned by token program, is not initialized, or does not match stake pool's mint"); + return Err(StakePoolError::InvalidFeeAccount.into()); + } + Ok(()) + } + /// Checks that the withdraw authority is valid #[inline] pub(crate) fn check_authority_withdraw( diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index e95ae5c4..c39bbd07 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -160,6 +160,54 @@ pub async fn create_token_account( Ok(()) } +pub async fn close_token_account( + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + account: &Pubkey, + lamports_destination: &Pubkey, + manager: &Keypair, +) -> Result<(), TransportError> { + let mut transaction = Transaction::new_with_payer( + &[spl_token::instruction::close_account( + &spl_token::id(), + &account, + &lamports_destination, + &manager.pubkey(), + &[], + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[payer, manager], *recent_blockhash); + banks_client.process_transaction(transaction).await?; + Ok(()) +} + +pub async fn freeze_token_account( + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + account: &Pubkey, + pool_mint: &Pubkey, + manager: &Keypair, +) -> Result<(), TransportError> { + let mut transaction = Transaction::new_with_payer( + &[spl_token::instruction::freeze_account( + &spl_token::id(), + &account, + pool_mint, + &manager.pubkey(), + &[], + ) + .unwrap()], + Some(&payer.pubkey()), + ); + transaction.sign(&[payer, manager], *recent_blockhash); + banks_client.process_transaction(transaction).await?; + Ok(()) +} + pub async fn mint_tokens( banks_client: &mut BanksClient, payer: &Keypair, diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 1af022bf..db34fe55 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -102,6 +102,20 @@ async fn setup() -> ( #[tokio::test] async fn success() { + _success(SuccessTestType::Success).await; +} + +#[tokio::test] +async fn success_with_closed_manager_fee_account() { + _success(SuccessTestType::UninitializedManagerFee).await; +} + +enum SuccessTestType { + Success, + UninitializedManagerFee, +} + +async fn _success(test_type: SuccessTestType) { let ( mut banks_client, payer, @@ -148,6 +162,60 @@ async fn success() { ) .await; + let destination_keypair = Keypair::new(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &destination_keypair, + &stake_pool_accounts.pool_mint.pubkey(), + &Keypair::new().pubkey(), + ) + .await + .unwrap(); + + if let SuccessTestType::UninitializedManagerFee = test_type { + transfer_spl_tokens( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.pool_fee_account.pubkey(), + &destination_keypair.pubkey(), + &stake_pool_accounts.manager, + pool_fee_balance_before, + ) + .await; + // Check that the account cannot be frozen due to lack of + // freeze authority. + let transaction_error = freeze_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.pool_fee_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &stake_pool_accounts.manager, + ) + .await + .unwrap_err(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { + assert_eq!(error, InstructionError::Custom(0x10)); + } + _ => panic!("Wrong error occurs while try to withdraw with wrong stake program ID"), + } + close_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.pool_fee_account.pubkey(), + &destination_keypair.pubkey(), + &stake_pool_accounts.manager, + ) + .await + .unwrap(); + } + let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts .withdraw_stake( @@ -169,7 +237,12 @@ async fn success() { let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); // first and only deposit, lamports:pool 1:1 - let tokens_withdrawal_fee = stake_pool_accounts.calculate_withdrawal_fee(tokens_to_withdraw); + let tokens_withdrawal_fee = match test_type { + SuccessTestType::Success => { + stake_pool_accounts.calculate_withdrawal_fee(tokens_to_withdraw) + } + _ => 0, + }; let tokens_burnt = tokens_to_withdraw - tokens_withdrawal_fee; assert_eq!( stake_pool.total_stake_lamports, @@ -180,16 +253,18 @@ async fn success() { stake_pool_before.pool_token_supply - tokens_burnt ); - // Check manager received withdrawal fee - let pool_fee_balance = get_token_balance( - &mut banks_client, - &stake_pool_accounts.pool_fee_account.pubkey(), - ) - .await; - assert_eq!( - pool_fee_balance, - pool_fee_balance_before + tokens_withdrawal_fee, - ); + if let SuccessTestType::Success = test_type { + // Check manager received withdrawal fee + let pool_fee_balance = get_token_balance( + &mut banks_client, + &stake_pool_accounts.pool_fee_account.pubkey(), + ) + .await; + assert_eq!( + pool_fee_balance, + pool_fee_balance_before + tokens_withdrawal_fee, + ); + } // Check validator stake list storage let validator_list = get_account( From ffdd2c359701ad1b3cf5a6472bf1e682b2133964 Mon Sep 17 00:00:00 2001 From: jon-chuang <9093549+jon-chuang@users.noreply.github.com> Date: Wed, 18 Aug 2021 04:36:32 +0800 Subject: [PATCH 0156/1076] Use stake pool's declared token ID rather than hard-coded (#2286) * fix * tests use hard-coded `&spl_token::id()` - fine since we need a baseline * use spl_token::id --- program/src/instruction.rs | 4 +++- program/tests/helpers/mod.rs | 2 ++ program/tests/huge_pool.rs | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/program/src/instruction.rs b/program/src/instruction.rs index a7633e9f..59aab84b 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -768,6 +768,7 @@ pub fn update_stake_pool_balance( reserve_stake: &Pubkey, manager_fee_account: &Pubkey, stake_pool_mint: &Pubkey, + token_program_id: &Pubkey, ) -> Instruction { let accounts = vec![ AccountMeta::new(*stake_pool, false), @@ -777,7 +778,7 @@ pub fn update_stake_pool_balance( AccountMeta::new(*manager_fee_account, false), AccountMeta::new(*stake_pool_mint, false), AccountMeta::new_readonly(sysvar::clock::id(), false), - AccountMeta::new_readonly(spl_token::id(), false), + AccountMeta::new_readonly(*token_program_id, false), ]; Instruction { program_id: *program_id, @@ -850,6 +851,7 @@ pub fn update_stake_pool( &stake_pool.reserve_stake, &stake_pool.manager_fee_account, &stake_pool.pool_mint, + &stake_pool.token_program_id, ), cleanup_removed_validator_entries( program_id, diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index c39bbd07..f64e852e 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -974,6 +974,7 @@ impl StakePoolAccounts { &self.reserve_stake.pubkey(), &self.pool_fee_account.pubkey(), &self.pool_mint.pubkey(), + &spl_token::id(), )], Some(&payer.pubkey()), &[payer], @@ -1029,6 +1030,7 @@ impl StakePoolAccounts { &self.reserve_stake.pubkey(), &self.pool_fee_account.pubkey(), &self.pool_mint.pubkey(), + &spl_token::id(), ), instruction::cleanup_removed_validator_entries( &id(), diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index baa5b1d1..38c0ded0 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -350,6 +350,7 @@ async fn update() { &stake_pool_accounts.reserve_stake.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), + &spl_token::id(), )], Some(&context.payer.pubkey()), &[&context.payer], From 62b7f20ebe1ea13cf48dfe31aa73cc3d8fd45668 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 18 Aug 2021 00:59:11 -0400 Subject: [PATCH 0157/1076] stake-pool-cli: Add `list-all` instruction (#2296) * stake-pool-cli: Add "list-all" command to see all pools * Cleanup output for withdraw --- clients/cli/src/client.rs | 39 +++++++++++++++++++++++++++++++++ clients/cli/src/main.rs | 45 ++++++++++++++++++++++++++++++++------- 2 files changed, 76 insertions(+), 8 deletions(-) diff --git a/clients/cli/src/client.rs b/clients/cli/src/client.rs index 229807ce..7f58d581 100644 --- a/clients/cli/src/client.rs +++ b/clients/cli/src/client.rs @@ -113,3 +113,42 @@ pub(crate) fn get_stake_accounts_by_withdraw_authority( .collect() }) } + +pub(crate) fn get_stake_pools( + rpc_client: &RpcClient, +) -> Result, ClientError> { + rpc_client + .get_program_accounts_with_config( + &spl_stake_pool::id(), + RpcProgramAccountsConfig { + filters: Some(vec![RpcFilterType::Memcmp(Memcmp { + offset: 0, // 0 is the account type + bytes: MemcmpEncodedBytes::Binary("2".to_string()), + encoding: None, + })]), + account_config: RpcAccountInfoConfig { + encoding: Some(UiAccountEncoding::Base64), + ..RpcAccountInfoConfig::default() + }, + ..RpcProgramAccountsConfig::default() + }, + ) + .map(|accounts| { + accounts + .into_iter() + .filter_map(|(address, account)| { + match try_from_slice_unchecked::(account.data.as_slice()) { + Ok(stake_pool) => { + get_validator_list(rpc_client, &stake_pool.validator_list) + .map(|v| (address, stake_pool, v)) + .ok() + } + Err(err) => { + eprintln!("Invalid stake pool data for {}: {}", address, err); + None + } + } + }) + .collect() + }) +} diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 061d5f20..b8c8639c 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -1234,14 +1234,22 @@ fn command_withdraw( .calc_lamports_withdraw_amount(withdraw_account.pool_amount) .unwrap(); - println!( - "Withdrawing {}, or {} pool tokens, from stake account {}, delegated to {:?}, stake / withdraw authority {}", - Sol(sol_withdraw_amount), - spl_token::amount_to_ui_amount(withdraw_account.pool_amount, pool_mint.decimals), - withdraw_account.stake_address, - withdraw_account.vote_address, - config.staker.pubkey(), - ); + if let Some(vote_address) = withdraw_account.vote_address { + println!( + "Withdrawing {}, or {} pool tokens, from stake account {}, delegated to {}", + Sol(sol_withdraw_amount), + spl_token::amount_to_ui_amount(withdraw_account.pool_amount, pool_mint.decimals), + withdraw_account.stake_address, + vote_address, + ); + } else { + println!( + "Withdrawing {}, or {} pool tokens, from stake account {}", + Sol(sol_withdraw_amount), + spl_token::amount_to_ui_amount(withdraw_account.pool_amount, pool_mint.decimals), + withdraw_account.stake_address, + ); + } // Use separate mutable variable because withdraw might create a new account let stake_receiver = stake_receiver_param.unwrap_or_else(|| { @@ -1421,6 +1429,23 @@ fn command_set_fee( Ok(()) } +fn command_list_all_pools(config: &Config) -> CommandResult { + let all_pools = get_stake_pools(&config.rpc_client)?; + let count = all_pools.len(); + for (address, stake_pool, validator_list) in all_pools { + println!( + "Address: {}\tManager: {}\tLamports: {}\tPool tokens: {}\tValidators: {}", + address, + stake_pool.manager, + stake_pool.total_stake_lamports, + stake_pool.pool_token_supply, + validator_list.validators.len() + ); + } + println!("Total number of pools: {}", count); + Ok(()) +} + fn main() { solana_logger::setup_with_default("solana=info"); @@ -2149,6 +2174,9 @@ fn main() { .help("Fee percentage, maximum 100"), ) ) + .subcommand(SubCommand::with_name("list-all") + .about("List information about all stake pools") + ) .get_matches(); let mut wallet_manager = None; @@ -2428,6 +2456,7 @@ fn main() { }; command_set_fee(&config, &stake_pool_address, fee_type) } + ("list-all", _) => command_list_all_pools(&config), _ => unreachable!(), } .map_err(|err| { From 7241c01ad0458f0b2ac117325c12a8ece54fbc59 Mon Sep 17 00:00:00 2001 From: jon-chuang <9093549+jon-chuang@users.noreply.github.com> Date: Fri, 20 Aug 2021 13:14:42 +0800 Subject: [PATCH 0158/1076] stake-pool: seed suffix to allow creating & discarding multiple transient stake accs (#2298) * seed suffix to allow creating & discarding multiple transient stake accs * "suffix" * fix tests, memcmp and len, reorder struct fields * remove proptest --- program/src/lib.rs | 4 ++++ program/src/processor.rs | 2 ++ program/src/state.rs | 48 ++++++++++++++----------------------- program/tests/huge_pool.rs | 2 ++ program/tests/vsa_add.rs | 2 ++ program/tests/vsa_remove.rs | 2 ++ 6 files changed, 30 insertions(+), 30 deletions(-) diff --git a/program/src/lib.rs b/program/src/lib.rs index 0c71bb41..a6f905a9 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -49,6 +49,10 @@ pub const WITHDRAWAL_BASELINE_FEE: Fee = Fee { denominator: 1000, }; +/// The maximum number of transient stake accounts respecting +/// transaction account limits. +pub const MAX_TRANSIENT_STAKE_ACCOUNTS: usize = 10; + /// Get the stake amount under consideration when calculating pool token /// conversions #[inline] diff --git a/program/src/processor.rs b/program/src/processor.rs index e4186f12..130303b2 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -861,6 +861,8 @@ impl Processor { active_stake_lamports: 0, transient_stake_lamports: 0, last_update_epoch: clock.epoch, + transient_seed_suffix_start: 0, + transient_seed_suffix_end: 0, })?; Ok(()) diff --git a/program/src/state.rs b/program/src/state.rs index e7ec27b8..0e6ed0f1 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -472,30 +472,6 @@ impl Default for StakeStatus { } } -/// Packed version of the validator stake info, for use with pointer casts -#[repr(packed)] -#[derive(Clone, Copy, Debug, Default, PartialEq)] -pub struct ValidatorStakeInfoPacked { - /// Status of the validator stake account - pub status: StakeStatus, - - /// Validator vote account address - pub vote_account_address: Pubkey, - - /// Amount of active stake delegated to this validator - /// Note that if `last_update_epoch` does not match the current epoch then - /// this field may not be accurate - pub active_stake_lamports: u64, - - /// Amount of transient stake delegated to this validator - /// Note that if `last_update_epoch` does not match the current epoch then - /// this field may not be accurate - pub transient_stake_lamports: u64, - - /// Last epoch the active and transient stake lamports fields were updated - pub last_update_epoch: u64, -} - /// Information about a validator in the pool /// /// NOTE: ORDER IS VERY IMPORTANT HERE, PLEASE DO NOT RE-ORDER THE FIELDS UNLESS @@ -520,6 +496,12 @@ pub struct ValidatorStakeInfo { /// Last epoch the active and transient stake lamports fields were updated pub last_update_epoch: u64, + /// Start of the validator transient account seed suffixess + pub transient_seed_suffix_start: u64, + + /// End of the validator transient account seed suffixes + pub transient_seed_suffix_end: u64, + /// Status of the validator stake account pub status: StakeStatus, @@ -539,7 +521,7 @@ impl ValidatorStakeInfo { /// info matches the vote account address pub fn memcmp_pubkey(data: &[u8], vote_address_bytes: &[u8]) -> bool { sol_memcmp( - &data[25..25 + PUBKEY_BYTES], + &data[41..41 + PUBKEY_BYTES], vote_address_bytes, PUBKEY_BYTES, ) == 0 @@ -559,14 +541,14 @@ impl ValidatorStakeInfo { /// Check that the validator stake info is valid pub fn is_not_removed(data: &[u8]) -> bool { - FromPrimitive::from_u8(data[24]) != Some(StakeStatus::ReadyForRemoval) + FromPrimitive::from_u8(data[40]) != Some(StakeStatus::ReadyForRemoval) } } impl Sealed for ValidatorStakeInfo {} impl Pack for ValidatorStakeInfo { - const LEN: usize = 57; + const LEN: usize = 73; fn pack_into_slice(&self, data: &mut [u8]) { let mut data = data; self.serialize(&mut data).unwrap(); @@ -808,9 +790,11 @@ mod test { ValidatorStakeInfo { status: StakeStatus::Active, vote_account_address: Pubkey::new_from_array([1; 32]), - active_stake_lamports: 123456789, - transient_stake_lamports: 1111111, - last_update_epoch: 987654321, + active_stake_lamports: u64::from_le_bytes([255; 8]), + transient_stake_lamports: u64::from_le_bytes([128; 8]), + last_update_epoch: u64::from_le_bytes([64; 8]), + transient_seed_suffix_start: 0, + transient_seed_suffix_end: 0, }, ValidatorStakeInfo { status: StakeStatus::DeactivatingTransient, @@ -818,6 +802,8 @@ mod test { active_stake_lamports: 998877665544, transient_stake_lamports: 222222222, last_update_epoch: 11223445566, + transient_seed_suffix_start: 0, + transient_seed_suffix_end: 0, }, ValidatorStakeInfo { status: StakeStatus::ReadyForRemoval, @@ -825,6 +811,8 @@ mod test { active_stake_lamports: 0, transient_stake_lamports: 0, last_update_epoch: 999999999999999, + transient_seed_suffix_start: 0, + transient_seed_suffix_end: 0, }, ], } diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index 38c0ded0..d7566a7f 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -164,6 +164,8 @@ async fn setup( active_stake_lamports, transient_stake_lamports: 0, last_update_epoch: 0, + transient_seed_suffix_start: 0, + transient_seed_suffix_end: 0, }); stake_pool.total_stake_lamports += active_stake_lamports; diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index 8927b392..1b961a6d 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -91,6 +91,8 @@ async fn success() { last_update_epoch: 0, active_stake_lamports: 0, transient_stake_lamports: 0, + transient_seed_suffix_start: 0, + transient_seed_suffix_end: 0, }] } ); diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index c27d9c54..bb7e644c 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -539,6 +539,8 @@ async fn success_with_deactivating_transient_stake() { last_update_epoch: 0, active_stake_lamports: 0, transient_stake_lamports: TEST_STAKE_AMOUNT + stake_rent, + transient_seed_suffix_start: 0, + transient_seed_suffix_end: 0, }], }; assert_eq!(validator_list, expected_list); From fb0e1032f5d75a5c5de985add0c71b24f77d29f2 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 20 Aug 2021 14:15:02 -0400 Subject: [PATCH 0159/1076] stake-pool: Add seed for transient stake account (#2304) * stake-pool: Add seed for transient stake account * Use new functions in CLI * Put back transient stake seed prefix --- clients/cli/src/main.rs | 17 + program/src/error.rs | 3 + program/src/instruction.rs | 102 +++-- program/src/lib.rs | 16 +- program/src/processor.rs | 328 ++++++++------ program/src/state.rs | 3 +- program/tests/decrease.rs | 31 +- program/tests/deposit.rs | 2 +- program/tests/helpers/mod.rs | 34 +- program/tests/huge_pool.rs | 18 +- program/tests/increase.rs | 33 +- program/tests/set_preferred.rs | 2 + .../tests/update_validator_list_balance.rs | 140 +++++- program/tests/vsa_add.rs | 10 +- program/tests/vsa_remove.rs | 426 +++++++++++++----- program/tests/withdraw.rs | 8 +- 16 files changed, 842 insertions(+), 331 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index b8c8639c..b5c20f8a 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -440,6 +440,11 @@ fn command_vsa_remove( let staker_pubkey = config.staker.pubkey(); let new_authority = new_authority.as_ref().unwrap_or(&staker_pubkey); + let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?; + let validator_stake_info = validator_list + .find(vote_account) + .ok_or("Vote account not found in validator list")?; + let mut signers = vec![config.fee_payer.as_ref(), config.staker.as_ref()]; unique_signers!(signers); let transaction = checked_transaction_with_signers( @@ -452,6 +457,7 @@ fn command_vsa_remove( stake_pool_address, vote_account, new_authority, + validator_stake_info.transient_seed_suffix_start, ), ], &signers, @@ -472,6 +478,10 @@ fn command_increase_validator_stake( } let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; + let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?; + let validator_stake_info = validator_list + .find(vote_account) + .ok_or("Vote account not found in validator list")?; let mut signers = vec![config.fee_payer.as_ref(), config.staker.as_ref()]; unique_signers!(signers); @@ -484,6 +494,7 @@ fn command_increase_validator_stake( stake_pool_address, vote_account, lamports, + validator_stake_info.transient_seed_suffix_start, ), ], &signers, @@ -504,6 +515,10 @@ fn command_decrease_validator_stake( } let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; + let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?; + let validator_stake_info = validator_list + .find(vote_account) + .ok_or("Vote account not found in validator list")?; let mut signers = vec![config.fee_payer.as_ref(), config.staker.as_ref()]; unique_signers!(signers); @@ -516,6 +531,7 @@ fn command_decrease_validator_stake( stake_pool_address, vote_account, lamports, + validator_stake_info.transient_seed_suffix_start, ), ], &signers, @@ -949,6 +965,7 @@ fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { &spl_stake_pool::id(), &validator.vote_account_address, stake_pool_address, + validator.transient_seed_suffix_start, ); println!( "Vote Account: {}\tStake Account: {}\tActive Balance: {}\tTransient Stake Account: {}\tTransient Balance: {}\tLast Update Epoch: {}{}", diff --git a/program/src/error.rs b/program/src/error.rs index bc471ec6..a8530e73 100644 --- a/program/src/error.rs +++ b/program/src/error.rs @@ -119,6 +119,9 @@ pub enum StakePoolError { /// Provided preferred validator is invalid #[error("InvalidPreferredValidator")] InvalidPreferredValidator, + /// Provided validator stake account already has a transient stake account in use + #[error("TransientAccountInUse")] + TransientAccountInUse, } impl From for ProgramError { fn from(e: StakePoolError) -> Self { diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 59aab84b..3b7ce1e6 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -155,8 +155,14 @@ pub enum StakePoolInstruction { /// 7. `[]` Rent sysvar /// 8. `[]` System program /// 9. `[]` Stake program - /// userdata: amount of lamports to split into the transient stake account - DecreaseValidatorStake(u64), + DecreaseValidatorStake { + /// amount of lamports to split into the transient stake account + #[allow(dead_code)] // but it's not + lamports: u64, + /// seed used to create transient stake account + #[allow(dead_code)] // but it's not + transient_stake_seed: u64, + }, /// (Staker only) Increase stake on a validator from the reserve account /// @@ -186,7 +192,14 @@ pub enum StakePoolInstruction { /// `lamports + stake_rent_exemption` /// The rent-exemption of the stake account is withdrawn back to the reserve /// after it is merged. - IncreaseValidatorStake(u64), + IncreaseValidatorStake { + /// amount of lamports to increase on the given validator + #[allow(dead_code)] // but it's not + lamports: u64, + /// seed used to create transient stake account + #[allow(dead_code)] // but it's not + transient_stake_seed: u64, + }, /// (Staker only) Set the preferred deposit or withdraw stake account for the /// stake pool @@ -502,6 +515,7 @@ pub fn decrease_validator_stake( validator_stake: &Pubkey, transient_stake: &Pubkey, lamports: u64, + transient_stake_seed: u64, ) -> Instruction { let accounts = vec![ AccountMeta::new_readonly(*stake_pool, false), @@ -518,9 +532,12 @@ pub fn decrease_validator_stake( Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::DecreaseValidatorStake(lamports) - .try_to_vec() - .unwrap(), + data: StakePoolInstruction::DecreaseValidatorStake { + lamports, + transient_stake_seed, + } + .try_to_vec() + .unwrap(), } } @@ -536,6 +553,7 @@ pub fn increase_validator_stake( transient_stake: &Pubkey, validator: &Pubkey, lamports: u64, + transient_stake_seed: u64, ) -> Instruction { let accounts = vec![ AccountMeta::new_readonly(*stake_pool, false), @@ -555,9 +573,12 @@ pub fn increase_validator_stake( Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::IncreaseValidatorStake(lamports) - .try_to_vec() - .unwrap(), + data: StakePoolInstruction::IncreaseValidatorStake { + lamports, + transient_stake_seed, + } + .try_to_vec() + .unwrap(), } } @@ -636,13 +657,18 @@ pub fn remove_validator_from_pool_with_vote( stake_pool_address: &Pubkey, vote_account_address: &Pubkey, new_stake_account_authority: &Pubkey, + transient_stake_seed: u64, ) -> Instruction { let pool_withdraw_authority = find_withdraw_authority_program_address(program_id, stake_pool_address).0; let (stake_account_address, _) = find_stake_program_address(program_id, vote_account_address, stake_pool_address); - let (transient_stake_account, _) = - find_transient_stake_program_address(program_id, vote_account_address, stake_pool_address); + let (transient_stake_account, _) = find_transient_stake_program_address( + program_id, + vote_account_address, + stake_pool_address, + transient_stake_seed, + ); remove_validator_from_pool( program_id, stake_pool_address, @@ -663,11 +689,16 @@ pub fn increase_validator_stake_with_vote( stake_pool_address: &Pubkey, vote_account_address: &Pubkey, lamports: u64, + transient_stake_seed: u64, ) -> Instruction { let pool_withdraw_authority = find_withdraw_authority_program_address(program_id, stake_pool_address).0; - let (transient_stake_address, _) = - find_transient_stake_program_address(program_id, vote_account_address, stake_pool_address); + let (transient_stake_address, _) = find_transient_stake_program_address( + program_id, + vote_account_address, + stake_pool_address, + transient_stake_seed, + ); increase_validator_stake( program_id, @@ -679,6 +710,7 @@ pub fn increase_validator_stake_with_vote( &transient_stake_address, vote_account_address, lamports, + transient_stake_seed, ) } @@ -690,13 +722,18 @@ pub fn decrease_validator_stake_with_vote( stake_pool_address: &Pubkey, vote_account_address: &Pubkey, lamports: u64, + transient_stake_seed: u64, ) -> Instruction { let pool_withdraw_authority = find_withdraw_authority_program_address(program_id, stake_pool_address).0; let (validator_stake_address, _) = find_stake_program_address(program_id, vote_account_address, stake_pool_address); - let (transient_stake_address, _) = - find_transient_stake_program_address(program_id, vote_account_address, stake_pool_address); + let (transient_stake_address, _) = find_transient_stake_program_address( + program_id, + vote_account_address, + stake_pool_address, + transient_stake_seed, + ); decrease_validator_stake( program_id, stake_pool_address, @@ -706,6 +743,7 @@ pub fn decrease_validator_stake_with_vote( &validator_stake_address, &transient_stake_address, lamports, + transient_stake_seed, ) } @@ -714,8 +752,9 @@ pub fn update_validator_list_balance( program_id: &Pubkey, stake_pool: &Pubkey, stake_pool_withdraw_authority: &Pubkey, - validator_list: &Pubkey, + validator_list_address: &Pubkey, reserve_stake: &Pubkey, + validator_list: &ValidatorList, validator_vote_accounts: &[Pubkey], start_index: u32, no_merge: bool, @@ -723,7 +762,7 @@ pub fn update_validator_list_balance( let mut accounts = vec![ AccountMeta::new_readonly(*stake_pool, false), AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), - AccountMeta::new(*validator_list, false), + AccountMeta::new(*validator_list_address, false), AccountMeta::new(*reserve_stake, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), @@ -733,17 +772,23 @@ pub fn update_validator_list_balance( &mut validator_vote_accounts .iter() .flat_map(|vote_account_address| { - let (validator_stake_account, _) = - find_stake_program_address(program_id, vote_account_address, stake_pool); - let (transient_stake_account, _) = find_transient_stake_program_address( - program_id, - vote_account_address, - stake_pool, - ); - vec![ - AccountMeta::new(validator_stake_account, false), - AccountMeta::new(transient_stake_account, false), - ] + let validator_stake_info = validator_list.find(vote_account_address); + if let Some(validator_stake_info) = validator_stake_info { + let (validator_stake_account, _) = + find_stake_program_address(program_id, vote_account_address, stake_pool); + let (transient_stake_account, _) = find_transient_stake_program_address( + program_id, + vote_account_address, + stake_pool, + validator_stake_info.transient_seed_suffix_start, + ); + vec![ + AccountMeta::new(validator_stake_account, false), + AccountMeta::new(transient_stake_account, false), + ] + } else { + vec![] + } }) .collect::>(), ); @@ -835,6 +880,7 @@ pub fn update_stake_pool( &withdraw_authority, &stake_pool.validator_list, &stake_pool.reserve_stake, + validator_list, accounts_chunk, start_index, no_merge, diff --git a/program/src/lib.rs b/program/src/lib.rs index a6f905a9..06650f7d 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -26,7 +26,7 @@ const AUTHORITY_DEPOSIT: &[u8] = b"deposit"; const AUTHORITY_WITHDRAW: &[u8] = b"withdraw"; /// Seed for transient stake account -const TRANSIENT_STAKE_SEED: &[u8] = b"transient"; +const TRANSIENT_STAKE_SEED_PREFIX: &[u8] = b"transient"; /// Minimum amount of staked SOL required in a validator stake account to allow /// for merges without a mismatch on credits observed @@ -85,7 +85,7 @@ pub fn find_withdraw_authority_program_address( stake_pool_address: &Pubkey, ) -> (Pubkey, u8) { Pubkey::find_program_address( - &[&stake_pool_address.to_bytes()[..32], AUTHORITY_WITHDRAW], + &[&stake_pool_address.to_bytes(), AUTHORITY_WITHDRAW], program_id, ) } @@ -98,8 +98,8 @@ pub fn find_stake_program_address( ) -> (Pubkey, u8) { Pubkey::find_program_address( &[ - &vote_account_address.to_bytes()[..32], - &stake_pool_address.to_bytes()[..32], + &vote_account_address.to_bytes(), + &stake_pool_address.to_bytes(), ], program_id, ) @@ -110,12 +110,14 @@ pub fn find_transient_stake_program_address( program_id: &Pubkey, vote_account_address: &Pubkey, stake_pool_address: &Pubkey, + seed: u64, ) -> (Pubkey, u8) { Pubkey::find_program_address( &[ - TRANSIENT_STAKE_SEED, - &vote_account_address.to_bytes()[..32], - &stake_pool_address.to_bytes()[..32], + TRANSIENT_STAKE_SEED_PREFIX, + &vote_account_address.to_bytes(), + &stake_pool_address.to_bytes(), + &seed.to_le_bytes(), ], program_id, ) diff --git a/program/src/processor.rs b/program/src/processor.rs index 130303b2..26617f91 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -11,7 +11,7 @@ use { AccountType, Fee, FeeType, StakePool, StakeStatus, ValidatorList, ValidatorListHeader, ValidatorStakeInfo, }, - AUTHORITY_DEPOSIT, AUTHORITY_WITHDRAW, MINIMUM_ACTIVE_STAKE, TRANSIENT_STAKE_SEED, + AUTHORITY_DEPOSIT, AUTHORITY_WITHDRAW, MINIMUM_ACTIVE_STAKE, TRANSIENT_STAKE_SEED_PREFIX, }, borsh::{BorshDeserialize, BorshSerialize}, num_traits::FromPrimitive, @@ -77,10 +77,15 @@ fn check_transient_stake_address( stake_pool_address: &Pubkey, stake_account_address: &Pubkey, vote_address: &Pubkey, + seed: u64, ) -> Result { // Check stake account address validity - let (transient_stake_address, bump_seed) = - crate::find_transient_stake_program_address(program_id, vote_address, stake_pool_address); + let (transient_stake_address, bump_seed) = crate::find_transient_stake_program_address( + program_id, + vote_address, + stake_pool_address, + seed, + ); if transient_stake_address != *stake_account_address { Err(StakePoolError::InvalidStakeAccountAddress.into()) } else { @@ -922,12 +927,6 @@ impl Processor { stake_account_info.key, &vote_account_address, )?; - check_transient_stake_address( - program_id, - stake_pool_info.key, - transient_stake_account_info.key, - &vote_account_address, - )?; let maybe_validator_stake_info = validator_list.find_mut::( vote_account_address.as_ref(), @@ -940,6 +939,7 @@ impl Processor { ); return Err(StakePoolError::ValidatorNotFound.into()); } + let mut validator_stake_info = maybe_validator_stake_info.unwrap(); let stake_lamports = **stake_account_info.lamports.borrow(); let required_lamports = minimum_stake_lamports(&meta); @@ -961,19 +961,34 @@ impl Processor { return Err(StakePoolError::StakeLamportsNotEqualToMinimum.into()); } - // check that the transient stake account doesn't exist - let new_status = if let Ok((_meta, stake)) = get_stake_state(transient_stake_account_info) { - if stake.delegation.deactivation_epoch == Epoch::MAX { - msg!( - "Transient stake {} activating, can't remove stake {} on validator {}", - transient_stake_account_info.key, - stake_account_info.key, - vote_account_address - ); - return Err(StakePoolError::WrongStakeState.into()); - } else { - // stake is deactivating, mark the entry as such - StakeStatus::DeactivatingTransient + let new_status = if validator_stake_info.transient_stake_lamports > 0 { + check_transient_stake_address( + program_id, + stake_pool_info.key, + transient_stake_account_info.key, + &vote_account_address, + validator_stake_info.transient_seed_suffix_start, + )?; + + match get_stake_state(transient_stake_account_info) { + Ok((meta, stake)) + if meta.authorized.staker == *withdraw_authority_info.key + && meta.authorized.withdrawer == *withdraw_authority_info.key => + { + if stake.delegation.deactivation_epoch == Epoch::MAX { + msg!( + "Transient stake {} activating, can't remove stake {} on validator {}", + transient_stake_account_info.key, + stake_account_info.key, + vote_account_address + ); + return Err(StakePoolError::WrongStakeState.into()); + } else { + // stake is deactivating, mark the entry as such + StakeStatus::DeactivatingTransient + } + } + _ => StakeStatus::ReadyForRemoval, } } else { StakeStatus::ReadyForRemoval @@ -990,7 +1005,6 @@ impl Processor { stake_program_info.clone(), )?; - let mut validator_stake_info = maybe_validator_stake_info.unwrap(); validator_stake_info.status = new_status; if stake_pool.preferred_deposit_validator_vote_address == Some(vote_account_address) { @@ -1009,6 +1023,7 @@ impl Processor { program_id: &Pubkey, accounts: &[AccountInfo], lamports: u64, + transient_stake_seed: u64, ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; @@ -1063,19 +1078,6 @@ impl Processor { &vote_account_address, )?; - let transient_stake_bump_seed = check_transient_stake_address( - program_id, - stake_pool_info.key, - transient_stake_account_info.key, - &vote_account_address, - )?; - let transient_stake_account_signer_seeds: &[&[_]] = &[ - TRANSIENT_STAKE_SEED, - &vote_account_address.to_bytes()[..32], - &stake_pool_info.key.to_bytes()[..32], - &[transient_stake_bump_seed], - ]; - let maybe_validator_stake_info = validator_list.find_mut::( vote_account_address.as_ref(), ValidatorStakeInfo::memcmp_pubkey, @@ -1088,6 +1090,24 @@ impl Processor { return Err(StakePoolError::ValidatorNotFound.into()); } let mut validator_stake_info = maybe_validator_stake_info.unwrap(); + if validator_stake_info.transient_stake_lamports > 0 { + return Err(StakePoolError::TransientAccountInUse.into()); + } + + let transient_stake_bump_seed = check_transient_stake_address( + program_id, + stake_pool_info.key, + transient_stake_account_info.key, + &vote_account_address, + transient_stake_seed, + )?; + let transient_stake_account_signer_seeds: &[&[_]] = &[ + TRANSIENT_STAKE_SEED_PREFIX, + &vote_account_address.to_bytes(), + &stake_pool_info.key.to_bytes(), + &transient_stake_seed.to_le_bytes(), + &[transient_stake_bump_seed], + ]; let stake_rent = rent.minimum_balance(std::mem::size_of::()); if lamports <= stake_rent { @@ -1131,6 +1151,7 @@ impl Processor { .checked_sub(lamports) .ok_or(StakePoolError::CalculationFailure)?; validator_stake_info.transient_stake_lamports = lamports; + validator_stake_info.transient_seed_suffix_start = transient_stake_seed; Ok(()) } @@ -1140,6 +1161,7 @@ impl Processor { program_id: &Pubkey, accounts: &[AccountInfo], lamports: u64, + transient_stake_seed: u64, ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; @@ -1191,18 +1213,6 @@ impl Processor { } let vote_account_address = validator_vote_account_info.key; - let transient_stake_bump_seed = check_transient_stake_address( - program_id, - stake_pool_info.key, - transient_stake_account_info.key, - vote_account_address, - )?; - let transient_stake_account_signer_seeds: &[&[_]] = &[ - TRANSIENT_STAKE_SEED, - &vote_account_address.to_bytes()[..32], - &stake_pool_info.key.to_bytes()[..32], - &[transient_stake_bump_seed], - ]; let maybe_validator_stake_info = validator_list.find_mut::( vote_account_address.as_ref(), @@ -1216,6 +1226,24 @@ impl Processor { return Err(StakePoolError::ValidatorNotFound.into()); } let mut validator_stake_info = maybe_validator_stake_info.unwrap(); + if validator_stake_info.transient_stake_lamports > 0 { + return Err(StakePoolError::TransientAccountInUse.into()); + } + + let transient_stake_bump_seed = check_transient_stake_address( + program_id, + stake_pool_info.key, + transient_stake_account_info.key, + vote_account_address, + transient_stake_seed, + )?; + let transient_stake_account_signer_seeds: &[&[_]] = &[ + TRANSIENT_STAKE_SEED_PREFIX, + &vote_account_address.to_bytes(), + &stake_pool_info.key.to_bytes(), + &transient_stake_seed.to_le_bytes(), + &[transient_stake_bump_seed], + ]; if validator_stake_info.status != StakeStatus::Active { msg!("Validator is marked for removal and no longer allows increases"); @@ -1282,6 +1310,7 @@ impl Processor { )?; validator_stake_info.transient_stake_lamports = total_lamports; + validator_stake_info.transient_seed_suffix_start = transient_stake_seed; Ok(()) } @@ -1415,6 +1444,7 @@ impl Processor { stake_pool_info.key, transient_stake_info.key, &validator_stake_record.vote_account_address, + validator_stake_record.transient_seed_suffix_start, ) .is_err() { @@ -1439,102 +1469,112 @@ impl Processor { // * inactive -> merge into reserve stake // * not a stake -> ignore match transient_stake_state { - Some(stake_program::StakeState::Initialized(_meta)) => { - if no_merge { - transient_stake_lamports = transient_stake_info.lamports(); - } else { - // merge into reserve - Self::stake_merge( - stake_pool_info.key, - transient_stake_info.clone(), - withdraw_authority_info.clone(), - AUTHORITY_WITHDRAW, - stake_pool.stake_withdraw_bump_seed, - reserve_stake_info.clone(), - clock_info.clone(), - stake_history_info.clone(), - stake_program_info.clone(), - )?; - if validator_stake_record.status == StakeStatus::DeactivatingTransient { - // the validator stake was previously removed, and - // now this entry can be removed totally - validator_stake_record.status = StakeStatus::ReadyForRemoval; + Some(stake_program::StakeState::Initialized(meta)) => { + // if transient account was hijacked, ignore it + if meta.authorized.staker == *withdraw_authority_info.key + && meta.authorized.withdrawer == *withdraw_authority_info.key + { + if no_merge { + transient_stake_lamports = transient_stake_info.lamports(); + } else { + // merge into reserve + Self::stake_merge( + stake_pool_info.key, + transient_stake_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + reserve_stake_info.clone(), + clock_info.clone(), + stake_history_info.clone(), + stake_program_info.clone(), + )?; + if validator_stake_record.status == StakeStatus::DeactivatingTransient { + // the validator stake was previously removed, and + // now this entry can be removed totally + validator_stake_record.status = StakeStatus::ReadyForRemoval; + } } } } Some(stake_program::StakeState::Stake(meta, stake)) => { - let account_stake = meta - .rent_exempt_reserve - .saturating_add(stake.delegation.stake); - if no_merge { - transient_stake_lamports = account_stake; - } else if stake.delegation.deactivation_epoch < clock.epoch { - // deactivated, merge into reserve - Self::stake_merge( - stake_pool_info.key, - transient_stake_info.clone(), - withdraw_authority_info.clone(), - AUTHORITY_WITHDRAW, - stake_pool.stake_withdraw_bump_seed, - reserve_stake_info.clone(), - clock_info.clone(), - stake_history_info.clone(), - stake_program_info.clone(), - )?; - if validator_stake_record.status == StakeStatus::DeactivatingTransient { - // the validator stake was previously removed, and - // now this entry can be removed totally - validator_stake_record.status = StakeStatus::ReadyForRemoval; - } - } else if stake.delegation.activation_epoch < clock.epoch { - if let Some(stake_program::StakeState::Stake(_, validator_stake)) = - validator_stake_state - { - if stake_program::active_stakes_can_merge(&stake, &validator_stake) - .is_ok() + // if transient account was hijacked, ignore it + if meta.authorized.staker == *withdraw_authority_info.key + && meta.authorized.withdrawer == *withdraw_authority_info.key + { + let account_stake = meta + .rent_exempt_reserve + .saturating_add(stake.delegation.stake); + if no_merge { + transient_stake_lamports = account_stake; + } else if stake.delegation.deactivation_epoch < clock.epoch { + // deactivated, merge into reserve + Self::stake_merge( + stake_pool_info.key, + transient_stake_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + reserve_stake_info.clone(), + clock_info.clone(), + stake_history_info.clone(), + stake_program_info.clone(), + )?; + if validator_stake_record.status == StakeStatus::DeactivatingTransient { + // the validator stake was previously removed, and + // now this entry can be removed totally + validator_stake_record.status = StakeStatus::ReadyForRemoval; + } + } else if stake.delegation.activation_epoch < clock.epoch { + if let Some(stake_program::StakeState::Stake(_, validator_stake)) = + validator_stake_state { - let additional_lamports = transient_stake_info - .lamports() - .saturating_sub(stake.delegation.stake); - Self::stake_merge( - stake_pool_info.key, - transient_stake_info.clone(), - withdraw_authority_info.clone(), - AUTHORITY_WITHDRAW, - stake_pool.stake_withdraw_bump_seed, - validator_stake_info.clone(), - clock_info.clone(), - stake_history_info.clone(), - stake_program_info.clone(), - )?; - - // post merge of two active stakes, withdraw - // the extra back to the reserve - if additional_lamports > 0 { - Self::stake_withdraw( + if stake_program::active_stakes_can_merge(&stake, &validator_stake) + .is_ok() + { + let additional_lamports = transient_stake_info + .lamports() + .saturating_sub(stake.delegation.stake); + Self::stake_merge( stake_pool_info.key, - validator_stake_info.clone(), + transient_stake_info.clone(), withdraw_authority_info.clone(), AUTHORITY_WITHDRAW, stake_pool.stake_withdraw_bump_seed, - reserve_stake_info.clone(), + validator_stake_info.clone(), clock_info.clone(), stake_history_info.clone(), stake_program_info.clone(), - additional_lamports, )?; + + // post merge of two active stakes, withdraw + // the extra back to the reserve + if additional_lamports > 0 { + Self::stake_withdraw( + stake_pool_info.key, + validator_stake_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + reserve_stake_info.clone(), + clock_info.clone(), + stake_history_info.clone(), + stake_program_info.clone(), + additional_lamports, + )?; + } + } else { + msg!("Stake activating or just active, not ready to merge"); + transient_stake_lamports = account_stake; } } else { - msg!("Stake activating or just active, not ready to merge"); + msg!("Transient stake is activating or active, but validator stake is not, need to add the validator stake account on {} back into the stake pool", stake.delegation.voter_pubkey); transient_stake_lamports = account_stake; } } else { - msg!("Transient stake is activating or active, but validator stake is not, need to add the validator stake account on {} back into the stake pool", stake.delegation.voter_pubkey); + msg!("Transient stake not ready to be merged anywhere"); transient_stake_lamports = account_stake; } - } else { - msg!("Transient stake not ready to be merged anywhere"); - transient_stake_lamports = account_stake; } } None @@ -2287,6 +2327,13 @@ impl Processor { } } + let validator_stake_info = validator_list + .find_mut::( + vote_account_address.as_ref(), + ValidatorStakeInfo::memcmp_pubkey, + ) + .ok_or(StakePoolError::ValidatorNotFound)?; + // if there's any active stake, we must withdraw from an active // stake account let withdrawing_from_transient_stake = if has_active_stake { @@ -2303,17 +2350,11 @@ impl Processor { stake_pool_info.key, stake_split_from.key, &vote_account_address, + validator_stake_info.transient_seed_suffix_start, )?; true }; - let validator_stake_info = validator_list - .find_mut::( - vote_account_address.as_ref(), - ValidatorStakeInfo::memcmp_pubkey, - ) - .ok_or(StakePoolError::ValidatorNotFound)?; - if validator_stake_info.status != StakeStatus::Active { msg!("Validator is marked for removal and no longer allowing withdrawals"); return Err(StakePoolError::ValidatorNotFound.into()); @@ -2550,13 +2591,29 @@ impl Processor { msg!("Instruction: RemoveValidatorFromPool"); Self::process_remove_validator_from_pool(program_id, accounts) } - StakePoolInstruction::DecreaseValidatorStake(amount) => { + StakePoolInstruction::DecreaseValidatorStake { + lamports, + transient_stake_seed, + } => { msg!("Instruction: DecreaseValidatorStake"); - Self::process_decrease_validator_stake(program_id, accounts, amount) + Self::process_decrease_validator_stake( + program_id, + accounts, + lamports, + transient_stake_seed, + ) } - StakePoolInstruction::IncreaseValidatorStake(amount) => { + StakePoolInstruction::IncreaseValidatorStake { + lamports, + transient_stake_seed, + } => { msg!("Instruction: IncreaseValidatorStake"); - Self::process_increase_validator_stake(program_id, accounts, amount) + Self::process_increase_validator_stake( + program_id, + accounts, + lamports, + transient_stake_seed, + ) } StakePoolInstruction::SetPreferredValidator { validator_type, @@ -2663,6 +2720,7 @@ impl PrintProgramError for StakePoolError { StakePoolError::InvalidStakeDepositAuthority => msg!("Error: Provided stake deposit authority does not match the program's"), StakePoolError::InvalidSolDepositAuthority => msg!("Error: Provided sol deposit authority does not match the program's"), StakePoolError::InvalidPreferredValidator => msg!("Error: Provided preferred validator is invalid"), + StakePoolError::TransientAccountInUse => msg!("Error: Provided validator stake account already has a transient stake account in use"), } } } diff --git a/program/src/state.rs b/program/src/state.rs index 0e6ed0f1..46435648 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -19,8 +19,7 @@ use { pubkey::{Pubkey, PUBKEY_BYTES}, }, spl_math::checked_ceil_div::CheckedCeilDiv, - std::convert::TryFrom, - std::{fmt, matches}, + std::{convert::TryFrom, fmt, matches}, }; /// Enum representing the account type managed by the program diff --git a/program/tests/decrease.rs b/program/tests/decrease.rs index 31530ace..037a1735 100644 --- a/program/tests/decrease.rs +++ b/program/tests/decrease.rs @@ -5,16 +5,15 @@ mod helpers; use { bincode::deserialize, helpers::*, - solana_program::{ - clock::Epoch, hash::Hash, instruction::InstructionError, pubkey::Pubkey, - system_instruction::SystemError, - }, + solana_program::{clock::Epoch, hash::Hash, instruction::InstructionError, pubkey::Pubkey}, solana_program_test::*, solana_sdk::{ signature::{Keypair, Signer}, transaction::{Transaction, TransactionError}, }, - spl_stake_pool::{error::StakePoolError, id, instruction, stake_program}, + spl_stake_pool::{ + error::StakePoolError, find_transient_stake_program_address, id, instruction, stake_program, + }, }; async fn setup() -> ( @@ -96,6 +95,7 @@ async fn success() { &validator_stake.stake_account, &validator_stake.transient_stake_account, decrease_lamports, + validator_stake.transient_stake_seed, ) .await; assert!(error.is_none()); @@ -156,6 +156,7 @@ async fn fail_with_wrong_withdraw_authority() { &validator_stake.stake_account, &validator_stake.transient_stake_account, decrease_lamports, + validator_stake.transient_stake_seed, )], Some(&payer.pubkey()), &[&payer, &stake_pool_accounts.staker], @@ -201,6 +202,7 @@ async fn fail_with_wrong_validator_list() { &validator_stake.stake_account, &validator_stake.transient_stake_account, decrease_lamports, + validator_stake.transient_stake_seed, )], Some(&payer.pubkey()), &[&payer, &stake_pool_accounts.staker], @@ -234,7 +236,7 @@ async fn fail_with_unknown_validator() { decrease_lamports, ) = setup().await; - let unknown_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey()); + let unknown_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), 222); unknown_stake .create_and_delegate( &mut banks_client, @@ -254,6 +256,7 @@ async fn fail_with_unknown_validator() { &unknown_stake.stake_account, &unknown_stake.transient_stake_account, decrease_lamports, + unknown_stake.transient_stake_seed, )], Some(&payer.pubkey()), &[&payer, &stake_pool_accounts.staker], @@ -295,25 +298,35 @@ async fn fail_decrease_twice() { &validator_stake.stake_account, &validator_stake.transient_stake_account, decrease_lamports / 3, + validator_stake.transient_stake_seed, ) .await; assert!(error.is_none()); + let transient_stake_seed = validator_stake.transient_stake_seed * 100; + let transient_stake_address = find_transient_stake_program_address( + &id(), + &validator_stake.vote.pubkey(), + &stake_pool_accounts.stake_pool.pubkey(), + transient_stake_seed, + ) + .0; let error = stake_pool_accounts .decrease_validator_stake( &mut banks_client, &payer, &recent_blockhash, &validator_stake.stake_account, - &validator_stake.transient_stake_account, + &transient_stake_address, decrease_lamports / 2, + transient_stake_seed, ) .await .unwrap() .unwrap(); match error { TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { - let program_error = SystemError::AccountAlreadyInUse as u32; + let program_error = StakePoolError::TransientAccountInUse as u32; assert_eq!(error_index, program_error); } _ => panic!("Wrong error"), @@ -343,6 +356,7 @@ async fn fail_with_small_lamport_amount() { &validator_stake.stake_account, &validator_stake.transient_stake_account, lamports, + validator_stake.transient_stake_seed, ) .await .unwrap() @@ -374,6 +388,7 @@ async fn fail_overdraw_validator() { &validator_stake.stake_account, &validator_stake.transient_stake_account, deposit_info.stake_lamports * 1_000_000, + validator_stake.transient_stake_seed, ) .await .unwrap() diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 6dd07b51..2a73137e 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -612,7 +612,7 @@ async fn fail_with_unknown_validator() { .unwrap(); let validator_stake_account = - ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey()); + ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), u64::MAX); validator_stake_account .create_and_delegate( &mut banks_client, diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index f64e852e..4cd4e74b 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -21,12 +21,14 @@ use { }, spl_stake_pool::{ find_stake_program_address, find_transient_stake_program_address, id, instruction, - processor, stake_program, state, state::FeeType, + processor, stake_program, + state::{self, FeeType, ValidatorList}, }, }; pub const TEST_STAKE_AMOUNT: u64 = 1_500_000_000; pub const MAX_TEST_VALIDATORS: u32 = 10_000; +pub const DEFAULT_TRANSIENT_STAKE_SEED: u64 = 42; pub fn program_test() -> ProgramTest { ProgramTest::new( @@ -549,21 +551,27 @@ pub async fn authorize_stake_account( pub struct ValidatorStakeAccount { pub stake_account: Pubkey, pub transient_stake_account: Pubkey, + pub transient_stake_seed: u64, pub vote: Keypair, pub validator: Keypair, pub stake_pool: Pubkey, } impl ValidatorStakeAccount { - pub fn new(stake_pool: &Pubkey) -> Self { + pub fn new(stake_pool: &Pubkey, transient_stake_seed: u64) -> Self { let validator = Keypair::new(); let vote = Keypair::new(); let (stake_account, _) = find_stake_program_address(&id(), &vote.pubkey(), stake_pool); - let (transient_stake_account, _) = - find_transient_stake_program_address(&id(), &vote.pubkey(), stake_pool); + let (transient_stake_account, _) = find_transient_stake_program_address( + &id(), + &vote.pubkey(), + stake_pool, + transient_stake_seed, + ); ValidatorStakeAccount { stake_account, transient_stake_account, + transient_stake_seed, vote, validator, stake_pool: *stake_pool, @@ -933,6 +941,11 @@ impl StakePoolAccounts { banks_client.process_transaction(transaction).await.err() } + pub async fn get_validator_list(&self, banks_client: &mut BanksClient) -> ValidatorList { + let validator_list_account = get_account(banks_client, &self.validator_list.pubkey()).await; + try_from_slice_unchecked::(validator_list_account.data.as_slice()).unwrap() + } + pub async fn update_validator_list_balance( &self, banks_client: &mut BanksClient, @@ -941,6 +954,7 @@ impl StakePoolAccounts { validator_vote_accounts: &[Pubkey], no_merge: bool, ) -> Option { + let validator_list = self.get_validator_list(banks_client).await; let transaction = Transaction::new_signed_with_payer( &[instruction::update_validator_list_balance( &id(), @@ -948,6 +962,7 @@ impl StakePoolAccounts { &self.withdraw_authority, &self.validator_list.pubkey(), &self.reserve_stake.pubkey(), + &validator_list, validator_vote_accounts, 0, no_merge, @@ -1010,6 +1025,7 @@ impl StakePoolAccounts { validator_vote_accounts: &[Pubkey], no_merge: bool, ) -> Option { + let validator_list = self.get_validator_list(banks_client).await; let transaction = Transaction::new_signed_with_payer( &[ instruction::update_validator_list_balance( @@ -1018,6 +1034,7 @@ impl StakePoolAccounts { &self.withdraw_authority, &self.validator_list.pubkey(), &self.reserve_stake.pubkey(), + &validator_list, validator_vote_accounts, 0, no_merge, @@ -1103,6 +1120,7 @@ impl StakePoolAccounts { validator_stake: &Pubkey, transient_stake: &Pubkey, lamports: u64, + transient_stake_seed: u64, ) -> Option { let transaction = Transaction::new_signed_with_payer( &[instruction::decrease_validator_stake( @@ -1114,6 +1132,7 @@ impl StakePoolAccounts { validator_stake, transient_stake, lamports, + transient_stake_seed, )], Some(&payer.pubkey()), &[payer, &self.staker], @@ -1130,6 +1149,7 @@ impl StakePoolAccounts { transient_stake: &Pubkey, validator: &Pubkey, lamports: u64, + transient_stake_seed: u64, ) -> Option { let transaction = Transaction::new_signed_with_payer( &[instruction::increase_validator_stake( @@ -1142,6 +1162,7 @@ impl StakePoolAccounts { transient_stake, validator, lamports, + transient_stake_seed, )], Some(&payer.pubkey()), &[payer, &self.staker], @@ -1181,7 +1202,10 @@ pub async fn simple_add_validator_to_pool( recent_blockhash: &Hash, stake_pool_accounts: &StakePoolAccounts, ) -> ValidatorStakeAccount { - let validator_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey()); + let validator_stake = ValidatorStakeAccount::new( + &stake_pool_accounts.stake_pool.pubkey(), + DEFAULT_TRANSIENT_STAKE_SEED, + ); validator_stake .create_and_delegate( banks_client, diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index d7566a7f..81498d1a 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -321,6 +321,9 @@ async fn update() { let (mut context, stake_pool_accounts, vote_account_pubkeys, _, _, _, _) = setup(HUGE_POOL_SIZE, HUGE_POOL_SIZE, STAKE_AMOUNT).await; + let validator_list = stake_pool_accounts + .get_validator_list(&mut context.banks_client) + .await; let transaction = Transaction::new_signed_with_payer( &[instruction::update_validator_list_balance( &id(), @@ -328,6 +331,7 @@ async fn update() { &stake_pool_accounts.withdraw_authority, &stake_pool_accounts.validator_list.pubkey(), &stake_pool_accounts.reserve_stake.pubkey(), + &validator_list, &vote_account_pubkeys[0..MAX_VALIDATORS_TO_UPDATE], 0, /* no_merge = */ false, @@ -391,10 +395,12 @@ async fn remove_validator_from_pool() { let first_vote = vote_account_pubkeys[0]; let (stake_address, _) = find_stake_program_address(&id(), &first_vote, &stake_pool_accounts.stake_pool.pubkey()); + let transient_stake_seed = u64::MAX; let (transient_stake_address, _) = find_transient_stake_program_address( &id(), &first_vote, &stake_pool_accounts.stake_pool.pubkey(), + transient_stake_seed, ); let new_authority = Pubkey::new_unique(); @@ -421,6 +427,7 @@ async fn remove_validator_from_pool() { &id(), &middle_vote, &stake_pool_accounts.stake_pool.pubkey(), + transient_stake_seed, ); let new_authority = Pubkey::new_unique(); @@ -444,6 +451,7 @@ async fn remove_validator_from_pool() { &id(), &last_vote, &stake_pool_accounts.stake_pool.pubkey(), + transient_stake_seed, ); let new_authority = Pubkey::new_unique(); @@ -585,8 +593,13 @@ async fn add_validator_to_pool() { assert_eq!(last_element.transient_stake_lamports, 0); assert_eq!(last_element.vote_account_address, test_vote_address); - let (transient_stake_address, _) = - find_transient_stake_program_address(&id(), &test_vote_address, &stake_pool_pubkey); + let transient_stake_seed = u64::MAX; + let (transient_stake_address, _) = find_transient_stake_program_address( + &id(), + &test_vote_address, + &stake_pool_pubkey, + transient_stake_seed, + ); let increase_amount = MINIMUM_ACTIVE_STAKE; let error = stake_pool_accounts .increase_validator_stake( @@ -596,6 +609,7 @@ async fn add_validator_to_pool() { &transient_stake_address, &test_vote_address, increase_amount, + transient_stake_seed, ) .await; assert!(error.is_none(), "{:?}", error); diff --git a/program/tests/increase.rs b/program/tests/increase.rs index bd091c33..611bf0b2 100644 --- a/program/tests/increase.rs +++ b/program/tests/increase.rs @@ -5,16 +5,15 @@ mod helpers; use { bincode::deserialize, helpers::*, - solana_program::{ - clock::Epoch, hash::Hash, instruction::InstructionError, pubkey::Pubkey, - system_instruction::SystemError, - }, + solana_program::{clock::Epoch, hash::Hash, instruction::InstructionError, pubkey::Pubkey}, solana_program_test::*, solana_sdk::{ signature::{Keypair, Signer}, transaction::{Transaction, TransactionError}, }, - spl_stake_pool::{error::StakePoolError, id, instruction, stake_program}, + spl_stake_pool::{ + error::StakePoolError, find_transient_stake_program_address, id, instruction, stake_program, + }, }; async fn setup() -> ( @@ -103,6 +102,7 @@ async fn success() { &validator_stake.transient_stake_account, &validator_stake.vote.pubkey(), increase_amount, + validator_stake.transient_stake_seed, ) .await; assert!(error.is_none()); @@ -160,6 +160,7 @@ async fn fail_with_wrong_withdraw_authority() { &validator_stake.transient_stake_account, &validator_stake.vote.pubkey(), reserve_lamports / 2, + validator_stake.transient_stake_seed, )], Some(&payer.pubkey()), &[&payer, &stake_pool_accounts.staker], @@ -205,6 +206,7 @@ async fn fail_with_wrong_validator_list() { &validator_stake.transient_stake_account, &validator_stake.vote.pubkey(), reserve_lamports / 2, + validator_stake.transient_stake_seed, )], Some(&payer.pubkey()), &[&payer, &stake_pool_accounts.staker], @@ -237,7 +239,7 @@ async fn fail_with_unknown_validator() { reserve_lamports, ) = setup().await; - let unknown_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey()); + let unknown_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), 1241); unknown_stake .create_and_delegate( &mut banks_client, @@ -258,6 +260,7 @@ async fn fail_with_unknown_validator() { &unknown_stake.transient_stake_account, &unknown_stake.vote.pubkey(), reserve_lamports / 2, + unknown_stake.transient_stake_seed, )], Some(&payer.pubkey()), &[&payer, &stake_pool_accounts.staker], @@ -298,25 +301,35 @@ async fn fail_increase_twice() { &validator_stake.transient_stake_account, &validator_stake.vote.pubkey(), reserve_lamports / 3, + validator_stake.transient_stake_seed, ) .await; assert!(error.is_none()); + let transient_stake_seed = validator_stake.transient_stake_seed * 100; + let transient_stake_address = find_transient_stake_program_address( + &id(), + &validator_stake.vote.pubkey(), + &stake_pool_accounts.stake_pool.pubkey(), + transient_stake_seed, + ) + .0; let error = stake_pool_accounts .increase_validator_stake( &mut banks_client, &payer, &recent_blockhash, - &validator_stake.transient_stake_account, - &validator_stake.vote.pubkey(), + &validator_stake.stake_account, + &transient_stake_address, reserve_lamports / 4, + transient_stake_seed, ) .await .unwrap() .unwrap(); match error { TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { - let program_error = SystemError::AccountAlreadyInUse as u32; + let program_error = StakePoolError::ValidatorNotFound as u32; assert_eq!(error_index, program_error); } _ => panic!("Wrong error"), @@ -345,6 +358,7 @@ async fn fail_with_small_lamport_amount() { &validator_stake.transient_stake_account, &validator_stake.vote.pubkey(), stake_rent, + validator_stake.transient_stake_seed, ) .await .unwrap() @@ -375,6 +389,7 @@ async fn fail_overdraw_reserve() { &validator_stake.transient_stake_account, &validator_stake.vote.pubkey(), reserve_lamports, + validator_stake.transient_stake_seed, ) .await .unwrap() diff --git a/program/tests/set_preferred.rs b/program/tests/set_preferred.rs index 05c3c481..23b47ef6 100644 --- a/program/tests/set_preferred.rs +++ b/program/tests/set_preferred.rs @@ -215,10 +215,12 @@ async fn fail_ready_for_removal() { let validator_vote_address = validator_stake_account.vote.pubkey(); // Mark validator as ready for removal + let transient_stake_seed = 0; let (transient_stake_address, _) = find_transient_stake_program_address( &id(), &validator_vote_address, &stake_pool_accounts.stake_pool.pubkey(), + transient_stake_seed, ); let new_authority = Pubkey::new_unique(); let remove_err = stake_pool_accounts diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index f761aa0f..73021ffb 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -6,9 +6,9 @@ use { helpers::*, solana_program::{borsh::try_from_slice_unchecked, program_pack::Pack, pubkey::Pubkey}, solana_program_test::*, - solana_sdk::signature::Signer, + solana_sdk::{signature::Signer, system_instruction, transaction::Transaction}, spl_stake_pool::{ - stake_program, + find_transient_stake_program_address, id, instruction, stake_program, state::{StakePool, StakeStatus, ValidatorList}, MAX_VALIDATORS_TO_UPDATE, MINIMUM_ACTIVE_STAKE, }, @@ -48,7 +48,8 @@ async fn setup( let mut stake_accounts: Vec = vec![]; let mut deposit_accounts: Vec = vec![]; for _ in 0..num_validators { - let stake_account = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey()); + let stake_account = + ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), u64::MAX); stake_account .create_and_delegate( &mut context.banks_client, @@ -239,6 +240,7 @@ async fn merge_into_reserve() { &stake_account.stake_account, &stake_account.transient_stake_account, lamports, + stake_account.transient_stake_seed, ) .await; assert!(error.is_none()); @@ -342,6 +344,7 @@ async fn merge_into_validator_stake() { &stake_account.transient_stake_account, &stake_account.vote.pubkey(), reserve_lamports / stake_accounts.len() as u64, + stake_account.transient_stake_seed, ) .await; assert!(error.is_none()); @@ -469,6 +472,7 @@ async fn merge_transient_stake_after_remove() { &stake_account.stake_account, &stake_account.transient_stake_account, deactivated_lamports, + stake_account.transient_stake_seed, ) .await; assert!(error.is_none()); @@ -663,6 +667,136 @@ async fn success_with_burned_tokens() { assert_eq!(mint.supply, stake_pool.pool_token_supply); } +#[tokio::test] +async fn success_ignoring_hijacked_transient_stake() { + let num_validators = 1; + let (mut context, stake_pool_accounts, stake_accounts, _, lamports, _, mut slot) = + setup(num_validators).await; + + let pre_lamports = get_validator_list_sum( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + + println!("Decrease from all validators"); + let stake_account = &stake_accounts[0]; + let error = stake_pool_accounts + .decrease_validator_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_account.stake_account, + &stake_account.transient_stake_account, + lamports, + stake_account.transient_stake_seed, + ) + .await; + assert!(error.is_none()); + + println!("Warp one epoch so the stakes deactivate and merge"); + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + slot += slots_per_epoch; + context.warp_to_slot(slot).unwrap(); + + println!("During update, hijack the transient stake account"); + let validator_list = stake_pool_accounts + .get_validator_list(&mut context.banks_client) + .await; + let hijacker = Pubkey::new_unique(); + let transient_stake_address = find_transient_stake_program_address( + &id(), + &stake_account.vote.pubkey(), + &stake_pool_accounts.stake_pool.pubkey(), + stake_account.transient_stake_seed, + ) + .0; + let transaction = Transaction::new_signed_with_payer( + &[ + instruction::update_validator_list_balance( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), + &validator_list, + &[stake_account.vote.pubkey()], + 0, + /* no_merge = */ false, + ), + system_instruction::transfer( + &context.payer.pubkey(), + &transient_stake_address, + 1_000_000_000, + ), + stake_program::initialize( + &transient_stake_address, + &stake_program::Authorized { + staker: hijacker, + withdrawer: hijacker, + }, + &stake_program::Lockup::default(), + ), + instruction::update_stake_pool_balance( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.pool_fee_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &spl_token::id(), + ), + instruction::cleanup_removed_validator_entries( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + ), + ], + Some(&context.payer.pubkey()), + &[&context.payer], + context.last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err(); + assert!(error.is_none()); + + println!("Update again normally, should be no change in the lamports"); + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + stake_accounts + .iter() + .map(|v| v.vote.pubkey()) + .collect::>() + .as_slice(), + false, + ) + .await; + + let expected_lamports = get_validator_list_sum( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + assert_eq!(pre_lamports, expected_lamports); + + let stake_pool_info = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data).unwrap(); + assert_eq!(pre_lamports, stake_pool.total_stake_lamports); +} + #[tokio::test] async fn fail_with_uninitialized_validator_list() {} // TODO diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index 1b961a6d..3e7d8e5e 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -36,7 +36,7 @@ async fn setup() -> ( .await .unwrap(); - let user_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey()); + let user_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), 0); user_stake .create_and_delegate( &mut banks_client, @@ -161,7 +161,7 @@ async fn fail_too_little_stake() { .await .unwrap(); - let user_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey()); + let user_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), 0); create_vote( &mut banks_client, &payer, @@ -227,7 +227,7 @@ async fn fail_too_much_stake() { .await .unwrap(); - let user_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey()); + let user_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), 0); user_stake .create_and_delegate( &mut banks_client, @@ -435,7 +435,7 @@ async fn fail_add_too_many_validator_stake_accounts() { .await .unwrap(); - let user_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey()); + let user_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), 0); user_stake .create_and_delegate( &mut banks_client, @@ -455,7 +455,7 @@ async fn fail_add_too_many_validator_stake_accounts() { .await; assert!(error.is_none()); - let user_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey()); + let user_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), 0); user_stake .create_and_delegate( &mut banks_client, diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index bb7e644c..c60d0098 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -8,10 +8,9 @@ use { helpers::*, solana_program::{ borsh::try_from_slice_unchecked, - hash::Hash, instruction::{AccountMeta, Instruction, InstructionError}, pubkey::Pubkey, - sysvar, + system_instruction, sysvar, }, solana_program_test::*, solana_sdk::{ @@ -19,63 +18,59 @@ use { transaction::{Transaction, TransactionError}, transport::TransportError, }, - spl_stake_pool::{error::StakePoolError, id, instruction, stake_program, state}, + spl_stake_pool::{ + error::StakePoolError, find_transient_stake_program_address, id, instruction, + stake_program, state, + }, }; -async fn setup() -> ( - BanksClient, - Keypair, - Hash, - StakePoolAccounts, - ValidatorStakeAccount, -) { - let (mut banks_client, payer, recent_blockhash) = program_test().start().await; +async fn setup() -> (ProgramTestContext, StakePoolAccounts, ValidatorStakeAccount) { + let mut context = program_test().start_with_context().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 10_000_000_000) + .initialize_stake_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + 10_000_000_000, + ) .await .unwrap(); - let validator_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey()); + let validator_stake = + ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), u64::MAX); validator_stake .create_and_delegate( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &stake_pool_accounts.staker, ) .await; let error = stake_pool_accounts .add_validator_to_pool( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &validator_stake.stake_account, ) .await; assert!(error.is_none()); - ( - banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - validator_stake, - ) + (context, stake_pool_accounts, validator_stake) } #[tokio::test] async fn success() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = - setup().await; + let (mut context, stake_pool_accounts, validator_stake) = setup().await; let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts .remove_validator_from_pool( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &new_authority, &validator_stake.stake_account, &validator_stake.transient_stake_account, @@ -84,13 +79,17 @@ async fn success() { assert!(error.is_none()); let error = stake_pool_accounts - .cleanup_removed_validator_entries(&mut banks_client, &payer, &recent_blockhash) + .cleanup_removed_validator_entries( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) .await; assert!(error.is_none()); // Check if account was removed from the list of stake accounts let validator_list = get_account( - &mut banks_client, + &mut context.banks_client, &stake_pool_accounts.validator_list.pubkey(), ) .await; @@ -108,7 +107,7 @@ async fn success() { ); // Check of stake account authority has changed - let stake = get_account(&mut banks_client, &validator_stake.stake_account).await; + let stake = get_account(&mut context.banks_client, &validator_stake.stake_account).await; let stake_state = deserialize::(&stake.data).unwrap(); match stake_state { stake_program::StakeState::Stake(meta, _) => { @@ -121,8 +120,7 @@ async fn success() { #[tokio::test] async fn fail_with_wrong_stake_program_id() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = - setup().await; + let (mut context, stake_pool_accounts, validator_stake) = setup().await; let wrong_stake_program = Pubkey::new_unique(); @@ -146,9 +144,14 @@ async fn fail_with_wrong_stake_program_id() { .unwrap(), }; - let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); - transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); - let transaction_error = banks_client + let mut transaction = + Transaction::new_with_payer(&[instruction], Some(&context.payer.pubkey())); + transaction.sign( + &[&context.payer, &stake_pool_accounts.staker], + context.last_blockhash, + ); + let transaction_error = context + .banks_client .process_transaction(transaction) .await .err() @@ -167,8 +170,7 @@ async fn fail_with_wrong_stake_program_id() { #[tokio::test] async fn fail_with_wrong_validator_list_account() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = - setup().await; + let (mut context, stake_pool_accounts, validator_stake) = setup().await; let wrong_validator_list = Keypair::new(); @@ -184,10 +186,14 @@ async fn fail_with_wrong_validator_list_account() { &validator_stake.stake_account, &validator_stake.transient_stake_account, )], - Some(&payer.pubkey()), + Some(&context.payer.pubkey()), ); - transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); - let transaction_error = banks_client + transaction.sign( + &[&context.payer, &stake_pool_accounts.staker], + context.last_blockhash, + ); + let transaction_error = context + .banks_client .process_transaction(transaction) .await .err() @@ -207,13 +213,12 @@ async fn fail_with_wrong_validator_list_account() { #[tokio::test] async fn fail_not_at_minimum() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = - setup().await; + let (mut context, stake_pool_accounts, validator_stake) = setup().await; transfer( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &validator_stake.stake_account, 1_000_001, ) @@ -222,9 +227,9 @@ async fn fail_not_at_minimum() { let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts .remove_validator_from_pool( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &new_authority, &validator_stake.stake_account, &validator_stake.transient_stake_account, @@ -243,15 +248,14 @@ async fn fail_not_at_minimum() { #[tokio::test] async fn fail_double_remove() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = - setup().await; + let (mut context, stake_pool_accounts, validator_stake) = setup().await; let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts .remove_validator_from_pool( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &new_authority, &validator_stake.stake_account, &validator_stake.transient_stake_account, @@ -260,16 +264,20 @@ async fn fail_double_remove() { assert!(error.is_none()); let error = stake_pool_accounts - .cleanup_removed_validator_entries(&mut banks_client, &payer, &recent_blockhash) + .cleanup_removed_validator_entries( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) .await; assert!(error.is_none()); - let latest_blockhash = banks_client.get_recent_blockhash().await.unwrap(); + let latest_blockhash = context.banks_client.get_recent_blockhash().await.unwrap(); let transaction_error = stake_pool_accounts .remove_validator_from_pool( - &mut banks_client, - &payer, + &mut context.banks_client, + &context.payer, &latest_blockhash, &new_authority, &validator_stake.stake_account, @@ -294,8 +302,7 @@ async fn fail_double_remove() { #[tokio::test] async fn fail_wrong_staker() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = - setup().await; + let (mut context, stake_pool_accounts, validator_stake) = setup().await; let malicious = Keypair::new(); @@ -311,10 +318,11 @@ async fn fail_wrong_staker() { &validator_stake.stake_account, &validator_stake.transient_stake_account, )], - Some(&payer.pubkey()), + Some(&context.payer.pubkey()), ); - transaction.sign(&[&payer, &malicious], recent_blockhash); - let transaction_error = banks_client + transaction.sign(&[&context.payer, &malicious], context.last_blockhash); + let transaction_error = context + .banks_client .process_transaction(transaction) .await .err() @@ -336,8 +344,7 @@ async fn fail_wrong_staker() { #[tokio::test] async fn fail_no_signature() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = - setup().await; + let (mut context, stake_pool_accounts, validator_stake) = setup().await; let new_authority = Pubkey::new_unique(); @@ -362,11 +369,12 @@ async fn fail_no_signature() { let transaction = Transaction::new_signed_with_payer( &[instruction], - Some(&payer.pubkey()), - &[&payer], - recent_blockhash, + Some(&context.payer.pubkey()), + &[&context.payer], + context.last_blockhash, ); - let transaction_error = banks_client + let transaction_error = context + .banks_client .process_transaction(transaction) .await .err() @@ -386,18 +394,18 @@ async fn fail_no_signature() { #[tokio::test] async fn fail_with_activating_transient_stake() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = - setup().await; + let (mut context, stake_pool_accounts, validator_stake) = setup().await; // increase the validator stake let error = stake_pool_accounts .increase_validator_stake( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &validator_stake.transient_stake_account, &validator_stake.vote.pubkey(), 2_000_000_000, + validator_stake.transient_stake_seed, ) .await; assert!(error.is_none()); @@ -405,9 +413,9 @@ async fn fail_with_activating_transient_stake() { let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts .remove_validator_from_pool( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &new_authority, &validator_stake.stake_account, &validator_stake.transient_stake_account, @@ -429,15 +437,14 @@ async fn fail_with_activating_transient_stake() { #[tokio::test] async fn success_with_deactivating_transient_stake() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = - setup().await; + let (mut context, stake_pool_accounts, validator_stake) = setup().await; - let rent = banks_client.get_rent().await.unwrap(); + let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); let deposit_info = simple_deposit_stake( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &stake_pool_accounts, &validator_stake, TEST_STAKE_AMOUNT, @@ -448,12 +455,13 @@ async fn success_with_deactivating_transient_stake() { // increase the validator stake let error = stake_pool_accounts .decrease_validator_stake( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &validator_stake.stake_account, &validator_stake.transient_stake_account, TEST_STAKE_AMOUNT + stake_rent, + validator_stake.transient_stake_seed, ) .await; assert!(error.is_none()); @@ -461,9 +469,9 @@ async fn success_with_deactivating_transient_stake() { let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts .remove_validator_from_pool( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &new_authority, &validator_stake.stake_account, &validator_stake.transient_stake_account, @@ -473,9 +481,9 @@ async fn success_with_deactivating_transient_stake() { // fail deposit let maybe_deposit = simple_deposit_stake( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &stake_pool_accounts, &validator_stake, TEST_STAKE_AMOUNT, @@ -486,9 +494,9 @@ async fn success_with_deactivating_transient_stake() { // fail withdraw let user_stake_recipient = Keypair::new(); create_blank_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &user_stake_recipient, ) .await; @@ -496,9 +504,9 @@ async fn success_with_deactivating_transient_stake() { let user_transfer_authority = Keypair::new(); let new_authority = Pubkey::new_unique(); delegate_tokens( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &deposit_info.pool_account.pubkey(), &deposit_info.authority, &user_transfer_authority.pubkey(), @@ -507,9 +515,9 @@ async fn success_with_deactivating_transient_stake() { .await; let error = stake_pool_accounts .withdraw_stake( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &user_stake_recipient.pubkey(), &user_transfer_authority, &deposit_info.pool_account.pubkey(), @@ -522,7 +530,7 @@ async fn success_with_deactivating_transient_stake() { // check validator has changed let validator_list = get_account( - &mut banks_client, + &mut context.banks_client, &stake_pool_accounts.validator_list.pubkey(), ) .await; @@ -539,7 +547,7 @@ async fn success_with_deactivating_transient_stake() { last_update_epoch: 0, active_stake_lamports: 0, transient_stake_lamports: TEST_STAKE_AMOUNT + stake_rent, - transient_seed_suffix_start: 0, + transient_seed_suffix_start: validator_stake.transient_stake_seed, transient_seed_suffix_end: 0, }], }; @@ -548,9 +556,9 @@ async fn success_with_deactivating_transient_stake() { // Update, should not change, no merges yet let error = stake_pool_accounts .update_all( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &[validator_stake.vote.pubkey()], false, ) @@ -558,7 +566,7 @@ async fn success_with_deactivating_transient_stake() { assert!(error.is_none()); let validator_list = get_account( - &mut banks_client, + &mut context.banks_client, &stake_pool_accounts.validator_list.pubkey(), ) .await; @@ -569,23 +577,22 @@ async fn success_with_deactivating_transient_stake() { #[tokio::test] async fn success_resets_preferred_validator() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = - setup().await; + let (mut context, stake_pool_accounts, validator_stake) = setup().await; stake_pool_accounts .set_preferred_validator( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, instruction::PreferredValidatorType::Deposit, Some(validator_stake.vote.pubkey()), ) .await; stake_pool_accounts .set_preferred_validator( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, instruction::PreferredValidatorType::Withdraw, Some(validator_stake.vote.pubkey()), ) @@ -594,9 +601,9 @@ async fn success_resets_preferred_validator() { let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts .remove_validator_from_pool( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &new_authority, &validator_stake.stake_account, &validator_stake.transient_stake_account, @@ -605,13 +612,17 @@ async fn success_resets_preferred_validator() { assert!(error.is_none()); let error = stake_pool_accounts - .cleanup_removed_validator_entries(&mut banks_client, &payer, &recent_blockhash) + .cleanup_removed_validator_entries( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) .await; assert!(error.is_none()); // Check if account was removed from the list of stake accounts let validator_list = get_account( - &mut banks_client, + &mut context.banks_client, &stake_pool_accounts.validator_list.pubkey(), ) .await; @@ -629,7 +640,7 @@ async fn success_resets_preferred_validator() { ); // Check of stake account authority has changed - let stake = get_account(&mut banks_client, &validator_stake.stake_account).await; + let stake = get_account(&mut context.banks_client, &validator_stake.stake_account).await; let stake_state = deserialize::(&stake.data).unwrap(); match stake_state { stake_program::StakeState::Stake(meta, _) => { @@ -640,6 +651,173 @@ async fn success_resets_preferred_validator() { } } +#[tokio::test] +async fn success_with_hijacked_transient_account() { + let (mut context, stake_pool_accounts, validator_stake) = setup().await; + + // increase stake on validator + let error = stake_pool_accounts + .increase_validator_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &validator_stake.transient_stake_account, + &validator_stake.vote.pubkey(), + 1_000_000_000, + validator_stake.transient_stake_seed, + ) + .await; + assert!(error.is_none()); + + // warp forward to merge + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + context.warp_to_slot(slots_per_epoch * 2).unwrap(); + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &[validator_stake.vote.pubkey()], + false, + ) + .await; + + // decrease + let error = stake_pool_accounts + .decrease_validator_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &validator_stake.stake_account, + &validator_stake.transient_stake_account, + 1_000_000_000, + validator_stake.transient_stake_seed, + ) + .await; + assert!(error.is_none()); + + // warp forward to merge + context.warp_to_slot(slots_per_epoch * 4).unwrap(); + + // hijack + let validator_list = stake_pool_accounts + .get_validator_list(&mut context.banks_client) + .await; + let hijacker = Keypair::new(); + let transient_stake_address = find_transient_stake_program_address( + &id(), + &validator_stake.vote.pubkey(), + &stake_pool_accounts.stake_pool.pubkey(), + validator_stake.transient_stake_seed, + ) + .0; + let transaction = Transaction::new_signed_with_payer( + &[ + instruction::update_validator_list_balance( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), + &validator_list, + &[validator_stake.vote.pubkey()], + 0, + /* no_merge = */ false, + ), + system_instruction::transfer( + &context.payer.pubkey(), + &transient_stake_address, + 1_000_000_000, + ), + stake_program::initialize( + &transient_stake_address, + &stake_program::Authorized { + staker: hijacker.pubkey(), + withdrawer: hijacker.pubkey(), + }, + &stake_program::Lockup::default(), + ), + instruction::update_stake_pool_balance( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.pool_fee_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &spl_token::id(), + ), + instruction::cleanup_removed_validator_entries( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + ), + ], + Some(&context.payer.pubkey()), + &[&context.payer], + context.last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err(); + assert!(error.is_none()); + + // activate transient stake account + delegate_stake_account( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &transient_stake_address, + &hijacker, + &validator_stake.vote.pubkey(), + ) + .await; + + // Remove works even though transient account is activating + let new_authority = Pubkey::new_unique(); + let error = stake_pool_accounts + .remove_validator_from_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &new_authority, + &validator_stake.stake_account, + &validator_stake.transient_stake_account, + ) + .await; + assert!(error.is_none()); + + let error = stake_pool_accounts + .cleanup_removed_validator_entries( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; + assert!(error.is_none()); + + // Check if account was removed from the list of stake accounts + let validator_list = get_account( + &mut context.banks_client, + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + let validator_list = + try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); + assert_eq!( + validator_list, + state::ValidatorList { + header: state::ValidatorListHeader { + account_type: state::AccountType::ValidatorList, + max_validators: stake_pool_accounts.max_validators, + }, + validators: vec![] + } + ); +} + #[tokio::test] async fn fail_not_updated_stake_pool() {} // TODO diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index db34fe55..ae0ec591 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -530,7 +530,7 @@ async fn fail_with_unknown_validator() { ) = setup().await; let validator_stake_account = - ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey()); + ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), 111); validator_stake_account .create_and_delegate( &mut banks_client, @@ -540,7 +540,7 @@ async fn fail_with_unknown_validator() { ) .await; - let user_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey()); + let user_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), 111); user_stake .create_and_delegate( &mut banks_client, @@ -952,6 +952,7 @@ async fn success_with_reserve() { &validator_stake.stake_account, &validator_stake.transient_stake_account, deposit_lamports - 1, + validator_stake.transient_stake_seed, ) .await; assert!(error.is_none()); @@ -1029,6 +1030,7 @@ async fn success_with_reserve() { &validator_stake.stake_account, &validator_stake.transient_stake_account, stake_rent + 1, + validator_stake.transient_stake_seed, ) .await; assert!(error.is_none()); @@ -1329,6 +1331,7 @@ async fn success_withdraw_from_transient() { &validator_stake.stake_account, &validator_stake.transient_stake_account, stake_rent + 1, + validator_stake.transient_stake_seed, ) .await; assert!(error.is_none()); @@ -1397,6 +1400,7 @@ async fn success_withdraw_from_transient() { &validator_stake.stake_account, &validator_stake.transient_stake_account, deposit_lamports - 1, + validator_stake.transient_stake_seed, ) .await; assert!(error.is_none()); From 8b3632e624316e2531b6b1cf4fff1fb749c3ec7f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Aug 2021 11:29:51 +0000 Subject: [PATCH 0160/1076] build(deps): bump serde from 1.0.127 to 1.0.128 (#2318) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.127 to 1.0.128. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.127...v1.0.128) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index b32192f1..e85ca00e 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,7 +17,7 @@ borsh = "0.9" num-derive = "0.3" num-traits = "0.2" num_enum = "0.5.4" -serde = "1.0.127" +serde = "1.0.128" serde_derive = "1.0.103" solana-program = "1.7.7" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } From ab80a511db696534e0ee67b8b71a7e5d47639581 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Aug 2021 11:17:42 +0000 Subject: [PATCH 0161/1076] build(deps): bump serde from 1.0.128 to 1.0.129 (#2322) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.128 to 1.0.129. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.128...v1.0.129) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index e85ca00e..5a137929 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,7 +17,7 @@ borsh = "0.9" num-derive = "0.3" num-traits = "0.2" num_enum = "0.5.4" -serde = "1.0.128" +serde = "1.0.129" serde_derive = "1.0.103" solana-program = "1.7.7" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } From fc30e4dea0e0382e16fbc49700369166bf9cf967 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Aug 2021 11:32:19 +0000 Subject: [PATCH 0162/1076] build(deps): bump serde_json from 1.0.66 to 1.0.67 (#2351) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.66 to 1.0.67. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.66...v1.0.67) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 6bd750a5..846d3f1d 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "0.4.0" [dependencies] borsh = "0.9" clap = "2.33.3" -serde_json = "1.0.66" +serde_json = "1.0.67" solana-account-decoder = "=1.7.7" solana-clap-utils = "=1.7.7" solana-cli-config = "=1.7.7" From e92626f2f44a1d8b4efdd8283be03c2a0a711fda Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Mon, 30 Aug 2021 12:20:33 -0700 Subject: [PATCH 0163/1076] Upgrade to Solana 1.7.11 --- clients/cli/Cargo.toml | 16 ++++++++-------- program/Cargo.toml | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 846d3f1d..ce98303c 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -12,14 +12,14 @@ version = "0.4.0" borsh = "0.9" clap = "2.33.3" serde_json = "1.0.67" -solana-account-decoder = "=1.7.7" -solana-clap-utils = "=1.7.7" -solana-cli-config = "=1.7.7" -solana-client = "=1.7.7" -solana-logger = "=1.7.7" -solana-program = "=1.7.7" -solana-remote-wallet = "=1.7.7" -solana-sdk = "=1.7.7" +solana-account-decoder = "=1.7.11" +solana-clap-utils = "=1.7.11" +solana-cli-config = "=1.7.11" +solana-client = "=1.7.11" +solana-logger = "=1.7.11" +solana-program = "=1.7.11" +solana-remote-wallet = "=1.7.11" +solana-sdk = "=1.7.11" spl-associated-token-account = { version = "1.0", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "0.4", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "3.2", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/program/Cargo.toml b/program/Cargo.toml index 5a137929..664082b7 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -19,7 +19,7 @@ num-traits = "0.2" num_enum = "0.5.4" serde = "1.0.129" serde_derive = "1.0.103" -solana-program = "1.7.7" +solana-program = "1.7.11" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-token = { version = "3.2", path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" @@ -27,9 +27,9 @@ bincode = "1.3.1" [dev-dependencies] proptest = "1.0" -solana-program-test = "1.7.7" -solana-sdk = "1.7.7" -solana-vote-program = "1.7.7" +solana-program-test = "1.7.11" +solana-sdk = "1.7.11" +solana-vote-program = "1.7.11" [lib] crate-type = ["cdylib", "lib"] From 41a833ea0fe90f3ec4eef3bb1ebd0d9605854f49 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Aug 2021 11:13:17 +0000 Subject: [PATCH 0164/1076] build(deps): bump serde from 1.0.129 to 1.0.130 (#2361) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.129 to 1.0.130. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.129...v1.0.130) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 664082b7..6a0ee5e8 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,7 +17,7 @@ borsh = "0.9" num-derive = "0.3" num-traits = "0.2" num_enum = "0.5.4" -serde = "1.0.129" +serde = "1.0.130" serde_derive = "1.0.103" solana-program = "1.7.11" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } From 09d47e8b4a6eebbb6815eb5e55819607c365d116 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 2 Sep 2021 01:38:16 +0200 Subject: [PATCH 0165/1076] stake-pool: Split from stake account during removal (#2367) If the stake pool gives over the validator stake account to the staker, they may keep it and make it impossible to re-add that validator in the future. Split the whole amount into a new stake account on removal. --- clients/cli/src/main.rs | 93 ++++++++++---- program/src/instruction.rs | 9 +- program/src/processor.rs | 14 ++- program/tests/helpers/mod.rs | 33 +++-- program/tests/huge_pool.rs | 6 + program/tests/set_preferred.rs | 2 + .../tests/update_validator_list_balance.rs | 8 +- program/tests/vsa_remove.rs | 117 +++++++++++------- 8 files changed, 200 insertions(+), 82 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index b5c20f8a..8b2b3e0a 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -152,6 +152,33 @@ fn checked_transaction_with_signers( Ok(transaction) } +fn new_stake_account( + fee_payer: &Pubkey, + instructions: &mut Vec, + lamports: u64, +) -> Keypair { + // Account for tokens not specified, creating one + let stake_receiver_keypair = Keypair::new(); + let stake_receiver_pubkey = stake_receiver_keypair.pubkey(); + println!( + "Creating account to receive stake {}", + stake_receiver_pubkey + ); + + instructions.push( + // Creating new account + system_instruction::create_account( + fee_payer, + &stake_receiver_pubkey, + lamports, + STAKE_STATE_LEN as u64, + &stake_program::id(), + ), + ); + + stake_receiver_keypair +} + #[allow(clippy::too_many_arguments)] fn command_create_pool( config: &Config, @@ -423,6 +450,7 @@ fn command_vsa_remove( stake_pool_address: &Pubkey, vote_account: &Pubkey, new_authority: &Option, + stake_receiver: &Option, ) -> CommandResult { if !config.no_update { command_update(config, stake_pool_address, false, false)?; @@ -437,6 +465,20 @@ fn command_vsa_remove( let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; + let mut instructions = vec![]; + let mut stake_keypair = None; + + let stake_receiver = stake_receiver.unwrap_or_else(|| { + let new_stake_keypair = new_stake_account( + &config.fee_payer.pubkey(), + &mut instructions, + /* stake_receiver_account_balance = */ 0, + ); + let stake_pubkey = new_stake_keypair.pubkey(); + stake_keypair = Some(new_stake_keypair); + stake_pubkey + }); + let staker_pubkey = config.staker.pubkey(); let new_authority = new_authority.as_ref().unwrap_or(&staker_pubkey); @@ -446,6 +488,9 @@ fn command_vsa_remove( .ok_or("Vote account not found in validator list")?; let mut signers = vec![config.fee_payer.as_ref(), config.staker.as_ref()]; + if let Some(stake_keypair) = stake_keypair.as_ref() { + signers.push(stake_keypair); + } unique_signers!(signers); let transaction = checked_transaction_with_signers( config, @@ -458,6 +503,7 @@ fn command_vsa_remove( vote_account, new_authority, validator_stake_info.transient_seed_suffix_start, + &stake_receiver, ), ], &signers, @@ -1270,33 +1316,19 @@ fn command_withdraw( // Use separate mutable variable because withdraw might create a new account let stake_receiver = stake_receiver_param.unwrap_or_else(|| { - // Account for tokens not specified, creating one - let stake_receiver_account = Keypair::new(); // Will be added to signers if creating new account - let stake_receiver_pubkey = stake_receiver_account.pubkey(); - println!( - "Creating account to receive stake {}", - stake_receiver_pubkey - ); - let stake_receiver_account_balance = config .rpc_client .get_minimum_balance_for_rent_exemption(STAKE_STATE_LEN) .unwrap(); - - instructions.push( - // Creating new account - system_instruction::create_account( - &config.fee_payer.pubkey(), - &stake_receiver_pubkey, - stake_receiver_account_balance, - STAKE_STATE_LEN as u64, - &stake_program::id(), - ), + let stake_keypair = new_stake_account( + &config.fee_payer.pubkey(), + &mut instructions, + stake_receiver_account_balance, ); - + let stake_pubkey = stake_keypair.pubkey(); total_rent_free_balances += stake_receiver_account_balance; - new_stake_keypairs.push(stake_receiver_account); - stake_receiver_pubkey + new_stake_keypairs.push(stake_keypair); + stake_pubkey }); instructions.push(spl_stake_pool::instruction::withdraw_stake( @@ -1753,6 +1785,14 @@ fn main() { .help("New authority to set as Staker and Withdrawer in the stake account removed from the pool. Defaults to the client keypair."), ) + .arg( + Arg::with_name("stake_receiver") + .long("stake-receiver") + .validator(is_pubkey) + .value_name("ADDRESS") + .takes_value(true) + .help("Stake account to receive SOL from the stake pool. Defaults to a new stake account."), + ) ) .subcommand(SubCommand::with_name("increase-validator-stake") .about("Increase stake to a validator, drawing from the stake pool reserve. Must be signed by the pool staker.") @@ -2318,8 +2358,15 @@ fn main() { ("remove-validator", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); let vote_account = pubkey_of(arg_matches, "vote_account").unwrap(); - let new_authority: Option = pubkey_of(arg_matches, "new_authority"); - command_vsa_remove(&config, &stake_pool_address, &vote_account, &new_authority) + let new_authority = pubkey_of(arg_matches, "new_authority"); + let stake_receiver = pubkey_of(arg_matches, "stake_receiver"); + command_vsa_remove( + &config, + &stake_pool_address, + &vote_account, + &new_authority, + &stake_receiver, + ) } ("increase-validator-stake", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 3b7ce1e6..ca5c6bf8 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -127,8 +127,9 @@ pub enum StakePoolInstruction { /// 4. `[w]` Validator stake list storage account /// 5. `[w]` Stake account to remove from the pool /// 6. `[]` Transient stake account, to check that that we're not trying to activate - /// 7. '[]' Sysvar clock - /// 8. `[]` Stake program id, + /// 7. `[w]` Destination stake account, to receive the minimum SOL from the validator stake account. Must be + /// 8. `[]` Sysvar clock + /// 9. `[]` Stake program id, RemoveValidatorFromPool, /// (Staker only) Decrease active stake on a validator, eventually moving it to the reserve @@ -483,6 +484,7 @@ pub fn remove_validator_from_pool( validator_list: &Pubkey, stake_account: &Pubkey, transient_stake_account: &Pubkey, + destination_stake_account: &Pubkey, ) -> Instruction { let accounts = vec![ AccountMeta::new(*stake_pool, false), @@ -492,6 +494,7 @@ pub fn remove_validator_from_pool( AccountMeta::new(*validator_list, false), AccountMeta::new(*stake_account, false), AccountMeta::new_readonly(*transient_stake_account, false), + AccountMeta::new(*destination_stake_account, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(stake_program::id(), false), ]; @@ -658,6 +661,7 @@ pub fn remove_validator_from_pool_with_vote( vote_account_address: &Pubkey, new_stake_account_authority: &Pubkey, transient_stake_seed: u64, + destination_stake_address: &Pubkey, ) -> Instruction { let pool_withdraw_authority = find_withdraw_authority_program_address(program_id, stake_pool_address).0; @@ -678,6 +682,7 @@ pub fn remove_validator_from_pool_with_vote( &stake_pool.validator_list, &stake_account_address, &transient_stake_account, + destination_stake_address, ) } diff --git a/program/src/processor.rs b/program/src/processor.rs index 26617f91..4c7e0515 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -886,6 +886,7 @@ impl Processor { let validator_list_info = next_account_info(account_info_iter)?; let stake_account_info = next_account_info(account_info_iter)?; let transient_stake_account_info = next_account_info(account_info_iter)?; + let destination_stake_account_info = next_account_info(account_info_iter)?; let clock_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(clock_info)?; let stake_program_info = next_account_info(account_info_iter)?; @@ -994,12 +995,23 @@ impl Processor { StakeStatus::ReadyForRemoval }; - Self::stake_authorize_signed( + // split whole thing into destination stake account + Self::stake_split( stake_pool_info.key, stake_account_info.clone(), withdraw_authority_info.clone(), AUTHORITY_WITHDRAW, stake_pool.stake_withdraw_bump_seed, + stake_account_info.lamports(), + destination_stake_account_info.clone(), + )?; + + Self::stake_authorize_signed( + stake_pool_info.key, + destination_stake_account_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, new_stake_authority_info.key, clock_info.clone(), stake_program_info.clone(), diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 4cd4e74b..69c4dadb 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -1093,20 +1093,31 @@ impl StakePoolAccounts { new_authority: &Pubkey, validator_stake: &Pubkey, transient_stake: &Pubkey, + destination_stake: &Keypair, ) -> Option { let transaction = Transaction::new_signed_with_payer( - &[instruction::remove_validator_from_pool( - &id(), - &self.stake_pool.pubkey(), - &self.staker.pubkey(), - &self.withdraw_authority, - &new_authority, - &self.validator_list.pubkey(), - validator_stake, - transient_stake, - )], + &[ + system_instruction::create_account( + &payer.pubkey(), + &destination_stake.pubkey(), + 0, + std::mem::size_of::() as u64, + &stake_program::id(), + ), + instruction::remove_validator_from_pool( + &id(), + &self.stake_pool.pubkey(), + &self.staker.pubkey(), + &self.withdraw_authority, + &new_authority, + &self.validator_list.pubkey(), + validator_stake, + transient_stake, + &destination_stake.pubkey(), + ), + ], Some(&payer.pubkey()), - &[payer, &self.staker], + &[payer, &self.staker, destination_stake], *recent_blockhash, ); banks_client.process_transaction(transaction).await.err() diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index 81498d1a..35892657 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -404,6 +404,7 @@ async fn remove_validator_from_pool() { ); let new_authority = Pubkey::new_unique(); + let destination_stake = Keypair::new(); let error = stake_pool_accounts .remove_validator_from_pool( &mut context.banks_client, @@ -412,6 +413,7 @@ async fn remove_validator_from_pool() { &new_authority, &stake_address, &transient_stake_address, + &destination_stake, ) .await; assert!(error.is_none()); @@ -431,6 +433,7 @@ async fn remove_validator_from_pool() { ); let new_authority = Pubkey::new_unique(); + let destination_stake = Keypair::new(); let error = stake_pool_accounts .remove_validator_from_pool( &mut context.banks_client, @@ -439,6 +442,7 @@ async fn remove_validator_from_pool() { &new_authority, &stake_address, &transient_stake_address, + &destination_stake, ) .await; assert!(error.is_none()); @@ -455,6 +459,7 @@ async fn remove_validator_from_pool() { ); let new_authority = Pubkey::new_unique(); + let destination_stake = Keypair::new(); let error = stake_pool_accounts .remove_validator_from_pool( &mut context.banks_client, @@ -463,6 +468,7 @@ async fn remove_validator_from_pool() { &new_authority, &stake_address, &transient_stake_address, + &destination_stake, ) .await; assert!(error.is_none()); diff --git a/program/tests/set_preferred.rs b/program/tests/set_preferred.rs index 23b47ef6..04184f2d 100644 --- a/program/tests/set_preferred.rs +++ b/program/tests/set_preferred.rs @@ -223,6 +223,7 @@ async fn fail_ready_for_removal() { transient_stake_seed, ); let new_authority = Pubkey::new_unique(); + let destination_stake = Keypair::new(); let remove_err = stake_pool_accounts .remove_validator_from_pool( &mut banks_client, @@ -231,6 +232,7 @@ async fn fail_ready_for_removal() { &new_authority, &validator_stake_account.stake_account, &transient_stake_address, + &destination_stake, ) .await; assert!(remove_err.is_none()); diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index 73021ffb..9c3041da 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -6,7 +6,11 @@ use { helpers::*, solana_program::{borsh::try_from_slice_unchecked, program_pack::Pack, pubkey::Pubkey}, solana_program_test::*, - solana_sdk::{signature::Signer, system_instruction, transaction::Transaction}, + solana_sdk::{ + signature::{Keypair, Signer}, + system_instruction, + transaction::Transaction, + }, spl_stake_pool::{ find_transient_stake_program_address, id, instruction, stake_program, state::{StakePool, StakeStatus, ValidatorList}, @@ -462,6 +466,7 @@ async fn merge_transient_stake_after_remove() { let stake_rent = rent.minimum_balance(std::mem::size_of::()); let deactivated_lamports = lamports; let new_authority = Pubkey::new_unique(); + let destination_stake = Keypair::new(); // Decrease and remove all validators for stake_account in &stake_accounts { let error = stake_pool_accounts @@ -484,6 +489,7 @@ async fn merge_transient_stake_after_remove() { &new_authority, &stake_account.stake_account, &stake_account.transient_stake_account, + &destination_stake, ) .await; assert!(error.is_none()); diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index c60d0098..2be7adc3 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -24,7 +24,13 @@ use { }, }; -async fn setup() -> (ProgramTestContext, StakePoolAccounts, ValidatorStakeAccount) { +async fn setup() -> ( + ProgramTestContext, + StakePoolAccounts, + ValidatorStakeAccount, + Pubkey, + Keypair, +) { let mut context = program_test().start_with_context().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts @@ -58,14 +64,23 @@ async fn setup() -> (ProgramTestContext, StakePoolAccounts, ValidatorStakeAccoun .await; assert!(error.is_none()); - (context, stake_pool_accounts, validator_stake) + let new_authority = Pubkey::new_unique(); + let destination_stake = Keypair::new(); + + ( + context, + stake_pool_accounts, + validator_stake, + new_authority, + destination_stake, + ) } #[tokio::test] async fn success() { - let (mut context, stake_pool_accounts, validator_stake) = setup().await; + let (mut context, stake_pool_accounts, validator_stake, new_authority, destination_stake) = + setup().await; - let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts .remove_validator_from_pool( &mut context.banks_client, @@ -74,6 +89,7 @@ async fn success() { &new_authority, &validator_stake.stake_account, &validator_stake.transient_stake_account, + &destination_stake, ) .await; assert!(error.is_none()); @@ -106,8 +122,14 @@ async fn success() { } ); - // Check of stake account authority has changed - let stake = get_account(&mut context.banks_client, &validator_stake.stake_account).await; + // Check stake account no longer exists + let account = context + .banks_client + .get_account(validator_stake.stake_account) + .await + .unwrap(); + assert!(account.is_none()); + let stake = get_account(&mut context.banks_client, &destination_stake.pubkey()).await; let stake_state = deserialize::(&stake.data).unwrap(); match stake_state { stake_program::StakeState::Stake(meta, _) => { @@ -120,11 +142,11 @@ async fn success() { #[tokio::test] async fn fail_with_wrong_stake_program_id() { - let (mut context, stake_pool_accounts, validator_stake) = setup().await; + let (mut context, stake_pool_accounts, validator_stake, new_authority, destination_stake) = + setup().await; let wrong_stake_program = Pubkey::new_unique(); - let new_authority = Pubkey::new_unique(); let accounts = vec![ AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), AccountMeta::new_readonly(stake_pool_accounts.staker.pubkey(), true), @@ -133,6 +155,7 @@ async fn fail_with_wrong_stake_program_id() { AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false), AccountMeta::new(validator_stake.stake_account, false), AccountMeta::new_readonly(validator_stake.transient_stake_account, false), + AccountMeta::new(destination_stake.pubkey(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(wrong_stake_program, false), ]; @@ -170,11 +193,11 @@ async fn fail_with_wrong_stake_program_id() { #[tokio::test] async fn fail_with_wrong_validator_list_account() { - let (mut context, stake_pool_accounts, validator_stake) = setup().await; + let (mut context, stake_pool_accounts, validator_stake, new_authority, destination_stake) = + setup().await; let wrong_validator_list = Keypair::new(); - let new_authority = Pubkey::new_unique(); let mut transaction = Transaction::new_with_payer( &[instruction::remove_validator_from_pool( &id(), @@ -185,6 +208,7 @@ async fn fail_with_wrong_validator_list_account() { &wrong_validator_list.pubkey(), &validator_stake.stake_account, &validator_stake.transient_stake_account, + &destination_stake.pubkey(), )], Some(&context.payer.pubkey()), ); @@ -213,7 +237,8 @@ async fn fail_with_wrong_validator_list_account() { #[tokio::test] async fn fail_not_at_minimum() { - let (mut context, stake_pool_accounts, validator_stake) = setup().await; + let (mut context, stake_pool_accounts, validator_stake, new_authority, destination_stake) = + setup().await; transfer( &mut context.banks_client, @@ -224,7 +249,6 @@ async fn fail_not_at_minimum() { ) .await; - let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts .remove_validator_from_pool( &mut context.banks_client, @@ -233,6 +257,7 @@ async fn fail_not_at_minimum() { &new_authority, &validator_stake.stake_account, &validator_stake.transient_stake_account, + &destination_stake, ) .await .unwrap() @@ -240,7 +265,7 @@ async fn fail_not_at_minimum() { assert_eq!( error, TransactionError::InstructionError( - 0, + 1, InstructionError::Custom(StakePoolError::StakeLamportsNotEqualToMinimum as u32) ), ); @@ -248,9 +273,9 @@ async fn fail_not_at_minimum() { #[tokio::test] async fn fail_double_remove() { - let (mut context, stake_pool_accounts, validator_stake) = setup().await; + let (mut context, stake_pool_accounts, validator_stake, new_authority, destination_stake) = + setup().await; - let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts .remove_validator_from_pool( &mut context.banks_client, @@ -259,6 +284,7 @@ async fn fail_double_remove() { &new_authority, &validator_stake.stake_account, &validator_stake.transient_stake_account, + &destination_stake, ) .await; assert!(error.is_none()); @@ -272,41 +298,39 @@ async fn fail_double_remove() { .await; assert!(error.is_none()); - let latest_blockhash = context.banks_client.get_recent_blockhash().await.unwrap(); + let _latest_blockhash = context.banks_client.get_recent_blockhash().await.unwrap(); - let transaction_error = stake_pool_accounts + let destination_stake = Keypair::new(); + let error = stake_pool_accounts .remove_validator_from_pool( &mut context.banks_client, &context.payer, - &latest_blockhash, + &context.last_blockhash, &new_authority, &validator_stake.stake_account, &validator_stake.transient_stake_account, + &destination_stake, ) .await + .unwrap() .unwrap(); - match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError( - _, - InstructionError::Custom(error_index), - )) => { - let program_error = StakePoolError::ValidatorNotFound as u32; - assert_eq!(error_index, program_error); - } - _ => { - panic!("Wrong error occurs while try to remove already removed validator stake address") - } - } + assert_eq!( + error, + TransactionError::InstructionError( + 1, + InstructionError::BorshIoError("Unkown".to_string()), // sic + ) + ); } #[tokio::test] async fn fail_wrong_staker() { - let (mut context, stake_pool_accounts, validator_stake) = setup().await; + let (mut context, stake_pool_accounts, validator_stake, new_authority, destination_stake) = + setup().await; let malicious = Keypair::new(); - let new_authority = Pubkey::new_unique(); let mut transaction = Transaction::new_with_payer( &[instruction::remove_validator_from_pool( &id(), @@ -317,6 +341,7 @@ async fn fail_wrong_staker() { &stake_pool_accounts.validator_list.pubkey(), &validator_stake.stake_account, &validator_stake.transient_stake_account, + &destination_stake.pubkey(), )], Some(&context.payer.pubkey()), ); @@ -344,9 +369,8 @@ async fn fail_wrong_staker() { #[tokio::test] async fn fail_no_signature() { - let (mut context, stake_pool_accounts, validator_stake) = setup().await; - - let new_authority = Pubkey::new_unique(); + let (mut context, stake_pool_accounts, validator_stake, new_authority, destination_stake) = + setup().await; let accounts = vec![ AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), @@ -356,6 +380,7 @@ async fn fail_no_signature() { AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false), AccountMeta::new(validator_stake.stake_account, false), AccountMeta::new_readonly(validator_stake.transient_stake_account, false), + AccountMeta::new(destination_stake.pubkey(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(stake_program::id(), false), ]; @@ -394,7 +419,8 @@ async fn fail_no_signature() { #[tokio::test] async fn fail_with_activating_transient_stake() { - let (mut context, stake_pool_accounts, validator_stake) = setup().await; + let (mut context, stake_pool_accounts, validator_stake, new_authority, destination_stake) = + setup().await; // increase the validator stake let error = stake_pool_accounts @@ -410,7 +436,6 @@ async fn fail_with_activating_transient_stake() { .await; assert!(error.is_none()); - let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts .remove_validator_from_pool( &mut context.banks_client, @@ -419,6 +444,7 @@ async fn fail_with_activating_transient_stake() { &new_authority, &validator_stake.stake_account, &validator_stake.transient_stake_account, + &destination_stake, ) .await .unwrap() @@ -437,7 +463,8 @@ async fn fail_with_activating_transient_stake() { #[tokio::test] async fn success_with_deactivating_transient_stake() { - let (mut context, stake_pool_accounts, validator_stake) = setup().await; + let (mut context, stake_pool_accounts, validator_stake, new_authority, destination_stake) = + setup().await; let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); @@ -466,7 +493,6 @@ async fn success_with_deactivating_transient_stake() { .await; assert!(error.is_none()); - let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts .remove_validator_from_pool( &mut context.banks_client, @@ -475,6 +501,7 @@ async fn success_with_deactivating_transient_stake() { &new_authority, &validator_stake.stake_account, &validator_stake.transient_stake_account, + &destination_stake, ) .await; assert!(error.is_none()); @@ -577,7 +604,8 @@ async fn success_with_deactivating_transient_stake() { #[tokio::test] async fn success_resets_preferred_validator() { - let (mut context, stake_pool_accounts, validator_stake) = setup().await; + let (mut context, stake_pool_accounts, validator_stake, new_authority, destination_stake) = + setup().await; stake_pool_accounts .set_preferred_validator( @@ -598,7 +626,6 @@ async fn success_resets_preferred_validator() { ) .await; - let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts .remove_validator_from_pool( &mut context.banks_client, @@ -607,6 +634,7 @@ async fn success_resets_preferred_validator() { &new_authority, &validator_stake.stake_account, &validator_stake.transient_stake_account, + &destination_stake, ) .await; assert!(error.is_none()); @@ -640,7 +668,7 @@ async fn success_resets_preferred_validator() { ); // Check of stake account authority has changed - let stake = get_account(&mut context.banks_client, &validator_stake.stake_account).await; + let stake = get_account(&mut context.banks_client, &destination_stake.pubkey()).await; let stake_state = deserialize::(&stake.data).unwrap(); match stake_state { stake_program::StakeState::Stake(meta, _) => { @@ -653,7 +681,8 @@ async fn success_resets_preferred_validator() { #[tokio::test] async fn success_with_hijacked_transient_account() { - let (mut context, stake_pool_accounts, validator_stake) = setup().await; + let (mut context, stake_pool_accounts, validator_stake, new_authority, destination_stake) = + setup().await; // increase stake on validator let error = stake_pool_accounts @@ -776,7 +805,6 @@ async fn success_with_hijacked_transient_account() { .await; // Remove works even though transient account is activating - let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts .remove_validator_from_pool( &mut context.banks_client, @@ -785,6 +813,7 @@ async fn success_with_hijacked_transient_account() { &new_authority, &validator_stake.stake_account, &validator_stake.transient_stake_account, + &destination_stake, ) .await; assert!(error.is_none()); From 752b4dbac764cdb12fe2bdf0060758478d62a646 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 3 Sep 2021 00:54:51 +0200 Subject: [PATCH 0166/1076] stake-pool: Combine create stake and add validator (#2371) --- clients/cli/scripts/setup-stake-pool.sh | 11 - clients/cli/src/main.rs | 71 +--- program/src/instruction.rs | 107 ++---- program/src/processor.rs | 194 ++++------ program/tests/decrease.rs | 30 +- program/tests/deposit.rs | 62 ++-- program/tests/helpers/mod.rs | 118 +++---- program/tests/huge_pool.rs | 12 +- program/tests/increase.rs | 30 +- .../tests/update_validator_list_balance.rs | 35 +- program/tests/vsa_add.rs | 331 +++++++++--------- program/tests/vsa_create.rs | 264 -------------- program/tests/vsa_remove.rs | 17 +- program/tests/withdraw.rs | 100 +----- 14 files changed, 408 insertions(+), 974 deletions(-) delete mode 100644 program/tests/vsa_create.rs diff --git a/clients/cli/scripts/setup-stake-pool.sh b/clients/cli/scripts/setup-stake-pool.sh index 5a9fe3ad..ba2b5e64 100755 --- a/clients/cli/scripts/setup-stake-pool.sh +++ b/clients/cli/scripts/setup-stake-pool.sh @@ -37,15 +37,6 @@ setup_pool () { --mint-keypair $mint_keyfile } -create_validator_stakes() { - pool=$1 - validator_list=$2 - for validator in $(cat $validator_list) - do - $spl_stake_pool create-validator-stake $pool $validator - done -} - add_validator_stakes () { pool=$1 validator_list=$2 @@ -65,7 +56,5 @@ setup_pool $max_validators $stake_pool_keyfile $mint_keyfile stake_pool_pubkey=$(solana-keygen pubkey $stake_pool_keyfile) -echo "Creating validator stake accounts" -create_validator_stakes $stake_pool_pubkey $validator_list echo "Adding validator stake accounts to the pool" add_validator_stakes $stake_pool_pubkey $validator_list diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 8b2b3e0a..d0f85081 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -357,36 +357,6 @@ fn command_create_pool( Ok(()) } -fn command_vsa_create( - config: &Config, - stake_pool_address: &Pubkey, - vote_account: &Pubkey, -) -> CommandResult { - let (stake_account, _) = - find_stake_program_address(&spl_stake_pool::id(), vote_account, stake_pool_address); - println!( - "Creating stake account {}, delegated to {}", - stake_account, vote_account - ); - let transaction = checked_transaction_with_signers( - config, - &[ - // Create new validator stake account address - spl_stake_pool::instruction::create_validator_stake_account( - &spl_stake_pool::id(), - stake_pool_address, - &config.staker.pubkey(), - &config.fee_payer.pubkey(), - &stake_account, - vote_account, - ), - ], - &[config.fee_payer.as_ref(), config.staker.as_ref()], - )?; - send_transaction(config, transaction)?; - Ok(()) -} - fn command_vsa_add( config: &Config, stake_pool_address: &Pubkey, @@ -408,20 +378,6 @@ fn command_vsa_add( return Ok(()); } - let stake_state = get_stake_state(&config.rpc_client, &stake_account_address)?; - if let stake_program::StakeState::Stake(meta, _stake) = stake_state { - if meta.authorized.withdrawer != config.staker.pubkey() { - let error = format!( - "Stake account withdraw authority must be the staker {}, actual {}", - config.staker.pubkey(), - meta.authorized.withdrawer - ); - return Err(error.into()); - } - } else { - return Err("Stake account is not active.".into()); - } - if !config.no_update { command_update(config, stake_pool_address, false, false)?; } @@ -435,6 +391,7 @@ fn command_vsa_add( &spl_stake_pool::id(), &stake_pool, stake_pool_address, + &config.fee_payer.pubkey(), vote_account, ), ], @@ -1714,27 +1671,6 @@ fn main() { .help("Stake pool reserve keypair [default: new keypair]"), ) ) - .subcommand(SubCommand::with_name("create-validator-stake") - .about("Create a new stake account to use with the pool. Must be signed by the pool staker.") - .arg( - Arg::with_name("pool") - .index(1) - .validator(is_pubkey) - .value_name("POOL_ADDRESS") - .takes_value(true) - .required(true) - .help("Stake pool address"), - ) - .arg( - Arg::with_name("vote_account") - .index(2) - .validator(is_pubkey) - .value_name("VOTE_ACCOUNT_ADDRESS") - .takes_value(true) - .required(true) - .help("The validator vote account that this stake will be delegated to"), - ) - ) .subcommand(SubCommand::with_name("add-validator") .about("Add validator account to the stake pool. Must be signed by the pool staker.") .arg( @@ -2345,11 +2281,6 @@ fn main() { reserve_keypair, ) } - ("create-validator-stake", Some(arg_matches)) => { - let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); - let vote_account_address = pubkey_of(arg_matches, "vote_account").unwrap(); - command_vsa_create(&config, &stake_pool_address, &vote_account_address) - } ("add-validator", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); let vote_account_address = pubkey_of(arg_matches, "vote_account").unwrap(); diff --git a/program/src/instruction.rs b/program/src/instruction.rs index ca5c6bf8..2cd62b19 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -77,42 +77,24 @@ pub enum StakePoolInstruction { max_validators: u32, }, - /// (Staker only) Creates new program account for accumulating stakes for - /// a particular validator - /// - /// 0. `[]` Stake pool account this stake will belong to - /// 1. `[s]` Staker - /// 2. `[ws]` Funding account (must be a system account) - /// 3. `[w]` Stake account to be created - /// 4. `[]` Validator this stake account will vote for - /// 5. `[]` Rent sysvar - /// 6. `[]` Stake History sysvar - /// 7. `[]` Stake Config sysvar - /// 8. `[]` System program - /// 9. `[]` Stake program - CreateValidatorStakeAccount, - /// (Staker only) Adds stake account delegated to validator to the pool's /// list of managed validators. /// - /// The stake account must have the rent-exempt amount plus at least 1 SOL, - /// and at most 1.001 SOL. - /// - /// Once we delegate even 1 SOL, it will accrue rewards one epoch later, - /// so we'll have more than 1 active SOL at this point. - /// At 10% annualized rewards, 1 epoch of 2 days will accrue - /// 0.000547945 SOL, so we check that it is at least 1 SOL, and at most - /// 1.001 SOL. + /// The stake account will have the rent-exempt amount plus 1 SOL. /// /// 0. `[w]` Stake pool /// 1. `[s]` Staker - /// 2. `[]` Stake pool withdraw authority - /// 3. `[w]` Validator stake list storage account - /// 4. `[w]` Stake account to add to the pool, its withdraw authority must - /// be set to the staker - /// 5. `[]` Clock sysvar - /// 6. '[]' Sysvar stake history account - /// 7. `[]` Stake program + /// 2. `[ws]` Funding account (must be a system account) + /// 3. `[]` Stake pool withdraw authority + /// 4. `[w]` Validator stake list storage account + /// 5. `[w]` Stake account to add to the pool + /// 6. `[]` Validator this stake account will be delegated to + /// 7. `[]` Rent sysvar + /// 8. `[]` Clock sysvar + /// 9. '[]' Stake history sysvar + /// 10. '[]' Stake config sysvar + /// 11. `[]` System program + /// 12. `[]` Stake program AddValidatorToPool, /// (Staker only) Removes validator from the pool @@ -415,54 +397,30 @@ pub fn initialize( } } -/// Creates `CreateValidatorStakeAccount` instruction (create new stake account for the validator) -pub fn create_validator_stake_account( - program_id: &Pubkey, - stake_pool: &Pubkey, - staker: &Pubkey, - funder: &Pubkey, - stake_account: &Pubkey, - validator: &Pubkey, -) -> Instruction { - let accounts = vec![ - AccountMeta::new_readonly(*stake_pool, false), - AccountMeta::new_readonly(*staker, true), - AccountMeta::new(*funder, true), - AccountMeta::new(*stake_account, false), - AccountMeta::new_readonly(*validator, false), - AccountMeta::new_readonly(sysvar::rent::id(), false), - AccountMeta::new_readonly(sysvar::clock::id(), false), - AccountMeta::new_readonly(sysvar::stake_history::id(), false), - AccountMeta::new_readonly(stake_program::config_id(), false), - AccountMeta::new_readonly(system_program::id(), false), - AccountMeta::new_readonly(stake_program::id(), false), - ]; - Instruction { - program_id: *program_id, - accounts, - data: StakePoolInstruction::CreateValidatorStakeAccount - .try_to_vec() - .unwrap(), - } -} - /// Creates `AddValidatorToPool` instruction (add new validator stake account to the pool) pub fn add_validator_to_pool( program_id: &Pubkey, stake_pool: &Pubkey, staker: &Pubkey, + funder: &Pubkey, stake_pool_withdraw: &Pubkey, validator_list: &Pubkey, - stake_account: &Pubkey, + stake: &Pubkey, + validator: &Pubkey, ) -> Instruction { let accounts = vec![ AccountMeta::new(*stake_pool, false), AccountMeta::new_readonly(*staker, true), + AccountMeta::new(*funder, true), AccountMeta::new_readonly(*stake_pool_withdraw, false), AccountMeta::new(*validator_list, false), - AccountMeta::new(*stake_account, false), + AccountMeta::new(*stake, false), + AccountMeta::new_readonly(*validator, false), + AccountMeta::new_readonly(sysvar::rent::id(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), + AccountMeta::new_readonly(stake_program::config_id(), false), + AccountMeta::new_readonly(system_program::id(), false), AccountMeta::new_readonly(stake_program::id(), false), ]; Instruction { @@ -610,32 +568,13 @@ pub fn set_preferred_validator( } } -/// Creates `CreateValidatorStakeAccount` instruction with a vote account -pub fn create_validator_stake_account_with_vote( - program_id: &Pubkey, - stake_pool_address: &Pubkey, - staker: &Pubkey, - funder: &Pubkey, - vote_account_address: &Pubkey, -) -> Instruction { - let (stake_account, _) = - find_stake_program_address(program_id, vote_account_address, stake_pool_address); - create_validator_stake_account( - program_id, - stake_pool_address, - staker, - funder, - &stake_account, - vote_account_address, - ) -} - /// Create an `AddValidatorToPool` instruction given an existing stake pool and /// vote account pub fn add_validator_to_pool_with_vote( program_id: &Pubkey, stake_pool: &StakePool, stake_pool_address: &Pubkey, + funder: &Pubkey, vote_account_address: &Pubkey, ) -> Instruction { let pool_withdraw_authority = @@ -646,9 +585,11 @@ pub fn add_validator_to_pool_with_vote( program_id, stake_pool_address, &stake_pool.staker, + funder, &pool_withdraw_authority, &stake_pool.validator_list, &stake_account_address, + vote_account_address, ) } diff --git a/program/src/processor.rs b/program/src/processor.rs index 4c7e0515..7f067ed6 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -672,8 +672,8 @@ impl Processor { .map_err(|e| e.into()) } - /// Processes `CreateValidatorStakeAccount` instruction. - fn process_create_validator_stake_account( + /// Processes `AddValidatorToPool` instruction. + fn process_add_validator_to_pool( program_id: &Pubkey, accounts: &[AccountInfo], ) -> ProgramResult { @@ -681,34 +681,70 @@ impl Processor { let stake_pool_info = next_account_info(account_info_iter)?; let staker_info = next_account_info(account_info_iter)?; let funder_info = next_account_info(account_info_iter)?; - let stake_account_info = next_account_info(account_info_iter)?; - let validator_info = next_account_info(account_info_iter)?; + let withdraw_authority_info = next_account_info(account_info_iter)?; + let validator_list_info = next_account_info(account_info_iter)?; + let stake_info = next_account_info(account_info_iter)?; + let validator_vote_info = next_account_info(account_info_iter)?; let rent_info = next_account_info(account_info_iter)?; let rent = &Rent::from_account_info(rent_info)?; let clock_info = next_account_info(account_info_iter)?; + let clock = &Clock::from_account_info(clock_info)?; let stake_history_info = next_account_info(account_info_iter)?; let stake_config_info = next_account_info(account_info_iter)?; let system_program_info = next_account_info(account_info_iter)?; let stake_program_info = next_account_info(account_info_iter)?; + check_system_program(system_program_info.key)?; + check_stake_program(stake_program_info.key)?; + check_account_owner(stake_pool_info, program_id)?; let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); } + + stake_pool.check_authority_withdraw( + withdraw_authority_info.key, + program_id, + stake_pool_info.key, + )?; + stake_pool.check_staker(staker_info)?; + stake_pool.check_validator_list(validator_list_info)?; - check_system_program(system_program_info.key)?; - check_stake_program(stake_program_info.key)?; + if stake_pool.last_update_epoch < clock.epoch { + return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); + } + + check_account_owner(validator_list_info, program_id)?; + let mut validator_list_data = validator_list_info.data.borrow_mut(); + let (header, mut validator_list) = + ValidatorListHeader::deserialize_vec(&mut validator_list_data)?; + if !header.is_valid() { + return Err(StakePoolError::InvalidState.into()); + } + if header.max_validators == validator_list.len() { + return Err(ProgramError::AccountDataTooSmall); + } + let maybe_validator_stake_info = validator_list.find::( + validator_vote_info.key.as_ref(), + ValidatorStakeInfo::memcmp_pubkey, + ); + if maybe_validator_stake_info.is_some() { + return Err(StakePoolError::ValidatorAlreadyAdded.into()); + } - let (stake_address, bump_seed) = - crate::find_stake_program_address(program_id, validator_info.key, stake_pool_info.key); - if stake_address != *stake_account_info.key { + let (stake_address, bump_seed) = crate::find_stake_program_address( + program_id, + validator_vote_info.key, + stake_pool_info.key, + ); + if stake_address != *stake_info.key { return Err(StakePoolError::InvalidStakeAccountAddress.into()); } let stake_account_signer_seeds: &[&[_]] = &[ - &validator_info.key.to_bytes()[..32], + &validator_vote_info.key.to_bytes()[..32], &stake_pool_info.key.to_bytes()[..32], &[bump_seed], ]; @@ -721,148 +757,46 @@ impl Processor { invoke_signed( &system_instruction::create_account( funder_info.key, - stake_account_info.key, + stake_info.key, required_lamports, std::mem::size_of::() as u64, &stake_program::id(), ), - &[funder_info.clone(), stake_account_info.clone()], + &[funder_info.clone(), stake_info.clone()], &[stake_account_signer_seeds], )?; invoke( &stake_program::initialize( - stake_account_info.key, + stake_info.key, &stake_program::Authorized { - staker: *staker_info.key, - withdrawer: *staker_info.key, + staker: *withdraw_authority_info.key, + withdrawer: *withdraw_authority_info.key, }, &stake_program::Lockup::default(), ), &[ - stake_account_info.clone(), + stake_info.clone(), rent_info.clone(), stake_program_info.clone(), ], )?; - invoke( - &stake_program::delegate_stake( - stake_account_info.key, - staker_info.key, - validator_info.key, - ), - &[ - stake_account_info.clone(), - validator_info.clone(), - clock_info.clone(), - stake_history_info.clone(), - stake_config_info.clone(), - staker_info.clone(), - ], - ) - } - - /// Processes `AddValidatorToPool` instruction. - fn process_add_validator_to_pool( - program_id: &Pubkey, - accounts: &[AccountInfo], - ) -> ProgramResult { - let account_info_iter = &mut accounts.iter(); - let stake_pool_info = next_account_info(account_info_iter)?; - let staker_info = next_account_info(account_info_iter)?; - let withdraw_authority_info = next_account_info(account_info_iter)?; - let validator_list_info = next_account_info(account_info_iter)?; - let stake_account_info = next_account_info(account_info_iter)?; - let clock_info = next_account_info(account_info_iter)?; - let clock = &Clock::from_account_info(clock_info)?; - let _stake_history_info = next_account_info(account_info_iter)?; - //let stake_history = &StakeHistory::from_account_info(stake_history_info)?; - let stake_program_info = next_account_info(account_info_iter)?; - - check_stake_program(stake_program_info.key)?; - - check_account_owner(stake_pool_info, program_id)?; - let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; - if !stake_pool.is_valid() { - return Err(StakePoolError::InvalidState.into()); - } - - stake_pool.check_authority_withdraw( - withdraw_authority_info.key, - program_id, - stake_pool_info.key, - )?; - - stake_pool.check_staker(staker_info)?; - stake_pool.check_validator_list(validator_list_info)?; - - if stake_pool.last_update_epoch < clock.epoch { - return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); - } - - check_account_owner(validator_list_info, program_id)?; - let mut validator_list_data = validator_list_info.data.borrow_mut(); - let (header, mut validator_list) = - ValidatorListHeader::deserialize_vec(&mut validator_list_data)?; - if !header.is_valid() { - return Err(StakePoolError::InvalidState.into()); - } - if header.max_validators == validator_list.len() { - return Err(ProgramError::AccountDataTooSmall); - } - - let (meta, stake) = get_stake_state(stake_account_info)?; - let vote_account_address = stake.delegation.voter_pubkey; - check_validator_stake_address( - program_id, - stake_pool_info.key, - stake_account_info.key, - &vote_account_address, - )?; - - if meta.lockup != stake_program::Lockup::default() { - msg!("Stake account has a lockup"); - return Err(StakePoolError::WrongStakeState.into()); - } - - let maybe_validator_stake_info = validator_list.find::( - vote_account_address.as_ref(), - ValidatorStakeInfo::memcmp_pubkey, - ); - if maybe_validator_stake_info.is_some() { - return Err(StakePoolError::ValidatorAlreadyAdded.into()); - } - - // Check amount of lamports - let stake_lamports = **stake_account_info.lamports.borrow(); - let minimum_lamport_amount = minimum_stake_lamports(&meta); - if stake_lamports != minimum_lamport_amount - || stake.delegation.stake != MINIMUM_ACTIVE_STAKE - { - msg!( - "Error: attempting to add (stake: {}, delegation: {}), below minimum", - stake_lamports, - stake.delegation.stake, - ); - return Err(StakePoolError::StakeLamportsNotEqualToMinimum.into()); - } - - // Check if stake is warmed up - //Self::check_stake_activation(stake_account_info, clock, stake_history)?; - - // Update Withdrawer and Staker authority to the program withdraw authority - Self::stake_authorize( - stake_account_info.clone(), - staker_info.clone(), - withdraw_authority_info.key, + Self::stake_delegate( + stake_info.clone(), + validator_vote_info.clone(), clock_info.clone(), - stake_program_info.clone(), + stake_history_info.clone(), + stake_config_info.clone(), + withdraw_authority_info.clone(), + stake_pool_info.key, + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, )?; validator_list.push(ValidatorStakeInfo { status: StakeStatus::Active, - vote_account_address, + vote_account_address: *validator_vote_info.key, active_stake_lamports: 0, transient_stake_lamports: 0, last_update_epoch: clock.epoch, @@ -2591,10 +2525,6 @@ impl Processor { max_validators, ) } - StakePoolInstruction::CreateValidatorStakeAccount => { - msg!("Instruction: CreateValidatorStakeAccount"); - Self::process_create_validator_stake_account(program_id, accounts) - } StakePoolInstruction::AddValidatorToPool => { msg!("Instruction: AddValidatorToPool"); Self::process_add_validator_to_pool(program_id, accounts) diff --git a/program/tests/decrease.rs b/program/tests/decrease.rs index 037a1735..e3400891 100644 --- a/program/tests/decrease.rs +++ b/program/tests/decrease.rs @@ -236,15 +236,13 @@ async fn fail_with_unknown_validator() { decrease_lamports, ) = setup().await; - let unknown_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), 222); - unknown_stake - .create_and_delegate( - &mut banks_client, - &payer, - &recent_blockhash, - &stake_pool_accounts.staker, - ) - .await; + let unknown_stake = create_unknown_validator_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; let transaction = Transaction::new_signed_with_payer( &[instruction::decrease_validator_stake( @@ -269,13 +267,13 @@ async fn fail_with_unknown_validator() { .unwrap() .unwrap(); - match error { - TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { - let program_error = StakePoolError::ValidatorNotFound as u32; - assert_eq!(error_index, program_error); - } - _ => panic!("Wrong error occurs while decreasing stake from unknown validator"), - } + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::InvalidStakeAccountAddress as u32) + ) + ); } #[tokio::test] diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 2a73137e..00daabaa 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -19,7 +19,9 @@ use { transaction::TransactionError, transport::TransportError, }, - spl_stake_pool::{error, id, instruction, minimum_stake_lamports, stake_program, state}, + spl_stake_pool::{ + error::StakePoolError, id, instruction, minimum_stake_lamports, stake_program, state, + }, spl_token::error as token_error, }; @@ -595,7 +597,7 @@ async fn fail_with_wrong_validator_list_account() { _, InstructionError::Custom(error_index), ) => { - let program_error = error::StakePoolError::InvalidValidatorStakeList as u32; + let program_error = StakePoolError::InvalidValidatorStakeList as u32; assert_eq!(error_index, program_error); } _ => panic!("Wrong error occurs while try to make a deposit with wrong validator stake list account"), @@ -611,19 +613,16 @@ async fn fail_with_unknown_validator() { .await .unwrap(); - let validator_stake_account = - ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), u64::MAX); - validator_stake_account - .create_and_delegate( - &mut banks_client, - &payer, - &recent_blockhash, - &stake_pool_accounts.staker, - ) - .await; + let unknown_stake = create_unknown_validator_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; - let user_pool_account = Keypair::new(); let user = Keypair::new(); + let user_pool_account = Keypair::new(); create_token_account( &mut banks_client, &payer, @@ -652,48 +651,37 @@ async fn fail_with_unknown_validator() { TEST_STAKE_AMOUNT, ) .await; - let random_vote_account = Keypair::new(); - create_vote( - &mut banks_client, - &payer, - &recent_blockhash, - &Keypair::new(), - &random_vote_account, - ) - .await; delegate_stake_account( &mut banks_client, &payer, &recent_blockhash, &user_stake.pubkey(), &user, - &random_vote_account.pubkey(), + &unknown_stake.vote.pubkey(), ) .await; - let transaction_error = stake_pool_accounts + let error = stake_pool_accounts .deposit_stake( &mut banks_client, &payer, &recent_blockhash, &user_stake.pubkey(), &user_pool_account.pubkey(), - &validator_stake_account.stake_account, + &unknown_stake.stake_account, &user, ) .await .unwrap() .unwrap(); - match transaction_error { - TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { - let program_error = error::StakePoolError::ValidatorNotFound as u32; - assert_eq!(error_index, program_error); - } - _ => { - panic!("Wrong error occurs while try to make a deposit with unknown validator account") - } - } + assert_eq!( + error, + TransactionError::InstructionError( + 2, + InstructionError::Custom(StakePoolError::InvalidStakeAccountAddress as u32) + ) + ); } #[tokio::test] @@ -726,7 +714,7 @@ async fn fail_with_wrong_withdraw_authority() { match transaction_error { TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { - let program_error = error::StakePoolError::InvalidProgramAddress as u32; + let program_error = StakePoolError::InvalidProgramAddress as u32; assert_eq!(error_index, program_error); } _ => panic!("Wrong error occurs while try to make a deposit with wrong withdraw authority"), @@ -974,7 +962,7 @@ async fn fail_without_stake_deposit_authority_signature() { TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { assert_eq!( error_index, - error::StakePoolError::InvalidStakeDepositAuthority as u32 + StakePoolError::InvalidStakeDepositAuthority as u32 ); } _ => panic!("Wrong error occurs while try to make a deposit with wrong stake program ID"), @@ -1064,7 +1052,7 @@ async fn fail_with_wrong_preferred_deposit() { TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { assert_eq!( error_index, - error::StakePoolError::IncorrectDepositVoteAddress as u32 + StakePoolError::IncorrectDepositVoteAddress as u32 ); } _ => panic!("Wrong error occurs while try to make a deposit with wrong stake program ID"), diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 69c4dadb..103254b3 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -23,6 +23,7 @@ use { find_stake_program_address, find_transient_stake_program_address, id, instruction, processor, stake_program, state::{self, FeeType, ValidatorList}, + MINIMUM_ACTIVE_STAKE, }, }; @@ -481,31 +482,6 @@ pub async fn create_blank_stake_account( lamports } -pub async fn create_validator_stake_account( - banks_client: &mut BanksClient, - payer: &Keypair, - recent_blockhash: &Hash, - stake_pool: &Pubkey, - staker: &Keypair, - stake_account: &Pubkey, - validator: &Pubkey, -) { - let transaction = Transaction::new_signed_with_payer( - &[instruction::create_validator_stake_account( - &id(), - &stake_pool, - &staker.pubkey(), - &payer.pubkey(), - &stake_account, - &validator, - )], - Some(&payer.pubkey()), - &[payer, staker], - *recent_blockhash, - ); - banks_client.process_transaction(transaction).await.unwrap(); -} - pub async fn delegate_stake_account( banks_client: &mut BanksClient, payer: &Keypair, @@ -548,6 +524,49 @@ pub async fn authorize_stake_account( banks_client.process_transaction(transaction).await.unwrap(); } +pub async fn create_unknown_validator_stake( + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + stake_pool: &Pubkey, +) -> ValidatorStakeAccount { + let mut unknown_stake = ValidatorStakeAccount::new(stake_pool, 222); + create_vote( + banks_client, + payer, + recent_blockhash, + &unknown_stake.validator, + &unknown_stake.vote, + ) + .await; + let user = Keypair::new(); + let fake_validator_stake = Keypair::new(); + create_independent_stake_account( + banks_client, + payer, + recent_blockhash, + &fake_validator_stake, + &stake_program::Authorized { + staker: user.pubkey(), + withdrawer: user.pubkey(), + }, + &stake_program::Lockup::default(), + MINIMUM_ACTIVE_STAKE, + ) + .await; + delegate_stake_account( + banks_client, + payer, + recent_blockhash, + &fake_validator_stake.pubkey(), + &user, + &unknown_stake.vote.pubkey(), + ) + .await; + unknown_stake.stake_account = fake_validator_stake.pubkey(); + unknown_stake +} + pub struct ValidatorStakeAccount { pub stake_account: Pubkey, pub transient_stake_account: Pubkey, @@ -577,34 +596,6 @@ impl ValidatorStakeAccount { stake_pool: *stake_pool, } } - - pub async fn create_and_delegate( - &self, - mut banks_client: &mut BanksClient, - payer: &Keypair, - recent_blockhash: &Hash, - staker: &Keypair, - ) { - create_vote( - &mut banks_client, - &payer, - &recent_blockhash, - &self.validator, - &self.vote, - ) - .await; - - create_validator_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &self.stake_pool, - staker, - &self.stake_account, - &self.vote.pubkey(), - ) - .await; - } } pub struct StakePoolAccounts { @@ -1068,15 +1059,18 @@ impl StakePoolAccounts { payer: &Keypair, recent_blockhash: &Hash, stake: &Pubkey, + validator: &Pubkey, ) -> Option { let transaction = Transaction::new_signed_with_payer( &[instruction::add_validator_to_pool( &id(), &self.stake_pool.pubkey(), &self.staker.pubkey(), + &payer.pubkey(), &self.withdraw_authority, &self.validator_list.pubkey(), stake, + validator, )], Some(&payer.pubkey()), &[payer, &self.staker], @@ -1217,14 +1211,15 @@ pub async fn simple_add_validator_to_pool( &stake_pool_accounts.stake_pool.pubkey(), DEFAULT_TRANSIENT_STAKE_SEED, ); - validator_stake - .create_and_delegate( - banks_client, - &payer, - &recent_blockhash, - &stake_pool_accounts.staker, - ) - .await; + + create_vote( + banks_client, + payer, + recent_blockhash, + &validator_stake.validator, + &validator_stake.vote, + ) + .await; let error = stake_pool_accounts .add_validator_to_pool( @@ -1232,6 +1227,7 @@ pub async fn simple_add_validator_to_pool( &payer, &recent_blockhash, &validator_stake.stake_account, + &validator_stake.vote.pubkey(), ) .await; assert!(error.is_none()); diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index 35892657..55043bc1 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -564,23 +564,13 @@ async fn add_validator_to_pool() { let (stake_address, _) = find_stake_program_address(&id(), &test_vote_address, &stake_pool_pubkey); - create_validator_stake_account( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_pubkey, - &stake_pool_accounts.staker, - &stake_address, - &test_vote_address, - ) - .await; - let error = stake_pool_accounts .add_validator_to_pool( &mut context.banks_client, &context.payer, &context.last_blockhash, &stake_address, + &test_vote_address, ) .await; assert!(error.is_none()); diff --git a/program/tests/increase.rs b/program/tests/increase.rs index 611bf0b2..459dbe39 100644 --- a/program/tests/increase.rs +++ b/program/tests/increase.rs @@ -239,15 +239,13 @@ async fn fail_with_unknown_validator() { reserve_lamports, ) = setup().await; - let unknown_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), 1241); - unknown_stake - .create_and_delegate( - &mut banks_client, - &payer, - &recent_blockhash, - &stake_pool_accounts.staker, - ) - .await; + let unknown_stake = create_unknown_validator_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; let transaction = Transaction::new_signed_with_payer( &[instruction::increase_validator_stake( @@ -273,13 +271,13 @@ async fn fail_with_unknown_validator() { .unwrap() .unwrap(); - match error { - TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { - let program_error = StakePoolError::ValidatorNotFound as u32; - assert_eq!(error_index, program_error); - } - _ => panic!("Wrong error"), - } + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::ValidatorNotFound as u32) + ) + ); } #[tokio::test] diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index 9c3041da..a394acf0 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -54,14 +54,25 @@ async fn setup( for _ in 0..num_validators { let stake_account = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), u64::MAX); - stake_account - .create_and_delegate( + create_vote( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_account.validator, + &stake_account.vote, + ) + .await; + + let error = stake_pool_accounts + .add_validator_to_pool( &mut context.banks_client, &context.payer, &context.last_blockhash, - &stake_pool_accounts.staker, + &stake_account.stake_account, + &stake_account.vote.pubkey(), ) .await; + assert!(error.is_none()); let deposit_account = DepositStakeAccount::new_with_vote( stake_account.vote.pubkey(), @@ -89,23 +100,15 @@ async fn setup( &mut context.banks_client, &context.payer, &context.last_blockhash, - &[], + stake_accounts + .iter() + .map(|v| v.vote.pubkey()) + .collect::>() + .as_slice(), false, ) .await; - for stake_account in &stake_accounts { - let error = stake_pool_accounts - .add_validator_to_pool( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_account.stake_account, - ) - .await; - assert!(error.is_none()); - } - for deposit_account in &mut deposit_accounts { deposit_account .deposit_stake( diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index 3e7d8e5e..4063d3f2 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -11,7 +11,7 @@ use { hash::Hash, instruction::{AccountMeta, Instruction, InstructionError}, pubkey::Pubkey, - sysvar, + system_program, sysvar, }, solana_program_test::*, solana_sdk::{ @@ -19,7 +19,9 @@ use { transaction::{Transaction, TransactionError}, transport::TransportError, }, - spl_stake_pool::{error::StakePoolError, id, instruction, stake_program, state}, + spl_stake_pool::{ + error::StakePoolError, find_stake_program_address, id, instruction, stake_program, state, + }, }; async fn setup() -> ( @@ -36,28 +38,28 @@ async fn setup() -> ( .await .unwrap(); - let user_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), 0); - user_stake - .create_and_delegate( - &mut banks_client, - &payer, - &recent_blockhash, - &stake_pool_accounts.staker, - ) - .await; + let validator_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), 0); + create_vote( + &mut banks_client, + &payer, + &recent_blockhash, + &validator_stake.validator, + &validator_stake.vote, + ) + .await; ( banks_client, payer, recent_blockhash, stake_pool_accounts, - user_stake, + validator_stake, ) } #[tokio::test] async fn success() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = setup().await; let error = stake_pool_accounts @@ -65,7 +67,8 @@ async fn success() { &mut banks_client, &payer, &recent_blockhash, - &user_stake.stake_account, + &validator_stake.stake_account, + &validator_stake.vote.pubkey(), ) .await; assert!(error.is_none()); @@ -87,7 +90,7 @@ async fn success() { }, validators: vec![state::ValidatorStakeInfo { status: state::StakeStatus::Active, - vote_account_address: user_stake.vote.pubkey(), + vote_account_address: validator_stake.vote.pubkey(), last_update_epoch: 0, active_stake_lamports: 0, transient_stake_lamports: 0, @@ -97,8 +100,8 @@ async fn success() { } ); - // Check of stake account authority has changed - let stake = get_account(&mut banks_client, &user_stake.stake_account).await; + // Check stake account existence and authority + let stake = get_account(&mut banks_client, &validator_stake.stake_account).await; let stake_state = deserialize::(&stake.data).unwrap(); match stake_state { stake_program::StakeState::Stake(meta, _) => { @@ -117,7 +120,7 @@ async fn success() { #[tokio::test] async fn fail_with_wrong_validator_list_account() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = setup().await; let wrong_validator_list = Keypair::new(); @@ -127,9 +130,11 @@ async fn fail_with_wrong_validator_list_account() { &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.staker.pubkey(), + &payer.pubkey(), &stake_pool_accounts.withdraw_authority, &wrong_validator_list.pubkey(), - &user_stake.stake_account, + &validator_stake.stake_account, + &validator_stake.vote.pubkey(), )], Some(&payer.pubkey()), ); @@ -152,122 +157,9 @@ async fn fail_with_wrong_validator_list_account() { } } -#[tokio::test] -async fn fail_too_little_stake() { - let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); - stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) - .await - .unwrap(); - - let user_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), 0); - create_vote( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake.validator, - &user_stake.vote, - ) - .await; - - create_validator_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake.stake_pool, - &stake_pool_accounts.staker, - &user_stake.stake_account, - &user_stake.vote.pubkey(), - ) - .await; - - // Create stake account to withdraw to - let split = Keypair::new(); - create_blank_stake_account(&mut banks_client, &payer, &recent_blockhash, &split).await; - let transaction = Transaction::new_signed_with_payer( - &[stake_program::split_only( - &user_stake.stake_account, - &stake_pool_accounts.staker.pubkey(), - 1, - &split.pubkey(), - )], - Some(&payer.pubkey()), - &[&payer, &stake_pool_accounts.staker], - recent_blockhash, - ); - - banks_client.process_transaction(transaction).await.unwrap(); - - let error = stake_pool_accounts - .add_validator_to_pool( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake.stake_account, - ) - .await - .unwrap() - .unwrap(); - assert_eq!( - error, - TransactionError::InstructionError( - 0, - InstructionError::Custom(StakePoolError::StakeLamportsNotEqualToMinimum as u32) - ), - ); -} - -#[tokio::test] -async fn fail_too_much_stake() { - let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); - stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) - .await - .unwrap(); - - let user_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), 0); - user_stake - .create_and_delegate( - &mut banks_client, - &payer, - &recent_blockhash, - &stake_pool_accounts.staker, - ) - .await; - - transfer( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake.stake_account, - 1, - ) - .await; - - let error = stake_pool_accounts - .add_validator_to_pool( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake.stake_account, - ) - .await - .unwrap() - .unwrap(); - assert_eq!( - error, - TransactionError::InstructionError( - 0, - InstructionError::Custom(StakePoolError::StakeLamportsNotEqualToMinimum as u32) - ), - ); -} - #[tokio::test] async fn fail_double_add() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = setup().await; stake_pool_accounts @@ -275,7 +167,8 @@ async fn fail_double_add() { &mut banks_client, &payer, &recent_blockhash, - &user_stake.stake_account, + &validator_stake.stake_account, + &validator_stake.vote.pubkey(), ) .await; @@ -286,7 +179,8 @@ async fn fail_double_add() { &mut banks_client, &payer, &latest_blockhash, - &user_stake.stake_account, + &validator_stake.stake_account, + &validator_stake.vote.pubkey(), ) .await .unwrap(); @@ -305,7 +199,7 @@ async fn fail_double_add() { #[tokio::test] async fn fail_wrong_staker() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = setup().await; let malicious = Keypair::new(); @@ -315,9 +209,11 @@ async fn fail_wrong_staker() { &id(), &stake_pool_accounts.stake_pool.pubkey(), &malicious.pubkey(), + &payer.pubkey(), &stake_pool_accounts.withdraw_authority, &stake_pool_accounts.validator_list.pubkey(), - &user_stake.stake_account, + &validator_stake.stake_account, + &validator_stake.vote.pubkey(), )], Some(&payer.pubkey()), ); @@ -342,17 +238,22 @@ async fn fail_wrong_staker() { #[tokio::test] async fn fail_without_signature() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = setup().await; let accounts = vec![ AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), AccountMeta::new_readonly(stake_pool_accounts.staker.pubkey(), false), + AccountMeta::new(payer.pubkey(), false), AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false), AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false), - AccountMeta::new(user_stake.stake_account, false), + AccountMeta::new(validator_stake.stake_account, false), + AccountMeta::new(validator_stake.vote.pubkey(), false), + AccountMeta::new_readonly(sysvar::rent::id(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), + AccountMeta::new_readonly(stake_program::config_id(), false), + AccountMeta::new_readonly(system_program::id(), false), AccountMeta::new_readonly(stake_program::id(), false), ]; let instruction = Instruction { @@ -385,19 +286,23 @@ async fn fail_without_signature() { #[tokio::test] async fn fail_with_wrong_stake_program_id() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, user_stake) = + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = setup().await; let wrong_stake_program = Pubkey::new_unique(); - let accounts = vec![ AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), AccountMeta::new_readonly(stake_pool_accounts.staker.pubkey(), true), + AccountMeta::new(payer.pubkey(), true), AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false), AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false), - AccountMeta::new(user_stake.stake_account, false), + AccountMeta::new(validator_stake.stake_account, false), + AccountMeta::new(validator_stake.vote.pubkey(), false), + AccountMeta::new_readonly(sysvar::rent::id(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), + AccountMeta::new_readonly(stake_program::config_id(), false), + AccountMeta::new_readonly(system_program::id(), false), AccountMeta::new_readonly(wrong_stake_program, false), ]; let instruction = Instruction { @@ -425,6 +330,53 @@ async fn fail_with_wrong_stake_program_id() { } } +#[tokio::test] +async fn fail_with_wrong_system_program_id() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = + setup().await; + + let wrong_system_program = Pubkey::new_unique(); + + let accounts = vec![ + AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), + AccountMeta::new_readonly(stake_pool_accounts.staker.pubkey(), true), + AccountMeta::new(payer.pubkey(), true), + AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false), + AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false), + AccountMeta::new(validator_stake.stake_account, false), + AccountMeta::new(validator_stake.vote.pubkey(), false), + AccountMeta::new_readonly(sysvar::rent::id(), false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(sysvar::stake_history::id(), false), + AccountMeta::new_readonly(stake_program::config_id(), false), + AccountMeta::new_readonly(wrong_system_program, false), + AccountMeta::new_readonly(stake_program::id(), false), + ]; + let instruction = Instruction { + program_id: id(), + accounts, + data: instruction::StakePoolInstruction::AddValidatorToPool + .try_to_vec() + .unwrap(), + }; + let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); + transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { + assert_eq!(error, InstructionError::IncorrectProgramId); + } + _ => panic!( + "Wrong error occurs while try to add validator stake account with wrong stake program ID" + ), + } +} + #[tokio::test] async fn fail_add_too_many_validator_stake_accounts() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; @@ -435,41 +387,43 @@ async fn fail_add_too_many_validator_stake_accounts() { .await .unwrap(); - let user_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), 0); - user_stake - .create_and_delegate( - &mut banks_client, - &payer, - &recent_blockhash, - &stake_pool_accounts.staker, - ) - .await; + let validator_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), 0); + create_vote( + &mut banks_client, + &payer, + &recent_blockhash, + &validator_stake.validator, + &validator_stake.vote, + ) + .await; let error = stake_pool_accounts .add_validator_to_pool( &mut banks_client, &payer, &recent_blockhash, - &user_stake.stake_account, + &validator_stake.stake_account, + &validator_stake.vote.pubkey(), ) .await; assert!(error.is_none()); - let user_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), 0); - user_stake - .create_and_delegate( - &mut banks_client, - &payer, - &recent_blockhash, - &stake_pool_accounts.staker, - ) - .await; + let validator_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), 0); + create_vote( + &mut banks_client, + &payer, + &recent_blockhash, + &validator_stake.validator, + &validator_stake.vote, + ) + .await; let error = stake_pool_accounts .add_validator_to_pool( &mut banks_client, &payer, &recent_blockhash, - &user_stake.stake_account, + &validator_stake.stake_account, + &validator_stake.vote.pubkey(), ) .await .unwrap() @@ -485,3 +439,56 @@ async fn fail_with_unupdated_stake_pool() {} // TODO #[tokio::test] async fn fail_with_uninitialized_validator_list_account() {} // TODO + +#[tokio::test] +async fn fail_on_non_vote_account() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, _) = setup().await; + + let validator = Pubkey::new_unique(); + let (stake_account, _) = + find_stake_program_address(&id(), &validator, &stake_pool_accounts.stake_pool.pubkey()); + + let error = stake_pool_accounts + .add_validator_to_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_account, + &validator, + ) + .await + .unwrap() + .unwrap(); + + assert_eq!( + error, + TransactionError::InstructionError(0, InstructionError::IncorrectProgramId,) + ); +} + +#[tokio::test] +async fn fail_on_incorrectly_derived_stake_account() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = + setup().await; + + let bad_stake_account = Pubkey::new_unique(); + let error = stake_pool_accounts + .add_validator_to_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &bad_stake_account, + &validator_stake.vote.pubkey(), + ) + .await + .unwrap() + .unwrap(); + + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::InvalidStakeAccountAddress as u32), + ) + ); +} diff --git a/program/tests/vsa_create.rs b/program/tests/vsa_create.rs deleted file mode 100644 index 2298e613..00000000 --- a/program/tests/vsa_create.rs +++ /dev/null @@ -1,264 +0,0 @@ -#![cfg(feature = "test-bpf")] - -mod helpers; - -use { - bincode::deserialize, - borsh::BorshSerialize, - helpers::*, - solana_program::{ - instruction::{AccountMeta, Instruction, InstructionError}, - pubkey::Pubkey, - system_program, sysvar, - }, - solana_program_test::*, - solana_sdk::{ - signature::{Keypair, Signer}, - transaction::Transaction, - transaction::TransactionError, - transport::TransportError, - }, - spl_stake_pool::{error, find_stake_program_address, id, instruction, stake_program}, -}; - -#[tokio::test] -async fn success_create_validator_stake_account() { - let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); - stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) - .await - .unwrap(); - - let validator = Keypair::new(); - let vote = Keypair::new(); - create_vote( - &mut banks_client, - &payer, - &recent_blockhash, - &validator, - &vote, - ) - .await; - - let (stake_account, _) = find_stake_program_address( - &id(), - &vote.pubkey(), - &stake_pool_accounts.stake_pool.pubkey(), - ); - - let mut transaction = Transaction::new_with_payer( - &[instruction::create_validator_stake_account( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.staker.pubkey(), - &payer.pubkey(), - &stake_account, - &vote.pubkey(), - )], - Some(&payer.pubkey()), - ); - transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); - banks_client.process_transaction(transaction).await.unwrap(); - - // Check authorities - let stake = get_account(&mut banks_client, &stake_account).await; - let stake_state = deserialize::(&stake.data).unwrap(); - match stake_state { - stake_program::StakeState::Stake(meta, stake) => { - assert_eq!( - &meta.authorized.staker, - &stake_pool_accounts.staker.pubkey() - ); - assert_eq!( - &meta.authorized.withdrawer, - &stake_pool_accounts.staker.pubkey() - ); - assert_eq!(stake.delegation.voter_pubkey, vote.pubkey()); - } - _ => panic!(), - } -} - -#[tokio::test] -async fn fail_create_validator_stake_account_on_non_vote_account() { - let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); - stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) - .await - .unwrap(); - - let validator = Pubkey::new_unique(); - - let (stake_account, _) = - find_stake_program_address(&id(), &validator, &stake_pool_accounts.stake_pool.pubkey()); - - let mut transaction = Transaction::new_with_payer( - &[instruction::create_validator_stake_account( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.staker.pubkey(), - &payer.pubkey(), - &stake_account, - &validator, - )], - Some(&payer.pubkey()), - ); - transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); - let transaction_error = banks_client - .process_transaction(transaction) - .await - .err() - .unwrap() - .unwrap(); - - assert_eq!( - transaction_error, - TransactionError::InstructionError(0, InstructionError::IncorrectProgramId,) - ); -} - -#[tokio::test] -async fn fail_create_validator_stake_account_with_wrong_system_program() { - let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); - stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) - .await - .unwrap(); - - let validator = Pubkey::new_unique(); - - let (stake_account, _) = - find_stake_program_address(&id(), &validator, &stake_pool_accounts.stake_pool.pubkey()); - let wrong_system_program = Pubkey::new_unique(); - let accounts = vec![ - AccountMeta::new_readonly(stake_pool_accounts.stake_pool.pubkey(), false), - AccountMeta::new_readonly(stake_pool_accounts.staker.pubkey(), true), - AccountMeta::new(payer.pubkey(), true), - AccountMeta::new(stake_account, false), - AccountMeta::new_readonly(validator, false), - AccountMeta::new_readonly(sysvar::rent::id(), false), - AccountMeta::new_readonly(sysvar::clock::id(), false), - AccountMeta::new_readonly(sysvar::stake_history::id(), false), - AccountMeta::new_readonly(stake_program::config_id(), false), - AccountMeta::new_readonly(wrong_system_program, false), - AccountMeta::new_readonly(stake_program::id(), false), - ]; - let instruction = Instruction { - program_id: id(), - accounts, - data: instruction::StakePoolInstruction::CreateValidatorStakeAccount - .try_to_vec() - .unwrap(), - }; - - let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); - transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); - let transaction_error = banks_client - .process_transaction(transaction) - .await - .err() - .unwrap() - .unwrap(); - - assert_eq!( - transaction_error, - TransactionError::InstructionError(0, InstructionError::IncorrectProgramId,) - ); -} - -#[tokio::test] -async fn fail_create_validator_stake_account_with_wrong_stake_program() { - let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); - stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) - .await - .unwrap(); - - let validator = Pubkey::new_unique(); - - let (stake_account, _) = - find_stake_program_address(&id(), &validator, &stake_pool_accounts.stake_pool.pubkey()); - let wrong_stake_program = Pubkey::new_unique(); - let accounts = vec![ - AccountMeta::new_readonly(stake_pool_accounts.stake_pool.pubkey(), false), - AccountMeta::new_readonly(stake_pool_accounts.staker.pubkey(), true), - AccountMeta::new(payer.pubkey(), true), - AccountMeta::new(stake_account, false), - AccountMeta::new_readonly(validator, false), - AccountMeta::new_readonly(sysvar::rent::id(), false), - AccountMeta::new_readonly(sysvar::clock::id(), false), - AccountMeta::new_readonly(sysvar::stake_history::id(), false), - AccountMeta::new_readonly(stake_program::config_id(), false), - AccountMeta::new_readonly(system_program::id(), false), - AccountMeta::new_readonly(wrong_stake_program, false), - ]; - let instruction = Instruction { - program_id: id(), - accounts, - data: instruction::StakePoolInstruction::CreateValidatorStakeAccount - .try_to_vec() - .unwrap(), - }; - - let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); - transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); - let transaction_error = banks_client - .process_transaction(transaction) - .await - .err() - .unwrap() - .unwrap(); - - assert_eq!( - transaction_error, - TransactionError::InstructionError(0, InstructionError::IncorrectProgramId,) - ); -} - -#[tokio::test] -async fn fail_create_validator_stake_account_with_incorrect_address() { - let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); - stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) - .await - .unwrap(); - - let validator = Pubkey::new_unique(); - let stake_account = Keypair::new(); - - let mut transaction = Transaction::new_with_payer( - &[instruction::create_validator_stake_account( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.staker.pubkey(), - &payer.pubkey(), - &stake_account.pubkey(), - &validator, - )], - Some(&payer.pubkey()), - ); - transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); - let transaction_error = banks_client - .process_transaction(transaction) - .await - .err() - .unwrap(); - - match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError( - _, - InstructionError::Custom(error_index), - )) => { - let program_error = error::StakePoolError::InvalidStakeAccountAddress as u32; - assert_eq!(error_index, program_error); - } - _ => panic!( - "Wrong error occurs while try to create validator stake account with incorrect address" - ), - } -} diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 2be7adc3..a8e221c0 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -45,14 +45,14 @@ async fn setup() -> ( let validator_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), u64::MAX); - validator_stake - .create_and_delegate( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts.staker, - ) - .await; + create_vote( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &validator_stake.validator, + &validator_stake.vote, + ) + .await; let error = stake_pool_accounts .add_validator_to_pool( @@ -60,6 +60,7 @@ async fn setup() -> ( &context.payer, &context.last_blockhash, &validator_stake.stake_account, + &validator_stake.vote.pubkey(), ) .await; assert!(error.is_none()); diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index ae0ec591..236c0694 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -476,7 +476,7 @@ async fn fail_with_wrong_validator_list() { payer, recent_blockhash, mut stake_pool_accounts, - validator_stake_account, + validator_stake, deposit_info, user_transfer_authority, user_stake_recipient, @@ -494,7 +494,7 @@ async fn fail_with_wrong_validator_list() { &user_stake_recipient.pubkey(), &user_transfer_authority, &deposit_info.pool_account.pubkey(), - &validator_stake_account.stake_account, + &validator_stake.stake_account, &new_authority, tokens_to_burn, ) @@ -529,90 +529,16 @@ async fn fail_with_unknown_validator() { tokens_to_withdraw, ) = setup().await; - let validator_stake_account = - ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), 111); - validator_stake_account - .create_and_delegate( - &mut banks_client, - &payer, - &recent_blockhash, - &stake_pool_accounts.staker, - ) - .await; - - let user_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), 111); - user_stake - .create_and_delegate( - &mut banks_client, - &payer, - &recent_blockhash, - &stake_pool_accounts.staker, - ) - .await; - - let user_pool_account = Keypair::new(); - let user = Keypair::new(); - create_token_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_pool_account, - &stake_pool_accounts.pool_mint.pubkey(), - &user.pubkey(), - ) - .await - .unwrap(); - - let user = Keypair::new(); - // make stake account - let user_stake = Keypair::new(); - let lockup = stake_program::Lockup::default(); - let authorized = stake_program::Authorized { - staker: stake_pool_accounts.stake_deposit_authority, - withdrawer: stake_pool_accounts.stake_deposit_authority, - }; - create_independent_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake, - &authorized, - &lockup, - TEST_STAKE_AMOUNT, - ) - .await; - // make pool token account - let user_pool_account = Keypair::new(); - create_token_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_pool_account, - &stake_pool_accounts.pool_mint.pubkey(), - &user.pubkey(), - ) - .await - .unwrap(); - - let user_pool_account = user_pool_account.pubkey(); - let pool_tokens = get_token_balance(&mut banks_client, &user_pool_account).await; - - let tokens_to_burn = pool_tokens / 4; - - // Delegate tokens for burning - delegate_tokens( + let unknown_stake = create_unknown_validator_stake( &mut banks_client, &payer, &recent_blockhash, - &user_pool_account, - &user, - &user_transfer_authority.pubkey(), - tokens_to_burn, + &stake_pool_accounts.stake_pool.pubkey(), ) .await; let new_authority = Pubkey::new_unique(); - let transaction_error = stake_pool_accounts + let error = stake_pool_accounts .withdraw_stake( &mut banks_client, &payer, @@ -620,7 +546,7 @@ async fn fail_with_unknown_validator() { &user_stake_recipient.pubkey(), &user_transfer_authority, &deposit_info.pool_account.pubkey(), - &validator_stake_account.stake_account, + &unknown_stake.stake_account, &new_authority, tokens_to_withdraw, ) @@ -628,13 +554,13 @@ async fn fail_with_unknown_validator() { .unwrap() .unwrap(); - match transaction_error { - TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { - let program_error = StakePoolError::ValidatorNotFound as u32; - assert_eq!(error_index, program_error); - } - _ => panic!("Wrong error occurs while try to do withdraw from unknown validator"), - } + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::ValidatorNotFound as u32) + ) + ); } #[tokio::test] From c30a8d0dfeeec384cb972dbb0900c28daf097b92 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 8 Sep 2021 02:10:31 +0200 Subject: [PATCH 0167/1076] stake-pool: Reduce minimum stake per validator to 0.001 SOL (#2373) * stake-pool: Reduce minimum stake per validator to 0.01 SOL * Lower the limit to 0.001 SOL --- program/src/lib.rs | 2 +- program/src/processor.rs | 2 +- program/tests/increase.rs | 8 +++----- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/program/src/lib.rs b/program/src/lib.rs index 06650f7d..a45604ef 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -30,7 +30,7 @@ const TRANSIENT_STAKE_SEED_PREFIX: &[u8] = b"transient"; /// Minimum amount of staked SOL required in a validator stake account to allow /// for merges without a mismatch on credits observed -pub const MINIMUM_ACTIVE_STAKE: u64 = LAMPORTS_PER_SOL; +pub const MINIMUM_ACTIVE_STAKE: u64 = LAMPORTS_PER_SOL / 1_000; /// Maximum amount of validator stake accounts to update per /// `UpdateValidatorListBalance` instruction, based on compute limits diff --git a/program/src/processor.rs b/program/src/processor.rs index 7f067ed6..50297cfa 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -749,7 +749,7 @@ impl Processor { &[bump_seed], ]; - // Fund the stake account with 1 SOL + rent-exempt balance + // Fund the stake account with the minimum + rent-exempt balance let required_lamports = MINIMUM_ACTIVE_STAKE + rent.minimum_balance(std::mem::size_of::()); diff --git a/program/tests/increase.rs b/program/tests/increase.rs index 459dbe39..11314951 100644 --- a/program/tests/increase.rs +++ b/program/tests/increase.rs @@ -12,7 +12,8 @@ use { transaction::{Transaction, TransactionError}, }, spl_stake_pool::{ - error::StakePoolError, find_transient_stake_program_address, id, instruction, stake_program, + error::StakePoolError, find_transient_stake_program_address, id, instruction, + stake_program, MINIMUM_ACTIVE_STAKE, }, }; @@ -345,9 +346,6 @@ async fn fail_with_small_lamport_amount() { _reserve_lamports, ) = setup().await; - let rent = banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); - let error = stake_pool_accounts .increase_validator_stake( &mut banks_client, @@ -355,7 +353,7 @@ async fn fail_with_small_lamport_amount() { &recent_blockhash, &validator_stake.transient_stake_account, &validator_stake.vote.pubkey(), - stake_rent, + MINIMUM_ACTIVE_STAKE - 1, validator_stake.transient_stake_seed, ) .await From 07ab4c47c560e9432e8929479de80b9281f7d0a2 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 8 Sep 2021 13:00:32 +0200 Subject: [PATCH 0168/1076] stake-pool: Bump versions and update id for deployment (#2384) --- clients/cli/Cargo.toml | 4 ++-- clients/cli/scripts/setup-local.sh | 2 +- program/Cargo.toml | 2 +- program/program-id.md | 2 +- program/src/lib.rs | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index ce98303c..9cc99f6e 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -6,7 +6,7 @@ homepage = "https://spl.solana.com/stake-pool" license = "Apache-2.0" name = "spl-stake-pool-cli" repository = "https://github.com/solana-labs/solana-program-library" -version = "0.4.0" +version = "0.5.0" [dependencies] borsh = "0.9" @@ -21,7 +21,7 @@ solana-program = "=1.7.11" solana-remote-wallet = "=1.7.11" solana-sdk = "=1.7.11" spl-associated-token-account = { version = "1.0", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } -spl-stake-pool = { version = "0.4", path="../program", features = [ "no-entrypoint" ] } +spl-stake-pool = { version = "0.5", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "3.2", path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" bincode = "1.3.1" diff --git a/clients/cli/scripts/setup-local.sh b/clients/cli/scripts/setup-local.sh index 422b7944..a1683b7b 100755 --- a/clients/cli/scripts/setup-local.sh +++ b/clients/cli/scripts/setup-local.sh @@ -25,7 +25,7 @@ build_program () { } setup_validator() { - solana-test-validator --bpf-program SPoo1xuN9wGpxNjGnPNbRPtpQ7mHgKM8d9BeFC549Jy ../../../target/deploy/spl_stake_pool.so --quiet --reset --slots-per-epoch 32 & + solana-test-validator --bpf-program SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy ../../../target/deploy/spl_stake_pool.so --quiet --reset --slots-per-epoch 32 & pid=$! solana config set --url http://127.0.0.1:8899 solana config set --commitment confirmed diff --git a/program/Cargo.toml b/program/Cargo.toml index 6a0ee5e8..5aba6550 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "spl-stake-pool" -version = "0.4.0" +version = "0.5.0" description = "Solana Program Library Stake Pool" authors = ["Solana Maintainers "] repository = "https://github.com/solana-labs/solana-program-library" diff --git a/program/program-id.md b/program/program-id.md index cd9b26d3..7b5157e4 100644 --- a/program/program-id.md +++ b/program/program-id.md @@ -1 +1 @@ -SPoo1xuN9wGpxNjGnPNbRPtpQ7mHgKM8d9BeFC549Jy +SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy diff --git a/program/src/lib.rs b/program/src/lib.rs index a45604ef..08952ecb 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -123,4 +123,4 @@ pub fn find_transient_stake_program_address( ) } -solana_program::declare_id!("SPoo1xuN9wGpxNjGnPNbRPtpQ7mHgKM8d9BeFC549Jy"); +solana_program::declare_id!("SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy"); From 4d6162d3eb815abe958ece811584c969d0bfd806 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 10 Sep 2021 01:27:43 +0200 Subject: [PATCH 0169/1076] stake-pool-cli: Fix sol deposit for private pool (#2399) * stake-pool-cli: Fix sol deposit for private pool * cargo fmt --- clients/cli/Cargo.toml | 2 +- clients/cli/src/main.rs | 37 +++++++++---------------------------- 2 files changed, 10 insertions(+), 29 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 9cc99f6e..c6b0cec3 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -6,7 +6,7 @@ homepage = "https://spl.solana.com/stake-pool" license = "Apache-2.0" name = "spl-stake-pool-cli" repository = "https://github.com/solana-labs/solana-program-library" -version = "0.5.0" +version = "0.5.1" [dependencies] borsh = "0.9" diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index d0f85081..7c37c1e7 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -50,7 +50,6 @@ struct Config { manager: Box, staker: Box, depositor: Option>, - sol_depositor: Option>, token_owner: Box, fee_payer: Box, dry_run: bool, @@ -737,10 +736,9 @@ fn command_deposit_sol( let amount = native_token::sol_to_lamports(amount); // Check withdraw_from balance - let from_pubkey = from.as_ref().map_or_else( - || config.fee_payer.try_pubkey().unwrap(), - |keypair| keypair.try_pubkey().unwrap(), - ); + let from_pubkey = from + .as_ref() + .map_or_else(|| config.fee_payer.pubkey(), |keypair| keypair.pubkey()); let from_balance = config.rpc_client.get_balance(&from_pubkey)?; if from_balance < amount { return Err(format!( @@ -757,11 +755,7 @@ fn command_deposit_sol( // ephemeral SOL account just to do the transfer let user_sol_transfer = Keypair::new(); - let mut signers = vec![ - config.fee_payer.as_ref(), - config.staker.as_ref(), - &user_sol_transfer, - ]; + let mut signers = vec![config.fee_payer.as_ref(), &user_sol_transfer]; if let Some(keypair) = from.as_ref() { signers.push(keypair) } @@ -790,18 +784,16 @@ fn command_deposit_sol( let pool_withdraw_authority = find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; - let mut deposit_instructions = if let Some(sol_deposit_authority) = - config.sol_depositor.as_ref() - { + let mut deposit_instructions = if let Some(deposit_authority) = config.depositor.as_ref() { let expected_sol_deposit_authority = stake_pool.sol_deposit_authority.ok_or_else(|| { "SOL deposit authority specified in arguments but stake pool has none".to_string() })?; - signers.push(sol_deposit_authority.as_ref()); - if sol_deposit_authority.pubkey() != expected_sol_deposit_authority { + signers.push(deposit_authority.as_ref()); + if deposit_authority.pubkey() != expected_sol_deposit_authority { let error = format!( "Invalid deposit authority specified, expected {}, received {}", expected_sol_deposit_authority, - sol_deposit_authority.pubkey() + deposit_authority.pubkey() ); return Err(error.into()); } @@ -809,7 +801,7 @@ fn command_deposit_sol( spl_stake_pool::instruction::deposit_sol_with_authority( &spl_stake_pool::id(), stake_pool_address, - &sol_deposit_authority.pubkey(), + &deposit_authority.pubkey(), &pool_withdraw_authority, &stake_pool.reserve_stake, &user_sol_transfer.pubkey(), @@ -2199,16 +2191,6 @@ fn main() { } else { None }; - let sol_depositor = if matches.is_present("sol_depositor") { - Some(get_signer( - &matches, - "sol_depositor", - &cli_config.keypair_path, - &mut wallet_manager, - )) - } else { - None - }; let manager = get_signer( &matches, "manager", @@ -2237,7 +2219,6 @@ fn main() { manager, staker, depositor, - sol_depositor, token_owner, fee_payer, dry_run, From f917102861d6b6ade196b472e433ca05279eb582 Mon Sep 17 00:00:00 2001 From: Han Yang Date: Mon, 13 Sep 2021 05:39:22 -0700 Subject: [PATCH 0170/1076] stake-pool: cli fix remove-vsa bug (#2404) * fix remove-vsa bug: join instructions * missed & * pls squash this merge --- clients/cli/src/main.rs | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 7c37c1e7..03cb5ae0 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -447,23 +447,20 @@ fn command_vsa_remove( if let Some(stake_keypair) = stake_keypair.as_ref() { signers.push(stake_keypair); } + instructions.push( + // Create new validator stake account address + spl_stake_pool::instruction::remove_validator_from_pool_with_vote( + &spl_stake_pool::id(), + &stake_pool, + stake_pool_address, + vote_account, + new_authority, + validator_stake_info.transient_seed_suffix_start, + &stake_receiver, + ), + ); unique_signers!(signers); - let transaction = checked_transaction_with_signers( - config, - &[ - // Create new validator stake account address - spl_stake_pool::instruction::remove_validator_from_pool_with_vote( - &spl_stake_pool::id(), - &stake_pool, - stake_pool_address, - vote_account, - new_authority, - validator_stake_info.transient_seed_suffix_start, - &stake_receiver, - ), - ], - &signers, - )?; + let transaction = checked_transaction_with_signers(config, &instructions, &signers)?; send_transaction(config, transaction)?; Ok(()) } From 8ba7c9cc51d0a29dba1a9839d465190b1510f2d8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Sep 2021 11:17:56 +0000 Subject: [PATCH 0171/1076] build(deps): bump serde_json from 1.0.67 to 1.0.68 (#2416) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.67 to 1.0.68. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.67...v1.0.68) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index c6b0cec3..4954c0e7 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "0.5.1" [dependencies] borsh = "0.9" clap = "2.33.3" -serde_json = "1.0.67" +serde_json = "1.0.68" solana-account-decoder = "=1.7.11" solana-clap-utils = "=1.7.11" solana-cli-config = "=1.7.11" From ba7f7bf7b0ae1b5d04dce89ad59da8016cca5b67 Mon Sep 17 00:00:00 2001 From: Alexander Ray Date: Wed, 22 Sep 2021 21:53:32 +0200 Subject: [PATCH 0172/1076] - fix "attempt to subtract with overflow" issue (#2445) * - fix "attempt to subtract with overflow" issue * Update stake-pool/cli/src/main.rs Co-authored-by: Jon Cinque * Update stake-pool/cli/src/main.rs Co-authored-by: Jon Cinque * - run cargo fmt on it Co-authored-by: Jon Cinque --- clients/cli/src/main.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 03cb5ae0..011a57b0 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -1104,9 +1104,11 @@ fn prepare_withdraw_accounts( if lamports <= min_balance { continue; } + let available_for_withdrawal = stake_pool - .calc_lamports_withdraw_amount(lamports - *MIN_STAKE_BALANCE) + .calc_lamports_withdraw_amount(lamports.saturating_sub(*MIN_STAKE_BALANCE)) .unwrap(); + let pool_amount = u64::min(available_for_withdrawal, remaining_amount); // Those accounts will be withdrawn completely with `claim` instruction @@ -1187,9 +1189,13 @@ fn command_withdraw( stake_pool_address, ); let stake_account = config.rpc_client.get_account(&stake_account_address)?; + let available_for_withdrawal = stake_pool - .calc_lamports_withdraw_amount(stake_account.lamports - *MIN_STAKE_BALANCE) + .calc_lamports_withdraw_amount( + stake_account.lamports.saturating_sub(*MIN_STAKE_BALANCE), + ) .unwrap(); + if available_for_withdrawal < pool_amount { return Err(format!( "Not enough lamports available for withdrawal from {}, {} asked, {} available", From 4ae9b4a6fcde4068adb86ceed7619f15f3321208 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 23 Sep 2021 23:42:25 +0200 Subject: [PATCH 0173/1076] stake-pool: Update docs and help messages (#2435) * stake-pool: Update docs and help messages * Integrate review feedback --- clients/cli/src/main.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 011a57b0..ed17c8e6 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -2079,9 +2079,9 @@ fn main() { Arg::with_name("new_stake_deposit_authority") .index(3) .validator(is_pubkey) - .value_name("ADDRESS_OR_NONE") + .value_name("AUTHORITY_ADDRESS") .takes_value(true) - .help("'none', or a public key for the new stake pool sol deposit authority."), + .help("Public key for the new stake pool sol deposit authority."), ) .arg( Arg::with_name("unset") @@ -2096,7 +2096,7 @@ fn main() { ) ) .subcommand(SubCommand::with_name("set-fee") - .about("Change the [management/withdrawal/stake deposit/sol deposit] fee assessed by the stake pool. Must be signed by the manager.") + .about("Change the [epoch/withdraw/stake deposit/sol deposit] fee assessed by the stake pool. Must be signed by the manager.") .arg( Arg::with_name("pool") .index(1) From 9239780158add3389b3c73ea648519337732d124 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 24 Sep 2021 01:46:37 +0200 Subject: [PATCH 0174/1076] stake-pool-cli: Update minimum balance to be correct (#2449) --- clients/cli/Cargo.toml | 1 - clients/cli/src/main.rs | 29 ++++++++++++++--------------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 4954c0e7..36e9b935 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -25,7 +25,6 @@ spl-stake-pool = { version = "0.5", path="../program", features = [ "no-entrypoi spl-token = { version = "3.2", path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" bincode = "1.3.1" -lazy_static = "1.4.0" [[bin]] name = "spl-stake-pool" diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index ed17c8e6..cc2d3251 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -1,6 +1,3 @@ -#[macro_use] -extern crate lazy_static; - mod client; use { @@ -40,6 +37,7 @@ use { instruction::{DepositType, PreferredValidatorType}, stake_program::{self, StakeState}, state::{Fee, FeeType, StakePool, ValidatorList}, + MINIMUM_ACTIVE_STAKE, }, std::{process::exit, sync::Arc}, }; @@ -60,9 +58,6 @@ type Error = Box; type CommandResult = Result<(), Error>; const STAKE_STATE_LEN: usize = 200; -lazy_static! { - static ref MIN_STAKE_BALANCE: u64 = native_token::sol_to_lamports(1.0); -} macro_rules! unique_signers { ($vec:ident) => { @@ -1089,7 +1084,9 @@ fn prepare_withdraw_accounts( if accounts.is_empty() { return Err("No accounts found.".to_string().into()); } - let min_balance = rpc_client.get_minimum_balance_for_rent_exemption(STAKE_STATE_LEN)? + 1; + let min_balance = rpc_client + .get_minimum_balance_for_rent_exemption(STAKE_STATE_LEN)? + .saturating_add(MINIMUM_ACTIVE_STAKE); let pool_mint = get_token_mint(rpc_client, &stake_pool.pool_mint)?; // Sort from highest to lowest balance @@ -1106,7 +1103,7 @@ fn prepare_withdraw_accounts( } let available_for_withdrawal = stake_pool - .calc_lamports_withdraw_amount(lamports.saturating_sub(*MIN_STAKE_BALANCE)) + .calc_lamports_withdraw_amount(lamports.saturating_sub(min_balance)) .unwrap(); let pool_amount = u64::min(available_for_withdrawal, remaining_amount); @@ -1165,6 +1162,9 @@ fn command_withdraw( &pool_token_account, &stake_pool.pool_mint, )?; + let stake_account_rent_exemption = config + .rpc_client + .get_minimum_balance_for_rent_exemption(STAKE_STATE_LEN)?; // Check withdraw_from balance if token_account.amount < pool_amount { @@ -1192,7 +1192,10 @@ fn command_withdraw( let available_for_withdrawal = stake_pool .calc_lamports_withdraw_amount( - stake_account.lamports.saturating_sub(*MIN_STAKE_BALANCE), + stake_account + .lamports + .saturating_sub(MINIMUM_ACTIVE_STAKE) + .saturating_sub(stake_account_rent_exemption), ) .unwrap(); @@ -1268,17 +1271,13 @@ fn command_withdraw( // Use separate mutable variable because withdraw might create a new account let stake_receiver = stake_receiver_param.unwrap_or_else(|| { - let stake_receiver_account_balance = config - .rpc_client - .get_minimum_balance_for_rent_exemption(STAKE_STATE_LEN) - .unwrap(); let stake_keypair = new_stake_account( &config.fee_payer.pubkey(), &mut instructions, - stake_receiver_account_balance, + stake_account_rent_exemption, ); let stake_pubkey = stake_keypair.pubkey(); - total_rent_free_balances += stake_receiver_account_balance; + total_rent_free_balances += stake_account_rent_exemption; new_stake_keypairs.push(stake_keypair); stake_pubkey }); From 449789400a1782fcb6983b8c9e979394657d7b90 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Sun, 26 Sep 2021 23:58:30 +0200 Subject: [PATCH 0175/1076] stake-pool: Use `matches!` to allow for fix in underlying error (#2453) --- program/tests/vsa_remove.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index a8e221c0..b47a7dec 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -316,13 +316,10 @@ async fn fail_double_remove() { .unwrap() .unwrap(); - assert_eq!( + assert!(matches!( error, - TransactionError::InstructionError( - 1, - InstructionError::BorshIoError("Unkown".to_string()), // sic - ) - ); + TransactionError::InstructionError(1, InstructionError::BorshIoError(_),) + )); } #[tokio::test] From 51e395b41ba51debcc78fdf8fd8f9e4b180f85ef Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 6 Oct 2021 04:44:03 +0200 Subject: [PATCH 0176/1076] stake-pool: Add withdraw-sol command + CLI + docs (#2475) * stake-pool: plumb sol withdraw fee and authority * Add sol withdraw instruction and processor * Cleanup sysvar usage * Fix stack size violation * Add tests * Add CLI support * Add docs for new command * Integrate review feedback --- clients/cli/scripts/deposit-withdraw.sh | 2 + clients/cli/scripts/setup-stake-pool.sh | 2 +- clients/cli/src/main.rs | 443 ++++++++++++------ program/src/error.rs | 10 +- program/src/instruction.rs | 175 +++++-- program/src/processor.rs | 296 ++++++++---- program/src/state.rs | 182 ++++--- program/tests/deposit.rs | 12 +- program/tests/deposit_sol.rs | 60 +-- program/tests/helpers/mod.rs | 115 +++-- program/tests/huge_pool.rs | 22 +- program/tests/initialize.rs | 32 +- program/tests/set_deposit_fee.rs | 6 +- .../tests/{set_fee.rs => set_epoch_fee.rs} | 12 +- ..._authority.rs => set_funding_authority.rs} | 223 +++------ program/tests/set_manager.rs | 2 +- program/tests/set_preferred.rs | 8 +- program/tests/set_referral_fee.rs | 6 +- program/tests/set_staker.rs | 6 +- program/tests/set_withdrawal_fee.rs | 276 +++++++++-- program/tests/update_stake_pool_balance.rs | 10 +- program/tests/withdraw.rs | 6 +- program/tests/withdraw_sol.rs | 312 ++++++++++++ 23 files changed, 1538 insertions(+), 680 deletions(-) rename program/tests/{set_fee.rs => set_epoch_fee.rs} (93%) rename program/tests/{set_deposit_authority.rs => set_funding_authority.rs} (56%) create mode 100644 program/tests/withdraw_sol.rs diff --git a/clients/cli/scripts/deposit-withdraw.sh b/clients/cli/scripts/deposit-withdraw.sh index 318cee52..007d7250 100755 --- a/clients/cli/scripts/deposit-withdraw.sh +++ b/clients/cli/scripts/deposit-withdraw.sh @@ -72,3 +72,5 @@ echo "Depositing stakes into stake pool" deposit_stakes $stake_pool_pubkey $validator_list echo "Withdrawing stakes from stake pool" withdraw_stakes $stake_pool_pubkey $validator_list $half_sol_amount +echo "Withdrawing sol from stake pool" +$spl_stake_pool withdraw-sol $stake_pool_pubkey $half_sol_amount diff --git a/clients/cli/scripts/setup-stake-pool.sh b/clients/cli/scripts/setup-stake-pool.sh index ba2b5e64..71b9844d 100755 --- a/clients/cli/scripts/setup-stake-pool.sh +++ b/clients/cli/scripts/setup-stake-pool.sh @@ -30,7 +30,7 @@ setup_pool () { create_keypair $stake_pool_keyfile create_keypair $mint_keyfile - $spl_stake_pool create-pool --fee-numerator 3 --fee-denominator 100 \ + $spl_stake_pool create-pool --epoch-fee-numerator 3 --epoch-fee-denominator 100 \ --withdrawal-fee-numerator 5 --withdrawal-fee-denominator 1000 \ --max-validators $max_validators \ --pool-keypair $stake_pool_keyfile \ diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index cc2d3251..cca9fa56 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -34,7 +34,7 @@ use { spl_stake_pool::{ self, find_stake_program_address, find_transient_stake_program_address, find_withdraw_authority_program_address, - instruction::{DepositType, PreferredValidatorType}, + instruction::{FundingType, PreferredValidatorType}, stake_program::{self, StakeState}, state::{Fee, FeeType, StakePool, ValidatorList}, MINIMUM_ACTIVE_STAKE, @@ -47,7 +47,7 @@ struct Config { verbose: bool, manager: Box, staker: Box, - depositor: Option>, + funding_authority: Option>, token_owner: Box, fee_payer: Box, dry_run: bool, @@ -177,8 +177,8 @@ fn new_stake_account( fn command_create_pool( config: &Config, stake_deposit_authority: Option, - fee: Fee, - withdrawal_fee: Fee, + epoch_fee: Fee, + stake_withdrawal_fee: Fee, stake_deposit_fee: Fee, stake_referral_fee: u8, max_validators: u32, @@ -309,8 +309,8 @@ fn command_create_pool( &pool_fee_account, &spl_token::id(), stake_deposit_authority.as_ref().map(|x| x.pubkey()), - fee, - withdrawal_fee, + epoch_fee, + stake_withdrawal_fee, stake_deposit_fee, stake_referral_fee, max_validators, @@ -651,51 +651,51 @@ fn command_deposit_stake( let pool_withdraw_authority = find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; - let mut deposit_instructions = if let Some(stake_deposit_authority) = config.depositor.as_ref() - { - signers.push(stake_deposit_authority.as_ref()); - if stake_deposit_authority.pubkey() != stake_pool.stake_deposit_authority { - let error = format!( - "Invalid deposit authority specified, expected {}, received {}", - stake_pool.stake_deposit_authority, - stake_deposit_authority.pubkey() - ); - return Err(error.into()); - } + let mut deposit_instructions = + if let Some(stake_deposit_authority) = config.funding_authority.as_ref() { + signers.push(stake_deposit_authority.as_ref()); + if stake_deposit_authority.pubkey() != stake_pool.stake_deposit_authority { + let error = format!( + "Invalid deposit authority specified, expected {}, received {}", + stake_pool.stake_deposit_authority, + stake_deposit_authority.pubkey() + ); + return Err(error.into()); + } - spl_stake_pool::instruction::deposit_stake_with_authority( - &spl_stake_pool::id(), - stake_pool_address, - &stake_pool.validator_list, - &stake_deposit_authority.pubkey(), - &pool_withdraw_authority, - stake, - &config.staker.pubkey(), - &validator_stake_account, - &stake_pool.reserve_stake, - &pool_token_receiver_account, - &stake_pool.manager_fee_account, - &referrer_token_account, - &stake_pool.pool_mint, - &spl_token::id(), - ) - } else { - spl_stake_pool::instruction::deposit_stake( - &spl_stake_pool::id(), - stake_pool_address, - &stake_pool.validator_list, - &pool_withdraw_authority, - stake, - &config.staker.pubkey(), - &validator_stake_account, - &stake_pool.reserve_stake, - &pool_token_receiver_account, - &stake_pool.manager_fee_account, - &referrer_token_account, - &stake_pool.pool_mint, - &spl_token::id(), - ) - }; + spl_stake_pool::instruction::deposit_stake_with_authority( + &spl_stake_pool::id(), + stake_pool_address, + &stake_pool.validator_list, + &stake_deposit_authority.pubkey(), + &pool_withdraw_authority, + stake, + &config.staker.pubkey(), + &validator_stake_account, + &stake_pool.reserve_stake, + &pool_token_receiver_account, + &stake_pool.manager_fee_account, + &referrer_token_account, + &stake_pool.pool_mint, + &spl_token::id(), + ) + } else { + spl_stake_pool::instruction::deposit_stake( + &spl_stake_pool::id(), + stake_pool_address, + &stake_pool.validator_list, + &pool_withdraw_authority, + stake, + &config.staker.pubkey(), + &validator_stake_account, + &stake_pool.reserve_stake, + &pool_token_receiver_account, + &stake_pool.manager_fee_account, + &referrer_token_account, + &stake_pool.pool_mint, + &spl_token::id(), + ) + }; instructions.append(&mut deposit_instructions); @@ -776,7 +776,7 @@ fn command_deposit_sol( let pool_withdraw_authority = find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; - let mut deposit_instructions = if let Some(deposit_authority) = config.depositor.as_ref() { + let deposit_instruction = if let Some(deposit_authority) = config.funding_authority.as_ref() { let expected_sol_deposit_authority = stake_pool.sol_deposit_authority.ok_or_else(|| { "SOL deposit authority specified in arguments but stake pool has none".to_string() })?; @@ -820,7 +820,7 @@ fn command_deposit_sol( ) }; - instructions.append(&mut deposit_instructions); + instructions.push(deposit_instruction); let mut transaction = Transaction::new_with_payer(&instructions, Some(&config.fee_payer.pubkey())); @@ -846,6 +846,9 @@ fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { let sol_deposit_authority = stake_pool .sol_deposit_authority .map_or("None".into(), |pubkey| pubkey.to_string()); + let sol_withdraw_authority = stake_pool + .sol_withdraw_authority + .map_or("None".into(), |pubkey| pubkey.to_string()); if config.verbose { println!("Stake Pool Info"); @@ -856,6 +859,7 @@ fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { println!("Staker: {}", stake_pool.staker); println!("Depositor: {}", stake_pool.stake_deposit_authority); println!("SOL Deposit Authority: {}", sol_deposit_authority); + println!("SOL Withdraw Authority: {}", sol_withdraw_authority); println!("Withdraw Authority: {}", pool_withdraw_authority); println!("Pool Token Mint: {}", stake_pool.pool_mint); println!("Fee Account: {}", stake_pool.manager_fee_account); @@ -879,51 +883,31 @@ fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { } // Display fees information - if stake_pool.fee.numerator > 0 && stake_pool.fee.denominator > 0 { - println!("Epoch Fee: {} of epoch rewards", stake_pool.fee); - } else { - println!("Epoch Fee: none"); - } - if stake_pool.withdrawal_fee.numerator > 0 && stake_pool.withdrawal_fee.denominator > 0 { - println!( - "Withdrawal Fee: {} of withdrawal amount", - stake_pool.withdrawal_fee - ); - } else { - println!("Withdrawal Fee: none"); - } - if stake_pool.stake_deposit_fee.numerator > 0 && stake_pool.stake_deposit_fee.denominator > 0 { - println!( - "Stake Deposit Fee: {} of staked amount", - stake_pool.stake_deposit_fee - ); - } else { - println!("Stake Deposit Fee: none"); - } - if stake_pool.sol_deposit_fee.numerator > 0 && stake_pool.sol_deposit_fee.denominator > 0 { - println!( - "SOL Deposit Fee: {} of deposit amount", - stake_pool.sol_deposit_fee - ); - } else { - println!("SOL Deposit Fee: none"); - } - if stake_pool.sol_referral_fee > 0 { - println!( - "SOL Deposit Referral Fee: {}% of SOL Deposit Fee", - stake_pool.sol_referral_fee - ); - } else { - println!("SOL Deposit Referral Fee: none"); - } - if stake_pool.stake_referral_fee > 0 { - println!( - "Stake Deposit Referral Fee: {}% of Stake Deposit Fee", - stake_pool.stake_referral_fee - ); - } else { - println!("Stake Deposit Referral Fee: none"); - } + println!("Epoch Fee: {} of epoch rewards", stake_pool.epoch_fee); + println!( + "Stake Withdrawal Fee: {} of withdrawal amount", + stake_pool.stake_withdrawal_fee + ); + println!( + "SOL Withdrawal Fee: {} of withdrawal amount", + stake_pool.sol_withdrawal_fee + ); + println!( + "Stake Deposit Fee: {} of deposit amount", + stake_pool.stake_deposit_fee + ); + println!( + "SOL Deposit Fee: {} of deposit amount", + stake_pool.sol_deposit_fee + ); + println!( + "Stake Deposit Referral Fee: {}% of Stake Deposit Fee", + stake_pool.stake_referral_fee + ); + println!( + "SOL Deposit Referral Fee: {}% of SOL Deposit Fee", + stake_pool.sol_referral_fee + ); if config.verbose { println!(); @@ -1012,6 +996,10 @@ fn command_update( force: bool, no_merge: bool, ) -> CommandResult { + if config.no_update { + println!("Update requested, but --no-update flag specified, so doing nothing"); + return Ok(()); + } let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; let epoch_info = config.rpc_client.get_epoch_info()?; @@ -1133,7 +1121,7 @@ fn prepare_withdraw_accounts( Ok(withdraw_from) } -fn command_withdraw( +fn command_withdraw_stake( config: &Config, stake_pool_address: &Pubkey, use_reserve: bool, @@ -1316,6 +1304,123 @@ fn command_withdraw( Ok(()) } +fn command_withdraw_sol( + config: &Config, + stake_pool_address: &Pubkey, + sol_receiver: &Option, + pool_token_account: &Option, + pool_amount: f64, +) -> CommandResult { + if !config.no_update { + command_update(config, stake_pool_address, false, false)?; + } + + let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; + let pool_mint = get_token_mint(&config.rpc_client, &stake_pool.pool_mint)?; + let pool_amount = spl_token::ui_amount_to_amount(pool_amount, pool_mint.decimals); + + let sol_receiver = sol_receiver.unwrap_or_else(|| config.fee_payer.pubkey()); + let pool_token_account = pool_token_account.unwrap_or(get_associated_token_address( + &config.token_owner.pubkey(), + &stake_pool.pool_mint, + )); + let token_account = get_token_account( + &config.rpc_client, + &pool_token_account, + &stake_pool.pool_mint, + )?; + + // Check withdraw_from balance + if token_account.amount < pool_amount { + return Err(format!( + "Not enough token balance to withdraw {} pool tokens.\nMaximum withdraw amount is {} pool tokens.", + spl_token::amount_to_ui_amount(pool_amount, pool_mint.decimals), + spl_token::amount_to_ui_amount(token_account.amount, pool_mint.decimals) + ) + .into()); + } + + // Construct transaction to withdraw from withdraw_accounts account list + let user_transfer_authority = Keypair::new(); // ephemeral keypair just to do the transfer + let mut signers = vec![ + config.fee_payer.as_ref(), + config.token_owner.as_ref(), + &user_transfer_authority, + ]; + + let mut instructions = vec![ + // Approve spending token + spl_token::instruction::approve( + &spl_token::id(), + &pool_token_account, + &user_transfer_authority.pubkey(), + &config.token_owner.pubkey(), + &[], + pool_amount, + )?, + ]; + + let pool_withdraw_authority = + find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; + + let withdraw_instruction = if let Some(withdraw_authority) = config.funding_authority.as_ref() { + let expected_sol_withdraw_authority = + stake_pool.sol_withdraw_authority.ok_or_else(|| { + "SOL withdraw authority specified in arguments but stake pool has none".to_string() + })?; + signers.push(withdraw_authority.as_ref()); + if withdraw_authority.pubkey() != expected_sol_withdraw_authority { + let error = format!( + "Invalid deposit withdraw specified, expected {}, received {}", + expected_sol_withdraw_authority, + withdraw_authority.pubkey() + ); + return Err(error.into()); + } + + spl_stake_pool::instruction::withdraw_sol_with_authority( + &spl_stake_pool::id(), + stake_pool_address, + &withdraw_authority.pubkey(), + &pool_withdraw_authority, + &user_transfer_authority.pubkey(), + &pool_token_account, + &stake_pool.reserve_stake, + &sol_receiver, + &stake_pool.manager_fee_account, + &stake_pool.pool_mint, + &spl_token::id(), + pool_amount, + ) + } else { + spl_stake_pool::instruction::withdraw_sol( + &spl_stake_pool::id(), + stake_pool_address, + &pool_withdraw_authority, + &user_transfer_authority.pubkey(), + &pool_token_account, + &stake_pool.reserve_stake, + &sol_receiver, + &stake_pool.manager_fee_account, + &stake_pool.pool_mint, + &spl_token::id(), + pool_amount, + ) + }; + + instructions.push(withdraw_instruction); + + let mut transaction = + Transaction::new_with_payer(&instructions, Some(&config.fee_payer.pubkey())); + + let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + check_fee_payer_balance(config, fee_calculator.calculate_fee(transaction.message()))?; + unique_signers!(signers); + transaction.sign(&signers, recent_blockhash); + send_transaction(config, transaction)?; + Ok(()) +} + fn command_set_manager( config: &Config, stake_pool_address: &Pubkey, @@ -1385,22 +1490,22 @@ fn command_set_staker( Ok(()) } -fn command_set_deposit_authority( +fn command_set_funding_authority( config: &Config, stake_pool_address: &Pubkey, new_sol_deposit_authority: Option, - deposit_type: DepositType, + funding_type: FundingType, ) -> CommandResult { let mut signers = vec![config.fee_payer.as_ref(), config.manager.as_ref()]; unique_signers!(signers); let transaction = checked_transaction_with_signers( config, - &[spl_stake_pool::instruction::set_deposit_authority( + &[spl_stake_pool::instruction::set_funding_authority( &spl_stake_pool::id(), stake_pool_address, &config.manager.pubkey(), new_sol_deposit_authority.as_ref(), - deposit_type, + funding_type, )], &signers, )?; @@ -1522,13 +1627,13 @@ fn main() { ), ) .arg( - Arg::with_name("depositor") - .long("depositor") + Arg::with_name("funding_authority") + .long("funding-authority") .value_name("KEYPAIR") .validator(is_keypair) .takes_value(true) .help( - "Specify the stake pool depositor. \ + "Specify the stake pool funding authority, for deposits or withdrawals. \ This may be a keypair file, the ASK keyword.", ), ) @@ -1559,24 +1664,24 @@ fn main() { .subcommand(SubCommand::with_name("create-pool") .about("Create a new stake pool") .arg( - Arg::with_name("fee_numerator") - .long("fee-numerator") + Arg::with_name("epoch_fee_numerator") + .long("epoch-fee-numerator") .short("n") .validator(is_parsable::) .value_name("NUMERATOR") .takes_value(true) .required(true) - .help("Fee numerator, fee amount is numerator divided by denominator."), + .help("Epoch fee numerator, fee amount is numerator divided by denominator."), ) .arg( - Arg::with_name("fee_denominator") - .long("fee-denominator") + Arg::with_name("epoch_fee_denominator") + .long("epoch-fee-denominator") .short("d") .validator(is_parsable::) .value_name("DENOMINATOR") .takes_value(true) .required(true) - .help("Fee denominator, fee amount is numerator divided by denominator."), + .help("Epoch fee denominator, fee amount is numerator divided by denominator."), ) .arg( Arg::with_name("withdrawal_fee_numerator") @@ -1945,7 +2050,7 @@ fn main() { ) ) .subcommand(SubCommand::with_name("withdraw-stake") - .about("Withdraw amount from the stake pool") + .about("Withdraw active stake from the stake pool in exchange for pool tokens") .arg( Arg::with_name("pool") .index(1) @@ -1979,7 +2084,7 @@ fn main() { .value_name("STAKE_ACCOUNT_ADDRESS") .takes_value(true) .requires("withdraw_from") - .help("Stake account to receive SOL from the stake pool. Defaults to a new stake account."), + .help("Stake account from which to receive a stake from the stake pool. Defaults to a new stake account."), ) .arg( Arg::with_name("vote_account") @@ -2000,6 +2105,43 @@ fn main() { .arg("vote_account") ) ) + .subcommand(SubCommand::with_name("withdraw-sol") + .about("Withdraw SOL from the stake pool's reserve in exchange for pool tokens") + .arg( + Arg::with_name("pool") + .index(1) + .validator(is_pubkey) + .value_name("POOL_ADDRESS") + .takes_value(true) + .required(true) + .help("Stake pool address."), + ) + .arg( + Arg::with_name("amount") + .index(2) + .validator(is_amount) + .value_name("AMOUNT") + .takes_value(true) + .required(true) + .help("Amount of pool tokens to withdraw for SOL."), + ) + .arg( + Arg::with_name("pool_account") + .long("pool-account") + .validator(is_pubkey) + .value_name("ADDRESS") + .takes_value(true) + .help("Pool token account to withdraw tokens from. Defaults to the token-owner's associated token account."), + ) + .arg( + Arg::with_name("sol_receiver") + .long("sol-receiver") + .validator(is_pubkey) + .value_name("SYSTEM_ACCOUNT_ADDRESS") + .takes_value(true) + .help("System account to receive SOL from the stake pool. Defaults to the payer."), + ) + ) .subcommand(SubCommand::with_name("set-manager") .about("Change manager or fee receiver account for the stake pool. Must be signed by the current manager.") .arg( @@ -2054,8 +2196,8 @@ fn main() { .help("Public key for the new stake pool staker."), ) ) - .subcommand(SubCommand::with_name("set-deposit-authority") - .about("Change deposit authority account for the stake pool. Must be signed by the manager.") + .subcommand(SubCommand::with_name("set-funding-authority") + .about("Change one of the funding authorities for the stake pool. Must be signed by the manager.") .arg( Arg::with_name("pool") .index(1) @@ -2066,21 +2208,21 @@ fn main() { .help("Stake pool address."), ) .arg( - Arg::with_name("deposit_type") + Arg::with_name("funding_type") .index(2) - .value_name("DEPOSIT_TYPE") - .possible_values(&["stake", "sol"]) // DepositType enum + .value_name("FUNDING_TYPE") + .possible_values(&["stake-deposit", "sol-deposit", "sol-withdraw"]) // FundingType enum .takes_value(true) .required(true) - .help("Deposit type to be updated."), + .help("Funding type to be updated."), ) .arg( - Arg::with_name("new_stake_deposit_authority") + Arg::with_name("new_authority") .index(3) .validator(is_pubkey) .value_name("AUTHORITY_ADDRESS") .takes_value(true) - .help("Public key for the new stake pool sol deposit authority."), + .help("Public key for the new stake pool funding authority."), ) .arg( Arg::with_name("unset") @@ -2089,7 +2231,7 @@ fn main() { .help("Unset the stake deposit authority. The program will use a program derived address.") ) .group(ArgGroup::with_name("validator") - .arg("new_stake_deposit_authority") + .arg("new_authority") .arg("unset") .required(true) ) @@ -2108,7 +2250,7 @@ fn main() { .arg(Arg::with_name("fee_type") .index(2) .value_name("FEE_TYPE") - .possible_values(&["epoch", "stake-deposit", "sol-deposit", "withdrawal"]) // FeeType enum + .possible_values(&["epoch", "stake-deposit", "sol-deposit", "stake-withdrawal", "sol-withdrawal"]) // FeeType enum .takes_value(true) .required(true) .help("Fee type to be updated."), @@ -2183,10 +2325,10 @@ fn main() { &mut wallet_manager, ); - let depositor = if matches.is_present("depositor") { + let funding_authority = if matches.is_present("funding_authority") { Some(get_signer( &matches, - "depositor", + "funding_authority", &cli_config.keypair_path, &mut wallet_manager, )) @@ -2220,7 +2362,7 @@ fn main() { verbose, manager, staker, - depositor, + funding_authority, token_owner, fee_payer, dry_run, @@ -2231,8 +2373,8 @@ fn main() { let _ = match matches.subcommand() { ("create-pool", Some(arg_matches)) => { let stake_deposit_authority = keypair_of(arg_matches, "stake_deposit_authority"); - let numerator = value_t_or_exit!(arg_matches, "fee_numerator", u64); - let denominator = value_t_or_exit!(arg_matches, "fee_denominator", u64); + let e_numerator = value_t_or_exit!(arg_matches, "epoch_fee_numerator", u64); + let e_denominator = value_t_or_exit!(arg_matches, "epoch_fee_denominator", u64); let w_numerator = value_t!(arg_matches, "withdrawal_fee_numerator", u64); let w_denominator = value_t!(arg_matches, "withdrawal_fee_denominator", u64); let d_numerator = value_t!(arg_matches, "deposit_fee_numerator", u64); @@ -2246,8 +2388,8 @@ fn main() { &config, stake_deposit_authority, Fee { - denominator, - numerator, + numerator: e_numerator, + denominator: e_denominator, }, Fee { numerator: w_numerator.unwrap_or(0), @@ -2357,7 +2499,7 @@ fn main() { let pool_amount = value_t_or_exit!(arg_matches, "amount", f64); let stake_receiver = pubkey_of(arg_matches, "stake_receiver"); let use_reserve = arg_matches.is_present("use_reserve"); - command_withdraw( + command_withdraw_stake( &config, &stake_pool_address, use_reserve, @@ -2367,6 +2509,19 @@ fn main() { pool_amount, ) } + ("withdraw-sol", Some(arg_matches)) => { + let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); + let pool_account = pubkey_of(arg_matches, "pool_account"); + let pool_amount = value_t_or_exit!(arg_matches, "amount", f64); + let sol_receiver = pubkey_of(arg_matches, "sol_receiver"); + command_withdraw_sol( + &config, + &stake_pool_address, + &sol_receiver, + &pool_account, + pool_amount, + ) + } ("set-manager", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); let new_manager: Option = keypair_of(arg_matches, "new_manager"); @@ -2383,20 +2538,21 @@ fn main() { let new_staker = pubkey_of(arg_matches, "new_staker").unwrap(); command_set_staker(&config, &stake_pool_address, &new_staker) } - ("set-deposit-authority", Some(arg_matches)) => { + ("set-funding-authority", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); let new_stake_deposit_authority = pubkey_of(arg_matches, "new_stake_deposit_authority"); - let deposit_type = match arg_matches.value_of("deposit_type").unwrap() { - "sol" => DepositType::Sol, - "stake" => DepositType::Stake, + let funding_type = match arg_matches.value_of("funding_type").unwrap() { + "sol-deposit" => FundingType::SolDeposit, + "stake-deposit" => FundingType::StakeDeposit, + "sol-withdraw" => FundingType::SolWithdraw, _ => unreachable!(), }; let _unset = arg_matches.is_present("unset"); - command_set_deposit_authority( + command_set_funding_authority( &config, &stake_pool_address, new_stake_deposit_authority, - deposit_type, + funding_type, ) } ("set-fee", Some(arg_matches)) => { @@ -2415,9 +2571,16 @@ fn main() { "sol-deposit" => { command_set_fee(&config, &stake_pool_address, FeeType::SolDeposit(new_fee)) } - "withdrawal" => { - command_set_fee(&config, &stake_pool_address, FeeType::Withdrawal(new_fee)) - } + "stake-withdrawal" => command_set_fee( + &config, + &stake_pool_address, + FeeType::StakeWithdrawal(new_fee), + ), + "sol-withdrawal" => command_set_fee( + &config, + &stake_pool_address, + FeeType::SolWithdrawal(new_fee), + ), _ => unreachable!(), } } diff --git a/program/src/error.rs b/program/src/error.rs index a8530e73..48bf1bc3 100644 --- a/program/src/error.rs +++ b/program/src/error.rs @@ -111,7 +111,7 @@ pub enum StakePoolError { // 30. /// Provided stake deposit authority does not match the program's - #[error("FeeIncreaseTooHigh")] + #[error("InvalidStakeDepositAuthority")] InvalidStakeDepositAuthority, /// Provided sol deposit authority does not match the program's #[error("InvalidSolDepositAuthority")] @@ -122,6 +122,14 @@ pub enum StakePoolError { /// Provided validator stake account already has a transient stake account in use #[error("TransientAccountInUse")] TransientAccountInUse, + /// Provided sol withdraw authority does not match the program's + #[error("InvalidSolWithdrawAuthority")] + InvalidSolWithdrawAuthority, + + // 35. + /// Too much SOL withdrawn from the stake pool's reserve account + #[error("SolWithdrawalTooLarge")] + SolWithdrawalTooLarge, } impl From for ProgramError { fn from(e: StakePoolError) -> Self { diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 2cd62b19..d4e64602 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -28,15 +28,17 @@ pub enum PreferredValidatorType { Withdraw, } -/// Defines which deposit authority to update in the `SetDepositAuthority` +/// Defines which authority to update in the `SetFundingAuthority` /// instruction #[repr(C)] #[derive(Clone, Debug, PartialEq, BorshSerialize, BorshDeserialize, BorshSchema)] -pub enum DepositType { +pub enum FundingType { /// Sets the stake deposit authority - Stake, + StakeDeposit, /// Sets the SOL deposit authority - Sol, + SolDeposit, + /// Sets the SOL withdraw authority + SolWithdraw, } /// Instructions supported by the StakePool program. @@ -53,10 +55,8 @@ pub enum StakePoolInstruction { /// and staker / withdrawer authority set to pool withdraw authority. /// 5. `[]` Pool token mint. Must have zero supply, owned by withdraw authority. /// 6. `[]` Pool account to deposit the generated fee for manager. - /// 7. `[]` Clock sysvar - /// 8. `[]` Rent sysvar - /// 9. `[]` Token program id - /// 10. `[]` (Optional) Deposit authority that must sign all deposits. + /// 7. `[]` Token program id + /// 8. `[]` (Optional) Deposit authority that must sign all deposits. /// Defaults to the program address generated using /// `find_deposit_authority_program_address`, making deposits permissionless. Initialize { @@ -242,8 +242,7 @@ pub enum StakePoolInstruction { /// 3. `[]` Reserve stake account /// 4. `[w]` Account to receive pool fee tokens /// 5. `[w]` Pool mint account - /// 6. `[]` Sysvar clock account - /// 7. `[]` Pool token program + /// 6. `[]` Pool token program UpdateStakePoolBalance, /// Cleans up validator stake account entries marked as `ReadyForRemoval` @@ -310,7 +309,6 @@ pub enum StakePoolInstruction { /// /// 0. `[w]` StakePool /// 1. `[s]` Manager - /// 2. `[]` Sysvar clock SetFee { /// Type of fee to update and value to update it to #[allow(dead_code)] // but it's not @@ -328,25 +326,42 @@ pub enum StakePoolInstruction { /// representing ownership into the pool. Inputs are converted to the current ratio. /// /// 0. `[w]` Stake pool - /// 1. `[s]/[]` Stake pool sol deposit authority. - /// 2. `[]` Stake pool withdraw authority - /// 3. `[w]` Reserve stake account, to withdraw rent exempt reserve - /// 4. `[s]` Account providing the lamports to be deposited into the pool - /// 5. `[w]` User account to receive pool tokens - /// 6. `[w]` Account to receive pool fee tokens - /// 7. `[w]` Account to receive a portion of pool fee tokens as referral fees - /// 8. `[w]` Pool token mint account - /// 9. '[]' Sysvar clock account - /// 10 `[]` System program account - /// 11. `[]` Pool token program id, + /// 1. `[]` Stake pool withdraw authority + /// 2. `[w]` Reserve stake account, to deposit SOL + /// 3. `[s]` Account providing the lamports to be deposited into the pool + /// 4. `[w]` User account to receive pool tokens + /// 5. `[w]` Account to receive fee tokens + /// 6. `[w]` Account to receive a portion of fee as referral fees + /// 7. `[w]` Pool token mint account + /// 8. `[]` System program account + /// 9. `[]` Token program id + /// 10. `[s]` (Optional) Stake pool sol deposit authority. DepositSol(u64), /// (Manager only) Update SOL deposit authority /// /// 0. `[w]` StakePool /// 1. `[s]` Manager - /// 2. '[]` New sol_deposit_authority pubkey or none - SetDepositAuthority(DepositType), + /// 2. '[]` New authority pubkey or none + SetFundingAuthority(FundingType), + + /// Withdraw SOL directly from the pool's reserve account. Fails if the + /// reserve does not have enough SOL. + /// + /// 0. `[w]` Stake pool + /// 1. `[]` Stake pool withdraw authority + /// 2. `[s]` User transfer authority, for pool token account + /// 3. `[w]` User account to burn pool tokens + /// 4. `[w]` Reserve stake account, to withdraw SOL + /// 5. `[w]` Account receiving the lamports from the reserve, must be a system account + /// 6. `[w]` Account to receive pool fee tokens + /// 7. `[w]` Pool token mint account + /// 8. '[]' Clock sysvar + /// 9. '[]' Stake history sysvar + /// 10. `[]` Stake program account + /// 11. `[]` Token program id + /// 12. `[s]` (Optional) Stake pool sol withdraw authority + WithdrawSol(u64), } /// Creates an 'initialize' instruction. @@ -376,15 +391,13 @@ pub fn initialize( }; let data = init_data.try_to_vec().unwrap(); let mut accounts = vec![ - AccountMeta::new(*stake_pool, true), + AccountMeta::new(*stake_pool, false), AccountMeta::new_readonly(*manager, true), AccountMeta::new_readonly(*staker, false), AccountMeta::new(*validator_list, false), AccountMeta::new_readonly(*reserve_stake, false), AccountMeta::new_readonly(*pool_mint, false), AccountMeta::new_readonly(*manager_pool_account, false), - AccountMeta::new_readonly(sysvar::clock::id(), false), - AccountMeta::new_readonly(sysvar::rent::id(), false), AccountMeta::new_readonly(*token_program_id, false), ]; if let Some(deposit_authority) = deposit_authority { @@ -768,7 +781,6 @@ pub fn update_stake_pool_balance( AccountMeta::new_readonly(*reserve_stake, false), AccountMeta::new(*manager_fee_account, false), AccountMeta::new(*stake_pool_mint, false), - AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(*token_program_id, false), ]; Instruction { @@ -981,7 +993,7 @@ pub fn deposit_sol( pool_mint: &Pubkey, token_program_id: &Pubkey, amount: u64, -) -> Vec { +) -> Instruction { let accounts = vec![ AccountMeta::new(*stake_pool, false), AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), @@ -991,24 +1003,21 @@ pub fn deposit_sol( AccountMeta::new(*manager_fee_account, false), AccountMeta::new(*referrer_pool_tokens_account, false), AccountMeta::new(*pool_mint, false), - AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(system_program::id(), false), AccountMeta::new_readonly(*token_program_id, false), ]; - vec![Instruction { + Instruction { program_id: *program_id, accounts, data: StakePoolInstruction::DepositSol(amount) .try_to_vec() .unwrap(), - }] + } } -/// Creates instructions required to deposit SOL directly into a stake pool. +/// Creates instruction required to deposit SOL directly into a stake pool. /// The difference with `deposit_sol()` is that a deposit -/// authority must sign this instruction, which is required for private pools. -/// `require_deposit_authority` should be false only if -/// `sol_deposit_authority == None` +/// authority must sign this instruction. pub fn deposit_sol_with_authority( program_id: &Pubkey, stake_pool: &Pubkey, @@ -1022,7 +1031,7 @@ pub fn deposit_sol_with_authority( pool_mint: &Pubkey, token_program_id: &Pubkey, amount: u64, -) -> Vec { +) -> Instruction { let accounts = vec![ AccountMeta::new(*stake_pool, false), AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), @@ -1032,18 +1041,17 @@ pub fn deposit_sol_with_authority( AccountMeta::new(*manager_fee_account, false), AccountMeta::new(*referrer_pool_tokens_account, false), AccountMeta::new(*pool_mint, false), - AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(system_program::id(), false), AccountMeta::new_readonly(*token_program_id, false), AccountMeta::new_readonly(*sol_deposit_authority, true), ]; - vec![Instruction { + Instruction { program_id: *program_id, accounts, data: StakePoolInstruction::DepositSol(amount) .try_to_vec() .unwrap(), - }] + } } /// Creates a 'WithdrawStake' instruction. @@ -1086,6 +1094,84 @@ pub fn withdraw_stake( } } +/// Creates instruction required to withdraw SOL directly from a stake pool. +pub fn withdraw_sol( + program_id: &Pubkey, + stake_pool: &Pubkey, + stake_pool_withdraw_authority: &Pubkey, + user_transfer_authority: &Pubkey, + pool_tokens_from: &Pubkey, + reserve_stake_account: &Pubkey, + lamports_to: &Pubkey, + manager_fee_account: &Pubkey, + pool_mint: &Pubkey, + token_program_id: &Pubkey, + pool_tokens: u64, +) -> Instruction { + let accounts = vec![ + AccountMeta::new(*stake_pool, false), + AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), + AccountMeta::new_readonly(*user_transfer_authority, true), + AccountMeta::new(*pool_tokens_from, false), + AccountMeta::new(*reserve_stake_account, false), + AccountMeta::new(*lamports_to, false), + AccountMeta::new(*manager_fee_account, false), + AccountMeta::new(*pool_mint, false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(sysvar::stake_history::id(), false), + AccountMeta::new_readonly(stake_program::id(), false), + AccountMeta::new_readonly(*token_program_id, false), + ]; + Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::WithdrawSol(pool_tokens) + .try_to_vec() + .unwrap(), + } +} + +/// Creates instruction required to withdraw SOL directly from a stake pool. +/// The difference with `withdraw_sol()` is that the sol withdraw authority +/// must sign this instruction. +pub fn withdraw_sol_with_authority( + program_id: &Pubkey, + stake_pool: &Pubkey, + sol_withdraw_authority: &Pubkey, + stake_pool_withdraw_authority: &Pubkey, + user_transfer_authority: &Pubkey, + pool_tokens_from: &Pubkey, + reserve_stake_account: &Pubkey, + lamports_to: &Pubkey, + manager_fee_account: &Pubkey, + pool_mint: &Pubkey, + token_program_id: &Pubkey, + pool_tokens: u64, +) -> Instruction { + let accounts = vec![ + AccountMeta::new(*stake_pool, false), + AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), + AccountMeta::new_readonly(*user_transfer_authority, true), + AccountMeta::new(*pool_tokens_from, false), + AccountMeta::new(*reserve_stake_account, false), + AccountMeta::new(*lamports_to, false), + AccountMeta::new(*manager_fee_account, false), + AccountMeta::new(*pool_mint, false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(sysvar::stake_history::id(), false), + AccountMeta::new_readonly(stake_program::id(), false), + AccountMeta::new_readonly(*token_program_id, false), + AccountMeta::new_readonly(*sol_withdraw_authority, true), + ]; + Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::WithdrawSol(pool_tokens) + .try_to_vec() + .unwrap(), + } +} + /// Creates a 'set manager' instruction. pub fn set_manager( program_id: &Pubkey, @@ -1117,7 +1203,6 @@ pub fn set_fee( let accounts = vec![ AccountMeta::new(*stake_pool, false), AccountMeta::new_readonly(*manager, true), - AccountMeta::new_readonly(sysvar::clock::id(), false), ]; Instruction { program_id: *program_id, @@ -1145,13 +1230,13 @@ pub fn set_staker( } } -/// Creates a 'set deposit authority' instruction. -pub fn set_deposit_authority( +/// Creates a 'SetFundingAuthority' instruction. +pub fn set_funding_authority( program_id: &Pubkey, stake_pool: &Pubkey, manager: &Pubkey, new_sol_deposit_authority: Option<&Pubkey>, - deposit_type: DepositType, + funding_type: FundingType, ) -> Instruction { let mut accounts = vec![ AccountMeta::new(*stake_pool, false), @@ -1163,7 +1248,7 @@ pub fn set_deposit_authority( Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::SetDepositAuthority(deposit_type) + data: StakePoolInstruction::SetFundingAuthority(funding_type) .try_to_vec() .unwrap(), } diff --git a/program/src/processor.rs b/program/src/processor.rs index 50297cfa..fa559901 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1,11 +1,10 @@ //! Program state processor -use crate::instruction::DepositType; use { crate::{ error::StakePoolError, find_deposit_authority_program_address, - instruction::{PreferredValidatorType, StakePoolInstruction}, + instruction::{FundingType, PreferredValidatorType, StakePoolInstruction}, minimum_reserve_lamports, minimum_stake_lamports, stake_program, state::{ AccountType, Fee, FeeType, StakePool, StakeStatus, ValidatorList, ValidatorListHeader, @@ -29,7 +28,6 @@ use { program_pack::Pack, pubkey::Pubkey, rent::Rent, - stake_history::StakeHistory, system_instruction, system_program, sysvar::Sysvar, }, @@ -484,13 +482,14 @@ impl Processor { } /// Processes `Initialize` instruction. + #[inline(never)] // needed due to stack size violation fn process_initialize( program_id: &Pubkey, accounts: &[AccountInfo], - fee: Fee, + epoch_fee: Fee, withdrawal_fee: Fee, - stake_deposit_fee: Fee, - stake_referral_fee: u8, + deposit_fee: Fee, + referral_fee: u8, max_validators: u32, ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); @@ -501,12 +500,10 @@ impl Processor { let reserve_stake_info = next_account_info(account_info_iter)?; let pool_mint_info = next_account_info(account_info_iter)?; let manager_fee_info = next_account_info(account_info_iter)?; - let clock_info = next_account_info(account_info_iter)?; - let clock = &Clock::from_account_info(clock_info)?; - let rent_info = next_account_info(account_info_iter)?; - let rent = &Rent::from_account_info(rent_info)?; let token_program_info = next_account_info(account_info_iter)?; + let rent = Rent::get()?; + if !manager_info.is_signer { msg!("Manager did not sign initialization"); return Err(StakePoolError::SignatureMissing.into()); @@ -560,10 +557,10 @@ impl Processor { } // Numerator should be smaller than or equal to denominator (fee <= 1) - if fee.numerator > fee.denominator + if epoch_fee.numerator > epoch_fee.denominator || withdrawal_fee.numerator > withdrawal_fee.denominator - || stake_deposit_fee.numerator > stake_deposit_fee.denominator - || stake_referral_fee > 100u8 + || deposit_fee.numerator > deposit_fee.denominator + || referral_fee > 100u8 { return Err(StakePoolError::FeeTooHigh.into()); } @@ -655,17 +652,22 @@ impl Processor { stake_pool.pool_mint = *pool_mint_info.key; stake_pool.manager_fee_account = *manager_fee_info.key; stake_pool.token_program_id = *token_program_info.key; - stake_pool.last_update_epoch = clock.epoch; + stake_pool.last_update_epoch = Clock::get()?.epoch; stake_pool.total_stake_lamports = total_stake_lamports; - stake_pool.fee = fee; + stake_pool.epoch_fee = epoch_fee; stake_pool.next_epoch_fee = None; stake_pool.preferred_deposit_validator_vote_address = None; stake_pool.preferred_withdraw_validator_vote_address = None; - stake_pool.stake_deposit_fee = stake_deposit_fee; - stake_pool.withdrawal_fee = withdrawal_fee; - stake_pool.next_withdrawal_fee = None; - stake_pool.stake_referral_fee = stake_referral_fee; + stake_pool.stake_deposit_fee = deposit_fee; + stake_pool.stake_withdrawal_fee = withdrawal_fee; + stake_pool.next_stake_withdrawal_fee = None; + stake_pool.stake_referral_fee = referral_fee; stake_pool.sol_deposit_authority = None; + stake_pool.sol_deposit_fee = deposit_fee; + stake_pool.sol_referral_fee = referral_fee; + stake_pool.sol_withdraw_authority = None; + stake_pool.sol_withdrawal_fee = withdrawal_fee; + stake_pool.next_stake_withdrawal_fee = None; stake_pool .serialize(&mut *stake_pool_info.data.borrow_mut()) @@ -673,6 +675,7 @@ impl Processor { } /// Processes `AddValidatorToPool` instruction. + #[inline(never)] // needed due to stack size violation fn process_add_validator_to_pool( program_id: &Pubkey, accounts: &[AccountInfo], @@ -808,6 +811,7 @@ impl Processor { } /// Processes `RemoveValidatorFromPool` instruction. + #[inline(never)] // needed due to stack size violation fn process_remove_validator_from_pool( program_id: &Pubkey, accounts: &[AccountInfo], @@ -965,6 +969,7 @@ impl Processor { } /// Processes `DecreaseValidatorStake` instruction. + #[inline(never)] // needed due to stack size violation fn process_decrease_validator_stake( program_id: &Pubkey, accounts: &[AccountInfo], @@ -1103,6 +1108,7 @@ impl Processor { } /// Processes `IncreaseValidatorStake` instruction. + #[inline(never)] // needed due to stack size violation fn process_increase_validator_stake( program_id: &Pubkey, accounts: &[AccountInfo], @@ -1262,6 +1268,7 @@ impl Processor { } /// Process `SetPreferredValidator` instruction + #[inline(never)] // needed due to stack size violation fn process_set_preferred_validator( program_id: &Pubkey, accounts: &[AccountInfo], @@ -1324,6 +1331,7 @@ impl Processor { } /// Processes `UpdateValidatorListBalance` instruction. + #[inline(always)] // needed to maximize number of validators fn process_update_validator_list_balance( program_id: &Pubkey, accounts: &[AccountInfo], @@ -1564,6 +1572,7 @@ impl Processor { } /// Processes `UpdateStakePoolBalance` instruction. + #[inline(always)] // needed to optimize number of validators fn process_update_stake_pool_balance( program_id: &Pubkey, accounts: &[AccountInfo], @@ -1575,9 +1584,8 @@ impl Processor { let reserve_stake_info = next_account_info(account_info_iter)?; let manager_fee_info = next_account_info(account_info_iter)?; let pool_mint_info = next_account_info(account_info_iter)?; - let clock_info = next_account_info(account_info_iter)?; - let clock = &Clock::from_account_info(clock_info)?; let token_program_info = next_account_info(account_info_iter)?; + let clock = Clock::get()?; check_account_owner(stake_pool_info, program_id)?; let mut stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; @@ -1659,13 +1667,17 @@ impl Processor { } if stake_pool.last_update_epoch < clock.epoch { - if let Some(next_epoch_fee) = stake_pool.next_epoch_fee { - stake_pool.fee = next_epoch_fee; + if let Some(fee) = stake_pool.next_epoch_fee { + stake_pool.epoch_fee = fee; stake_pool.next_epoch_fee = None; } - if let Some(next_withdrawal_fee) = stake_pool.next_withdrawal_fee { - stake_pool.withdrawal_fee = next_withdrawal_fee; - stake_pool.next_withdrawal_fee = None; + if let Some(fee) = stake_pool.next_stake_withdrawal_fee { + stake_pool.stake_withdrawal_fee = fee; + stake_pool.next_stake_withdrawal_fee = None; + } + if let Some(fee) = stake_pool.next_sol_withdrawal_fee { + stake_pool.sol_withdrawal_fee = fee; + stake_pool.next_sol_withdrawal_fee = None; } stake_pool.last_update_epoch = clock.epoch; } @@ -1680,6 +1692,7 @@ impl Processor { } /// Processes the `CleanupRemovedValidatorEntries` instruction + #[inline(never)] // needed to avoid stack size violation fn process_cleanup_removed_validator_entries( program_id: &Pubkey, accounts: &[AccountInfo], @@ -1708,33 +1721,8 @@ impl Processor { Ok(()) } - /// Check stake activation status - #[allow(clippy::unnecessary_wraps)] - fn _check_stake_activation( - stake_info: &AccountInfo, - clock: &Clock, - stake_history: &StakeHistory, - ) -> ProgramResult { - let stake_acc_state = - try_from_slice_unchecked::(&stake_info.data.borrow()) - .unwrap(); - let delegation = stake_acc_state.delegation(); - if let Some(delegation) = delegation { - let target_epoch = clock.epoch; - let history = Some(stake_history); - let fix_stake_deactivate = true; - let (effective, activating, deactivating) = delegation - .stake_activating_and_deactivating(target_epoch, history, fix_stake_deactivate); - if activating != 0 || deactivating != 0 || effective == 0 { - return Err(StakePoolError::UserStakeNotActive.into()); - } - } else { - return Err(StakePoolError::WrongStakeState.into()); - } - Ok(()) - } - /// Processes [DepositStake](enum.Instruction.html). + #[inline(never)] // needed to avoid stack size violation fn process_deposit_stake(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; @@ -2001,7 +1989,8 @@ impl Processor { Ok(()) } - /// Processes [DepositStake](enum.Instruction.html). + /// Processes [DepositSol](enum.Instruction.html). + #[inline(never)] // needed to avoid stack size violation fn process_deposit_sol( program_id: &Pubkey, accounts: &[AccountInfo], @@ -2016,20 +2005,18 @@ impl Processor { let manager_fee_info = next_account_info(account_info_iter)?; let referrer_fee_info = next_account_info(account_info_iter)?; let pool_mint_info = next_account_info(account_info_iter)?; - let clock_info = next_account_info(account_info_iter)?; - let clock = &Clock::from_account_info(clock_info)?; let system_program_info = next_account_info(account_info_iter)?; let token_program_info = next_account_info(account_info_iter)?; let sol_deposit_authority_info = next_account_info(account_info_iter); + let clock = Clock::get()?; + check_account_owner(stake_pool_info, program_id)?; let mut stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); } - // Self::check_stake_activation(stake_info, clock, stake_history)?; - stake_pool.check_authority_withdraw( withdraw_authority_info.key, program_id, @@ -2144,6 +2131,7 @@ impl Processor { } /// Processes [WithdrawStake](enum.Instruction.html). + #[inline(never)] // needed to avoid stack size violation fn process_withdraw_stake( program_id: &Pubkey, accounts: &[AccountInfo], @@ -2207,7 +2195,7 @@ impl Processor { 0 } else { stake_pool - .calc_pool_tokens_withdrawal_fee(pool_tokens) + .calc_pool_tokens_stake_withdrawal_fee(pool_tokens) .ok_or(StakePoolError::CalculationFailure)? }; let pool_tokens_burnt = pool_tokens @@ -2382,7 +2370,147 @@ impl Processor { Ok(()) } + /// Processes [WithdrawSol](enum.Instruction.html). + #[inline(never)] // needed to avoid stack size violation + fn process_withdraw_sol( + program_id: &Pubkey, + accounts: &[AccountInfo], + pool_tokens: u64, + ) -> ProgramResult { + let account_info_iter = &mut accounts.iter(); + let stake_pool_info = next_account_info(account_info_iter)?; + let withdraw_authority_info = next_account_info(account_info_iter)?; + let user_transfer_authority_info = next_account_info(account_info_iter)?; + let burn_from_pool_info = next_account_info(account_info_iter)?; + let reserve_stake_info = next_account_info(account_info_iter)?; + let destination_lamports_info = next_account_info(account_info_iter)?; + let manager_fee_info = next_account_info(account_info_iter)?; + let pool_mint_info = next_account_info(account_info_iter)?; + let clock_info = next_account_info(account_info_iter)?; + let stake_history_info = next_account_info(account_info_iter)?; + let stake_program_info = next_account_info(account_info_iter)?; + let token_program_info = next_account_info(account_info_iter)?; + let sol_withdraw_authority_info = next_account_info(account_info_iter); + + check_account_owner(stake_pool_info, program_id)?; + let mut stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; + if !stake_pool.is_valid() { + return Err(StakePoolError::InvalidState.into()); + } + + stake_pool.check_authority_withdraw( + withdraw_authority_info.key, + program_id, + stake_pool_info.key, + )?; + stake_pool.check_sol_withdraw_authority(sol_withdraw_authority_info)?; + stake_pool.check_mint(pool_mint_info)?; + stake_pool.check_reserve_stake(reserve_stake_info)?; + + if stake_pool.token_program_id != *token_program_info.key { + return Err(ProgramError::IncorrectProgramId); + } + check_stake_program(stake_program_info.key)?; + + if stake_pool.manager_fee_account != *manager_fee_info.key { + return Err(StakePoolError::InvalidFeeAccount.into()); + } + + // We want this to hold to ensure that withdraw_sol burns pool tokens + // at the right price + if stake_pool.last_update_epoch < Clock::get()?.epoch { + return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); + } + + // To prevent a faulty manager fee account from preventing withdrawals + // if the token program does not own the account, or if the account is not initialized + let pool_tokens_fee = if stake_pool.manager_fee_account == *burn_from_pool_info.key + || stake_pool.check_manager_fee_info(manager_fee_info).is_err() + { + 0 + } else { + stake_pool + .calc_pool_tokens_sol_withdrawal_fee(pool_tokens) + .ok_or(StakePoolError::CalculationFailure)? + }; + let pool_tokens_burnt = pool_tokens + .checked_sub(pool_tokens_fee) + .ok_or(StakePoolError::CalculationFailure)?; + + let withdraw_lamports = stake_pool + .calc_lamports_withdraw_amount(pool_tokens_burnt) + .ok_or(StakePoolError::CalculationFailure)?; + + if withdraw_lamports == 0 { + return Err(StakePoolError::WithdrawalTooSmall.into()); + } + + let new_reserve_lamports = reserve_stake_info + .lamports() + .saturating_sub(withdraw_lamports); + let stake_state = try_from_slice_unchecked::( + &reserve_stake_info.data.borrow(), + )?; + if let stake_program::StakeState::Initialized(meta) = stake_state { + let minimum_reserve_lamports = minimum_reserve_lamports(&meta); + if new_reserve_lamports < minimum_reserve_lamports { + msg!("Attempting to withdraw {} lamports, maximum possible SOL withdrawal is {} lamports", + withdraw_lamports, + reserve_stake_info.lamports().saturating_sub(minimum_reserve_lamports) + ); + return Err(StakePoolError::SolWithdrawalTooLarge.into()); + } + } else { + msg!("Reserve stake account not in intialized state"); + return Err(StakePoolError::WrongStakeState.into()); + }; + + Self::token_burn( + token_program_info.clone(), + burn_from_pool_info.clone(), + pool_mint_info.clone(), + user_transfer_authority_info.clone(), + pool_tokens_burnt, + )?; + + if pool_tokens_fee > 0 { + Self::token_transfer( + token_program_info.clone(), + burn_from_pool_info.clone(), + manager_fee_info.clone(), + user_transfer_authority_info.clone(), + pool_tokens_fee, + )?; + } + + Self::stake_withdraw( + stake_pool_info.key, + reserve_stake_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + destination_lamports_info.clone(), + clock_info.clone(), + stake_history_info.clone(), + stake_program_info.clone(), + withdraw_lamports, + )?; + + stake_pool.pool_token_supply = stake_pool + .pool_token_supply + .checked_sub(pool_tokens_burnt) + .ok_or(StakePoolError::CalculationFailure)?; + stake_pool.total_stake_lamports = stake_pool + .total_stake_lamports + .checked_sub(withdraw_lamports) + .ok_or(StakePoolError::CalculationFailure)?; + stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; + + Ok(()) + } + /// Processes [SetManager](enum.Instruction.html). + #[inline(never)] // needed to avoid stack size violation fn process_set_manager(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; @@ -2417,6 +2545,7 @@ impl Processor { } /// Processes [SetFee](enum.Instruction.html). + #[inline(never)] // needed to avoid stack size violation fn process_set_fee( program_id: &Pubkey, accounts: &[AccountInfo], @@ -2425,15 +2554,13 @@ impl Processor { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; let manager_info = next_account_info(account_info_iter)?; - let clock_info = next_account_info(account_info_iter)?; - let clock = &Clock::from_account_info(clock_info)?; + let clock = Clock::get()?; check_account_owner(stake_pool_info, program_id)?; let mut stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; if !stake_pool.is_valid() { return Err(StakePoolError::InvalidState.into()); } - stake_pool.check_manager(manager_info)?; if fee.can_only_change_next_epoch() && stake_pool.last_update_epoch < clock.epoch { @@ -2441,14 +2568,13 @@ impl Processor { } fee.check_too_high()?; - fee.check_withdrawal(&stake_pool.withdrawal_fee)?; - - stake_pool.update_fee(&fee); + stake_pool.update_fee(&fee)?; stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; Ok(()) } /// Processes [SetStaker](enum.Instruction.html). + #[inline(never)] // needed to avoid stack size violation fn process_set_staker(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; @@ -2471,19 +2597,20 @@ impl Processor { Ok(()) } - /// Processes [SetStakeDepositAuthority/SetSolDepositAuthority](enum.Instruction.html). - fn process_set_deposit_authority( + /// Processes [SetFundingAuthority](enum.Instruction.html). + #[inline(never)] // needed to avoid stack size violation + fn process_set_funding_authority( program_id: &Pubkey, accounts: &[AccountInfo], - deposit_type: DepositType, + funding_type: FundingType, ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; let manager_info = next_account_info(account_info_iter)?; - let new_sol_deposit_authority = next_account_info(account_info_iter).ok().map( - |new_sol_deposit_authority_account_info| *new_sol_deposit_authority_account_info.key, - ); + let new_authority = next_account_info(account_info_iter) + .ok() + .map(|new_authority_account_info| *new_authority_account_info.key); check_account_owner(stake_pool_info, program_id)?; let mut stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; @@ -2491,13 +2618,14 @@ impl Processor { return Err(StakePoolError::InvalidState.into()); } stake_pool.check_manager(manager_info)?; - match deposit_type { - DepositType::Stake => { - stake_pool.stake_deposit_authority = new_sol_deposit_authority.unwrap_or( + match funding_type { + FundingType::StakeDeposit => { + stake_pool.stake_deposit_authority = new_authority.unwrap_or( find_deposit_authority_program_address(program_id, stake_pool_info.key).0, ); } - DepositType::Sol => stake_pool.sol_deposit_authority = new_sol_deposit_authority, + FundingType::SolDeposit => stake_pool.sol_deposit_authority = new_authority, + FundingType::SolWithdraw => stake_pool.sol_withdraw_authority = new_authority, } stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; Ok(()) @@ -2597,25 +2725,29 @@ impl Processor { msg!("Instruction: WithdrawStake"); Self::process_withdraw_stake(program_id, accounts, amount) } - StakePoolInstruction::SetManager => { - msg!("Instruction: SetManager"); - Self::process_set_manager(program_id, accounts) - } StakePoolInstruction::SetFee { fee } => { msg!("Instruction: SetFee"); Self::process_set_fee(program_id, accounts, fee) } + StakePoolInstruction::SetManager => { + msg!("Instruction: SetManager"); + Self::process_set_manager(program_id, accounts) + } StakePoolInstruction::SetStaker => { msg!("Instruction: SetStaker"); Self::process_set_staker(program_id, accounts) } + StakePoolInstruction::SetFundingAuthority(funding_type) => { + msg!("Instruction: SetFundingAuthority"); + Self::process_set_funding_authority(program_id, accounts, funding_type) + } StakePoolInstruction::DepositSol(lamports) => { msg!("Instruction: DepositSol"); Self::process_deposit_sol(program_id, accounts, lamports) } - StakePoolInstruction::SetDepositAuthority(deposit_type) => { - msg!("Instruction: SetDepositAuthority"); - Self::process_set_deposit_authority(program_id, accounts, deposit_type) + StakePoolInstruction::WithdrawSol(pool_tokens) => { + msg!("Instruction: WithdrawSol"); + Self::process_withdraw_sol(program_id, accounts, pool_tokens) } } } @@ -2663,6 +2795,8 @@ impl PrintProgramError for StakePoolError { StakePoolError::InvalidSolDepositAuthority => msg!("Error: Provided sol deposit authority does not match the program's"), StakePoolError::InvalidPreferredValidator => msg!("Error: Provided preferred validator is invalid"), StakePoolError::TransientAccountInUse => msg!("Error: Provided validator stake account already has a transient stake account in use"), + StakePoolError::InvalidSolWithdrawAuthority => msg!("Error: Provided sol withdraw authority does not match the program's"), + StakePoolError::SolWithdrawalTooLarge => msg!("Error: Too much SOL withdrawn from the stake pool's reserve account"), } } } diff --git a/program/src/state.rs b/program/src/state.rs index 46435648..1466cfb6 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -98,7 +98,7 @@ pub struct StakePool { pub lockup: Lockup, /// Fee taken as a proportion of rewards each epoch - pub fee: Fee, + pub epoch_fee: Fee, /// Fee for next epoch pub next_epoch_fee: Option, @@ -113,10 +113,10 @@ pub struct StakePool { pub stake_deposit_fee: Fee, /// Fee assessed on withdrawals - pub withdrawal_fee: Fee, + pub stake_withdrawal_fee: Fee, - /// Future withdrawal fee, to be set for the following epoch - pub next_withdrawal_fee: Option, + /// Future stake withdrawal fee, to be set for the following epoch + pub next_stake_withdrawal_fee: Option, /// Fees paid out to referrers on referred stake deposits. /// Expressed as a percentage (0 - 100) of deposit fees. @@ -125,7 +125,7 @@ pub struct StakePool { pub stake_referral_fee: u8, /// Toggles whether the `DepositSol` instruction requires a signature from - /// the `deposit_authority` + /// this `sol_deposit_authority` pub sol_deposit_authority: Option, /// Fee assessed on SOL deposits @@ -136,6 +136,16 @@ pub struct StakePool { /// i.e. `sol_deposit_fee`% of SOL deposited is collected as deposit fees for every deposit /// and `sol_referral_fee`% of the collected SOL deposit fees is paid out to the referrer pub sol_referral_fee: u8, + + /// Toggles whether the `WithdrawSol` instruction requires a signature from + /// the `deposit_authority` + pub sol_withdraw_authority: Option, + + /// Fee assessed on SOL withdrawals + pub sol_withdrawal_fee: Fee, + + /// Future SOL withdrawal fee, to be set for the following epoch + pub next_sol_withdrawal_fee: Option, } impl StakePool { /// calculate the pool tokens that should be minted for a deposit of `stake_lamports` @@ -170,8 +180,14 @@ impl StakePool { /// calculate pool tokens to be deducted as withdrawal fees #[inline] - pub fn calc_pool_tokens_withdrawal_fee(&self, pool_tokens: u64) -> Option { - u64::try_from(self.withdrawal_fee.apply(pool_tokens)?).ok() + pub fn calc_pool_tokens_stake_withdrawal_fee(&self, pool_tokens: u64) -> Option { + u64::try_from(self.stake_withdrawal_fee.apply(pool_tokens)?).ok() + } + + /// calculate pool tokens to be deducted as withdrawal fees + #[inline] + pub fn calc_pool_tokens_sol_withdrawal_fee(&self, pool_tokens: u64) -> Option { + u64::try_from(self.sol_withdrawal_fee.apply(pool_tokens)?).ok() } /// calculate pool tokens to be deducted as stake deposit fees @@ -219,7 +235,7 @@ impl StakePool { } let total_stake_lamports = (self.total_stake_lamports as u128).checked_add(reward_lamports as u128)?; - let fee_lamports = self.fee.apply(reward_lamports)?; + let fee_lamports = self.epoch_fee.apply(reward_lamports)?; if total_stake_lamports == fee_lamports || self.pool_token_supply == 0 { Some(reward_lamports) } else { @@ -317,6 +333,7 @@ impl StakePool { if let Some(auth) = self.sol_deposit_authority { let sol_deposit_authority = maybe_sol_deposit_authority?; if auth != *sol_deposit_authority.key { + msg!("Expected {}, received {}", auth, sol_deposit_authority.key); return Err(StakePoolError::InvalidSolDepositAuthority.into()); } if !sol_deposit_authority.is_signer { @@ -327,6 +344,26 @@ impl StakePool { Ok(()) } + /// Checks that the sol withdraw authority is valid + /// Does nothing if `sol_withdraw_authority` is currently not set + #[inline] + pub(crate) fn check_sol_withdraw_authority( + &self, + maybe_sol_withdraw_authority: Result<&AccountInfo, ProgramError>, + ) -> Result<(), ProgramError> { + if let Some(auth) = self.sol_withdraw_authority { + let sol_withdraw_authority = maybe_sol_withdraw_authority?; + if auth != *sol_withdraw_authority.key { + return Err(StakePoolError::InvalidSolWithdrawAuthority.into()); + } + if !sol_withdraw_authority.is_signer { + msg!("SOL withdraw authority signature missing"); + return Err(StakePoolError::SignatureMissing.into()); + } + } + Ok(()) + } + /// Check mint is correct #[inline] pub(crate) fn check_mint(&self, mint_info: &AccountInfo) -> Result<(), ProgramError> { @@ -416,15 +453,23 @@ impl StakePool { } /// Updates one of the StakePool's fees. - pub fn update_fee(&mut self, fee: &FeeType) { + pub fn update_fee(&mut self, fee: &FeeType) -> Result<(), StakePoolError> { match fee { FeeType::SolReferral(new_fee) => self.sol_referral_fee = *new_fee, FeeType::StakeReferral(new_fee) => self.stake_referral_fee = *new_fee, FeeType::Epoch(new_fee) => self.next_epoch_fee = Some(*new_fee), - FeeType::Withdrawal(new_fee) => self.next_withdrawal_fee = Some(*new_fee), + FeeType::StakeWithdrawal(new_fee) => { + new_fee.check_withdrawal(&self.stake_withdrawal_fee)?; + self.next_stake_withdrawal_fee = Some(*new_fee) + } + FeeType::SolWithdrawal(new_fee) => { + new_fee.check_withdrawal(&self.sol_withdrawal_fee)?; + self.next_sol_withdrawal_fee = Some(*new_fee) + } FeeType::SolDeposit(new_fee) => self.sol_deposit_fee = *new_fee, FeeType::StakeDeposit(new_fee) => self.stake_deposit_fee = *new_fee, - } + }; + Ok(()) } } @@ -666,11 +711,52 @@ impl Fee { .checked_mul(self.numerator as u128)? .checked_div(self.denominator as u128) } + + /// Withdrawal fees have some additional restrictions, + /// this fn checks if those are met, returning an error if not. + /// Does nothing and returns Ok if fee type is not withdrawal + pub fn check_withdrawal(&self, old_withdrawal_fee: &Fee) -> Result<(), StakePoolError> { + // If the previous withdrawal fee was 0, we allow the fee to be set to a + // maximum of (WITHDRAWAL_BASELINE_FEE * MAX_WITHDRAWAL_FEE_INCREASE) + let (old_num, old_denom) = + if old_withdrawal_fee.denominator == 0 || old_withdrawal_fee.numerator == 0 { + ( + WITHDRAWAL_BASELINE_FEE.numerator, + WITHDRAWAL_BASELINE_FEE.denominator, + ) + } else { + (old_withdrawal_fee.numerator, old_withdrawal_fee.denominator) + }; + + // Check that new_fee / old_fee <= MAX_WITHDRAWAL_FEE_INCREASE + // Program fails if provided numerator or denominator is too large, resulting in overflow + if (old_num as u128) + .checked_mul(self.denominator as u128) + .map(|x| x.checked_mul(MAX_WITHDRAWAL_FEE_INCREASE.numerator as u128)) + .ok_or(StakePoolError::CalculationFailure)? + < (self.numerator as u128) + .checked_mul(old_denom as u128) + .map(|x| x.checked_mul(MAX_WITHDRAWAL_FEE_INCREASE.denominator as u128)) + .ok_or(StakePoolError::CalculationFailure)? + { + msg!( + "Fee increase exceeds maximum allowed, proposed increase factor ({} / {})", + self.numerator * old_denom, + old_num * self.denominator, + ); + return Err(StakePoolError::FeeIncreaseTooHigh); + } + Ok(()) + } } impl fmt::Display for Fee { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}/{}", self.numerator, self.denominator) + if self.numerator > 0 && self.denominator > 0 { + write!(f, "{}/{}", self.numerator, self.denominator) + } else { + write!(f, "none") + } } } @@ -683,12 +769,14 @@ pub enum FeeType { StakeReferral(u8), /// Management fee paid per epoch Epoch(Fee), - /// Withdrawal fee - Withdrawal(Fee), + /// Stake withdrawal fee + StakeWithdrawal(Fee), /// Deposit fee for SOL deposits SolDeposit(Fee), /// Deposit fee for stake deposits StakeDeposit(Fee), + /// SOL withdrawal fee + SolWithdrawal(Fee), } impl FeeType { @@ -698,7 +786,8 @@ impl FeeType { Self::SolReferral(pct) => *pct > 100u8, Self::StakeReferral(pct) => *pct > 100u8, Self::Epoch(fee) => fee.numerator > fee.denominator, - Self::Withdrawal(fee) => fee.numerator > fee.denominator, + Self::StakeWithdrawal(fee) => fee.numerator > fee.denominator, + Self::SolWithdrawal(fee) => fee.numerator > fee.denominator, Self::SolDeposit(fee) => fee.numerator > fee.denominator, Self::StakeDeposit(fee) => fee.numerator > fee.denominator, }; @@ -709,52 +798,13 @@ impl FeeType { Ok(()) } - /// Withdrawal fees have some additional restrictions, - /// this fn checks if those are met, returning an error if not. - /// Does nothing and returns Ok if fee type is not withdrawal - pub fn check_withdrawal(&self, old_withdrawal_fee: &Fee) -> Result<(), StakePoolError> { - let fee = match self { - Self::Withdrawal(fee) => fee, - _ => return Ok(()), - }; - - // If the previous withdrawal fee was 0, we allow the fee to be set to a - // maximum of (WITHDRAWAL_BASELINE_FEE * MAX_WITHDRAWAL_FEE_INCREASE) - let (old_num, old_denom) = - if old_withdrawal_fee.denominator == 0 || old_withdrawal_fee.numerator == 0 { - ( - WITHDRAWAL_BASELINE_FEE.numerator, - WITHDRAWAL_BASELINE_FEE.denominator, - ) - } else { - (old_withdrawal_fee.numerator, old_withdrawal_fee.denominator) - }; - - // Check that new_fee / old_fee <= MAX_WITHDRAWAL_FEE_INCREASE - // Program fails if provided numerator or denominator is too large, resulting in overflow - if (old_num as u128) - .checked_mul(fee.denominator as u128) - .map(|x| x.checked_mul(MAX_WITHDRAWAL_FEE_INCREASE.numerator as u128)) - .ok_or(StakePoolError::CalculationFailure)? - < (fee.numerator as u128) - .checked_mul(old_denom as u128) - .map(|x| x.checked_mul(MAX_WITHDRAWAL_FEE_INCREASE.denominator as u128)) - .ok_or(StakePoolError::CalculationFailure)? - { - msg!( - "Fee increase exceeds maximum allowed, proposed increase factor ({} / {})", - fee.numerator * old_denom, - old_num * fee.denominator, - ); - return Err(StakePoolError::FeeIncreaseTooHigh); - } - Ok(()) - } - /// Returns if the contained fee can only be updated earliest on the next epoch #[inline] pub fn can_only_change_next_epoch(&self) -> bool { - matches!(self, Self::Withdrawal(_) | Self::Epoch(_)) + matches!( + self, + Self::StakeWithdrawal(_) | Self::SolWithdrawal(_) | Self::Epoch(_) + ) } } @@ -953,14 +1003,14 @@ mod test { #[test] fn specific_fee_calculation() { // 10% of 10 SOL in rewards should be 1 SOL in fees - let fee = Fee { + let epoch_fee = Fee { numerator: 1, denominator: 10, }; let mut stake_pool = StakePool { total_stake_lamports: 100 * LAMPORTS_PER_SOL, pool_token_supply: 100 * LAMPORTS_PER_SOL, - fee, + epoch_fee, ..StakePool::default() }; let reward_lamports = 10 * LAMPORTS_PER_SOL; @@ -977,12 +1027,12 @@ mod test { #[test] fn zero_withdraw_calculation() { - let fee = Fee { + let epoch_fee = Fee { numerator: 0, denominator: 1, }; let stake_pool = StakePool { - fee, + epoch_fee, ..StakePool::default() }; let fee_lamports = stake_pool.calc_lamports_withdraw_amount(0).unwrap(); @@ -993,7 +1043,7 @@ mod test { fn divide_by_zero_fee() { let stake_pool = StakePool { total_stake_lamports: 0, - fee: Fee { + epoch_fee: Fee { numerator: 1, denominator: 10, }, @@ -1010,11 +1060,11 @@ mod test { (numerator, denominator) in fee(), (total_stake_lamports, reward_lamports) in total_stake_and_rewards(), ) { - let fee = Fee { denominator, numerator }; + let epoch_fee = Fee { denominator, numerator }; let mut stake_pool = StakePool { total_stake_lamports, pool_token_supply: total_stake_lamports, - fee, + epoch_fee, ..StakePool::default() }; let pool_token_fee = stake_pool.calc_epoch_fee_amount(reward_lamports).unwrap(); @@ -1023,7 +1073,7 @@ mod test { stake_pool.pool_token_supply += pool_token_fee; let fee_lamports = stake_pool.calc_lamports_withdraw_amount(pool_token_fee).unwrap(); - let max_fee_lamports = u64::try_from((reward_lamports as u128) * (fee.numerator as u128) / (fee.denominator as u128)).unwrap(); + let max_fee_lamports = u64::try_from((reward_lamports as u128) * (epoch_fee.numerator as u128) / (epoch_fee.denominator as u128)).unwrap(); assert!(max_fee_lamports >= fee_lamports, "Max possible fee must always be greater than or equal to what is actually withdrawn, max {} actual {}", max_fee_lamports, diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 00daabaa..4e95a82a 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -149,7 +149,7 @@ async fn success() { ) .await; let pre_stake_pool = - try_from_slice_unchecked::(&pre_stake_pool.data.as_slice()).unwrap(); + try_from_slice_unchecked::(pre_stake_pool.data.as_slice()).unwrap(); // Save validator stake account record before depositing let validator_list = get_account( @@ -201,7 +201,7 @@ async fn success() { ) .await; let post_stake_pool = - try_from_slice_unchecked::(&post_stake_pool.data.as_slice()).unwrap(); + try_from_slice_unchecked::(post_stake_pool.data.as_slice()).unwrap(); assert_eq!( post_stake_pool.total_stake_lamports, pre_stake_pool.total_stake_lamports + stake_lamports @@ -244,7 +244,7 @@ async fn success() { deserialize::(&validator_stake_account.data).unwrap(); let meta = stake_state.meta().unwrap(); assert_eq!( - validator_stake_account.lamports - minimum_stake_lamports(&meta), + validator_stake_account.lamports - minimum_stake_lamports(meta), post_validator_stake_item.stake_lamports() ); assert_eq!(post_validator_stake_item.transient_stake_lamports, 0); @@ -314,7 +314,7 @@ async fn success_with_extra_stake_lamports() { ) .await; let pre_stake_pool = - try_from_slice_unchecked::(&pre_stake_pool.data.as_slice()).unwrap(); + try_from_slice_unchecked::(pre_stake_pool.data.as_slice()).unwrap(); // Save validator stake account record before depositing let validator_list = get_account( @@ -372,7 +372,7 @@ async fn success_with_extra_stake_lamports() { .await; let post_stake_pool = - try_from_slice_unchecked::(&post_stake_pool.data.as_slice()).unwrap(); + try_from_slice_unchecked::(post_stake_pool.data.as_slice()).unwrap(); assert_eq!( post_stake_pool.total_stake_lamports, pre_stake_pool.total_stake_lamports + extra_lamports + stake_lamports @@ -439,7 +439,7 @@ async fn success_with_extra_stake_lamports() { deserialize::(&validator_stake_account.data).unwrap(); let meta = stake_state.meta().unwrap(); assert_eq!( - validator_stake_account.lamports - minimum_stake_lamports(&meta), + validator_stake_account.lamports - minimum_stake_lamports(meta), post_validator_stake_item.stake_lamports() ); assert_eq!(post_validator_stake_item.transient_stake_lamports, 0); diff --git a/program/tests/deposit_sol.rs b/program/tests/deposit_sol.rs index edf4e141..3d30e2d3 100644 --- a/program/tests/deposit_sol.rs +++ b/program/tests/deposit_sol.rs @@ -16,7 +16,7 @@ use { }, spl_stake_pool::{ error, id, - instruction::{self, DepositType}, + instruction::{self, FundingType}, state, }, spl_token::error as token_error, @@ -50,33 +50,6 @@ async fn setup() -> (ProgramTestContext, StakePoolAccounts, Keypair, Pubkey) { ) .await .unwrap(); - let mut transaction = Transaction::new_with_payer( - &[ - instruction::set_fee( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.manager.pubkey(), - state::FeeType::SolDeposit(stake_pool_accounts.deposit_fee), - ), - instruction::set_fee( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.manager.pubkey(), - state::FeeType::SolReferral(stake_pool_accounts.referral_fee), - ), - ], - Some(&context.payer.pubkey()), - ); - - transaction.sign( - &[&context.payer, &stake_pool_accounts.manager], - context.last_blockhash, - ); - context - .banks_client - .process_transaction(transaction) - .await - .unwrap(); ( context, @@ -97,7 +70,7 @@ async fn success() { ) .await; let pre_stake_pool = - try_from_slice_unchecked::(&pre_stake_pool.data.as_slice()).unwrap(); + try_from_slice_unchecked::(pre_stake_pool.data.as_slice()).unwrap(); // Save reserve state before depositing let pre_reserve_lamports = get_account( @@ -128,7 +101,7 @@ async fn success() { ) .await; let post_stake_pool = - try_from_slice_unchecked::(&post_stake_pool.data.as_slice()).unwrap(); + try_from_slice_unchecked::(post_stake_pool.data.as_slice()).unwrap(); assert_eq!( post_stake_pool.total_stake_lamports, pre_stake_pool.total_stake_lamports + TEST_STAKE_AMOUNT @@ -142,7 +115,7 @@ async fn success() { let user_token_balance = get_token_balance(&mut context.banks_client, &pool_token_account).await; let tokens_issued_user = - tokens_issued - stake_pool_accounts.calculate_deposit_fee(tokens_issued); + tokens_issued - stake_pool_accounts.calculate_sol_deposit_fee(tokens_issued); assert_eq!(user_token_balance, tokens_issued_user); // Check reserve @@ -165,7 +138,7 @@ async fn fail_with_wrong_token_program_id() { let wrong_token_program = Keypair::new(); let mut transaction = Transaction::new_with_payer( - &instruction::deposit_sol( + &[instruction::deposit_sol( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.withdraw_authority, @@ -177,7 +150,7 @@ async fn fail_with_wrong_token_program_id() { &stake_pool_accounts.pool_mint.pubkey(), &wrong_token_program.pubkey(), TEST_STAKE_AMOUNT, - ), + )], Some(&context.payer.pubkey()), ); transaction.sign(&[&context.payer], context.last_blockhash); @@ -317,12 +290,12 @@ async fn success_with_sol_deposit_authority() { let sol_deposit_authority = Keypair::new(); let mut transaction = Transaction::new_with_payer( - &[instruction::set_deposit_authority( + &[instruction::set_funding_authority( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), Some(&sol_deposit_authority.pubkey()), - DepositType::Sol, + FundingType::SolDeposit, )], Some(&payer.pubkey()), ); @@ -368,12 +341,12 @@ async fn fail_without_sol_deposit_authority_signature() { .unwrap(); let mut transaction = Transaction::new_with_payer( - &[instruction::set_deposit_authority( + &[instruction::set_funding_authority( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), Some(&sol_deposit_authority.pubkey()), - DepositType::Sol, + FundingType::SolDeposit, )], Some(&payer.pubkey()), ); @@ -427,7 +400,7 @@ async fn success_with_referral_fee() { get_token_balance(&mut context.banks_client, &referrer_token_account.pubkey()).await; let mut transaction = Transaction::new_with_payer( - &instruction::deposit_sol( + &[instruction::deposit_sol( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.withdraw_authority, @@ -439,7 +412,7 @@ async fn success_with_referral_fee() { &stake_pool_accounts.pool_mint.pubkey(), &spl_token::id(), TEST_STAKE_AMOUNT, - ), + )], Some(&context.payer.pubkey()), ); transaction.sign(&[&context.payer], context.last_blockhash); @@ -451,8 +424,9 @@ async fn success_with_referral_fee() { let referrer_balance_post = get_token_balance(&mut context.banks_client, &referrer_token_account.pubkey()).await; - let referral_fee = stake_pool_accounts - .calculate_referral_fee(stake_pool_accounts.calculate_deposit_fee(TEST_STAKE_AMOUNT)); + let referral_fee = stake_pool_accounts.calculate_sol_referral_fee( + stake_pool_accounts.calculate_sol_deposit_fee(TEST_STAKE_AMOUNT), + ); assert!(referral_fee > 0); assert_eq!(referrer_balance_pre + referral_fee, referrer_balance_post); } @@ -464,7 +438,7 @@ async fn fail_with_invalid_referrer() { let invalid_token_account = Keypair::new(); let mut transaction = Transaction::new_with_payer( - &instruction::deposit_sol( + &[instruction::deposit_sol( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.withdraw_authority, @@ -476,7 +450,7 @@ async fn fail_with_invalid_referrer() { &stake_pool_accounts.pool_mint.pubkey(), &spl_token::id(), TEST_STAKE_AMOUNT, - ), + )], Some(&context.payer.pubkey()), ); transaction.sign(&[&context.payer], context.last_blockhash); diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 103254b3..ad0ede77 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -69,7 +69,7 @@ pub async fn create_mint( spl_token::instruction::initialize_mint( &spl_token::id(), &pool_mint.pubkey(), - &manager, + manager, None, 0, ) @@ -174,8 +174,8 @@ pub async fn close_token_account( let mut transaction = Transaction::new_with_payer( &[spl_token::instruction::close_account( &spl_token::id(), - &account, - &lamports_destination, + account, + lamports_destination, &manager.pubkey(), &[], ) @@ -198,7 +198,7 @@ pub async fn freeze_token_account( let mut transaction = Transaction::new_with_payer( &[spl_token::instruction::freeze_account( &spl_token::id(), - &account, + account, pool_mint, &manager.pubkey(), &[], @@ -291,8 +291,8 @@ pub async fn delegate_tokens( let transaction = Transaction::new_signed_with_payer( &[spl_token::instruction::approve( &spl_token::id(), - &account, - &delegate, + account, + delegate, &manager.pubkey(), &[], amount, @@ -318,7 +318,7 @@ pub async fn create_stake_pool( manager: &Keypair, staker: &Pubkey, stake_deposit_authority: &Option, - fee: &state::Fee, + epoch_fee: &state::Fee, withdrawal_fee: &state::Fee, deposit_fee: &state::Fee, referral_fee: u8, @@ -359,7 +359,7 @@ pub async fn create_stake_pool( pool_token_account, &spl_token::id(), stake_deposit_authority.as_ref().map(|k| k.pubkey()), - *fee, + *epoch_fee, *withdrawal_fee, *deposit_fee, referral_fee, @@ -492,9 +492,9 @@ pub async fn delegate_stake_account( ) { let mut transaction = Transaction::new_with_payer( &[stake_program::delegate_stake( - &stake, + stake, &authorized.pubkey(), - &vote, + vote, )], Some(&payer.pubkey()), ); @@ -513,9 +513,9 @@ pub async fn authorize_stake_account( ) { let mut transaction = Transaction::new_with_payer( &[stake_program::authorize( - &stake, + stake, &authorized.pubkey(), - &new_authorized, + new_authorized, stake_authorize, )], Some(&payer.pubkey()), @@ -609,7 +609,7 @@ pub struct StakePoolAccounts { pub withdraw_authority: Pubkey, pub stake_deposit_authority: Pubkey, pub stake_deposit_authority_keypair: Option, - pub fee: state::Fee, + pub epoch_fee: state::Fee, pub withdrawal_fee: state::Fee, pub deposit_fee: state::Fee, pub referral_fee: u8, @@ -648,7 +648,7 @@ impl StakePoolAccounts { withdraw_authority, stake_deposit_authority, stake_deposit_authority_keypair: None, - fee: state::Fee { + epoch_fee: state::Fee { numerator: 1, denominator: 100, }, @@ -678,7 +678,7 @@ impl StakePoolAccounts { } pub fn calculate_fee(&self, amount: u64) -> u64 { - amount * self.fee.numerator / self.fee.denominator + amount * self.epoch_fee.numerator / self.epoch_fee.denominator } pub fn calculate_withdrawal_fee(&self, pool_tokens: u64) -> u64 { @@ -710,16 +710,16 @@ impl StakePoolAccounts { ) -> Result<(), TransportError> { create_mint( &mut banks_client, - &payer, - &recent_blockhash, + payer, + recent_blockhash, &self.pool_mint, &self.withdraw_authority, ) .await?; create_token_account( &mut banks_client, - &payer, - &recent_blockhash, + payer, + recent_blockhash, &self.pool_fee_account, &self.pool_mint.pubkey(), &self.manager.pubkey(), @@ -727,8 +727,8 @@ impl StakePoolAccounts { .await?; create_independent_stake_account( &mut banks_client, - &payer, - &recent_blockhash, + payer, + recent_blockhash, &self.reserve_stake, &stake_program::Authorized { staker: self.withdraw_authority, @@ -740,8 +740,8 @@ impl StakePoolAccounts { .await; create_stake_pool( &mut banks_client, - &payer, - &recent_blockhash, + payer, + recent_blockhash, &self.stake_pool, &self.validator_list, &self.reserve_stake.pubkey(), @@ -750,7 +750,7 @@ impl StakePoolAccounts { &self.manager, &self.staker.pubkey(), &self.stake_deposit_authority_keypair, - &self.fee, + &self.epoch_fee, &self.withdrawal_fee, &self.deposit_fee, self.referral_fee, @@ -831,7 +831,7 @@ impl StakePoolAccounts { &self.reserve_stake.pubkey(), pool_account, &self.pool_fee_account.pubkey(), - &referrer, + referrer, &self.pool_mint.pubkey(), &spl_token::id(), ) @@ -856,7 +856,7 @@ impl StakePoolAccounts { sol_deposit_authority: Option<&Keypair>, ) -> Option { let mut signers = vec![payer]; - let instructions = if let Some(sol_deposit_authority) = sol_deposit_authority { + let instruction = if let Some(sol_deposit_authority) = sol_deposit_authority { signers.push(sol_deposit_authority); instruction::deposit_sol_with_authority( &id(), @@ -888,7 +888,7 @@ impl StakePoolAccounts { ) }; let transaction = Transaction::new_signed_with_payer( - &instructions, + &[instruction], Some(&payer.pubkey()), &signers, *recent_blockhash, @@ -932,6 +932,58 @@ impl StakePoolAccounts { banks_client.process_transaction(transaction).await.err() } + #[allow(clippy::too_many_arguments)] + pub async fn withdraw_sol( + &self, + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + user: &Keypair, + pool_account: &Pubkey, + amount: u64, + sol_withdraw_authority: Option<&Keypair>, + ) -> Option { + let mut signers = vec![payer, user]; + let instruction = if let Some(sol_withdraw_authority) = sol_withdraw_authority { + signers.push(sol_withdraw_authority); + instruction::withdraw_sol_with_authority( + &id(), + &self.stake_pool.pubkey(), + &sol_withdraw_authority.pubkey(), + &self.withdraw_authority, + &user.pubkey(), + pool_account, + &self.reserve_stake.pubkey(), + &user.pubkey(), + &self.pool_fee_account.pubkey(), + &self.pool_mint.pubkey(), + &spl_token::id(), + amount, + ) + } else { + instruction::withdraw_sol( + &id(), + &self.stake_pool.pubkey(), + &self.withdraw_authority, + &user.pubkey(), + pool_account, + &self.reserve_stake.pubkey(), + &user.pubkey(), + &self.pool_fee_account.pubkey(), + &self.pool_mint.pubkey(), + &spl_token::id(), + amount, + ) + }; + let transaction = Transaction::new_signed_with_payer( + &[instruction], + Some(&payer.pubkey()), + &signers, + *recent_blockhash, + ); + banks_client.process_transaction(transaction).await.err() + } + pub async fn get_validator_list(&self, banks_client: &mut BanksClient) -> ValidatorList { let validator_list_account = get_account(banks_client, &self.validator_list.pubkey()).await; try_from_slice_unchecked::(validator_list_account.data.as_slice()).unwrap() @@ -1079,6 +1131,7 @@ impl StakePoolAccounts { banks_client.process_transaction(transaction).await.err() } + #[allow(clippy::too_many_arguments)] pub async fn remove_validator_from_pool( &self, banks_client: &mut BanksClient, @@ -1103,7 +1156,7 @@ impl StakePoolAccounts { &self.stake_pool.pubkey(), &self.staker.pubkey(), &self.withdraw_authority, - &new_authority, + new_authority, &self.validator_list.pubkey(), validator_stake, transient_stake, @@ -1117,6 +1170,7 @@ impl StakePoolAccounts { banks_client.process_transaction(transaction).await.err() } + #[allow(clippy::too_many_arguments)] pub async fn decrease_validator_stake( &self, banks_client: &mut BanksClient, @@ -1146,6 +1200,7 @@ impl StakePoolAccounts { banks_client.process_transaction(transaction).await.err() } + #[allow(clippy::too_many_arguments)] pub async fn increase_validator_stake( &self, banks_client: &mut BanksClient, @@ -1224,8 +1279,8 @@ pub async fn simple_add_validator_to_pool( let error = stake_pool_accounts .add_validator_to_pool( banks_client, - &payer, - &recent_blockhash, + payer, + recent_blockhash, &validator_stake.stake_account, &validator_stake.vote.pubkey(), ) diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index 55043bc1..2188961b 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -3,7 +3,6 @@ mod helpers; use { - bincode, borsh::BorshSerialize, helpers::*, solana_program::{ @@ -74,17 +73,20 @@ async fn setup( pool_token_supply: 0, last_update_epoch: 0, lockup: stake_program::Lockup::default(), - fee: stake_pool_accounts.fee, + epoch_fee: stake_pool_accounts.epoch_fee, next_epoch_fee: None, preferred_deposit_validator_vote_address: None, preferred_withdraw_validator_vote_address: None, stake_deposit_fee: Fee::default(), sol_deposit_fee: Fee::default(), - withdrawal_fee: Fee::default(), - next_withdrawal_fee: None, + stake_withdrawal_fee: Fee::default(), + next_stake_withdrawal_fee: None, stake_referral_fee: 0, sol_referral_fee: 0, sol_deposit_authority: None, + sol_withdraw_authority: None, + sol_withdrawal_fee: Fee::default(), + next_sol_withdrawal_fee: None, }; let mut validator_list = ValidatorList::new(max_validators); @@ -127,13 +129,11 @@ async fn setup( program_test.add_account(vote_pubkey, vote_account); } - for i in 0..num_validators as usize { - let vote_account_address = vote_account_pubkeys[i]; - + for vote_account_address in vote_account_pubkeys.iter().take(num_validators as usize) { // create validator stake account let stake = stake_program::Stake { delegation: stake_program::Delegation { - voter_pubkey: vote_account_address, + voter_pubkey: *vote_account_address, stake: stake_amount, activation_epoch: 0, deactivation_epoch: u64::MAX, @@ -154,13 +154,13 @@ async fn setup( ); let (stake_address, _) = - find_stake_program_address(&id(), &vote_account_address, &stake_pool_pubkey); + find_stake_program_address(&id(), vote_account_address, &stake_pool_pubkey); program_test.add_account(stake_address, stake_account); let active_stake_lamports = stake_amount - MINIMUM_ACTIVE_STAKE; // add to validator list validator_list.validators.push(ValidatorStakeInfo { status: StakeStatus::Active, - vote_account_address, + vote_account_address: *vote_account_address, active_stake_lamports, transient_stake_lamports: 0, last_update_epoch: 0, @@ -658,7 +658,7 @@ async fn set_preferred() { &stake_pool_accounts.stake_pool.pubkey(), ) .await; - let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); assert_eq!( stake_pool.preferred_deposit_validator_vote_address, diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index 652d2274..1c4044a6 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -50,8 +50,8 @@ async fn create_required_accounts( create_independent_stake_account( banks_client, - &payer, - &recent_blockhash, + payer, + recent_blockhash, &stake_pool_accounts.reserve_stake, &stake_program::Authorized { staker: stake_pool_accounts.withdraw_authority, @@ -154,7 +154,7 @@ async fn fail_with_already_initialized_validator_list() { async fn fail_with_high_fee() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let mut stake_pool_accounts = StakePoolAccounts::new(); - stake_pool_accounts.fee = state::Fee { + stake_pool_accounts.epoch_fee = state::Fee { numerator: 100001, denominator: 100000, }; @@ -252,7 +252,7 @@ async fn fail_with_wrong_max_validators() { &stake_pool_accounts.pool_fee_account.pubkey(), &spl_token::id(), None, - stake_pool_accounts.fee, + stake_pool_accounts.epoch_fee, stake_pool_accounts.withdrawal_fee, stake_pool_accounts.deposit_fee, stake_pool_accounts.referral_fee, @@ -325,7 +325,7 @@ async fn fail_with_wrong_mint_authority() { &stake_pool_accounts.manager, &stake_pool_accounts.staker.pubkey(), &None, - &stake_pool_accounts.fee, + &stake_pool_accounts.epoch_fee, &stake_pool_accounts.withdrawal_fee, &stake_pool_accounts.deposit_fee, stake_pool_accounts.referral_fee, @@ -415,7 +415,7 @@ async fn fail_with_freeze_authority() { &stake_pool_accounts.manager, &stake_pool_accounts.staker.pubkey(), &None, - &stake_pool_accounts.fee, + &stake_pool_accounts.epoch_fee, &stake_pool_accounts.withdrawal_fee, &stake_pool_accounts.deposit_fee, stake_pool_accounts.referral_fee, @@ -507,7 +507,7 @@ async fn fail_with_wrong_token_program_id() { &stake_pool_accounts.pool_fee_account.pubkey(), &wrong_token_program.pubkey(), None, - stake_pool_accounts.fee, + stake_pool_accounts.epoch_fee, stake_pool_accounts.withdrawal_fee, stake_pool_accounts.deposit_fee, stake_pool_accounts.referral_fee, @@ -586,7 +586,7 @@ async fn fail_with_wrong_fee_account() { &stake_pool_accounts.manager, &stake_pool_accounts.staker.pubkey(), &None, - &stake_pool_accounts.fee, + &stake_pool_accounts.epoch_fee, &stake_pool_accounts.withdrawal_fee, &stake_pool_accounts.deposit_fee, stake_pool_accounts.referral_fee, @@ -679,7 +679,7 @@ async fn fail_with_not_rent_exempt_pool() { &stake_pool_accounts.pool_fee_account.pubkey(), &spl_token::id(), None, - stake_pool_accounts.fee, + stake_pool_accounts.epoch_fee, stake_pool_accounts.withdrawal_fee, stake_pool_accounts.deposit_fee, stake_pool_accounts.referral_fee, @@ -756,7 +756,7 @@ async fn fail_with_not_rent_exempt_validator_list() { &stake_pool_accounts.pool_fee_account.pubkey(), &spl_token::id(), None, - stake_pool_accounts.fee, + stake_pool_accounts.epoch_fee, stake_pool_accounts.withdrawal_fee, stake_pool_accounts.deposit_fee, stake_pool_accounts.referral_fee, @@ -810,7 +810,7 @@ async fn fail_without_manager_signature() { let rent_validator_list = rent.minimum_balance(validator_list_size); let init_data = instruction::StakePoolInstruction::Initialize { - fee: stake_pool_accounts.fee, + fee: stake_pool_accounts.epoch_fee, withdrawal_fee: stake_pool_accounts.withdrawal_fee, deposit_fee: stake_pool_accounts.deposit_fee, referral_fee: stake_pool_accounts.referral_fee, @@ -934,7 +934,7 @@ async fn fail_with_pre_minted_pool_tokens() { &stake_pool_accounts.manager, &stake_pool_accounts.staker.pubkey(), &None, - &stake_pool_accounts.fee, + &stake_pool_accounts.epoch_fee, &stake_pool_accounts.withdrawal_fee, &stake_pool_accounts.deposit_fee, stake_pool_accounts.referral_fee, @@ -1000,7 +1000,7 @@ async fn fail_with_bad_reserve() { &stake_pool_accounts.manager, &stake_pool_accounts.staker.pubkey(), &None, - &stake_pool_accounts.fee, + &stake_pool_accounts.epoch_fee, &stake_pool_accounts.withdrawal_fee, &stake_pool_accounts.deposit_fee, stake_pool_accounts.referral_fee, @@ -1050,7 +1050,7 @@ async fn fail_with_bad_reserve() { &stake_pool_accounts.manager, &stake_pool_accounts.staker.pubkey(), &None, - &stake_pool_accounts.fee, + &stake_pool_accounts.epoch_fee, &stake_pool_accounts.withdrawal_fee, &stake_pool_accounts.deposit_fee, stake_pool_accounts.referral_fee, @@ -1103,7 +1103,7 @@ async fn fail_with_bad_reserve() { &stake_pool_accounts.manager, &stake_pool_accounts.staker.pubkey(), &None, - &stake_pool_accounts.fee, + &stake_pool_accounts.epoch_fee, &stake_pool_accounts.withdrawal_fee, &stake_pool_accounts.deposit_fee, stake_pool_accounts.referral_fee, @@ -1156,7 +1156,7 @@ async fn fail_with_bad_reserve() { &stake_pool_accounts.manager, &stake_pool_accounts.staker.pubkey(), &None, - &stake_pool_accounts.fee, + &stake_pool_accounts.epoch_fee, &stake_pool_accounts.withdrawal_fee, &stake_pool_accounts.deposit_fee, stake_pool_accounts.referral_fee, diff --git a/program/tests/set_deposit_fee.rs b/program/tests/set_deposit_fee.rs index 37508341..761440f5 100644 --- a/program/tests/set_deposit_fee.rs +++ b/program/tests/set_deposit_fee.rs @@ -67,7 +67,7 @@ async fn success_stake() { &stake_pool_accounts.stake_pool.pubkey(), ) .await; - let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); assert_eq!(stake_pool.stake_deposit_fee, new_deposit_fee); } @@ -105,7 +105,7 @@ async fn success_stake_increase_fee_from_0() { &stake_pool_accounts.stake_pool.pubkey(), ) .await; - let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); assert_eq!(stake_pool.stake_deposit_fee, new_deposit_fee); } @@ -204,7 +204,7 @@ async fn success_sol() { &stake_pool_accounts.stake_pool.pubkey(), ) .await; - let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); assert_eq!(stake_pool.sol_deposit_fee, new_deposit_fee); } diff --git a/program/tests/set_fee.rs b/program/tests/set_epoch_fee.rs similarity index 93% rename from program/tests/set_fee.rs rename to program/tests/set_epoch_fee.rs index 1dcbdcfe..8eb87366 100644 --- a/program/tests/set_fee.rs +++ b/program/tests/set_epoch_fee.rs @@ -46,8 +46,8 @@ async fn success() { &stake_pool_accounts.stake_pool.pubkey(), ) .await; - let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); - let old_fee = stake_pool.fee; + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); + let old_fee = stake_pool.epoch_fee; let transaction = Transaction::new_signed_with_payer( &[instruction::set_fee( @@ -71,9 +71,9 @@ async fn success() { &stake_pool_accounts.stake_pool.pubkey(), ) .await; - let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); - assert_eq!(stake_pool.fee, old_fee); + assert_eq!(stake_pool.epoch_fee, old_fee); assert_eq!(stake_pool.next_epoch_fee, Some(new_fee)); let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; @@ -97,8 +97,8 @@ async fn success() { &stake_pool_accounts.stake_pool.pubkey(), ) .await; - let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); - assert_eq!(stake_pool.fee, new_fee); + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); + assert_eq!(stake_pool.epoch_fee, new_fee); assert_eq!(stake_pool.next_epoch_fee, None); } diff --git a/program/tests/set_deposit_authority.rs b/program/tests/set_funding_authority.rs similarity index 56% rename from program/tests/set_deposit_authority.rs rename to program/tests/set_funding_authority.rs index 61a098c6..4faf663e 100644 --- a/program/tests/set_deposit_authority.rs +++ b/program/tests/set_funding_authority.rs @@ -17,7 +17,7 @@ use { }, spl_stake_pool::{ error, find_deposit_authority_program_address, id, - instruction::{self, DepositType}, + instruction::{self, FundingType}, state, }, }; @@ -43,54 +43,16 @@ async fn setup() -> (BanksClient, Keypair, Hash, StakePoolAccounts, Keypair) { #[tokio::test] async fn success_set_stake_deposit_authority() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - new_stake_deposit_authority, - ) = setup().await; - - let mut transaction = Transaction::new_with_payer( - &[instruction::set_deposit_authority( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.manager.pubkey(), - Some(&new_stake_deposit_authority.pubkey()), - DepositType::Stake, - )], - Some(&payer.pubkey()), - ); - transaction.sign(&[&payer, &stake_pool_accounts.manager], recent_blockhash); - banks_client.process_transaction(transaction).await.unwrap(); - - let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; - let stake_pool = - try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); - - assert_eq!( - stake_pool.stake_deposit_authority, - new_stake_deposit_authority.pubkey() - ); -} - -#[tokio::test] -async fn success_set_stake_deposit_authority_to_none() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - new_stake_deposit_authority, - ) = setup().await; + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_authority) = + setup().await; let mut transaction = Transaction::new_with_payer( - &[instruction::set_deposit_authority( + &[instruction::set_funding_authority( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - Some(&new_stake_deposit_authority.pubkey()), - DepositType::Stake, + Some(&new_authority.pubkey()), + FundingType::StakeDeposit, )], Some(&payer.pubkey()), ); @@ -99,20 +61,17 @@ async fn success_set_stake_deposit_authority_to_none() { let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; let stake_pool = - try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); - assert_eq!( - stake_pool.stake_deposit_authority, - new_stake_deposit_authority.pubkey() - ); + assert_eq!(stake_pool.stake_deposit_authority, new_authority.pubkey()); let mut transaction = Transaction::new_with_payer( - &[instruction::set_deposit_authority( + &[instruction::set_funding_authority( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), None, - DepositType::Stake, + FundingType::StakeDeposit, )], Some(&payer.pubkey()), ); @@ -121,7 +80,7 @@ async fn success_set_stake_deposit_authority_to_none() { let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; let stake_pool = - try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); assert_eq!( stake_pool.stake_deposit_authority, @@ -130,26 +89,21 @@ async fn success_set_stake_deposit_authority_to_none() { } #[tokio::test] -async fn fail_stake_wrong_manager() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - new_stake_deposit_authority, - ) = setup().await; +async fn fail_wrong_manager() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_authority) = + setup().await; let mut transaction = Transaction::new_with_payer( - &[instruction::set_deposit_authority( + &[instruction::set_funding_authority( &id(), &stake_pool_accounts.stake_pool.pubkey(), - &new_stake_deposit_authority.pubkey(), - Some(&new_stake_deposit_authority.pubkey()), - DepositType::Stake, + &new_authority.pubkey(), + Some(&new_authority.pubkey()), + FundingType::StakeDeposit, )], Some(&payer.pubkey()), ); - transaction.sign(&[&payer, &new_stake_deposit_authority], recent_blockhash); + transaction.sign(&[&payer, &new_authority], recent_blockhash); let transaction_error = banks_client .process_transaction(transaction) .await @@ -169,23 +123,17 @@ async fn fail_stake_wrong_manager() { } #[tokio::test] -async fn fail_set_stake_deposit_authority_without_signature() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - new_stake_deposit_authority, - ) = setup().await; +async fn fail_without_signature() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_authority) = + setup().await; - let data = - instruction::StakePoolInstruction::SetDepositAuthority(instruction::DepositType::Stake) - .try_to_vec() - .unwrap(); + let data = instruction::StakePoolInstruction::SetFundingAuthority(FundingType::StakeDeposit) + .try_to_vec() + .unwrap(); let accounts = vec![ AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), AccountMeta::new_readonly(stake_pool_accounts.manager.pubkey(), false), - AccountMeta::new_readonly(new_stake_deposit_authority.pubkey(), false), + AccountMeta::new_readonly(new_authority.pubkey(), false), ]; let instruction = Instruction { program_id: id(), @@ -219,12 +167,12 @@ async fn success_set_sol_deposit_authority() { setup().await; let mut transaction = Transaction::new_with_payer( - &[instruction::set_deposit_authority( + &[instruction::set_funding_authority( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), Some(&new_sol_deposit_authority.pubkey()), - DepositType::Sol, + FundingType::SolDeposit, )], Some(&payer.pubkey()), ); @@ -233,26 +181,20 @@ async fn success_set_sol_deposit_authority() { let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; let stake_pool = - try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); assert_eq!( stake_pool.sol_deposit_authority, Some(new_sol_deposit_authority.pubkey()) ); -} - -#[tokio::test] -async fn success_set_sol_deposit_authority_to_none() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_sol_deposit_authority) = - setup().await; let mut transaction = Transaction::new_with_payer( - &[instruction::set_deposit_authority( + &[instruction::set_funding_authority( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - Some(&new_sol_deposit_authority.pubkey()), - DepositType::Sol, + None, + FundingType::SolDeposit, )], Some(&payer.pubkey()), ); @@ -261,20 +203,23 @@ async fn success_set_sol_deposit_authority_to_none() { let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; let stake_pool = - try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); - assert_eq!( - stake_pool.sol_deposit_authority, - Some(new_sol_deposit_authority.pubkey()) - ); + assert_eq!(stake_pool.sol_deposit_authority, None); +} + +#[tokio::test] +async fn success_set_withdraw_authority() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_authority) = + setup().await; let mut transaction = Transaction::new_with_payer( - &[instruction::set_deposit_authority( + &[instruction::set_funding_authority( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - None, - DepositType::Sol, + Some(&new_authority.pubkey()), + FundingType::SolWithdraw, )], Some(&payer.pubkey()), ); @@ -283,81 +228,29 @@ async fn success_set_sol_deposit_authority_to_none() { let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; let stake_pool = - try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); - assert_eq!(stake_pool.sol_deposit_authority, None); -} - -#[tokio::test] -async fn fail_sol_wrong_manager() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_sol_deposit_authority) = - setup().await; + assert_eq!( + stake_pool.sol_withdraw_authority, + Some(new_authority.pubkey()) + ); let mut transaction = Transaction::new_with_payer( - &[instruction::set_deposit_authority( + &[instruction::set_funding_authority( &id(), &stake_pool_accounts.stake_pool.pubkey(), - &new_sol_deposit_authority.pubkey(), - Some(&new_sol_deposit_authority.pubkey()), - DepositType::Sol, + &stake_pool_accounts.manager.pubkey(), + None, + FundingType::SolWithdraw, )], Some(&payer.pubkey()), ); - transaction.sign(&[&payer, &new_sol_deposit_authority], recent_blockhash); - let transaction_error = banks_client - .process_transaction(transaction) - .await - .err() - .unwrap(); - - match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError( - _, - InstructionError::Custom(error_index), - )) => { - let program_error = error::StakePoolError::WrongManager as u32; - assert_eq!(error_index, program_error); - } - _ => panic!("Wrong error occurs while malicious try to set manager"), - } -} - -#[tokio::test] -async fn fail_set_sol_deposit_authority_without_signature() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_sol_deposit_authority) = - setup().await; - - let data = - instruction::StakePoolInstruction::SetDepositAuthority(instruction::DepositType::Sol) - .try_to_vec() - .unwrap(); - let accounts = vec![ - AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), - AccountMeta::new_readonly(stake_pool_accounts.manager.pubkey(), false), - AccountMeta::new_readonly(new_sol_deposit_authority.pubkey(), false), - ]; - let instruction = Instruction { - program_id: id(), - accounts, - data, - }; + transaction.sign(&[&payer, &stake_pool_accounts.manager], recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); - let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); - transaction.sign(&[&payer], recent_blockhash); - let transaction_error = banks_client - .process_transaction(transaction) - .await - .err() - .unwrap(); + let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; + let stake_pool = + try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); - match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError( - _, - InstructionError::Custom(error_index), - )) => { - let program_error = error::StakePoolError::SignatureMissing as u32; - assert_eq!(error_index, program_error); - } - _ => panic!("Wrong error occurs while try to set new manager without signature"), - } + assert_eq!(stake_pool.sol_withdraw_authority, None); } diff --git a/program/tests/set_manager.rs b/program/tests/set_manager.rs index 9909486a..4815825d 100644 --- a/program/tests/set_manager.rs +++ b/program/tests/set_manager.rs @@ -79,7 +79,7 @@ async fn test_set_manager() { let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; let stake_pool = - try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); assert_eq!(stake_pool.manager, new_manager.pubkey()); } diff --git a/program/tests/set_preferred.rs b/program/tests/set_preferred.rs index 04184f2d..fb5fbf81 100644 --- a/program/tests/set_preferred.rs +++ b/program/tests/set_preferred.rs @@ -69,7 +69,7 @@ async fn success_deposit() { assert!(error.is_none()); let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; - let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); assert_eq!( stake_pool.preferred_deposit_validator_vote_address, @@ -97,7 +97,7 @@ async fn success_withdraw() { assert!(error.is_none()); let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; - let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); assert_eq!(stake_pool.preferred_deposit_validator_vote_address, None); assert_eq!( @@ -124,7 +124,7 @@ async fn success_unset() { assert!(error.is_none()); let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; - let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); assert_eq!( stake_pool.preferred_withdraw_validator_vote_address, @@ -143,7 +143,7 @@ async fn success_unset() { assert!(error.is_none()); let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; - let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); assert_eq!(stake_pool.preferred_withdraw_validator_vote_address, None); } diff --git a/program/tests/set_referral_fee.rs b/program/tests/set_referral_fee.rs index f9bb2d3e..5a19c2f0 100644 --- a/program/tests/set_referral_fee.rs +++ b/program/tests/set_referral_fee.rs @@ -63,7 +63,7 @@ async fn success_stake() { &stake_pool_accounts.stake_pool.pubkey(), ) .await; - let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); assert_eq!(stake_pool.stake_referral_fee, new_referral_fee); } @@ -94,7 +94,7 @@ async fn success_stake_increase_fee_from_0() { &stake_pool_accounts.stake_pool.pubkey(), ) .await; - let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); assert_eq!(stake_pool.stake_referral_fee, new_referral_fee); } @@ -190,7 +190,7 @@ async fn success_sol() { &stake_pool_accounts.stake_pool.pubkey(), ) .await; - let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); assert_eq!(stake_pool.sol_referral_fee, new_referral_fee); } diff --git a/program/tests/set_staker.rs b/program/tests/set_staker.rs index 2425f4d1..61a6dede 100644 --- a/program/tests/set_staker.rs +++ b/program/tests/set_staker.rs @@ -56,7 +56,7 @@ async fn success_set_staker_as_manager() { let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; let stake_pool = - try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); assert_eq!(stake_pool.staker, new_staker.pubkey()); } @@ -80,7 +80,7 @@ async fn success_set_staker_as_staker() { let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; let stake_pool = - try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); assert_eq!(stake_pool.staker, new_staker.pubkey()); @@ -98,7 +98,7 @@ async fn success_set_staker_as_staker() { let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; let stake_pool = - try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); assert_eq!(stake_pool.staker, stake_pool_accounts.staker.pubkey()); } diff --git a/program/tests/set_withdrawal_fee.rs b/program/tests/set_withdrawal_fee.rs index bd2ec094..5fb475e0 100644 --- a/program/tests/set_withdrawal_fee.rs +++ b/program/tests/set_withdrawal_fee.rs @@ -49,15 +49,33 @@ async fn success() { &stake_pool_accounts.stake_pool.pubkey(), ) .await; - let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); - let old_withdrawal_fee = stake_pool.withdrawal_fee; + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); + let old_stake_withdrawal_fee = stake_pool.stake_withdrawal_fee; + let old_sol_withdrawal_fee = stake_pool.sol_withdrawal_fee; let transaction = Transaction::new_signed_with_payer( &[instruction::set_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - FeeType::Withdrawal(new_withdrawal_fee), + FeeType::StakeWithdrawal(new_withdrawal_fee), + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + context + .banks_client + .process_transaction(transaction) + .await + .unwrap(); + + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + FeeType::SolWithdrawal(new_withdrawal_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &stake_pool_accounts.manager], @@ -74,10 +92,15 @@ async fn success() { &stake_pool_accounts.stake_pool.pubkey(), ) .await; - let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); - assert_eq!(stake_pool.withdrawal_fee, old_withdrawal_fee); - assert_eq!(stake_pool.next_withdrawal_fee, Some(new_withdrawal_fee)); + assert_eq!(stake_pool.stake_withdrawal_fee, old_stake_withdrawal_fee); + assert_eq!( + stake_pool.next_stake_withdrawal_fee, + Some(new_withdrawal_fee) + ); + assert_eq!(stake_pool.sol_withdrawal_fee, old_sol_withdrawal_fee); + assert_eq!(stake_pool.next_sol_withdrawal_fee, Some(new_withdrawal_fee)); let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; @@ -100,9 +123,11 @@ async fn success() { &stake_pool_accounts.stake_pool.pubkey(), ) .await; - let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); - assert_eq!(stake_pool.withdrawal_fee, new_withdrawal_fee); - assert_eq!(stake_pool.next_withdrawal_fee, None); + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); + assert_eq!(stake_pool.stake_withdrawal_fee, new_withdrawal_fee); + assert_eq!(stake_pool.next_stake_withdrawal_fee, None); + assert_eq!(stake_pool.sol_withdrawal_fee, new_withdrawal_fee); + assert_eq!(stake_pool.next_sol_withdrawal_fee, None); } #[tokio::test] @@ -114,15 +139,33 @@ async fn success_fee_cannot_increase_more_than_once() { &stake_pool_accounts.stake_pool.pubkey(), ) .await; - let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); - let old_withdrawal_fee = stake_pool.withdrawal_fee; + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); + let old_stake_withdrawal_fee = stake_pool.stake_withdrawal_fee; + let old_sol_withdrawal_fee = stake_pool.sol_withdrawal_fee; + + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + FeeType::StakeWithdrawal(new_withdrawal_fee), + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + context + .banks_client + .process_transaction(transaction) + .await + .unwrap(); let transaction = Transaction::new_signed_with_payer( &[instruction::set_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - FeeType::Withdrawal(new_withdrawal_fee), + FeeType::SolWithdrawal(new_withdrawal_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &stake_pool_accounts.manager], @@ -139,10 +182,15 @@ async fn success_fee_cannot_increase_more_than_once() { &stake_pool_accounts.stake_pool.pubkey(), ) .await; - let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); - assert_eq!(stake_pool.withdrawal_fee, old_withdrawal_fee); - assert_eq!(stake_pool.next_withdrawal_fee, Some(new_withdrawal_fee)); + assert_eq!(stake_pool.stake_withdrawal_fee, old_stake_withdrawal_fee); + assert_eq!( + stake_pool.next_stake_withdrawal_fee, + Some(new_withdrawal_fee) + ); + assert_eq!(stake_pool.sol_withdrawal_fee, old_sol_withdrawal_fee); + assert_eq!(stake_pool.next_sol_withdrawal_fee, Some(new_withdrawal_fee)); let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; @@ -165,9 +213,11 @@ async fn success_fee_cannot_increase_more_than_once() { &stake_pool_accounts.stake_pool.pubkey(), ) .await; - let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); - assert_eq!(stake_pool.withdrawal_fee, new_withdrawal_fee); - assert_eq!(stake_pool.next_withdrawal_fee, None); + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); + assert_eq!(stake_pool.stake_withdrawal_fee, new_withdrawal_fee); + assert_eq!(stake_pool.next_stake_withdrawal_fee, None); + assert_eq!(stake_pool.sol_withdrawal_fee, new_withdrawal_fee); + assert_eq!(stake_pool.next_sol_withdrawal_fee, None); // try setting to the old fee in the same epoch let transaction = Transaction::new_signed_with_payer( @@ -175,7 +225,23 @@ async fn success_fee_cannot_increase_more_than_once() { &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - FeeType::Withdrawal(old_withdrawal_fee), + FeeType::StakeWithdrawal(old_stake_withdrawal_fee), + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + context + .banks_client + .process_transaction(transaction) + .await + .unwrap(); + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + FeeType::SolWithdrawal(old_sol_withdrawal_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &stake_pool_accounts.manager], @@ -192,9 +258,17 @@ async fn success_fee_cannot_increase_more_than_once() { &stake_pool_accounts.stake_pool.pubkey(), ) .await; - let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); - assert_eq!(stake_pool.withdrawal_fee, new_withdrawal_fee); - assert_eq!(stake_pool.next_withdrawal_fee, Some(old_withdrawal_fee)); + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); + assert_eq!(stake_pool.stake_withdrawal_fee, new_withdrawal_fee); + assert_eq!( + stake_pool.next_stake_withdrawal_fee, + Some(old_stake_withdrawal_fee) + ); + assert_eq!(stake_pool.sol_withdrawal_fee, new_withdrawal_fee); + assert_eq!( + stake_pool.next_sol_withdrawal_fee, + Some(old_sol_withdrawal_fee) + ); let error = stake_pool_accounts .update_stake_pool_balance( @@ -211,9 +285,17 @@ async fn success_fee_cannot_increase_more_than_once() { &stake_pool_accounts.stake_pool.pubkey(), ) .await; - let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); - assert_eq!(stake_pool.withdrawal_fee, new_withdrawal_fee); - assert_eq!(stake_pool.next_withdrawal_fee, Some(old_withdrawal_fee)); + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); + assert_eq!(stake_pool.stake_withdrawal_fee, new_withdrawal_fee); + assert_eq!( + stake_pool.next_stake_withdrawal_fee, + Some(old_stake_withdrawal_fee) + ); + assert_eq!(stake_pool.sol_withdrawal_fee, new_withdrawal_fee); + assert_eq!( + stake_pool.next_sol_withdrawal_fee, + Some(old_sol_withdrawal_fee) + ); } #[tokio::test] @@ -233,15 +315,33 @@ async fn success_increase_fee_from_0() { &stake_pool_accounts.stake_pool.pubkey(), ) .await; - let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); - let old_withdrawal_fee = stake_pool.withdrawal_fee; + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); + let old_stake_withdrawal_fee = stake_pool.stake_withdrawal_fee; + let old_sol_withdrawal_fee = stake_pool.sol_withdrawal_fee; let transaction = Transaction::new_signed_with_payer( &[instruction::set_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - FeeType::Withdrawal(new_withdrawal_fee), + FeeType::StakeWithdrawal(new_withdrawal_fee), + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + context + .banks_client + .process_transaction(transaction) + .await + .unwrap(); + + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + FeeType::SolWithdrawal(new_withdrawal_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &stake_pool_accounts.manager], @@ -258,10 +358,15 @@ async fn success_increase_fee_from_0() { &stake_pool_accounts.stake_pool.pubkey(), ) .await; - let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); - assert_eq!(stake_pool.withdrawal_fee, old_withdrawal_fee); - assert_eq!(stake_pool.next_withdrawal_fee, Some(new_withdrawal_fee)); + assert_eq!(stake_pool.stake_withdrawal_fee, old_stake_withdrawal_fee); + assert_eq!( + stake_pool.next_stake_withdrawal_fee, + Some(new_withdrawal_fee) + ); + assert_eq!(stake_pool.sol_withdrawal_fee, old_sol_withdrawal_fee); + assert_eq!(stake_pool.next_sol_withdrawal_fee, Some(new_withdrawal_fee)); let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; @@ -284,14 +389,16 @@ async fn success_increase_fee_from_0() { &stake_pool_accounts.stake_pool.pubkey(), ) .await; - let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); - assert_eq!(stake_pool.withdrawal_fee, new_withdrawal_fee); - assert_eq!(stake_pool.next_withdrawal_fee, None); + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); + assert_eq!(stake_pool.stake_withdrawal_fee, new_withdrawal_fee); + assert_eq!(stake_pool.next_stake_withdrawal_fee, None); + assert_eq!(stake_pool.sol_withdrawal_fee, new_withdrawal_fee); + assert_eq!(stake_pool.next_sol_withdrawal_fee, None); } #[tokio::test] async fn fail_wrong_manager() { - let (mut context, stake_pool_accounts, new_withdrawal_fee) = setup(None).await; + let (mut context, stake_pool_accounts, new_stake_withdrawal_fee) = setup(None).await; let wrong_manager = Keypair::new(); let transaction = Transaction::new_signed_with_payer( @@ -299,7 +406,7 @@ async fn fail_wrong_manager() { &id(), &stake_pool_accounts.stake_pool.pubkey(), &wrong_manager.pubkey(), - FeeType::Withdrawal(new_withdrawal_fee), + FeeType::StakeWithdrawal(new_stake_withdrawal_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &wrong_manager], @@ -324,9 +431,9 @@ async fn fail_wrong_manager() { #[tokio::test] async fn fail_high_withdrawal_fee() { - let (mut context, stake_pool_accounts, _new_withdrawal_fee) = setup(None).await; + let (mut context, stake_pool_accounts, _new_stake_withdrawal_fee) = setup(None).await; - let new_withdrawal_fee = Fee { + let new_stake_withdrawal_fee = Fee { numerator: 11, denominator: 10, }; @@ -335,7 +442,7 @@ async fn fail_high_withdrawal_fee() { &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - FeeType::Withdrawal(new_withdrawal_fee), + FeeType::StakeWithdrawal(new_stake_withdrawal_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &stake_pool_accounts.manager], @@ -359,18 +466,54 @@ async fn fail_high_withdrawal_fee() { } #[tokio::test] -async fn fail_high_withdrawal_fee_increase() { - let (mut context, stake_pool_accounts, _new_withdrawal_fee) = setup(None).await; +async fn fail_high_stake_fee_increase() { + let (mut context, stake_pool_accounts, _new_stake_withdrawal_fee) = setup(None).await; + let new_withdrawal_fee = Fee { + numerator: 46, + denominator: 10_000, + }; + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + FeeType::StakeWithdrawal(new_withdrawal_fee), + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = error::StakePoolError::FeeIncreaseTooHigh as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs when increasing fee by too large a factor"), + } +} + +#[tokio::test] +async fn fail_high_sol_fee_increase() { + let (mut context, stake_pool_accounts, _new_stake_withdrawal_fee) = setup(None).await; let new_withdrawal_fee = Fee { numerator: 46, denominator: 10_000, }; + let transaction = Transaction::new_signed_with_payer( &[instruction::set_fee( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - FeeType::Withdrawal(new_withdrawal_fee), + FeeType::SolWithdrawal(new_withdrawal_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &stake_pool_accounts.manager], @@ -394,8 +537,8 @@ async fn fail_high_withdrawal_fee_increase() { } #[tokio::test] -async fn fail_high_withdrawal_fee_increase_from_0() { - let (mut context, stake_pool_accounts, _new_withdrawal_fee) = setup(Some(Fee { +async fn fail_high_stake_fee_increase_from_0() { + let (mut context, stake_pool_accounts, _new_stake_withdrawal_fee) = setup(Some(Fee { numerator: 0, denominator: 1, })) @@ -409,7 +552,46 @@ async fn fail_high_withdrawal_fee_increase_from_0() { &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - FeeType::Withdrawal(new_withdrawal_fee), + FeeType::StakeWithdrawal(new_withdrawal_fee), + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = error::StakePoolError::FeeIncreaseTooHigh as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs when increasing fee by too large a factor"), + } +} + +#[tokio::test] +async fn fail_high_sol_fee_increase_from_0() { + let (mut context, stake_pool_accounts, _new_stake_withdrawal_fee) = setup(Some(Fee { + numerator: 0, + denominator: 1, + })) + .await; + let new_withdrawal_fee = Fee { + numerator: 16, + denominator: 10_000, + }; + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + FeeType::SolWithdrawal(new_withdrawal_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &stake_pool_accounts.manager], @@ -445,7 +627,7 @@ async fn fail_not_updated() { ) .await .unwrap(); - let new_withdrawal_fee = Fee { + let new_stake_withdrawal_fee = Fee { numerator: 11, denominator: 100, }; @@ -458,7 +640,7 @@ async fn fail_not_updated() { &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), - FeeType::Withdrawal(new_withdrawal_fee), + FeeType::StakeWithdrawal(new_stake_withdrawal_fee), )], Some(&context.payer.pubkey()), &[&context.payer, &stake_pool_accounts.manager], diff --git a/program/tests/update_stake_pool_balance.rs b/program/tests/update_stake_pool_balance.rs index aa1a2272..8b0583f0 100644 --- a/program/tests/update_stake_pool_balance.rs +++ b/program/tests/update_stake_pool_balance.rs @@ -82,7 +82,7 @@ async fn success() { &stake_pool_accounts.stake_pool.pubkey(), ) .await; - let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); assert_eq!(pre_balance, stake_pool.total_stake_lamports); let pre_token_supply = get_token_supply( @@ -137,7 +137,7 @@ async fn success() { &stake_pool_accounts.stake_pool.pubkey(), ) .await; - let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); assert_eq!(post_balance, stake_pool.total_stake_lamports); let post_fee = get_token_balance( @@ -153,8 +153,8 @@ async fn success() { let actual_fee = post_fee - pre_fee; assert_eq!(pool_token_supply - pre_token_supply, actual_fee); - let expected_fee_lamports = - (post_balance - pre_balance) * stake_pool.fee.numerator / stake_pool.fee.denominator; + let expected_fee_lamports = (post_balance - pre_balance) * stake_pool.epoch_fee.numerator + / stake_pool.epoch_fee.denominator; let actual_fee_lamports = stake_pool.calc_pool_tokens_for_deposit(actual_fee).unwrap(); assert_eq!(actual_fee_lamports, expected_fee_lamports); @@ -179,7 +179,7 @@ async fn success_ignoring_extra_lamports() { &stake_pool_accounts.stake_pool.pubkey(), ) .await; - let stake_pool = try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); assert_eq!(pre_balance, stake_pool.total_stake_lamports); let pre_token_supply = get_token_supply( diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 236c0694..ba0acab3 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -132,7 +132,7 @@ async fn _success(test_type: SuccessTestType) { let stake_pool_before = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; let stake_pool_before = - try_from_slice_unchecked::(&stake_pool_before.data.as_slice()).unwrap(); + try_from_slice_unchecked::(stake_pool_before.data.as_slice()).unwrap(); // Check user recipient stake account balance let initial_stake_lamports = get_account(&mut banks_client, &user_stake_recipient.pubkey()) @@ -235,7 +235,7 @@ async fn _success(test_type: SuccessTestType) { // Check pool stats let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; let stake_pool = - try_from_slice_unchecked::(&stake_pool.data.as_slice()).unwrap(); + try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); // first and only deposit, lamports:pool 1:1 let tokens_withdrawal_fee = match test_type { SuccessTestType::Success => { @@ -301,7 +301,7 @@ async fn _success(test_type: SuccessTestType) { deserialize::(&validator_stake_account.data).unwrap(); let meta = stake_state.meta().unwrap(); assert_eq!( - validator_stake_account.lamports - minimum_stake_lamports(&meta), + validator_stake_account.lamports - minimum_stake_lamports(meta), validator_stake_item.active_stake_lamports ); diff --git a/program/tests/withdraw_sol.rs b/program/tests/withdraw_sol.rs new file mode 100644 index 00000000..69c280be --- /dev/null +++ b/program/tests/withdraw_sol.rs @@ -0,0 +1,312 @@ +#![cfg(feature = "test-bpf")] + +mod helpers; + +use { + helpers::*, + solana_program::{ + borsh::try_from_slice_unchecked, instruction::InstructionError, pubkey::Pubkey, + }, + solana_program_test::*, + solana_sdk::{ + signature::{Keypair, Signer}, + transaction::Transaction, + transaction::TransactionError, + }, + spl_stake_pool::{ + error::StakePoolError, + id, + instruction::{self, FundingType}, + stake_program, state, + }, +}; + +async fn setup() -> (ProgramTestContext, StakePoolAccounts, Keypair, Pubkey, u64) { + let mut context = program_test().start_with_context().await; + + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + 1, + ) + .await + .unwrap(); + + let user = Keypair::new(); + + // make pool token account for user + let pool_token_account = Keypair::new(); + create_token_account( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &pool_token_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user.pubkey(), + ) + .await + .unwrap(); + + let error = stake_pool_accounts + .deposit_sol( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &pool_token_account.pubkey(), + TEST_STAKE_AMOUNT, + None, + ) + .await; + assert!(error.is_none()); + + let tokens_issued = + get_token_balance(&mut context.banks_client, &pool_token_account.pubkey()).await; + + ( + context, + stake_pool_accounts, + user, + pool_token_account.pubkey(), + tokens_issued, + ) +} + +#[tokio::test] +async fn success() { + let (mut context, stake_pool_accounts, user, pool_token_account, pool_tokens) = setup().await; + + // Save stake pool state before withdrawing + let pre_stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let pre_stake_pool = + try_from_slice_unchecked::(pre_stake_pool.data.as_slice()).unwrap(); + + // Save reserve state before withdrawing + let pre_reserve_lamports = get_account( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + ) + .await + .lamports; + + let error = stake_pool_accounts + .withdraw_sol( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user, + &pool_token_account, + pool_tokens, + None, + ) + .await; + assert!(error.is_none()); + + // Stake pool should add its balance to the pool balance + let post_stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let post_stake_pool = + try_from_slice_unchecked::(post_stake_pool.data.as_slice()).unwrap(); + let amount_withdrawn_minus_fee = + pool_tokens - stake_pool_accounts.calculate_withdrawal_fee(pool_tokens); + assert_eq!( + post_stake_pool.total_stake_lamports, + pre_stake_pool.total_stake_lamports - amount_withdrawn_minus_fee + ); + assert_eq!( + post_stake_pool.pool_token_supply, + pre_stake_pool.pool_token_supply - amount_withdrawn_minus_fee + ); + + // Check minted tokens + let user_token_balance = + get_token_balance(&mut context.banks_client, &pool_token_account).await; + assert_eq!(user_token_balance, 0); + + // Check reserve + let post_reserve_lamports = get_account( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + ) + .await + .lamports; + assert_eq!( + post_reserve_lamports, + pre_reserve_lamports - amount_withdrawn_minus_fee + ); +} + +#[tokio::test] +async fn fail_with_wrong_withdraw_authority() { + let (mut context, mut stake_pool_accounts, user, pool_token_account, pool_tokens) = + setup().await; + + stake_pool_accounts.withdraw_authority = Pubkey::new_unique(); + + let error = stake_pool_accounts + .withdraw_sol( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user, + &pool_token_account, + pool_tokens, + None, + ) + .await + .unwrap() + .unwrap(); + + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::InvalidProgramAddress as u32) + ) + ); +} + +#[tokio::test] +async fn fail_overdraw_reserve() { + let (mut context, stake_pool_accounts, user, pool_token_account, _) = setup().await; + + // add a validator and increase stake to drain the reserve + let validator_stake = simple_add_validator_to_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + ) + .await; + + let rent = context.banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let error = stake_pool_accounts + .increase_validator_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &validator_stake.transient_stake_account, + &validator_stake.vote.pubkey(), + TEST_STAKE_AMOUNT - stake_rent, + validator_stake.transient_stake_seed, + ) + .await; + assert!(error.is_none()); + + // try to withdraw one lamport, will overdraw + let error = stake_pool_accounts + .withdraw_sol( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user, + &pool_token_account, + 1, + None, + ) + .await + .unwrap() + .unwrap(); + + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::SolWithdrawalTooLarge as u32) + ) + ); +} + +#[tokio::test] +async fn success_with_sol_withdraw_authority() { + let (mut context, stake_pool_accounts, user, pool_token_account, pool_tokens) = setup().await; + let sol_withdraw_authority = Keypair::new(); + + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_funding_authority( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + Some(&sol_withdraw_authority.pubkey()), + FundingType::SolWithdraw, + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + context + .banks_client + .process_transaction(transaction) + .await + .unwrap(); + + let error = stake_pool_accounts + .withdraw_sol( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user, + &pool_token_account, + pool_tokens, + Some(&sol_withdraw_authority), + ) + .await; + assert!(error.is_none()); +} + +#[tokio::test] +async fn fail_without_sol_withdraw_authority_signature() { + let (mut context, stake_pool_accounts, user, pool_token_account, pool_tokens) = setup().await; + let sol_withdraw_authority = Keypair::new(); + + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_funding_authority( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + Some(&sol_withdraw_authority.pubkey()), + FundingType::SolWithdraw, + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + context + .banks_client + .process_transaction(transaction) + .await + .unwrap(); + + let wrong_withdrawer = Keypair::new(); + let error = stake_pool_accounts + .withdraw_sol( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user, + &pool_token_account, + pool_tokens, + Some(&wrong_withdrawer), + ) + .await + .unwrap() + .unwrap(); + + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::InvalidSolWithdrawAuthority as u32) + ) + ); +} From a5618897f8a6cbe762294a463cde2f60dcd3c16f Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 6 Oct 2021 06:11:20 +0200 Subject: [PATCH 0177/1076] stake-pool: Bump version for 0.6.0 release (#2487) --- clients/cli/Cargo.toml | 4 ++-- program/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 36e9b935..3230ae50 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -6,7 +6,7 @@ homepage = "https://spl.solana.com/stake-pool" license = "Apache-2.0" name = "spl-stake-pool-cli" repository = "https://github.com/solana-labs/solana-program-library" -version = "0.5.1" +version = "0.6.0" [dependencies] borsh = "0.9" @@ -21,7 +21,7 @@ solana-program = "=1.7.11" solana-remote-wallet = "=1.7.11" solana-sdk = "=1.7.11" spl-associated-token-account = { version = "1.0", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } -spl-stake-pool = { version = "0.5", path="../program", features = [ "no-entrypoint" ] } +spl-stake-pool = { version = "0.6", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "3.2", path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" bincode = "1.3.1" diff --git a/program/Cargo.toml b/program/Cargo.toml index 5aba6550..39f82c31 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "spl-stake-pool" -version = "0.5.0" +version = "0.6.0" description = "Solana Program Library Stake Pool" authors = ["Solana Maintainers "] repository = "https://github.com/solana-labs/solana-program-library" From d05e102eb3cae39ad8d1d4926930c88f3007bf7c Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 7 Oct 2021 00:01:15 -0400 Subject: [PATCH 0178/1076] stake-pool: Add last epoch values for APR calculation (#2491) * stake-pool: Add last epoch values for APR calculation * Bump versions for release --- clients/cli/Cargo.toml | 2 +- clients/cli/src/main.rs | 4 +- program/Cargo.toml | 2 +- program/src/processor.rs | 57 ++++++------- program/src/state.rs | 82 +++++++++++++------ program/tests/deposit.rs | 8 +- program/tests/deposit_sol.rs | 4 +- program/tests/huge_pool.rs | 6 +- program/tests/update_stake_pool_balance.rs | 8 +- .../tests/update_validator_list_balance.rs | 12 +-- program/tests/withdraw.rs | 4 +- program/tests/withdraw_sol.rs | 4 +- 12 files changed, 112 insertions(+), 81 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 3230ae50..3731b289 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -6,7 +6,7 @@ homepage = "https://spl.solana.com/stake-pool" license = "Apache-2.0" name = "spl-stake-pool-cli" repository = "https://github.com/solana-labs/solana-program-library" -version = "0.6.0" +version = "0.6.1" [dependencies] borsh = "0.9" diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index cca9fa56..d572c7c5 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -967,7 +967,7 @@ fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { } println!( "Total Pool Stake: {}{}", - Sol(stake_pool.total_stake_lamports), + Sol(stake_pool.total_lamports), if stake_pool.last_update_epoch != epoch_info.epoch { " [UPDATE REQUIRED]" } else { @@ -1542,7 +1542,7 @@ fn command_list_all_pools(config: &Config) -> CommandResult { "Address: {}\tManager: {}\tLamports: {}\tPool tokens: {}\tValidators: {}", address, stake_pool.manager, - stake_pool.total_stake_lamports, + stake_pool.total_lamports, stake_pool.pool_token_supply, validator_list.validators.len() ); diff --git a/program/Cargo.toml b/program/Cargo.toml index 39f82c31..e3157e12 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "spl-stake-pool" -version = "0.6.0" +version = "0.6.1" description = "Solana Program Library Stake Pool" authors = ["Solana Maintainers "] repository = "https://github.com/solana-labs/solana-program-library" diff --git a/program/src/processor.rs b/program/src/processor.rs index fa559901..e7fdc8df 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -607,8 +607,7 @@ impl Processor { let stake_state = try_from_slice_unchecked::( &reserve_stake_info.data.borrow(), )?; - let total_stake_lamports = if let stake_program::StakeState::Initialized(meta) = stake_state - { + let total_lamports = if let stake_program::StakeState::Initialized(meta) = stake_state { if meta.lockup != stake_program::Lockup::default() { msg!("Reserve stake account has some lockup"); return Err(StakePoolError::WrongStakeState.into()); @@ -653,7 +652,7 @@ impl Processor { stake_pool.manager_fee_account = *manager_fee_info.key; stake_pool.token_program_id = *token_program_info.key; stake_pool.last_update_epoch = Clock::get()?.epoch; - stake_pool.total_stake_lamports = total_stake_lamports; + stake_pool.total_lamports = total_lamports; stake_pool.epoch_fee = epoch_fee; stake_pool.next_epoch_fee = None; stake_pool.preferred_deposit_validator_vote_address = None; @@ -1614,30 +1613,31 @@ impl Processor { return Err(StakePoolError::InvalidState.into()); } - let previous_lamports = stake_pool.total_stake_lamports; + let previous_lamports = stake_pool.total_lamports; + let previous_pool_token_supply = stake_pool.pool_token_supply; let reserve_stake = try_from_slice_unchecked::( &reserve_stake_info.data.borrow(), )?; - let mut total_stake_lamports = - if let stake_program::StakeState::Initialized(meta) = reserve_stake { - reserve_stake_info - .lamports() - .checked_sub(minimum_reserve_lamports(&meta)) - .ok_or(StakePoolError::CalculationFailure)? - } else { - msg!("Reserve stake account in unknown state, aborting"); - return Err(StakePoolError::WrongStakeState.into()); - }; + let mut total_lamports = if let stake_program::StakeState::Initialized(meta) = reserve_stake + { + reserve_stake_info + .lamports() + .checked_sub(minimum_reserve_lamports(&meta)) + .ok_or(StakePoolError::CalculationFailure)? + } else { + msg!("Reserve stake account in unknown state, aborting"); + return Err(StakePoolError::WrongStakeState.into()); + }; for validator_stake_record in validator_list.iter::() { if validator_stake_record.last_update_epoch < clock.epoch { return Err(StakePoolError::StakeListOutOfDate.into()); } - total_stake_lamports = total_stake_lamports + total_lamports = total_lamports .checked_add(validator_stake_record.stake_lamports()) .ok_or(StakePoolError::CalculationFailure)?; } - let reward_lamports = total_stake_lamports.saturating_sub(previous_lamports); + let reward_lamports = total_lamports.saturating_sub(previous_lamports); // If the manager fee info is invalid, they don't deserve to receive the fee. let fee = if stake_pool.check_manager_fee_info(manager_fee_info).is_ok() { @@ -1659,11 +1659,6 @@ impl Processor { stake_pool.stake_withdraw_bump_seed, fee, )?; - - stake_pool.pool_token_supply = stake_pool - .pool_token_supply - .checked_add(fee) - .ok_or(StakePoolError::CalculationFailure)?; } if stake_pool.last_update_epoch < clock.epoch { @@ -1680,8 +1675,10 @@ impl Processor { stake_pool.next_sol_withdrawal_fee = None; } stake_pool.last_update_epoch = clock.epoch; + stake_pool.last_epoch_total_lamports = previous_lamports; + stake_pool.last_epoch_pool_token_supply = previous_pool_token_supply; } - stake_pool.total_stake_lamports = total_stake_lamports; + stake_pool.total_lamports = total_lamports; let pool_mint = Mint::unpack_from_slice(&pool_mint_info.data.borrow())?; stake_pool.pool_token_supply = pool_mint.supply; @@ -1974,8 +1971,8 @@ impl Processor { .ok_or(StakePoolError::CalculationFailure)?; // We treat the extra lamports as though they were // transferred directly to the reserve stake account. - stake_pool.total_stake_lamports = stake_pool - .total_stake_lamports + stake_pool.total_lamports = stake_pool + .total_lamports .checked_add(all_deposit_lamports) .ok_or(StakePoolError::CalculationFailure)?; stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; @@ -2121,8 +2118,8 @@ impl Processor { .pool_token_supply .checked_add(new_pool_tokens) .ok_or(StakePoolError::CalculationFailure)?; - stake_pool.total_stake_lamports = stake_pool - .total_stake_lamports + stake_pool.total_lamports = stake_pool + .total_lamports .checked_add(deposit_lamports) .ok_or(StakePoolError::CalculationFailure)?; stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; @@ -2345,8 +2342,8 @@ impl Processor { .pool_token_supply .checked_sub(pool_tokens_burnt) .ok_or(StakePoolError::CalculationFailure)?; - stake_pool.total_stake_lamports = stake_pool - .total_stake_lamports + stake_pool.total_lamports = stake_pool + .total_lamports .checked_sub(withdraw_lamports) .ok_or(StakePoolError::CalculationFailure)?; stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; @@ -2500,8 +2497,8 @@ impl Processor { .pool_token_supply .checked_sub(pool_tokens_burnt) .ok_or(StakePoolError::CalculationFailure)?; - stake_pool.total_stake_lamports = stake_pool - .total_stake_lamports + stake_pool.total_lamports = stake_pool + .total_lamports .checked_sub(withdraw_lamports) .ok_or(StakePoolError::CalculationFailure)?; stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; diff --git a/program/src/state.rs b/program/src/state.rs index 1466cfb6..9c2776f0 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -86,12 +86,12 @@ pub struct StakePool { /// Total stake under management. /// Note that if `last_update_epoch` does not match the current epoch then /// this field may not be accurate - pub total_stake_lamports: u64, + pub total_lamports: u64, /// Total supply of pool tokens (should always match the supply in the Pool Mint) pub pool_token_supply: u64, - /// Last epoch the `total_stake_lamports` field was updated + /// Last epoch the `total_lamports` field was updated pub last_update_epoch: u64, /// Lockup that all stakes in the pool must have @@ -146,18 +146,24 @@ pub struct StakePool { /// Future SOL withdrawal fee, to be set for the following epoch pub next_sol_withdrawal_fee: Option, + + /// Last epoch's total pool tokens, used only for APR estimation + pub last_epoch_pool_token_supply: u64, + + /// Last epoch's total lamports, used only for APR estimation + pub last_epoch_total_lamports: u64, } impl StakePool { /// calculate the pool tokens that should be minted for a deposit of `stake_lamports` #[inline] pub fn calc_pool_tokens_for_deposit(&self, stake_lamports: u64) -> Option { - if self.total_stake_lamports == 0 || self.pool_token_supply == 0 { + if self.total_lamports == 0 || self.pool_token_supply == 0 { return Some(stake_lamports); } u64::try_from( (stake_lamports as u128) .checked_mul(self.pool_token_supply as u128)? - .checked_div(self.total_stake_lamports as u128)?, + .checked_div(self.total_lamports as u128)?, ) .ok() } @@ -168,7 +174,7 @@ impl StakePool { // `checked_ceil_div` returns `None` for a 0 quotient result, but in this // case, a return of 0 is valid for small amounts of pool tokens. So // we check for that separately - let numerator = (pool_tokens as u128).checked_mul(self.total_stake_lamports as u128)?; + let numerator = (pool_tokens as u128).checked_mul(self.total_lamports as u128)?; let denominator = self.pool_token_supply as u128; if numerator < denominator || denominator == 0 { Some(0) @@ -227,22 +233,21 @@ impl StakePool { /// Calculate the fee in pool tokens that goes to the manager /// /// This function assumes that `reward_lamports` has not already been added - /// to the stake pool's `total_stake_lamports` + /// to the stake pool's `total_lamports` #[inline] pub fn calc_epoch_fee_amount(&self, reward_lamports: u64) -> Option { if reward_lamports == 0 { return Some(0); } - let total_stake_lamports = - (self.total_stake_lamports as u128).checked_add(reward_lamports as u128)?; + let total_lamports = (self.total_lamports as u128).checked_add(reward_lamports as u128)?; let fee_lamports = self.epoch_fee.apply(reward_lamports)?; - if total_stake_lamports == fee_lamports || self.pool_token_supply == 0 { + if total_lamports == fee_lamports || self.pool_token_supply == 0 { Some(reward_lamports) } else { u64::try_from( (self.pool_token_supply as u128) .checked_mul(fee_lamports)? - .checked_div(total_stake_lamports.checked_sub(fee_lamports)?)?, + .checked_div(total_lamports.checked_sub(fee_lamports)?)?, ) .ok() } @@ -816,7 +821,10 @@ mod test { solana_program::borsh::{ get_instance_packed_len, get_packed_len, try_from_slice_unchecked, }, - solana_program::native_token::LAMPORTS_PER_SOL, + solana_program::{ + clock::{DEFAULT_SLOTS_PER_EPOCH, DEFAULT_S_PER_SLOT, SECONDS_PER_DAY}, + native_token::LAMPORTS_PER_SOL, + }, }; fn uninitialized_validator_list() -> ValidatorList { @@ -992,11 +1000,11 @@ mod test { } prop_compose! { - fn total_stake_and_rewards()(total_stake_lamports in 1..u64::MAX)( - total_stake_lamports in Just(total_stake_lamports), - rewards in 0..=total_stake_lamports, + fn total_stake_and_rewards()(total_lamports in 1..u64::MAX)( + total_lamports in Just(total_lamports), + rewards in 0..=total_lamports, ) -> (u64, u64) { - (total_stake_lamports - rewards, rewards) + (total_lamports - rewards, rewards) } } @@ -1008,7 +1016,7 @@ mod test { denominator: 10, }; let mut stake_pool = StakePool { - total_stake_lamports: 100 * LAMPORTS_PER_SOL, + total_lamports: 100 * LAMPORTS_PER_SOL, pool_token_supply: 100 * LAMPORTS_PER_SOL, epoch_fee, ..StakePool::default() @@ -1016,7 +1024,7 @@ mod test { let reward_lamports = 10 * LAMPORTS_PER_SOL; let pool_token_fee = stake_pool.calc_epoch_fee_amount(reward_lamports).unwrap(); - stake_pool.total_stake_lamports += reward_lamports; + stake_pool.total_lamports += reward_lamports; stake_pool.pool_token_supply += pool_token_fee; let fee_lamports = stake_pool @@ -1042,7 +1050,7 @@ mod test { #[test] fn divide_by_zero_fee() { let stake_pool = StakePool { - total_stake_lamports: 0, + total_lamports: 0, epoch_fee: Fee { numerator: 1, denominator: 10, @@ -1054,22 +1062,44 @@ mod test { assert_eq!(fee, rewards); } + #[test] + fn approximate_apr_calculation() { + // 8% / year means roughly .044% / epoch + let stake_pool = StakePool { + last_epoch_total_lamports: 100_000, + last_epoch_pool_token_supply: 100_000, + total_lamports: 100_044, + pool_token_supply: 100_000, + ..StakePool::default() + }; + let pool_token_value = + stake_pool.total_lamports as f64 / stake_pool.pool_token_supply as f64; + let last_epoch_pool_token_value = stake_pool.last_epoch_total_lamports as f64 + / stake_pool.last_epoch_pool_token_supply as f64; + let epoch_rate = pool_token_value / last_epoch_pool_token_value - 1.0; + const SECONDS_PER_EPOCH: f64 = DEFAULT_SLOTS_PER_EPOCH as f64 * DEFAULT_S_PER_SLOT; + const EPOCHS_PER_YEAR: f64 = SECONDS_PER_DAY as f64 * 365.25 / SECONDS_PER_EPOCH; + const EPSILON: f64 = 0.00001; + let yearly_rate = epoch_rate * EPOCHS_PER_YEAR; + assert!((yearly_rate - 0.080355).abs() < EPSILON); + } + proptest! { #[test] fn fee_calculation( (numerator, denominator) in fee(), - (total_stake_lamports, reward_lamports) in total_stake_and_rewards(), + (total_lamports, reward_lamports) in total_stake_and_rewards(), ) { let epoch_fee = Fee { denominator, numerator }; let mut stake_pool = StakePool { - total_stake_lamports, - pool_token_supply: total_stake_lamports, + total_lamports, + pool_token_supply: total_lamports, epoch_fee, ..StakePool::default() }; let pool_token_fee = stake_pool.calc_epoch_fee_amount(reward_lamports).unwrap(); - stake_pool.total_stake_lamports += reward_lamports; + stake_pool.total_lamports += reward_lamports; stake_pool.pool_token_supply += pool_token_fee; let fee_lamports = stake_pool.calc_lamports_withdraw_amount(pool_token_fee).unwrap(); @@ -1082,7 +1112,7 @@ mod test { // since we do two "flooring" conversions, the max epsilon should be // correct up to 2 lamports (one for each floor division), plus a // correction for huge discrepancies between rewards and total stake - let epsilon = 2 + reward_lamports / total_stake_lamports; + let epsilon = 2 + reward_lamports / total_lamports; assert!(max_fee_lamports - fee_lamports <= epsilon, "Max expected fee in lamports {}, actually receive {}, epsilon {}", max_fee_lamports, fee_lamports, epsilon); @@ -1102,16 +1132,16 @@ mod test { proptest! { #[test] fn deposit_and_withdraw( - (total_stake_lamports, pool_token_supply, deposit_stake) in total_tokens_and_deposit() + (total_lamports, pool_token_supply, deposit_stake) in total_tokens_and_deposit() ) { let mut stake_pool = StakePool { - total_stake_lamports, + total_lamports, pool_token_supply, ..StakePool::default() }; let deposit_result = stake_pool.calc_pool_tokens_for_deposit(deposit_stake).unwrap(); prop_assume!(deposit_result > 0); - stake_pool.total_stake_lamports += deposit_stake; + stake_pool.total_lamports += deposit_stake; stake_pool.pool_token_supply += deposit_result; let withdraw_result = stake_pool.calc_lamports_withdraw_amount(deposit_result).unwrap(); assert!(withdraw_result <= deposit_stake); diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 4e95a82a..d58f1511 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -203,8 +203,8 @@ async fn success() { let post_stake_pool = try_from_slice_unchecked::(post_stake_pool.data.as_slice()).unwrap(); assert_eq!( - post_stake_pool.total_stake_lamports, - pre_stake_pool.total_stake_lamports + stake_lamports + post_stake_pool.total_lamports, + pre_stake_pool.total_lamports + stake_lamports ); assert_eq!( post_stake_pool.pool_token_supply, @@ -374,8 +374,8 @@ async fn success_with_extra_stake_lamports() { let post_stake_pool = try_from_slice_unchecked::(post_stake_pool.data.as_slice()).unwrap(); assert_eq!( - post_stake_pool.total_stake_lamports, - pre_stake_pool.total_stake_lamports + extra_lamports + stake_lamports + post_stake_pool.total_lamports, + pre_stake_pool.total_lamports + extra_lamports + stake_lamports ); assert_eq!( post_stake_pool.pool_token_supply, diff --git a/program/tests/deposit_sol.rs b/program/tests/deposit_sol.rs index 3d30e2d3..ded76693 100644 --- a/program/tests/deposit_sol.rs +++ b/program/tests/deposit_sol.rs @@ -103,8 +103,8 @@ async fn success() { let post_stake_pool = try_from_slice_unchecked::(post_stake_pool.data.as_slice()).unwrap(); assert_eq!( - post_stake_pool.total_stake_lamports, - pre_stake_pool.total_stake_lamports + TEST_STAKE_AMOUNT + post_stake_pool.total_lamports, + pre_stake_pool.total_lamports + TEST_STAKE_AMOUNT ); assert_eq!( post_stake_pool.pool_token_supply, diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index 2188961b..dac35614 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -69,7 +69,7 @@ async fn setup( pool_mint: stake_pool_accounts.pool_mint.pubkey(), manager_fee_account: stake_pool_accounts.pool_fee_account.pubkey(), token_program_id: spl_token::id(), - total_stake_lamports: 0, + total_lamports: 0, pool_token_supply: 0, last_update_epoch: 0, lockup: stake_program::Lockup::default(), @@ -87,6 +87,8 @@ async fn setup( sol_withdraw_authority: None, sol_withdrawal_fee: Fee::default(), next_sol_withdrawal_fee: None, + last_epoch_pool_token_supply: 0, + last_epoch_total_lamports: 0, }; let mut validator_list = ValidatorList::new(max_validators); @@ -168,7 +170,7 @@ async fn setup( transient_seed_suffix_end: 0, }); - stake_pool.total_stake_lamports += active_stake_lamports; + stake_pool.total_lamports += active_stake_lamports; stake_pool.pool_token_supply += active_stake_lamports; } diff --git a/program/tests/update_stake_pool_balance.rs b/program/tests/update_stake_pool_balance.rs index 8b0583f0..9bbb558f 100644 --- a/program/tests/update_stake_pool_balance.rs +++ b/program/tests/update_stake_pool_balance.rs @@ -83,7 +83,7 @@ async fn success() { ) .await; let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); - assert_eq!(pre_balance, stake_pool.total_stake_lamports); + assert_eq!(pre_balance, stake_pool.total_lamports); let pre_token_supply = get_token_supply( &mut context.banks_client, @@ -138,7 +138,7 @@ async fn success() { ) .await; let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); - assert_eq!(post_balance, stake_pool.total_stake_lamports); + assert_eq!(post_balance, stake_pool.total_lamports); let post_fee = get_token_balance( &mut context.banks_client, @@ -162,6 +162,8 @@ async fn success() { assert_eq!(expected_fee, actual_fee); assert_eq!(pool_token_supply, stake_pool.pool_token_supply); + assert_eq!(pre_token_supply, stake_pool.last_epoch_pool_token_supply); + assert_eq!(pre_balance, stake_pool.last_epoch_total_lamports); } #[tokio::test] @@ -180,7 +182,7 @@ async fn success_ignoring_extra_lamports() { ) .await; let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); - assert_eq!(pre_balance, stake_pool.total_stake_lamports); + assert_eq!(pre_balance, stake_pool.total_lamports); let pre_token_supply = get_token_supply( &mut context.banks_client, diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index a394acf0..82387d46 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -214,7 +214,7 @@ async fn success() { ) .await; let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data).unwrap(); - assert_eq!(new_lamports, stake_pool.total_stake_lamports); + assert_eq!(new_lamports, stake_pool.total_lamports); } #[tokio::test] @@ -282,7 +282,7 @@ async fn merge_into_reserve() { ) .await; let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data).unwrap(); - assert_eq!(expected_lamports, stake_pool.total_stake_lamports); + assert_eq!(expected_lamports, stake_pool.total_lamports); println!("Warp one more epoch so the stakes deactivate"); let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; @@ -325,7 +325,7 @@ async fn merge_into_reserve() { ) .await; let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data).unwrap(); - assert_eq!(expected_lamports, stake_pool.total_stake_lamports); + assert_eq!(expected_lamports, stake_pool.total_lamports); } #[tokio::test] @@ -389,7 +389,7 @@ async fn merge_into_validator_stake() { ) .await; let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data).unwrap(); - assert_eq!(expected_lamports, stake_pool.total_stake_lamports); + assert_eq!(expected_lamports, stake_pool.total_lamports); // Warp one more epoch so the stakes activate, ready to merge let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; @@ -422,7 +422,7 @@ async fn merge_into_validator_stake() { ) .await; let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data).unwrap(); - assert_eq!(current_lamports, stake_pool.total_stake_lamports); + assert_eq!(current_lamports, stake_pool.total_lamports); // Check that transient accounts are gone for stake_account in &stake_accounts { @@ -803,7 +803,7 @@ async fn success_ignoring_hijacked_transient_stake() { ) .await; let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data).unwrap(); - assert_eq!(pre_lamports, stake_pool.total_stake_lamports); + assert_eq!(pre_lamports, stake_pool.total_lamports); } #[tokio::test] diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index ba0acab3..b8ebbeb3 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -245,8 +245,8 @@ async fn _success(test_type: SuccessTestType) { }; let tokens_burnt = tokens_to_withdraw - tokens_withdrawal_fee; assert_eq!( - stake_pool.total_stake_lamports, - stake_pool_before.total_stake_lamports - tokens_burnt + stake_pool.total_lamports, + stake_pool_before.total_lamports - tokens_burnt ); assert_eq!( stake_pool.pool_token_supply, diff --git a/program/tests/withdraw_sol.rs b/program/tests/withdraw_sol.rs index 69c280be..690ab361 100644 --- a/program/tests/withdraw_sol.rs +++ b/program/tests/withdraw_sol.rs @@ -119,8 +119,8 @@ async fn success() { let amount_withdrawn_minus_fee = pool_tokens - stake_pool_accounts.calculate_withdrawal_fee(pool_tokens); assert_eq!( - post_stake_pool.total_stake_lamports, - pre_stake_pool.total_stake_lamports - amount_withdrawn_minus_fee + post_stake_pool.total_lamports, + pre_stake_pool.total_lamports - amount_withdrawn_minus_fee ); assert_eq!( post_stake_pool.pool_token_supply, From 1210ae989b66cfb9f1f9e4c53c51c03ebb6468bf Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 12 Oct 2021 00:04:35 -0400 Subject: [PATCH 0179/1076] stake-pool-cli: Fix funding authority flag name (#2500) --- clients/cli/Cargo.toml | 2 +- clients/cli/src/main.rs | 13 ++++--------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 3731b289..3406d10a 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -6,7 +6,7 @@ homepage = "https://spl.solana.com/stake-pool" license = "Apache-2.0" name = "spl-stake-pool-cli" repository = "https://github.com/solana-labs/solana-program-library" -version = "0.6.1" +version = "0.6.2" [dependencies] borsh = "0.9" diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index d572c7c5..292a6d71 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -1493,7 +1493,7 @@ fn command_set_staker( fn command_set_funding_authority( config: &Config, stake_pool_address: &Pubkey, - new_sol_deposit_authority: Option, + new_authority: Option, funding_type: FundingType, ) -> CommandResult { let mut signers = vec![config.fee_payer.as_ref(), config.manager.as_ref()]; @@ -1504,7 +1504,7 @@ fn command_set_funding_authority( &spl_stake_pool::id(), stake_pool_address, &config.manager.pubkey(), - new_sol_deposit_authority.as_ref(), + new_authority.as_ref(), funding_type, )], &signers, @@ -2540,7 +2540,7 @@ fn main() { } ("set-funding-authority", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); - let new_stake_deposit_authority = pubkey_of(arg_matches, "new_stake_deposit_authority"); + let new_authority = pubkey_of(arg_matches, "new_authority"); let funding_type = match arg_matches.value_of("funding_type").unwrap() { "sol-deposit" => FundingType::SolDeposit, "stake-deposit" => FundingType::StakeDeposit, @@ -2548,12 +2548,7 @@ fn main() { _ => unreachable!(), }; let _unset = arg_matches.is_present("unset"); - command_set_funding_authority( - &config, - &stake_pool_address, - new_stake_deposit_authority, - funding_type, - ) + command_set_funding_authority(&config, &stake_pool_address, new_authority, funding_type) } ("set-fee", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); From f3eca83e8e7514feba47c92eaff3dc625bf34147 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Tue, 12 Oct 2021 09:14:32 -0700 Subject: [PATCH 0180/1076] Upgrade to Solana 1.8.0 --- clients/cli/Cargo.toml | 16 ++++++++-------- program/Cargo.toml | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 3406d10a..9b447417 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -12,14 +12,14 @@ version = "0.6.2" borsh = "0.9" clap = "2.33.3" serde_json = "1.0.68" -solana-account-decoder = "=1.7.11" -solana-clap-utils = "=1.7.11" -solana-cli-config = "=1.7.11" -solana-client = "=1.7.11" -solana-logger = "=1.7.11" -solana-program = "=1.7.11" -solana-remote-wallet = "=1.7.11" -solana-sdk = "=1.7.11" +solana-account-decoder = "=1.8.0" +solana-clap-utils = "=1.8.0" +solana-cli-config = "=1.8.0" +solana-client = "=1.8.0" +solana-logger = "=1.8.0" +solana-program = "=1.8.0" +solana-remote-wallet = "=1.8.0" +solana-sdk = "=1.8.0" spl-associated-token-account = { version = "1.0", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "0.6", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "3.2", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/program/Cargo.toml b/program/Cargo.toml index e3157e12..d0dc8464 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -19,7 +19,7 @@ num-traits = "0.2" num_enum = "0.5.4" serde = "1.0.130" serde_derive = "1.0.103" -solana-program = "1.7.11" +solana-program = "1.8.0" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-token = { version = "3.2", path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" @@ -27,9 +27,9 @@ bincode = "1.3.1" [dev-dependencies] proptest = "1.0" -solana-program-test = "1.7.11" -solana-sdk = "1.7.11" -solana-vote-program = "1.7.11" +solana-program-test = "1.8.0" +solana-sdk = "1.8.0" +solana-vote-program = "1.8.0" [lib] crate-type = ["cdylib", "lib"] From 104280735fb3d70a82cda41954bf793c2df7c085 Mon Sep 17 00:00:00 2001 From: Alexander Ray Date: Fri, 15 Oct 2021 22:35:44 +0200 Subject: [PATCH 0181/1076] - reimplement prepare_withdraw_accounts according to the documentation (#2513) * - reimplement prepare_withdraw_accounts according to the docu * - add preferred withdraw validator * - fix clippy issues * - fix styling --- clients/cli/src/client.rs | 37 ----------------- clients/cli/src/main.rs | 86 ++++++++++++++++++++++++++++++++++----- 2 files changed, 75 insertions(+), 48 deletions(-) diff --git a/clients/cli/src/client.rs b/clients/cli/src/client.rs index 7f58d581..ef4d1d8e 100644 --- a/clients/cli/src/client.rs +++ b/clients/cli/src/client.rs @@ -77,43 +77,6 @@ pub(crate) fn get_stake_state( Ok(stake_state) } -pub(crate) fn get_stake_accounts_by_withdraw_authority( - rpc_client: &RpcClient, - withdraw_authority: &Pubkey, -) -> Result, ClientError> { - rpc_client - .get_program_accounts_with_config( - &stake_program::id(), - #[allow(clippy::needless_update)] // TODO: Remove after updating to solana >=1.6.10 - RpcProgramAccountsConfig { - filters: Some(vec![RpcFilterType::Memcmp(Memcmp { - offset: 44, // 44 is Withdrawer authority offset in stake account stake - bytes: MemcmpEncodedBytes::Binary(format!("{}", withdraw_authority)), - encoding: None, - })]), - account_config: RpcAccountInfoConfig { - encoding: Some(UiAccountEncoding::Base64), - ..RpcAccountInfoConfig::default() - }, - ..RpcProgramAccountsConfig::default() - }, - ) - .map(|accounts| { - accounts - .into_iter() - .filter_map( - |(address, account)| match deserialize(account.data.as_slice()) { - Ok(stake_state) => Some((address, account.lamports, stake_state)), - Err(err) => { - eprintln!("Invalid stake account data for {}: {}", address, err); - None - } - }, - ) - .collect() - }) -} - pub(crate) fn get_stake_pools( rpc_client: &RpcClient, ) -> Result, ClientError> { diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 292a6d71..d914a743 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -31,6 +31,7 @@ use { transaction::Transaction, }, spl_associated_token_account::{create_associated_token_account, get_associated_token_address}, + spl_stake_pool::state::ValidatorStakeInfo, spl_stake_pool::{ self, find_stake_program_address, find_transient_stake_program_address, find_withdraw_authority_program_address, @@ -39,6 +40,7 @@ use { state::{Fee, FeeType, StakePool, ValidatorList}, MINIMUM_ACTIVE_STAKE, }, + std::cmp::Ordering, std::{process::exit, sync::Arc}, }; @@ -1061,31 +1063,93 @@ struct WithdrawAccount { pool_amount: u64, } +fn sorted_accounts( + validator_list: &ValidatorList, + stake_pool: &StakePool, + get_pubkey: F, +) -> Vec<(Pubkey, u64, Option)> +where + F: Fn(&ValidatorStakeInfo) -> Pubkey, +{ + let mut result: Vec<(Pubkey, u64, Option)> = validator_list + .validators + .iter() + .map(|validator| { + ( + get_pubkey(validator), + validator.active_stake_lamports, + Some(validator.vote_account_address), + ) + }) + .collect::>(); + + result.sort_by(|left, right| { + if left.2 == stake_pool.preferred_withdraw_validator_vote_address { + Ordering::Less + } else if right.2 == stake_pool.preferred_withdraw_validator_vote_address { + Ordering::Greater + } else { + right.1.cmp(&left.1) + } + }); + + result +} + fn prepare_withdraw_accounts( rpc_client: &RpcClient, stake_pool: &StakePool, - pool_withdraw_authority: &Pubkey, pool_amount: u64, + stake_pool_address: &Pubkey, ) -> Result, Error> { - let mut accounts = - get_stake_accounts_by_withdraw_authority(rpc_client, pool_withdraw_authority)?; - if accounts.is_empty() { - return Err("No accounts found.".to_string().into()); - } let min_balance = rpc_client .get_minimum_balance_for_rent_exemption(STAKE_STATE_LEN)? .saturating_add(MINIMUM_ACTIVE_STAKE); let pool_mint = get_token_mint(rpc_client, &stake_pool.pool_mint)?; - // Sort from highest to lowest balance - accounts.sort_by(|a, b| b.1.cmp(&a.1)); + let validator_list: ValidatorList = get_validator_list(rpc_client, &stake_pool.validator_list)?; + + let mut accounts: Vec<(Pubkey, u64, Option)> = Vec::new(); + + accounts.append(&mut sorted_accounts( + &validator_list, + stake_pool, + |validator| { + let (stake_account_address, _) = find_stake_program_address( + &spl_stake_pool::id(), + &validator.vote_account_address, + stake_pool_address, + ); + + stake_account_address + }, + )); + + accounts.append(&mut sorted_accounts( + &validator_list, + stake_pool, + |validator| { + let (transient_stake_account_address, _) = find_transient_stake_program_address( + &spl_stake_pool::id(), + &validator.vote_account_address, + stake_pool_address, + validator.transient_seed_suffix_start, + ); + + transient_stake_account_address + }, + )); + + let reserve_stake = rpc_client.get_account(&stake_pool.reserve_stake)?; + + accounts.push((stake_pool.reserve_stake, reserve_stake.lamports, None)); // Prepare the list of accounts to withdraw from let mut withdraw_from: Vec = vec![]; let mut remaining_amount = pool_amount; // Go through available accounts and withdraw from largest to smallest - for (stake_address, lamports, stake) in accounts { + for (stake_address, lamports, vote_address_opt) in accounts { if lamports <= min_balance { continue; } @@ -1099,7 +1163,7 @@ fn prepare_withdraw_accounts( // Those accounts will be withdrawn completely with `claim` instruction withdraw_from.push(WithdrawAccount { stake_address, - vote_address: stake.delegation().map(|x| x.voter_pubkey), + vote_address: vote_address_opt, pool_amount, }); remaining_amount -= pool_amount; @@ -1204,8 +1268,8 @@ fn command_withdraw_stake( prepare_withdraw_accounts( &config.rpc_client, &stake_pool, - &pool_withdraw_authority, pool_amount, + stake_pool_address, )? }; From e98fb4fda682fc6be300bf74fe47ee2a2d430179 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 19 Oct 2021 00:45:46 +0200 Subject: [PATCH 0182/1076] stake-pool: Improve error when overdrawing on decrease (#2522) --- program/src/processor.rs | 16 +++++++++++++- program/tests/decrease.rs | 45 ++++++++++++++++++++++++++++++++++----- 2 files changed, 55 insertions(+), 6 deletions(-) diff --git a/program/src/processor.rs b/program/src/processor.rs index e7fdc8df..ff476abe 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1019,7 +1019,7 @@ impl Processor { return Err(StakePoolError::InvalidState.into()); } - let (_meta, stake) = get_stake_state(validator_stake_account_info)?; + let (meta, stake) = get_stake_state(validator_stake_account_info)?; let vote_account_address = stake.delegation.voter_pubkey; check_validator_stake_address( program_id, @@ -1069,6 +1069,20 @@ impl Processor { return Err(ProgramError::AccountNotRentExempt); } + let remaining_lamports = validator_stake_account_info + .lamports() + .checked_sub(lamports) + .ok_or(ProgramError::InsufficientFunds)?; + let required_lamports = minimum_stake_lamports(&meta); + if remaining_lamports < required_lamports { + msg!("Need at least {} lamports in the stake account after decrease, {} requested, {} is the current possible maximum", + required_lamports, + lamports, + validator_stake_account_info.lamports().checked_sub(required_lamports).ok_or(StakePoolError::CalculationFailure)? + ); + return Err(ProgramError::InsufficientFunds); + } + create_transient_stake_account( transient_stake_account_info.clone(), transient_stake_account_signer_seeds, diff --git a/program/tests/decrease.rs b/program/tests/decrease.rs index e3400891..20c73fbf 100644 --- a/program/tests/decrease.rs +++ b/program/tests/decrease.rs @@ -367,7 +367,7 @@ async fn fail_with_small_lamport_amount() { } #[tokio::test] -async fn fail_overdraw_validator() { +async fn fail_big_overdraw() { let ( mut banks_client, payer, @@ -392,8 +392,43 @@ async fn fail_overdraw_validator() { .unwrap() .unwrap(); - match error { - TransactionError::InstructionError(_, InstructionError::InsufficientFunds) => {} - _ => panic!("Wrong error occurs while overdrawing stake account on decrease"), - } + assert_eq!( + error, + TransactionError::InstructionError(0, InstructionError::InsufficientFunds) + ); +} + +#[tokio::test] +async fn fail_overdraw() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + validator_stake, + deposit_info, + _decrease_lamports, + ) = setup().await; + + let rent = banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + + let error = stake_pool_accounts + .decrease_validator_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &validator_stake.stake_account, + &validator_stake.transient_stake_account, + deposit_info.stake_lamports + stake_rent + 1, + validator_stake.transient_stake_seed, + ) + .await + .unwrap() + .unwrap(); + + assert_eq!( + error, + TransactionError::InstructionError(0, InstructionError::InsufficientFunds) + ); } From f74f4efd90ec4e6a699855a016c8ace9dfc079d9 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 19 Oct 2021 00:46:39 +0200 Subject: [PATCH 0183/1076] stake-pool: Initialize all pool fields explicitly (#2523) --- program/src/processor.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/program/src/processor.rs b/program/src/processor.rs index ff476abe..9c065f10 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -644,15 +644,17 @@ impl Processor { stake_pool.account_type = AccountType::StakePool; stake_pool.manager = *manager_info.key; stake_pool.staker = *staker_info.key; - stake_pool.reserve_stake = *reserve_stake_info.key; stake_pool.stake_deposit_authority = stake_deposit_authority; stake_pool.stake_withdraw_bump_seed = stake_withdraw_bump_seed; stake_pool.validator_list = *validator_list_info.key; + stake_pool.reserve_stake = *reserve_stake_info.key; stake_pool.pool_mint = *pool_mint_info.key; stake_pool.manager_fee_account = *manager_fee_info.key; stake_pool.token_program_id = *token_program_info.key; - stake_pool.last_update_epoch = Clock::get()?.epoch; stake_pool.total_lamports = total_lamports; + stake_pool.pool_token_supply = 0; + stake_pool.last_update_epoch = Clock::get()?.epoch; + stake_pool.lockup = stake_program::Lockup::default(); stake_pool.epoch_fee = epoch_fee; stake_pool.next_epoch_fee = None; stake_pool.preferred_deposit_validator_vote_address = None; @@ -666,7 +668,9 @@ impl Processor { stake_pool.sol_referral_fee = referral_fee; stake_pool.sol_withdraw_authority = None; stake_pool.sol_withdrawal_fee = withdrawal_fee; - stake_pool.next_stake_withdrawal_fee = None; + stake_pool.next_sol_withdrawal_fee = None; + stake_pool.last_epoch_pool_token_supply = 0; + stake_pool.last_epoch_total_lamports = 0; stake_pool .serialize(&mut *stake_pool_info.data.borrow_mut()) From 1be6e31cf15b6afa1b26f69a7982ee5a7c09027a Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 19 Oct 2021 00:46:49 +0200 Subject: [PATCH 0184/1076] stake-pool: Add checked math to big vec calc (#2524) --- program/src/big_vec.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/program/src/big_vec.rs b/program/src/big_vec.rs index 0c0f81a6..385fb3f2 100644 --- a/program/src/big_vec.rs +++ b/program/src/big_vec.rs @@ -90,7 +90,10 @@ impl<'data> BigVec<'data> { len: usize, ) -> Result, ProgramError> { let vec_len = self.len(); - if skip + len > vec_len as usize { + let last_item_index = skip + .checked_add(len) + .ok_or(ProgramError::AccountDataTooSmall)?; + if last_item_index > vec_len as usize { return Err(ProgramError::AccountDataTooSmall); } From 05675c40224b4328abedc2fa502f542bb6d0aaad Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 19 Oct 2021 01:39:57 +0200 Subject: [PATCH 0185/1076] stake-pool: Force pools to only use the SPL token program (#2521) --- program/src/processor.rs | 9 ++++ program/tests/initialize.rs | 101 ++++++++++++++++++++++++++++++++++-- 2 files changed, 107 insertions(+), 3 deletions(-) diff --git a/program/src/processor.rs b/program/src/processor.rs index 9c065f10..82ff479a 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -565,6 +565,15 @@ impl Processor { return Err(StakePoolError::FeeTooHigh.into()); } + if *token_program_info.key != spl_token::id() { + msg!( + "Only the SPL token program is currently supported, expected {}, received {}", + spl_token::id(), + *token_program_info.key + ); + return Err(ProgramError::IncorrectProgramId); + } + if manager_fee_info.owner != token_program_info.key { return Err(ProgramError::IncorrectProgramId); } diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index 1c4044a6..e9aa1160 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -454,10 +454,107 @@ async fn fail_with_wrong_token_program_id() { .await .unwrap(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.pool_fee_account, + &stake_pool_accounts.pool_mint.pubkey(), + &stake_pool_accounts.manager.pubkey(), + ) + .await + .unwrap(); + let rent = banks_client.get_rent().await.unwrap(); + let rent_stake_pool = rent.minimum_balance(get_packed_len::()); + let validator_list_size = get_instance_packed_len(&state::ValidatorList::new( + stake_pool_accounts.max_validators, + )) + .unwrap(); + let rent_validator_list = rent.minimum_balance(validator_list_size); - let account_rent = rent.minimum_balance(spl_token::state::Account::LEN); let mut transaction = Transaction::new_with_payer( + &[ + system_instruction::create_account( + &payer.pubkey(), + &stake_pool_accounts.stake_pool.pubkey(), + rent_stake_pool, + get_packed_len::() as u64, + &id(), + ), + system_instruction::create_account( + &payer.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + rent_validator_list, + validator_list_size as u64, + &id(), + ), + instruction::initialize( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + &stake_pool_accounts.staker.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &stake_pool_accounts.pool_fee_account.pubkey(), + &wrong_token_program.pubkey(), + None, + stake_pool_accounts.epoch_fee, + stake_pool_accounts.withdrawal_fee, + stake_pool_accounts.deposit_fee, + stake_pool_accounts.referral_fee, + stake_pool_accounts.max_validators, + ), + ], + Some(&payer.pubkey()), + ); + transaction.sign( + &[ + &payer, + &stake_pool_accounts.stake_pool, + &stake_pool_accounts.validator_list, + &stake_pool_accounts.manager, + ], + recent_blockhash, + ); + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { + assert_eq!(error, InstructionError::IncorrectProgramId); + } + _ => panic!( + "Wrong error occurs while try to initialize stake pool with wrong token program ID" + ), + } +} + +#[tokio::test] +async fn fail_with_fee_owned_by_wrong_token_program_id() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + + let wrong_token_program = Keypair::new(); + + create_mint( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.pool_mint, + &stake_pool_accounts.withdraw_authority, + ) + .await + .unwrap(); + + let rent = banks_client.get_rent().await.unwrap(); + + let account_rent = rent.minimum_balance(spl_token::state::Account::LEN); + let transaction = Transaction::new_signed_with_payer( &[system_instruction::create_account( &payer.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), @@ -466,8 +563,6 @@ async fn fail_with_wrong_token_program_id() { &wrong_token_program.pubkey(), )], Some(&payer.pubkey()), - ); - transaction.sign( &[&payer, &stake_pool_accounts.pool_fee_account], recent_blockhash, ); From ee9eda7b4c321eeaf4579d1145f9729427169614 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 19 Oct 2021 01:50:35 +0200 Subject: [PATCH 0186/1076] stake-pool: Cleanup documentation in code (#2525) --- program/src/instruction.rs | 35 +++++++++++++++++++++++------------ program/src/processor.rs | 38 ++++++++++++++++++++++---------------- 2 files changed, 45 insertions(+), 28 deletions(-) diff --git a/program/src/instruction.rs b/program/src/instruction.rs index d4e64602..e114a4d6 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -80,7 +80,8 @@ pub enum StakePoolInstruction { /// (Staker only) Adds stake account delegated to validator to the pool's /// list of managed validators. /// - /// The stake account will have the rent-exempt amount plus 1 SOL. + /// The stake account will have the rent-exempt amount plus + /// `crate::MINIMUM_ACTIVE_STAKE` (currently 0.001 SOL). /// /// 0. `[w]` Stake pool /// 1. `[s]` Staker @@ -99,8 +100,9 @@ pub enum StakePoolInstruction { /// (Staker only) Removes validator from the pool /// - /// Only succeeds if the validator stake account has the minimum of 1 SOL - /// plus the rent-exempt amount. + /// Only succeeds if the validator stake account has the minimum of + /// `crate::MINIMUM_ACTIVE_STAKE` (currently 0.001 SOL) plus the rent-exempt + /// amount. /// /// 0. `[w]` Stake pool /// 1. `[s]` Staker @@ -109,7 +111,7 @@ pub enum StakePoolInstruction { /// 4. `[w]` Validator stake list storage account /// 5. `[w]` Stake account to remove from the pool /// 6. `[]` Transient stake account, to check that that we're not trying to activate - /// 7. `[w]` Destination stake account, to receive the minimum SOL from the validator stake account. Must be + /// 7. `[w]` Destination stake account, to receive the minimum SOL from the validator stake account /// 8. `[]` Sysvar clock /// 9. `[]` Stake program id, RemoveValidatorFromPool, @@ -154,8 +156,9 @@ pub enum StakePoolInstruction { /// will do the work of merging once it's ready. /// /// This instruction only succeeds if the transient stake account does not exist. - /// The minimum amount to move is rent-exemption plus 1 SOL in order to avoid - /// issues on credits observed when merging active stakes later. + /// The minimum amount to move is rent-exemption plus `crate::MINIMUM_ACTIVE_STAKE` + /// (currently 0.001 SOL) in order to avoid issues on credits observed when + /// merging active stakes later. /// /// 0. `[]` Stake pool /// 1. `[s]` Stake pool staker @@ -275,11 +278,19 @@ pub enum StakePoolInstruction { /// /// Succeeds if the stake account has enough SOL to cover the desired amount /// of pool tokens, and if the withdrawal keeps the total staked amount - /// above the minimum of rent-exempt amount + 1 SOL. + /// above the minimum of rent-exempt amount + 0.001 SOL. /// - /// A validator stake account can be withdrawn from freely, and the reserve - /// can only be drawn from if there is no active stake left, where all - /// validator accounts are left with 1 lamport. + /// When allowing withdrawals, the order of priority goes: + /// + /// * preferred withdraw validator stake account (if set) + /// * validator stake accounts + /// * transient stake accounts + /// * reserve stake account + /// + /// A user can freely withdraw from a validator stake account, and if they + /// are all at the minimum, then they can withdraw from transient stake + /// accounts, and if they are all at minimum, then they can withdraw from + /// the reserve. /// /// 0. `[w]` Stake pool /// 1. `[w]` Validator stake list storage account @@ -301,8 +312,8 @@ pub enum StakePoolInstruction { /// /// 0. `[w]` StakePool /// 1. `[s]` Manager - /// 2. '[]` New manager pubkey - /// 3. '[]` New manager fee account + /// 2. `[s]` New manager + /// 3. `[]` New manager fee account SetManager, /// (Manager only) Update fee diff --git a/program/src/processor.rs b/program/src/processor.rs index 82ff479a..aff89ee6 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -163,7 +163,7 @@ fn create_transient_stake_account<'a>( /// Program state handler. pub struct Processor {} impl Processor { - /// Issue a stake_deactivate instruction. + /// Issue a delegate_stake instruction. #[allow(clippy::too_many_arguments)] fn stake_delegate<'a>( stake_info: AccountInfo<'a>, @@ -1389,6 +1389,16 @@ impl Processor { stake_pool.check_reserve_stake(reserve_stake_info)?; check_stake_program(stake_program_info.key)?; + if validator_stake_accounts + .len() + .checked_rem(2) + .ok_or(StakePoolError::CalculationFailure)? + != 0 + { + msg!("Odd number of validator stake accounts passed in, should be pairs of validator stake and transient stake accounts"); + return Err(StakePoolError::UnexpectedValidatorListAccountSize.into()); + } + check_account_owner(validator_list_info, program_id)?; let mut validator_list_data = validator_list_info.data.borrow_mut(); let (validator_list_header, mut validator_slice) = @@ -1766,9 +1776,7 @@ impl Processor { let token_program_info = next_account_info(account_info_iter)?; let stake_program_info = next_account_info(account_info_iter)?; - if *stake_program_info.key != stake_program::id() { - return Err(ProgramError::IncorrectProgramId); - } + check_stake_program(stake_program_info.key)?; check_account_owner(stake_pool_info, program_id)?; let mut stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; @@ -2102,18 +2110,16 @@ impl Processor { deposit_lamports, )?; - if pool_tokens_user > 0 { - Self::token_mint_to( - stake_pool_info.key, - token_program_info.clone(), - pool_mint_info.clone(), - dest_user_pool_info.clone(), - withdraw_authority_info.clone(), - AUTHORITY_WITHDRAW, - stake_pool.stake_withdraw_bump_seed, - pool_tokens_user, - )?; - } + Self::token_mint_to( + stake_pool_info.key, + token_program_info.clone(), + pool_mint_info.clone(), + dest_user_pool_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + pool_tokens_user, + )?; if pool_tokens_manager_deposit_fee > 0 { Self::token_mint_to( From 2465fb84deba8be60570593d0666b23355fbd064 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 19 Oct 2021 12:26:50 +0200 Subject: [PATCH 0187/1076] stake-pool: Clarify stake deposit fee (#2520) --- program/src/processor.rs | 72 +++++++++++++++++------------------- program/tests/deposit.rs | 51 +++++++++++++++++-------- program/tests/helpers/mod.rs | 4 -- program/tests/withdraw.rs | 35 ++++++++++++------ 4 files changed, 91 insertions(+), 71 deletions(-) diff --git a/program/src/processor.rs b/program/src/processor.rs index aff89ee6..b7106300 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1784,8 +1784,6 @@ impl Processor { return Err(StakePoolError::InvalidState.into()); } - //Self::check_stake_activation(stake_info, clock, stake_history)?; - stake_pool.check_authority_withdraw( withdraw_authority_info.key, program_id, @@ -1836,16 +1834,6 @@ impl Processor { } } - let (meta, stake) = get_stake_state(stake_info)?; - - // If the stake account is mergeable (full-activated), `meta.rent_exempt_reserve` - // will not be merged into `stake.delegation.stake` - let unactivated_stake_rent = if stake.delegation.activation_epoch < clock.epoch { - meta.rent_exempt_reserve - } else { - 0 - }; - let mut validator_stake_info = validator_list .find_mut::( vote_account_address.as_ref(), @@ -1899,7 +1887,7 @@ impl Processor { let post_all_validator_lamports = validator_stake_account_info.lamports(); msg!("Stake post merge {}", post_validator_stake.delegation.stake); - let all_deposit_lamports = post_all_validator_lamports + let total_deposit_lamports = post_all_validator_lamports .checked_sub(pre_all_validator_lamports) .ok_or(StakePoolError::CalculationFailure)?; let stake_deposit_lamports = post_validator_stake @@ -1907,30 +1895,39 @@ impl Processor { .stake .checked_sub(validator_stake.delegation.stake) .ok_or(StakePoolError::CalculationFailure)?; - let additional_lamports = all_deposit_lamports + let sol_deposit_lamports = total_deposit_lamports .checked_sub(stake_deposit_lamports) .ok_or(StakePoolError::CalculationFailure)?; - let credited_additional_lamports = additional_lamports.min(unactivated_stake_rent); - let credited_deposit_lamports = - stake_deposit_lamports.saturating_add(credited_additional_lamports); let new_pool_tokens = stake_pool - .calc_pool_tokens_for_deposit(credited_deposit_lamports) + .calc_pool_tokens_for_deposit(total_deposit_lamports) + .ok_or(StakePoolError::CalculationFailure)?; + let new_pool_tokens_from_stake = stake_pool + .calc_pool_tokens_for_deposit(stake_deposit_lamports) + .ok_or(StakePoolError::CalculationFailure)?; + let new_pool_tokens_from_sol = new_pool_tokens + .checked_sub(new_pool_tokens_from_stake) .ok_or(StakePoolError::CalculationFailure)?; - let pool_tokens_stake_deposit_fee = stake_pool - .calc_pool_tokens_stake_deposit_fee(new_pool_tokens) + let stake_deposit_fee = stake_pool + .calc_pool_tokens_stake_deposit_fee(new_pool_tokens_from_stake) + .ok_or(StakePoolError::CalculationFailure)?; + let sol_deposit_fee = stake_pool + .calc_pool_tokens_sol_deposit_fee(new_pool_tokens_from_sol) .ok_or(StakePoolError::CalculationFailure)?; + let total_fee = stake_deposit_fee + .checked_add(sol_deposit_fee) + .ok_or(StakePoolError::CalculationFailure)?; let pool_tokens_user = new_pool_tokens - .checked_sub(pool_tokens_stake_deposit_fee) + .checked_sub(total_fee) .ok_or(StakePoolError::CalculationFailure)?; let pool_tokens_referral_fee = stake_pool - .calc_pool_tokens_stake_referral_fee(pool_tokens_stake_deposit_fee) + .calc_pool_tokens_stake_referral_fee(total_fee) .ok_or(StakePoolError::CalculationFailure)?; - let pool_tokens_manager_deposit_fee = pool_tokens_stake_deposit_fee + let pool_tokens_manager_deposit_fee = total_fee .checked_sub(pool_tokens_referral_fee) .ok_or(StakePoolError::CalculationFailure)?; @@ -1946,18 +1943,16 @@ impl Processor { return Err(StakePoolError::DepositTooSmall.into()); } - if pool_tokens_user > 0 { - Self::token_mint_to( - stake_pool_info.key, - token_program_info.clone(), - pool_mint_info.clone(), - dest_user_pool_info.clone(), - withdraw_authority_info.clone(), - AUTHORITY_WITHDRAW, - stake_pool.stake_withdraw_bump_seed, - pool_tokens_user, - )?; - } + Self::token_mint_to( + stake_pool_info.key, + token_program_info.clone(), + pool_mint_info.clone(), + dest_user_pool_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + pool_tokens_user, + )?; if pool_tokens_manager_deposit_fee > 0 { Self::token_mint_to( stake_pool_info.key, @@ -1984,8 +1979,7 @@ impl Processor { } // withdraw additional lamports to the reserve - - if additional_lamports > 0 { + if sol_deposit_lamports > 0 { Self::stake_withdraw( stake_pool_info.key, validator_stake_account_info.clone(), @@ -1996,7 +1990,7 @@ impl Processor { clock_info.clone(), stake_history_info.clone(), stake_program_info.clone(), - additional_lamports, + sol_deposit_lamports, )?; } @@ -2008,7 +2002,7 @@ impl Processor { // transferred directly to the reserve stake account. stake_pool.total_lamports = stake_pool .total_lamports - .checked_add(all_deposit_lamports) + .checked_add(total_deposit_lamports) .ok_or(StakePoolError::CalculationFailure)?; stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index d58f1511..8ba464a1 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -214,8 +214,13 @@ async fn success() { // Check minted tokens let user_token_balance = get_token_balance(&mut context.banks_client, &pool_token_account).await; - let tokens_issued_user = - tokens_issued - stake_pool_accounts.calculate_deposit_fee(tokens_issued); + let tokens_issued_user = tokens_issued + - post_stake_pool + .calc_pool_tokens_sol_deposit_fee(stake_rent) + .unwrap() + - post_stake_pool + .calc_pool_tokens_stake_deposit_fee(stake_lamports - stake_rent) + .unwrap(); assert_eq!(user_token_balance, tokens_issued_user); // Check balances in validator stake account list storage @@ -358,7 +363,7 @@ async fn success_with_extra_stake_lamports() { .expect("get_account") .is_none()); - let tokens_issued = stake_lamports; + let tokens_issued = stake_lamports + extra_lamports; // For now tokens are 1:1 to stake // Stake pool should add its balance to the pool balance @@ -386,22 +391,22 @@ async fn success_with_extra_stake_lamports() { let user_token_balance = get_token_balance(&mut context.banks_client, &pool_token_account).await; - let tokens_issued_user = - tokens_issued - stake_pool_accounts.calculate_deposit_fee(tokens_issued); + let fee_tokens = post_stake_pool + .calc_pool_tokens_sol_deposit_fee(extra_lamports + stake_rent) + .unwrap() + + post_stake_pool + .calc_pool_tokens_stake_deposit_fee(stake_lamports - stake_rent) + .unwrap(); + let tokens_issued_user = tokens_issued - fee_tokens; assert_eq!(user_token_balance, tokens_issued_user); let referrer_balance_post = get_token_balance(&mut context.banks_client, &referrer_token_account.pubkey()).await; - let tokens_issued_fees = stake_pool_accounts.calculate_deposit_fee(tokens_issued); - let tokens_issued_referral_fee = stake_pool_accounts - .calculate_referral_fee(stake_pool_accounts.calculate_deposit_fee(tokens_issued)); - let tokens_issued_manager_fee = tokens_issued_fees - tokens_issued_referral_fee; + let referral_fee = stake_pool_accounts.calculate_referral_fee(fee_tokens); + let manager_fee = fee_tokens - referral_fee; - assert_eq!( - referrer_balance_post - referrer_balance_pre, - tokens_issued_referral_fee - ); + assert_eq!(referrer_balance_post - referrer_balance_pre, referral_fee); let manager_pool_balance_post = get_token_balance( &mut context.banks_client, @@ -410,7 +415,7 @@ async fn success_with_extra_stake_lamports() { .await; assert_eq!( manager_pool_balance_post - manager_pool_balance_pre, - tokens_issued_manager_fee + manager_fee ); // Check balances in validator stake account list storage @@ -1114,8 +1119,22 @@ async fn success_with_referral_fee() { let referrer_balance_post = get_token_balance(&mut context.banks_client, &referrer_token_account.pubkey()).await; - let referral_fee = stake_pool_accounts - .calculate_referral_fee(stake_pool_accounts.calculate_deposit_fee(stake_lamports)); + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = + try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); + let rent = context.banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let fee_tokens = stake_pool + .calc_pool_tokens_sol_deposit_fee(stake_rent) + .unwrap() + + stake_pool + .calc_pool_tokens_stake_deposit_fee(stake_lamports - stake_rent) + .unwrap(); + let referral_fee = stake_pool_accounts.calculate_referral_fee(fee_tokens); assert!(referral_fee > 0); assert_eq!(referrer_balance_pre + referral_fee, referrer_balance_post); } diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index ad0ede77..bc9a8501 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -685,10 +685,6 @@ impl StakePoolAccounts { pool_tokens * self.withdrawal_fee.numerator / self.withdrawal_fee.denominator } - pub fn calculate_deposit_fee(&self, pool_tokens: u64) -> u64 { - pool_tokens * self.deposit_fee.numerator / self.deposit_fee.denominator - } - pub fn calculate_referral_fee(&self, deposit_fee_collected: u64) -> u64 { deposit_fee_collected * self.referral_fee as u64 / 100 } diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index b8ebbeb3..3b91023a 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -994,15 +994,30 @@ async fn success_with_reserve() { assert!(error.is_none()); // first and only deposit, lamports:pool 1:1 - let tokens_deposit_fee = - stake_pool_accounts.calculate_deposit_fee(deposit_info.stake_lamports + stake_rent); - let tokens_withdrawal_fee = - stake_pool_accounts.calculate_withdrawal_fee(deposit_info.pool_tokens); + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = + try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); + // the entire deposit is actually stake since it isn't activated, so only + // the stake deposit fee is charged + let deposit_fee = stake_pool + .calc_pool_tokens_stake_deposit_fee(stake_rent + deposit_info.stake_lamports) + .unwrap(); assert_eq!( - deposit_info.stake_lamports + stake_rent - tokens_deposit_fee, + deposit_info.stake_lamports + stake_rent - deposit_fee, deposit_info.pool_tokens, + "stake {} rent {} deposit fee {} pool tokens {}", + deposit_info.stake_lamports, + stake_rent, + deposit_fee, + deposit_info.pool_tokens ); + let withdrawal_fee = stake_pool_accounts.calculate_withdrawal_fee(deposit_info.pool_tokens); + // Check tokens used let user_token_balance = get_token_balance( &mut context.banks_client, @@ -1020,12 +1035,8 @@ async fn success_with_reserve() { let stake_state = deserialize::(&reserve_stake_account.data).unwrap(); let meta = stake_state.meta().unwrap(); - // TODO: these numbers dont add up even with +tokens_deposit_fee assert_eq!( - initial_reserve_lamports - + meta.rent_exempt_reserve - + tokens_withdrawal_fee - + tokens_deposit_fee, + initial_reserve_lamports + meta.rent_exempt_reserve + withdrawal_fee + deposit_fee, reserve_stake_account.lamports ); @@ -1035,8 +1046,8 @@ async fn success_with_reserve() { assert_eq!( user_stake_recipient_account.lamports, initial_stake_lamports + deposit_info.stake_lamports + stake_rent - - tokens_withdrawal_fee - - tokens_deposit_fee + - withdrawal_fee + - deposit_fee ); } From 7bbbc481553c333893f5147f6d846ea805dc3c45 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 19 Oct 2021 16:48:56 +0200 Subject: [PATCH 0188/1076] stake-pool: Remove copied stake program code (mostly) (#2526) * stake-pool: Remove (mostly) the copied stake program * Remove references to stake_program in CLI --- clients/cli/src/client.rs | 9 +- clients/cli/src/main.rs | 14 +- program/src/instruction.rs | 47 +- program/src/lib.rs | 4 +- program/src/processor.rs | 116 +-- program/src/stake_program.rs | 673 +----------------- program/tests/decrease.rs | 14 +- program/tests/deposit.rs | 36 +- program/tests/helpers/mod.rs | 47 +- program/tests/huge_pool.rs | 24 +- program/tests/increase.rs | 12 +- program/tests/initialize.rs | 28 +- .../tests/update_validator_list_balance.rs | 16 +- program/tests/vsa_add.rs | 20 +- program/tests/vsa_remove.rs | 23 +- program/tests/withdraw.rs | 17 +- program/tests/withdraw_sol.rs | 6 +- 17 files changed, 227 insertions(+), 879 deletions(-) diff --git a/clients/cli/src/client.rs b/clients/cli/src/client.rs index ef4d1d8e..40d6cb89 100644 --- a/clients/cli/src/client.rs +++ b/clients/cli/src/client.rs @@ -7,11 +7,8 @@ use { rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig}, rpc_filter::{Memcmp, MemcmpEncodedBytes, RpcFilterType}, }, - solana_program::{borsh::try_from_slice_unchecked, program_pack::Pack, pubkey::Pubkey}, - spl_stake_pool::{ - stake_program, - state::{StakePool, ValidatorList}, - }, + solana_program::{borsh::try_from_slice_unchecked, program_pack::Pack, pubkey::Pubkey, stake}, + spl_stake_pool::state::{StakePool, ValidatorList}, }; type Error = Box; @@ -70,7 +67,7 @@ pub fn get_token_mint( pub(crate) fn get_stake_state( rpc_client: &RpcClient, stake_address: &Pubkey, -) -> Result { +) -> Result { let account_data = rpc_client.get_account_data(stake_address)?; let stake_state = deserialize(account_data.as_slice()) .map_err(|err| format!("Invalid stake account {}: {}", stake_address, err))?; diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index d914a743..851ee139 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -20,6 +20,7 @@ use { instruction::Instruction, program_pack::Pack, pubkey::Pubkey, + stake, }, solana_remote_wallet::remote_wallet::RemoteWalletManager, solana_sdk::{ @@ -36,7 +37,6 @@ use { self, find_stake_program_address, find_transient_stake_program_address, find_withdraw_authority_program_address, instruction::{FundingType, PreferredValidatorType}, - stake_program::{self, StakeState}, state::{Fee, FeeType, StakePool, ValidatorList}, MINIMUM_ACTIVE_STAKE, }, @@ -168,7 +168,7 @@ fn new_stake_account( &stake_receiver_pubkey, lamports, STAKE_STATE_LEN as u64, - &stake_program::id(), + &stake::program::id(), ), ); @@ -241,15 +241,15 @@ fn command_create_pool( &reserve_keypair.pubkey(), reserve_stake_balance, STAKE_STATE_LEN as u64, - &stake_program::id(), + &stake::program::id(), ), - stake_program::initialize( + stake::instruction::initialize( &reserve_keypair.pubkey(), - &stake_program::Authorized { + &stake::state::Authorized { staker: withdraw_authority, withdrawer: withdraw_authority, }, - &stake_program::Lockup::default(), + &stake::state::Lockup::default(), ), // Account for the stake pool mint system_instruction::create_account( @@ -610,7 +610,7 @@ fn command_deposit_stake( println!("Depositing stake account {:?}", stake_state); } let vote_account = match stake_state { - StakeState::Stake(_, stake) => Ok(stake.delegation.voter_pubkey), + stake::state::StakeState::Stake(_, stake) => Ok(stake.delegation.voter_pubkey), _ => Err("Wrong stake account state, must be delegated to validator"), }?; diff --git a/program/src/instruction.rs b/program/src/instruction.rs index e114a4d6..7aa47c16 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -5,7 +5,6 @@ use { crate::{ find_deposit_authority_program_address, find_stake_program_address, find_transient_stake_program_address, find_withdraw_authority_program_address, - stake_program, state::{Fee, FeeType, StakePool, ValidatorList}, MAX_VALIDATORS_TO_UPDATE, }, @@ -13,7 +12,7 @@ use { solana_program::{ instruction::{AccountMeta, Instruction}, pubkey::Pubkey, - system_program, sysvar, + stake, system_program, sysvar, }, }; @@ -443,9 +442,9 @@ pub fn add_validator_to_pool( AccountMeta::new_readonly(sysvar::rent::id(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), - AccountMeta::new_readonly(stake_program::config_id(), false), + AccountMeta::new_readonly(stake::config::id(), false), AccountMeta::new_readonly(system_program::id(), false), - AccountMeta::new_readonly(stake_program::id(), false), + AccountMeta::new_readonly(stake::program::id(), false), ]; Instruction { program_id: *program_id, @@ -478,7 +477,7 @@ pub fn remove_validator_from_pool( AccountMeta::new_readonly(*transient_stake_account, false), AccountMeta::new(*destination_stake_account, false), AccountMeta::new_readonly(sysvar::clock::id(), false), - AccountMeta::new_readonly(stake_program::id(), false), + AccountMeta::new_readonly(stake::program::id(), false), ]; Instruction { program_id: *program_id, @@ -512,7 +511,7 @@ pub fn decrease_validator_stake( AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::rent::id(), false), AccountMeta::new_readonly(system_program::id(), false), - AccountMeta::new_readonly(stake_program::id(), false), + AccountMeta::new_readonly(stake::program::id(), false), ]; Instruction { program_id: *program_id, @@ -551,9 +550,9 @@ pub fn increase_validator_stake( AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::rent::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), - AccountMeta::new_readonly(stake_program::config_id(), false), + AccountMeta::new_readonly(stake::config::id(), false), AccountMeta::new_readonly(system_program::id(), false), - AccountMeta::new_readonly(stake_program::id(), false), + AccountMeta::new_readonly(stake::program::id(), false), ]; Instruction { program_id: *program_id, @@ -736,7 +735,7 @@ pub fn update_validator_list_balance( AccountMeta::new(*reserve_stake, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), - AccountMeta::new_readonly(stake_program::id(), false), + AccountMeta::new_readonly(stake::program::id(), false), ]; accounts.append( &mut validator_vote_accounts @@ -911,20 +910,22 @@ pub fn deposit_stake( AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), AccountMeta::new_readonly(*token_program_id, false), - AccountMeta::new_readonly(stake_program::id(), false), + AccountMeta::new_readonly(stake::program::id(), false), ]; vec![ - stake_program::authorize( + stake::instruction::authorize( deposit_stake_address, deposit_stake_withdraw_authority, &stake_pool_deposit_authority, - stake_program::StakeAuthorize::Staker, + stake::state::StakeAuthorize::Staker, + None, ), - stake_program::authorize( + stake::instruction::authorize( deposit_stake_address, deposit_stake_withdraw_authority, &stake_pool_deposit_authority, - stake_program::StakeAuthorize::Withdrawer, + stake::state::StakeAuthorize::Withdrawer, + None, ), Instruction { program_id: *program_id, @@ -968,20 +969,22 @@ pub fn deposit_stake_with_authority( AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), AccountMeta::new_readonly(*token_program_id, false), - AccountMeta::new_readonly(stake_program::id(), false), + AccountMeta::new_readonly(stake::program::id(), false), ]; vec![ - stake_program::authorize( + stake::instruction::authorize( deposit_stake_address, deposit_stake_withdraw_authority, stake_pool_deposit_authority, - stake_program::StakeAuthorize::Staker, + stake::state::StakeAuthorize::Staker, + None, ), - stake_program::authorize( + stake::instruction::authorize( deposit_stake_address, deposit_stake_withdraw_authority, stake_pool_deposit_authority, - stake_program::StakeAuthorize::Withdrawer, + stake::state::StakeAuthorize::Withdrawer, + None, ), Instruction { program_id: *program_id, @@ -1094,7 +1097,7 @@ pub fn withdraw_stake( AccountMeta::new(*pool_mint, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(*token_program_id, false), - AccountMeta::new_readonly(stake_program::id(), false), + AccountMeta::new_readonly(stake::program::id(), false), ]; Instruction { program_id: *program_id, @@ -1130,7 +1133,7 @@ pub fn withdraw_sol( AccountMeta::new(*pool_mint, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), - AccountMeta::new_readonly(stake_program::id(), false), + AccountMeta::new_readonly(stake::program::id(), false), AccountMeta::new_readonly(*token_program_id, false), ]; Instruction { @@ -1170,7 +1173,7 @@ pub fn withdraw_sol_with_authority( AccountMeta::new(*pool_mint, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), - AccountMeta::new_readonly(stake_program::id(), false), + AccountMeta::new_readonly(stake::program::id(), false), AccountMeta::new_readonly(*token_program_id, false), AccountMeta::new_readonly(*sol_withdraw_authority, true), ]; diff --git a/program/src/lib.rs b/program/src/lib.rs index 08952ecb..d8a53453 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -15,8 +15,8 @@ pub mod entrypoint; // Export current sdk types for downstream users building with a different sdk version pub use solana_program; use { - crate::{stake_program::Meta, state::Fee}, - solana_program::{native_token::LAMPORTS_PER_SOL, pubkey::Pubkey}, + crate::state::Fee, + solana_program::{native_token::LAMPORTS_PER_SOL, pubkey::Pubkey, stake::state::Meta}, }; /// Seed for deposit authority seed diff --git a/program/src/processor.rs b/program/src/processor.rs index b7106300..4f6b6079 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -28,7 +28,7 @@ use { program_pack::Pack, pubkey::Pubkey, rent::Rent, - system_instruction, system_program, + stake, system_instruction, system_program, sysvar::Sysvar, }, spl_token::state::Mint, @@ -37,11 +37,11 @@ use { /// Deserialize the stake state from AccountInfo fn get_stake_state( stake_account_info: &AccountInfo, -) -> Result<(stake_program::Meta, stake_program::Stake), ProgramError> { +) -> Result<(stake::state::Meta, stake::state::Stake), ProgramError> { let stake_state = - try_from_slice_unchecked::(&stake_account_info.data.borrow())?; + try_from_slice_unchecked::(&stake_account_info.data.borrow())?; match stake_state { - stake_program::StakeState::Stake(meta, stake) => Ok((meta, stake)), + stake::state::StakeState::Stake(meta, stake) => Ok((meta, stake)), _ => Err(StakePoolError::WrongStakeState.into()), } } @@ -107,10 +107,10 @@ fn check_system_program(program_id: &Pubkey) -> Result<(), ProgramError> { /// Check stake program address fn check_stake_program(program_id: &Pubkey) -> Result<(), ProgramError> { - if *program_id != stake_program::id() { + if *program_id != stake::program::id() { msg!( "Expected stake program {}, received {}", - stake_program::id(), + stake::program::id(), program_id ); Err(ProgramError::IncorrectProgramId) @@ -145,7 +145,7 @@ fn create_transient_stake_account<'a>( invoke_signed( &system_instruction::allocate( transient_stake_account_info.key, - std::mem::size_of::() as u64, + std::mem::size_of::() as u64, ), &[ transient_stake_account_info.clone(), @@ -154,7 +154,7 @@ fn create_transient_stake_account<'a>( &[transient_stake_account_signer_seeds], )?; invoke_signed( - &system_instruction::assign(transient_stake_account_info.key, &stake_program::id()), + &system_instruction::assign(transient_stake_account_info.key, &stake::program::id()), &[transient_stake_account_info, system_program_info], &[transient_stake_account_signer_seeds], ) @@ -180,7 +180,7 @@ impl Processor { [&stake_pool.to_bytes()[..32], authority_type, &[bump_seed]]; let signers = &[&authority_signature_seeds[..]]; - let ix = stake_program::delegate_stake( + let ix = stake::instruction::delegate_stake( stake_info.key, authority_info.key, vote_account_info.key, @@ -213,7 +213,7 @@ impl Processor { [&stake_pool.to_bytes()[..32], authority_type, &[bump_seed]]; let signers = &[&authority_signature_seeds[..]]; - let ix = stake_program::deactivate_stake(stake_info.key, authority_info.key); + let ix = stake::instruction::deactivate_stake(stake_info.key, authority_info.key); invoke_signed(&ix, &[stake_info, clock_info, authority_info], signers) } @@ -233,10 +233,10 @@ impl Processor { let signers = &[&authority_signature_seeds[..]]; let split_instruction = - stake_program::split_only(stake_account.key, authority.key, amount, split_stake.key); + stake::instruction::split(stake_account.key, authority.key, amount, split_stake.key); invoke_signed( - &split_instruction, + split_instruction.last().unwrap(), &[stake_account, split_stake, authority], signers, ) @@ -260,10 +260,10 @@ impl Processor { let signers = &[&authority_signature_seeds[..]]; let merge_instruction = - stake_program::merge(destination_account.key, source_account.key, authority.key); + stake::instruction::merge(destination_account.key, source_account.key, authority.key); invoke_signed( - &merge_instruction, + &merge_instruction[0], &[ destination_account, source_account, @@ -276,7 +276,7 @@ impl Processor { ) } - /// Issue stake_program::authorize instructions to update both authorities + /// Issue stake::instruction::authorize instructions to update both authorities fn stake_authorize<'a>( stake_account: AccountInfo<'a>, stake_authority: AccountInfo<'a>, @@ -284,11 +284,12 @@ impl Processor { clock: AccountInfo<'a>, stake_program_info: AccountInfo<'a>, ) -> Result<(), ProgramError> { - let authorize_instruction = stake_program::authorize( + let authorize_instruction = stake::instruction::authorize( stake_account.key, stake_authority.key, new_stake_authority, - stake_program::StakeAuthorize::Staker, + stake::state::StakeAuthorize::Staker, + None, ); invoke( @@ -301,11 +302,12 @@ impl Processor { ], )?; - let authorize_instruction = stake_program::authorize( + let authorize_instruction = stake::instruction::authorize( stake_account.key, stake_authority.key, new_stake_authority, - stake_program::StakeAuthorize::Withdrawer, + stake::state::StakeAuthorize::Withdrawer, + None, ); invoke( @@ -314,7 +316,7 @@ impl Processor { ) } - /// Issue stake_program::authorize instructions to update both authorities + /// Issue stake::instruction::authorize instructions to update both authorities #[allow(clippy::too_many_arguments)] fn stake_authorize_signed<'a>( stake_pool: &Pubkey, @@ -330,11 +332,12 @@ impl Processor { let authority_signature_seeds = [&me_bytes[..32], authority_type, &[bump_seed]]; let signers = &[&authority_signature_seeds[..]]; - let authorize_instruction = stake_program::authorize( + let authorize_instruction = stake::instruction::authorize( stake_account.key, stake_authority.key, new_stake_authority, - stake_program::StakeAuthorize::Staker, + stake::state::StakeAuthorize::Staker, + None, ); invoke_signed( @@ -348,11 +351,12 @@ impl Processor { signers, )?; - let authorize_instruction = stake_program::authorize( + let authorize_instruction = stake::instruction::authorize( stake_account.key, stake_authority.key, new_stake_authority, - stake_program::StakeAuthorize::Withdrawer, + stake::state::StakeAuthorize::Withdrawer, + None, ); invoke_signed( &authorize_instruction, @@ -361,7 +365,7 @@ impl Processor { ) } - /// Issue stake_program::withdraw instruction to move additional lamports + /// Issue stake::instruction::withdraw instruction to move additional lamports #[allow(clippy::too_many_arguments)] fn stake_withdraw<'a>( stake_pool: &Pubkey, @@ -380,7 +384,7 @@ impl Processor { let signers = &[&authority_signature_seeds[..]]; let custodian_pubkey = None; - let withdraw_instruction = stake_program::withdraw( + let withdraw_instruction = stake::instruction::withdraw( source_account.key, authority.key, destination_account.key, @@ -609,15 +613,15 @@ impl Processor { return Err(StakePoolError::InvalidMintFreezeAuthority.into()); } - if *reserve_stake_info.owner != stake_program::id() { + if *reserve_stake_info.owner != stake::program::id() { msg!("Reserve stake account not owned by stake program"); return Err(ProgramError::IncorrectProgramId); } - let stake_state = try_from_slice_unchecked::( + let stake_state = try_from_slice_unchecked::( &reserve_stake_info.data.borrow(), )?; - let total_lamports = if let stake_program::StakeState::Initialized(meta) = stake_state { - if meta.lockup != stake_program::Lockup::default() { + let total_lamports = if let stake::state::StakeState::Initialized(meta) = stake_state { + if meta.lockup != stake::state::Lockup::default() { msg!("Reserve stake account has some lockup"); return Err(StakePoolError::WrongStakeState.into()); } @@ -766,7 +770,7 @@ impl Processor { // Fund the stake account with the minimum + rent-exempt balance let required_lamports = MINIMUM_ACTIVE_STAKE - + rent.minimum_balance(std::mem::size_of::()); + + rent.minimum_balance(std::mem::size_of::()); // Create new stake account invoke_signed( @@ -774,21 +778,21 @@ impl Processor { funder_info.key, stake_info.key, required_lamports, - std::mem::size_of::() as u64, - &stake_program::id(), + std::mem::size_of::() as u64, + &stake::program::id(), ), &[funder_info.clone(), stake_info.clone()], &[stake_account_signer_seeds], )?; invoke( - &stake_program::initialize( + &stake::instruction::initialize( stake_info.key, - &stake_program::Authorized { + &stake::state::Authorized { staker: *withdraw_authority_info.key, withdrawer: *withdraw_authority_info.key, }, - &stake_program::Lockup::default(), + &stake::state::Lockup::default(), ), &[ stake_info.clone(), @@ -1072,7 +1076,7 @@ impl Processor { &[transient_stake_bump_seed], ]; - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); if lamports <= stake_rent { msg!( "Need more than {} lamports for transient stake to be rent-exempt, {} provided", @@ -1228,7 +1232,7 @@ impl Processor { return Err(StakePoolError::ValidatorNotFound.into()); } - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); if lamports < MINIMUM_ACTIVE_STAKE { msg!( "Need more than {} lamports for transient stake to be rent-exempt and mergeable, {} provided", @@ -1443,11 +1447,11 @@ impl Processor { let mut active_stake_lamports = 0; let mut transient_stake_lamports = 0; - let validator_stake_state = try_from_slice_unchecked::( + let validator_stake_state = try_from_slice_unchecked::( &validator_stake_info.data.borrow(), ) .ok(); - let transient_stake_state = try_from_slice_unchecked::( + let transient_stake_state = try_from_slice_unchecked::( &transient_stake_info.data.borrow(), ) .ok(); @@ -1459,7 +1463,7 @@ impl Processor { // * inactive -> merge into reserve stake // * not a stake -> ignore match transient_stake_state { - Some(stake_program::StakeState::Initialized(meta)) => { + Some(stake::state::StakeState::Initialized(meta)) => { // if transient account was hijacked, ignore it if meta.authorized.staker == *withdraw_authority_info.key && meta.authorized.withdrawer == *withdraw_authority_info.key @@ -1487,7 +1491,7 @@ impl Processor { } } } - Some(stake_program::StakeState::Stake(meta, stake)) => { + Some(stake::state::StakeState::Stake(meta, stake)) => { // if transient account was hijacked, ignore it if meta.authorized.staker == *withdraw_authority_info.key && meta.authorized.withdrawer == *withdraw_authority_info.key @@ -1516,7 +1520,7 @@ impl Processor { validator_stake_record.status = StakeStatus::ReadyForRemoval; } } else if stake.delegation.activation_epoch < clock.epoch { - if let Some(stake_program::StakeState::Stake(_, validator_stake)) = + if let Some(stake::state::StakeState::Stake(_, validator_stake)) = validator_stake_state { if stake_program::active_stakes_can_merge(&stake, &validator_stake) @@ -1568,19 +1572,19 @@ impl Processor { } } None - | Some(stake_program::StakeState::Uninitialized) - | Some(stake_program::StakeState::RewardsPool) => {} // do nothing + | Some(stake::state::StakeState::Uninitialized) + | Some(stake::state::StakeState::RewardsPool) => {} // do nothing } // Status for validator stake // * active -> do everything // * any other state / not a stake -> error state, but account for transient stake - let validator_stake_state = try_from_slice_unchecked::( + let validator_stake_state = try_from_slice_unchecked::( &validator_stake_info.data.borrow(), ) .ok(); match validator_stake_state { - Some(stake_program::StakeState::Stake(_, stake)) => { + Some(stake::state::StakeState::Stake(_, stake)) => { if validator_stake_record.status == StakeStatus::Active { active_stake_lamports = stake .delegation @@ -1591,9 +1595,9 @@ impl Processor { msg!("Validator stake account no longer part of the pool, ignoring"); } } - Some(stake_program::StakeState::Initialized(_)) - | Some(stake_program::StakeState::Uninitialized) - | Some(stake_program::StakeState::RewardsPool) + Some(stake::state::StakeState::Initialized(_)) + | Some(stake::state::StakeState::Uninitialized) + | Some(stake::state::StakeState::RewardsPool) | None => { msg!("Validator stake account no longer part of the pool, ignoring"); } @@ -1652,10 +1656,10 @@ impl Processor { let previous_lamports = stake_pool.total_lamports; let previous_pool_token_supply = stake_pool.pool_token_supply; - let reserve_stake = try_from_slice_unchecked::( + let reserve_stake = try_from_slice_unchecked::( &reserve_stake_info.data.borrow(), )?; - let mut total_lamports = if let stake_program::StakeState::Initialized(meta) = reserve_stake + let mut total_lamports = if let stake::state::StakeState::Initialized(meta) = reserve_stake { reserve_stake_info .lamports() @@ -2255,13 +2259,13 @@ impl Processor { } // check that reserve has enough (should never fail, but who knows?) - let stake_state = try_from_slice_unchecked::( + let stake_state = try_from_slice_unchecked::( &stake_split_from.data.borrow(), )?; let meta = stake_state.meta().ok_or(StakePoolError::WrongStakeState)?; stake_split_from .lamports() - .checked_sub(minimum_reserve_lamports(meta)) + .checked_sub(minimum_reserve_lamports(&meta)) .ok_or(StakePoolError::StakeLamportsNotEqualToMinimum)?; None } else { @@ -2472,10 +2476,10 @@ impl Processor { let new_reserve_lamports = reserve_stake_info .lamports() .saturating_sub(withdraw_lamports); - let stake_state = try_from_slice_unchecked::( + let stake_state = try_from_slice_unchecked::( &reserve_stake_info.data.borrow(), )?; - if let stake_program::StakeState::Initialized(meta) = stake_state { + if let stake::state::StakeState::Initialized(meta) = stake_state { let minimum_reserve_lamports = minimum_reserve_lamports(&meta); if new_reserve_lamports < minimum_reserve_lamports { msg!("Attempting to withdraw {} lamports, maximum possible SOL withdrawal is {} lamports", diff --git a/program/src/stake_program.rs b/program/src/stake_program.rs index ffe21d29..093f2cdf 100644 --- a/program/src/stake_program.rs +++ b/program/src/stake_program.rs @@ -1,265 +1,19 @@ //! FIXME copied from the solana stake program use { - borsh::{ - maybestd::io::{Error as IoError, ErrorKind as IoErrorKind, Result as IoResult}, - BorshDeserialize, BorshSchema, BorshSerialize, - }, + borsh::{BorshDeserialize, BorshSchema, BorshSerialize}, serde_derive::{Deserialize, Serialize}, solana_program::{ clock::{Epoch, UnixTimestamp}, - instruction::{AccountMeta, Instruction}, msg, program_error::ProgramError, pubkey::Pubkey, - stake_history::StakeHistory, - system_instruction, sysvar, + stake, }, - std::str::FromStr, }; -solana_program::declare_id!("Stake11111111111111111111111111111111111111"); - -const STAKE_CONFIG: &str = "StakeConfig11111111111111111111111111111111"; -/// Id for stake config account -pub fn config_id() -> Pubkey { - Pubkey::from_str(STAKE_CONFIG).unwrap() -} - -/// FIXME copied from solana stake program -#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] -pub enum StakeInstruction { - /// Initialize a stake with lockup and authorization information - /// - /// # Account references - /// 0. `[WRITE]` Uninitialized stake account - /// 1. `[]` Rent sysvar - /// - /// Authorized carries pubkeys that must sign staker transactions - /// and withdrawer transactions. - /// Lockup carries information about withdrawal restrictions - Initialize(Authorized, Lockup), - - /// Authorize a key to manage stake or withdrawal - /// - /// # Account references - /// 0. `[WRITE]` Stake account to be updated - /// 1. `[]` (reserved for future use) Clock sysvar - /// 2. `[SIGNER]` The stake or withdraw authority - Authorize(Pubkey, StakeAuthorize), - - /// Delegate a stake to a particular vote account - /// - /// # Account references - /// 0. `[WRITE]` Initialized stake account to be delegated - /// 1. `[]` Vote account to which this stake will be delegated - /// 2. `[]` Clock sysvar - /// 3. `[]` Stake history sysvar that carries stake warmup/cooldown history - /// 4. `[]` Address of config account that carries stake config - /// 5. `[SIGNER]` Stake authority - /// - /// The entire balance of the staking account is staked. DelegateStake - /// can be called multiple times, but re-delegation is delayed - /// by one epoch - DelegateStake, - - /// Split u64 tokens and stake off a stake account into another stake account. - /// - /// # Account references - /// 0. `[WRITE]` Stake account to be split; must be in the Initialized or Stake state - /// 1. `[WRITE]` Uninitialized stake account that will take the split-off amount - /// 2. `[SIGNER]` Stake authority - Split(u64), - - /// Withdraw unstaked lamports from the stake account - /// - /// # Account references - /// 0. `[WRITE]` Stake account from which to withdraw - /// 1. `[WRITE]` Recipient account - /// 2. `[]` Clock sysvar - /// 3. `[]` Stake history sysvar that carries stake warmup/cooldown history - /// 4. `[SIGNER]` Withdraw authority - /// 5. Optional: `[SIGNER]` Lockup authority, if before lockup expiration - /// - /// The u64 is the portion of the stake account balance to be withdrawn, - /// must be `<= ValidatorStakeAccount.lamports - staked_lamports`. - Withdraw(u64), - - /// Deactivates the stake in the account - /// - /// # Account references - /// 0. `[WRITE]` Delegated stake account - /// 1. `[]` Clock sysvar - /// 2. `[SIGNER]` Stake authority - Deactivate, - - /// Set stake lockup - /// - /// # Account references - /// 0. `[WRITE]` Initialized stake account - /// 1. `[SIGNER]` Lockup authority - SetLockup, - - /// Merge two stake accounts. Both accounts must be deactivated and have identical lockup and - /// authority keys. - /// - /// # Account references - /// 0. `[WRITE]` Destination stake account for the merge - /// 1. `[WRITE]` Source stake account for to merge. This account will be drained - /// 2. `[]` Clock sysvar - /// 3. `[]` Stake history sysvar that carries stake warmup/cooldown history - /// 4. `[SIGNER]` Stake authority - Merge, - - /// Authorize a key to manage stake or withdrawal with a derived key - /// - /// # Account references - /// 0. `[WRITE]` Stake account to be updated - /// 1. `[SIGNER]` Base key of stake or withdraw authority - AuthorizeWithSeed, -} - -/// FIXME copied from the stake program -#[derive(Debug, Serialize, Deserialize, PartialEq, Clone, Copy)] -#[allow(clippy::large_enum_variant)] -pub enum StakeState { - /// FIXME copied from the stake program - Uninitialized, - /// FIXME copied from the stake program - Initialized(Meta), - /// FIXME copied from the stake program - Stake(Meta, Stake), - /// FIXME copied from the stake program - RewardsPool, -} - -impl BorshDeserialize for StakeState { - fn deserialize(buf: &mut &[u8]) -> IoResult { - let u: u32 = BorshDeserialize::deserialize(buf)?; - match u { - 0 => Ok(StakeState::Uninitialized), - 1 => { - let meta: Meta = BorshDeserialize::deserialize(buf)?; - Ok(StakeState::Initialized(meta)) - } - 2 => { - let meta: Meta = BorshDeserialize::deserialize(buf)?; - let stake: Stake = BorshDeserialize::deserialize(buf)?; - Ok(StakeState::Stake(meta, stake)) - } - 3 => Ok(StakeState::RewardsPool), - _ => Err(IoError::new(IoErrorKind::InvalidData, "Invalid enum value")), - } - } -} - -/// FIXME copied from the stake program -#[derive( - BorshSerialize, - BorshDeserialize, - BorshSchema, - Default, - Debug, - Serialize, - Deserialize, - PartialEq, - Clone, - Copy, -)] -pub struct Meta { - /// FIXME copied from the stake program - pub rent_exempt_reserve: u64, - /// FIXME copied from the stake program - pub authorized: Authorized, - /// FIXME copied from the stake program - pub lockup: Lockup, -} - -/// FIXME copied from the stake program -#[derive( - BorshSerialize, - BorshDeserialize, - BorshSchema, - Debug, - Default, - Serialize, - Deserialize, - PartialEq, - Clone, - Copy, -)] -pub struct Stake { - /// FIXME copied from the stake program - pub delegation: Delegation, - /// credits observed is credits from vote account state when delegated or redeemed - pub credits_observed: u64, -} - -/// FIXME copied from the stake program -#[derive( - BorshSerialize, - BorshDeserialize, - BorshSchema, - Debug, - Default, - Serialize, - Deserialize, - PartialEq, - Clone, - Copy, -)] -pub struct Delegation { - /// to whom the stake is delegated - pub voter_pubkey: Pubkey, - /// activated stake amount, set at delegate() time - pub stake: u64, - /// epoch at which this stake was activated, std::Epoch::MAX if is a bootstrap stake - pub activation_epoch: Epoch, - /// epoch the stake was deactivated, std::Epoch::MAX if not deactivated - pub deactivation_epoch: Epoch, - /// how much stake we can activate per-epoch as a fraction of currently effective stake - pub warmup_cooldown_rate: f64, -} - -/// FIXME copied from the stake program -#[derive( - BorshSerialize, - BorshDeserialize, - BorshSchema, - Debug, - Serialize, - Deserialize, - PartialEq, - Clone, - Copy, -)] -pub enum StakeAuthorize { - /// FIXME copied from the stake program - Staker, - /// FIXME copied from the stake program - Withdrawer, -} -/// FIXME copied from the stake program -#[derive( - BorshSerialize, - BorshDeserialize, - BorshSchema, - Default, - Debug, - Serialize, - Deserialize, - PartialEq, - Clone, - Copy, -)] -pub struct Authorized { - /// FIXME copied from the stake program - pub staker: Pubkey, - /// FIXME copied from the stake program - pub withdrawer: Pubkey, -} - -/// FIXME copied from the stake program +/// FIXME copied from the stake program, once https://github.com/solana-labs/solana/pull/20784 +/// lands this can be removed #[derive( BorshSerialize, BorshDeserialize, @@ -284,226 +38,12 @@ pub struct Lockup { pub custodian: Pubkey, } -/// FIXME copied from the stake program -impl StakeState { - /// Get Delegation - pub fn delegation(&self) -> Option { - match self { - StakeState::Stake(_meta, stake) => Some(stake.delegation), - _ => None, - } - } - /// Get meta - pub fn meta(&self) -> Option<&Meta> { - match self { - StakeState::Initialized(meta) => Some(meta), - StakeState::Stake(meta, _) => Some(meta), - _ => None, - } - } -} - -/// FIXME copied from the stake program -impl Delegation { - /// Create new Delegation - pub fn new( - voter_pubkey: &Pubkey, - stake: u64, - activation_epoch: Epoch, - warmup_cooldown_rate: f64, - ) -> Self { - Self { - voter_pubkey: *voter_pubkey, - stake, - activation_epoch, - warmup_cooldown_rate, - ..Delegation::default() - } - } - /// Check if it bootstrap - pub fn is_bootstrap(&self) -> bool { - self.activation_epoch == std::u64::MAX - } - - /// Return tuple (effective, activating, deactivating) stake - #[allow(clippy::comparison_chain)] - pub fn stake_activating_and_deactivating( - &self, - target_epoch: Epoch, - history: Option<&StakeHistory>, - fix_stake_deactivate: bool, - ) -> (u64, u64, u64) { - let delegated_stake = self.stake; - - // first, calculate an effective and activating stake - let (effective_stake, activating_stake) = - self.stake_and_activating(target_epoch, history, fix_stake_deactivate); - - // then de-activate some portion if necessary - if target_epoch < self.deactivation_epoch { - // not deactivated - (effective_stake, activating_stake, 0) - } else if target_epoch == self.deactivation_epoch { - // can only deactivate what's activated - (effective_stake, 0, effective_stake.min(delegated_stake)) - } else if let Some((history, mut prev_epoch, mut prev_cluster_stake)) = - history.and_then(|history| { - history - .get(&self.deactivation_epoch) - .map(|cluster_stake_at_deactivation_epoch| { - ( - history, - self.deactivation_epoch, - cluster_stake_at_deactivation_epoch, - ) - }) - }) - { - // target_epoch > self.deactivation_epoch - - // loop from my deactivation epoch until the target epoch - // current effective stake is updated using its previous epoch's cluster stake - let mut current_epoch; - let mut current_effective_stake = effective_stake; - loop { - current_epoch = prev_epoch + 1; - // if there is no deactivating stake at prev epoch, we should have been - // fully undelegated at this moment - if prev_cluster_stake.deactivating == 0 { - break; - } - - // I'm trying to get to zero, how much of the deactivation in stake - // this account is entitled to take - let weight = - current_effective_stake as f64 / prev_cluster_stake.deactivating as f64; - - // portion of newly not-effective cluster stake I'm entitled to at current epoch - let newly_not_effective_cluster_stake = - prev_cluster_stake.effective as f64 * self.warmup_cooldown_rate; - let newly_not_effective_stake = - ((weight * newly_not_effective_cluster_stake) as u64).max(1); - - current_effective_stake = - current_effective_stake.saturating_sub(newly_not_effective_stake); - if current_effective_stake == 0 { - break; - } - - if current_epoch >= target_epoch { - break; - } - if let Some(current_cluster_stake) = history.get(¤t_epoch) { - prev_epoch = current_epoch; - prev_cluster_stake = current_cluster_stake; - } else { - break; - } - } - - // deactivating stake should equal to all of currently remaining effective stake - (current_effective_stake, 0, current_effective_stake) - } else { - // no history or I've dropped out of history, so assume fully deactivated - (0, 0, 0) - } - } - - // returned tuple is (effective, activating) stake - fn stake_and_activating( - &self, - target_epoch: Epoch, - history: Option<&StakeHistory>, - fix_stake_deactivate: bool, - ) -> (u64, u64) { - let delegated_stake = self.stake; - - if self.is_bootstrap() { - // fully effective immediately - (delegated_stake, 0) - } else if fix_stake_deactivate && self.activation_epoch == self.deactivation_epoch { - // activated but instantly deactivated; no stake at all regardless of target_epoch - // this must be after the bootstrap check and before all-is-activating check - (0, 0) - } else if target_epoch == self.activation_epoch { - // all is activating - (0, delegated_stake) - } else if target_epoch < self.activation_epoch { - // not yet enabled - (0, 0) - } else if let Some((history, mut prev_epoch, mut prev_cluster_stake)) = - history.and_then(|history| { - history - .get(&self.activation_epoch) - .map(|cluster_stake_at_activation_epoch| { - ( - history, - self.activation_epoch, - cluster_stake_at_activation_epoch, - ) - }) - }) - { - // target_epoch > self.activation_epoch - - // loop from my activation epoch until the target epoch summing up my entitlement - // current effective stake is updated using its previous epoch's cluster stake - let mut current_epoch; - let mut current_effective_stake = 0; - loop { - current_epoch = prev_epoch + 1; - // if there is no activating stake at prev epoch, we should have been - // fully effective at this moment - if prev_cluster_stake.activating == 0 { - break; - } - - // how much of the growth in stake this account is - // entitled to take - let remaining_activating_stake = delegated_stake - current_effective_stake; - let weight = - remaining_activating_stake as f64 / prev_cluster_stake.activating as f64; - - // portion of newly effective cluster stake I'm entitled to at current epoch - let newly_effective_cluster_stake = - prev_cluster_stake.effective as f64 * self.warmup_cooldown_rate; - let newly_effective_stake = - ((weight * newly_effective_cluster_stake) as u64).max(1); - - current_effective_stake += newly_effective_stake; - if current_effective_stake >= delegated_stake { - current_effective_stake = delegated_stake; - break; - } - - if current_epoch >= target_epoch || current_epoch >= self.deactivation_epoch { - break; - } - if let Some(current_cluster_stake) = history.get(¤t_epoch) { - prev_epoch = current_epoch; - prev_cluster_stake = current_cluster_stake; - } else { - break; - } - } - - ( - current_effective_stake, - delegated_stake - current_effective_stake, - ) - } else { - // no history or I've dropped out of history, so assume fully effective - (delegated_stake, 0) - } - } -} - /// FIXME copied from stake program /// Checks if two active delegations are mergeable, required since we cannot recover /// from a CPI error. pub fn active_delegations_can_merge( - stake: &Delegation, - source: &Delegation, + stake: &stake::state::Delegation, + source: &stake::state::Delegation, ) -> Result<(), ProgramError> { if stake.voter_pubkey != source.voter_pubkey { msg!("Unable to merge due to voter mismatch"); @@ -522,7 +62,10 @@ pub fn active_delegations_can_merge( /// FIXME copied from stake program /// Checks if two active stakes are mergeable, required since we cannot recover /// from a CPI error. -pub fn active_stakes_can_merge(stake: &Stake, source: &Stake) -> Result<(), ProgramError> { +pub fn active_stakes_can_merge( + stake: &stake::state::Stake, + source: &stake::state::Stake, +) -> Result<(), ProgramError> { active_delegations_can_merge(&stake.delegation, &source.delegation)?; if stake.credits_observed == source.credits_observed { @@ -532,199 +75,3 @@ pub fn active_stakes_can_merge(stake: &Stake, source: &Stake) -> Result<(), Prog Err(ProgramError::InvalidAccountData) } } - -/// FIXME copied from the stake program -pub fn split_only( - stake_pubkey: &Pubkey, - authorized_pubkey: &Pubkey, - lamports: u64, - split_stake_pubkey: &Pubkey, -) -> Instruction { - let account_metas = vec![ - AccountMeta::new(*stake_pubkey, false), - AccountMeta::new(*split_stake_pubkey, false), - AccountMeta::new_readonly(*authorized_pubkey, true), - ]; - - Instruction::new_with_bincode(id(), &StakeInstruction::Split(lamports), account_metas) -} - -/// FIXME copied from the stake program -pub fn authorize( - stake_pubkey: &Pubkey, - authorized_pubkey: &Pubkey, - new_authorized_pubkey: &Pubkey, - stake_authorize: StakeAuthorize, -) -> Instruction { - let account_metas = vec![ - AccountMeta::new(*stake_pubkey, false), - AccountMeta::new_readonly(sysvar::clock::id(), false), - AccountMeta::new_readonly(*authorized_pubkey, true), - ]; - - Instruction::new_with_bincode( - id(), - &StakeInstruction::Authorize(*new_authorized_pubkey, stake_authorize), - account_metas, - ) -} - -/// FIXME copied from the stake program -pub fn merge( - destination_stake_pubkey: &Pubkey, - source_stake_pubkey: &Pubkey, - authorized_pubkey: &Pubkey, -) -> Instruction { - let account_metas = vec![ - AccountMeta::new(*destination_stake_pubkey, false), - AccountMeta::new(*source_stake_pubkey, false), - AccountMeta::new_readonly(sysvar::clock::id(), false), - AccountMeta::new_readonly(sysvar::stake_history::id(), false), - AccountMeta::new_readonly(*authorized_pubkey, true), - ]; - - Instruction::new_with_bincode(id(), &StakeInstruction::Merge, account_metas) -} - -/// FIXME copied from the stake program -pub fn create_account( - from_pubkey: &Pubkey, - stake_pubkey: &Pubkey, - authorized: &Authorized, - lockup: &Lockup, - lamports: u64, -) -> Vec { - vec![ - system_instruction::create_account( - from_pubkey, - stake_pubkey, - lamports, - std::mem::size_of::() as u64, - &id(), - ), - initialize(stake_pubkey, authorized, lockup), - ] -} - -/// FIXME copied from the stake program -pub fn initialize(stake_pubkey: &Pubkey, authorized: &Authorized, lockup: &Lockup) -> Instruction { - Instruction::new_with_bincode( - id(), - &StakeInstruction::Initialize(*authorized, *lockup), - vec![ - AccountMeta::new(*stake_pubkey, false), - AccountMeta::new_readonly(sysvar::rent::id(), false), - ], - ) -} - -/// FIXME copied from the stake program -pub fn delegate_stake( - stake_pubkey: &Pubkey, - authorized_pubkey: &Pubkey, - vote_pubkey: &Pubkey, -) -> Instruction { - let account_metas = vec![ - AccountMeta::new(*stake_pubkey, false), - AccountMeta::new_readonly(*vote_pubkey, false), - AccountMeta::new_readonly(sysvar::clock::id(), false), - AccountMeta::new_readonly(sysvar::stake_history::id(), false), - AccountMeta::new_readonly(config_id(), false), - AccountMeta::new_readonly(*authorized_pubkey, true), - ]; - Instruction::new_with_bincode(id(), &StakeInstruction::DelegateStake, account_metas) -} - -/// FIXME copied from stake program -pub fn deactivate_stake(stake_pubkey: &Pubkey, authorized_pubkey: &Pubkey) -> Instruction { - let account_metas = vec![ - AccountMeta::new(*stake_pubkey, false), - AccountMeta::new_readonly(sysvar::clock::id(), false), - AccountMeta::new_readonly(*authorized_pubkey, true), - ]; - Instruction::new_with_bincode(id(), &StakeInstruction::Deactivate, account_metas) -} - -/// FIXME copied from the stake program -pub fn withdraw( - stake_pubkey: &Pubkey, - withdrawer_pubkey: &Pubkey, - to_pubkey: &Pubkey, - lamports: u64, - custodian_pubkey: Option<&Pubkey>, -) -> Instruction { - let mut account_metas = vec![ - AccountMeta::new(*stake_pubkey, false), - AccountMeta::new(*to_pubkey, false), - AccountMeta::new_readonly(sysvar::clock::id(), false), - AccountMeta::new_readonly(sysvar::stake_history::id(), false), - AccountMeta::new_readonly(*withdrawer_pubkey, true), - ]; - - if let Some(custodian_pubkey) = custodian_pubkey { - account_metas.push(AccountMeta::new_readonly(*custodian_pubkey, true)); - } - - Instruction::new_with_bincode(id(), &StakeInstruction::Withdraw(lamports), account_metas) -} - -#[cfg(test)] -mod test { - use {super::*, bincode::serialize, solana_program::borsh::try_from_slice_unchecked}; - - fn check_borsh_deserialization(stake: StakeState) { - let serialized = serialize(&stake).unwrap(); - let deserialized = StakeState::try_from_slice(&serialized).unwrap(); - assert_eq!(stake, deserialized); - } - - #[test] - fn bincode_vs_borsh() { - check_borsh_deserialization(StakeState::Uninitialized); - check_borsh_deserialization(StakeState::RewardsPool); - check_borsh_deserialization(StakeState::Initialized(Meta { - rent_exempt_reserve: u64::MAX, - authorized: Authorized { - staker: Pubkey::new_unique(), - withdrawer: Pubkey::new_unique(), - }, - lockup: Lockup::default(), - })); - check_borsh_deserialization(StakeState::Stake( - Meta { - rent_exempt_reserve: 1, - authorized: Authorized { - staker: Pubkey::new_unique(), - withdrawer: Pubkey::new_unique(), - }, - lockup: Lockup::default(), - }, - Stake { - delegation: Delegation { - voter_pubkey: Pubkey::new_unique(), - stake: u64::MAX, - activation_epoch: Epoch::MAX, - deactivation_epoch: Epoch::MAX, - warmup_cooldown_rate: f64::MAX, - }, - credits_observed: 1, - }, - )); - } - - #[test] - fn borsh_deserialization_live_data() { - let data = [ - 1, 0, 0, 0, 128, 213, 34, 0, 0, 0, 0, 0, 133, 0, 79, 231, 141, 29, 73, 61, 232, 35, - 119, 124, 168, 12, 120, 216, 195, 29, 12, 166, 139, 28, 36, 182, 186, 154, 246, 149, - 224, 109, 52, 100, 133, 0, 79, 231, 141, 29, 73, 61, 232, 35, 119, 124, 168, 12, 120, - 216, 195, 29, 12, 166, 139, 28, 36, 182, 186, 154, 246, 149, 224, 109, 52, 100, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - ]; - let _deserialized = try_from_slice_unchecked::(&data).unwrap(); - } -} diff --git a/program/tests/decrease.rs b/program/tests/decrease.rs index 20c73fbf..72ebc5d7 100644 --- a/program/tests/decrease.rs +++ b/program/tests/decrease.rs @@ -5,14 +5,16 @@ mod helpers; use { bincode::deserialize, helpers::*, - solana_program::{clock::Epoch, hash::Hash, instruction::InstructionError, pubkey::Pubkey}, + solana_program::{ + clock::Epoch, hash::Hash, instruction::InstructionError, pubkey::Pubkey, stake, + }, solana_program_test::*, solana_sdk::{ signature::{Keypair, Signer}, transaction::{Transaction, TransactionError}, }, spl_stake_pool::{ - error::StakePoolError, find_transient_stake_program_address, id, instruction, stake_program, + error::StakePoolError, find_transient_stake_program_address, id, instruction, }, }; @@ -104,7 +106,7 @@ async fn success() { let validator_stake_account = get_account(&mut banks_client, &validator_stake.stake_account).await; let validator_stake_state = - deserialize::(&validator_stake_account.data).unwrap(); + deserialize::(&validator_stake_account.data).unwrap(); assert_eq!( pre_validator_stake_account.lamports - decrease_lamports, validator_stake_account.lamports @@ -121,7 +123,7 @@ async fn success() { let transient_stake_account = get_account(&mut banks_client, &validator_stake.transient_stake_account).await; let transient_stake_state = - deserialize::(&transient_stake_account.data).unwrap(); + deserialize::(&transient_stake_account.data).unwrap(); assert_eq!(transient_stake_account.lamports, decrease_lamports); assert_ne!( transient_stake_state @@ -344,7 +346,7 @@ async fn fail_with_small_lamport_amount() { ) = setup().await; let rent = banks_client.get_rent().await.unwrap(); - let lamports = rent.minimum_balance(std::mem::size_of::()); + let lamports = rent.minimum_balance(std::mem::size_of::()); let error = stake_pool_accounts .decrease_validator_stake( @@ -411,7 +413,7 @@ async fn fail_overdraw() { ) = setup().await; let rent = banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let error = stake_pool_accounts .decrease_validator_stake( diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 8ba464a1..754a2a8d 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -10,7 +10,7 @@ use { borsh::try_from_slice_unchecked, instruction::{AccountMeta, Instruction, InstructionError}, pubkey::Pubkey, - sysvar, + stake, sysvar, }, solana_program_test::*, solana_sdk::{ @@ -19,9 +19,7 @@ use { transaction::TransactionError, transport::TransportError, }, - spl_stake_pool::{ - error::StakePoolError, id, instruction, minimum_stake_lamports, stake_program, state, - }, + spl_stake_pool::{error::StakePoolError, id, instruction, minimum_stake_lamports, state}, spl_token::error as token_error, }; @@ -63,9 +61,9 @@ async fn setup() -> ( let user = Keypair::new(); // make stake account let deposit_stake = Keypair::new(); - let lockup = stake_program::Lockup::default(); + let lockup = stake::state::Lockup::default(); - let authorized = stake_program::Authorized { + let authorized = stake::state::Authorized { staker: user.pubkey(), withdrawer: user.pubkey(), }; @@ -140,7 +138,7 @@ async fn success() { ) = setup().await; let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); // Save stake pool state before depositing let pre_stake_pool = get_account( @@ -246,10 +244,10 @@ async fn success() { ) .await; let stake_state = - deserialize::(&validator_stake_account.data).unwrap(); + deserialize::(&validator_stake_account.data).unwrap(); let meta = stake_state.meta().unwrap(); assert_eq!( - validator_stake_account.lamports - minimum_stake_lamports(meta), + validator_stake_account.lamports - minimum_stake_lamports(&meta), post_validator_stake_item.stake_lamports() ); assert_eq!(post_validator_stake_item.transient_stake_lamports, 0); @@ -310,7 +308,7 @@ async fn success_with_extra_stake_lamports() { .await; let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); // Save stake pool state before depositing let pre_stake_pool = get_account( @@ -441,10 +439,10 @@ async fn success_with_extra_stake_lamports() { ) .await; let stake_state = - deserialize::(&validator_stake_account.data).unwrap(); + deserialize::(&validator_stake_account.data).unwrap(); let meta = stake_state.meta().unwrap(); assert_eq!( - validator_stake_account.lamports - minimum_stake_lamports(meta), + validator_stake_account.lamports - minimum_stake_lamports(&meta), post_validator_stake_item.stake_lamports() ); assert_eq!(post_validator_stake_item.transient_stake_lamports, 0); @@ -641,8 +639,8 @@ async fn fail_with_unknown_validator() { // make stake account let user_stake = Keypair::new(); - let lockup = stake_program::Lockup::default(); - let authorized = stake_program::Authorized { + let lockup = stake::state::Lockup::default(); + let authorized = stake::state::Authorized { staker: user.pubkey(), withdrawer: user.pubkey(), }; @@ -816,8 +814,8 @@ async fn success_with_stake_deposit_authority() { let user = Keypair::new(); let user_stake = Keypair::new(); - let lockup = stake_program::Lockup::default(); - let authorized = stake_program::Authorized { + let lockup = stake::state::Lockup::default(); + let authorized = stake::state::Authorized { staker: user.pubkey(), withdrawer: user.pubkey(), }; @@ -898,8 +896,8 @@ async fn fail_without_stake_deposit_authority_signature() { let user = Keypair::new(); let user_stake = Keypair::new(); - let lockup = stake_program::Lockup::default(); - let authorized = stake_program::Authorized { + let lockup = stake::state::Lockup::default(); + let authorized = stake::state::Authorized { staker: user.pubkey(), withdrawer: user.pubkey(), }; @@ -1127,7 +1125,7 @@ async fn success_with_referral_fee() { let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let fee_tokens = stake_pool .calc_pool_tokens_sol_deposit_fee(stake_rent) .unwrap() diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index bc9a8501..54a0a82b 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -6,7 +6,7 @@ use { hash::Hash, program_pack::Pack, pubkey::Pubkey, - system_instruction, system_program, + stake, system_instruction, system_program, }, solana_program_test::*, solana_sdk::{ @@ -21,7 +21,7 @@ use { }, spl_stake_pool::{ find_stake_program_address, find_transient_stake_program_address, id, instruction, - processor, stake_program, + processor, state::{self, FeeType, ValidatorList}, MINIMUM_ACTIVE_STAKE, }, @@ -431,16 +431,16 @@ pub async fn create_independent_stake_account( payer: &Keypair, recent_blockhash: &Hash, stake: &Keypair, - authorized: &stake_program::Authorized, - lockup: &stake_program::Lockup, + authorized: &stake::state::Authorized, + lockup: &stake::state::Lockup, stake_amount: u64, ) -> u64 { let rent = banks_client.get_rent().await.unwrap(); let lamports = - rent.minimum_balance(std::mem::size_of::()) + stake_amount; + rent.minimum_balance(std::mem::size_of::()) + stake_amount; let transaction = Transaction::new_signed_with_payer( - &stake_program::create_account( + &stake::instruction::create_account( &payer.pubkey(), &stake.pubkey(), authorized, @@ -463,15 +463,15 @@ pub async fn create_blank_stake_account( stake: &Keypair, ) -> u64 { let rent = banks_client.get_rent().await.unwrap(); - let lamports = rent.minimum_balance(std::mem::size_of::()) + 1; + let lamports = rent.minimum_balance(std::mem::size_of::()) + 1; let transaction = Transaction::new_signed_with_payer( &[system_instruction::create_account( &payer.pubkey(), &stake.pubkey(), lamports, - std::mem::size_of::() as u64, - &stake_program::id(), + std::mem::size_of::() as u64, + &stake::program::id(), )], Some(&payer.pubkey()), &[payer, stake], @@ -491,7 +491,7 @@ pub async fn delegate_stake_account( vote: &Pubkey, ) { let mut transaction = Transaction::new_with_payer( - &[stake_program::delegate_stake( + &[stake::instruction::delegate_stake( stake, &authorized.pubkey(), vote, @@ -509,14 +509,15 @@ pub async fn authorize_stake_account( stake: &Pubkey, authorized: &Keypair, new_authorized: &Pubkey, - stake_authorize: stake_program::StakeAuthorize, + stake_authorize: stake::state::StakeAuthorize, ) { let mut transaction = Transaction::new_with_payer( - &[stake_program::authorize( + &[stake::instruction::authorize( stake, &authorized.pubkey(), new_authorized, stake_authorize, + None, )], Some(&payer.pubkey()), ); @@ -546,11 +547,11 @@ pub async fn create_unknown_validator_stake( payer, recent_blockhash, &fake_validator_stake, - &stake_program::Authorized { + &stake::state::Authorized { staker: user.pubkey(), withdrawer: user.pubkey(), }, - &stake_program::Lockup::default(), + &stake::state::Lockup::default(), MINIMUM_ACTIVE_STAKE, ) .await; @@ -726,11 +727,11 @@ impl StakePoolAccounts { payer, recent_blockhash, &self.reserve_stake, - &stake_program::Authorized { + &stake::state::Authorized { staker: self.withdraw_authority, withdrawer: self.withdraw_authority, }, - &stake_program::Lockup::default(), + &stake::state::Lockup::default(), reserve_lamports, ) .await; @@ -1144,8 +1145,8 @@ impl StakePoolAccounts { &payer.pubkey(), &destination_stake.pubkey(), 0, - std::mem::size_of::() as u64, - &stake_program::id(), + std::mem::size_of::() as u64, + &stake::program::id(), ), instruction::remove_validator_from_pool( &id(), @@ -1323,8 +1324,8 @@ impl DepositStakeAccount { payer: &Keypair, recent_blockhash: &Hash, ) { - let lockup = stake_program::Lockup::default(); - let authorized = stake_program::Authorized { + let lockup = stake::state::Lockup::default(); + let authorized = stake::state::Authorized { staker: self.authority.pubkey(), withdrawer: self.authority.pubkey(), }; @@ -1395,8 +1396,8 @@ pub async fn simple_deposit_stake( let authority = Keypair::new(); // make stake account let stake = Keypair::new(); - let lockup = stake_program::Lockup::default(); - let authorized = stake_program::Authorized { + let lockup = stake::state::Lockup::default(); + let authorized = stake::state::Authorized { staker: authority.pubkey(), withdrawer: authority.pubkey(), }; @@ -1487,6 +1488,6 @@ pub async fn get_validator_list_sum( .map(|info| info.stake_lamports()) .sum(); let rent = banks_client.get_rent().await.unwrap(); - let rent = rent.minimum_balance(std::mem::size_of::()); + let rent = rent.minimum_balance(std::mem::size_of::()); validator_sum + reserve_stake.lamports - rent - 1 } diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index dac35614..48b7e741 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -7,7 +7,7 @@ use { helpers::*, solana_program::{ borsh::try_from_slice_unchecked, program_option::COption, program_pack::Pack, - pubkey::Pubkey, + pubkey::Pubkey, stake, }, solana_program_test::*, solana_sdk::{ @@ -98,13 +98,13 @@ async fn setup( let authorized_withdrawer = Pubkey::new_unique(); let commission = 1; - let meta = stake_program::Meta { + let meta = stake::state::Meta { rent_exempt_reserve: STAKE_ACCOUNT_RENT_EXEMPTION, - authorized: stake_program::Authorized { + authorized: stake::state::Authorized { staker: stake_pool_accounts.withdraw_authority, withdrawer: stake_pool_accounts.withdraw_authority, }, - lockup: stake_program::Lockup::default(), + lockup: stake::state::Lockup::default(), }; for _ in 0..max_validators { @@ -133,8 +133,8 @@ async fn setup( for vote_account_address in vote_account_pubkeys.iter().take(num_validators as usize) { // create validator stake account - let stake = stake_program::Stake { - delegation: stake_program::Delegation { + let stake = stake::state::Stake { + delegation: stake::state::Delegation { voter_pubkey: *vote_account_address, stake: stake_amount, activation_epoch: 0, @@ -146,11 +146,11 @@ async fn setup( let stake_account = Account::create( stake_amount + STAKE_ACCOUNT_RENT_EXEMPTION, - bincode::serialize::(&stake_program::StakeState::Stake( + bincode::serialize::(&stake::state::StakeState::Stake( meta, stake, )) .unwrap(), - stake_program::id(), + stake::program::id(), false, Epoch::default(), ); @@ -183,11 +183,11 @@ async fn setup( let reserve_stake_account = Account::create( stake_amount + STAKE_ACCOUNT_RENT_EXEMPTION, - bincode::serialize::(&stake_program::StakeState::Initialized( + bincode::serialize::(&stake::state::StakeState::Initialized( meta, )) .unwrap(), - stake_program::id(), + stake::program::id(), false, Epoch::default(), ); @@ -266,9 +266,9 @@ async fn setup( // make stake account let user = Keypair::new(); let deposit_stake = Keypair::new(); - let lockup = stake_program::Lockup::default(); + let lockup = stake::state::Lockup::default(); - let authorized = stake_program::Authorized { + let authorized = stake::state::Authorized { staker: user.pubkey(), withdrawer: user.pubkey(), }; diff --git a/program/tests/increase.rs b/program/tests/increase.rs index 11314951..105eda3c 100644 --- a/program/tests/increase.rs +++ b/program/tests/increase.rs @@ -5,7 +5,9 @@ mod helpers; use { bincode::deserialize, helpers::*, - solana_program::{clock::Epoch, hash::Hash, instruction::InstructionError, pubkey::Pubkey}, + solana_program::{ + clock::Epoch, hash::Hash, instruction::InstructionError, pubkey::Pubkey, stake, + }, solana_program_test::*, solana_sdk::{ signature::{Keypair, Signer}, @@ -13,7 +15,7 @@ use { }, spl_stake_pool::{ error::StakePoolError, find_transient_stake_program_address, id, instruction, - stake_program, MINIMUM_ACTIVE_STAKE, + MINIMUM_ACTIVE_STAKE, }, }; @@ -93,7 +95,7 @@ async fn success() { assert!(transient_account.is_none()); let rent = banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let increase_amount = reserve_lamports - stake_rent - 1; let error = stake_pool_accounts .increase_validator_stake( @@ -115,7 +117,7 @@ async fn success() { ) .await; let reserve_stake_state = - deserialize::(&reserve_stake_account.data).unwrap(); + deserialize::(&reserve_stake_account.data).unwrap(); assert_eq!( pre_reserve_stake_account.lamports - increase_amount - stake_rent, reserve_stake_account.lamports @@ -126,7 +128,7 @@ async fn success() { let transient_stake_account = get_account(&mut banks_client, &validator_stake.transient_stake_account).await; let transient_stake_state = - deserialize::(&transient_stake_account.data).unwrap(); + deserialize::(&transient_stake_account.data).unwrap(); assert_eq!( transient_stake_account.lamports, increase_amount + stake_rent diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index e9aa1160..7aa03f52 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -11,14 +11,14 @@ use { instruction::{AccountMeta, Instruction}, program_pack::Pack, pubkey::Pubkey, - system_instruction, sysvar, + stake, system_instruction, sysvar, }, solana_program_test::*, solana_sdk::{ instruction::InstructionError, signature::Keypair, signature::Signer, transaction::Transaction, transaction::TransactionError, transport::TransportError, }, - spl_stake_pool::{error, id, instruction, stake_program, state}, + spl_stake_pool::{error, id, instruction, state}, }; async fn create_required_accounts( @@ -53,11 +53,11 @@ async fn create_required_accounts( payer, recent_blockhash, &stake_pool_accounts.reserve_stake, - &stake_program::Authorized { + &stake::state::Authorized { staker: stake_pool_accounts.withdraw_authority, withdrawer: stake_pool_accounts.withdraw_authority, }, - &stake_program::Lockup::default(), + &stake::state::Lockup::default(), 1, ) .await; @@ -1074,11 +1074,11 @@ async fn fail_with_bad_reserve() { &payer, &recent_blockhash, &bad_stake, - &stake_program::Authorized { + &stake::state::Authorized { staker: wrong_authority, withdrawer: stake_pool_accounts.withdraw_authority, }, - &stake_program::Lockup::default(), + &stake::state::Lockup::default(), 1, ) .await; @@ -1124,11 +1124,11 @@ async fn fail_with_bad_reserve() { &payer, &recent_blockhash, &bad_stake, - &stake_program::Authorized { + &stake::state::Authorized { staker: stake_pool_accounts.withdraw_authority, withdrawer: wrong_authority, }, - &stake_program::Lockup::default(), + &stake::state::Lockup::default(), 1, ) .await; @@ -1174,13 +1174,13 @@ async fn fail_with_bad_reserve() { &payer, &recent_blockhash, &bad_stake, - &stake_program::Authorized { + &stake::state::Authorized { staker: stake_pool_accounts.withdraw_authority, withdrawer: stake_pool_accounts.withdraw_authority, }, - &stake_program::Lockup { + &stake::state::Lockup { custodian: wrong_authority, - ..stake_program::Lockup::default() + ..stake::state::Lockup::default() }, 1, ) @@ -1223,15 +1223,15 @@ async fn fail_with_bad_reserve() { { let bad_stake = Keypair::new(); let rent = banks_client.get_rent().await.unwrap(); - let lamports = rent.minimum_balance(std::mem::size_of::()); + let lamports = rent.minimum_balance(std::mem::size_of::()); let transaction = Transaction::new_signed_with_payer( &[system_instruction::create_account( &payer.pubkey(), &bad_stake.pubkey(), lamports, - std::mem::size_of::() as u64, - &stake_program::id(), + std::mem::size_of::() as u64, + &stake::program::id(), )], Some(&payer.pubkey()), &[&payer, &bad_stake], diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index 82387d46..7c8c270a 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -4,7 +4,7 @@ mod helpers; use { helpers::*, - solana_program::{borsh::try_from_slice_unchecked, program_pack::Pack, pubkey::Pubkey}, + solana_program::{borsh::try_from_slice_unchecked, program_pack::Pack, pubkey::Pubkey, stake}, solana_program_test::*, solana_sdk::{ signature::{Keypair, Signer}, @@ -12,7 +12,7 @@ use { transaction::Transaction, }, spl_stake_pool::{ - find_transient_stake_program_address, id, instruction, stake_program, + find_transient_stake_program_address, id, instruction, state::{StakePool, StakeStatus, ValidatorList}, MAX_VALIDATORS_TO_UPDATE, MINIMUM_ACTIVE_STAKE, }, @@ -163,7 +163,7 @@ async fn success() { // Check current balance in the list let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); // initially, have all of the deposits plus their rent, and the reserve stake let initial_lamports = (validator_lamports + stake_rent) * num_validators as u64 + reserve_lamports; @@ -436,7 +436,7 @@ async fn merge_into_validator_stake() { // Check validator stake accounts have the expected balance now: // validator stake account minimum + deposited lamports + rents + increased lamports - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let expected_lamports = MINIMUM_ACTIVE_STAKE + lamports + reserve_lamports / stake_accounts.len() as u64 @@ -466,7 +466,7 @@ async fn merge_transient_stake_after_remove() { setup(1).await; let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let deactivated_lamports = lamports; let new_authority = Pubkey::new_unique(); let destination_stake = Keypair::new(); @@ -739,13 +739,13 @@ async fn success_ignoring_hijacked_transient_stake() { &transient_stake_address, 1_000_000_000, ), - stake_program::initialize( + stake::instruction::initialize( &transient_stake_address, - &stake_program::Authorized { + &stake::state::Authorized { staker: hijacker, withdrawer: hijacker, }, - &stake_program::Lockup::default(), + &stake::state::Lockup::default(), ), instruction::update_stake_pool_balance( &id(), diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index 4063d3f2..08cb1a36 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -11,7 +11,7 @@ use { hash::Hash, instruction::{AccountMeta, Instruction, InstructionError}, pubkey::Pubkey, - system_program, sysvar, + stake, system_program, sysvar, }, solana_program_test::*, solana_sdk::{ @@ -19,9 +19,7 @@ use { transaction::{Transaction, TransactionError}, transport::TransportError, }, - spl_stake_pool::{ - error::StakePoolError, find_stake_program_address, id, instruction, stake_program, state, - }, + spl_stake_pool::{error::StakePoolError, find_stake_program_address, id, instruction, state}, }; async fn setup() -> ( @@ -102,9 +100,9 @@ async fn success() { // Check stake account existence and authority let stake = get_account(&mut banks_client, &validator_stake.stake_account).await; - let stake_state = deserialize::(&stake.data).unwrap(); + let stake_state = deserialize::(&stake.data).unwrap(); match stake_state { - stake_program::StakeState::Stake(meta, _) => { + stake::state::StakeState::Stake(meta, _) => { assert_eq!( &meta.authorized.staker, &stake_pool_accounts.withdraw_authority @@ -252,9 +250,9 @@ async fn fail_without_signature() { AccountMeta::new_readonly(sysvar::rent::id(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), - AccountMeta::new_readonly(stake_program::config_id(), false), + AccountMeta::new_readonly(stake::config::id(), false), AccountMeta::new_readonly(system_program::id(), false), - AccountMeta::new_readonly(stake_program::id(), false), + AccountMeta::new_readonly(stake::program::id(), false), ]; let instruction = Instruction { program_id: id(), @@ -301,7 +299,7 @@ async fn fail_with_wrong_stake_program_id() { AccountMeta::new_readonly(sysvar::rent::id(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), - AccountMeta::new_readonly(stake_program::config_id(), false), + AccountMeta::new_readonly(stake::config::id(), false), AccountMeta::new_readonly(system_program::id(), false), AccountMeta::new_readonly(wrong_stake_program, false), ]; @@ -348,9 +346,9 @@ async fn fail_with_wrong_system_program_id() { AccountMeta::new_readonly(sysvar::rent::id(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), - AccountMeta::new_readonly(stake_program::config_id(), false), + AccountMeta::new_readonly(stake::config::id(), false), AccountMeta::new_readonly(wrong_system_program, false), - AccountMeta::new_readonly(stake_program::id(), false), + AccountMeta::new_readonly(stake::program::id(), false), ]; let instruction = Instruction { program_id: id(), diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index b47a7dec..acbb0d88 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -10,7 +10,7 @@ use { borsh::try_from_slice_unchecked, instruction::{AccountMeta, Instruction, InstructionError}, pubkey::Pubkey, - system_instruction, sysvar, + stake, system_instruction, sysvar, }, solana_program_test::*, solana_sdk::{ @@ -19,8 +19,7 @@ use { transport::TransportError, }, spl_stake_pool::{ - error::StakePoolError, find_transient_stake_program_address, id, instruction, - stake_program, state, + error::StakePoolError, find_transient_stake_program_address, id, instruction, state, }, }; @@ -131,9 +130,9 @@ async fn success() { .unwrap(); assert!(account.is_none()); let stake = get_account(&mut context.banks_client, &destination_stake.pubkey()).await; - let stake_state = deserialize::(&stake.data).unwrap(); + let stake_state = deserialize::(&stake.data).unwrap(); match stake_state { - stake_program::StakeState::Stake(meta, _) => { + stake::state::StakeState::Stake(meta, _) => { assert_eq!(&meta.authorized.staker, &new_authority); assert_eq!(&meta.authorized.withdrawer, &new_authority); } @@ -380,7 +379,7 @@ async fn fail_no_signature() { AccountMeta::new_readonly(validator_stake.transient_stake_account, false), AccountMeta::new(destination_stake.pubkey(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), - AccountMeta::new_readonly(stake_program::id(), false), + AccountMeta::new_readonly(stake::program::id(), false), ]; let instruction = Instruction { program_id: id(), @@ -465,7 +464,7 @@ async fn success_with_deactivating_transient_stake() { setup().await; let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let deposit_info = simple_deposit_stake( &mut context.banks_client, &context.payer, @@ -667,9 +666,9 @@ async fn success_resets_preferred_validator() { // Check of stake account authority has changed let stake = get_account(&mut context.banks_client, &destination_stake.pubkey()).await; - let stake_state = deserialize::(&stake.data).unwrap(); + let stake_state = deserialize::(&stake.data).unwrap(); match stake_state { - stake_program::StakeState::Stake(meta, _) => { + stake::state::StakeState::Stake(meta, _) => { assert_eq!(&meta.authorized.staker, &new_authority); assert_eq!(&meta.authorized.withdrawer, &new_authority); } @@ -756,13 +755,13 @@ async fn success_with_hijacked_transient_account() { &transient_stake_address, 1_000_000_000, ), - stake_program::initialize( + stake::instruction::initialize( &transient_stake_address, - &stake_program::Authorized { + &stake::state::Authorized { staker: hijacker.pubkey(), withdrawer: hijacker.pubkey(), }, - &stake_program::Lockup::default(), + &stake::state::Lockup::default(), ), instruction::update_stake_pool_balance( &id(), diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 3b91023a..8f368b45 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -11,7 +11,7 @@ use { hash::Hash, instruction::{AccountMeta, Instruction, InstructionError}, pubkey::Pubkey, - sysvar, + stake, sysvar, }, solana_program_test::*, solana_sdk::{ @@ -19,9 +19,7 @@ use { transaction::{Transaction, TransactionError}, transport::TransportError, }, - spl_stake_pool::{ - error::StakePoolError, id, instruction, minimum_stake_lamports, stake_program, state, - }, + spl_stake_pool::{error::StakePoolError, id, instruction, minimum_stake_lamports, state}, spl_token::error::TokenError, }; @@ -298,10 +296,10 @@ async fn _success(test_type: SuccessTestType) { let validator_stake_account = get_account(&mut banks_client, &validator_stake_account.stake_account).await; let stake_state = - deserialize::(&validator_stake_account.data).unwrap(); + deserialize::(&validator_stake_account.data).unwrap(); let meta = stake_state.meta().unwrap(); assert_eq!( - validator_stake_account.lamports - minimum_stake_lamports(meta), + validator_stake_account.lamports - minimum_stake_lamports(&meta), validator_stake_item.active_stake_lamports ); @@ -856,7 +854,7 @@ async fn success_with_reserve() { let deposit_lamports = TEST_STAKE_AMOUNT; let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let deposit_info = simple_deposit_stake( &mut context.banks_client, @@ -1032,8 +1030,7 @@ async fn success_with_reserve() { &stake_pool_accounts.reserve_stake.pubkey(), ) .await; - let stake_state = - deserialize::(&reserve_stake_account.data).unwrap(); + let stake_state = deserialize::(&reserve_stake_account.data).unwrap(); let meta = stake_state.meta().unwrap(); assert_eq!( initial_reserve_lamports + meta.rent_exempt_reserve + withdrawal_fee + deposit_fee, @@ -1233,7 +1230,7 @@ async fn success_withdraw_from_transient() { let deposit_lamports = TEST_STAKE_AMOUNT; let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let deposit_info = simple_deposit_stake( &mut context.banks_client, diff --git a/program/tests/withdraw_sol.rs b/program/tests/withdraw_sol.rs index 690ab361..4dd35b3d 100644 --- a/program/tests/withdraw_sol.rs +++ b/program/tests/withdraw_sol.rs @@ -5,7 +5,7 @@ mod helpers; use { helpers::*, solana_program::{ - borsh::try_from_slice_unchecked, instruction::InstructionError, pubkey::Pubkey, + borsh::try_from_slice_unchecked, instruction::InstructionError, pubkey::Pubkey, stake, }, solana_program_test::*, solana_sdk::{ @@ -17,7 +17,7 @@ use { error::StakePoolError, id, instruction::{self, FundingType}, - stake_program, state, + state, }, }; @@ -189,7 +189,7 @@ async fn fail_overdraw_reserve() { .await; let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let error = stake_pool_accounts .increase_validator_stake( &mut context.banks_client, From 7a0b8cdb2ecccc7556a1c554fff9d15ad7f6dbfa Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 19 Oct 2021 17:19:10 +0200 Subject: [PATCH 0189/1076] stake-pool: Add comment to validator stake info field (#2527) --- program/src/state.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/program/src/state.rs b/program/src/state.rs index 9c2776f0..792e18cc 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -532,12 +532,16 @@ impl Default for StakeStatus { #[repr(C)] #[derive(Clone, Copy, Debug, Default, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)] pub struct ValidatorStakeInfo { - /// Amount of active stake delegated to this validator + /// Amount of active stake delegated to this validator, minus the minimum + /// required stake amount of rent-exemption + `crate::MINIMUM_ACTIVE_STAKE` + /// (currently 0.001 SOL). + /// /// Note that if `last_update_epoch` does not match the current epoch then /// this field may not be accurate pub active_stake_lamports: u64, /// Amount of transient stake delegated to this validator + /// /// Note that if `last_update_epoch` does not match the current epoch then /// this field may not be accurate pub transient_stake_lamports: u64, From 8603796e70c256710fdd767346982a8720eedcd2 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 19 Oct 2021 23:30:41 +0200 Subject: [PATCH 0190/1076] stake-pool-cli: Improve deposit and withdraw UX (#2530) --- clients/cli/src/main.rs | 98 ++++++++++++++++++++++++++++++----------- 1 file changed, 72 insertions(+), 26 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 851ee139..6fc1868c 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -10,9 +10,9 @@ use { input_parsers::{keypair_of, pubkey_of}, input_validators::{ is_amount, is_keypair, is_keypair_or_ask_keyword, is_parsable, is_pubkey, is_url, - is_valid_percentage, + is_valid_percentage, is_valid_pubkey, }, - keypair::signer_from_path, + keypair::{signer_from_path_with_config, SignerFromPathConfig}, }, solana_client::rpc_client::RpcClient, solana_program::{ @@ -88,12 +88,14 @@ fn get_signer( keypair_name: &str, keypair_path: &str, wallet_manager: &mut Option>, + signer_from_path_config: SignerFromPathConfig, ) -> Box { - signer_from_path( + signer_from_path_with_config( matches, matches.value_of(keypair_name).unwrap_or(keypair_path), keypair_name, wallet_manager, + &signer_from_path_config, ) .unwrap_or_else(|e| { eprintln!("error: {}", e); @@ -596,6 +598,7 @@ fn command_deposit_stake( config: &Config, stake_pool_address: &Pubkey, stake: &Pubkey, + withdraw_authority: Box, pool_token_receiver_account: &Option, referrer_token_account: &Option, ) -> CommandResult { @@ -634,7 +637,7 @@ fn command_deposit_stake( } let mut instructions: Vec = vec![]; - let mut signers = vec![config.fee_payer.as_ref(), config.staker.as_ref()]; + let mut signers = vec![config.fee_payer.as_ref(), withdraw_authority.as_ref()]; let mut total_rent_free_balances: u64 = 0; @@ -672,7 +675,7 @@ fn command_deposit_stake( &stake_deposit_authority.pubkey(), &pool_withdraw_authority, stake, - &config.staker.pubkey(), + &withdraw_authority.pubkey(), &validator_stake_account, &stake_pool.reserve_stake, &pool_token_receiver_account, @@ -688,7 +691,7 @@ fn command_deposit_stake( &stake_pool.validator_list, &pool_withdraw_authority, stake, - &config.staker.pubkey(), + &withdraw_authority.pubkey(), &validator_stake_account, &stake_pool.reserve_stake, &pool_token_receiver_account, @@ -1371,8 +1374,8 @@ fn command_withdraw_stake( fn command_withdraw_sol( config: &Config, stake_pool_address: &Pubkey, - sol_receiver: &Option, pool_token_account: &Option, + sol_receiver: &Pubkey, pool_amount: f64, ) -> CommandResult { if !config.no_update { @@ -1383,7 +1386,6 @@ fn command_withdraw_sol( let pool_mint = get_token_mint(&config.rpc_client, &stake_pool.pool_mint)?; let pool_amount = spl_token::ui_amount_to_amount(pool_amount, pool_mint.decimals); - let sol_receiver = sol_receiver.unwrap_or_else(|| config.fee_payer.pubkey()); let pool_token_account = pool_token_account.unwrap_or(get_associated_token_address( &config.token_owner.pubkey(), &stake_pool.pool_mint, @@ -1450,7 +1452,7 @@ fn command_withdraw_sol( &user_transfer_authority.pubkey(), &pool_token_account, &stake_pool.reserve_stake, - &sol_receiver, + sol_receiver, &stake_pool.manager_fee_account, &stake_pool.pool_mint, &spl_token::id(), @@ -1464,7 +1466,7 @@ fn command_withdraw_sol( &user_transfer_authority.pubkey(), &pool_token_account, &stake_pool.reserve_stake, - &sol_receiver, + sol_receiver, &stake_pool.manager_fee_account, &stake_pool.pool_mint, &spl_token::id(), @@ -2011,6 +2013,15 @@ fn main() { .required(true) .help("Stake address to join the pool"), ) + .arg( + Arg::with_name("withdraw_authority") + .long("withdraw-authority") + .validator(is_keypair) + .value_name("KEYPAIR") + .takes_value(true) + .help("Withdraw authority for the stake account to be deposited. \ + Defaults to the fee payer."), + ) .arg( Arg::with_name("token_receiver") .long("token-receiver") @@ -2181,8 +2192,17 @@ fn main() { .help("Stake pool address."), ) .arg( - Arg::with_name("amount") + Arg::with_name("sol_receiver") .index(2) + .validator(is_valid_pubkey) + .value_name("SYSTEM_ACCOUNT_ADDRESS_OR_KEYPAIR") + .takes_value(true) + .required(true) + .help("System account to receive SOL from the stake pool. Defaults to the payer."), + ) + .arg( + Arg::with_name("amount") + .index(3) .validator(is_amount) .value_name("AMOUNT") .takes_value(true) @@ -2197,14 +2217,6 @@ fn main() { .takes_value(true) .help("Pool token account to withdraw tokens from. Defaults to the token-owner's associated token account."), ) - .arg( - Arg::with_name("sol_receiver") - .long("sol-receiver") - .validator(is_pubkey) - .value_name("SYSTEM_ACCOUNT_ADDRESS") - .takes_value(true) - .help("System account to receive SOL from the stake pool. Defaults to the payer."), - ) ) .subcommand(SubCommand::with_name("set-manager") .about("Change manager or fee receiver account for the stake pool. Must be signed by the current manager.") @@ -2373,12 +2385,12 @@ fn main() { .get_matches(); let mut wallet_manager = None; + let cli_config = if let Some(config_file) = matches.value_of("config_file") { + solana_cli_config::Config::load(config_file).unwrap_or_default() + } else { + solana_cli_config::Config::default() + }; let config = { - let cli_config = if let Some(config_file) = matches.value_of("config_file") { - solana_cli_config::Config::load(config_file).unwrap_or_default() - } else { - solana_cli_config::Config::default() - }; let json_rpc_url = value_t!(matches, "json_rpc_url", String) .unwrap_or_else(|_| cli_config.json_rpc_url.clone()); @@ -2387,6 +2399,9 @@ fn main() { "staker", &cli_config.keypair_path, &mut wallet_manager, + SignerFromPathConfig { + allow_null_signer: false, + }, ); let funding_authority = if matches.is_present("funding_authority") { @@ -2395,6 +2410,9 @@ fn main() { "funding_authority", &cli_config.keypair_path, &mut wallet_manager, + SignerFromPathConfig { + allow_null_signer: false, + }, )) } else { None @@ -2404,18 +2422,27 @@ fn main() { "manager", &cli_config.keypair_path, &mut wallet_manager, + SignerFromPathConfig { + allow_null_signer: false, + }, ); let token_owner = get_signer( &matches, "token_owner", &cli_config.keypair_path, &mut wallet_manager, + SignerFromPathConfig { + allow_null_signer: false, + }, ); let fee_payer = get_signer( &matches, "fee_payer", &cli_config.keypair_path, &mut wallet_manager, + SignerFromPathConfig { + allow_null_signer: false, + }, ); let verbose = matches.is_present("verbose"); let dry_run = matches.is_present("dry_run"); @@ -2523,10 +2550,20 @@ fn main() { let stake_account = pubkey_of(arg_matches, "stake_account").unwrap(); let token_receiver: Option = pubkey_of(arg_matches, "token_receiver"); let referrer: Option = pubkey_of(arg_matches, "referrer"); + let withdraw_authority = get_signer( + arg_matches, + "withdraw_authority", + &cli_config.keypair_path, + &mut wallet_manager, + SignerFromPathConfig { + allow_null_signer: false, + }, + ); command_deposit_stake( &config, &stake_pool_address, &stake_account, + withdraw_authority, &token_receiver, &referrer, ) @@ -2577,12 +2614,21 @@ fn main() { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); let pool_account = pubkey_of(arg_matches, "pool_account"); let pool_amount = value_t_or_exit!(arg_matches, "amount", f64); - let sol_receiver = pubkey_of(arg_matches, "sol_receiver"); + let sol_receiver = get_signer( + arg_matches, + "sol_receiver", + &cli_config.keypair_path, + &mut wallet_manager, + SignerFromPathConfig { + allow_null_signer: true, + }, + ) + .pubkey(); command_withdraw_sol( &config, &stake_pool_address, - &sol_receiver, &pool_account, + &sol_receiver, pool_amount, ) } From aa5f38013a7229e005ca19c499b0d5c1d78b7ecd Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 20 Oct 2021 01:29:00 +0200 Subject: [PATCH 0191/1076] stake-pool-cli: Add more docs around scripts (#2531) --- clients/cli/README.md | 21 +++++-- clients/cli/scripts/deposit-withdraw.sh | 51 +++++++++------- clients/cli/scripts/setup-local.sh | 35 ++++++----- clients/cli/scripts/setup-stake-pool.sh | 78 +++++++++++++++++-------- clients/cli/src/main.rs | 38 ++++++------ 5 files changed, 141 insertions(+), 82 deletions(-) diff --git a/clients/cli/README.md b/clients/cli/README.md index 13b1ead3..36f57c28 100644 --- a/clients/cli/README.md +++ b/clients/cli/README.md @@ -15,10 +15,11 @@ have a usable keypair, created at the default location using `solana-keygen new` Builds the stake pool program and sets up a `solana-test-validator` with some new validator vote accounts. -The only input it accepts is a number, for the number of vote accounts to create, e.g.: +It accepts the number of vote accounts to create and validator list file path to output +vote accounts, e.g.: ```bash -$ ./setup-local.sh 100 +$ ./setup-local.sh 100 validator_list.txt ``` #### Important notes on local network @@ -39,13 +40,23 @@ $ solana delegate-stake --force stake.json CzDy6uxLTko5Jjcdm46AozMmrARY6R2aDBagd Creates a new stake pool with the parameters hardcoded in the script: -* fee numerator -* fee denominator +* epoch fee numerator +* epoch fee denominator +* withdrawal fee numerator +* withdrawal fee denominator +* deposit fee numerator +* deposit fee denominator +* referral fee +* manager +* staker * maximum number of validators * list of validator vote accounts +* (Optional) deposit authority, for restricted pools + +Modify the parameters to suit your needs, and your pool will be created! ```bash -$ ./setup-stake-pool.sh 100 validator_list.txt +$ ./setup-stake-pool.sh ``` ### deposit-withdraw.sh diff --git a/clients/cli/scripts/deposit-withdraw.sh b/clients/cli/scripts/deposit-withdraw.sh index 007d7250..0781aae5 100755 --- a/clients/cli/scripts/deposit-withdraw.sh +++ b/clients/cli/scripts/deposit-withdraw.sh @@ -1,21 +1,12 @@ #!/usr/bin/env bash # Script to deposit and withdraw stakes from a pool, given stake pool public key -# and a list of validators +# and a path to a file containing a list of validator vote accounts cd "$(dirname "$0")" stake_pool_keyfile=$1 validator_list=$2 -stake_pool_pubkey=$(solana-keygen pubkey $stake_pool_keyfile) - -sol_amount=2 -half_sol_amount=1 -keys_dir=keys -spl_stake_pool=../../../target/debug/spl-stake-pool - -mkdir -p $keys_dir - create_keypair () { if test ! -f $1 then @@ -26,28 +17,31 @@ create_keypair () { create_user_stakes () { validator_list=$1 sol_amount=$2 + authority=$3 for validator in $(cat $validator_list) do create_keypair $keys_dir/stake_$validator.json - solana create-stake-account $keys_dir/stake_$validator.json $sol_amount + solana create-stake-account $keys_dir/stake_$validator.json $sol_amount --withdraw-authority $authority --stake-authority $authority done } delegate_user_stakes () { validator_list=$1 + authority=$2 for validator in $(cat $validator_list) do - solana delegate-stake --force $keys_dir/stake_$validator.json $validator + solana delegate-stake --force $keys_dir/stake_$validator.json $validator --stake-authority $authority done } deposit_stakes () { stake_pool_pubkey=$1 validator_list=$2 + authority=$3 for validator in $(cat $validator_list) do stake=$(solana-keygen pubkey $keys_dir/stake_$validator.json) - $spl_stake_pool deposit-stake $stake_pool_pubkey $stake + $spl_stake_pool deposit-stake $stake_pool_pubkey $stake --withdraw-authority $authority done } @@ -61,16 +55,29 @@ withdraw_stakes () { done } -echo "Creating user stake accounts" -create_user_stakes $validator_list $sol_amount -echo "Delegating user stakes" -delegate_user_stakes $validator_list +sol_amount=2 +half_sol_amount=1 +keys_dir=keys +spl_stake_pool=../../../target/debug/spl-stake-pool +stake_pool_pubkey=$(solana-keygen pubkey $stake_pool_keyfile) +echo "Setting up keys directory $keys_dir" +mkdir -p $keys_dir +authority=$keys_dir/authority.json +echo "Setting up authority for deposited stake accounts at $authority" +create_keypair $authority + +echo "Creating user stake accounts to deposit into the pool" +create_user_stakes $validator_list $sol_amount $authority +echo "Delegating user stakes so that deposit will work" +delegate_user_stakes $validator_list $authority echo "Waiting for stakes to activate, this may take awhile depending on the network!" -echo "If you are running on localnet with 32 slots per epoch, wait 24 seconds..." -sleep 24 +echo "If you are running on localnet with 32 slots per epoch, wait 12 seconds..." +sleep 12 echo "Depositing stakes into stake pool" -deposit_stakes $stake_pool_pubkey $validator_list +deposit_stakes $stake_pool_pubkey $validator_list $authority echo "Withdrawing stakes from stake pool" withdraw_stakes $stake_pool_pubkey $validator_list $half_sol_amount -echo "Withdrawing sol from stake pool" -$spl_stake_pool withdraw-sol $stake_pool_pubkey $half_sol_amount +echo "Depositing SOL into stake pool to authority" +$spl_stake_pool deposit-sol $stake_pool_pubkey $sol_amount +echo "Withdrawing SOL from stake pool to authority" +$spl_stake_pool withdraw-sol $stake_pool_pubkey $authority $half_sol_amount diff --git a/clients/cli/scripts/setup-local.sh b/clients/cli/scripts/setup-local.sh index a1683b7b..70e019a1 100755 --- a/clients/cli/scripts/setup-local.sh +++ b/clients/cli/scripts/setup-local.sh @@ -1,18 +1,13 @@ #!/usr/bin/env bash # Script to setup a local solana-test-validator with the stake pool program +# given a maximum number of validators and a file path to store the list of +# test validator vote accounts. cd "$(dirname "$0")" max_validators=$1 validator_list=$2 -keys_dir=keys -mkdir -p $keys_dir -if test -f $validator_list -then - rm $validator_list -fi - create_keypair () { if test ! -f $1 then @@ -20,11 +15,11 @@ create_keypair () { fi } -build_program () { +build_stake_pool_program () { cargo build-bpf --manifest-path ../../program/Cargo.toml } -setup_validator() { +setup_test_validator() { solana-test-validator --bpf-program SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy ../../../target/deploy/spl_stake_pool.so --quiet --reset --slots-per-epoch 32 & pid=$! solana config set --url http://127.0.0.1:8899 @@ -40,17 +35,27 @@ create_vote_accounts () { do create_keypair $keys_dir/identity_$number.json create_keypair $keys_dir/vote_$number.json - solana create-vote-account $keys_dir/vote_$number.json $keys_dir/identity_$number.json --commission 1 + create_keypair $keys_dir/withdrawer_$number.json + solana create-vote-account $keys_dir/vote_$number.json $keys_dir/identity_$number.json $keys_dir/withdrawer_$number.json --commission 1 vote_pubkey=$(solana-keygen pubkey $keys_dir/vote_$number.json) echo $vote_pubkey >> $validator_list done } -echo "Building on-chain program" -build_program -echo "Setting up local validator" -setup_validator +echo "Setup keys directory and clear old validator list file if found" +keys_dir=keys +mkdir -p $keys_dir +if test -f $validator_list +then + rm $validator_list +fi + +echo "Building on-chain stake pool program" +build_stake_pool_program + +echo "Setting up local test validator" +setup_test_validator -echo "Creating vote accounts" +echo "Creating vote accounts, these accounts be added to the stake pool" create_vote_accounts $max_validators $validator_list diff --git a/clients/cli/scripts/setup-stake-pool.sh b/clients/cli/scripts/setup-stake-pool.sh index 71b9844d..8e0e4994 100755 --- a/clients/cli/scripts/setup-stake-pool.sh +++ b/clients/cli/scripts/setup-stake-pool.sh @@ -3,15 +3,50 @@ # Script to setup a stake pool, add new validators from a list cd "$(dirname "$0")" -max_validators=$1 -validator_list=$2 +global_args=() +command_args=() + +################################################### +### MODIFY PARAMETERS BELOW THIS LINE FOR YOUR POOL +################################################### + +global_args+=( --manager keys/new_manager.json ) # Keypair of the manager of the stake pool +global_args+=( --staker keys/new_staker.json ) # Keypair of the staker of the stake pool + +# Epoch fee, assessed as a percentage of rewards earned by the pool every epoch, +# represented as `numerator / denominator` +command_args+=( --epoch-fee-numerator 0 ) +command_args+=( --epoch-fee-denominator 0 ) + +# Withdrawal fee for SOL and stake accounts, represented as `numerator / denominator` +command_args+=( --withdrawal-fee-numerator 0 ) +command_args+=( --withdrawal-fee-denominator 0 ) + +# Deposit fee for SOL and stake accounts, represented as `numerator / denominator` +command_args+=( --deposit-fee-numerator 0 ) +command_args+=( --deposit-fee-denominator 0 ) + +command_args+=( --referral-fee 0 ) # Percentage of deposit fee that goes towards the referrer (a number between 0 and 100, inclusive) + +command_args+=( --max-validators 3950 ) # Maximum number of validators in the stake pool, 3950 is the current maximum possible + +validator_list=validator_list.txt # File containing validator vote account addresses, each will be added to the stake pool after creation + +# (Optional) Deposit authority, required to sign all deposits into the pool. +# Setting this variable makes the pool "private" or "restricted". +# Comment it out if you want the pool to be open to all depositors. +command_args+=( --deposit-authority keys/authority.json ) + +################################################### +### MODIFY PARAMETERS ABOVE THIS LINE FOR YOUR POOL +################################################### keys_dir=keys spl_stake_pool=../../../target/debug/spl-stake-pool mkdir -p $keys_dir -build_cli () { +build_stake_pool_cli () { cargo build --manifest-path ../Cargo.toml } @@ -22,37 +57,34 @@ create_keypair () { fi } -setup_pool () { - max_validators=$1 - stake_pool_keyfile=$2 - mint_keyfile=$3 - mkdir -p $keys_dir - create_keypair $stake_pool_keyfile - create_keypair $mint_keyfile - - $spl_stake_pool create-pool --epoch-fee-numerator 3 --epoch-fee-denominator 100 \ - --withdrawal-fee-numerator 5 --withdrawal-fee-denominator 1000 \ - --max-validators $max_validators \ - --pool-keypair $stake_pool_keyfile \ - --mint-keypair $mint_keyfile -} - add_validator_stakes () { pool=$1 validator_list=$2 for validator in $(cat $validator_list) do - $spl_stake_pool add-validator $pool $validator + $spl_stake_pool "${global_args[@]}" add-validator $pool $validator done } +echo "Building stake pool CLI" +build_stake_pool_cli + +echo "Creating pool" stake_pool_keyfile=$keys_dir/stake-pool.json mint_keyfile=$keys_dir/mint.json +reserve_keyfile=$keys_dir/reserve.json +create_keypair $stake_pool_keyfile +create_keypair $mint_keyfile +create_keypair $reserve_keyfile -echo "Building CLI" -build_cli -echo "Creating pool" -setup_pool $max_validators $stake_pool_keyfile $mint_keyfile +set -ex +$spl_stake_pool \ + "${global_args[@]}" \ + create-pool \ + "${command_args[@]}" \ + --pool-keypair "$stake_pool_keyfile" \ + --mint-keypair "$mint_keyfile" \ + --reserve-keypair "$reserve_keyfile" stake_pool_pubkey=$(solana-keygen pubkey $stake_pool_keyfile) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 6fc1868c..1a0aedd6 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -9,7 +9,7 @@ use { solana_clap_utils::{ input_parsers::{keypair_of, pubkey_of}, input_validators::{ - is_amount, is_keypair, is_keypair_or_ask_keyword, is_parsable, is_pubkey, is_url, + is_amount, is_keypair_or_ask_keyword, is_parsable, is_pubkey, is_url, is_valid_percentage, is_valid_pubkey, }, keypair::{signer_from_path_with_config, SignerFromPathConfig}, @@ -180,7 +180,7 @@ fn new_stake_account( #[allow(clippy::too_many_arguments)] fn command_create_pool( config: &Config, - stake_deposit_authority: Option, + deposit_authority: Option, epoch_fee: Fee, stake_withdrawal_fee: Fee, stake_deposit_fee: Fee, @@ -312,7 +312,7 @@ fn command_create_pool( &mint_keypair.pubkey(), &pool_fee_account, &spl_token::id(), - stake_deposit_authority.as_ref().map(|x| x.pubkey()), + deposit_authority.as_ref().map(|x| x.pubkey()), epoch_fee, stake_withdrawal_fee, stake_deposit_fee, @@ -342,9 +342,13 @@ fn command_create_pool( &validator_list, config.manager.as_ref(), ]; - if let Some(stake_deposit_authority) = stake_deposit_authority { + if let Some(deposit_authority) = deposit_authority { + println!( + "Deposits will be restricted to {} only, this can be changed using the set-funding-authority command.", + deposit_authority.pubkey() + ); let mut initialize_signers = initialize_signers.clone(); - initialize_signers.push(&stake_deposit_authority); + initialize_signers.push(&deposit_authority); unique_signers!(initialize_signers); initialize_transaction.sign(&initialize_signers, recent_blockhash); } else { @@ -1672,7 +1676,7 @@ fn main() { Arg::with_name("staker") .long("staker") .value_name("KEYPAIR") - .validator(is_keypair) + .validator(is_keypair_or_ask_keyword) .takes_value(true) .help( "Specify the stake pool staker. \ @@ -1684,7 +1688,7 @@ fn main() { Arg::with_name("manager") .long("manager") .value_name("KEYPAIR") - .validator(is_keypair) + .validator(is_keypair_or_ask_keyword) .takes_value(true) .help( "Specify the stake pool manager. \ @@ -1696,7 +1700,7 @@ fn main() { Arg::with_name("funding_authority") .long("funding-authority") .value_name("KEYPAIR") - .validator(is_keypair) + .validator(is_keypair_or_ask_keyword) .takes_value(true) .help( "Specify the stake pool funding authority, for deposits or withdrawals. \ @@ -1707,7 +1711,7 @@ fn main() { Arg::with_name("token_owner") .long("token-owner") .value_name("KEYPAIR") - .validator(is_keypair) + .validator(is_keypair_or_ask_keyword) .takes_value(true) .help( "Specify the owner of the pool token account. \ @@ -1719,7 +1723,7 @@ fn main() { Arg::with_name("fee_payer") .long("fee-payer") .value_name("KEYPAIR") - .validator(is_keypair) + .validator(is_keypair_or_ask_keyword) .takes_value(true) .help( "Specify the fee-payer account. \ @@ -1802,11 +1806,11 @@ fn main() { .help("Max number of validators included in the stake pool"), ) .arg( - Arg::with_name("stake_deposit_authority") - .long("stake-deposit-authority") + Arg::with_name("deposit_authority") + .long("deposit-authority") .short("a") .validator(is_keypair_or_ask_keyword) - .value_name("STAKE_DEPOSIT_AUTHORITY_KEYPAIR") + .value_name("DEPOSIT_AUTHORITY_KEYPAIR") .takes_value(true) .help("Deposit authority required to sign all deposits into the stake pool"), ) @@ -2016,7 +2020,7 @@ fn main() { .arg( Arg::with_name("withdraw_authority") .long("withdraw-authority") - .validator(is_keypair) + .validator(is_keypair_or_ask_keyword) .value_name("KEYPAIR") .takes_value(true) .help("Withdraw authority for the stake account to be deposited. \ @@ -2232,7 +2236,7 @@ fn main() { .arg( Arg::with_name("new_manager") .long("new-manager") - .validator(is_keypair) + .validator(is_keypair_or_ask_keyword) .value_name("KEYPAIR") .takes_value(true) .help("Keypair for the new stake pool manager."), @@ -2463,7 +2467,7 @@ fn main() { let _ = match matches.subcommand() { ("create-pool", Some(arg_matches)) => { - let stake_deposit_authority = keypair_of(arg_matches, "stake_deposit_authority"); + let deposit_authority = keypair_of(arg_matches, "deposit_authority"); let e_numerator = value_t_or_exit!(arg_matches, "epoch_fee_numerator", u64); let e_denominator = value_t_or_exit!(arg_matches, "epoch_fee_denominator", u64); let w_numerator = value_t!(arg_matches, "withdrawal_fee_numerator", u64); @@ -2477,7 +2481,7 @@ fn main() { let reserve_keypair = keypair_of(arg_matches, "reserve_keypair"); command_create_pool( &config, - stake_deposit_authority, + deposit_authority, Fee { numerator: e_numerator, denominator: e_denominator, From da5794e4015572b24bb687020540a1966caec235 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 20 Oct 2021 01:45:00 +0200 Subject: [PATCH 0192/1076] stake-pool: Also set the sol deposit authority on init (#2532) --- program/src/processor.rs | 17 ++++++++++++----- program/tests/deposit.rs | 8 ++++---- program/tests/helpers/mod.rs | 2 +- program/tests/initialize.rs | 14 ++++++-------- 4 files changed, 23 insertions(+), 18 deletions(-) diff --git a/program/src/processor.rs b/program/src/processor.rs index 4f6b6079..948d2450 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -592,10 +592,17 @@ impl Processor { return Err(StakePoolError::WrongAccountMint.into()); } - let stake_deposit_authority = match next_account_info(account_info_iter) { - Ok(stake_deposit_authority_info) => *stake_deposit_authority_info.key, - Err(_) => find_deposit_authority_program_address(program_id, stake_pool_info.key).0, - }; + let (stake_deposit_authority, sol_deposit_authority) = + match next_account_info(account_info_iter) { + Ok(deposit_authority_info) => ( + *deposit_authority_info.key, + Some(*deposit_authority_info.key), + ), + Err(_) => ( + find_deposit_authority_program_address(program_id, stake_pool_info.key).0, + None, + ), + }; let (withdraw_authority_key, stake_withdraw_bump_seed) = crate::find_withdraw_authority_program_address(program_id, stake_pool_info.key); @@ -676,7 +683,7 @@ impl Processor { stake_pool.stake_withdrawal_fee = withdrawal_fee; stake_pool.next_stake_withdrawal_fee = None; stake_pool.stake_referral_fee = referral_fee; - stake_pool.sol_deposit_authority = None; + stake_pool.sol_deposit_authority = sol_deposit_authority; stake_pool.sol_deposit_fee = deposit_fee; stake_pool.sol_referral_fee = referral_fee; stake_pool.sol_withdraw_authority = None; diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 754a2a8d..0d84b64d 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -794,11 +794,11 @@ async fn fail_with_uninitialized_validator_list() {} // TODO async fn fail_with_out_of_dated_pool_balances() {} // TODO #[tokio::test] -async fn success_with_stake_deposit_authority() { +async fn success_with_deposit_authority() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_deposit_authority = Keypair::new(); let stake_pool_accounts = - StakePoolAccounts::new_with_stake_deposit_authority(stake_deposit_authority); + StakePoolAccounts::new_with_deposit_authority(stake_deposit_authority); stake_pool_accounts .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await @@ -876,11 +876,11 @@ async fn success_with_stake_deposit_authority() { } #[tokio::test] -async fn fail_without_stake_deposit_authority_signature() { +async fn fail_without_deposit_authority_signature() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_deposit_authority = Keypair::new(); let mut stake_pool_accounts = - StakePoolAccounts::new_with_stake_deposit_authority(stake_deposit_authority); + StakePoolAccounts::new_with_deposit_authority(stake_deposit_authority); stake_pool_accounts .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 54a0a82b..37bc0916 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -671,7 +671,7 @@ impl StakePoolAccounts { } } - pub fn new_with_stake_deposit_authority(stake_deposit_authority: Keypair) -> Self { + pub fn new_with_deposit_authority(stake_deposit_authority: Keypair) -> Self { let mut stake_pool_accounts = Self::new(); stake_pool_accounts.stake_deposit_authority = stake_deposit_authority.pubkey(); stake_pool_accounts.stake_deposit_authority_keypair = Some(stake_deposit_authority); diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index 7aa03f52..6fd44848 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -1275,11 +1275,11 @@ async fn fail_with_bad_reserve() { } #[tokio::test] -async fn success_with_required_stake_deposit_authority() { +async fn success_with_deposit_authority() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_deposit_authority = Keypair::new(); - let stake_pool_accounts = - StakePoolAccounts::new_with_stake_deposit_authority(stake_deposit_authority); + let deposit_authority = Keypair::new(); + let stake_pool_accounts = StakePoolAccounts::new_with_deposit_authority(deposit_authority); + let deposit_authority = stake_pool_accounts.stake_deposit_authority; stake_pool_accounts .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) .await @@ -1290,8 +1290,6 @@ async fn success_with_required_stake_deposit_authority() { get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; let stake_pool = try_from_slice_unchecked::(stake_pool_account.data.as_slice()).unwrap(); - assert_eq!( - stake_pool.stake_deposit_authority, - stake_pool_accounts.stake_deposit_authority - ); + assert_eq!(stake_pool.stake_deposit_authority, deposit_authority); + assert_eq!(stake_pool.sol_deposit_authority.unwrap(), deposit_authority); } From 7d2adc701774d16b30bd73ec188e9f358a734197 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Wed, 20 Oct 2021 22:20:12 -0700 Subject: [PATCH 0193/1076] Upgrade to Solana v1.8.1 --- clients/cli/Cargo.toml | 16 ++++++++-------- program/Cargo.toml | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 9b447417..57379f0e 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -12,14 +12,14 @@ version = "0.6.2" borsh = "0.9" clap = "2.33.3" serde_json = "1.0.68" -solana-account-decoder = "=1.8.0" -solana-clap-utils = "=1.8.0" -solana-cli-config = "=1.8.0" -solana-client = "=1.8.0" -solana-logger = "=1.8.0" -solana-program = "=1.8.0" -solana-remote-wallet = "=1.8.0" -solana-sdk = "=1.8.0" +solana-account-decoder = "=1.8.1" +solana-clap-utils = "=1.8.1" +solana-cli-config = "=1.8.1" +solana-client = "=1.8.1" +solana-logger = "=1.8.1" +solana-program = "=1.8.1" +solana-remote-wallet = "=1.8.1" +solana-sdk = "=1.8.1" spl-associated-token-account = { version = "1.0", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "0.6", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "3.2", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/program/Cargo.toml b/program/Cargo.toml index d0dc8464..5d1fbb24 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -19,7 +19,7 @@ num-traits = "0.2" num_enum = "0.5.4" serde = "1.0.130" serde_derive = "1.0.103" -solana-program = "1.8.0" +solana-program = "1.8.1" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-token = { version = "3.2", path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" @@ -27,9 +27,9 @@ bincode = "1.3.1" [dev-dependencies] proptest = "1.0" -solana-program-test = "1.8.0" -solana-sdk = "1.8.0" -solana-vote-program = "1.8.0" +solana-program-test = "1.8.1" +solana-sdk = "1.8.1" +solana-vote-program = "1.8.1" [lib] crate-type = ["cdylib", "lib"] From 6ad87c5575a97dd68bc93f855d4a96f2424d4329 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Wed, 20 Oct 2021 22:27:57 -0700 Subject: [PATCH 0194/1076] Avoid MemcmpEncodedBytes::Binary --- clients/cli/src/client.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/src/client.rs b/clients/cli/src/client.rs index 40d6cb89..8fb0aa8b 100644 --- a/clients/cli/src/client.rs +++ b/clients/cli/src/client.rs @@ -83,7 +83,7 @@ pub(crate) fn get_stake_pools( RpcProgramAccountsConfig { filters: Some(vec![RpcFilterType::Memcmp(Memcmp { offset: 0, // 0 is the account type - bytes: MemcmpEncodedBytes::Binary("2".to_string()), + bytes: MemcmpEncodedBytes::Base58("2".to_string()), encoding: None, })]), account_config: RpcAccountInfoConfig { From 92d4e2ef50da34104393bd508b0179f3ff3590fd Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Mon, 25 Oct 2021 23:13:58 +0200 Subject: [PATCH 0195/1076] stake-pool-cli: Add validator list argument to create (#2545) People want to know more about the validator list, but there isn't too much info provided. * Include the validator list as an optional parameter to pool creation * Print out the address during creation * Always print out the address during `list` * Add docs about it --- clients/cli/scripts/setup-stake-pool.sh | 3 +++ clients/cli/src/main.rs | 26 ++++++++++++++++++++----- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/clients/cli/scripts/setup-stake-pool.sh b/clients/cli/scripts/setup-stake-pool.sh index 8e0e4994..58a34fd4 100755 --- a/clients/cli/scripts/setup-stake-pool.sh +++ b/clients/cli/scripts/setup-stake-pool.sh @@ -71,9 +71,11 @@ build_stake_pool_cli echo "Creating pool" stake_pool_keyfile=$keys_dir/stake-pool.json +validator_list_keyfile=$keys_dir/validator-list.json mint_keyfile=$keys_dir/mint.json reserve_keyfile=$keys_dir/reserve.json create_keypair $stake_pool_keyfile +create_keypair $validator_list_keyfile create_keypair $mint_keyfile create_keypair $reserve_keyfile @@ -83,6 +85,7 @@ $spl_stake_pool \ create-pool \ "${command_args[@]}" \ --pool-keypair "$stake_pool_keyfile" \ + --validator-list-keypair "$validator_list_keyfile" \ --mint-keypair "$mint_keyfile" \ --reserve-keypair "$reserve_keyfile" diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 1a0aedd6..7bd12cbe 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -187,6 +187,7 @@ fn command_create_pool( stake_referral_fee: u8, max_validators: u32, stake_pool_keypair: Option, + validator_list_keypair: Option, mint_keypair: Option, reserve_keypair: Option, ) -> CommandResult { @@ -198,7 +199,7 @@ fn command_create_pool( let stake_pool_keypair = stake_pool_keypair.unwrap_or_else(Keypair::new); - let validator_list = Keypair::new(); + let validator_list_keypair = validator_list_keypair.unwrap_or_else(Keypair::new); let reserve_stake_balance = config .rpc_client @@ -288,7 +289,7 @@ fn command_create_pool( // Validator stake account list storage system_instruction::create_account( &config.fee_payer.pubkey(), - &validator_list.pubkey(), + &validator_list_keypair.pubkey(), validator_list_balance, validator_list_size as u64, &spl_stake_pool::id(), @@ -307,7 +308,7 @@ fn command_create_pool( &stake_pool_keypair.pubkey(), &config.manager.pubkey(), &config.staker.pubkey(), - &validator_list.pubkey(), + &validator_list_keypair.pubkey(), &reserve_keypair.pubkey(), &mint_keypair.pubkey(), &pool_fee_account, @@ -335,11 +336,15 @@ fn command_create_pool( setup_transaction.sign(&setup_signers, recent_blockhash); send_transaction(config, setup_transaction)?; - println!("Creating stake pool {}", stake_pool_keypair.pubkey()); + println!( + "Creating stake pool {} with validator list {}", + stake_pool_keypair.pubkey(), + validator_list_keypair.pubkey() + ); let mut initialize_signers = vec![ config.fee_payer.as_ref(), &stake_pool_keypair, - &validator_list, + &validator_list_keypair, config.manager.as_ref(), ]; if let Some(deposit_authority) = deposit_authority { @@ -874,6 +879,7 @@ fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { println!("Fee Account: {}", stake_pool.manager_fee_account); } else { println!("Stake Pool: {}", stake_pool_address); + println!("Validator List: {}", stake_pool.validator_list); println!("Pool Token Mint: {}", stake_pool.pool_mint); } @@ -1823,6 +1829,14 @@ fn main() { .takes_value(true) .help("Stake pool keypair [default: new keypair]"), ) + .arg( + Arg::with_name("validator_list_keypair") + .long("validator-list-keypair") + .validator(is_keypair_or_ask_keyword) + .value_name("PATH") + .takes_value(true) + .help("Validator list keypair [default: new keypair]"), + ) .arg( Arg::with_name("mint_keypair") .long("mint-keypair") @@ -2477,6 +2491,7 @@ fn main() { let referral_fee = value_t!(arg_matches, "referral_fee", u8); let max_validators = value_t_or_exit!(arg_matches, "max_validators", u32); let pool_keypair = keypair_of(arg_matches, "pool_keypair"); + let validator_list_keypair = keypair_of(arg_matches, "validator_list_keypair"); let mint_keypair = keypair_of(arg_matches, "mint_keypair"); let reserve_keypair = keypair_of(arg_matches, "reserve_keypair"); command_create_pool( @@ -2497,6 +2512,7 @@ fn main() { referral_fee.unwrap_or(0), max_validators, pool_keypair, + validator_list_keypair, mint_keypair, reserve_keypair, ) From b2416a17f5c60baaac7a0c626132fd8b4d0d036a Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 26 Oct 2021 22:30:16 +0200 Subject: [PATCH 0196/1076] stake-pool-docs: Add the published audits (#2546) --- README.md | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index b3d5a412..af9a5003 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,7 @@ # stake-pool program -A work-in-progress program for pooling together SOL to be staked by an off-chain -agent running SoM (Stake-o-Matic). - -Each SoM needs at least one pool. Users deposit stakes into the SoM pool -and receives a pool token minus the fee. The SoM redistributes the stakes -across the network and tries to maximize censorship resistance and rewards. - Full documentation is available at https://spl.solana.com/stake-pool +The command-line interface tool is available in the `./cli` directory. + Javascript bindings are available in the `./js` directory. From 79a561079655024e47458719171afb7f966c4bb8 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 26 Oct 2021 22:50:16 +0200 Subject: [PATCH 0197/1076] stake-pool: Add test for withdrawing all, with fee (#2550) --- program/tests/withdraw.rs | 115 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 8f368b45..d7152f10 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -1425,3 +1425,118 @@ async fn success_withdraw_all_fee_tokens() { .await; assert_eq!(fee_tokens, 0); } + +#[tokio::test] +async fn success_empty_out_stake_with_fee() { + let ( + mut banks_client, + payer, + recent_blockhash, + stake_pool_accounts, + _, + deposit_info, + user_transfer_authority, + user_stake_recipient, + tokens_to_withdraw, + ) = setup().await; + + // add another validator and deposit into it + let other_validator_stake_account = simple_add_validator_to_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + ) + .await; + + let other_deposit_info = simple_deposit_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + &other_validator_stake_account, + TEST_STAKE_AMOUNT, + ) + .await + .unwrap(); + + // move tokens to new account + transfer_spl_tokens( + &mut banks_client, + &payer, + &recent_blockhash, + &deposit_info.pool_account.pubkey(), + &other_deposit_info.pool_account.pubkey(), + &user_transfer_authority, + tokens_to_withdraw, + ) + .await; + + let user_tokens = + get_token_balance(&mut banks_client, &other_deposit_info.pool_account.pubkey()).await; + + let user_transfer_authority = Keypair::new(); + delegate_tokens( + &mut banks_client, + &payer, + &recent_blockhash, + &other_deposit_info.pool_account.pubkey(), + &other_deposit_info.authority, + &user_transfer_authority.pubkey(), + user_tokens, + ) + .await; + + // calculate exactly how much to withdraw, given the fee, to get the account + // down to 0, using an inverse fee calculation + let validator_stake_account = get_account( + &mut banks_client, + &other_validator_stake_account.stake_account, + ) + .await; + let stake_state = + deserialize::(&validator_stake_account.data).unwrap(); + let meta = stake_state.meta().unwrap(); + let lamports_to_withdraw = validator_stake_account.lamports - minimum_stake_lamports(&meta); + let stake_pool_account = + get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; + let stake_pool = + try_from_slice_unchecked::(stake_pool_account.data.as_slice()).unwrap(); + let fee = stake_pool.stake_withdrawal_fee; + let inverse_fee = state::Fee { + numerator: fee.denominator - fee.numerator, + denominator: fee.denominator, + }; + let pool_tokens_to_withdraw = + lamports_to_withdraw * inverse_fee.denominator / inverse_fee.numerator; + + let new_authority = Pubkey::new_unique(); + let error = stake_pool_accounts + .withdraw_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake_recipient.pubkey(), + &user_transfer_authority, + &other_deposit_info.pool_account.pubkey(), + &other_validator_stake_account.stake_account, + &new_authority, + pool_tokens_to_withdraw, + ) + .await; + assert!(error.is_none()); + + // Check balance of validator stake account is MINIMUM + rent-exemption + let validator_stake_account = get_account( + &mut banks_client, + &other_validator_stake_account.stake_account, + ) + .await; + let stake_state = + deserialize::(&validator_stake_account.data).unwrap(); + let meta = stake_state.meta().unwrap(); + assert_eq!( + validator_stake_account.lamports, + minimum_stake_lamports(&meta) + ); +} From 6cf485d11f5b14831e25f3ab0e388a6a7ad57765 Mon Sep 17 00:00:00 2001 From: Alexander Ray Date: Tue, 26 Oct 2021 23:13:59 +0200 Subject: [PATCH 0198/1076] stake-pool-cli: Fix prepare_withdraw_accounts issues (#2548) * - fix prepare_withdraw_accounts issues * - use reverse fee as workaround for withdraw issue --- clients/cli/src/main.rs | 44 +++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 7bd12cbe..6a690380 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -1079,21 +1079,15 @@ struct WithdrawAccount { fn sorted_accounts( validator_list: &ValidatorList, stake_pool: &StakePool, - get_pubkey: F, + get_info: F, ) -> Vec<(Pubkey, u64, Option)> where - F: Fn(&ValidatorStakeInfo) -> Pubkey, + F: Fn(&ValidatorStakeInfo) -> (Pubkey, u64, Option), { let mut result: Vec<(Pubkey, u64, Option)> = validator_list .validators .iter() - .map(|validator| { - ( - get_pubkey(validator), - validator.active_stake_lamports, - Some(validator.vote_account_address), - ) - }) + .map(get_info) .collect::>(); result.sort_by(|left, right| { @@ -1114,12 +1108,12 @@ fn prepare_withdraw_accounts( stake_pool: &StakePool, pool_amount: u64, stake_pool_address: &Pubkey, + skip_fee: bool, ) -> Result, Error> { let min_balance = rpc_client .get_minimum_balance_for_rent_exemption(STAKE_STATE_LEN)? .saturating_add(MINIMUM_ACTIVE_STAKE); let pool_mint = get_token_mint(rpc_client, &stake_pool.pool_mint)?; - let validator_list: ValidatorList = get_validator_list(rpc_client, &stake_pool.validator_list)?; let mut accounts: Vec<(Pubkey, u64, Option)> = Vec::new(); @@ -1134,7 +1128,11 @@ fn prepare_withdraw_accounts( stake_pool_address, ); - stake_account_address + ( + stake_account_address, + validator.active_stake_lamports, + Some(validator.vote_account_address), + ) }, )); @@ -1149,7 +1147,11 @@ fn prepare_withdraw_accounts( validator.transient_seed_suffix_start, ); - transient_stake_account_address + ( + transient_stake_account_address, + validator.transient_stake_lamports, + Some(validator.vote_account_address), + ) }, )); @@ -1161,15 +1163,26 @@ fn prepare_withdraw_accounts( let mut withdraw_from: Vec = vec![]; let mut remaining_amount = pool_amount; + let fee = stake_pool.stake_withdrawal_fee; + let inverse_fee = Fee { + numerator: fee.denominator - fee.numerator, + denominator: fee.denominator, + }; + // Go through available accounts and withdraw from largest to smallest for (stake_address, lamports, vote_address_opt) in accounts { if lamports <= min_balance { continue; } - let available_for_withdrawal = stake_pool - .calc_lamports_withdraw_amount(lamports.saturating_sub(min_balance)) - .unwrap(); + let available_for_withdrawal_wo_fee = + stake_pool.calc_pool_tokens_for_deposit(lamports).unwrap(); + + let available_for_withdrawal = if skip_fee { + available_for_withdrawal_wo_fee + } else { + available_for_withdrawal_wo_fee * inverse_fee.denominator / inverse_fee.numerator + }; let pool_amount = u64::min(available_for_withdrawal, remaining_amount); @@ -1283,6 +1296,7 @@ fn command_withdraw_stake( &stake_pool, pool_amount, stake_pool_address, + stake_pool.manager_fee_account == pool_token_account, )? }; From 2690fac54ef7bc3ae2a093cc76581acff41d1e81 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Mon, 1 Nov 2021 15:14:49 +0100 Subject: [PATCH 0199/1076] stake-pool: Reduce wait for active stake merges (#2553) * stake-pool: Reduce wait to one epoch for active merges * Remove stake_program references * Remove credits observed point from docs --- program/src/lib.rs | 1 - program/src/processor.rs | 8 +- program/src/stake_program.rs | 77 ------------------- program/src/state.rs | 3 +- program/tests/deposit.rs | 2 +- program/tests/huge_pool.rs | 3 +- program/tests/set_epoch_fee.rs | 6 +- program/tests/set_withdrawal_fee.rs | 6 +- program/tests/update_stake_pool_balance.rs | 12 ++- .../tests/update_validator_list_balance.rs | 2 +- program/tests/vsa_remove.rs | 7 +- 11 files changed, 33 insertions(+), 94 deletions(-) delete mode 100644 program/src/stake_program.rs diff --git a/program/src/lib.rs b/program/src/lib.rs index d8a53453..3c726fa3 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -6,7 +6,6 @@ pub mod big_vec; pub mod error; pub mod instruction; pub mod processor; -pub mod stake_program; pub mod state; #[cfg(not(feature = "no-entrypoint"))] diff --git a/program/src/processor.rs b/program/src/processor.rs index 948d2450..29ed14eb 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -5,7 +5,7 @@ use { error::StakePoolError, find_deposit_authority_program_address, instruction::{FundingType, PreferredValidatorType, StakePoolInstruction}, - minimum_reserve_lamports, minimum_stake_lamports, stake_program, + minimum_reserve_lamports, minimum_stake_lamports, state::{ AccountType, Fee, FeeType, StakePool, StakeStatus, ValidatorList, ValidatorListHeader, ValidatorStakeInfo, @@ -674,7 +674,7 @@ impl Processor { stake_pool.total_lamports = total_lamports; stake_pool.pool_token_supply = 0; stake_pool.last_update_epoch = Clock::get()?.epoch; - stake_pool.lockup = stake_program::Lockup::default(); + stake_pool.lockup = stake::state::Lockup::default(); stake_pool.epoch_fee = epoch_fee; stake_pool.next_epoch_fee = None; stake_pool.preferred_deposit_validator_vote_address = None; @@ -1530,9 +1530,7 @@ impl Processor { if let Some(stake::state::StakeState::Stake(_, validator_stake)) = validator_stake_state { - if stake_program::active_stakes_can_merge(&stake, &validator_stake) - .is_ok() - { + if validator_stake.delegation.activation_epoch < clock.epoch { let additional_lamports = transient_stake_info .lamports() .saturating_sub(stake.delegation.stake); diff --git a/program/src/stake_program.rs b/program/src/stake_program.rs deleted file mode 100644 index 093f2cdf..00000000 --- a/program/src/stake_program.rs +++ /dev/null @@ -1,77 +0,0 @@ -//! FIXME copied from the solana stake program - -use { - borsh::{BorshDeserialize, BorshSchema, BorshSerialize}, - serde_derive::{Deserialize, Serialize}, - solana_program::{ - clock::{Epoch, UnixTimestamp}, - msg, - program_error::ProgramError, - pubkey::Pubkey, - stake, - }, -}; - -/// FIXME copied from the stake program, once https://github.com/solana-labs/solana/pull/20784 -/// lands this can be removed -#[derive( - BorshSerialize, - BorshDeserialize, - BorshSchema, - Default, - Debug, - Serialize, - Deserialize, - PartialEq, - Clone, - Copy, -)] -pub struct Lockup { - /// UnixTimestamp at which this stake will allow withdrawal, unless the - /// transaction is signed by the custodian - pub unix_timestamp: UnixTimestamp, - /// epoch height at which this stake will allow withdrawal, unless the - /// transaction is signed by the custodian - pub epoch: Epoch, - /// custodian signature on a transaction exempts the operation from - /// lockup constraints - pub custodian: Pubkey, -} - -/// FIXME copied from stake program -/// Checks if two active delegations are mergeable, required since we cannot recover -/// from a CPI error. -pub fn active_delegations_can_merge( - stake: &stake::state::Delegation, - source: &stake::state::Delegation, -) -> Result<(), ProgramError> { - if stake.voter_pubkey != source.voter_pubkey { - msg!("Unable to merge due to voter mismatch"); - Err(ProgramError::InvalidAccountData) - } else if (stake.warmup_cooldown_rate - source.warmup_cooldown_rate).abs() < f64::EPSILON - && stake.deactivation_epoch == Epoch::MAX - && source.deactivation_epoch == Epoch::MAX - { - Ok(()) - } else { - msg!("Unable to merge due to stake deactivation"); - Err(ProgramError::InvalidAccountData) - } -} - -/// FIXME copied from stake program -/// Checks if two active stakes are mergeable, required since we cannot recover -/// from a CPI error. -pub fn active_stakes_can_merge( - stake: &stake::state::Stake, - source: &stake::state::Stake, -) -> Result<(), ProgramError> { - active_delegations_can_merge(&stake.delegation, &source.delegation)?; - - if stake.credits_observed == source.credits_observed { - Ok(()) - } else { - msg!("Unable to merge due to credits observed mismatch"); - Err(ProgramError::InvalidAccountData) - } -} diff --git a/program/src/state.rs b/program/src/state.rs index 792e18cc..bcbf6f8c 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -3,7 +3,7 @@ use spl_token::state::{Account, AccountState}; use { crate::{ - big_vec::BigVec, error::StakePoolError, stake_program::Lockup, MAX_WITHDRAWAL_FEE_INCREASE, + big_vec::BigVec, error::StakePoolError, MAX_WITHDRAWAL_FEE_INCREASE, WITHDRAWAL_BASELINE_FEE, }, borsh::{BorshDeserialize, BorshSchema, BorshSerialize}, @@ -17,6 +17,7 @@ use { program_memory::sol_memcmp, program_pack::{Pack, Sealed}, pubkey::{Pubkey, PUBKEY_BYTES}, + stake::state::Lockup, }, spl_math::checked_ceil_div::CheckedCeilDiv, std::{convert::TryFrom, fmt, matches}, diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 0d84b64d..0b7eda1e 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -89,7 +89,7 @@ async fn setup() -> ( ) .await; - slot += 2 * slots_per_epoch; + slot += slots_per_epoch; context.warp_to_slot(slot).unwrap(); stake_pool_accounts .update_all( diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index 48b7e741..d85f362a 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -24,7 +24,6 @@ use { find_stake_program_address, find_transient_stake_program_address, find_withdraw_authority_program_address, id, instruction::{self, PreferredValidatorType}, - stake_program, state::{AccountType, Fee, StakePool, StakeStatus, ValidatorList, ValidatorStakeInfo}, MAX_VALIDATORS_TO_UPDATE, MINIMUM_ACTIVE_STAKE, }, @@ -72,7 +71,7 @@ async fn setup( total_lamports: 0, pool_token_supply: 0, last_update_epoch: 0, - lockup: stake_program::Lockup::default(), + lockup: stake::state::Lockup::default(), epoch_fee: stake_pool_accounts.epoch_fee, next_epoch_fee: None, preferred_deposit_validator_vote_address: None, diff --git a/program/tests/set_epoch_fee.rs b/program/tests/set_epoch_fee.rs index 8eb87366..95d3a46c 100644 --- a/program/tests/set_epoch_fee.rs +++ b/program/tests/set_epoch_fee.rs @@ -190,7 +190,11 @@ async fn fail_not_updated() { }; // move forward so an update is required - context.warp_to_slot(50_000).unwrap(); + let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + context + .warp_to_slot(first_normal_slot + slots_per_epoch) + .unwrap(); let transaction = Transaction::new_signed_with_payer( &[instruction::set_fee( diff --git a/program/tests/set_withdrawal_fee.rs b/program/tests/set_withdrawal_fee.rs index 5fb475e0..10438662 100644 --- a/program/tests/set_withdrawal_fee.rs +++ b/program/tests/set_withdrawal_fee.rs @@ -633,7 +633,11 @@ async fn fail_not_updated() { }; // move forward so an update is required - context.warp_to_slot(50_000).unwrap(); + let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + context + .warp_to_slot(first_normal_slot + slots_per_epoch) + .unwrap(); let transaction = Transaction::new_signed_with_payer( &[instruction::set_fee( diff --git a/program/tests/update_stake_pool_balance.rs b/program/tests/update_stake_pool_balance.rs index 9bbb558f..aa031690 100644 --- a/program/tests/update_stake_pool_balance.rs +++ b/program/tests/update_stake_pool_balance.rs @@ -107,7 +107,11 @@ async fn success() { } // Update epoch - context.warp_to_slot(50_000).unwrap(); + let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + context + .warp_to_slot(first_normal_slot + slots_per_epoch) + .unwrap(); // Update list and pool let error = stake_pool_accounts @@ -213,7 +217,11 @@ async fn success_ignoring_extra_lamports() { } // Update epoch - context.warp_to_slot(50_000).unwrap(); + let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + context + .warp_to_slot(first_normal_slot + slots_per_epoch) + .unwrap(); // Update list and pool let error = stake_pool_accounts diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index 7c8c270a..44cb093e 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -92,7 +92,7 @@ async fn setup( } // Warp forward so the stakes properly activate, and deposit - slot += 2 * slots_per_epoch; + slot += slots_per_epoch; context.warp_to_slot(slot).unwrap(); stake_pool_accounts diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index acbb0d88..560da5da 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -696,8 +696,10 @@ async fn success_with_hijacked_transient_account() { assert!(error.is_none()); // warp forward to merge + let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; - context.warp_to_slot(slots_per_epoch * 2).unwrap(); + let mut slot = first_normal_slot + slots_per_epoch; + context.warp_to_slot(slot).unwrap(); stake_pool_accounts .update_all( &mut context.banks_client, @@ -723,7 +725,8 @@ async fn success_with_hijacked_transient_account() { assert!(error.is_none()); // warp forward to merge - context.warp_to_slot(slots_per_epoch * 4).unwrap(); + slot += slots_per_epoch; + context.warp_to_slot(slot).unwrap(); // hijack let validator_list = stake_pool_accounts From 5a641480d0f6e511df117a17f73acef5a3d3e12b Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 2 Nov 2021 22:15:33 +0100 Subject: [PATCH 0200/1076] stake-pool: Bump CLI and program version to 0.6.3 (#2555) --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 57379f0e..2733d8fb 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -6,7 +6,7 @@ homepage = "https://spl.solana.com/stake-pool" license = "Apache-2.0" name = "spl-stake-pool-cli" repository = "https://github.com/solana-labs/solana-program-library" -version = "0.6.2" +version = "0.6.3" [dependencies] borsh = "0.9" diff --git a/program/Cargo.toml b/program/Cargo.toml index 5d1fbb24..67cb93f3 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "spl-stake-pool" -version = "0.6.1" +version = "0.6.3" description = "Solana Program Library Stake Pool" authors = ["Solana Maintainers "] repository = "https://github.com/solana-labs/solana-program-library" From 5d7b4f8ee534a4599d4985433d44342d7ec5837a Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Sat, 6 Nov 2021 13:48:11 +0100 Subject: [PATCH 0201/1076] stake-pool-docs: Rearrange docs, add quickstart guide (#2561) * stake-pool-docs: Rearrange docs, add quickstart guide * Rearrange doc sidebar --- clients/cli/README.md | 68 +---------------- clients/cli/scripts/add-validators.sh | 25 +++++++ clients/cli/scripts/deposit-withdraw.sh | 83 --------------------- clients/cli/scripts/deposit.sh | 73 ++++++++++++++++++ clients/cli/scripts/rebalance.sh | 27 +++++++ clients/cli/scripts/setup-local.sh | 61 --------------- clients/cli/scripts/setup-stake-pool.sh | 45 +++-------- clients/cli/scripts/setup-test-validator.sh | 56 ++++++++++++++ clients/cli/scripts/withdraw.sh | 44 +++++++++++ 9 files changed, 238 insertions(+), 244 deletions(-) create mode 100755 clients/cli/scripts/add-validators.sh delete mode 100755 clients/cli/scripts/deposit-withdraw.sh create mode 100755 clients/cli/scripts/deposit.sh create mode 100755 clients/cli/scripts/rebalance.sh delete mode 100755 clients/cli/scripts/setup-local.sh create mode 100755 clients/cli/scripts/setup-test-validator.sh create mode 100755 clients/cli/scripts/withdraw.sh diff --git a/clients/cli/README.md b/clients/cli/README.md index 36f57c28..b3ed9f3f 100644 --- a/clients/cli/README.md +++ b/clients/cli/README.md @@ -2,68 +2,6 @@ A basic command-line for creating and using SPL Stake Pools. See https://spl.solana.com/stake-pool for more details. -## Scripts for setting up a stake pool - -Under `./scripts`, this repo also contains some bash scripts that are useful for -setting up your own stake pool. These scripts require the Solana CLI tool suite, -which can be downloaded by following the instructions at -(https://docs.solana.com/cli/install-solana-cli-tools). Additionally, you must -have a usable keypair, created at the default location using `solana-keygen new`. - -### setup-local.sh - -Builds the stake pool program and sets up a `solana-test-validator` with some -new validator vote accounts. - -It accepts the number of vote accounts to create and validator list file path to output -vote accounts, e.g.: - -```bash -$ ./setup-local.sh 100 validator_list.txt -``` - -#### Important notes on local network - -If you are using epochs of 32 slots, there is a good chance -that you will pass an epoch while using one of the stake pool commands, causing -it to fail with: `Custom program error: 0x11`. This is totally normal, and will -not happen on a normal network. - -Since there is no voting activity on the test validator network, you will -need to use the `--force` flag with `solana delegate-stake`, ie: - -```bash -$ solana delegate-stake --force stake.json CzDy6uxLTko5Jjcdm46AozMmrARY6R2aDBagdemiBuiT -``` - -### setup-stake-pool.sh - -Creates a new stake pool with the parameters hardcoded in the script: - -* epoch fee numerator -* epoch fee denominator -* withdrawal fee numerator -* withdrawal fee denominator -* deposit fee numerator -* deposit fee denominator -* referral fee -* manager -* staker -* maximum number of validators -* list of validator vote accounts -* (Optional) deposit authority, for restricted pools - -Modify the parameters to suit your needs, and your pool will be created! - -```bash -$ ./setup-stake-pool.sh -``` - -### deposit-withdraw.sh - -Creates new stakes to deposit into each of the stake accounts in the pool, given -the stake pool, mint, and validator list. - -```bash -$ ./deposit-withdraw.sh keys/stake-pool.json validator_list.txt -``` +Under `./scripts`, there are helpful Bash scripts for setting up and running a +stake pool. More information at the +[stake pool quick start guide](https://spl.solana.com/stake-pool/quickstart). diff --git a/clients/cli/scripts/add-validators.sh b/clients/cli/scripts/add-validators.sh new file mode 100755 index 00000000..4bdcbdf1 --- /dev/null +++ b/clients/cli/scripts/add-validators.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +# Script to add new validators to a stake pool, given the stake pool keyfile and +# a file listing validator vote account pubkeys + +cd "$(dirname "$0")" || exit +stake_pool_keyfile=$1 +validator_list=$2 # File containing validator vote account addresses, each will be added to the stake pool after creation + +add_validator_stakes () { + stake_pool=$1 + validator_list=$2 + while read -r validator + do + $spl_stake_pool add-validator "$stake_pool" "$validator" + done < "$validator_list" +} + +spl_stake_pool=spl-stake-pool +# Uncomment to use a local build +#spl_stake_pool=../../../target/debug/spl-stake-pool + +stake_pool_pubkey=$(solana-keygen pubkey "$stake_pool_keyfile") +echo "Adding validator stake accounts to the pool" +add_validator_stakes "$stake_pool_pubkey" "$validator_list" diff --git a/clients/cli/scripts/deposit-withdraw.sh b/clients/cli/scripts/deposit-withdraw.sh deleted file mode 100755 index 0781aae5..00000000 --- a/clients/cli/scripts/deposit-withdraw.sh +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/env bash - -# Script to deposit and withdraw stakes from a pool, given stake pool public key -# and a path to a file containing a list of validator vote accounts - -cd "$(dirname "$0")" -stake_pool_keyfile=$1 -validator_list=$2 - -create_keypair () { - if test ! -f $1 - then - solana-keygen new --no-passphrase -s -o $1 - fi -} - -create_user_stakes () { - validator_list=$1 - sol_amount=$2 - authority=$3 - for validator in $(cat $validator_list) - do - create_keypair $keys_dir/stake_$validator.json - solana create-stake-account $keys_dir/stake_$validator.json $sol_amount --withdraw-authority $authority --stake-authority $authority - done -} - -delegate_user_stakes () { - validator_list=$1 - authority=$2 - for validator in $(cat $validator_list) - do - solana delegate-stake --force $keys_dir/stake_$validator.json $validator --stake-authority $authority - done -} - -deposit_stakes () { - stake_pool_pubkey=$1 - validator_list=$2 - authority=$3 - for validator in $(cat $validator_list) - do - stake=$(solana-keygen pubkey $keys_dir/stake_$validator.json) - $spl_stake_pool deposit-stake $stake_pool_pubkey $stake --withdraw-authority $authority - done -} - -withdraw_stakes () { - stake_pool_pubkey=$1 - validator_list=$2 - pool_amount=$3 - for validator in $(cat $validator_list) - do - $spl_stake_pool withdraw-stake $stake_pool_pubkey $pool_amount --vote-account $validator - done -} - -sol_amount=2 -half_sol_amount=1 -keys_dir=keys -spl_stake_pool=../../../target/debug/spl-stake-pool -stake_pool_pubkey=$(solana-keygen pubkey $stake_pool_keyfile) -echo "Setting up keys directory $keys_dir" -mkdir -p $keys_dir -authority=$keys_dir/authority.json -echo "Setting up authority for deposited stake accounts at $authority" -create_keypair $authority - -echo "Creating user stake accounts to deposit into the pool" -create_user_stakes $validator_list $sol_amount $authority -echo "Delegating user stakes so that deposit will work" -delegate_user_stakes $validator_list $authority -echo "Waiting for stakes to activate, this may take awhile depending on the network!" -echo "If you are running on localnet with 32 slots per epoch, wait 12 seconds..." -sleep 12 -echo "Depositing stakes into stake pool" -deposit_stakes $stake_pool_pubkey $validator_list $authority -echo "Withdrawing stakes from stake pool" -withdraw_stakes $stake_pool_pubkey $validator_list $half_sol_amount -echo "Depositing SOL into stake pool to authority" -$spl_stake_pool deposit-sol $stake_pool_pubkey $sol_amount -echo "Withdrawing SOL from stake pool to authority" -$spl_stake_pool withdraw-sol $stake_pool_pubkey $authority $half_sol_amount diff --git a/clients/cli/scripts/deposit.sh b/clients/cli/scripts/deposit.sh new file mode 100755 index 00000000..9f316f35 --- /dev/null +++ b/clients/cli/scripts/deposit.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash + +# Script to deposit stakes and SOL into a stake pool, given the stake pool keyfile +# and a path to a file containing a list of validator vote accounts + +cd "$(dirname "$0")" || exit +stake_pool_keyfile=$1 +validator_list=$2 +sol_amount=$3 + +create_keypair () { + if test ! -f "$1" + then + solana-keygen new --no-passphrase -s -o "$1" + fi +} + +create_user_stakes () { + validator_list=$1 + sol_amount=$2 + authority=$3 + while read -r validator + do + create_keypair "$keys_dir/stake_$validator".json + solana create-stake-account "$keys_dir/stake_$validator.json" "$sol_amount" --withdraw-authority "$authority" --stake-authority "$authority" + done < "$validator_list" +} + +delegate_user_stakes () { + validator_list=$1 + authority=$2 + while read -r validator + do + solana delegate-stake --force "$keys_dir/stake_$validator.json" "$validator" --stake-authority "$authority" + done < "$validator_list" +} + +deposit_stakes () { + stake_pool_pubkey=$1 + validator_list=$2 + authority=$3 + while read -r validator + do + stake=$(solana-keygen pubkey "$keys_dir/stake_$validator.json") + $spl_stake_pool deposit-stake "$stake_pool_pubkey" "$stake" --withdraw-authority "$authority" + done < "$validator_list" +} + +keys_dir=keys +stake_pool_pubkey=$(solana-keygen pubkey "$stake_pool_keyfile") + +spl_stake_pool=spl-stake-pool +# Uncomment to use a locally build CLI +#spl_stake_pool=../../../target/debug/spl-stake-pool + +echo "Setting up keys directory $keys_dir" +mkdir -p $keys_dir +authority=$keys_dir/authority.json +echo "Setting up authority for deposited stake accounts at $authority" +create_keypair $authority + +echo "Creating user stake accounts to deposit into the pool" +create_user_stakes "$validator_list" "$sol_amount" $authority +echo "Delegating user stakes so that deposit will work" +delegate_user_stakes "$validator_list" $authority + +echo "Waiting for stakes to activate, this may take awhile depending on the network!" +echo "If you are running on localnet with 32 slots per epoch, wait 12 seconds..." +sleep 12 +echo "Depositing stakes into stake pool" +deposit_stakes "$stake_pool_pubkey" "$validator_list" $authority +echo "Depositing SOL into stake pool" +$spl_stake_pool deposit-sol "$stake_pool_pubkey" "$sol_amount" diff --git a/clients/cli/scripts/rebalance.sh b/clients/cli/scripts/rebalance.sh new file mode 100755 index 00000000..3db44972 --- /dev/null +++ b/clients/cli/scripts/rebalance.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +# Script to add a certain amount of SOL into a stake pool, given the stake pool +# keyfile and a path to a file containing a list of validator vote accounts + +cd "$(dirname "$0")" || exit +stake_pool_keyfile=$1 +validator_list=$2 +sol_amount=$3 + +spl_stake_pool=spl-stake-pool +# Uncomment to use a locally build CLI +#spl_stake_pool=../../../target/debug/spl-stake-pool + +increase_stakes () { + stake_pool_pubkey=$1 + validator_list=$2 + sol_amount=$3 + while read -r validator + do + $spl_stake_pool increase-validator-stake "$stake_pool_pubkey" "$validator" "$sol_amount" + done < "$validator_list" +} + +stake_pool_pubkey=$(solana-keygen pubkey "$stake_pool_keyfile") +echo "Increasing amount delegated to each validator in stake pool" +increase_stakes "$stake_pool_pubkey" "$validator_list" "$sol_amount" diff --git a/clients/cli/scripts/setup-local.sh b/clients/cli/scripts/setup-local.sh deleted file mode 100755 index 70e019a1..00000000 --- a/clients/cli/scripts/setup-local.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env bash - -# Script to setup a local solana-test-validator with the stake pool program -# given a maximum number of validators and a file path to store the list of -# test validator vote accounts. - -cd "$(dirname "$0")" -max_validators=$1 -validator_list=$2 - -create_keypair () { - if test ! -f $1 - then - solana-keygen new --no-passphrase -s -o $1 - fi -} - -build_stake_pool_program () { - cargo build-bpf --manifest-path ../../program/Cargo.toml -} - -setup_test_validator() { - solana-test-validator --bpf-program SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy ../../../target/deploy/spl_stake_pool.so --quiet --reset --slots-per-epoch 32 & - pid=$! - solana config set --url http://127.0.0.1:8899 - solana config set --commitment confirmed - echo "waiting for solana-test-validator, pid: $pid" - sleep 5 -} - -create_vote_accounts () { - max_validators=$1 - validator_list=$2 - for number in $(seq 1 $max_validators) - do - create_keypair $keys_dir/identity_$number.json - create_keypair $keys_dir/vote_$number.json - create_keypair $keys_dir/withdrawer_$number.json - solana create-vote-account $keys_dir/vote_$number.json $keys_dir/identity_$number.json $keys_dir/withdrawer_$number.json --commission 1 - vote_pubkey=$(solana-keygen pubkey $keys_dir/vote_$number.json) - echo $vote_pubkey >> $validator_list - done -} - - -echo "Setup keys directory and clear old validator list file if found" -keys_dir=keys -mkdir -p $keys_dir -if test -f $validator_list -then - rm $validator_list -fi - -echo "Building on-chain stake pool program" -build_stake_pool_program - -echo "Setting up local test validator" -setup_test_validator - -echo "Creating vote accounts, these accounts be added to the stake pool" -create_vote_accounts $max_validators $validator_list diff --git a/clients/cli/scripts/setup-stake-pool.sh b/clients/cli/scripts/setup-stake-pool.sh index 58a34fd4..e9bb2baf 100755 --- a/clients/cli/scripts/setup-stake-pool.sh +++ b/clients/cli/scripts/setup-stake-pool.sh @@ -1,18 +1,15 @@ #!/usr/bin/env bash -# Script to setup a stake pool, add new validators from a list +# Script to setup a stake pool from scratch. Please modify the parameters to +# create a stake pool to your liking! -cd "$(dirname "$0")" -global_args=() +cd "$(dirname "$0")" || exit command_args=() ################################################### ### MODIFY PARAMETERS BELOW THIS LINE FOR YOUR POOL ################################################### -global_args+=( --manager keys/new_manager.json ) # Keypair of the manager of the stake pool -global_args+=( --staker keys/new_staker.json ) # Keypair of the staker of the stake pool - # Epoch fee, assessed as a percentage of rewards earned by the pool every epoch, # represented as `numerator / denominator` command_args+=( --epoch-fee-numerator 0 ) @@ -30,45 +27,29 @@ command_args+=( --referral-fee 0 ) # Percentage of deposit fee that goes towards command_args+=( --max-validators 3950 ) # Maximum number of validators in the stake pool, 3950 is the current maximum possible -validator_list=validator_list.txt # File containing validator vote account addresses, each will be added to the stake pool after creation - # (Optional) Deposit authority, required to sign all deposits into the pool. # Setting this variable makes the pool "private" or "restricted". -# Comment it out if you want the pool to be open to all depositors. -command_args+=( --deposit-authority keys/authority.json ) +# Uncomment and set to a valid keypair if you want the pool to be restricted. +#command_args+=( --deposit-authority keys/authority.json ) ################################################### ### MODIFY PARAMETERS ABOVE THIS LINE FOR YOUR POOL ################################################### keys_dir=keys -spl_stake_pool=../../../target/debug/spl-stake-pool +spl_stake_pool=spl-stake-pool +# Uncomment to use a local build +#spl_stake_pool=../../../target/debug/spl-stake-pool mkdir -p $keys_dir -build_stake_pool_cli () { - cargo build --manifest-path ../Cargo.toml -} - create_keypair () { - if test ! -f $1 + if test ! -f "$1" then - solana-keygen new --no-passphrase -s -o $1 + solana-keygen new --no-passphrase -s -o "$1" fi } -add_validator_stakes () { - pool=$1 - validator_list=$2 - for validator in $(cat $validator_list) - do - $spl_stake_pool "${global_args[@]}" add-validator $pool $validator - done -} - -echo "Building stake pool CLI" -build_stake_pool_cli - echo "Creating pool" stake_pool_keyfile=$keys_dir/stake-pool.json validator_list_keyfile=$keys_dir/validator-list.json @@ -81,15 +62,9 @@ create_keypair $reserve_keyfile set -ex $spl_stake_pool \ - "${global_args[@]}" \ create-pool \ "${command_args[@]}" \ --pool-keypair "$stake_pool_keyfile" \ --validator-list-keypair "$validator_list_keyfile" \ --mint-keypair "$mint_keyfile" \ --reserve-keypair "$reserve_keyfile" - -stake_pool_pubkey=$(solana-keygen pubkey $stake_pool_keyfile) - -echo "Adding validator stake accounts to the pool" -add_validator_stakes $stake_pool_pubkey $validator_list diff --git a/clients/cli/scripts/setup-test-validator.sh b/clients/cli/scripts/setup-test-validator.sh new file mode 100755 index 00000000..5fd803dd --- /dev/null +++ b/clients/cli/scripts/setup-test-validator.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash + +# Script to setup a local solana-test-validator with the stake pool program +# given a maximum number of validators and a file path to store the list of +# test validator vote accounts. + +cd "$(dirname "$0")" || exit +max_validators=$1 +validator_file=$2 + +create_keypair () { + if test ! -f "$1" + then + solana-keygen new --no-passphrase -s -o "$1" + fi +} + +setup_test_validator() { + solana-test-validator -c SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy -c EmiU8AQkB2sswTxVB6aCmsAJftoowZGGDXuytm6X65R3 --url devnet --slots-per-epoch 32 --quiet --reset & + pid=$! + solana config set --url http://127.0.0.1:8899 + solana config set --commitment confirmed + echo "waiting for solana-test-validator, pid: $pid" + sleep 5 +} + +create_vote_accounts () { + max_validators=$1 + validator_file=$2 + for number in $(seq 1 "$max_validators") + do + create_keypair "$keys_dir/identity_$number.json" + create_keypair "$keys_dir/vote_$number.json" + create_keypair "$keys_dir/withdrawer_$number.json" + solana create-vote-account "$keys_dir/vote_$number.json" "$keys_dir/identity_$number.json" "$keys_dir/withdrawer_$number.json" --commission 1 + vote_pubkey=$(solana-keygen pubkey "$keys_dir/vote_$number.json") + echo "$vote_pubkey" >> "$validator_file" + done +} + + +echo "Setup keys directory and clear old validator list file if found" +keys_dir=keys +mkdir -p $keys_dir +if test -f "$validator_file" +then + rm "$validator_file" +fi + +echo "Setting up local test validator" +setup_test_validator + +echo "Creating vote accounts, these accounts be added to the stake pool" +create_vote_accounts "$max_validators" "$validator_file" + +echo "Done adding $max_validators validator vote accounts, their pubkeys can be found in $validator_file" diff --git a/clients/cli/scripts/withdraw.sh b/clients/cli/scripts/withdraw.sh new file mode 100755 index 00000000..deeee7a0 --- /dev/null +++ b/clients/cli/scripts/withdraw.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash + +# Script to withdraw stakes and SOL from a stake pool, given the stake pool public key +# and a path to a file containing a list of validator vote accounts + +cd "$(dirname "$0")" || exit +stake_pool_keyfile=$1 +validator_list=$2 +withdraw_sol_amount=$3 + +create_keypair () { + if test ! -f "$1" + then + solana-keygen new --no-passphrase -s -o "$1" + fi +} + +withdraw_stakes () { + stake_pool_pubkey=$1 + validator_list=$2 + pool_amount=$3 + while read -r validator + do + $spl_stake_pool withdraw-stake "$stake_pool_pubkey" "$pool_amount" --vote-account "$validator" + done < "$validator_list" +} + +stake_pool_pubkey=$(solana-keygen pubkey "$stake_pool_keyfile") +keys_dir=keys + +spl_stake_pool=spl-stake-pool +# Uncomment to use a locally build CLI +#spl_stake_pool=../../../target/debug/spl-stake-pool + +echo "Setting up keys directory $keys_dir" +mkdir -p $keys_dir +authority=$keys_dir/authority.json +echo "Setting up authority for withdrawn stake accounts at $authority" +create_keypair $authority + +echo "Withdrawing stakes from stake pool" +withdraw_stakes "$stake_pool_pubkey" "$validator_list" "$withdraw_sol_amount" +echo "Withdrawing SOL from stake pool to authority" +$spl_stake_pool withdraw-sol "$stake_pool_pubkey" $authority "$withdraw_sol_amount" From ccd08d328e2939459d5ef3cab23c4135d6128301 Mon Sep 17 00:00:00 2001 From: JulI0-concerto <93286550+JulI0-concerto@users.noreply.github.com> Date: Wed, 10 Nov 2021 21:06:14 +0100 Subject: [PATCH 0202/1076] Implement multiple output format for spl-stake-pool list-all (#2558) * Implement json output formats for spl-stake-pool list-all * Implement --output json or json-compact or display in list-all cmd * cleanup: use destructuring instead of tuple * Fix related to PR comments * Add json and json-compact output for list command * implement list command display with Display and VerboseDisplay * make CliStakePool->details optional * cleanup use * Update stake-pool/cli/src/main.rs Co-authored-by: Tyera Eulberg * Update stake-pool/cli/src/main.rs Co-authored-by: Tyera Eulberg * clippished * fix use * fix fmt issue Co-authored-by: Julien Piccaluga Co-authored-by: Tyera Eulberg --- clients/cli/Cargo.toml | 3 + clients/cli/src/client.rs | 13 +- clients/cli/src/main.rs | 227 +++++++----------- clients/cli/src/output.rs | 481 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 578 insertions(+), 146 deletions(-) create mode 100644 clients/cli/src/output.rs diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 2733d8fb..699f3cd7 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,10 +11,13 @@ version = "0.6.3" [dependencies] borsh = "0.9" clap = "2.33.3" +serde = "1.0.130" +serde_derive = "1.0.130" serde_json = "1.0.68" solana-account-decoder = "=1.8.1" solana-clap-utils = "=1.8.1" solana-cli-config = "=1.8.1" +solana-cli-output = "1.8.1" solana-client = "=1.8.1" solana-logger = "=1.8.1" solana-program = "=1.8.1" diff --git a/clients/cli/src/client.rs b/clients/cli/src/client.rs index 8fb0aa8b..c36a8956 100644 --- a/clients/cli/src/client.rs +++ b/clients/cli/src/client.rs @@ -8,7 +8,10 @@ use { rpc_filter::{Memcmp, MemcmpEncodedBytes, RpcFilterType}, }, solana_program::{borsh::try_from_slice_unchecked, program_pack::Pack, pubkey::Pubkey, stake}, - spl_stake_pool::state::{StakePool, ValidatorList}, + spl_stake_pool::{ + find_withdraw_authority_program_address, + state::{StakePool, ValidatorList}, + }, }; type Error = Box; @@ -76,7 +79,7 @@ pub(crate) fn get_stake_state( pub(crate) fn get_stake_pools( rpc_client: &RpcClient, -) -> Result, ClientError> { +) -> Result, ClientError> { rpc_client .get_program_accounts_with_config( &spl_stake_pool::id(), @@ -97,10 +100,14 @@ pub(crate) fn get_stake_pools( accounts .into_iter() .filter_map(|(address, account)| { + let pool_withdraw_authority = + find_withdraw_authority_program_address(&spl_stake_pool::id(), &address).0; match try_from_slice_unchecked::(account.data.as_slice()) { Ok(stake_pool) => { get_validator_list(rpc_client, &stake_pool.validator_list) - .map(|v| (address, stake_pool, v)) + .map(|validator_list| { + (address, stake_pool, validator_list, pool_withdraw_authority) + }) .ok() } Err(err) => { diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 6a690380..4247716e 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -1,7 +1,11 @@ mod client; +mod output; use { - crate::client::*, + crate::{ + client::*, + output::{CliStakePool, CliStakePoolDetails, CliStakePoolStakeAccountInfo, CliStakePools}, + }, clap::{ crate_description, crate_name, crate_version, value_t, value_t_or_exit, App, AppSettings, Arg, ArgGroup, ArgMatches, SubCommand, @@ -14,6 +18,7 @@ use { }, keypair::{signer_from_path_with_config, SignerFromPathConfig}, }, + solana_cli_output::OutputFormat, solana_client::rpc_client::RpcClient, solana_program::{ borsh::{get_instance_packed_len, get_packed_len}, @@ -44,9 +49,10 @@ use { std::{process::exit, sync::Arc}, }; -struct Config { +pub(crate) struct Config { rpc_client: RpcClient, verbose: bool, + output_format: OutputFormat, manager: Box, staker: Box, funding_authority: Option>, @@ -852,96 +858,25 @@ fn command_deposit_sol( fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; + let reserve_stake_account_address = stake_pool.reserve_stake.to_string(); + let total_lamports = stake_pool.total_lamports; + let last_update_epoch = stake_pool.last_update_epoch; let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?; + let max_number_of_validators = validator_list.header.max_validators; + let current_number_of_validators = validator_list.validators.len(); let pool_mint = get_token_mint(&config.rpc_client, &stake_pool.pool_mint)?; let epoch_info = config.rpc_client.get_epoch_info()?; let pool_withdraw_authority = find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; - let sol_deposit_authority = stake_pool - .sol_deposit_authority - .map_or("None".into(), |pubkey| pubkey.to_string()); - let sol_withdraw_authority = stake_pool - .sol_withdraw_authority - .map_or("None".into(), |pubkey| pubkey.to_string()); - - if config.verbose { - println!("Stake Pool Info"); - println!("==============="); - println!("Stake Pool: {}", stake_pool_address); - println!("Validator List: {}", stake_pool.validator_list); - println!("Manager: {}", stake_pool.manager); - println!("Staker: {}", stake_pool.staker); - println!("Depositor: {}", stake_pool.stake_deposit_authority); - println!("SOL Deposit Authority: {}", sol_deposit_authority); - println!("SOL Withdraw Authority: {}", sol_withdraw_authority); - println!("Withdraw Authority: {}", pool_withdraw_authority); - println!("Pool Token Mint: {}", stake_pool.pool_mint); - println!("Fee Account: {}", stake_pool.manager_fee_account); - } else { - println!("Stake Pool: {}", stake_pool_address); - println!("Validator List: {}", stake_pool.validator_list); - println!("Pool Token Mint: {}", stake_pool.pool_mint); - } - - if let Some(preferred_deposit_validator) = stake_pool.preferred_deposit_validator_vote_address { - println!( - "Preferred Deposit Validator: {}", - preferred_deposit_validator - ); - } - if let Some(preferred_withdraw_validator) = stake_pool.preferred_withdraw_validator_vote_address - { - println!( - "Preferred Withraw Validator: {}", - preferred_withdraw_validator - ); - } - - // Display fees information - println!("Epoch Fee: {} of epoch rewards", stake_pool.epoch_fee); - println!( - "Stake Withdrawal Fee: {} of withdrawal amount", - stake_pool.stake_withdrawal_fee - ); - println!( - "SOL Withdrawal Fee: {} of withdrawal amount", - stake_pool.sol_withdrawal_fee - ); - println!( - "Stake Deposit Fee: {} of deposit amount", - stake_pool.stake_deposit_fee - ); - println!( - "SOL Deposit Fee: {} of deposit amount", - stake_pool.sol_deposit_fee - ); - println!( - "Stake Deposit Referral Fee: {}% of Stake Deposit Fee", - stake_pool.stake_referral_fee - ); - println!( - "SOL Deposit Referral Fee: {}% of SOL Deposit Fee", - stake_pool.sol_referral_fee - ); - - if config.verbose { - println!(); - println!("Stake Accounts"); - println!("--------------"); - } let reserve_stake = config.rpc_client.get_account(&stake_pool.reserve_stake)?; let minimum_reserve_stake_balance = config .rpc_client .get_minimum_balance_for_rent_exemption(STAKE_STATE_LEN)? + 1; - println!( - "Reserve Account: {}\tAvailable Balance: {}", - stake_pool.reserve_stake, - Sol(reserve_stake.lamports - minimum_reserve_stake_balance), - ); - - for validator in &validator_list.validators { - if config.verbose { + let cli_stake_pool_stake_account_infos = validator_list + .validators + .iter() + .map(|validator| { let (stake_account_address, _) = find_stake_program_address( &spl_stake_pool::id(), &validator.vote_account_address, @@ -953,55 +888,42 @@ fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { stake_pool_address, validator.transient_seed_suffix_start, ); - println!( - "Vote Account: {}\tStake Account: {}\tActive Balance: {}\tTransient Stake Account: {}\tTransient Balance: {}\tLast Update Epoch: {}{}", - validator.vote_account_address, - stake_account_address, - Sol(validator.active_stake_lamports), - transient_stake_account_address, - Sol(validator.transient_stake_lamports), - validator.last_update_epoch, - if validator.last_update_epoch != epoch_info.epoch { - " [UPDATE REQUIRED]" - } else { - "" - } - ); - } else { - println!( - "Vote Account: {}\tBalance: {}\tLast Update Epoch: {}", - validator.vote_account_address, - Sol(validator.stake_lamports()), - validator.last_update_epoch, - ); - } - } - - if config.verbose { - println!(); - } - println!( - "Total Pool Stake: {}{}", - Sol(stake_pool.total_lamports), - if stake_pool.last_update_epoch != epoch_info.epoch { - " [UPDATE REQUIRED]" - } else { - "" - } - ); - println!( - "Total Pool Tokens: {}", - spl_token::amount_to_ui_amount(stake_pool.pool_token_supply, pool_mint.decimals) - ); - println!( - "Current Number of Validators: {}", - validator_list.validators.len() - ); - println!( - "Max Number of Validators: {}", - validator_list.header.max_validators - ); - + let update_required = validator.last_update_epoch != epoch_info.epoch; + CliStakePoolStakeAccountInfo { + vote_account_address: stake_pool_address.to_string(), + stake_account_address: stake_account_address.to_string(), + validator_active_stake_lamports: validator.active_stake_lamports, + validator_last_update_epoch: validator.last_update_epoch, + validator_lamports: validator.stake_lamports(), + validator_transient_stake_account_address: transient_stake_account_address + .to_string(), + validator_transient_stake_lamports: validator.transient_stake_lamports, + update_required, + } + }) + .collect(); + let total_pool_tokens = + spl_token::amount_to_ui_amount(stake_pool.pool_token_supply, pool_mint.decimals); + let mut cli_stake_pool = CliStakePool::from(( + *stake_pool_address, + stake_pool, + validator_list, + pool_withdraw_authority, + )); + let update_required = last_update_epoch != epoch_info.epoch; + let cli_stake_pool_details = CliStakePoolDetails { + reserve_stake_account_address, + reserve_stake_lamports: reserve_stake.lamports, + minimum_reserve_stake_balance, + stake_accounts: cli_stake_pool_stake_account_infos, + total_lamports, + total_pool_tokens, + current_number_of_validators: current_number_of_validators as u32, + max_number_of_validators, + update_required, + }; + cli_stake_pool.details = Some(cli_stake_pool_details); + println!("{}", config.output_format.formatted_string(&cli_stake_pool)); Ok(()) } @@ -1626,18 +1548,15 @@ fn command_set_fee( fn command_list_all_pools(config: &Config) -> CommandResult { let all_pools = get_stake_pools(&config.rpc_client)?; - let count = all_pools.len(); - for (address, stake_pool, validator_list) in all_pools { - println!( - "Address: {}\tManager: {}\tLamports: {}\tPool tokens: {}\tValidators: {}", - address, - stake_pool.manager, - stake_pool.total_lamports, - stake_pool.pool_token_supply, - validator_list.validators.len() - ); - } - println!("Total number of pools: {}", count); + let cli_stake_pool_vec: Vec = + all_pools.into_iter().map(CliStakePool::from).collect(); + let cli_stake_pools = CliStakePools { + pools: cli_stake_pool_vec, + }; + println!( + "{}", + config.output_format.formatted_string(&cli_stake_pools) + ); Ok(()) } @@ -1670,6 +1589,15 @@ fn main() { .global(true) .help("Show additional information"), ) + .arg( + Arg::with_name("output_format") + .long("output") + .value_name("FORMAT") + .global(true) + .takes_value(true) + .possible_values(&["json", "json-compact"]) + .help("Return information in specified output format"), + ) .arg( Arg::with_name("dry_run") .long("dry-run") @@ -2477,12 +2405,25 @@ fn main() { }, ); let verbose = matches.is_present("verbose"); + let output_format = matches + .value_of("output_format") + .map(|value| match value { + "json" => OutputFormat::Json, + "json-compact" => OutputFormat::JsonCompact, + _ => unreachable!(), + }) + .unwrap_or(if verbose { + OutputFormat::DisplayVerbose + } else { + OutputFormat::Display + }); let dry_run = matches.is_present("dry_run"); let no_update = matches.is_present("no_update"); Config { rpc_client: RpcClient::new_with_commitment(json_rpc_url, CommitmentConfig::confirmed()), verbose, + output_format, manager, staker, funding_authority, diff --git a/clients/cli/src/output.rs b/clients/cli/src/output.rs new file mode 100644 index 00000000..bc198f11 --- /dev/null +++ b/clients/cli/src/output.rs @@ -0,0 +1,481 @@ +use { + serde::{Deserialize, Serialize}, + solana_cli_output::{QuietDisplay, VerboseDisplay}, + solana_sdk::native_token::Sol, + solana_sdk::{pubkey::Pubkey, stake::state::Lockup}, + spl_stake_pool::state::{Fee, StakePool, StakeStatus, ValidatorList, ValidatorStakeInfo}, + std::fmt::{Display, Formatter, Result, Write}, +}; + +#[derive(Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct CliStakePools { + pub pools: Vec, +} + +impl Display for CliStakePools { + fn fmt(&self, f: &mut Formatter<'_>) -> Result { + for pool in &self.pools { + writeln!( + f, + "Address: {}\tManager: {}\tLamports: {}\tPool tokens: {}\tValidators: {}", + pool.address, + pool.manager, + pool.total_lamports, + pool.pool_token_supply, + pool.validator_list.len() + )?; + } + writeln!(f, "Total number of pools: {}", &self.pools.len())?; + Ok(()) + } +} + +impl QuietDisplay for CliStakePools {} +impl VerboseDisplay for CliStakePools {} + +#[derive(Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct CliStakePool { + pub address: String, + pub pool_withdraw_authority: String, + pub manager: String, + pub staker: String, + pub stake_deposit_authority: String, + pub stake_withdraw_bump_seed: u8, + pub max_validators: u32, + pub validator_list: Vec, + pub validator_list_storage_account: String, + pub reserve_stake: String, + pub pool_mint: String, + pub manager_fee_account: String, + pub token_program_id: String, + pub total_lamports: u64, + pub pool_token_supply: u64, + pub last_update_epoch: u64, + pub lockup: CliStakePoolLockup, + pub epoch_fee: CliStakePoolFee, + pub next_epoch_fee: Option, + pub preferred_deposit_validator_vote_address: Option, + pub preferred_withdraw_validator_vote_address: Option, + pub stake_deposit_fee: CliStakePoolFee, + pub stake_withdrawal_fee: CliStakePoolFee, + pub next_stake_withdrawal_fee: Option, + pub stake_referral_fee: u8, + pub sol_deposit_authority: Option, + pub sol_deposit_fee: CliStakePoolFee, + pub sol_referral_fee: u8, + pub sol_withdraw_authority: Option, + pub sol_withdrawal_fee: CliStakePoolFee, + pub next_sol_withdrawal_fee: Option, + pub last_epoch_pool_token_supply: u64, + pub last_epoch_total_lamports: u64, + pub details: Option, +} + +impl QuietDisplay for CliStakePool {} +impl VerboseDisplay for CliStakePool { + fn write_str(&self, w: &mut dyn Write) -> Result { + writeln!(w, "Stake Pool Info")?; + writeln!(w, "===============")?; + writeln!(w, "Stake Pool: {}", &self.address)?; + writeln!( + w, + "Validator List: {}", + &self.validator_list_storage_account + )?; + writeln!(w, "Manager: {}", &self.manager)?; + writeln!(w, "Staker: {}", &self.staker)?; + writeln!(w, "Depositor: {}", &self.stake_deposit_authority)?; + writeln!( + w, + "SOL Deposit Authority: {}", + &self + .sol_deposit_authority + .as_ref() + .unwrap_or(&"None".to_string()) + )?; + writeln!( + w, + "SOL Withdraw Authority: {}", + &self + .sol_withdraw_authority + .as_ref() + .unwrap_or(&"None".to_string()) + )?; + writeln!(w, "Withdraw Authority: {}", &self.pool_withdraw_authority)?; + writeln!(w, "Pool Token Mint: {}", &self.pool_mint)?; + writeln!(w, "Fee Account: {}", &self.manager_fee_account)?; + match &self.preferred_deposit_validator_vote_address { + None => {} + Some(s) => { + writeln!(w, "Preferred Deposit Validator: {}", s)?; + } + } + match &self.preferred_withdraw_validator_vote_address { + None => {} + Some(s) => { + writeln!(w, "Preferred Withraw Validator: {}", s)?; + } + } + writeln!(w, "Epoch Fee: {} of epoch rewards", &self.epoch_fee)?; + writeln!( + w, + "Stake Withdrawal Fee: {} of withdrawal amount", + &self.stake_withdrawal_fee + )?; + writeln!( + w, + "SOL Withdrawal Fee: {} of withdrawal amount", + &self.sol_withdrawal_fee + )?; + writeln!( + w, + "Stake Deposit Fee: {} of deposit amount", + &self.stake_deposit_fee + )?; + writeln!( + w, + "SOL Deposit Fee: {} of deposit amount", + &self.sol_deposit_fee + )?; + writeln!( + w, + "Stake Deposit Referral Fee: {}% of Stake Deposit Fee", + &self.stake_referral_fee + )?; + writeln!( + w, + "SOL Deposit Referral Fee: {}% of SOL Deposit Fee", + &self.sol_referral_fee + )?; + writeln!(w)?; + writeln!(w, "Stake Accounts")?; + writeln!(w, "--------------")?; + match &self.details { + None => {} + Some(details) => { + VerboseDisplay::write_str(details, w)?; + } + } + Ok(()) + } +} + +impl Display for CliStakePool { + fn fmt(&self, f: &mut Formatter<'_>) -> Result { + writeln!(f, "Stake Pool: {}", &self.address)?; + writeln!( + f, + "Validator List: {}", + &self.validator_list_storage_account + )?; + writeln!(f, "Pool Token Mint: {}", &self.pool_mint)?; + match &self.preferred_deposit_validator_vote_address { + None => {} + Some(s) => { + writeln!(f, "Preferred Deposit Validator: {}", s)?; + } + } + match &self.preferred_withdraw_validator_vote_address { + None => {} + Some(s) => { + writeln!(f, "Preferred Withraw Validator: {}", s)?; + } + } + writeln!(f, "Epoch Fee: {} of epoch rewards", &self.epoch_fee)?; + writeln!( + f, + "Stake Withdrawal Fee: {} of withdrawal amount", + &self.stake_withdrawal_fee + )?; + writeln!( + f, + "SOL Withdrawal Fee: {} of withdrawal amount", + &self.sol_withdrawal_fee + )?; + writeln!( + f, + "Stake Deposit Fee: {} of deposit amount", + &self.stake_deposit_fee + )?; + writeln!( + f, + "SOL Deposit Fee: {} of deposit amount", + &self.sol_deposit_fee + )?; + writeln!( + f, + "Stake Deposit Referral Fee: {}% of Stake Deposit Fee", + &self.stake_referral_fee + )?; + writeln!( + f, + "SOL Deposit Referral Fee: {}% of SOL Deposit Fee", + &self.sol_referral_fee + )?; + Ok(()) + } +} + +#[derive(Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct CliStakePoolDetails { + pub reserve_stake_account_address: String, + pub reserve_stake_lamports: u64, + pub minimum_reserve_stake_balance: u64, + pub stake_accounts: Vec, + pub total_lamports: u64, + pub total_pool_tokens: f64, + pub current_number_of_validators: u32, + pub max_number_of_validators: u32, + pub update_required: bool, +} + +impl Display for CliStakePoolDetails { + fn fmt(&self, f: &mut Formatter<'_>) -> Result { + writeln!( + f, + "Reserve Account: {}\tAvailable Balance: {}", + &self.reserve_stake_account_address, + Sol(self.reserve_stake_lamports - self.minimum_reserve_stake_balance), + )?; + for stake_account in &self.stake_accounts { + writeln!( + f, + "Vote Account: {}\tBalance: {}\tLast Update Epoch: {}", + stake_account.vote_account_address, + Sol(stake_account.validator_lamports), + stake_account.validator_last_update_epoch, + )?; + } + writeln!( + f, + "Total Pool Stake: {} {}", + Sol(self.total_lamports), + if self.update_required { + " [UPDATE REQUIRED]" + } else { + "" + }, + )?; + writeln!(f, "Total Pool Tokens: {}", &self.total_pool_tokens,)?; + writeln!( + f, + "Current Number of Validators: {}", + &self.current_number_of_validators, + )?; + writeln!( + f, + "Max Number of Validators: {}", + &self.max_number_of_validators, + )?; + Ok(()) + } +} + +impl QuietDisplay for CliStakePoolDetails {} +impl VerboseDisplay for CliStakePoolDetails { + fn write_str(&self, w: &mut dyn Write) -> Result { + writeln!(w)?; + writeln!(w, "Stake Accounts")?; + writeln!(w, "--------------")?; + writeln!( + w, + "Reserve Account: {}\tAvailable Balance: {}", + &self.reserve_stake_account_address, + Sol(self.reserve_stake_lamports - self.minimum_reserve_stake_balance), + )?; + for stake_account in &self.stake_accounts { + writeln!( + w, + "Vote Account: {}\tStake Account: {}\tActive Balance: {}\tTransient Stake Account: {}\tTransient Balance: {}\tLast Update Epoch: {}{}", + stake_account.vote_account_address, + stake_account.stake_account_address, + Sol(stake_account.validator_active_stake_lamports), + stake_account.validator_transient_stake_account_address, + Sol(stake_account.validator_transient_stake_lamports), + stake_account.validator_last_update_epoch, + if stake_account.update_required { + " [UPDATE REQUIRED]" + } else { + "" + }, + )?; + } + writeln!( + w, + "Total Pool Stake: {} {}", + Sol(self.total_lamports), + if self.update_required { + " [UPDATE REQUIRED]" + } else { + "" + }, + )?; + writeln!(w, "Total Pool Tokens: {}", &self.total_pool_tokens,)?; + writeln!( + w, + "Current Number of Validators: {}", + &self.current_number_of_validators, + )?; + writeln!( + w, + "Max Number of Validators: {}", + &self.max_number_of_validators, + )?; + Ok(()) + } +} + +#[derive(Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct CliStakePoolStakeAccountInfo { + pub vote_account_address: String, + pub stake_account_address: String, + pub validator_active_stake_lamports: u64, + pub validator_last_update_epoch: u64, + pub validator_lamports: u64, + pub validator_transient_stake_account_address: String, + pub validator_transient_stake_lamports: u64, + pub update_required: bool, +} + +#[derive(Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct CliStakePoolValidator { + pub active_stake_lamports: u64, + pub transient_stake_lamports: u64, + pub last_update_epoch: u64, + pub transient_seed_suffix_start: u64, + pub transient_seed_suffix_end: u64, + pub status: CliStakePoolValidatorStakeStatus, + pub vote_account_address: String, +} + +impl From for CliStakePoolValidator { + fn from(v: ValidatorStakeInfo) -> Self { + Self { + active_stake_lamports: v.active_stake_lamports, + transient_stake_lamports: v.transient_stake_lamports, + last_update_epoch: v.last_update_epoch, + transient_seed_suffix_start: v.transient_seed_suffix_start, + transient_seed_suffix_end: v.transient_seed_suffix_end, + status: CliStakePoolValidatorStakeStatus::from(v.status), + vote_account_address: v.vote_account_address.to_string(), + } + } +} + +impl From for CliStakePoolValidatorStakeStatus { + fn from(s: StakeStatus) -> CliStakePoolValidatorStakeStatus { + match s { + StakeStatus::Active => CliStakePoolValidatorStakeStatus::Active, + StakeStatus::DeactivatingTransient => { + CliStakePoolValidatorStakeStatus::DeactivatingTransient + } + StakeStatus::ReadyForRemoval => CliStakePoolValidatorStakeStatus::ReadyForRemoval, + } + } +} + +#[derive(Serialize, Deserialize)] +pub(crate) enum CliStakePoolValidatorStakeStatus { + Active, + DeactivatingTransient, + ReadyForRemoval, +} + +#[derive(Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct CliStakePoolLockup { + pub unix_timestamp: i64, + pub epoch: u64, + pub custodian: String, +} + +impl From for CliStakePoolLockup { + fn from(l: Lockup) -> Self { + Self { + unix_timestamp: l.unix_timestamp, + epoch: l.epoch, + custodian: l.custodian.to_string(), + } + } +} + +#[derive(Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct CliStakePoolFee { + pub denominator: u64, + pub numerator: u64, +} + +impl Display for CliStakePoolFee { + fn fmt(&self, f: &mut Formatter<'_>) -> Result { + write!(f, "{}/{}", &self.numerator, &self.denominator) + } +} + +impl From for CliStakePoolFee { + fn from(f: Fee) -> Self { + Self { + denominator: f.denominator, + numerator: f.numerator, + } + } +} + +impl From<(Pubkey, StakePool, ValidatorList, Pubkey)> for CliStakePool { + fn from(s: (Pubkey, StakePool, ValidatorList, Pubkey)) -> Self { + let (address, stake_pool, validator_list, pool_withdraw_authority) = s; + Self { + address: address.to_string(), + pool_withdraw_authority: pool_withdraw_authority.to_string(), + manager: stake_pool.manager.to_string(), + staker: stake_pool.staker.to_string(), + stake_deposit_authority: stake_pool.stake_deposit_authority.to_string(), + stake_withdraw_bump_seed: stake_pool.stake_withdraw_bump_seed, + max_validators: validator_list.header.max_validators, + validator_list: validator_list + .validators + .into_iter() + .map(CliStakePoolValidator::from) + .collect(), + validator_list_storage_account: stake_pool.validator_list.to_string(), + reserve_stake: stake_pool.reserve_stake.to_string(), + pool_mint: stake_pool.pool_mint.to_string(), + manager_fee_account: stake_pool.manager_fee_account.to_string(), + token_program_id: stake_pool.token_program_id.to_string(), + total_lamports: stake_pool.total_lamports, + pool_token_supply: stake_pool.pool_token_supply, + last_update_epoch: stake_pool.last_update_epoch, + lockup: CliStakePoolLockup::from(stake_pool.lockup), + epoch_fee: CliStakePoolFee::from(stake_pool.epoch_fee), + next_epoch_fee: stake_pool.next_epoch_fee.map(CliStakePoolFee::from), + preferred_deposit_validator_vote_address: stake_pool + .preferred_deposit_validator_vote_address + .map(|x| x.to_string()), + preferred_withdraw_validator_vote_address: stake_pool + .preferred_withdraw_validator_vote_address + .map(|x| x.to_string()), + stake_deposit_fee: CliStakePoolFee::from(stake_pool.stake_deposit_fee), + stake_withdrawal_fee: CliStakePoolFee::from(stake_pool.stake_withdrawal_fee), + next_stake_withdrawal_fee: stake_pool + .next_sol_withdrawal_fee + .map(CliStakePoolFee::from), + stake_referral_fee: stake_pool.stake_referral_fee, + sol_deposit_authority: stake_pool.sol_deposit_authority.map(|x| x.to_string()), + sol_deposit_fee: CliStakePoolFee::from(stake_pool.stake_deposit_fee), + sol_referral_fee: stake_pool.sol_referral_fee, + sol_withdraw_authority: stake_pool.sol_deposit_authority.map(|x| x.to_string()), + sol_withdrawal_fee: CliStakePoolFee::from(stake_pool.sol_withdrawal_fee), + next_sol_withdrawal_fee: stake_pool + .next_sol_withdrawal_fee + .map(CliStakePoolFee::from), + last_epoch_pool_token_supply: stake_pool.last_epoch_pool_token_supply, + last_epoch_total_lamports: stake_pool.last_epoch_total_lamports, + details: None, + } + } +} From 79e57c330416cc378343d457235a5fcf5dcfe596 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 16 Nov 2021 21:30:10 +0100 Subject: [PATCH 0203/1076] stake-pool-cli: Fix vote account address in details (#2585) --- clients/cli/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 4247716e..24b6022b 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -890,7 +890,7 @@ fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { ); let update_required = validator.last_update_epoch != epoch_info.epoch; CliStakePoolStakeAccountInfo { - vote_account_address: stake_pool_address.to_string(), + vote_account_address: validator.vote_account_address.to_string(), stake_account_address: stake_account_address.to_string(), validator_active_stake_lamports: validator.active_stake_lamports, validator_last_update_epoch: validator.last_update_epoch, From ef481520813b09b6a1396a86a8731c75f92aba53 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 3 Dec 2021 01:55:18 +0100 Subject: [PATCH 0204/1076] stake-pool-cli: Update input parser to work with ledgers (#2613) * stake-pool-cli: Update input parser to work with ledgers * fmt --- clients/cli/src/main.rs | 63 ++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 41 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 24b6022b..efe43d00 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -14,7 +14,7 @@ use { input_parsers::{keypair_of, pubkey_of}, input_validators::{ is_amount, is_keypair_or_ask_keyword, is_parsable, is_pubkey, is_url, - is_valid_percentage, is_valid_pubkey, + is_valid_percentage, is_valid_pubkey, is_valid_signer, }, keypair::{signer_from_path_with_config, SignerFromPathConfig}, }, @@ -1624,60 +1624,41 @@ fn main() { Arg::with_name("staker") .long("staker") .value_name("KEYPAIR") - .validator(is_keypair_or_ask_keyword) + .validator(is_valid_signer) .takes_value(true) - .help( - "Specify the stake pool staker. \ - This may be a keypair file, the ASK keyword. \ - Defaults to the client keypair.", - ), + .help("Stake pool staker. [default: cli config keypair]"), ) .arg( Arg::with_name("manager") .long("manager") .value_name("KEYPAIR") - .validator(is_keypair_or_ask_keyword) + .validator(is_valid_signer) .takes_value(true) - .help( - "Specify the stake pool manager. \ - This may be a keypair file, the ASK keyword. \ - Defaults to the client keypair.", - ), + .help("Stake pool manager. [default: cli config keypair]"), ) .arg( Arg::with_name("funding_authority") .long("funding-authority") .value_name("KEYPAIR") - .validator(is_keypair_or_ask_keyword) + .validator(is_valid_signer) .takes_value(true) - .help( - "Specify the stake pool funding authority, for deposits or withdrawals. \ - This may be a keypair file, the ASK keyword.", - ), + .help("Stake pool funding authority for deposits or withdrawals. [default: cli config keypair]"), ) .arg( Arg::with_name("token_owner") .long("token-owner") .value_name("KEYPAIR") - .validator(is_keypair_or_ask_keyword) + .validator(is_valid_signer) .takes_value(true) - .help( - "Specify the owner of the pool token account. \ - This may be a keypair file, the ASK keyword. \ - Defaults to the client keypair.", - ), + .help("Owner of pool token account [default: cli config keypair]"), ) .arg( Arg::with_name("fee_payer") .long("fee-payer") .value_name("KEYPAIR") - .validator(is_keypair_or_ask_keyword) + .validator(is_valid_signer) .takes_value(true) - .help( - "Specify the fee-payer account. \ - This may be a keypair file, the ASK keyword. \ - Defaults to the client keypair.", - ), + .help("Transaction fee payer account [default: cli config keypair]"), ) .subcommand(SubCommand::with_name("create-pool") .about("Create a new stake pool") @@ -1757,7 +1738,7 @@ fn main() { Arg::with_name("deposit_authority") .long("deposit-authority") .short("a") - .validator(is_keypair_or_ask_keyword) + .validator(is_valid_signer) .value_name("DEPOSIT_AUTHORITY_KEYPAIR") .takes_value(true) .help("Deposit authority required to sign all deposits into the stake pool"), @@ -1976,11 +1957,10 @@ fn main() { .arg( Arg::with_name("withdraw_authority") .long("withdraw-authority") - .validator(is_keypair_or_ask_keyword) + .validator(is_valid_signer) .value_name("KEYPAIR") .takes_value(true) - .help("Withdraw authority for the stake account to be deposited. \ - Defaults to the fee payer."), + .help("Withdraw authority for the stake account to be deposited. [default: cli config keypair]"), ) .arg( Arg::with_name("token_receiver") @@ -2022,11 +2002,10 @@ fn main() { .arg( Arg::with_name("from") .long("from") - .validator(is_keypair_or_ask_keyword) + .validator(is_valid_signer) .value_name("KEYPAIR") .takes_value(true) - .help("Source account of funds. \ - Defaults to the fee payer."), + .help("Source account of funds. [default: cli config keypair]"), ) .arg( Arg::with_name("token_receiver") @@ -2192,7 +2171,7 @@ fn main() { .arg( Arg::with_name("new_manager") .long("new-manager") - .validator(is_keypair_or_ask_keyword) + .validator(is_valid_signer) .value_name("KEYPAIR") .takes_value(true) .help("Keypair for the new stake pool manager."), @@ -2667,9 +2646,11 @@ fn main() { ("set-referral-fee", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); let fee = value_t_or_exit!(arg_matches, "fee", u8); - if fee > 100u8 { - panic!("Invalid fee {}%. Fee needs to be in range [0-100]", fee); - } + assert!( + fee <= 100u8, + "Invalid fee {}%. Fee needs to be in range [0-100]", + fee + ); let fee_type = match arg_matches.value_of("fee_type").unwrap() { "sol" => FeeType::SolReferral(fee), "stake" => FeeType::StakeReferral(fee), From 42ab9cbc10e3985bd8e70b1261bca53fc1a2206f Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 10 Dec 2021 00:43:25 +0100 Subject: [PATCH 0205/1076] stake-pool-py: Create and deserialize stake pools (#2557) * stake-pool-py: Create and deserialize stake pools with CI * Add ability to add / remove validators * Add vote init instruction for cleaner tests * Fixup CI * Add deposit / withdraw sol * Add update instructions * Add increase / decrease stake * Add deposit / withdraw stake --- README.md | 2 + clients/py/.flake8 | 2 + clients/py/.gitignore | 7 + clients/py/README.md | 3 + clients/py/requirements.txt | 35 + clients/py/spl_token/__init__.py | 0 clients/py/spl_token/actions.py | 57 ++ clients/py/stake/__init__.py | 0 clients/py/stake/actions.py | 87 ++ clients/py/stake/constants.py | 12 + clients/py/stake/instructions.py | 177 ++++ clients/py/stake/state.py | 59 ++ clients/py/stake_pool/__init__.py | 0 clients/py/stake_pool/actions.py | 572 +++++++++++ clients/py/stake_pool/constants.py | 74 ++ clients/py/stake_pool/instructions.py | 912 ++++++++++++++++++ clients/py/stake_pool/state.py | 321 ++++++ clients/py/system/__init__.py | 0 clients/py/system/actions.py | 9 + clients/py/tests/conftest.py | 95 ++ clients/py/tests/test_a_time_sensitive.py | 76 ++ clients/py/tests/test_add_remove.py | 31 + clients/py/tests/test_create.py | 68 ++ clients/py/tests/test_deposit_withdraw_sol.py | 26 + .../py/tests/test_deposit_withdraw_stake.py | 43 + clients/py/tests/test_stake.py | 32 + clients/py/tests/test_system.py | 14 + clients/py/tests/test_token.py | 16 + clients/py/tests/test_vote.py | 16 + clients/py/vote/__init__.py | 0 clients/py/vote/actions.py | 45 + clients/py/vote/constants.py | 8 + clients/py/vote/instructions.py | 97 ++ 33 files changed, 2896 insertions(+) create mode 100644 clients/py/.flake8 create mode 100644 clients/py/.gitignore create mode 100644 clients/py/README.md create mode 100644 clients/py/requirements.txt create mode 100644 clients/py/spl_token/__init__.py create mode 100644 clients/py/spl_token/actions.py create mode 100644 clients/py/stake/__init__.py create mode 100644 clients/py/stake/actions.py create mode 100644 clients/py/stake/constants.py create mode 100644 clients/py/stake/instructions.py create mode 100644 clients/py/stake/state.py create mode 100644 clients/py/stake_pool/__init__.py create mode 100644 clients/py/stake_pool/actions.py create mode 100644 clients/py/stake_pool/constants.py create mode 100644 clients/py/stake_pool/instructions.py create mode 100644 clients/py/stake_pool/state.py create mode 100644 clients/py/system/__init__.py create mode 100644 clients/py/system/actions.py create mode 100644 clients/py/tests/conftest.py create mode 100644 clients/py/tests/test_a_time_sensitive.py create mode 100644 clients/py/tests/test_add_remove.py create mode 100644 clients/py/tests/test_create.py create mode 100644 clients/py/tests/test_deposit_withdraw_sol.py create mode 100644 clients/py/tests/test_deposit_withdraw_stake.py create mode 100644 clients/py/tests/test_stake.py create mode 100644 clients/py/tests/test_system.py create mode 100644 clients/py/tests/test_token.py create mode 100644 clients/py/tests/test_vote.py create mode 100644 clients/py/vote/__init__.py create mode 100644 clients/py/vote/actions.py create mode 100644 clients/py/vote/constants.py create mode 100644 clients/py/vote/instructions.py diff --git a/README.md b/README.md index af9a5003..179033a2 100644 --- a/README.md +++ b/README.md @@ -5,3 +5,5 @@ Full documentation is available at https://spl.solana.com/stake-pool The command-line interface tool is available in the `./cli` directory. Javascript bindings are available in the `./js` directory. + +Python bindings are available in the `./py` directory. diff --git a/clients/py/.flake8 b/clients/py/.flake8 new file mode 100644 index 00000000..aa079ec5 --- /dev/null +++ b/clients/py/.flake8 @@ -0,0 +1,2 @@ +[flake8] +max-line-length=120 diff --git a/clients/py/.gitignore b/clients/py/.gitignore new file mode 100644 index 00000000..ad0e7548 --- /dev/null +++ b/clients/py/.gitignore @@ -0,0 +1,7 @@ +# python cache files +*__pycache__* +.pytest_cache +.mypy_cache + +# venv +venv/ diff --git a/clients/py/README.md b/clients/py/README.md new file mode 100644 index 00000000..97e3605c --- /dev/null +++ b/clients/py/README.md @@ -0,0 +1,3 @@ +# Stake-Pool Python Bindings + +WIP Python bindings to interact with the stake pool program. diff --git a/clients/py/requirements.txt b/clients/py/requirements.txt new file mode 100644 index 00000000..32b09a63 --- /dev/null +++ b/clients/py/requirements.txt @@ -0,0 +1,35 @@ +anyio==3.3.4 +attrs==21.2.0 +base58==2.1.0 +cachetools==4.2.4 +certifi==2021.10.8 +cffi==1.15.0 +charset-normalizer==2.0.7 +construct==2.10.67 +flake8==4.0.1 +h11==0.12.0 +httpcore==0.13.7 +httpx==0.20.0 +idna==3.3 +iniconfig==1.1.1 +mccabe==0.6.1 +mypy==0.910 +mypy-extensions==0.4.3 +packaging==21.2 +pluggy==1.0.0 +py==1.10.0 +pycodestyle==2.8.0 +pycparser==2.20 +pyflakes==2.4.0 +PyNaCl==1.4.0 +pyparsing==2.4.7 +pytest==6.2.5 +pytest-asyncio==0.16.0 +requests==2.26.0 +rfc3986==1.5.0 +six==1.16.0 +sniffio==1.2.0 +solana==0.18.1 +toml==0.10.2 +typing-extensions==3.10.0.2 +urllib3==1.26.7 diff --git a/clients/py/spl_token/__init__.py b/clients/py/spl_token/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/clients/py/spl_token/actions.py b/clients/py/spl_token/actions.py new file mode 100644 index 00000000..6c00a928 --- /dev/null +++ b/clients/py/spl_token/actions.py @@ -0,0 +1,57 @@ +from solana.publickey import PublicKey +from solana.keypair import Keypair +from solana.rpc.async_api import AsyncClient +from solana.rpc.commitment import Confirmed +from solana.rpc.types import TxOpts +from solana.transaction import Transaction +import solana.system_program as sys + +from spl.token.constants import TOKEN_PROGRAM_ID +from spl.token.async_client import AsyncToken +from spl.token._layouts import MINT_LAYOUT +import spl.token.instructions as spl_token + + +async def create_associated_token_account( + client: AsyncClient, + payer: Keypair, + owner: PublicKey, + mint: PublicKey +) -> PublicKey: + txn = Transaction() + create_txn = spl_token.create_associated_token_account( + payer=payer.public_key, owner=owner, mint=mint + ) + txn.add(create_txn) + await client.send_transaction(txn, payer, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + return create_txn.keys[1].pubkey + + +async def create_mint(client: AsyncClient, payer: Keypair, mint: Keypair, mint_authority: PublicKey): + mint_balance = await AsyncToken.get_min_balance_rent_for_exempt_for_mint(client) + print(f"Creating pool token mint {mint.public_key}") + txn = Transaction() + txn.add( + sys.create_account( + sys.CreateAccountParams( + from_pubkey=payer.public_key, + new_account_pubkey=mint.public_key, + lamports=mint_balance, + space=MINT_LAYOUT.sizeof(), + program_id=TOKEN_PROGRAM_ID, + ) + ) + ) + txn.add( + spl_token.initialize_mint( + spl_token.InitializeMintParams( + program_id=TOKEN_PROGRAM_ID, + mint=mint.public_key, + decimals=9, + mint_authority=mint_authority, + freeze_authority=None, + ) + ) + ) + await client.send_transaction( + txn, payer, mint, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) diff --git a/clients/py/stake/__init__.py b/clients/py/stake/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/clients/py/stake/actions.py b/clients/py/stake/actions.py new file mode 100644 index 00000000..2963a43d --- /dev/null +++ b/clients/py/stake/actions.py @@ -0,0 +1,87 @@ +from solana.publickey import PublicKey +from solana.keypair import Keypair +from solana.rpc.async_api import AsyncClient +from solana.rpc.commitment import Confirmed +from solana.rpc.types import TxOpts +from solana.sysvar import SYSVAR_CLOCK_PUBKEY, SYSVAR_STAKE_HISTORY_PUBKEY +from solana.transaction import Transaction +import solana.system_program as sys + +from stake.constants import STAKE_LEN, STAKE_PROGRAM_ID, SYSVAR_STAKE_CONFIG_ID +from stake.state import Authorized, Lockup, StakeAuthorize +import stake.instructions as st + + +async def create_stake(client: AsyncClient, payer: Keypair, stake: Keypair, authority: PublicKey, lamports: int): + print(f"Creating stake {stake.public_key}") + resp = await client.get_minimum_balance_for_rent_exemption(STAKE_LEN) + txn = Transaction() + txn.add( + sys.create_account( + sys.CreateAccountParams( + from_pubkey=payer.public_key, + new_account_pubkey=stake.public_key, + lamports=resp['result'] + lamports, + space=STAKE_LEN, + program_id=STAKE_PROGRAM_ID, + ) + ) + ) + txn.add( + st.initialize( + st.InitializeParams( + stake=stake.public_key, + authorized=Authorized( + staker=authority, + withdrawer=authority, + ), + lockup=Lockup( + unix_timestamp=0, + epoch=0, + custodian=sys.SYS_PROGRAM_ID, + ) + ) + ) + ) + await client.send_transaction( + txn, payer, stake, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + + +async def delegate_stake(client: AsyncClient, payer: Keypair, staker: Keypair, stake: PublicKey, vote: PublicKey): + txn = Transaction() + txn.add( + st.delegate_stake( + st.DelegateStakeParams( + stake=stake, + vote=vote, + clock_sysvar=SYSVAR_CLOCK_PUBKEY, + stake_history_sysvar=SYSVAR_STAKE_HISTORY_PUBKEY, + stake_config_id=SYSVAR_STAKE_CONFIG_ID, + staker=staker.public_key, + ) + ) + ) + signers = [payer, staker] if payer != staker else [payer] + await client.send_transaction( + txn, *signers, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + + +async def authorize( + client: AsyncClient, payer: Keypair, authority: Keypair, stake: PublicKey, + new_authority: PublicKey, stake_authorize: StakeAuthorize +): + txn = Transaction() + txn.add( + st.authorize( + st.AuthorizeParams( + stake=stake, + clock_sysvar=SYSVAR_CLOCK_PUBKEY, + authority=authority.public_key, + new_authority=new_authority, + stake_authorize=stake_authorize, + ) + ) + ) + signers = [payer, authority] if payer != authority else [payer] + await client.send_transaction( + txn, *signers, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) diff --git a/clients/py/stake/constants.py b/clients/py/stake/constants.py new file mode 100644 index 00000000..39e6c4a6 --- /dev/null +++ b/clients/py/stake/constants.py @@ -0,0 +1,12 @@ +"""Stake Program Constants.""" + +from solana.publickey import PublicKey + +STAKE_PROGRAM_ID: PublicKey = PublicKey("Stake11111111111111111111111111111111111111") +"""Public key that identifies the Stake program.""" + +SYSVAR_STAKE_CONFIG_ID: PublicKey = PublicKey("StakeConfig11111111111111111111111111111111") +"""Public key that identifies the Stake config sysvar.""" + +STAKE_LEN: int = 200 +"""Size of stake account.""" diff --git a/clients/py/stake/instructions.py b/clients/py/stake/instructions.py new file mode 100644 index 00000000..29378e52 --- /dev/null +++ b/clients/py/stake/instructions.py @@ -0,0 +1,177 @@ +"""Stake Program Instructions.""" + +from enum import IntEnum +from typing import NamedTuple + +from construct import Switch # type: ignore +from construct import Int32ul, Pass # type: ignore +from construct import Struct + +from solana._layouts.shared import PUBLIC_KEY_LAYOUT +from solana.publickey import PublicKey +from solana.sysvar import SYSVAR_RENT_PUBKEY +from solana.transaction import AccountMeta, TransactionInstruction + +from stake.constants import STAKE_PROGRAM_ID +from stake.state import AUTHORIZED_LAYOUT, LOCKUP_LAYOUT, Authorized, Lockup, StakeAuthorize + + +class InitializeParams(NamedTuple): + """Initialize stake transaction params.""" + + stake: PublicKey + """`[w]` Uninitialized stake account.""" + authorized: Authorized + """Information about the staker and withdrawer keys.""" + lockup: Lockup + """Stake lockup, if any.""" + + +class DelegateStakeParams(NamedTuple): + """Initialize stake transaction params.""" + + stake: PublicKey + """`[w]` Uninitialized stake account.""" + vote: PublicKey + """`[]` Vote account to which this stake will be delegated.""" + clock_sysvar: PublicKey + """`[]` Clock sysvar.""" + stake_history_sysvar: PublicKey + """`[]` Stake history sysvar that carries stake warmup/cooldown history.""" + stake_config_id: PublicKey + """`[]` Address of config account that carries stake config.""" + staker: PublicKey + """`[s]` Stake authority.""" + + +class AuthorizeParams(NamedTuple): + """Authorize stake transaction params.""" + + stake: PublicKey + """`[w]` Initialized stake account to modify.""" + clock_sysvar: PublicKey + """`[]` Clock sysvar.""" + authority: PublicKey + """`[s]` Current stake authority.""" + + # Params + new_authority: PublicKey + """New authority's public key.""" + stake_authorize: StakeAuthorize + """Type of authority to modify, staker or withdrawer.""" + + +class InstructionType(IntEnum): + """Stake Instruction Types.""" + + INITIALIZE = 0 + AUTHORIZE = 1 + DELEGATE_STAKE = 2 + SPLIT = 3 + WITHDRAW = 4 + DEACTIVATE = 5 + SET_LOCKUP = 6 + MERGE = 7 + AUTHORIZE_WITH_SEED = 8 + INITIALIZE_CHECKED = 9 + AUTHORIZED_CHECKED = 10 + AUTHORIZED_CHECKED_WITH_SEED = 11 + SET_LOCKUP_CHECKED = 12 + + +INITIALIZE_LAYOUT = Struct( + "authorized" / AUTHORIZED_LAYOUT, + "lockup" / LOCKUP_LAYOUT, +) + + +AUTHORIZE_LAYOUT = Struct( + "new_authority" / PUBLIC_KEY_LAYOUT, + "stake_authorize" / Int32ul, +) + + +INSTRUCTIONS_LAYOUT = Struct( + "instruction_type" / Int32ul, + "args" + / Switch( + lambda this: this.instruction_type, + { + InstructionType.INITIALIZE: INITIALIZE_LAYOUT, + InstructionType.AUTHORIZE: AUTHORIZE_LAYOUT, + InstructionType.DELEGATE_STAKE: Pass, + InstructionType.SPLIT: Pass, + InstructionType.WITHDRAW: Pass, + InstructionType.DEACTIVATE: Pass, + InstructionType.SET_LOCKUP: Pass, + InstructionType.MERGE: Pass, + InstructionType.AUTHORIZE_WITH_SEED: Pass, + InstructionType.INITIALIZE_CHECKED: Pass, + InstructionType.AUTHORIZED_CHECKED: Pass, + InstructionType.AUTHORIZED_CHECKED_WITH_SEED: Pass, + InstructionType.SET_LOCKUP_CHECKED: Pass, + }, + ), +) + + +def initialize(params: InitializeParams) -> TransactionInstruction: + """Creates a transaction instruction to initialize a new stake.""" + return TransactionInstruction( + keys=[ + AccountMeta(pubkey=params.stake, is_signer=False, is_writable=True), + AccountMeta(pubkey=SYSVAR_RENT_PUBKEY, is_signer=False, is_writable=False), + ], + program_id=STAKE_PROGRAM_ID, + data=INSTRUCTIONS_LAYOUT.build( + dict( + instruction_type=InstructionType.INITIALIZE, + args=dict( + authorized=params.authorized.as_bytes_dict(), + lockup=params.lockup.as_bytes_dict(), + ), + ) + ) + ) + + +def delegate_stake(params: DelegateStakeParams) -> TransactionInstruction: + """Creates an instruction to delegate a stake account.""" + return TransactionInstruction( + keys=[ + AccountMeta(pubkey=params.stake, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.vote, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.clock_sysvar, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.stake_history_sysvar, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.stake_config_id, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.staker, is_signer=True, is_writable=False), + ], + program_id=STAKE_PROGRAM_ID, + data=INSTRUCTIONS_LAYOUT.build( + dict( + instruction_type=InstructionType.DELEGATE_STAKE, + args=None, + ) + ) + ) + + +def authorize(params: AuthorizeParams) -> TransactionInstruction: + """Creates an instruction to change the authority on a stake account.""" + return TransactionInstruction( + keys=[ + AccountMeta(pubkey=params.stake, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.clock_sysvar, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.authority, is_signer=True, is_writable=False), + ], + program_id=STAKE_PROGRAM_ID, + data=INSTRUCTIONS_LAYOUT.build( + dict( + instruction_type=InstructionType.AUTHORIZE, + args={ + 'new_authority': bytes(params.new_authority), + 'stake_authorize': params.stake_authorize, + }, + ) + ) + ) diff --git a/clients/py/stake/state.py b/clients/py/stake/state.py new file mode 100644 index 00000000..38932e8d --- /dev/null +++ b/clients/py/stake/state.py @@ -0,0 +1,59 @@ +"""Stake State.""" + +from enum import IntEnum +from typing import NamedTuple, Dict +from construct import Container, Struct, Int64ul # type: ignore + +from solana.publickey import PublicKey +from solana._layouts.shared import PUBLIC_KEY_LAYOUT + + +class Lockup(NamedTuple): + """Lockup for a stake account.""" + unix_timestamp: int + epoch: int + custodian: PublicKey + + @classmethod + def decode_container(cls, container: Container): + return Lockup( + unix_timestamp=container['unix_timestamp'], + epoch=container['epoch'], + custodian=PublicKey(container['custodian']), + ) + + def as_bytes_dict(self) -> Dict: + self_dict = self._asdict() + self_dict['custodian'] = bytes(self_dict['custodian']) + return self_dict + + +class Authorized(NamedTuple): + """Define who is authorized to change a stake.""" + staker: PublicKey + withdrawer: PublicKey + + def as_bytes_dict(self) -> Dict: + return { + 'staker': bytes(self.staker), + 'withdrawer': bytes(self.withdrawer), + } + + +class StakeAuthorize(IntEnum): + """Stake Authorization Types.""" + STAKER = 0 + WITHDRAWER = 1 + + +LOCKUP_LAYOUT = Struct( + "unix_timestamp" / Int64ul, + "epoch" / Int64ul, + "custodian" / PUBLIC_KEY_LAYOUT, +) + + +AUTHORIZED_LAYOUT = Struct( + "staker" / PUBLIC_KEY_LAYOUT, + "withdrawer" / PUBLIC_KEY_LAYOUT, +) diff --git a/clients/py/stake_pool/__init__.py b/clients/py/stake_pool/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/clients/py/stake_pool/actions.py b/clients/py/stake_pool/actions.py new file mode 100644 index 00000000..54e4e3a6 --- /dev/null +++ b/clients/py/stake_pool/actions.py @@ -0,0 +1,572 @@ +from typing import Tuple + +from solana.keypair import Keypair +from solana.publickey import PublicKey +from solana.rpc.async_api import AsyncClient +from solana.rpc.commitment import Confirmed +from solana.rpc.types import TxOpts +from solana.sysvar import SYSVAR_CLOCK_PUBKEY, SYSVAR_RENT_PUBKEY, SYSVAR_STAKE_HISTORY_PUBKEY +from solana.transaction import Transaction +import solana.system_program as sys + +from spl.token.constants import TOKEN_PROGRAM_ID + +from stake.constants import STAKE_PROGRAM_ID, STAKE_LEN, SYSVAR_STAKE_CONFIG_ID +import stake.instructions as st +from stake.state import StakeAuthorize +from stake_pool.constants import \ + MAX_VALIDATORS_TO_UPDATE, \ + STAKE_POOL_PROGRAM_ID, \ + find_stake_program_address, \ + find_transient_stake_program_address, \ + find_withdraw_authority_program_address +from stake_pool.state import STAKE_POOL_LAYOUT, ValidatorList, Fee, StakePool +import stake_pool.instructions as sp + +from stake.actions import create_stake +from spl_token.actions import create_mint, create_associated_token_account + + +async def create(client: AsyncClient, manager: Keypair, + stake_pool: Keypair, validator_list: Keypair, + pool_mint: PublicKey, reserve_stake: PublicKey, + manager_fee_account: PublicKey, fee: Fee, referral_fee: int): + resp = await client.get_minimum_balance_for_rent_exemption(STAKE_POOL_LAYOUT.sizeof()) + pool_balance = resp['result'] + txn = Transaction() + txn.add( + sys.create_account( + sys.CreateAccountParams( + from_pubkey=manager.public_key, + new_account_pubkey=stake_pool.public_key, + lamports=pool_balance, + space=STAKE_POOL_LAYOUT.sizeof(), + program_id=STAKE_POOL_PROGRAM_ID, + ) + ) + ) + max_validators = 3950 # current supported max by the program, go big! + validator_list_size = ValidatorList.calculate_validator_list_size(max_validators) + resp = await client.get_minimum_balance_for_rent_exemption(validator_list_size) + validator_list_balance = resp['result'] + txn.add( + sys.create_account( + sys.CreateAccountParams( + from_pubkey=manager.public_key, + new_account_pubkey=validator_list.public_key, + lamports=validator_list_balance, + space=validator_list_size, + program_id=STAKE_POOL_PROGRAM_ID, + ) + ) + ) + await client.send_transaction( + txn, manager, stake_pool, validator_list, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + + txn = Transaction() + txn.add( + sp.initialize( + sp.InitializeParams( + program_id=STAKE_POOL_PROGRAM_ID, + stake_pool=stake_pool.public_key, + manager=manager.public_key, + staker=manager.public_key, + validator_list=validator_list.public_key, + reserve_stake=reserve_stake, + pool_mint=pool_mint, + manager_fee_account=manager_fee_account, + token_program_id=TOKEN_PROGRAM_ID, + epoch_fee=fee, + withdrawal_fee=fee, + deposit_fee=fee, + referral_fee=referral_fee, + max_validators=max_validators, + ) + ) + ) + await client.send_transaction( + txn, manager, validator_list, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + + +async def create_all(client: AsyncClient, manager: Keypair, fee: Fee, referral_fee: int) -> Tuple[PublicKey, PublicKey]: + stake_pool = Keypair() + validator_list = Keypair() + (pool_withdraw_authority, seed) = find_withdraw_authority_program_address( + STAKE_POOL_PROGRAM_ID, stake_pool.public_key) + + reserve_stake = Keypair() + await create_stake(client, manager, reserve_stake, pool_withdraw_authority, 1) + + pool_mint = Keypair() + await create_mint(client, manager, pool_mint, pool_withdraw_authority) + + manager_fee_account = await create_associated_token_account( + client, + manager, + manager.public_key, + pool_mint.public_key, + ) + + fee = Fee(numerator=1, denominator=1000) + referral_fee = 20 + await create( + client, manager, stake_pool, validator_list, pool_mint.public_key, + reserve_stake.public_key, manager_fee_account, fee, referral_fee) + return (stake_pool.public_key, validator_list.public_key) + + +async def add_validator_to_pool( + client: AsyncClient, funder: Keypair, + stake_pool_address: PublicKey, validator: PublicKey +): + resp = await client.get_account_info(stake_pool_address, commitment=Confirmed) + data = resp['result']['value']['data'] + stake_pool = StakePool.decode(data[0], data[1]) + txn = Transaction() + txn.add( + sp.add_validator_to_pool_with_vote( + STAKE_POOL_PROGRAM_ID, + stake_pool_address, + stake_pool.staker, + stake_pool.validator_list, + funder.public_key, + validator, + ) + ) + await client.send_transaction( + txn, funder, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + + +async def remove_validator_from_pool( + client: AsyncClient, staker: Keypair, + stake_pool_address: PublicKey, validator: PublicKey +): + resp = await client.get_account_info(stake_pool_address, commitment=Confirmed) + data = resp['result']['value']['data'] + stake_pool = StakePool.decode(data[0], data[1]) + resp = await client.get_account_info(stake_pool.validator_list, commitment=Confirmed) + data = resp['result']['value']['data'] + validator_list = ValidatorList.decode(data[0], data[1]) + validator_info = next(x for x in validator_list.validators if x.vote_account_address == validator) + destination_stake = Keypair() + txn = Transaction() + txn.add( + sys.create_account( + sys.CreateAccountParams( + from_pubkey=staker.public_key, + new_account_pubkey=destination_stake.public_key, + lamports=0, # will get filled by split + space=STAKE_LEN, + program_id=STAKE_PROGRAM_ID, + ) + ) + ) + txn.add( + sp.remove_validator_from_pool_with_vote( + STAKE_POOL_PROGRAM_ID, + stake_pool_address, + stake_pool.staker, + stake_pool.validator_list, + staker.public_key, + validator, + validator_info.transient_seed_suffix_start, + destination_stake.public_key + ) + ) + await client.send_transaction( + txn, staker, destination_stake, + opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + + +async def deposit_sol( + client: AsyncClient, funder: Keypair, stake_pool_address: PublicKey, + destination_token_account: PublicKey, amount: int, +): + resp = await client.get_account_info(stake_pool_address, commitment=Confirmed) + data = resp['result']['value']['data'] + stake_pool = StakePool.decode(data[0], data[1]) + + (withdraw_authority, seed) = find_withdraw_authority_program_address(STAKE_POOL_PROGRAM_ID, stake_pool_address) + + txn = Transaction() + txn.add( + sp.deposit_sol( + sp.DepositSolParams( + program_id=STAKE_POOL_PROGRAM_ID, + stake_pool=stake_pool_address, + withdraw_authority=withdraw_authority, + reserve_stake=stake_pool.reserve_stake, + funding_account=funder.public_key, + destination_pool_account=destination_token_account, + manager_fee_account=stake_pool.manager_fee_account, + referral_pool_account=destination_token_account, + pool_mint=stake_pool.pool_mint, + system_program_id=sys.SYS_PROGRAM_ID, + token_program_id=stake_pool.token_program_id, + amount=amount, + deposit_authority=None, + ) + ) + ) + await client.send_transaction( + txn, funder, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + + +async def withdraw_sol( + client: AsyncClient, owner: Keypair, source_token_account: PublicKey, + stake_pool_address: PublicKey, destination_system_account: PublicKey, amount: int, +): + resp = await client.get_account_info(stake_pool_address, commitment=Confirmed) + data = resp['result']['value']['data'] + stake_pool = StakePool.decode(data[0], data[1]) + + (withdraw_authority, seed) = find_withdraw_authority_program_address(STAKE_POOL_PROGRAM_ID, stake_pool_address) + + txn = Transaction() + txn.add( + sp.withdraw_sol( + sp.WithdrawSolParams( + program_id=STAKE_POOL_PROGRAM_ID, + stake_pool=stake_pool_address, + withdraw_authority=withdraw_authority, + source_transfer_authority=owner.public_key, + source_pool_account=source_token_account, + reserve_stake=stake_pool.reserve_stake, + destination_system_account=destination_system_account, + manager_fee_account=stake_pool.manager_fee_account, + pool_mint=stake_pool.pool_mint, + clock_sysvar=SYSVAR_CLOCK_PUBKEY, + stake_history_sysvar=SYSVAR_STAKE_HISTORY_PUBKEY, + stake_program_id=STAKE_PROGRAM_ID, + token_program_id=stake_pool.token_program_id, + amount=amount, + sol_withdraw_authority=None, + ) + ) + ) + await client.send_transaction( + txn, owner, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + + +async def deposit_stake( + client: AsyncClient, + deposit_stake_authority: Keypair, + stake_pool_address: PublicKey, + validator_vote: PublicKey, + deposit_stake: PublicKey, + destination_pool_account: PublicKey, +): + resp = await client.get_account_info(stake_pool_address, commitment=Confirmed) + data = resp['result']['value']['data'] + stake_pool = StakePool.decode(data[0], data[1]) + + (withdraw_authority, _) = find_withdraw_authority_program_address(STAKE_POOL_PROGRAM_ID, stake_pool_address) + (validator_stake, _) = find_stake_program_address( + STAKE_POOL_PROGRAM_ID, + validator_vote, + stake_pool_address, + ) + + txn = Transaction() + txn.add( + st.authorize( + st.AuthorizeParams( + stake=deposit_stake, + clock_sysvar=SYSVAR_CLOCK_PUBKEY, + authority=deposit_stake_authority.public_key, + new_authority=stake_pool.stake_deposit_authority, + stake_authorize=StakeAuthorize.STAKER, + ) + ) + ) + txn.add( + st.authorize( + st.AuthorizeParams( + stake=deposit_stake, + clock_sysvar=SYSVAR_CLOCK_PUBKEY, + authority=deposit_stake_authority.public_key, + new_authority=stake_pool.stake_deposit_authority, + stake_authorize=StakeAuthorize.WITHDRAWER, + ) + ) + ) + txn.add( + sp.deposit_stake( + sp.DepositStakeParams( + program_id=STAKE_POOL_PROGRAM_ID, + stake_pool=stake_pool_address, + validator_list=stake_pool.validator_list, + deposit_authority=stake_pool.stake_deposit_authority, + withdraw_authority=withdraw_authority, + deposit_stake=deposit_stake, + validator_stake=validator_stake, + reserve_stake=stake_pool.reserve_stake, + destination_pool_account=destination_pool_account, + manager_fee_account=stake_pool.manager_fee_account, + referral_pool_account=destination_pool_account, + pool_mint=stake_pool.pool_mint, + clock_sysvar=SYSVAR_CLOCK_PUBKEY, + stake_history_sysvar=SYSVAR_STAKE_HISTORY_PUBKEY, + token_program_id=stake_pool.token_program_id, + stake_program_id=STAKE_PROGRAM_ID, + ) + ) + ) + await client.send_transaction( + txn, deposit_stake_authority, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + + +async def withdraw_stake( + client: AsyncClient, + payer: Keypair, + source_transfer_authority: Keypair, + destination_stake: Keypair, + stake_pool_address: PublicKey, + validator_vote: PublicKey, + destination_stake_authority: PublicKey, + source_pool_account: PublicKey, + amount: int, +): + resp = await client.get_account_info(stake_pool_address, commitment=Confirmed) + data = resp['result']['value']['data'] + stake_pool = StakePool.decode(data[0], data[1]) + + (withdraw_authority, _) = find_withdraw_authority_program_address(STAKE_POOL_PROGRAM_ID, stake_pool_address) + (validator_stake, _) = find_stake_program_address( + STAKE_POOL_PROGRAM_ID, + validator_vote, + stake_pool_address, + ) + + resp = await client.get_minimum_balance_for_rent_exemption(STAKE_LEN) + stake_rent_exemption = resp['result'] + + txn = Transaction() + txn.add( + sys.create_account( + sys.CreateAccountParams( + from_pubkey=payer.public_key, + new_account_pubkey=destination_stake.public_key, + lamports=stake_rent_exemption, + space=STAKE_LEN, + program_id=STAKE_PROGRAM_ID, + ) + ) + ) + txn.add( + sp.withdraw_stake( + sp.WithdrawStakeParams( + program_id=STAKE_POOL_PROGRAM_ID, + stake_pool=stake_pool_address, + validator_list=stake_pool.validator_list, + withdraw_authority=withdraw_authority, + validator_stake=validator_stake, + destination_stake=destination_stake.public_key, + destination_stake_authority=destination_stake_authority, + source_transfer_authority=source_transfer_authority.public_key, + source_pool_account=source_pool_account, + manager_fee_account=stake_pool.manager_fee_account, + pool_mint=stake_pool.pool_mint, + clock_sysvar=SYSVAR_CLOCK_PUBKEY, + token_program_id=stake_pool.token_program_id, + stake_program_id=STAKE_PROGRAM_ID, + amount=amount, + ) + ) + ) + signers = [payer, source_transfer_authority, destination_stake] \ + if payer != source_transfer_authority else [payer, destination_stake] + await client.send_transaction( + txn, *signers, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + + +async def update_stake_pool(client: AsyncClient, payer: Keypair, stake_pool_address: PublicKey): + """Create and send all instructions to completely update a stake pool after epoch change.""" + resp = await client.get_account_info(stake_pool_address, commitment=Confirmed) + data = resp['result']['value']['data'] + stake_pool = StakePool.decode(data[0], data[1]) + resp = await client.get_account_info(stake_pool.validator_list, commitment=Confirmed) + data = resp['result']['value']['data'] + validator_list = ValidatorList.decode(data[0], data[1]) + (withdraw_authority, seed) = find_withdraw_authority_program_address(STAKE_POOL_PROGRAM_ID, stake_pool_address) + update_list_instructions = [] + validator_chunks = [ + validator_list.validators[i:i+MAX_VALIDATORS_TO_UPDATE] + for i in range(0, len(validator_list.validators), MAX_VALIDATORS_TO_UPDATE) + ] + start_index = 0 + for validator_chunk in validator_chunks: + validator_and_transient_stake_pairs = [] + for validator in validator_chunk: + (validator_stake_address, _) = find_stake_program_address( + STAKE_POOL_PROGRAM_ID, + validator.vote_account_address, + stake_pool_address, + ) + validator_and_transient_stake_pairs.append(validator_stake_address) + (transient_stake_address, _) = find_transient_stake_program_address( + STAKE_POOL_PROGRAM_ID, + validator.vote_account_address, + stake_pool_address, + validator.transient_seed_suffix_start, + ) + validator_and_transient_stake_pairs.append(transient_stake_address) + update_list_instructions.append( + sp.update_validator_list_balance( + sp.UpdateValidatorListBalanceParams( + program_id=STAKE_POOL_PROGRAM_ID, + stake_pool=stake_pool_address, + withdraw_authority=withdraw_authority, + validator_list=stake_pool.validator_list, + reserve_stake=stake_pool.reserve_stake, + clock_sysvar=SYSVAR_CLOCK_PUBKEY, + stake_history_sysvar=SYSVAR_STAKE_HISTORY_PUBKEY, + stake_program_id=STAKE_PROGRAM_ID, + validator_and_transient_stake_pairs=validator_and_transient_stake_pairs, + start_index=start_index, + no_merge=False, + ) + ) + ) + start_index += MAX_VALIDATORS_TO_UPDATE + if update_list_instructions: + last_instruction = update_list_instructions.pop() + for update_list_instruction in update_list_instructions: + txn = Transaction() + txn.add(update_list_instruction) + await client.send_transaction( + txn, payer, opts=TxOpts(skip_confirmation=True, preflight_commitment=Confirmed)) + txn = Transaction() + txn.add(last_instruction) + await client.send_transaction( + txn, payer, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + txn = Transaction() + txn.add( + sp.update_stake_pool_balance( + sp.UpdateStakePoolBalanceParams( + program_id=STAKE_POOL_PROGRAM_ID, + stake_pool=stake_pool_address, + withdraw_authority=withdraw_authority, + validator_list=stake_pool.validator_list, + reserve_stake=stake_pool.reserve_stake, + manager_fee_account=stake_pool.manager_fee_account, + pool_mint=stake_pool.pool_mint, + token_program_id=stake_pool.token_program_id, + ) + ) + ) + txn.add( + sp.cleanup_removed_validator_entries( + sp.CleanupRemovedValidatorEntriesParams( + program_id=STAKE_POOL_PROGRAM_ID, + stake_pool=stake_pool_address, + validator_list=stake_pool.validator_list, + ) + ) + ) + await client.send_transaction( + txn, payer, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + + +async def increase_validator_stake( + client: AsyncClient, payer: Keypair, staker: Keypair, stake_pool_address: PublicKey, + validator_vote: PublicKey, lamports: int +): + resp = await client.get_account_info(stake_pool_address, commitment=Confirmed) + data = resp['result']['value']['data'] + stake_pool = StakePool.decode(data[0], data[1]) + + resp = await client.get_account_info(stake_pool.validator_list, commitment=Confirmed) + data = resp['result']['value']['data'] + validator_list = ValidatorList.decode(data[0], data[1]) + (withdraw_authority, seed) = find_withdraw_authority_program_address(STAKE_POOL_PROGRAM_ID, stake_pool_address) + + validator_info = next(x for x in validator_list.validators if x.vote_account_address == validator_vote) + transient_stake_seed = validator_info.transient_seed_suffix_start + 1 # bump up by one to avoid reuse + (transient_stake, _) = find_transient_stake_program_address( + STAKE_POOL_PROGRAM_ID, + validator_info.vote_account_address, + stake_pool_address, + transient_stake_seed, + ) + + txn = Transaction() + txn.add( + sp.increase_validator_stake( + sp.IncreaseValidatorStakeParams( + program_id=STAKE_POOL_PROGRAM_ID, + stake_pool=stake_pool_address, + staker=staker.public_key, + withdraw_authority=withdraw_authority, + validator_list=stake_pool.validator_list, + reserve_stake=stake_pool.reserve_stake, + transient_stake=transient_stake, + validator_vote=validator_vote, + clock_sysvar=SYSVAR_CLOCK_PUBKEY, + rent_sysvar=SYSVAR_RENT_PUBKEY, + stake_history_sysvar=SYSVAR_STAKE_HISTORY_PUBKEY, + stake_config_sysvar=SYSVAR_STAKE_CONFIG_ID, + system_program_id=sys.SYS_PROGRAM_ID, + stake_program_id=STAKE_PROGRAM_ID, + lamports=lamports, + transient_stake_seed=transient_stake_seed, + ) + ) + ) + + signers = [payer, staker] if payer != staker else [payer] + await client.send_transaction( + txn, *signers, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + + +async def decrease_validator_stake( + client: AsyncClient, payer: Keypair, staker: Keypair, stake_pool_address: PublicKey, + validator_vote: PublicKey, lamports: int +): + resp = await client.get_account_info(stake_pool_address, commitment=Confirmed) + data = resp['result']['value']['data'] + stake_pool = StakePool.decode(data[0], data[1]) + + resp = await client.get_account_info(stake_pool.validator_list, commitment=Confirmed) + data = resp['result']['value']['data'] + validator_list = ValidatorList.decode(data[0], data[1]) + (withdraw_authority, seed) = find_withdraw_authority_program_address(STAKE_POOL_PROGRAM_ID, stake_pool_address) + + validator_info = next(x for x in validator_list.validators if x.vote_account_address == validator_vote) + (validator_stake, _) = find_stake_program_address( + STAKE_POOL_PROGRAM_ID, + validator_info.vote_account_address, + stake_pool_address, + ) + transient_stake_seed = validator_info.transient_seed_suffix_start + 1 # bump up by one to avoid reuse + (transient_stake, _) = find_transient_stake_program_address( + STAKE_POOL_PROGRAM_ID, + validator_info.vote_account_address, + stake_pool_address, + transient_stake_seed, + ) + + txn = Transaction() + txn.add( + sp.decrease_validator_stake( + sp.DecreaseValidatorStakeParams( + program_id=STAKE_POOL_PROGRAM_ID, + stake_pool=stake_pool_address, + staker=staker.public_key, + withdraw_authority=withdraw_authority, + validator_list=stake_pool.validator_list, + validator_stake=validator_stake, + transient_stake=transient_stake, + clock_sysvar=SYSVAR_CLOCK_PUBKEY, + rent_sysvar=SYSVAR_RENT_PUBKEY, + system_program_id=sys.SYS_PROGRAM_ID, + stake_program_id=STAKE_PROGRAM_ID, + lamports=lamports, + transient_stake_seed=transient_stake_seed, + ) + ) + ) + + signers = [payer, staker] if payer != staker else [payer] + await client.send_transaction( + txn, *signers, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) diff --git a/clients/py/stake_pool/constants.py b/clients/py/stake_pool/constants.py new file mode 100644 index 00000000..6e9f6a35 --- /dev/null +++ b/clients/py/stake_pool/constants.py @@ -0,0 +1,74 @@ +"""SPL Stake Pool Constants.""" + +from typing import Tuple + +from solana.publickey import PublicKey + +STAKE_POOL_PROGRAM_ID: PublicKey = PublicKey("SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy") +"""Public key that identifies the SPL Stake Pool program.""" + +MAX_VALIDATORS_TO_UPDATE: int = 5 +"""Maximum number of validators to update during UpdateValidatorListBalance.""" + + +def find_deposit_authority_program_address( + program_id: PublicKey, + stake_pool_address: PublicKey, +) -> Tuple[PublicKey, int]: + """Generates the deposit authority program address for the stake pool""" + return PublicKey.find_program_address( + [bytes(stake_pool_address), AUTHORITY_DEPOSIT], + program_id, + ) + + +def find_withdraw_authority_program_address( + program_id: PublicKey, + stake_pool_address: PublicKey, +) -> Tuple[PublicKey, int]: + """Generates the withdraw authority program address for the stake pool""" + return PublicKey.find_program_address( + [bytes(stake_pool_address), AUTHORITY_WITHDRAW], + program_id, + ) + + +def find_stake_program_address( + program_id: PublicKey, + vote_account_address: PublicKey, + stake_pool_address: PublicKey, +) -> Tuple[PublicKey, int]: + """Generates the stake program address for a validator's vote account""" + return PublicKey.find_program_address( + [ + bytes(vote_account_address), + bytes(stake_pool_address), + ], + program_id, + ) + + +def find_transient_stake_program_address( + program_id: PublicKey, + vote_account_address: PublicKey, + stake_pool_address: PublicKey, + seed: int, +) -> Tuple[PublicKey, int]: + """Generates the stake program address for a validator's vote account""" + return PublicKey.find_program_address( + [ + TRANSIENT_STAKE_SEED_PREFIX, + bytes(vote_account_address), + bytes(stake_pool_address), + seed.to_bytes(8, 'little'), + ], + program_id, + ) + + +AUTHORITY_DEPOSIT = b"deposit" +"""Seed used to derive the default stake pool deposit authority.""" +AUTHORITY_WITHDRAW = b"withdraw" +"""Seed used to derive the stake pool withdraw authority.""" +TRANSIENT_STAKE_SEED_PREFIX = b"transient" +"""Seed used to derive transient stake accounts.""" diff --git a/clients/py/stake_pool/instructions.py b/clients/py/stake_pool/instructions.py new file mode 100644 index 00000000..e0f17abf --- /dev/null +++ b/clients/py/stake_pool/instructions.py @@ -0,0 +1,912 @@ +"""SPL Stake Pool Instructions.""" + +from enum import IntEnum +from typing import List, NamedTuple, Optional +from construct import Struct, Switch, Int8ul, Int32ul, Int64ul, Pass # type: ignore + +from solana.publickey import PublicKey +from solana.transaction import AccountMeta, TransactionInstruction +from solana.system_program import SYS_PROGRAM_ID +from solana.sysvar import SYSVAR_CLOCK_PUBKEY, SYSVAR_RENT_PUBKEY, SYSVAR_STAKE_HISTORY_PUBKEY +from spl.token.constants import TOKEN_PROGRAM_ID + +from stake.constants import STAKE_PROGRAM_ID, SYSVAR_STAKE_CONFIG_ID +from stake_pool.constants import find_stake_program_address, find_transient_stake_program_address +from stake_pool.constants import find_withdraw_authority_program_address +from stake_pool.constants import STAKE_POOL_PROGRAM_ID +from stake_pool.state import Fee, FEE_LAYOUT + + +class PreferredValidatorType(IntEnum): + """Specifies the validator type for SetPreferredValidator instruction.""" + + DEPOSIT = 0 + """Specifies the preferred deposit validator.""" + WITHDRAW = 1 + """Specifies the preferred withdraw validator.""" + + +class FundingType(IntEnum): + """Defines which authority to update in the `SetFundingAuthority` instruction.""" + + STAKE_DEPOSIT = 0 + """Sets the stake deposit authority.""" + SOL_DEPOSIT = 1 + """Sets the SOL deposit authority.""" + SOL_WITHDRAW = 2 + """Sets the SOL withdraw authority.""" + + +class InitializeParams(NamedTuple): + """Initialize token mint transaction params.""" + + # Accounts + program_id: PublicKey + """SPL Stake Pool program account.""" + stake_pool: PublicKey + """[w] Stake Pool account to initialize.""" + manager: PublicKey + """[s] Manager for new stake pool.""" + staker: PublicKey + """[] Staker for the new stake pool.""" + validator_list: PublicKey + """[w] Uninitialized validator list account for the new stake pool.""" + reserve_stake: PublicKey + """[] Reserve stake account.""" + pool_mint: PublicKey + """[] Pool token mint account.""" + manager_fee_account: PublicKey + """[] Manager's fee account""" + token_program_id: PublicKey + """[] SPL Token program id.""" + + # Params + epoch_fee: Fee + """Fee assessed as percentage of rewards.""" + withdrawal_fee: Fee + """Fee charged per withdrawal.""" + deposit_fee: Fee + """Fee charged per deposit.""" + referral_fee: int + """Percentage [0-100] of deposit fee that goes to referrer.""" + max_validators: int + """Maximum number of possible validators in the pool.""" + + # Optional + deposit_authority: Optional[PublicKey] = None + """[] Optional deposit authority that must sign all deposits.""" + + +class AddValidatorToPoolParams(NamedTuple): + """(Staker only) Adds stake account delegated to validator to the pool's list of managed validators.""" + + program_id: PublicKey + """SPL Stake Pool program account.""" + stake_pool: PublicKey + """`[w]` Stake pool.""" + staker: PublicKey + """`[s]` Staker.""" + funding_account: PublicKey + """`[ws]` Funding account (must be a system account).""" + withdraw_authority: PublicKey + """`[]` Stake pool withdraw authority.""" + validator_list: PublicKey + """`[w]` Validator stake list storage account.""" + validator_stake: PublicKey + """`[w]` Stake account to add to the pool.""" + validator_vote: PublicKey + """`[]` Validator this stake account will be delegated to.""" + rent_sysvar: PublicKey + """`[]` Rent sysvar.""" + clock_sysvar: PublicKey + """`[]` Clock sysvar.""" + stake_history_sysvar: PublicKey + """'[]' Stake history sysvar.""" + stake_config_sysvar: PublicKey + """'[]' Stake config sysvar.""" + system_program_id: PublicKey + """`[]` System program.""" + stake_program_id: PublicKey + """`[]` Stake program.""" + + +class RemoveValidatorFromPoolParams(NamedTuple): + """(Staker only) Removes validator from the pool.""" + + program_id: PublicKey + """SPL Stake Pool program account.""" + stake_pool: PublicKey + """`[w]` Stake pool.""" + staker: PublicKey + """`[s]` Staker.""" + withdraw_authority: PublicKey + """`[]` Stake pool withdraw authority.""" + new_stake_authority: PublicKey + """`[]` New stake / withdraw authority on the split stake account.""" + validator_list: PublicKey + """`[w]` Validator stake list storage account.""" + validator_stake: PublicKey + """`[w]` Stake account to remove from the pool.""" + transient_stake: PublicKey + """`[]` Transient stake account, to check that there's no activation ongoing.""" + destination_stake: PublicKey + """`[w]` Destination stake account, to receive the minimum SOL from the validator stake account.""" + clock_sysvar: PublicKey + """'[]' Stake config sysvar.""" + stake_program_id: PublicKey + """`[]` Stake program.""" + + +class DecreaseValidatorStakeParams(NamedTuple): + """(Staker only) Decrease active stake on a validator, eventually moving it to the reserve""" + + # Accounts + program_id: PublicKey + """SPL Stake Pool program account.""" + stake_pool: PublicKey + """`[]` Stake pool.""" + staker: PublicKey + """`[s]` Staker.""" + withdraw_authority: PublicKey + """`[]` Stake pool withdraw authority.""" + validator_list: PublicKey + """`[w]` Validator stake list storage account.""" + validator_stake: PublicKey + """`[w]` Canonical stake to split from.""" + transient_stake: PublicKey + """`[w]` Transient stake account to receive split.""" + clock_sysvar: PublicKey + """`[]` Clock sysvar.""" + rent_sysvar: PublicKey + """`[]` Rent sysvar.""" + system_program_id: PublicKey + """`[]` System program.""" + stake_program_id: PublicKey + """`[]` Stake program.""" + + # Params + lamports: int + """Amount of lamports to split into the transient stake account.""" + transient_stake_seed: int + """Seed to used to create the transient stake account.""" + + +class IncreaseValidatorStakeParams(NamedTuple): + """(Staker only) Increase stake on a validator from the reserve account.""" + + # Accounts + program_id: PublicKey + """SPL Stake Pool program account.""" + stake_pool: PublicKey + """`[]` Stake pool.""" + staker: PublicKey + """`[s]` Staker.""" + withdraw_authority: PublicKey + """`[]` Stake pool withdraw authority.""" + validator_list: PublicKey + """`[w]` Validator stake list storage account.""" + reserve_stake: PublicKey + """`[w]` Stake pool's reserve.""" + transient_stake: PublicKey + """`[w]` Transient stake account to receive split.""" + validator_vote: PublicKey + """`[]` Validator vote account to delegate to.""" + clock_sysvar: PublicKey + """`[]` Clock sysvar.""" + rent_sysvar: PublicKey + """`[]` Rent sysvar.""" + stake_history_sysvar: PublicKey + """'[]' Stake history sysvar.""" + stake_config_sysvar: PublicKey + """'[]' Stake config sysvar.""" + system_program_id: PublicKey + """`[]` System program.""" + stake_program_id: PublicKey + """`[]` Stake program.""" + + # Params + lamports: int + """Amount of lamports to split into the transient stake account.""" + transient_stake_seed: int + """Seed to used to create the transient stake account.""" + + +class SetPreferredValidatorParams(NamedTuple): + pass + + +class UpdateValidatorListBalanceParams(NamedTuple): + """Updates balances of validator and transient stake accounts in the pool.""" + + # Accounts + program_id: PublicKey + """SPL Stake Pool program account.""" + stake_pool: PublicKey + """`[]` Stake pool.""" + withdraw_authority: PublicKey + """`[]` Stake pool withdraw authority.""" + validator_list: PublicKey + """`[w]` Validator stake list storage account.""" + reserve_stake: PublicKey + """`[w]` Stake pool's reserve.""" + clock_sysvar: PublicKey + """`[]` Clock sysvar.""" + stake_history_sysvar: PublicKey + """'[]' Stake history sysvar.""" + stake_program_id: PublicKey + """`[]` Stake program.""" + validator_and_transient_stake_pairs: List[PublicKey] + """[] N pairs of validator and transient stake accounts""" + + # Params + start_index: int + """Index to start updating on the validator list.""" + no_merge: bool + """If true, don't try merging transient stake accounts.""" + + +class UpdateStakePoolBalanceParams(NamedTuple): + """Updates total pool balance based on balances in the reserve and validator list.""" + + program_id: PublicKey + """SPL Stake Pool program account.""" + stake_pool: PublicKey + """`[w]` Stake pool.""" + withdraw_authority: PublicKey + """`[]` Stake pool withdraw authority.""" + validator_list: PublicKey + """`[w]` Validator stake list storage account.""" + reserve_stake: PublicKey + """`[w]` Stake pool's reserve.""" + manager_fee_account: PublicKey + """`[w]` Account to receive pool fee tokens.""" + pool_mint: PublicKey + """`[w]` Pool mint account.""" + token_program_id: PublicKey + """`[]` Pool token program.""" + + +class CleanupRemovedValidatorEntriesParams(NamedTuple): + """Cleans up validator stake account entries marked as `ReadyForRemoval`""" + + program_id: PublicKey + """SPL Stake Pool program account.""" + stake_pool: PublicKey + """`[w]` Stake pool.""" + validator_list: PublicKey + """`[w]` Validator stake list storage account.""" + + +class DepositStakeParams(NamedTuple): + """Deposits a stake account into the pool in exchange for pool tokens""" + + program_id: PublicKey + """SPL Stake Pool program account.""" + stake_pool: PublicKey + """`[w]` Stake pool""" + validator_list: PublicKey + """`[w]` Validator stake list storage account""" + deposit_authority: PublicKey + """`[s]/[]` Stake pool deposit authority""" + withdraw_authority: PublicKey + """`[]` Stake pool withdraw authority""" + deposit_stake: PublicKey + """`[w]` Stake account to join the pool (stake's withdraw authority set to the stake pool deposit authority)""" + validator_stake: PublicKey + """`[w]` Validator stake account for the stake account to be merged with""" + reserve_stake: PublicKey + """`[w]` Reserve stake account, to withdraw rent exempt reserve""" + destination_pool_account: PublicKey + """`[w]` User account to receive pool tokens""" + manager_fee_account: PublicKey + """`[w]` Account to receive pool fee tokens""" + referral_pool_account: PublicKey + """`[w]` Account to receive a portion of pool fee tokens as referral fees""" + pool_mint: PublicKey + """`[w]` Pool token mint account""" + clock_sysvar: PublicKey + """`[]` Sysvar clock account""" + stake_history_sysvar: PublicKey + """`[]` Sysvar stake history account""" + token_program_id: PublicKey + """`[]` Pool token program id""" + stake_program_id: PublicKey + """`[]` Stake program id""" + + +class WithdrawStakeParams(NamedTuple): + """Withdraws a stake account from the pool in exchange for pool tokens""" + + program_id: PublicKey + """SPL Stake Pool program account.""" + stake_pool: PublicKey + """`[w]` Stake pool""" + validator_list: PublicKey + """`[w]` Validator stake list storage account""" + withdraw_authority: PublicKey + """`[]` Stake pool withdraw authority""" + validator_stake: PublicKey + """`[w]` Validator or reserve stake account to split""" + destination_stake: PublicKey + """`[w]` Unitialized stake account to receive withdrawal""" + destination_stake_authority: PublicKey + """`[]` User account to set as a new withdraw authority""" + source_transfer_authority: PublicKey + """`[s]` User transfer authority, for pool token account""" + source_pool_account: PublicKey + """`[w]` User account with pool tokens to burn from""" + manager_fee_account: PublicKey + """`[w]` Account to receive pool fee tokens""" + pool_mint: PublicKey + """`[w]` Pool token mint account""" + clock_sysvar: PublicKey + """`[]` Sysvar clock account""" + token_program_id: PublicKey + """`[]` Pool token program id""" + stake_program_id: PublicKey + """`[]` Stake program id""" + + # Params + amount: int + """Amount of pool tokens to burn in exchange for stake""" + + +class SetManagerParams(NamedTuple): + pass + + +class SetFeeParams(NamedTuple): + pass + + +class SetStakerParams(NamedTuple): + pass + + +class DepositSolParams(NamedTuple): + """Deposit SOL directly into the pool's reserve account. The output is a "pool" token + representing ownership into the pool. Inputs are converted to the current ratio.""" + + # Accounts + program_id: PublicKey + """SPL Stake Pool program account.""" + stake_pool: PublicKey + """`[w]` Stake pool.""" + withdraw_authority: PublicKey + """`[]` Stake pool withdraw authority.""" + reserve_stake: PublicKey + """`[w]` Stake pool's reserve.""" + funding_account: PublicKey + """`[ws]` Funding account (must be a system account).""" + destination_pool_account: PublicKey + """`[w]` User account to receive pool tokens.""" + manager_fee_account: PublicKey + """`[w]` Manager's pool token account to receive deposit fee.""" + referral_pool_account: PublicKey + """`[w]` Referrer pool token account to receive referral fee.""" + pool_mint: PublicKey + """`[w]` Pool token mint.""" + system_program_id: PublicKey + """`[]` System program.""" + token_program_id: PublicKey + """`[]` Token program.""" + + # Params + amount: int + """Amount of SOL to deposit""" + + # Optional + deposit_authority: Optional[PublicKey] = None + """`[s]` (Optional) Stake pool sol deposit authority.""" + + +class SetFundingAuthorityParams(NamedTuple): + pass + + +class WithdrawSolParams(NamedTuple): + """Withdraw SOL directly from the pool's reserve account.""" + + # Accounts + program_id: PublicKey + """SPL Stake Pool program account.""" + stake_pool: PublicKey + """`[w]` Stake pool.""" + withdraw_authority: PublicKey + """`[]` Stake pool withdraw authority.""" + source_transfer_authority: PublicKey + """`[s]` Transfer authority for user pool token account.""" + source_pool_account: PublicKey + """`[w]` User's pool token account to burn pool tokens.""" + reserve_stake: PublicKey + """`[w]` Stake pool's reserve.""" + destination_system_account: PublicKey + """`[w]` Destination system account to receive lamports from the reserve.""" + manager_fee_account: PublicKey + """`[w]` Manager's pool token account to receive fee.""" + pool_mint: PublicKey + """`[w]` Pool token mint.""" + clock_sysvar: PublicKey + """`[]` Clock sysvar.""" + stake_history_sysvar: PublicKey + """'[]' Stake history sysvar.""" + stake_program_id: PublicKey + """`[]` Stake program.""" + token_program_id: PublicKey + """`[]` Token program.""" + + # Params + amount: int + """Amount of pool tokens to burn""" + + # Optional + sol_withdraw_authority: Optional[PublicKey] = None + """`[s]` (Optional) Stake pool sol withdraw authority.""" + + +class InstructionType(IntEnum): + """Stake Pool Instruction Types.""" + + INITIALIZE = 0 + ADD_VALIDATOR_TO_POOL = 1 + REMOVE_VALIDATOR_FROM_POOL = 2 + DECREASE_VALIDATOR_STAKE = 3 + INCREASE_VALIDATOR_STAKE = 4 + SET_PREFERRED_VALIDATOR = 5 + UPDATE_VALIDATOR_LIST_BALANCE = 6 + UPDATE_STAKE_POOL_BALANCE = 7 + CLEANUP_REMOVED_VALIDATOR_ENTRIES = 8 + DEPOSIT_STAKE = 9 + WITHDRAW_STAKE = 10 + SET_MANAGER = 11 + SET_FEE = 12 + SET_STAKER = 13 + DEPOSIT_SOL = 14 + SET_FUNDING_AUTHORITY = 15 + WITHDRAW_SOL = 16 + + +INITIALIZE_LAYOUT = Struct( + "epoch_fee" / FEE_LAYOUT, + "withdrawal_fee" / FEE_LAYOUT, + "deposit_fee" / FEE_LAYOUT, + "referral_fee" / Int8ul, + "max_validators" / Int32ul, +) + +MOVE_STAKE_LAYOUT = Struct( + "lamports" / Int64ul, + "transient_stake_seed" / Int64ul, +) + +UPDATE_VALIDATOR_LIST_BALANCE_LAYOUT = Struct( + "start_index" / Int32ul, + "no_merge" / Int8ul, +) + +AMOUNT_LAYOUT = Struct( + "amount" / Int64ul +) + +INSTRUCTIONS_LAYOUT = Struct( + "instruction_type" / Int8ul, + "args" + / Switch( + lambda this: this.instruction_type, + { + InstructionType.INITIALIZE: INITIALIZE_LAYOUT, + InstructionType.ADD_VALIDATOR_TO_POOL: Pass, + InstructionType.REMOVE_VALIDATOR_FROM_POOL: Pass, + InstructionType.DECREASE_VALIDATOR_STAKE: MOVE_STAKE_LAYOUT, + InstructionType.INCREASE_VALIDATOR_STAKE: MOVE_STAKE_LAYOUT, + InstructionType.SET_PREFERRED_VALIDATOR: Pass, # TODO + InstructionType.UPDATE_VALIDATOR_LIST_BALANCE: UPDATE_VALIDATOR_LIST_BALANCE_LAYOUT, + InstructionType.UPDATE_STAKE_POOL_BALANCE: Pass, + InstructionType.CLEANUP_REMOVED_VALIDATOR_ENTRIES: Pass, + InstructionType.DEPOSIT_STAKE: Pass, + InstructionType.WITHDRAW_STAKE: AMOUNT_LAYOUT, + InstructionType.SET_MANAGER: Pass, + InstructionType.SET_FEE: Pass, # TODO + InstructionType.SET_STAKER: Pass, + InstructionType.DEPOSIT_SOL: AMOUNT_LAYOUT, + InstructionType.SET_FUNDING_AUTHORITY: Pass, # TODO + InstructionType.WITHDRAW_SOL: AMOUNT_LAYOUT, + }, + ), +) + + +def initialize(params: InitializeParams) -> TransactionInstruction: + """Creates a transaction instruction to initialize a new stake pool.""" + + data = INSTRUCTIONS_LAYOUT.build( + dict( + instruction_type=InstructionType.INITIALIZE, + args=dict( + epoch_fee=params.epoch_fee._asdict(), + withdrawal_fee=params.withdrawal_fee._asdict(), + deposit_fee=params.deposit_fee._asdict(), + referral_fee=params.referral_fee, + max_validators=params.max_validators + ), + ) + ) + keys = [ + AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.manager, is_signer=True, is_writable=False), + AccountMeta(pubkey=params.staker, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.validator_list, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.reserve_stake, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.pool_mint, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.manager_fee_account, is_signer=False, is_writable=False), + AccountMeta(pubkey=TOKEN_PROGRAM_ID, is_signer=False, is_writable=False), + ] + if params.deposit_authority: + keys.append( + AccountMeta(pubkey=params.deposit_authority, is_signer=True, is_writable=False), + ) + return TransactionInstruction( + keys=keys, + program_id=params.program_id, + data=data, + ) + + +def add_validator_to_pool(params: AddValidatorToPoolParams) -> TransactionInstruction: + """Creates instruction to add a validator to the pool.""" + return TransactionInstruction( + keys=[ + AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.staker, is_signer=True, is_writable=False), + AccountMeta(pubkey=params.funding_account, is_signer=True, is_writable=True), + AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.validator_list, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.validator_stake, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.validator_vote, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.rent_sysvar, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.clock_sysvar, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.stake_history_sysvar, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.stake_config_sysvar, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.system_program_id, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.stake_program_id, is_signer=False, is_writable=False), + ], + program_id=params.program_id, + data=INSTRUCTIONS_LAYOUT.build( + dict( + instruction_type=InstructionType.ADD_VALIDATOR_TO_POOL, + args=None + ) + ) + ) + + +def add_validator_to_pool_with_vote( + program_id: PublicKey, + stake_pool: PublicKey, + staker: PublicKey, + validator_list: PublicKey, + funder: PublicKey, + validator: PublicKey +) -> TransactionInstruction: + """Creates instruction to add a validator based on their vote account address.""" + (withdraw_authority, seed) = find_withdraw_authority_program_address(program_id, stake_pool) + (validator_stake, seed) = find_stake_program_address(program_id, validator, stake_pool) + return add_validator_to_pool( + AddValidatorToPoolParams( + program_id=STAKE_POOL_PROGRAM_ID, + stake_pool=stake_pool, + staker=staker, + funding_account=funder, + withdraw_authority=withdraw_authority, + validator_list=validator_list, + validator_stake=validator_stake, + validator_vote=validator, + rent_sysvar=SYSVAR_RENT_PUBKEY, + clock_sysvar=SYSVAR_CLOCK_PUBKEY, + stake_history_sysvar=SYSVAR_STAKE_HISTORY_PUBKEY, + stake_config_sysvar=SYSVAR_STAKE_CONFIG_ID, + system_program_id=SYS_PROGRAM_ID, + stake_program_id=STAKE_PROGRAM_ID, + ) + ) + + +def remove_validator_from_pool(params: RemoveValidatorFromPoolParams) -> TransactionInstruction: + """Creates instruction to remove a validator from the pool.""" + return TransactionInstruction( + keys=[ + AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.staker, is_signer=True, is_writable=False), + AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.new_stake_authority, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.validator_list, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.validator_stake, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.transient_stake, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.destination_stake, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.clock_sysvar, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.stake_program_id, is_signer=False, is_writable=False), + ], + program_id=params.program_id, + data=INSTRUCTIONS_LAYOUT.build( + dict( + instruction_type=InstructionType.REMOVE_VALIDATOR_FROM_POOL, + args=None + ) + ) + ) + + +def remove_validator_from_pool_with_vote( + program_id: PublicKey, + stake_pool: PublicKey, + staker: PublicKey, + validator_list: PublicKey, + new_stake_authority: PublicKey, + validator: PublicKey, + transient_stake_seed: int, + destination_stake: PublicKey, +) -> TransactionInstruction: + """Creates instruction to remove a validator based on their vote account address.""" + (withdraw_authority, seed) = find_withdraw_authority_program_address(program_id, stake_pool) + (validator_stake, seed) = find_stake_program_address(program_id, validator, stake_pool) + (transient_stake, seed) = find_transient_stake_program_address( + program_id, validator, stake_pool, transient_stake_seed) + return remove_validator_from_pool( + RemoveValidatorFromPoolParams( + program_id=STAKE_POOL_PROGRAM_ID, + stake_pool=stake_pool, + staker=staker, + withdraw_authority=withdraw_authority, + new_stake_authority=new_stake_authority, + validator_list=validator_list, + validator_stake=validator_stake, + transient_stake=transient_stake, + destination_stake=destination_stake, + clock_sysvar=SYSVAR_CLOCK_PUBKEY, + stake_program_id=STAKE_PROGRAM_ID, + ) + ) + + +def deposit_stake(params: DepositStakeParams) -> TransactionInstruction: + """Creates a transaction instruction to deposit SOL into a stake pool.""" + keys = [ + AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.validator_list, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.deposit_authority, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.deposit_stake, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.validator_stake, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.reserve_stake, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.destination_pool_account, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.manager_fee_account, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.referral_pool_account, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.pool_mint, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.clock_sysvar, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.stake_history_sysvar, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.token_program_id, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.stake_program_id, is_signer=False, is_writable=False), + ] + return TransactionInstruction( + keys=keys, + program_id=params.program_id, + data=INSTRUCTIONS_LAYOUT.build( + dict( + instruction_type=InstructionType.DEPOSIT_STAKE, + args=None, + ) + ) + ) + + +def withdraw_stake(params: WithdrawStakeParams) -> TransactionInstruction: + """Creates a transaction instruction to withdraw SOL from a stake pool.""" + return TransactionInstruction( + keys=[ + AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.validator_list, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.validator_stake, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.destination_stake, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.destination_stake_authority, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.source_transfer_authority, is_signer=True, is_writable=False), + AccountMeta(pubkey=params.source_pool_account, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.manager_fee_account, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.pool_mint, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.clock_sysvar, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.token_program_id, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.stake_program_id, is_signer=False, is_writable=False), + ], + program_id=params.program_id, + data=INSTRUCTIONS_LAYOUT.build( + dict( + instruction_type=InstructionType.WITHDRAW_STAKE, + args={'amount': params.amount} + ) + ) + ) + + +def deposit_sol(params: DepositSolParams) -> TransactionInstruction: + """Creates a transaction instruction to deposit SOL into a stake pool.""" + keys = [ + AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.reserve_stake, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.funding_account, is_signer=True, is_writable=True), + AccountMeta(pubkey=params.destination_pool_account, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.manager_fee_account, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.referral_pool_account, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.pool_mint, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.system_program_id, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.token_program_id, is_signer=False, is_writable=False), + ] + if params.deposit_authority: + keys.append(AccountMeta(pubkey=params.deposit_authority, is_signer=True, is_writable=False)) + return TransactionInstruction( + keys=keys, + program_id=params.program_id, + data=INSTRUCTIONS_LAYOUT.build( + dict( + instruction_type=InstructionType.DEPOSIT_SOL, + args={'amount': params.amount} + ) + ) + ) + + +def withdraw_sol(params: WithdrawSolParams) -> TransactionInstruction: + """Creates a transaction instruction to withdraw SOL from a stake pool.""" + keys = [ + AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.source_transfer_authority, is_signer=True, is_writable=False), + AccountMeta(pubkey=params.source_pool_account, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.reserve_stake, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.destination_system_account, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.manager_fee_account, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.pool_mint, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.clock_sysvar, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.stake_history_sysvar, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.stake_program_id, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.token_program_id, is_signer=False, is_writable=False), + ] + + if params.sol_withdraw_authority: + AccountMeta(pubkey=params.sol_withdraw_authority, is_signer=True, is_writable=False) + + return TransactionInstruction( + keys=keys, + program_id=params.program_id, + data=INSTRUCTIONS_LAYOUT.build( + dict( + instruction_type=InstructionType.WITHDRAW_SOL, + args={'amount': params.amount} + ) + ) + ) + + +def update_validator_list_balance(params: UpdateValidatorListBalanceParams) -> TransactionInstruction: + """Creates instruction to update a set of validators in the stake pool.""" + keys = [ + AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.validator_list, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.reserve_stake, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.clock_sysvar, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.stake_history_sysvar, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.stake_program_id, is_signer=False, is_writable=False), + ] + keys.extend([ + AccountMeta(pubkey=pubkey, is_signer=False, is_writable=True) + for pubkey in params.validator_and_transient_stake_pairs + ]) + return TransactionInstruction( + keys=keys, + program_id=params.program_id, + data=INSTRUCTIONS_LAYOUT.build( + dict( + instruction_type=InstructionType.UPDATE_VALIDATOR_LIST_BALANCE, + args={'start_index': params.start_index, 'no_merge': params.no_merge} + ) + ) + ) + + +def update_stake_pool_balance(params: UpdateStakePoolBalanceParams) -> TransactionInstruction: + """Creates instruction to update the overall stake pool balance.""" + return TransactionInstruction( + keys=[ + AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.validator_list, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.reserve_stake, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.manager_fee_account, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.pool_mint, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.token_program_id, is_signer=False, is_writable=False), + ], + program_id=params.program_id, + data=INSTRUCTIONS_LAYOUT.build( + dict( + instruction_type=InstructionType.UPDATE_STAKE_POOL_BALANCE, + args=None, + ) + ) + ) + + +def cleanup_removed_validator_entries(params: CleanupRemovedValidatorEntriesParams) -> TransactionInstruction: + """Creates instruction to cleanup removed validator entries.""" + return TransactionInstruction( + keys=[ + AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.validator_list, is_signer=False, is_writable=True), + ], + program_id=params.program_id, + data=INSTRUCTIONS_LAYOUT.build( + dict( + instruction_type=InstructionType.CLEANUP_REMOVED_VALIDATOR_ENTRIES, + args=None, + ) + ) + ) + + +def increase_validator_stake(params: IncreaseValidatorStakeParams) -> TransactionInstruction: + """Creates instruction to increase the stake on a validator.""" + return TransactionInstruction( + keys=[ + AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.staker, is_signer=True, is_writable=False), + AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.validator_list, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.reserve_stake, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.transient_stake, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.validator_vote, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.clock_sysvar, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.rent_sysvar, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.stake_history_sysvar, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.stake_config_sysvar, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.system_program_id, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.stake_program_id, is_signer=False, is_writable=False), + ], + program_id=params.program_id, + data=INSTRUCTIONS_LAYOUT.build( + dict( + instruction_type=InstructionType.INCREASE_VALIDATOR_STAKE, + args={ + 'lamports': params.lamports, + 'transient_stake_seed': params.transient_stake_seed + } + ) + ) + ) + + +def decrease_validator_stake(params: DecreaseValidatorStakeParams) -> TransactionInstruction: + """Creates instruction to decrease the stake on a validator.""" + return TransactionInstruction( + keys=[ + AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.staker, is_signer=True, is_writable=False), + AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.validator_list, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.validator_stake, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.transient_stake, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.clock_sysvar, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.rent_sysvar, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.system_program_id, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.stake_program_id, is_signer=False, is_writable=False), + ], + program_id=params.program_id, + data=INSTRUCTIONS_LAYOUT.build( + dict( + instruction_type=InstructionType.DECREASE_VALIDATOR_STAKE, + args={ + 'lamports': params.lamports, + 'transient_stake_seed': params.transient_stake_seed + } + ) + ) + ) diff --git a/clients/py/stake_pool/state.py b/clients/py/stake_pool/state.py new file mode 100644 index 00000000..93acc103 --- /dev/null +++ b/clients/py/stake_pool/state.py @@ -0,0 +1,321 @@ +"""SPL Stake Pool State.""" + +from enum import IntEnum +from typing import List, NamedTuple, Optional +from construct import Container, Struct, Switch, Int8ul, Int32ul, Int64ul, Pass # type: ignore + +from solana.publickey import PublicKey +from solana.utils.helpers import decode_byte_string +from solana._layouts.shared import PUBLIC_KEY_LAYOUT +from stake.state import Lockup, LOCKUP_LAYOUT + + +def decode_optional_publickey(container: Container) -> Optional[PublicKey]: + if container: + return PublicKey(container) + else: + return None + + +class Fee(NamedTuple): + """Fee assessed by the stake pool, expressed as numerator / denominator.""" + numerator: int + denominator: int + + @classmethod + def decode_container(cls, container: Container): + return Fee( + numerator=container['numerator'], + denominator=container['denominator'], + ) + + @classmethod + def decode_optional_container(cls, container: Container): + if container: + return cls.decode_container(container) + else: + return None + + +class StakePool(NamedTuple): + """Stake pool and all its data.""" + manager: PublicKey + staker: PublicKey + stake_deposit_authority: PublicKey + stake_withdraw_bump_seed: int + validator_list: PublicKey + reserve_stake: PublicKey + pool_mint: PublicKey + manager_fee_account: PublicKey + token_program_id: PublicKey + total_lamports: int + pool_token_supply: int + last_update_epoch: int + lockup: Lockup + epoch_fee: Fee + next_epoch_fee: Optional[Fee] + preferred_deposit_validator: Optional[PublicKey] + preferred_withdraw_validator: Optional[PublicKey] + stake_deposit_fee: Fee + stake_withdrawal_fee: Fee + next_stake_withdrawal_fee: Optional[Fee] + stake_referral_fee: int + sol_deposit_authority: Optional[PublicKey] + sol_deposit_fee: Fee + sol_referral_fee: int + sol_withdraw_authority: Optional[PublicKey] + sol_withdrawal_fee: Fee + next_sol_withdrawal_fee: Optional[Fee] + last_epoch_pool_token_supply: int + last_epoch_total_lamports: int + + @classmethod + def decode(cls, data: str, encoding: str): + data_bytes = decode_byte_string(data, encoding) + parsed = DECODE_STAKE_POOL_LAYOUT.parse(data_bytes) + return StakePool( + manager=PublicKey(parsed['manager']), + staker=PublicKey(parsed['staker']), + stake_deposit_authority=PublicKey(parsed['stake_deposit_authority']), + stake_withdraw_bump_seed=parsed['stake_withdraw_bump_seed'], + validator_list=PublicKey(parsed['validator_list']), + reserve_stake=PublicKey(parsed['reserve_stake']), + pool_mint=PublicKey(parsed['pool_mint']), + manager_fee_account=PublicKey(parsed['manager_fee_account']), + token_program_id=PublicKey(parsed['token_program_id']), + total_lamports=parsed['total_lamports'], + pool_token_supply=parsed['pool_token_supply'], + last_update_epoch=parsed['last_update_epoch'], + lockup=Lockup.decode_container(parsed['lockup']), + epoch_fee=Fee.decode_container(parsed['epoch_fee']), + next_epoch_fee=Fee.decode_optional_container(parsed['next_epoch_fee']), + preferred_deposit_validator=decode_optional_publickey(parsed['preferred_deposit_validator']), + preferred_withdraw_validator=decode_optional_publickey(parsed['preferred_withdraw_validator']), + stake_deposit_fee=Fee.decode_container(parsed['stake_deposit_fee']), + stake_withdrawal_fee=Fee.decode_container(parsed['stake_withdrawal_fee']), + next_stake_withdrawal_fee=Fee.decode_optional_container(parsed['next_stake_withdrawal_fee']), + stake_referral_fee=parsed['stake_referral_fee'], + sol_deposit_authority=decode_optional_publickey(parsed['sol_deposit_authority']), + sol_deposit_fee=Fee.decode_container(parsed['sol_deposit_fee']), + sol_referral_fee=parsed['sol_referral_fee'], + sol_withdraw_authority=decode_optional_publickey(parsed['sol_withdraw_authority']), + sol_withdrawal_fee=Fee.decode_container(parsed['sol_withdrawal_fee']), + next_sol_withdrawal_fee=Fee.decode_optional_container(parsed['next_sol_withdrawal_fee']), + last_epoch_pool_token_supply=parsed['last_epoch_pool_token_supply'], + last_epoch_total_lamports=parsed['last_epoch_total_lamports'], + ) + + +class StakeStatus(IntEnum): + """Specifies the status of a stake on a validator in a stake pool.""" + + ACTIVE = 0 + """Stake is active and normal.""" + DEACTIVATING_TRANSIENT = 1 + """Stake has been removed, but a deactivating transient stake still exists.""" + READY_FOR_REMOVAL = 2 + """No more validator stake accounts exist, entry ready for removal.""" + + +class ValidatorStakeInfo(NamedTuple): + active_stake_lamports: int + """Amount of active stake delegated to this validator.""" + + transient_stake_lamports: int + """Amount of transient stake delegated to this validator.""" + + last_update_epoch: int + """Last epoch the active and transient stake lamports fields were updated.""" + + transient_seed_suffix_start: int + """Start of the validator transient account seed suffixes.""" + + transient_seed_suffix_end: int + """End of the validator transient account seed suffixes.""" + + status: StakeStatus + """Status of the validator stake account.""" + + vote_account_address: PublicKey + """Validator vote account address.""" + + @classmethod + def decode_container(cls, container: Container): + return ValidatorStakeInfo( + active_stake_lamports=container['active_stake_lamports'], + transient_stake_lamports=container['transient_stake_lamports'], + last_update_epoch=container['last_update_epoch'], + transient_seed_suffix_start=container['transient_seed_suffix_start'], + transient_seed_suffix_end=container['transient_seed_suffix_end'], + status=container['status'], + vote_account_address=PublicKey(container['vote_account_address']), + ) + + +class ValidatorList(NamedTuple): + """List of validators and amount staked, associated to a stake pool.""" + + max_validators: int + """Maximum number of validators possible in the list.""" + + validators: List[ValidatorStakeInfo] + """Info for each validator in the stake pool.""" + + @staticmethod + def calculate_validator_list_size(max_validators: int) -> int: + layout = VALIDATOR_LIST_LAYOUT + VALIDATOR_INFO_LAYOUT[max_validators] + return layout.sizeof() + + @classmethod + def decode(cls, data: str, encoding: str): + data_bytes = decode_byte_string(data, encoding) + parsed = DECODE_VALIDATOR_LIST_LAYOUT.parse(data_bytes) + print(parsed) + return ValidatorList( + max_validators=parsed['max_validators'], + validators=[ValidatorStakeInfo.decode_container(container) for container in parsed['validators']], + ) + + +FEE_LAYOUT = Struct( + "denominator" / Int64ul, + "numerator" / Int64ul, +) + +STAKE_POOL_LAYOUT = Struct( + "account_type" / Int8ul, + "manager" / PUBLIC_KEY_LAYOUT, + "staker" / PUBLIC_KEY_LAYOUT, + "stake_deposit_authority" / PUBLIC_KEY_LAYOUT, + "stake_withdraw_bump_seed" / Int8ul, + "validator_list" / PUBLIC_KEY_LAYOUT, + "reserve_stake" / PUBLIC_KEY_LAYOUT, + "pool_mint" / PUBLIC_KEY_LAYOUT, + "manager_fee_account" / PUBLIC_KEY_LAYOUT, + "token_program_id" / PUBLIC_KEY_LAYOUT, + "total_lamports" / Int64ul, + "pool_token_supply" / Int64ul, + "last_update_epoch" / Int64ul, + "lockup" / LOCKUP_LAYOUT, + "epoch_fee" / FEE_LAYOUT, + "next_epoch_fee_option" / Int8ul, + "next_epoch_fee" / FEE_LAYOUT, + "preferred_deposit_validator_option" / Int8ul, + "preferred_deposit_validator" / PUBLIC_KEY_LAYOUT, + "preferred_withdraw_validator_option" / Int8ul, + "preferred_withdraw_validator" / PUBLIC_KEY_LAYOUT, + "stake_deposit_fee" / FEE_LAYOUT, + "stake_withdrawal_fee" / FEE_LAYOUT, + "next_stake_withdrawal_fee_option" / Int8ul, + "next_stake_withdrawal_fee" / FEE_LAYOUT, + "stake_referral_fee" / Int8ul, + "sol_deposit_authority_option" / Int8ul, + "sol_deposit_authority" / PUBLIC_KEY_LAYOUT, + "sol_deposit_fee" / FEE_LAYOUT, + "sol_referral_fee" / Int8ul, + "sol_withdraw_authority_option" / Int8ul, + "sol_withdraw_authority" / PUBLIC_KEY_LAYOUT, + "sol_withdrawal_fee" / FEE_LAYOUT, + "next_sol_withdrawal_fee_option" / Int8ul, + "next_sol_withdrawal_fee" / FEE_LAYOUT, + "last_epoch_pool_token_supply" / Int64ul, + "last_epoch_total_lamports" / Int64ul, +) + +DECODE_STAKE_POOL_LAYOUT = Struct( + "account_type" / Int8ul, + "manager" / PUBLIC_KEY_LAYOUT, + "staker" / PUBLIC_KEY_LAYOUT, + "stake_deposit_authority" / PUBLIC_KEY_LAYOUT, + "stake_withdraw_bump_seed" / Int8ul, + "validator_list" / PUBLIC_KEY_LAYOUT, + "reserve_stake" / PUBLIC_KEY_LAYOUT, + "pool_mint" / PUBLIC_KEY_LAYOUT, + "manager_fee_account" / PUBLIC_KEY_LAYOUT, + "token_program_id" / PUBLIC_KEY_LAYOUT, + "total_lamports" / Int64ul, + "pool_token_supply" / Int64ul, + "last_update_epoch" / Int64ul, + "lockup" / LOCKUP_LAYOUT, + "epoch_fee" / FEE_LAYOUT, + "next_epoch_fee_option" / Int8ul, + "next_epoch_fee" / Switch( + lambda this: this.next_epoch_fee_option, + { + 0: Pass, + 1: FEE_LAYOUT, + }), + "preferred_deposit_validator_option" / Int8ul, + "preferred_deposit_validator" / Switch( + lambda this: this.preferred_deposit_validator_option, + { + 0: Pass, + 1: PUBLIC_KEY_LAYOUT, + }), + "preferred_withdraw_validator_option" / Int8ul, + "preferred_withdraw_validator" / Switch( + lambda this: this.preferred_withdraw_validator_option, + { + 0: Pass, + 1: PUBLIC_KEY_LAYOUT, + }), + "stake_deposit_fee" / FEE_LAYOUT, + "stake_withdrawal_fee" / FEE_LAYOUT, + "next_stake_withdrawal_fee_option" / Int8ul, + "next_stake_withdrawal_fee" / Switch( + lambda this: this.next_stake_withdrawal_fee_option, + { + 0: Pass, + 1: FEE_LAYOUT, + }), + "stake_referral_fee" / Int8ul, + "sol_deposit_authority_option" / Int8ul, + "sol_deposit_authority" / Switch( + lambda this: this.sol_deposit_authority_option, + { + 0: Pass, + 1: PUBLIC_KEY_LAYOUT, + }), + "sol_deposit_fee" / FEE_LAYOUT, + "sol_referral_fee" / Int8ul, + "sol_withdraw_authority_option" / Int8ul, + "sol_withdraw_authority" / Switch( + lambda this: this.sol_withdraw_authority_option, + { + 0: Pass, + 1: PUBLIC_KEY_LAYOUT, + }), + "sol_withdrawal_fee" / FEE_LAYOUT, + "next_sol_withdrawal_fee_option" / Int8ul, + "next_sol_withdrawal_fee" / Switch( + lambda this: this.next_sol_withdrawal_fee_option, + { + 0: Pass, + 1: FEE_LAYOUT, + }), + "last_epoch_pool_token_supply" / Int64ul, + "last_epoch_total_lamports" / Int64ul, +) + +VALIDATOR_INFO_LAYOUT = Struct( + "active_stake_lamports" / Int64ul, + "transient_stake_lamports" / Int64ul, + "last_update_epoch" / Int64ul, + "transient_seed_suffix_start" / Int64ul, + "transient_seed_suffix_end" / Int64ul, + "status" / Int8ul, + "vote_account_address" / PUBLIC_KEY_LAYOUT, +) + +VALIDATOR_LIST_LAYOUT = Struct( + "account_type" / Int8ul, + "max_validators" / Int32ul, + "validators_len" / Int32ul, +) + +DECODE_VALIDATOR_LIST_LAYOUT = Struct( + "account_type" / Int8ul, + "max_validators" / Int32ul, + "validators_len" / Int32ul, + "validators" / VALIDATOR_INFO_LAYOUT[lambda this: this.validators_len], +) diff --git a/clients/py/system/__init__.py b/clients/py/system/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/clients/py/system/actions.py b/clients/py/system/actions.py new file mode 100644 index 00000000..0b16a045 --- /dev/null +++ b/clients/py/system/actions.py @@ -0,0 +1,9 @@ +from solana.publickey import PublicKey +from solana.rpc.async_api import AsyncClient +from solana.rpc.commitment import Confirmed + + +async def airdrop(client: AsyncClient, receiver: PublicKey, lamports: int): + print(f"Airdropping {lamports} lamports to {receiver}...") + resp = await client.request_airdrop(receiver, lamports, Confirmed) + await client.confirm_transaction(resp['result'], Confirmed) diff --git a/clients/py/tests/conftest.py b/clients/py/tests/conftest.py new file mode 100644 index 00000000..32fa0797 --- /dev/null +++ b/clients/py/tests/conftest.py @@ -0,0 +1,95 @@ +import asyncio +import pytest +import os +import shutil +import tempfile +import time +from typing import Iterator, List, Tuple +from subprocess import Popen + +from solana.keypair import Keypair +from solana.publickey import PublicKey +from solana.rpc.async_api import AsyncClient +from solana.rpc.commitment import Confirmed + +from vote.actions import create_vote +from system.actions import airdrop +from stake_pool.actions import create_all, add_validator_to_pool +from stake_pool.state import Fee + + +@pytest.fixture(scope="session") +def solana_test_validator(): + old_cwd = os.getcwd() + newpath = tempfile.mkdtemp() + os.chdir(newpath) + validator = Popen([ + "solana-test-validator", + "--reset", "--quiet", + "--bpf-program", "SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy", + f"{old_cwd}/../../target/deploy/spl_stake_pool.so", + "--slots-per-epoch", "64", + ],) + yield + validator.kill() + os.chdir(old_cwd) + shutil.rmtree(newpath) + + +@pytest.fixture +def validators(event_loop, async_client, payer) -> List[PublicKey]: + num_validators = 3 + validators = [] + futures = [] + for i in range(num_validators): + vote = Keypair() + node = Keypair() + futures.append(create_vote(async_client, payer, vote, node, payer.public_key, payer.public_key, 10)) + validators.append(vote.public_key) + event_loop.run_until_complete(asyncio.gather(*futures)) + return validators + + +@pytest.fixture +def stake_pool_addresses(event_loop, async_client, payer, validators) -> Tuple[PublicKey, PublicKey]: + fee = Fee(numerator=1, denominator=1000) + referral_fee = 20 + stake_pool_addresses = event_loop.run_until_complete( + create_all(async_client, payer, fee, referral_fee) + ) + futures = [ + add_validator_to_pool(async_client, payer, stake_pool_addresses[0], validator) + for validator in validators + ] + event_loop.run_until_complete(asyncio.gather(*futures)) + return stake_pool_addresses + + +@pytest.fixture +def event_loop(): + loop = asyncio.get_event_loop() + yield loop + loop.close() + + +@pytest.fixture +def async_client(event_loop, solana_test_validator) -> Iterator[AsyncClient]: + async_client = AsyncClient(commitment=Confirmed) + total_attempts = 10 + current_attempt = 0 + while not event_loop.run_until_complete(async_client.is_connected()): + if current_attempt == total_attempts: + raise Exception("Could not connect to test validator") + else: + current_attempt += 1 + time.sleep(1) + yield async_client + event_loop.run_until_complete(async_client.close()) + + +@pytest.fixture +def payer(event_loop, async_client) -> Keypair: + payer = Keypair() + airdrop_lamports = 10_000_000_000 + event_loop.run_until_complete(airdrop(async_client, payer.public_key, airdrop_lamports)) + return payer diff --git a/clients/py/tests/test_a_time_sensitive.py b/clients/py/tests/test_a_time_sensitive.py new file mode 100644 index 00000000..e3267983 --- /dev/null +++ b/clients/py/tests/test_a_time_sensitive.py @@ -0,0 +1,76 @@ +"""Time sensitive test, so run it first out of the bunch.""" +import asyncio +import pytest +from solana.rpc.commitment import Confirmed +from spl.token.instructions import get_associated_token_address + +from stake.constants import STAKE_LEN +from stake_pool.state import StakePool, ValidatorList +from stake_pool.actions import deposit_sol, decrease_validator_stake, increase_validator_stake, update_stake_pool + + +@pytest.mark.asyncio +async def test_increase_decrease_this_is_very_slow(async_client, validators, payer, stake_pool_addresses): + (stake_pool_address, validator_list_address) = stake_pool_addresses + resp = await async_client.get_minimum_balance_for_rent_exemption(STAKE_LEN) + stake_rent_exemption = resp['result'] + increase_amount = 100_000_000 + decrease_amount = increase_amount // 2 + deposit_amount = (increase_amount + stake_rent_exemption) * len(validators) + + resp = await async_client.get_account_info(stake_pool_address, commitment=Confirmed) + data = resp['result']['value']['data'] + stake_pool = StakePool.decode(data[0], data[1]) + token_account = get_associated_token_address(payer.public_key, stake_pool.pool_mint) + await deposit_sol(async_client, payer, stake_pool_address, token_account, deposit_amount) + + # increase to all + futures = [ + increase_validator_stake(async_client, payer, payer, stake_pool_address, validator, increase_amount) + for validator in validators + ] + await asyncio.gather(*futures) + + resp = await async_client.get_account_info(validator_list_address, commitment=Confirmed) + data = resp['result']['value']['data'] + validator_list = ValidatorList.decode(data[0], data[1]) + for validator in validator_list.validators: + assert validator.transient_stake_lamports == increase_amount + stake_rent_exemption + assert validator.active_stake_lamports == 0 + + print("Waiting for epoch to roll over, roughly 24 seconds") + await asyncio.sleep(24.0) + await update_stake_pool(async_client, payer, stake_pool_address) + + resp = await async_client.get_account_info(validator_list_address, commitment=Confirmed) + data = resp['result']['value']['data'] + validator_list = ValidatorList.decode(data[0], data[1]) + for validator in validator_list.validators: + assert validator.last_update_epoch != 0 + assert validator.transient_stake_lamports == 0 + assert validator.active_stake_lamports == increase_amount # rent exemption brought back to reserve + + # decrease from all + futures = [ + decrease_validator_stake(async_client, payer, payer, stake_pool_address, validator, decrease_amount) + for validator in validators + ] + await asyncio.gather(*futures) + + resp = await async_client.get_account_info(validator_list_address, commitment=Confirmed) + data = resp['result']['value']['data'] + validator_list = ValidatorList.decode(data[0], data[1]) + for validator in validator_list.validators: + assert validator.transient_stake_lamports == decrease_amount + assert validator.active_stake_lamports == increase_amount - decrease_amount + + print("Waiting for epoch to roll over, roughly 24 seconds") + await asyncio.sleep(24.0) + await update_stake_pool(async_client, payer, stake_pool_address) + + resp = await async_client.get_account_info(validator_list_address, commitment=Confirmed) + data = resp['result']['value']['data'] + validator_list = ValidatorList.decode(data[0], data[1]) + for validator in validator_list.validators: + assert validator.transient_stake_lamports == 0 + assert validator.active_stake_lamports == increase_amount - decrease_amount diff --git a/clients/py/tests/test_add_remove.py b/clients/py/tests/test_add_remove.py new file mode 100644 index 00000000..5937a229 --- /dev/null +++ b/clients/py/tests/test_add_remove.py @@ -0,0 +1,31 @@ +import asyncio +import pytest +from solana.rpc.commitment import Confirmed + +from stake_pool.state import ValidatorList, StakeStatus +from stake_pool.actions import remove_validator_from_pool + + +@pytest.mark.asyncio +async def test_add_remove_validators(async_client, validators, payer, stake_pool_addresses): + (stake_pool_address, validator_list_address) = stake_pool_addresses + resp = await async_client.get_account_info(validator_list_address, commitment=Confirmed) + data = resp['result']['value']['data'] + validator_list = ValidatorList.decode(data[0], data[1]) + assert len(validator_list.validators) == len(validators) + futures = [] + for validator_info in validator_list.validators: + assert validator_info.vote_account_address in validators + assert validator_info.active_stake_lamports == 0 + assert validator_info.transient_stake_lamports == 0 + assert validator_info.status == StakeStatus.ACTIVE + futures.append( + remove_validator_from_pool(async_client, payer, stake_pool_address, validator_info.vote_account_address) + ) + await asyncio.gather(*futures) + + resp = await async_client.get_account_info(validator_list_address, commitment=Confirmed) + data = resp['result']['value']['data'] + validator_list = ValidatorList.decode(data[0], data[1]) + for validator_info in validator_list.validators: + assert validator_info.status == StakeStatus.READY_FOR_REMOVAL diff --git a/clients/py/tests/test_create.py b/clients/py/tests/test_create.py new file mode 100644 index 00000000..ee37be58 --- /dev/null +++ b/clients/py/tests/test_create.py @@ -0,0 +1,68 @@ +import pytest +from solana.keypair import Keypair +from solana.rpc.commitment import Confirmed +from spl.token.constants import TOKEN_PROGRAM_ID + +from stake_pool.constants import find_withdraw_authority_program_address, STAKE_POOL_PROGRAM_ID +from stake_pool.state import StakePool, Fee + +from stake.actions import create_stake +from stake_pool.actions import create +from spl_token.actions import create_mint, create_associated_token_account + + +@pytest.mark.asyncio +async def test_create_stake_pool(async_client, payer): + stake_pool = Keypair() + validator_list = Keypair() + (pool_withdraw_authority, seed) = find_withdraw_authority_program_address( + STAKE_POOL_PROGRAM_ID, stake_pool.public_key) + + reserve_stake = Keypair() + await create_stake(async_client, payer, reserve_stake, pool_withdraw_authority, 1) + + pool_mint = Keypair() + await create_mint(async_client, payer, pool_mint, pool_withdraw_authority) + + manager_fee_account = await create_associated_token_account( + async_client, + payer, + payer.public_key, + pool_mint.public_key, + ) + + fee = Fee(numerator=1, denominator=1000) + referral_fee = 20 + await create( + async_client, payer, stake_pool, validator_list, pool_mint.public_key, + reserve_stake.public_key, manager_fee_account, fee, referral_fee) + resp = await async_client.get_account_info(stake_pool.public_key, commitment=Confirmed) + assert resp['result']['value']['owner'] == str(STAKE_POOL_PROGRAM_ID) + data = resp['result']['value']['data'] + pool_data = StakePool.decode(data[0], data[1]) + assert pool_data.manager == payer.public_key + assert pool_data.staker == payer.public_key + assert pool_data.stake_withdraw_bump_seed == seed + assert pool_data.validator_list == validator_list.public_key + assert pool_data.reserve_stake == reserve_stake.public_key + assert pool_data.pool_mint == pool_mint.public_key + assert pool_data.manager_fee_account == manager_fee_account + assert pool_data.token_program_id == TOKEN_PROGRAM_ID + assert pool_data.total_lamports == 0 + assert pool_data.pool_token_supply == 0 + assert pool_data.epoch_fee == fee + assert pool_data.next_epoch_fee is None + assert pool_data.preferred_deposit_validator is None + assert pool_data.preferred_withdraw_validator is None + assert pool_data.stake_deposit_fee == fee + assert pool_data.stake_withdrawal_fee == fee + assert pool_data.next_stake_withdrawal_fee is None + assert pool_data.stake_referral_fee == referral_fee + assert pool_data.sol_deposit_authority is None + assert pool_data.sol_deposit_fee == fee + assert pool_data.sol_referral_fee == referral_fee + assert pool_data.sol_withdraw_authority is None + assert pool_data.sol_withdrawal_fee == fee + assert pool_data.next_sol_withdrawal_fee is None + assert pool_data.last_epoch_pool_token_supply == 0 + assert pool_data.last_epoch_total_lamports == 0 diff --git a/clients/py/tests/test_deposit_withdraw_sol.py b/clients/py/tests/test_deposit_withdraw_sol.py new file mode 100644 index 00000000..c61a353f --- /dev/null +++ b/clients/py/tests/test_deposit_withdraw_sol.py @@ -0,0 +1,26 @@ +import pytest +from solana.rpc.commitment import Confirmed +from solana.keypair import Keypair +from spl.token.instructions import get_associated_token_address + +from stake_pool.state import Fee, StakePool +from stake_pool.actions import create_all, deposit_sol, withdraw_sol + + +@pytest.mark.asyncio +async def test_deposit_withdraw_sol(async_client, payer): + fee = Fee(numerator=1, denominator=1000) + referral_fee = 20 + (stake_pool_address, validator_list_address) = await create_all(async_client, payer, fee, referral_fee) + resp = await async_client.get_account_info(stake_pool_address, commitment=Confirmed) + data = resp['result']['value']['data'] + stake_pool = StakePool.decode(data[0], data[1]) + token_account = get_associated_token_address(payer.public_key, stake_pool.pool_mint) + deposit_amount = 100_000_000 + await deposit_sol(async_client, payer, stake_pool_address, token_account, deposit_amount) + pool_token_balance = await async_client.get_token_account_balance(token_account, Confirmed) + assert pool_token_balance['result']['value']['amount'] == str(deposit_amount) + recipient = Keypair() + await withdraw_sol(async_client, payer, token_account, stake_pool_address, recipient.public_key, deposit_amount) + pool_token_balance = await async_client.get_token_account_balance(token_account, Confirmed) + assert pool_token_balance['result']['value']['amount'] == str('0') diff --git a/clients/py/tests/test_deposit_withdraw_stake.py b/clients/py/tests/test_deposit_withdraw_stake.py new file mode 100644 index 00000000..3341d0d9 --- /dev/null +++ b/clients/py/tests/test_deposit_withdraw_stake.py @@ -0,0 +1,43 @@ +import pytest +from solana.rpc.commitment import Confirmed +from solana.keypair import Keypair +from spl.token.instructions import get_associated_token_address + +from stake.actions import create_stake, delegate_stake +from stake.constants import STAKE_LEN +from stake_pool.actions import deposit_stake, withdraw_stake +from stake_pool.state import StakePool + + +@pytest.mark.asyncio +async def test_deposit_withdraw_stake(async_client, validators, payer, stake_pool_addresses): + (stake_pool_address, validator_list_address) = stake_pool_addresses + resp = await async_client.get_account_info(stake_pool_address, commitment=Confirmed) + data = resp['result']['value']['data'] + stake_pool = StakePool.decode(data[0], data[1]) + token_account = get_associated_token_address(payer.public_key, stake_pool.pool_mint) + + resp = await async_client.get_minimum_balance_for_rent_exemption(STAKE_LEN) + stake_rent_exemption = resp['result'] + + stake_amount = 1_000_000 + for validator in validators: + stake = Keypair() + await create_stake(async_client, payer, stake, payer.public_key, stake_amount) + await delegate_stake(async_client, payer, payer, stake.public_key, validator) + await deposit_stake(async_client, payer, stake_pool_address, validator, stake.public_key, token_account) + + pool_token_balance = await async_client.get_token_account_balance(token_account, Confirmed) + pool_token_balance = pool_token_balance['result']['value']['amount'] + assert pool_token_balance == str((stake_amount + stake_rent_exemption) * len(validators)) + + for validator in validators: + destination_stake = Keypair() + await withdraw_stake( + async_client, payer, payer, destination_stake, stake_pool_address, validator, + payer.public_key, token_account, stake_amount + ) + + pool_token_balance = await async_client.get_token_account_balance(token_account, Confirmed) + pool_token_balance = pool_token_balance['result']['value']['amount'] + assert pool_token_balance == str(stake_rent_exemption * len(validators)) diff --git a/clients/py/tests/test_stake.py b/clients/py/tests/test_stake.py new file mode 100644 index 00000000..152a487c --- /dev/null +++ b/clients/py/tests/test_stake.py @@ -0,0 +1,32 @@ +import asyncio +import pytest +from solana.keypair import Keypair + +from stake.state import StakeAuthorize +from stake.actions import authorize, create_stake, delegate_stake + + +@pytest.mark.asyncio +async def test_create_stake(async_client, payer): + stake = Keypair() + await create_stake(async_client, payer, stake, payer.public_key, 100_000) + + +@pytest.mark.asyncio +async def test_delegate_stake(async_client, validators, payer): + validator = validators[0] + stake = Keypair() + await create_stake(async_client, payer, stake, payer.public_key, 1) + await delegate_stake(async_client, payer, payer, stake.public_key, validator) + + +@pytest.mark.asyncio +async def test_authorize_stake(async_client, payer): + stake = Keypair() + new_authority = Keypair() + await create_stake(async_client, payer, stake, payer.public_key, 1_000) + await asyncio.gather( + authorize(async_client, payer, payer, stake.public_key, new_authority.public_key, StakeAuthorize.STAKER), + authorize(async_client, payer, payer, stake.public_key, new_authority.public_key, StakeAuthorize.WITHDRAWER) + ) + await authorize(async_client, payer, new_authority, stake.public_key, payer.public_key, StakeAuthorize.WITHDRAWER) diff --git a/clients/py/tests/test_system.py b/clients/py/tests/test_system.py new file mode 100644 index 00000000..31d2af34 --- /dev/null +++ b/clients/py/tests/test_system.py @@ -0,0 +1,14 @@ +import pytest +from solana.keypair import Keypair +from solana.rpc.commitment import Confirmed + +import system.actions + + +@pytest.mark.asyncio +async def test_airdrop(async_client): + manager = Keypair() + airdrop_lamports = 1_000_000 + await system.actions.airdrop(async_client, manager.public_key, airdrop_lamports) + resp = await async_client.get_balance(manager.public_key, commitment=Confirmed) + assert resp['result']['value'] == airdrop_lamports diff --git a/clients/py/tests/test_token.py b/clients/py/tests/test_token.py new file mode 100644 index 00000000..1d92c179 --- /dev/null +++ b/clients/py/tests/test_token.py @@ -0,0 +1,16 @@ +import pytest +from solana.keypair import Keypair + +from spl_token.actions import create_mint, create_associated_token_account + + +@pytest.mark.asyncio +async def test_create_mint(async_client, payer): + pool_mint = Keypair() + await create_mint(async_client, payer, pool_mint, payer.public_key) + await create_associated_token_account( + async_client, + payer, + payer.public_key, + pool_mint.public_key, + ) diff --git a/clients/py/tests/test_vote.py b/clients/py/tests/test_vote.py new file mode 100644 index 00000000..b0861d46 --- /dev/null +++ b/clients/py/tests/test_vote.py @@ -0,0 +1,16 @@ +import pytest +from solana.keypair import Keypair +from solana.publickey import PublicKey +from solana.rpc.commitment import Confirmed + +from vote.actions import create_vote +from vote.constants import VOTE_PROGRAM_ID + + +@pytest.mark.asyncio +async def test_create_vote(async_client, payer): + vote = Keypair() + node = Keypair() + await create_vote(async_client, payer, vote, node, payer.public_key, payer.public_key, 10) + resp = await async_client.get_account_info(vote.public_key, commitment=Confirmed) + assert PublicKey(resp['result']['value']['owner']) == VOTE_PROGRAM_ID diff --git a/clients/py/vote/__init__.py b/clients/py/vote/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/clients/py/vote/actions.py b/clients/py/vote/actions.py new file mode 100644 index 00000000..9f3fc49f --- /dev/null +++ b/clients/py/vote/actions.py @@ -0,0 +1,45 @@ +from solana.publickey import PublicKey +from solana.keypair import Keypair +from solana.rpc.async_api import AsyncClient +from solana.rpc.commitment import Confirmed +from solana.rpc.types import TxOpts +from solana.sysvar import SYSVAR_CLOCK_PUBKEY, SYSVAR_RENT_PUBKEY +from solana.transaction import Transaction +import solana.system_program as sys + +from vote.constants import VOTE_PROGRAM_ID, VOTE_STATE_LEN +from vote.instructions import initialize, InitializeParams + + +async def create_vote( + client: AsyncClient, payer: Keypair, vote: Keypair, node: Keypair, + voter: PublicKey, withdrawer: PublicKey, commission: int): + print(f"Creating vote account {vote.public_key}") + resp = await client.get_minimum_balance_for_rent_exemption(VOTE_STATE_LEN) + txn = Transaction() + txn.add( + sys.create_account( + sys.CreateAccountParams( + from_pubkey=payer.public_key, + new_account_pubkey=vote.public_key, + lamports=resp['result'], + space=VOTE_STATE_LEN, + program_id=VOTE_PROGRAM_ID, + ) + ) + ) + txn.add( + initialize( + InitializeParams( + vote=vote.public_key, + rent_sysvar=SYSVAR_RENT_PUBKEY, + clock_sysvar=SYSVAR_CLOCK_PUBKEY, + node=node.public_key, + authorized_voter=voter, + authorized_withdrawer=withdrawer, + commission=commission, + ) + ) + ) + await client.send_transaction( + txn, payer, vote, node, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) diff --git a/clients/py/vote/constants.py b/clients/py/vote/constants.py new file mode 100644 index 00000000..21f006e4 --- /dev/null +++ b/clients/py/vote/constants.py @@ -0,0 +1,8 @@ +from solana.publickey import PublicKey + + +VOTE_PROGRAM_ID = PublicKey("Vote111111111111111111111111111111111111111") +"""Program id for the native vote program.""" + +VOTE_STATE_LEN: int = 3731 +"""Size of vote account.""" diff --git a/clients/py/vote/instructions.py b/clients/py/vote/instructions.py new file mode 100644 index 00000000..38106535 --- /dev/null +++ b/clients/py/vote/instructions.py @@ -0,0 +1,97 @@ +"""Vote Program Instructions.""" + +from enum import IntEnum +from typing import NamedTuple + +from construct import Struct, Switch, Int8ul, Int32ul, Pass # type: ignore + +from solana.publickey import PublicKey +from solana.sysvar import SYSVAR_CLOCK_PUBKEY, SYSVAR_RENT_PUBKEY +from solana.transaction import AccountMeta, TransactionInstruction +from solana._layouts.shared import PUBLIC_KEY_LAYOUT + +from vote.constants import VOTE_PROGRAM_ID + + +class InitializeParams(NamedTuple): + """Initialize vote account params.""" + + vote: PublicKey + """`[w]` Uninitialized vote account""" + rent_sysvar: PublicKey + """`[]` Rent sysvar.""" + clock_sysvar: PublicKey + """`[]` Clock sysvar.""" + node: PublicKey + """`[s]` New validator identity.""" + + authorized_voter: PublicKey + """The authorized voter for this vote account.""" + authorized_withdrawer: PublicKey + """The authorized withdrawer for this vote account.""" + commission: int + """Commission, represented as a percentage""" + + +class InstructionType(IntEnum): + """Vote Instruction Types.""" + + INITIALIZE = 0 + AUTHORIZE = 1 + VOTE = 2 + WITHDRAW = 3 + UPDATE_VALIDATOR_IDENTITY = 4 + UPDATE_COMMISSION = 5 + VOTE_SWITCH = 6 + AUTHORIZE_CHECKED = 7 + + +INITIALIZE_LAYOUT = Struct( + "node" / PUBLIC_KEY_LAYOUT, + "authorized_voter" / PUBLIC_KEY_LAYOUT, + "authorized_withdrawer" / PUBLIC_KEY_LAYOUT, + "commission" / Int8ul, +) + +INSTRUCTIONS_LAYOUT = Struct( + "instruction_type" / Int32ul, + "args" + / Switch( + lambda this: this.instruction_type, + { + InstructionType.INITIALIZE: INITIALIZE_LAYOUT, + InstructionType.AUTHORIZE: Pass, # TODO + InstructionType.VOTE: Pass, # TODO + InstructionType.WITHDRAW: Pass, # TODO + InstructionType.UPDATE_VALIDATOR_IDENTITY: Pass, # TODO + InstructionType.UPDATE_COMMISSION: Pass, # TODO + InstructionType.VOTE_SWITCH: Pass, # TODO + InstructionType.AUTHORIZE_CHECKED: Pass, # TODO + }, + ), +) + + +def initialize(params: InitializeParams) -> TransactionInstruction: + """Creates a transaction instruction to initialize a new stake.""" + data = INSTRUCTIONS_LAYOUT.build( + dict( + instruction_type=InstructionType.INITIALIZE, + args=dict( + node=bytes(params.node), + authorized_voter=bytes(params.authorized_voter), + authorized_withdrawer=bytes(params.authorized_withdrawer), + commission=params.commission, + ), + ) + ) + return TransactionInstruction( + keys=[ + AccountMeta(pubkey=params.vote, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.rent_sysvar or SYSVAR_RENT_PUBKEY, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.clock_sysvar or SYSVAR_CLOCK_PUBKEY, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.node, is_signer=True, is_writable=False), + ], + program_id=VOTE_PROGRAM_ID, + data=data, + ) From b48033c61f3408802a10b2eb85996aef13593662 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Thu, 9 Dec 2021 22:12:22 -0800 Subject: [PATCH 0206/1076] Update to Rust 1.57.0 --- program/src/big_vec.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/program/src/big_vec.rs b/program/src/big_vec.rs index 385fb3f2..b98a29ec 100644 --- a/program/src/big_vec.rs +++ b/program/src/big_vec.rs @@ -120,8 +120,8 @@ impl<'data> BigVec<'data> { if self.data.len() < end_index { return Err(ProgramError::AccountDataTooSmall); } - let mut element_ref = &mut self.data[start_index..start_index + T::LEN]; - element.pack_into_slice(&mut element_ref); + let element_ref = &mut self.data[start_index..start_index + T::LEN]; + element.pack_into_slice(element_ref); Ok(()) } From c8ba6fa19288f65b335749818be3c7030d760648 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Mon, 13 Dec 2021 13:17:07 +0100 Subject: [PATCH 0207/1076] stake-pool-py: Add simple rebalance bot (#2630) * stake-pool-py: Add simple rebalance bot * Fixup test * Refactor flaky tests * Create vote earlier in test * Duplicate create_vote call causes stall * Wait more aggressively --- clients/py/README.md | 66 +++++- clients/py/bot/__init__.py | 0 clients/py/bot/rebalance.py | 135 ++++++++++++ clients/py/stake_pool/instructions.py | 4 +- clients/py/tests/conftest.py | 27 ++- clients/py/tests/test_a_time_sensitive.py | 10 +- clients/py/tests/test_bot_rebalance.py | 79 +++++++ .../py/tests/test_deposit_withdraw_stake.py | 43 +++- program/tests/deposit.rs | 179 ---------------- program/tests/deposit_authority.rs | 200 ++++++++++++++++++ program/tests/initialize.rs | 20 -- 11 files changed, 546 insertions(+), 217 deletions(-) create mode 100644 clients/py/bot/__init__.py create mode 100644 clients/py/bot/rebalance.py create mode 100644 clients/py/tests/test_bot_rebalance.py create mode 100644 program/tests/deposit_authority.rs diff --git a/clients/py/README.md b/clients/py/README.md index 97e3605c..49866fb6 100644 --- a/clients/py/README.md +++ b/clients/py/README.md @@ -1,3 +1,67 @@ # Stake-Pool Python Bindings -WIP Python bindings to interact with the stake pool program. +Preliminary Python bindings to interact with the stake pool program, enabling +simple stake delegation bots. + +## To do + +* More reference bot implementations +* Add bindings for all stake pool instructions, see `TODO`s in `stake_pool/instructions.py` +* Finish bindings for vote and stake program +* Upstream vote and stake program bindings to https://github.com/michaelhly/solana-py + +## Development + +### Environment Setup + +1. Ensure that Python 3 is installed with `venv`: https://www.python.org/downloads/ +2. (Optional, but highly recommended) Setup and activate a virtual environment: + +``` +$ python3 -m venv venv +$ source venv/bin/activate +``` + +3. Install requirements + +``` +$ pip install -r requirements.txt +``` + +4. Install the Solana tool suite: https://docs.solana.com/cli/install-solana-cli-tools + +### Test + +Testing through `pytest`: + +``` +$ python3 -m pytest +``` + +Note: the tests all run against a `solana-test-validator` with short epochs of 64 +slots (25.6 seconds exactly). Some tests wait for epoch changes, so they take +time, roughly 90 seconds total at the time of this writing. + +### Formatting + +``` +$ flake8 bot spl_token stake stake_pool system tests vote +``` + +### Type Checker + +``` +$ mypy bot stake stake_pool tests vote spl_token system +``` + +## Delegation Bots + +The `./bot` directory contains sample stake pool delegation bot implementations: + +* `rebalance`: simple bot to make the amount delegated to each validator +uniform, while also maintaining some SOL in the reserve if desired. Can be run +with the stake pool address, staker keypair, and SOL to leave in the reserve: + +``` +$ python3 bot/rebalance.py Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR staker.json 10.5 +``` diff --git a/clients/py/bot/__init__.py b/clients/py/bot/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/clients/py/bot/rebalance.py b/clients/py/bot/rebalance.py new file mode 100644 index 00000000..37e25261 --- /dev/null +++ b/clients/py/bot/rebalance.py @@ -0,0 +1,135 @@ +import argparse +import asyncio +import json + +from solana.keypair import Keypair +from solana.publickey import PublicKey +from solana.rpc.async_api import AsyncClient +from solana.rpc.commitment import Confirmed + +from stake.constants import STAKE_LEN +from stake_pool.actions import decrease_validator_stake, increase_validator_stake, update_stake_pool +from stake_pool.state import StakePool, ValidatorList + + +LAMPORTS_PER_SOL: int = 1_000_000_000 +MINIMUM_INCREASE_LAMPORTS: int = LAMPORTS_PER_SOL // 100 + + +async def get_client(endpoint: str) -> AsyncClient: + print(f'Connecting to network at {endpoint}') + async_client = AsyncClient(endpoint=endpoint, commitment=Confirmed) + total_attempts = 10 + current_attempt = 0 + while not await async_client.is_connected(): + if current_attempt == total_attempts: + raise Exception("Could not connect to test validator") + else: + current_attempt += 1 + await asyncio.sleep(1) + return async_client + + +async def rebalance(endpoint: str, stake_pool_address: PublicKey, staker: Keypair, retained_reserve_amount: float): + async_client = await get_client(endpoint) + + resp = await async_client.get_epoch_info(commitment=Confirmed) + epoch = resp['result']['epoch'] + resp = await async_client.get_account_info(stake_pool_address, commitment=Confirmed) + data = resp['result']['value']['data'] + stake_pool = StakePool.decode(data[0], data[1]) + + print(f'Stake pool last update epoch {stake_pool.last_update_epoch}, current epoch {epoch}') + if stake_pool.last_update_epoch != epoch: + print('Updating stake pool') + await update_stake_pool(async_client, staker, stake_pool_address) + resp = await async_client.get_account_info(stake_pool_address, commitment=Confirmed) + data = resp['result']['value']['data'] + stake_pool = StakePool.decode(data[0], data[1]) + + resp = await async_client.get_minimum_balance_for_rent_exemption(STAKE_LEN) + stake_rent_exemption = resp['result'] + retained_reserve_lamports = int(retained_reserve_amount * LAMPORTS_PER_SOL) + + resp = await async_client.get_account_info(stake_pool.validator_list, commitment=Confirmed) + data = resp['result']['value']['data'] + validator_list = ValidatorList.decode(data[0], data[1]) + + print('Stake pool stats:') + print(f'* {stake_pool.total_lamports} total lamports') + num_validators = len(validator_list.validators) + print(f'* {num_validators} validators') + print(f'* Retaining {retained_reserve_lamports} lamports in the reserve') + lamports_per_validator = (stake_pool.total_lamports - retained_reserve_lamports) // num_validators + num_increases = sum([ + 1 for validator in validator_list.validators + if validator.transient_stake_lamports == 0 and validator.active_stake_lamports < lamports_per_validator + ]) + total_usable_lamports = stake_pool.total_lamports - retained_reserve_lamports - num_increases * stake_rent_exemption + lamports_per_validator = total_usable_lamports // num_validators + print(f'* {lamports_per_validator} lamports desired per validator') + + futures = [] + for validator in validator_list.validators: + if validator.transient_stake_lamports != 0: + print(f'Skipping {validator.vote_account_address}: {validator.transient_stake_lamports} transient lamports') + else: + if validator.active_stake_lamports > lamports_per_validator: + lamports_to_decrease = validator.active_stake_lamports - lamports_per_validator + if lamports_to_decrease <= stake_rent_exemption: + print(f'Skipping decrease on {validator.vote_account_address}, \ +currently at {validator.active_stake_lamports} lamports, \ +decrease of {lamports_to_decrease} below the rent exmption') + else: + futures.append(decrease_validator_stake( + async_client, staker, staker, stake_pool_address, + validator.vote_account_address, lamports_to_decrease + )) + elif validator.active_stake_lamports < lamports_per_validator: + lamports_to_increase = lamports_per_validator - validator.active_stake_lamports + if lamports_to_increase < MINIMUM_INCREASE_LAMPORTS: + print(f'Skipping increase on {validator.vote_account_address}, \ +currently at {validator.active_stake_lamports} lamports, \ +increase of {lamports_to_increase} less than the minimum of {MINIMUM_INCREASE_LAMPORTS}') + else: + futures.append(increase_validator_stake( + async_client, staker, staker, stake_pool_address, + validator.vote_account_address, lamports_to_increase + )) + else: + print(f'{validator.vote_account_address}: already at {lamports_per_validator}') + + print('Executing strategy') + await asyncio.gather(*futures) + print('Done') + await async_client.close() + + +def keypair_from_file(keyfile_name: str) -> Keypair: + with open(keyfile_name, 'r') as keyfile: + data = keyfile.read() + int_list = json.loads(data) + bytes_list = [value.to_bytes(1, 'little') for value in int_list] + return Keypair.from_secret_key(b''.join(bytes_list)) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description='Rebalance stake evenly between all the validators in a stake pool.') + parser.add_argument('stake_pool', metavar='STAKE_POOL_ADDRESS', type=str, + help='Stake pool to rebalance, given by a public key in base-58,\ + e.g. Zg5YBPAk8RqBR9kaLLSoN5C8Uv7nErBz1WC63HTsCPR') + parser.add_argument('staker', metavar='STAKER_KEYPAIR', type=str, + help='Staker for the stake pool, given by a keypair file, e.g. staker.json') + parser.add_argument('reserve_amount', metavar='RESERVE_AMOUNT', type=float, + help='Amount of SOL to keep in the reserve, e.g. 10.5') + parser.add_argument('--endpoint', metavar='ENDPOINT_URL', type=str, + default='https://api.mainnet-beta.solana.com', + help='RPC endpoint to use, e.g. https://api.mainnet-beta.solana.com') + + args = parser.parse_args() + stake_pool = PublicKey(args.stake_pool) + staker = keypair_from_file(args.staker) + print(f'Rebalancing stake pool {stake_pool}') + print(f'Staker public key: {staker.public_key}') + print(f'Amount to leave in the reserve: {args.reserve_amount} SOL') + asyncio.run(rebalance(args.endpoint, stake_pool, staker, args.reserve_amount)) diff --git a/clients/py/stake_pool/instructions.py b/clients/py/stake_pool/instructions.py index e0f17abf..8f3f1ccb 100644 --- a/clients/py/stake_pool/instructions.py +++ b/clients/py/stake_pool/instructions.py @@ -505,9 +505,9 @@ class InstructionType(IntEnum): InstructionType.CLEANUP_REMOVED_VALIDATOR_ENTRIES: Pass, InstructionType.DEPOSIT_STAKE: Pass, InstructionType.WITHDRAW_STAKE: AMOUNT_LAYOUT, - InstructionType.SET_MANAGER: Pass, + InstructionType.SET_MANAGER: Pass, # TODO InstructionType.SET_FEE: Pass, # TODO - InstructionType.SET_STAKER: Pass, + InstructionType.SET_STAKER: Pass, # TODO InstructionType.DEPOSIT_SOL: AMOUNT_LAYOUT, InstructionType.SET_FUNDING_AUTHORITY: Pass, # TODO InstructionType.WITHDRAW_SOL: AMOUNT_LAYOUT, diff --git a/clients/py/tests/conftest.py b/clients/py/tests/conftest.py index 32fa0797..2c972f19 100644 --- a/clients/py/tests/conftest.py +++ b/clients/py/tests/conftest.py @@ -17,6 +17,8 @@ from stake_pool.actions import create_all, add_validator_to_pool from stake_pool.state import Fee +NUM_SLOTS_PER_EPOCH: int = 32 + @pytest.fixture(scope="session") def solana_test_validator(): @@ -28,7 +30,7 @@ def solana_test_validator(): "--reset", "--quiet", "--bpf-program", "SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy", f"{old_cwd}/../../target/deploy/spl_stake_pool.so", - "--slots-per-epoch", "64", + "--slots-per-epoch", str(NUM_SLOTS_PER_EPOCH), ],) yield validator.kill() @@ -93,3 +95,26 @@ def payer(event_loop, async_client) -> Keypair: airdrop_lamports = 10_000_000_000 event_loop.run_until_complete(airdrop(async_client, payer.public_key, airdrop_lamports)) return payer + + +class Waiter: + @staticmethod + async def wait_for_next_epoch(async_client: AsyncClient): + resp = await async_client.get_epoch_info(commitment=Confirmed) + current_epoch = resp['result']['epoch'] + next_epoch = current_epoch + while current_epoch == next_epoch: + await asyncio.sleep(1.0) + resp = await async_client.get_epoch_info(commitment=Confirmed) + next_epoch = resp['result']['epoch'] + + @staticmethod + async def wait_for_next_epoch_if_soon(async_client: AsyncClient): + resp = await async_client.get_epoch_info(commitment=Confirmed) + if resp['result']['slotsInEpoch'] - resp['result']['slotIndex'] < 10: + await Waiter.wait_for_next_epoch(async_client) + + +@pytest.fixture +def waiter() -> Waiter: + return Waiter() diff --git a/clients/py/tests/test_a_time_sensitive.py b/clients/py/tests/test_a_time_sensitive.py index e3267983..78f707c7 100644 --- a/clients/py/tests/test_a_time_sensitive.py +++ b/clients/py/tests/test_a_time_sensitive.py @@ -10,7 +10,7 @@ @pytest.mark.asyncio -async def test_increase_decrease_this_is_very_slow(async_client, validators, payer, stake_pool_addresses): +async def test_increase_decrease_this_is_very_slow(async_client, validators, payer, stake_pool_addresses, waiter): (stake_pool_address, validator_list_address) = stake_pool_addresses resp = await async_client.get_minimum_balance_for_rent_exemption(STAKE_LEN) stake_rent_exemption = resp['result'] @@ -38,8 +38,8 @@ async def test_increase_decrease_this_is_very_slow(async_client, validators, pay assert validator.transient_stake_lamports == increase_amount + stake_rent_exemption assert validator.active_stake_lamports == 0 - print("Waiting for epoch to roll over, roughly 24 seconds") - await asyncio.sleep(24.0) + print("Waiting for epoch to roll over") + await waiter.wait_for_next_epoch(async_client) await update_stake_pool(async_client, payer, stake_pool_address) resp = await async_client.get_account_info(validator_list_address, commitment=Confirmed) @@ -64,8 +64,8 @@ async def test_increase_decrease_this_is_very_slow(async_client, validators, pay assert validator.transient_stake_lamports == decrease_amount assert validator.active_stake_lamports == increase_amount - decrease_amount - print("Waiting for epoch to roll over, roughly 24 seconds") - await asyncio.sleep(24.0) + print("Waiting for epoch to roll over") + await waiter.wait_for_next_epoch(async_client) await update_stake_pool(async_client, payer, stake_pool_address) resp = await async_client.get_account_info(validator_list_address, commitment=Confirmed) diff --git a/clients/py/tests/test_bot_rebalance.py b/clients/py/tests/test_bot_rebalance.py new file mode 100644 index 00000000..1b28251b --- /dev/null +++ b/clients/py/tests/test_bot_rebalance.py @@ -0,0 +1,79 @@ +"""Time sensitive test, so run it first out of the bunch.""" +import pytest +from solana.rpc.commitment import Confirmed +from spl.token.instructions import get_associated_token_address + +from stake.constants import STAKE_LEN +from stake_pool.state import StakePool, ValidatorList +from stake_pool.actions import deposit_sol + +from bot.rebalance import rebalance + + +ENDPOINT: str = "http://127.0.0.1:8899" + + +@pytest.mark.asyncio +async def test_rebalance_this_is_very_slow(async_client, validators, payer, stake_pool_addresses, waiter): + (stake_pool_address, validator_list_address) = stake_pool_addresses + resp = await async_client.get_minimum_balance_for_rent_exemption(STAKE_LEN) + stake_rent_exemption = resp['result'] + increase_amount = 100_000_000 + deposit_amount = (increase_amount + stake_rent_exemption) * len(validators) + + resp = await async_client.get_account_info(stake_pool_address, commitment=Confirmed) + data = resp['result']['value']['data'] + stake_pool = StakePool.decode(data[0], data[1]) + token_account = get_associated_token_address(payer.public_key, stake_pool.pool_mint) + await deposit_sol(async_client, payer, stake_pool_address, token_account, deposit_amount) + + # Test case 1: Increase + await rebalance(ENDPOINT, stake_pool_address, payer, 0.0) + + # should only have minimum left + resp = await async_client.get_account_info(stake_pool.reserve_stake, commitment=Confirmed) + assert resp['result']['value']['lamports'] == stake_rent_exemption + 1 + + # should all be the same + resp = await async_client.get_account_info(validator_list_address, commitment=Confirmed) + data = resp['result']['value']['data'] + validator_list = ValidatorList.decode(data[0], data[1]) + for validator in validator_list.validators: + assert validator.active_stake_lamports == 0 + assert validator.transient_stake_lamports == increase_amount + stake_rent_exemption + + # Test case 2: Decrease + print('Waiting for next epoch') + await waiter.wait_for_next_epoch(async_client) + await rebalance(ENDPOINT, stake_pool_address, payer, deposit_amount / 1_000_000_000) + + # should still only have minimum left + rent exemptions from increase + resp = await async_client.get_account_info(stake_pool.reserve_stake, commitment=Confirmed) + reserve_lamports = resp['result']['value']['lamports'] + assert reserve_lamports == stake_rent_exemption * (1 + len(validator_list.validators)) + 1 + + # should all be decreasing now + resp = await async_client.get_account_info(validator_list_address, commitment=Confirmed) + data = resp['result']['value']['data'] + validator_list = ValidatorList.decode(data[0], data[1]) + for validator in validator_list.validators: + assert validator.active_stake_lamports == 0 + assert validator.transient_stake_lamports == increase_amount + + # Test case 3: Do nothing + print('Waiting for next epoch') + await waiter.wait_for_next_epoch(async_client) + await rebalance(ENDPOINT, stake_pool_address, payer, deposit_amount / 1_000_000_000) + + # should still only have minimum left + rent exemptions from increase + resp = await async_client.get_account_info(stake_pool.reserve_stake, commitment=Confirmed) + reserve_lamports = resp['result']['value']['lamports'] + assert reserve_lamports == stake_rent_exemption + deposit_amount + 1 + + # should all be decreasing now + resp = await async_client.get_account_info(validator_list_address, commitment=Confirmed) + data = resp['result']['value']['data'] + validator_list = ValidatorList.decode(data[0], data[1]) + for validator in validator_list.validators: + assert validator.active_stake_lamports == 0 + assert validator.transient_stake_lamports == 0 diff --git a/clients/py/tests/test_deposit_withdraw_stake.py b/clients/py/tests/test_deposit_withdraw_stake.py index 3341d0d9..12340a44 100644 --- a/clients/py/tests/test_deposit_withdraw_stake.py +++ b/clients/py/tests/test_deposit_withdraw_stake.py @@ -1,16 +1,30 @@ +import asyncio import pytest +from typing import Tuple +from solana.rpc.async_api import AsyncClient from solana.rpc.commitment import Confirmed from solana.keypair import Keypair +from solana.publickey import PublicKey from spl.token.instructions import get_associated_token_address from stake.actions import create_stake, delegate_stake from stake.constants import STAKE_LEN -from stake_pool.actions import deposit_stake, withdraw_stake +from stake_pool.actions import deposit_stake, withdraw_stake, update_stake_pool from stake_pool.state import StakePool +async def prepare_stake( + async_client: AsyncClient, payer: Keypair, stake_pool_address: PublicKey, + validator: PublicKey, token_account: PublicKey, stake_amount: int +) -> Tuple[PublicKey, PublicKey]: + stake = Keypair() + await create_stake(async_client, payer, stake, payer.public_key, stake_amount) + await delegate_stake(async_client, payer, payer, stake.public_key, validator) + return (stake.public_key, validator) + + @pytest.mark.asyncio -async def test_deposit_withdraw_stake(async_client, validators, payer, stake_pool_addresses): +async def test_deposit_withdraw_stake(async_client, validators, payer, stake_pool_addresses, waiter): (stake_pool_address, validator_list_address) = stake_pool_addresses resp = await async_client.get_account_info(stake_pool_address, commitment=Confirmed) data = resp['result']['value']['data'] @@ -19,24 +33,35 @@ async def test_deposit_withdraw_stake(async_client, validators, payer, stake_poo resp = await async_client.get_minimum_balance_for_rent_exemption(STAKE_LEN) stake_rent_exemption = resp['result'] + await waiter.wait_for_next_epoch_if_soon(async_client) + await update_stake_pool(async_client, payer, stake_pool_address) stake_amount = 1_000_000 - for validator in validators: - stake = Keypair() - await create_stake(async_client, payer, stake, payer.public_key, stake_amount) - await delegate_stake(async_client, payer, payer, stake.public_key, validator) - await deposit_stake(async_client, payer, stake_pool_address, validator, stake.public_key, token_account) + futures = [ + prepare_stake(async_client, payer, stake_pool_address, validator, token_account, stake_amount) + for validator in validators + ] + stakes = await asyncio.gather(*futures) + await waiter.wait_for_next_epoch(async_client) + await update_stake_pool(async_client, payer, stake_pool_address) + futures = [ + deposit_stake(async_client, payer, stake_pool_address, validator, stake, token_account) + for (stake, validator) in stakes + ] + stakes = await asyncio.gather(*futures) pool_token_balance = await async_client.get_token_account_balance(token_account, Confirmed) pool_token_balance = pool_token_balance['result']['value']['amount'] assert pool_token_balance == str((stake_amount + stake_rent_exemption) * len(validators)) + futures = [] for validator in validators: destination_stake = Keypair() - await withdraw_stake( + futures.append(withdraw_stake( async_client, payer, payer, destination_stake, stake_pool_address, validator, payer.public_key, token_account, stake_amount - ) + )) + await asyncio.gather(*futures) pool_token_balance = await async_client.get_token_account_balance(token_account, Confirmed) pool_token_balance = pool_token_balance['result']['value']['amount'] diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 0b7eda1e..b2eb5f5e 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -793,185 +793,6 @@ async fn fail_with_uninitialized_validator_list() {} // TODO #[tokio::test] async fn fail_with_out_of_dated_pool_balances() {} // TODO -#[tokio::test] -async fn success_with_deposit_authority() { - let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_deposit_authority = Keypair::new(); - let stake_pool_accounts = - StakePoolAccounts::new_with_deposit_authority(stake_deposit_authority); - stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) - .await - .unwrap(); - - let validator_stake_account = simple_add_validator_to_pool( - &mut banks_client, - &payer, - &recent_blockhash, - &stake_pool_accounts, - ) - .await; - - let user = Keypair::new(); - let user_stake = Keypair::new(); - let lockup = stake::state::Lockup::default(); - let authorized = stake::state::Authorized { - staker: user.pubkey(), - withdrawer: user.pubkey(), - }; - let _stake_lamports = create_independent_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake, - &authorized, - &lockup, - TEST_STAKE_AMOUNT, - ) - .await; - - create_vote( - &mut banks_client, - &payer, - &recent_blockhash, - &validator_stake_account.validator, - &validator_stake_account.vote, - ) - .await; - delegate_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake.pubkey(), - &user, - &validator_stake_account.vote.pubkey(), - ) - .await; - - // make pool token account - let user_pool_account = Keypair::new(); - create_token_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_pool_account, - &stake_pool_accounts.pool_mint.pubkey(), - &user.pubkey(), - ) - .await - .unwrap(); - - let error = stake_pool_accounts - .deposit_stake( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake.pubkey(), - &user_pool_account.pubkey(), - &validator_stake_account.stake_account, - &user, - ) - .await; - assert!(error.is_none()); -} - -#[tokio::test] -async fn fail_without_deposit_authority_signature() { - let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_deposit_authority = Keypair::new(); - let mut stake_pool_accounts = - StakePoolAccounts::new_with_deposit_authority(stake_deposit_authority); - stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) - .await - .unwrap(); - - let validator_stake_account = simple_add_validator_to_pool( - &mut banks_client, - &payer, - &recent_blockhash, - &stake_pool_accounts, - ) - .await; - - let user = Keypair::new(); - let user_stake = Keypair::new(); - let lockup = stake::state::Lockup::default(); - let authorized = stake::state::Authorized { - staker: user.pubkey(), - withdrawer: user.pubkey(), - }; - let _stake_lamports = create_independent_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake, - &authorized, - &lockup, - TEST_STAKE_AMOUNT, - ) - .await; - - create_vote( - &mut banks_client, - &payer, - &recent_blockhash, - &validator_stake_account.validator, - &validator_stake_account.vote, - ) - .await; - delegate_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake.pubkey(), - &user, - &validator_stake_account.vote.pubkey(), - ) - .await; - - // make pool token account - let user_pool_account = Keypair::new(); - create_token_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_pool_account, - &stake_pool_accounts.pool_mint.pubkey(), - &user.pubkey(), - ) - .await - .unwrap(); - - let wrong_depositor = Keypair::new(); - stake_pool_accounts.stake_deposit_authority = wrong_depositor.pubkey(); - stake_pool_accounts.stake_deposit_authority_keypair = Some(wrong_depositor); - - let error = stake_pool_accounts - .deposit_stake( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake.pubkey(), - &user_pool_account.pubkey(), - &validator_stake_account.stake_account, - &user, - ) - .await - .unwrap() - .unwrap(); - - match error { - TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { - assert_eq!( - error_index, - StakePoolError::InvalidStakeDepositAuthority as u32 - ); - } - _ => panic!("Wrong error occurs while try to make a deposit with wrong stake program ID"), - } -} - #[tokio::test] async fn success_with_preferred_deposit() { let ( diff --git a/program/tests/deposit_authority.rs b/program/tests/deposit_authority.rs new file mode 100644 index 00000000..ace4b5d1 --- /dev/null +++ b/program/tests/deposit_authority.rs @@ -0,0 +1,200 @@ +#![cfg(feature = "test-bpf")] + +mod helpers; + +use { + helpers::*, + solana_program::{instruction::InstructionError, stake}, + solana_program_test::*, + solana_sdk::{ + borsh::try_from_slice_unchecked, + signature::{Keypair, Signer}, + transaction::TransactionError, + }, + spl_stake_pool::{error::StakePoolError, state::StakePool}, +}; + +#[tokio::test] +async fn success_initialize() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let deposit_authority = Keypair::new(); + let stake_pool_accounts = StakePoolAccounts::new_with_deposit_authority(deposit_authority); + let deposit_authority = stake_pool_accounts.stake_deposit_authority; + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .await + .unwrap(); + + // Stake pool now exists + let stake_pool_account = + get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; + let stake_pool = + try_from_slice_unchecked::(stake_pool_account.data.as_slice()).unwrap(); + assert_eq!(stake_pool.stake_deposit_authority, deposit_authority); + assert_eq!(stake_pool.sol_deposit_authority.unwrap(), deposit_authority); +} + +#[tokio::test] +async fn success_deposit() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_deposit_authority = Keypair::new(); + let stake_pool_accounts = + StakePoolAccounts::new_with_deposit_authority(stake_deposit_authority); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .await + .unwrap(); + + let validator_stake_account = simple_add_validator_to_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + ) + .await; + + let user = Keypair::new(); + let user_stake = Keypair::new(); + let lockup = stake::state::Lockup::default(); + let authorized = stake::state::Authorized { + staker: user.pubkey(), + withdrawer: user.pubkey(), + }; + + let _stake_lamports = create_independent_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake, + &authorized, + &lockup, + TEST_STAKE_AMOUNT, + ) + .await; + + delegate_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.pubkey(), + &user, + &validator_stake_account.vote.pubkey(), + ) + .await; + + // make pool token account + let user_pool_account = Keypair::new(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user.pubkey(), + ) + .await + .unwrap(); + + let error = stake_pool_accounts + .deposit_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.pubkey(), + &user_pool_account.pubkey(), + &validator_stake_account.stake_account, + &user, + ) + .await; + assert!(error.is_none()); +} + +#[tokio::test] +async fn fail_deposit_without_authority_signature() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_deposit_authority = Keypair::new(); + let mut stake_pool_accounts = + StakePoolAccounts::new_with_deposit_authority(stake_deposit_authority); + stake_pool_accounts + .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .await + .unwrap(); + + let validator_stake_account = simple_add_validator_to_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + ) + .await; + + let user = Keypair::new(); + let user_stake = Keypair::new(); + let lockup = stake::state::Lockup::default(); + let authorized = stake::state::Authorized { + staker: user.pubkey(), + withdrawer: user.pubkey(), + }; + + let _stake_lamports = create_independent_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake, + &authorized, + &lockup, + TEST_STAKE_AMOUNT, + ) + .await; + + delegate_stake_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.pubkey(), + &user, + &validator_stake_account.vote.pubkey(), + ) + .await; + + // make pool token account + let user_pool_account = Keypair::new(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &user_pool_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user.pubkey(), + ) + .await + .unwrap(); + + let wrong_depositor = Keypair::new(); + stake_pool_accounts.stake_deposit_authority = wrong_depositor.pubkey(); + stake_pool_accounts.stake_deposit_authority_keypair = Some(wrong_depositor); + + let error = stake_pool_accounts + .deposit_stake( + &mut banks_client, + &payer, + &recent_blockhash, + &user_stake.pubkey(), + &user_pool_account.pubkey(), + &validator_stake_account.stake_account, + &user, + ) + .await + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + assert_eq!( + error_index, + StakePoolError::InvalidStakeDepositAuthority as u32 + ); + } + _ => panic!("Wrong error occurs while try to make a deposit with wrong stake program ID"), + } +} diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index 6fd44848..dd260923 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -1273,23 +1273,3 @@ async fn fail_with_bad_reserve() { ); } } - -#[tokio::test] -async fn success_with_deposit_authority() { - let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let deposit_authority = Keypair::new(); - let stake_pool_accounts = StakePoolAccounts::new_with_deposit_authority(deposit_authority); - let deposit_authority = stake_pool_accounts.stake_deposit_authority; - stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) - .await - .unwrap(); - - // Stake pool now exists - let stake_pool_account = - get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; - let stake_pool = - try_from_slice_unchecked::(stake_pool_account.data.as_slice()).unwrap(); - assert_eq!(stake_pool.stake_deposit_authority, deposit_authority); - assert_eq!(stake_pool.sol_deposit_authority.unwrap(), deposit_authority); -} From b1967d6e7fb33dbddc27fb90e9af64a5c641e139 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 14 Dec 2021 02:25:37 +0100 Subject: [PATCH 0208/1076] stake-pool-cli: Add `deposit-all-stake` command (#2614) * stake-pool-cli: Add `deposit-all-stake` command * Improve py test --- clients/cli/src/client.rs | 33 ++- clients/cli/src/main.rs | 209 ++++++++++++++++++ clients/py/tests/conftest.py | 5 +- .../py/tests/test_deposit_withdraw_stake.py | 52 ++--- 4 files changed, 261 insertions(+), 38 deletions(-) diff --git a/clients/cli/src/client.rs b/clients/cli/src/client.rs index c36a8956..005d8908 100644 --- a/clients/cli/src/client.rs +++ b/clients/cli/src/client.rs @@ -5,13 +5,14 @@ use { client_error::ClientError, rpc_client::RpcClient, rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig}, - rpc_filter::{Memcmp, MemcmpEncodedBytes, RpcFilterType}, + rpc_filter::{Memcmp, MemcmpEncodedBytes, MemcmpEncoding, RpcFilterType}, }, solana_program::{borsh::try_from_slice_unchecked, program_pack::Pack, pubkey::Pubkey, stake}, spl_stake_pool::{ find_withdraw_authority_program_address, state::{StakePool, ValidatorList}, }, + std::collections::HashSet, }; type Error = Box; @@ -119,3 +120,33 @@ pub(crate) fn get_stake_pools( .collect() }) } + +pub(crate) fn get_all_stake( + rpc_client: &RpcClient, + authorized_staker: &Pubkey, +) -> Result, ClientError> { + let all_stake_accounts = rpc_client.get_program_accounts_with_config( + &stake::program::id(), + RpcProgramAccountsConfig { + filters: Some(vec![ + // Filter by `Meta::authorized::staker`, which begins at byte offset 12 + RpcFilterType::Memcmp(Memcmp { + offset: 12, + bytes: MemcmpEncodedBytes::Base58(authorized_staker.to_string()), + encoding: Some(MemcmpEncoding::Binary), + }), + ]), + account_config: RpcAccountInfoConfig { + encoding: Some(solana_account_decoder::UiAccountEncoding::Base64), + commitment: Some(rpc_client.commitment()), + ..RpcAccountInfoConfig::default() + }, + ..RpcProgramAccountsConfig::default() + }, + )?; + + Ok(all_stake_accounts + .into_iter() + .map(|(address, _)| address) + .collect()) +} diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index efe43d00..ec944174 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -733,6 +733,145 @@ fn command_deposit_stake( Ok(()) } +fn command_deposit_all_stake( + config: &Config, + stake_pool_address: &Pubkey, + stake_authority: &Pubkey, + withdraw_authority: Box, + pool_token_receiver_account: &Option, + referrer_token_account: &Option, +) -> CommandResult { + if !config.no_update { + command_update(config, stake_pool_address, false, false)?; + } + + let stake_addresses = get_all_stake(&config.rpc_client, stake_authority)?; + let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; + + // Create token account if not specified + let mut total_rent_free_balances = 0; + let mut create_token_account_instructions = vec![]; + let pool_token_receiver_account = + pool_token_receiver_account.unwrap_or(add_associated_token_account( + config, + &stake_pool.pool_mint, + &config.token_owner.pubkey(), + &mut create_token_account_instructions, + &mut total_rent_free_balances, + )); + if !create_token_account_instructions.is_empty() { + let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + let transaction = Transaction::new_signed_with_payer( + &create_token_account_instructions, + Some(&config.fee_payer.pubkey()), + &[config.fee_payer.as_ref()], + recent_blockhash, + ); + check_fee_payer_balance( + config, + total_rent_free_balances + fee_calculator.calculate_fee(transaction.message()), + )?; + send_transaction(config, transaction)?; + } + + let referrer_token_account = referrer_token_account.unwrap_or(pool_token_receiver_account); + + let pool_withdraw_authority = + find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; + let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?; + let mut signers = if let Some(stake_deposit_authority) = config.funding_authority.as_ref() { + if stake_deposit_authority.pubkey() != stake_pool.stake_deposit_authority { + let error = format!( + "Invalid deposit authority specified, expected {}, received {}", + stake_pool.stake_deposit_authority, + stake_deposit_authority.pubkey() + ); + return Err(error.into()); + } + + vec![ + config.fee_payer.as_ref(), + withdraw_authority.as_ref(), + stake_deposit_authority.as_ref(), + ] + } else { + vec![config.fee_payer.as_ref(), withdraw_authority.as_ref()] + }; + unique_signers!(signers); + + for stake_address in stake_addresses { + let stake_state = get_stake_state(&config.rpc_client, &stake_address)?; + + let vote_account = match stake_state { + stake::state::StakeState::Stake(_, stake) => Ok(stake.delegation.voter_pubkey), + _ => Err("Wrong stake account state, must be delegated to validator"), + }?; + + if !validator_list.contains(&vote_account) { + return Err("Stake account for this validator does not exist in the pool.".into()); + } + + // Calculate validator stake account address linked to the pool + let (validator_stake_account, _) = + find_stake_program_address(&spl_stake_pool::id(), &vote_account, stake_pool_address); + + let validator_stake_state = get_stake_state(&config.rpc_client, &validator_stake_account)?; + println!("Depositing user stake {}: {:?}", stake_address, stake_state); + println!( + "..into pool stake {}: {:?}", + validator_stake_account, validator_stake_state + ); + + let instructions = if let Some(stake_deposit_authority) = config.funding_authority.as_ref() + { + spl_stake_pool::instruction::deposit_stake_with_authority( + &spl_stake_pool::id(), + stake_pool_address, + &stake_pool.validator_list, + &stake_deposit_authority.pubkey(), + &pool_withdraw_authority, + &stake_address, + &withdraw_authority.pubkey(), + &validator_stake_account, + &stake_pool.reserve_stake, + &pool_token_receiver_account, + &stake_pool.manager_fee_account, + &referrer_token_account, + &stake_pool.pool_mint, + &spl_token::id(), + ) + } else { + spl_stake_pool::instruction::deposit_stake( + &spl_stake_pool::id(), + stake_pool_address, + &stake_pool.validator_list, + &pool_withdraw_authority, + &stake_address, + &withdraw_authority.pubkey(), + &validator_stake_account, + &stake_pool.reserve_stake, + &pool_token_receiver_account, + &stake_pool.manager_fee_account, + &referrer_token_account, + &stake_pool.pool_mint, + &spl_token::id(), + ) + }; + + let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + let transaction = Transaction::new_signed_with_payer( + &instructions, + Some(&config.fee_payer.pubkey()), + &signers, + recent_blockhash, + ); + check_fee_payer_balance(config, fee_calculator.calculate_fee(transaction.message()))?; + + send_transaction(config, transaction)?; + } + Ok(()) +} + fn command_deposit_sol( config: &Config, stake_pool_address: &Pubkey, @@ -1981,6 +2120,53 @@ fn main() { Defaults to the token receiver."), ) ) + .subcommand(SubCommand::with_name("deposit-all-stake") + .about("Deposit all active stake accounts into the stake pool in exchange for pool tokens") + .arg( + Arg::with_name("pool") + .index(1) + .validator(is_pubkey) + .value_name("POOL_ADDRESS") + .takes_value(true) + .required(true) + .help("Stake pool address"), + ) + .arg( + Arg::with_name("stake_authority") + .index(2) + .validator(is_pubkey) + .value_name("ADDRESS") + .takes_value(true) + .required(true) + .help("Stake authority address to search for stake accounts"), + ) + .arg( + Arg::with_name("withdraw_authority") + .long("withdraw-authority") + .validator(is_valid_signer) + .value_name("KEYPAIR") + .takes_value(true) + .help("Withdraw authority for the stake account to be deposited. [default: cli config keypair]"), + ) + .arg( + Arg::with_name("token_receiver") + .long("token-receiver") + .validator(is_pubkey) + .value_name("ADDRESS") + .takes_value(true) + .help("Account to receive the minted pool tokens. \ + Defaults to the token-owner's associated pool token account. \ + Creates the account if it does not exist."), + ) + .arg( + Arg::with_name("referrer") + .validator(is_pubkey) + .value_name("ADDRESS") + .takes_value(true) + .help("Pool token account to receive the referral fees for deposits. \ + Defaults to the token receiver."), + ) + ) .subcommand(SubCommand::with_name("deposit-sol") .about("Deposit SOL into the stake pool in exchange for pool tokens") .arg( @@ -2659,6 +2845,29 @@ fn main() { command_set_fee(&config, &stake_pool_address, fee_type) } ("list-all", _) => command_list_all_pools(&config), + ("deposit-all-stake", Some(arg_matches)) => { + let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); + let stake_authority = pubkey_of(arg_matches, "stake_authority").unwrap(); + let token_receiver: Option = pubkey_of(arg_matches, "token_receiver"); + let referrer: Option = pubkey_of(arg_matches, "referrer"); + let withdraw_authority = get_signer( + arg_matches, + "withdraw_authority", + &cli_config.keypair_path, + &mut wallet_manager, + SignerFromPathConfig { + allow_null_signer: false, + }, + ); + command_deposit_all_stake( + &config, + &stake_pool_address, + &stake_authority, + withdraw_authority, + &token_receiver, + &referrer, + ) + } _ => unreachable!(), } .map_err(|err| { diff --git a/clients/py/tests/conftest.py b/clients/py/tests/conftest.py index 2c972f19..60a263fa 100644 --- a/clients/py/tests/conftest.py +++ b/clients/py/tests/conftest.py @@ -111,8 +111,11 @@ async def wait_for_next_epoch(async_client: AsyncClient): @staticmethod async def wait_for_next_epoch_if_soon(async_client: AsyncClient): resp = await async_client.get_epoch_info(commitment=Confirmed) - if resp['result']['slotsInEpoch'] - resp['result']['slotIndex'] < 10: + if resp['result']['slotsInEpoch'] - resp['result']['slotIndex'] < NUM_SLOTS_PER_EPOCH // 2: await Waiter.wait_for_next_epoch(async_client) + return True + else: + return False @pytest.fixture diff --git a/clients/py/tests/test_deposit_withdraw_stake.py b/clients/py/tests/test_deposit_withdraw_stake.py index 12340a44..0e260ff7 100644 --- a/clients/py/tests/test_deposit_withdraw_stake.py +++ b/clients/py/tests/test_deposit_withdraw_stake.py @@ -1,10 +1,6 @@ -import asyncio import pytest -from typing import Tuple -from solana.rpc.async_api import AsyncClient from solana.rpc.commitment import Confirmed from solana.keypair import Keypair -from solana.publickey import PublicKey from spl.token.instructions import get_associated_token_address from stake.actions import create_stake, delegate_stake @@ -13,16 +9,6 @@ from stake_pool.state import StakePool -async def prepare_stake( - async_client: AsyncClient, payer: Keypair, stake_pool_address: PublicKey, - validator: PublicKey, token_account: PublicKey, stake_amount: int -) -> Tuple[PublicKey, PublicKey]: - stake = Keypair() - await create_stake(async_client, payer, stake, payer.public_key, stake_amount) - await delegate_stake(async_client, payer, payer, stake.public_key, validator) - return (stake.public_key, validator) - - @pytest.mark.asyncio async def test_deposit_withdraw_stake(async_client, validators, payer, stake_pool_addresses, waiter): (stake_pool_address, validator_list_address) = stake_pool_addresses @@ -33,36 +19,30 @@ async def test_deposit_withdraw_stake(async_client, validators, payer, stake_poo resp = await async_client.get_minimum_balance_for_rent_exemption(STAKE_LEN) stake_rent_exemption = resp['result'] - await waiter.wait_for_next_epoch_if_soon(async_client) - await update_stake_pool(async_client, payer, stake_pool_address) + waited = await waiter.wait_for_next_epoch_if_soon(async_client) + if waited: + await update_stake_pool(async_client, payer, stake_pool_address) + validator = next(iter(validators)) stake_amount = 1_000_000 - futures = [ - prepare_stake(async_client, payer, stake_pool_address, validator, token_account, stake_amount) - for validator in validators - ] - stakes = await asyncio.gather(*futures) + stake = Keypair() + await create_stake(async_client, payer, stake, payer.public_key, stake_amount) + stake = stake.public_key + await delegate_stake(async_client, payer, payer, stake, validator) await waiter.wait_for_next_epoch(async_client) await update_stake_pool(async_client, payer, stake_pool_address) - futures = [ - deposit_stake(async_client, payer, stake_pool_address, validator, stake, token_account) - for (stake, validator) in stakes - ] - stakes = await asyncio.gather(*futures) + await deposit_stake(async_client, payer, stake_pool_address, validator, stake, token_account) pool_token_balance = await async_client.get_token_account_balance(token_account, Confirmed) pool_token_balance = pool_token_balance['result']['value']['amount'] - assert pool_token_balance == str((stake_amount + stake_rent_exemption) * len(validators)) + assert pool_token_balance == str(stake_amount + stake_rent_exemption) - futures = [] - for validator in validators: - destination_stake = Keypair() - futures.append(withdraw_stake( - async_client, payer, payer, destination_stake, stake_pool_address, validator, - payer.public_key, token_account, stake_amount - )) - await asyncio.gather(*futures) + destination_stake = Keypair() + await withdraw_stake( + async_client, payer, payer, destination_stake, stake_pool_address, validator, + payer.public_key, token_account, stake_amount + ) pool_token_balance = await async_client.get_token_account_balance(token_account, Confirmed) pool_token_balance = pool_token_balance['result']['value']['amount'] - assert pool_token_balance == str(stake_rent_exemption * len(validators)) + assert pool_token_balance == str(stake_rent_exemption) From 64fcdc54e5015bd224c4059638f1baea3fc9590b Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 14 Dec 2021 18:45:15 +0100 Subject: [PATCH 0209/1076] stake-pool: Mint extra reserve lamports as pool tokens on init (#2636) * stake-pool: Mint extra reserve lamports as pool tokens on init * Wait more aggressively in py test * Simplify test --- clients/cli/src/main.rs | 1 + clients/py/stake_pool/actions.py | 3 +++ clients/py/stake_pool/instructions.py | 11 +++++--- program/src/instruction.rs | 19 ++++++++------ program/src/processor.rs | 22 ++++++++++++++++ program/tests/helpers/mod.rs | 30 ++++++++++----------- program/tests/initialize.rs | 38 ++++++++++++++++++++++++++- 7 files changed, 96 insertions(+), 28 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index ec944174..5e7badc9 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -314,6 +314,7 @@ fn command_create_pool( &stake_pool_keypair.pubkey(), &config.manager.pubkey(), &config.staker.pubkey(), + &withdraw_authority, &validator_list_keypair.pubkey(), &reserve_keypair.pubkey(), &mint_keypair.pubkey(), diff --git a/clients/py/stake_pool/actions.py b/clients/py/stake_pool/actions.py index 54e4e3a6..24d285cf 100644 --- a/clients/py/stake_pool/actions.py +++ b/clients/py/stake_pool/actions.py @@ -63,6 +63,8 @@ async def create(client: AsyncClient, manager: Keypair, await client.send_transaction( txn, manager, stake_pool, validator_list, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + (withdraw_authority, seed) = find_withdraw_authority_program_address( + STAKE_POOL_PROGRAM_ID, stake_pool.public_key) txn = Transaction() txn.add( sp.initialize( @@ -71,6 +73,7 @@ async def create(client: AsyncClient, manager: Keypair, stake_pool=stake_pool.public_key, manager=manager.public_key, staker=manager.public_key, + withdraw_authority=withdraw_authority, validator_list=validator_list.public_key, reserve_stake=reserve_stake, pool_mint=pool_mint, diff --git a/clients/py/stake_pool/instructions.py b/clients/py/stake_pool/instructions.py index 8f3f1ccb..5a227575 100644 --- a/clients/py/stake_pool/instructions.py +++ b/clients/py/stake_pool/instructions.py @@ -49,14 +49,16 @@ class InitializeParams(NamedTuple): """[s] Manager for new stake pool.""" staker: PublicKey """[] Staker for the new stake pool.""" + withdraw_authority: PublicKey + """[] Withdraw authority for the new stake pool.""" validator_list: PublicKey """[w] Uninitialized validator list account for the new stake pool.""" reserve_stake: PublicKey """[] Reserve stake account.""" pool_mint: PublicKey - """[] Pool token mint account.""" + """[w] Pool token mint account.""" manager_fee_account: PublicKey - """[] Manager's fee account""" + """[w] Manager's fee account""" token_program_id: PublicKey """[] SPL Token program id.""" @@ -535,10 +537,11 @@ def initialize(params: InitializeParams) -> TransactionInstruction: AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=True), AccountMeta(pubkey=params.manager, is_signer=True, is_writable=False), AccountMeta(pubkey=params.staker, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), AccountMeta(pubkey=params.validator_list, is_signer=False, is_writable=True), AccountMeta(pubkey=params.reserve_stake, is_signer=False, is_writable=False), - AccountMeta(pubkey=params.pool_mint, is_signer=False, is_writable=False), - AccountMeta(pubkey=params.manager_fee_account, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.pool_mint, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.manager_fee_account, is_signer=False, is_writable=True), AccountMeta(pubkey=TOKEN_PROGRAM_ID, is_signer=False, is_writable=False), ] if params.deposit_authority: diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 7aa47c16..d511a051 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -49,13 +49,14 @@ pub enum StakePoolInstruction { /// 0. `[w]` New StakePool to create. /// 1. `[s]` Manager /// 2. `[]` Staker - /// 3. `[w]` Uninitialized validator stake list storage account - /// 4. `[]` Reserve stake account must be initialized, have zero balance, + /// 3. `[]` Stake pool withdraw authority + /// 4. `[w]` Uninitialized validator stake list storage account + /// 5. `[]` Reserve stake account must be initialized, have zero balance, /// and staker / withdrawer authority set to pool withdraw authority. - /// 5. `[]` Pool token mint. Must have zero supply, owned by withdraw authority. - /// 6. `[]` Pool account to deposit the generated fee for manager. - /// 7. `[]` Token program id - /// 8. `[]` (Optional) Deposit authority that must sign all deposits. + /// 6. `[]` Pool token mint. Must have zero supply, owned by withdraw authority. + /// 7. `[]` Pool account to deposit the generated fee for manager. + /// 8. `[]` Token program id + /// 9. `[]` (Optional) Deposit authority that must sign all deposits. /// Defaults to the program address generated using /// `find_deposit_authority_program_address`, making deposits permissionless. Initialize { @@ -380,6 +381,7 @@ pub fn initialize( stake_pool: &Pubkey, manager: &Pubkey, staker: &Pubkey, + stake_pool_withdraw_authority: &Pubkey, validator_list: &Pubkey, reserve_stake: &Pubkey, pool_mint: &Pubkey, @@ -404,10 +406,11 @@ pub fn initialize( AccountMeta::new(*stake_pool, false), AccountMeta::new_readonly(*manager, true), AccountMeta::new_readonly(*staker, false), + AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), AccountMeta::new(*validator_list, false), AccountMeta::new_readonly(*reserve_stake, false), - AccountMeta::new_readonly(*pool_mint, false), - AccountMeta::new_readonly(*manager_pool_account, false), + AccountMeta::new(*pool_mint, false), + AccountMeta::new(*manager_pool_account, false), AccountMeta::new_readonly(*token_program_id, false), ]; if let Some(deposit_authority) = deposit_authority { diff --git a/program/src/processor.rs b/program/src/processor.rs index 29ed14eb..9a5ad43d 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -500,6 +500,7 @@ impl Processor { let stake_pool_info = next_account_info(account_info_iter)?; let manager_info = next_account_info(account_info_iter)?; let staker_info = next_account_info(account_info_iter)?; + let withdraw_authority_info = next_account_info(account_info_iter)?; let validator_list_info = next_account_info(account_info_iter)?; let reserve_stake_info = next_account_info(account_info_iter)?; let pool_mint_info = next_account_info(account_info_iter)?; @@ -605,6 +606,14 @@ impl Processor { }; let (withdraw_authority_key, stake_withdraw_bump_seed) = crate::find_withdraw_authority_program_address(program_id, stake_pool_info.key); + if withdraw_authority_key != *withdraw_authority_info.key { + msg!( + "Incorrect withdraw authority provided, expected {}, received {}", + withdraw_authority_key, + withdraw_authority_info.key + ); + return Err(StakePoolError::InvalidProgramAddress.into()); + } let pool_mint = Mint::unpack_from_slice(&pool_mint_info.data.borrow())?; @@ -659,6 +668,19 @@ impl Processor { return Err(StakePoolError::WrongStakeState.into()); }; + if total_lamports > 0 { + Self::token_mint_to( + stake_pool_info.key, + token_program_info.clone(), + pool_mint_info.clone(), + manager_fee_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_withdraw_bump_seed, + total_lamports, + )?; + } + validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; stake_pool.account_type = AccountType::StakePool; diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 37bc0916..ec3fd059 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -20,8 +20,9 @@ use { vote_state::{VoteInit, VoteState}, }, spl_stake_pool::{ - find_stake_program_address, find_transient_stake_program_address, id, instruction, - processor, + find_deposit_authority_program_address, find_stake_program_address, + find_transient_stake_program_address, find_withdraw_authority_program_address, id, + instruction, processor, state::{self, FeeType, ValidatorList}, MINIMUM_ACTIVE_STAKE, }, @@ -317,6 +318,7 @@ pub async fn create_stake_pool( pool_token_account: &Pubkey, manager: &Keypair, staker: &Pubkey, + withdraw_authority: &Pubkey, stake_deposit_authority: &Option, epoch_fee: &state::Fee, withdrawal_fee: &state::Fee, @@ -353,6 +355,7 @@ pub async fn create_stake_pool( &stake_pool.pubkey(), &manager.pubkey(), staker, + withdraw_authority, &validator_list.pubkey(), reserve_stake, pool_mint, @@ -624,14 +627,10 @@ impl StakePoolAccounts { let stake_pool = Keypair::new(); let validator_list = Keypair::new(); let stake_pool_address = &stake_pool.pubkey(); - let (withdraw_authority, _) = Pubkey::find_program_address( - &[&stake_pool_address.to_bytes()[..32], b"withdraw"], - &id(), - ); - let (stake_deposit_authority, _) = Pubkey::find_program_address( - &[&stake_pool_address.to_bytes()[..32], b"deposit"], - &id(), - ); + let (stake_deposit_authority, _) = + find_deposit_authority_program_address(&id(), stake_pool_address); + let (withdraw_authority, _) = + find_withdraw_authority_program_address(&id(), stake_pool_address); let reserve_stake = Keypair::new(); let pool_mint = Keypair::new(); let pool_fee_account = Keypair::new(); @@ -700,13 +699,13 @@ impl StakePoolAccounts { pub async fn initialize_stake_pool( &self, - mut banks_client: &mut BanksClient, + banks_client: &mut BanksClient, payer: &Keypair, recent_blockhash: &Hash, reserve_lamports: u64, ) -> Result<(), TransportError> { create_mint( - &mut banks_client, + banks_client, payer, recent_blockhash, &self.pool_mint, @@ -714,7 +713,7 @@ impl StakePoolAccounts { ) .await?; create_token_account( - &mut banks_client, + banks_client, payer, recent_blockhash, &self.pool_fee_account, @@ -723,7 +722,7 @@ impl StakePoolAccounts { ) .await?; create_independent_stake_account( - &mut banks_client, + banks_client, payer, recent_blockhash, &self.reserve_stake, @@ -736,7 +735,7 @@ impl StakePoolAccounts { ) .await; create_stake_pool( - &mut banks_client, + banks_client, payer, recent_blockhash, &self.stake_pool, @@ -746,6 +745,7 @@ impl StakePoolAccounts { &self.pool_fee_account.pubkey(), &self.manager, &self.staker.pubkey(), + &self.withdraw_authority, &self.stake_deposit_authority_keypair, &self.epoch_fee, &self.withdrawal_fee, diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index dd260923..2b4f6e3b 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -246,6 +246,7 @@ async fn fail_with_wrong_max_validators() { &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), &stake_pool_accounts.staker.pubkey(), + &stake_pool_accounts.withdraw_authority, &stake_pool_accounts.validator_list.pubkey(), &stake_pool_accounts.reserve_stake.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), @@ -324,6 +325,7 @@ async fn fail_with_wrong_mint_authority() { &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.manager, &stake_pool_accounts.staker.pubkey(), + &stake_pool_accounts.withdraw_authority, &None, &stake_pool_accounts.epoch_fee, &stake_pool_accounts.withdrawal_fee, @@ -414,6 +416,7 @@ async fn fail_with_freeze_authority() { &pool_fee_account.pubkey(), &stake_pool_accounts.manager, &stake_pool_accounts.staker.pubkey(), + &stake_pool_accounts.withdraw_authority, &None, &stake_pool_accounts.epoch_fee, &stake_pool_accounts.withdrawal_fee, @@ -494,6 +497,7 @@ async fn fail_with_wrong_token_program_id() { &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), &stake_pool_accounts.staker.pubkey(), + &stake_pool_accounts.withdraw_authority, &stake_pool_accounts.validator_list.pubkey(), &stake_pool_accounts.reserve_stake.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), @@ -596,6 +600,7 @@ async fn fail_with_fee_owned_by_wrong_token_program_id() { &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), &stake_pool_accounts.staker.pubkey(), + &stake_pool_accounts.withdraw_authority, &stake_pool_accounts.validator_list.pubkey(), &stake_pool_accounts.reserve_stake.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), @@ -680,6 +685,7 @@ async fn fail_with_wrong_fee_account() { &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.manager, &stake_pool_accounts.staker.pubkey(), + &stake_pool_accounts.withdraw_authority, &None, &stake_pool_accounts.epoch_fee, &stake_pool_accounts.withdrawal_fee, @@ -718,7 +724,7 @@ async fn fail_with_wrong_withdraw_authority() { _, InstructionError::Custom(error_index), )) => { - let program_error = error::StakePoolError::WrongMintingAuthority as u32; + let program_error = error::StakePoolError::InvalidProgramAddress as u32; assert_eq!(error_index, program_error); } _ => panic!( @@ -768,6 +774,7 @@ async fn fail_with_not_rent_exempt_pool() { &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), &stake_pool_accounts.staker.pubkey(), + &stake_pool_accounts.withdraw_authority, &stake_pool_accounts.validator_list.pubkey(), &stake_pool_accounts.reserve_stake.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), @@ -845,6 +852,7 @@ async fn fail_with_not_rent_exempt_validator_list() { &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.manager.pubkey(), &stake_pool_accounts.staker.pubkey(), + &stake_pool_accounts.withdraw_authority, &stake_pool_accounts.validator_list.pubkey(), &stake_pool_accounts.reserve_stake.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), @@ -1028,6 +1036,7 @@ async fn fail_with_pre_minted_pool_tokens() { &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.manager, &stake_pool_accounts.staker.pubkey(), + &stake_pool_accounts.withdraw_authority, &None, &stake_pool_accounts.epoch_fee, &stake_pool_accounts.withdrawal_fee, @@ -1094,6 +1103,7 @@ async fn fail_with_bad_reserve() { &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.manager, &stake_pool_accounts.staker.pubkey(), + &stake_pool_accounts.withdraw_authority, &None, &stake_pool_accounts.epoch_fee, &stake_pool_accounts.withdrawal_fee, @@ -1144,6 +1154,7 @@ async fn fail_with_bad_reserve() { &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.manager, &stake_pool_accounts.staker.pubkey(), + &stake_pool_accounts.withdraw_authority, &None, &stake_pool_accounts.epoch_fee, &stake_pool_accounts.withdrawal_fee, @@ -1197,6 +1208,7 @@ async fn fail_with_bad_reserve() { &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.manager, &stake_pool_accounts.staker.pubkey(), + &stake_pool_accounts.withdraw_authority, &None, &stake_pool_accounts.epoch_fee, &stake_pool_accounts.withdrawal_fee, @@ -1250,6 +1262,7 @@ async fn fail_with_bad_reserve() { &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.manager, &stake_pool_accounts.staker.pubkey(), + &stake_pool_accounts.withdraw_authority, &None, &stake_pool_accounts.epoch_fee, &stake_pool_accounts.withdrawal_fee, @@ -1273,3 +1286,26 @@ async fn fail_with_bad_reserve() { ); } } + +#[tokio::test] +async fn success_with_extra_reserve_lamports() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new(); + let init_lamports = 1_000_000_000_000; + stake_pool_accounts + .initialize_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + 1 + init_lamports, + ) + .await + .unwrap(); + + let init_pool_tokens = get_token_balance( + &mut banks_client, + &stake_pool_accounts.pool_fee_account.pubkey(), + ) + .await; + assert_eq!(init_pool_tokens, init_lamports); +} From 1a4118a2de0ab4c4c0b88f236bfe307c91e2a9fe Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 16 Dec 2021 14:46:01 +0100 Subject: [PATCH 0210/1076] stake-pool-cli: Add next fees in verbose mode, fix mapping (#2645) --- clients/cli/src/main.rs | 12 ++++++++++++ clients/cli/src/output.rs | 19 ++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 5e7badc9..8aa67df0 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -1579,6 +1579,9 @@ fn command_set_manager( new_manager: &Option, new_fee_receiver: &Option, ) -> CommandResult { + if !config.no_update { + command_update(config, stake_pool_address, false, false)?; + } let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; // If new accounts are missing in the arguments use the old ones @@ -1626,6 +1629,9 @@ fn command_set_staker( stake_pool_address: &Pubkey, new_staker: &Pubkey, ) -> CommandResult { + if !config.no_update { + command_update(config, stake_pool_address, false, false)?; + } let mut signers = vec![config.fee_payer.as_ref(), config.manager.as_ref()]; unique_signers!(signers); let transaction = checked_transaction_with_signers( @@ -1648,6 +1654,9 @@ fn command_set_funding_authority( new_authority: Option, funding_type: FundingType, ) -> CommandResult { + if !config.no_update { + command_update(config, stake_pool_address, false, false)?; + } let mut signers = vec![config.fee_payer.as_ref(), config.manager.as_ref()]; unique_signers!(signers); let transaction = checked_transaction_with_signers( @@ -1670,6 +1679,9 @@ fn command_set_fee( stake_pool_address: &Pubkey, new_fee: FeeType, ) -> CommandResult { + if !config.no_update { + command_update(config, stake_pool_address, false, false)?; + } let mut signers = vec![config.fee_payer.as_ref(), config.manager.as_ref()]; unique_signers!(signers); let transaction = checked_transaction_with_signers( diff --git a/clients/cli/src/output.rs b/clients/cli/src/output.rs index bc198f11..81ddbd8d 100644 --- a/clients/cli/src/output.rs +++ b/clients/cli/src/output.rs @@ -119,16 +119,33 @@ impl VerboseDisplay for CliStakePool { } } writeln!(w, "Epoch Fee: {} of epoch rewards", &self.epoch_fee)?; + if let Some(next_epoch_fee) = &self.next_epoch_fee { + writeln!(w, "Next Epoch Fee: {} of epoch rewards", next_epoch_fee)?; + } writeln!( w, "Stake Withdrawal Fee: {} of withdrawal amount", &self.stake_withdrawal_fee )?; + if let Some(next_stake_withdrawal_fee) = &self.next_stake_withdrawal_fee { + writeln!( + w, + "Next Stake Withdrawal Fee: {} of withdrawal amount", + next_stake_withdrawal_fee + )?; + } writeln!( w, "SOL Withdrawal Fee: {} of withdrawal amount", &self.sol_withdrawal_fee )?; + if let Some(next_sol_withdrawal_fee) = &self.next_sol_withdrawal_fee { + writeln!( + w, + "Next SOL Withdrawal Fee: {} of withdrawal amount", + next_sol_withdrawal_fee + )?; + } writeln!( w, "Stake Deposit Fee: {} of deposit amount", @@ -462,7 +479,7 @@ impl From<(Pubkey, StakePool, ValidatorList, Pubkey)> for CliStakePool { stake_deposit_fee: CliStakePoolFee::from(stake_pool.stake_deposit_fee), stake_withdrawal_fee: CliStakePoolFee::from(stake_pool.stake_withdrawal_fee), next_stake_withdrawal_fee: stake_pool - .next_sol_withdrawal_fee + .next_stake_withdrawal_fee .map(CliStakePoolFee::from), stake_referral_fee: stake_pool.stake_referral_fee, sol_deposit_authority: stake_pool.sol_deposit_authority.map(|x| x.to_string()), From 3877e36695aee77b39f7ecaaea31f17ed6e959c8 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 21 Dec 2021 13:10:12 +0100 Subject: [PATCH 0211/1076] stake-pool: Reduce maximum pool size (#2654) * stake-pool: Reduce huge pool size in tests * stake-pool: Reduce supported maximum size --- clients/cli/scripts/setup-stake-pool.sh | 2 +- clients/py/stake_pool/actions.py | 2 +- program/tests/huge_pool.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clients/cli/scripts/setup-stake-pool.sh b/clients/cli/scripts/setup-stake-pool.sh index e9bb2baf..35205150 100755 --- a/clients/cli/scripts/setup-stake-pool.sh +++ b/clients/cli/scripts/setup-stake-pool.sh @@ -25,7 +25,7 @@ command_args+=( --deposit-fee-denominator 0 ) command_args+=( --referral-fee 0 ) # Percentage of deposit fee that goes towards the referrer (a number between 0 and 100, inclusive) -command_args+=( --max-validators 3950 ) # Maximum number of validators in the stake pool, 3950 is the current maximum possible +command_args+=( --max-validators 3825 ) # Maximum number of validators in the stake pool, 3825 is the current maximum possible # (Optional) Deposit authority, required to sign all deposits into the pool. # Setting this variable makes the pool "private" or "restricted". diff --git a/clients/py/stake_pool/actions.py b/clients/py/stake_pool/actions.py index 24d285cf..e78e0f95 100644 --- a/clients/py/stake_pool/actions.py +++ b/clients/py/stake_pool/actions.py @@ -45,7 +45,7 @@ async def create(client: AsyncClient, manager: Keypair, ) ) ) - max_validators = 3950 # current supported max by the program, go big! + max_validators = 3825 # current supported max by the program, go big! validator_list_size = ValidatorList.calculate_validator_list_size(max_validators) resp = await client.get_minimum_balance_for_rent_exemption(validator_list_size) validator_list_balance = resp['result'] diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index d85f362a..0de44add 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -30,7 +30,7 @@ use { spl_token::state::{Account as SplAccount, AccountState as SplAccountState, Mint}, }; -const HUGE_POOL_SIZE: u32 = 3_950; +const HUGE_POOL_SIZE: u32 = 3_825; const ACCOUNT_RENT_EXEMPTION: u64 = 1_000_000_000; // go with something big to be safe const STAKE_AMOUNT: u64 = 200_000_000_000; const STAKE_ACCOUNT_RENT_EXEMPTION: u64 = 2_282_880; From 5db79230ae5aa011b89f6e465d769cff61c11568 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 23 Dec 2021 19:08:06 +0100 Subject: [PATCH 0212/1076] Update tests to prepare for `BanksClientError` (#2657) * Update tests to prepare for `BanksClientError` * Remove import from record tests --- program/tests/deposit.rs | 8 +- program/tests/deposit_sol.rs | 4 +- program/tests/helpers/mod.rs | 140 ++++++++++++++++++++----- program/tests/initialize.rs | 16 ++- program/tests/set_funding_authority.rs | 8 +- program/tests/set_manager.rs | 16 ++- program/tests/set_staker.rs | 8 +- program/tests/vsa_add.rs | 20 +++- program/tests/vsa_remove.rs | 16 ++- program/tests/withdraw.rs | 8 +- 10 files changed, 191 insertions(+), 53 deletions(-) diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index b2eb5f5e..2d37bca1 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -503,12 +503,14 @@ async fn fail_with_wrong_stake_program_id() { let mut transaction = Transaction::new_with_payer(&[instruction], Some(&context.payer.pubkey())); transaction.sign(&[&context.payer], context.last_blockhash); + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = context .banks_client .process_transaction(transaction) .await .err() - .unwrap(); + .unwrap() + .into(); match transaction_error { TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { @@ -551,12 +553,14 @@ async fn fail_with_wrong_token_program_id() { Some(&context.payer.pubkey()), ); transaction.sign(&[&context.payer, &user], context.last_blockhash); + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = context .banks_client .process_transaction(transaction) .await .err() - .unwrap(); + .unwrap() + .into(); match transaction_error { TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { diff --git a/program/tests/deposit_sol.rs b/program/tests/deposit_sol.rs index ded76693..3639847a 100644 --- a/program/tests/deposit_sol.rs +++ b/program/tests/deposit_sol.rs @@ -154,12 +154,14 @@ async fn fail_with_wrong_token_program_id() { Some(&context.payer.pubkey()), ); transaction.sign(&[&context.payer], context.last_blockhash); + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = context .banks_client .process_transaction(transaction) .await .err() - .unwrap(); + .unwrap() + .into(); match transaction_error { TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index ec3fd059..b4319e89 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -79,8 +79,11 @@ pub async fn create_mint( Some(&payer.pubkey()), ); transaction.sign(&[payer, pool_mint], *recent_blockhash); - banks_client.process_transaction(transaction).await?; - Ok(()) + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 + banks_client + .process_transaction(transaction) + .await + .map_err(|e| e.into()) } pub async fn transfer( @@ -160,8 +163,11 @@ pub async fn create_token_account( Some(&payer.pubkey()), ); transaction.sign(&[payer, account], *recent_blockhash); - banks_client.process_transaction(transaction).await?; - Ok(()) + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 + banks_client + .process_transaction(transaction) + .await + .map_err(|e| e.into()) } pub async fn close_token_account( @@ -184,8 +190,11 @@ pub async fn close_token_account( Some(&payer.pubkey()), ); transaction.sign(&[payer, manager], *recent_blockhash); - banks_client.process_transaction(transaction).await?; - Ok(()) + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 + banks_client + .process_transaction(transaction) + .await + .map_err(|e| e.into()) } pub async fn freeze_token_account( @@ -208,8 +217,11 @@ pub async fn freeze_token_account( Some(&payer.pubkey()), ); transaction.sign(&[payer, manager], *recent_blockhash); - banks_client.process_transaction(transaction).await?; - Ok(()) + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 + banks_client + .process_transaction(transaction) + .await + .map_err(|e| e.into()) } pub async fn mint_tokens( @@ -235,8 +247,11 @@ pub async fn mint_tokens( &[payer, mint_authority], *recent_blockhash, ); - banks_client.process_transaction(transaction).await?; - Ok(()) + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 + banks_client + .process_transaction(transaction) + .await + .map_err(|e| e.into()) } pub async fn burn_tokens( @@ -262,8 +277,11 @@ pub async fn burn_tokens( &[payer, authority], *recent_blockhash, ); - banks_client.process_transaction(transaction).await?; - Ok(()) + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 + banks_client + .process_transaction(transaction) + .await + .map_err(|e| e.into()) } pub async fn get_token_balance(banks_client: &mut BanksClient, token: &Pubkey) -> u64 { @@ -388,8 +406,11 @@ pub async fn create_stake_pool( signers.push(stake_deposit_authority); } transaction.sign(&signers, *recent_blockhash); - banks_client.process_transaction(transaction).await?; - Ok(()) + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 + banks_client + .process_transaction(transaction) + .await + .map_err(|e| e.into()) } pub async fn create_vote( @@ -839,7 +860,12 @@ impl StakePoolAccounts { &signers, *recent_blockhash, ); - banks_client.process_transaction(transaction).await.err() + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 + banks_client + .process_transaction(transaction) + .await + .map_err(|e| e.into()) + .err() } #[allow(clippy::too_many_arguments)] @@ -890,7 +916,12 @@ impl StakePoolAccounts { &signers, *recent_blockhash, ); - banks_client.process_transaction(transaction).await.err() + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 + banks_client + .process_transaction(transaction) + .await + .map_err(|e| e.into()) + .err() } #[allow(clippy::too_many_arguments)] @@ -926,7 +957,12 @@ impl StakePoolAccounts { &[payer, user_transfer_authority], *recent_blockhash, ); - banks_client.process_transaction(transaction).await.err() + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 + banks_client + .process_transaction(transaction) + .await + .map_err(|e| e.into()) + .err() } #[allow(clippy::too_many_arguments)] @@ -978,7 +1014,12 @@ impl StakePoolAccounts { &signers, *recent_blockhash, ); - banks_client.process_transaction(transaction).await.err() + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 + banks_client + .process_transaction(transaction) + .await + .map_err(|e| e.into()) + .err() } pub async fn get_validator_list(&self, banks_client: &mut BanksClient) -> ValidatorList { @@ -1011,7 +1052,12 @@ impl StakePoolAccounts { &[payer], *recent_blockhash, ); - banks_client.process_transaction(transaction).await.err() + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 + banks_client + .process_transaction(transaction) + .await + .map_err(|e| e.into()) + .err() } pub async fn update_stake_pool_balance( @@ -1035,7 +1081,12 @@ impl StakePoolAccounts { &[payer], *recent_blockhash, ); - banks_client.process_transaction(transaction).await.err() + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 + banks_client + .process_transaction(transaction) + .await + .map_err(|e| e.into()) + .err() } pub async fn cleanup_removed_validator_entries( @@ -1054,7 +1105,12 @@ impl StakePoolAccounts { &[payer], *recent_blockhash, ); - banks_client.process_transaction(transaction).await.err() + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 + banks_client + .process_transaction(transaction) + .await + .map_err(|e| e.into()) + .err() } pub async fn update_all( @@ -1099,7 +1155,12 @@ impl StakePoolAccounts { &[payer], *recent_blockhash, ); - banks_client.process_transaction(transaction).await.err() + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 + banks_client + .process_transaction(transaction) + .await + .map_err(|e| e.into()) + .err() } pub async fn add_validator_to_pool( @@ -1125,7 +1186,12 @@ impl StakePoolAccounts { &[payer, &self.staker], *recent_blockhash, ); - banks_client.process_transaction(transaction).await.err() + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 + banks_client + .process_transaction(transaction) + .await + .map_err(|e| e.into()) + .err() } #[allow(clippy::too_many_arguments)] @@ -1164,7 +1230,12 @@ impl StakePoolAccounts { &[payer, &self.staker, destination_stake], *recent_blockhash, ); - banks_client.process_transaction(transaction).await.err() + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 + banks_client + .process_transaction(transaction) + .await + .map_err(|e| e.into()) + .err() } #[allow(clippy::too_many_arguments)] @@ -1194,7 +1265,12 @@ impl StakePoolAccounts { &[payer, &self.staker], *recent_blockhash, ); - banks_client.process_transaction(transaction).await.err() + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 + banks_client + .process_transaction(transaction) + .await + .map_err(|e| e.into()) + .err() } #[allow(clippy::too_many_arguments)] @@ -1225,7 +1301,12 @@ impl StakePoolAccounts { &[payer, &self.staker], *recent_blockhash, ); - banks_client.process_transaction(transaction).await.err() + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 + banks_client + .process_transaction(transaction) + .await + .map_err(|e| e.into()) + .err() } pub async fn set_preferred_validator( @@ -1249,7 +1330,12 @@ impl StakePoolAccounts { &[payer, &self.staker], *recent_blockhash, ); - banks_client.process_transaction(transaction).await.err() + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 + banks_client + .process_transaction(transaction) + .await + .map_err(|e| e.into()) + .err() } } diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index 2b4f6e3b..d65937bf 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -271,11 +271,13 @@ async fn fail_with_wrong_max_validators() { ], recent_blockhash, ); + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await .err() - .unwrap(); + .unwrap() + .into(); match transaction_error { TransportError::TransactionError(TransactionError::InstructionError( @@ -522,11 +524,13 @@ async fn fail_with_wrong_token_program_id() { ], recent_blockhash, ); + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await .err() - .unwrap(); + .unwrap() + .into(); match transaction_error { TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { @@ -625,11 +629,13 @@ async fn fail_with_fee_owned_by_wrong_token_program_id() { ], recent_blockhash, ); + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await .err() - .unwrap(); + .unwrap() + .into(); match transaction_error { TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { @@ -966,11 +972,13 @@ async fn fail_without_manager_signature() { ], recent_blockhash, ); + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await .err() - .unwrap(); + .unwrap() + .into(); match transaction_error { TransportError::TransactionError(TransactionError::InstructionError( diff --git a/program/tests/set_funding_authority.rs b/program/tests/set_funding_authority.rs index 4faf663e..d0394bee 100644 --- a/program/tests/set_funding_authority.rs +++ b/program/tests/set_funding_authority.rs @@ -104,11 +104,13 @@ async fn fail_wrong_manager() { Some(&payer.pubkey()), ); transaction.sign(&[&payer, &new_authority], recent_blockhash); + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await .err() - .unwrap(); + .unwrap() + .into(); match transaction_error { TransportError::TransactionError(TransactionError::InstructionError( @@ -143,11 +145,13 @@ async fn fail_without_signature() { let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); transaction.sign(&[&payer], recent_blockhash); + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await .err() - .unwrap(); + .unwrap() + .into(); match transaction_error { TransportError::TransactionError(TransactionError::InstructionError( diff --git a/program/tests/set_manager.rs b/program/tests/set_manager.rs index 4815825d..89b3b651 100644 --- a/program/tests/set_manager.rs +++ b/program/tests/set_manager.rs @@ -100,11 +100,13 @@ async fn test_set_manager_by_malicious() { Some(&payer.pubkey()), ); transaction.sign(&[&payer, &new_manager], recent_blockhash); + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await .err() - .unwrap(); + .unwrap() + .into(); match transaction_error { TransportError::TransactionError(TransactionError::InstructionError( @@ -140,11 +142,13 @@ async fn test_set_manager_without_existing_signature() { let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); transaction.sign(&[&payer, &new_manager], recent_blockhash); + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await .err() - .unwrap(); + .unwrap() + .into(); match transaction_error { TransportError::TransactionError(TransactionError::InstructionError( @@ -182,11 +186,13 @@ async fn test_set_manager_without_new_signature() { let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); transaction.sign(&[&payer, &stake_pool_accounts.manager], recent_blockhash); + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await .err() - .unwrap(); + .unwrap() + .into(); match transaction_error { TransportError::TransactionError(TransactionError::InstructionError( @@ -250,11 +256,13 @@ async fn test_set_manager_with_wrong_mint_for_pool_fee_acc() { &[&payer, &stake_pool_accounts.manager, &new_manager], recent_blockhash, ); + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await .err() - .unwrap(); + .unwrap() + .into(); match transaction_error { TransportError::TransactionError(TransactionError::InstructionError( diff --git a/program/tests/set_staker.rs b/program/tests/set_staker.rs index 61a6dede..314030be 100644 --- a/program/tests/set_staker.rs +++ b/program/tests/set_staker.rs @@ -118,11 +118,13 @@ async fn fail_wrong_manager() { Some(&payer.pubkey()), ); transaction.sign(&[&payer, &new_staker], recent_blockhash); + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await .err() - .unwrap(); + .unwrap() + .into(); match transaction_error { TransportError::TransactionError(TransactionError::InstructionError( @@ -157,11 +159,13 @@ async fn fail_set_staker_without_signature() { let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); transaction.sign(&[&payer], recent_blockhash); + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await .err() - .unwrap(); + .unwrap() + .into(); match transaction_error { TransportError::TransactionError(TransactionError::InstructionError( diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index 08cb1a36..4f108786 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -137,11 +137,13 @@ async fn fail_with_wrong_validator_list_account() { Some(&payer.pubkey()), ); transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await .err() - .unwrap(); + .unwrap() + .into(); match transaction_error { TransportError::TransactionError(TransactionError::InstructionError( @@ -216,11 +218,13 @@ async fn fail_wrong_staker() { Some(&payer.pubkey()), ); transaction.sign(&[&payer, &malicious], recent_blockhash); + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await .err() - .unwrap(); + .unwrap() + .into(); match transaction_error { TransportError::TransactionError(TransactionError::InstructionError( @@ -264,11 +268,13 @@ async fn fail_without_signature() { let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); transaction.sign(&[&payer], recent_blockhash); + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await .err() - .unwrap(); + .unwrap() + .into(); match transaction_error { TransportError::TransactionError(TransactionError::InstructionError( @@ -312,11 +318,13 @@ async fn fail_with_wrong_stake_program_id() { }; let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await .err() - .unwrap(); + .unwrap() + .into(); match transaction_error { TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { @@ -359,11 +367,13 @@ async fn fail_with_wrong_system_program_id() { }; let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await .err() - .unwrap(); + .unwrap() + .into(); match transaction_error { TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 560da5da..83e35d46 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -173,12 +173,14 @@ async fn fail_with_wrong_stake_program_id() { &[&context.payer, &stake_pool_accounts.staker], context.last_blockhash, ); + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = context .banks_client .process_transaction(transaction) .await .err() - .unwrap(); + .unwrap() + .into(); match transaction_error { TransportError::TransactionError(TransactionError::InstructionError( @@ -216,12 +218,14 @@ async fn fail_with_wrong_validator_list_account() { &[&context.payer, &stake_pool_accounts.staker], context.last_blockhash, ); + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = context .banks_client .process_transaction(transaction) .await .err() - .unwrap(); + .unwrap() + .into(); match transaction_error { TransportError::TransactionError(TransactionError::InstructionError( @@ -343,12 +347,14 @@ async fn fail_wrong_staker() { Some(&context.payer.pubkey()), ); transaction.sign(&[&context.payer, &malicious], context.last_blockhash); + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = context .banks_client .process_transaction(transaction) .await .err() - .unwrap(); + .unwrap() + .into(); match transaction_error { TransportError::TransactionError(TransactionError::InstructionError( @@ -395,12 +401,14 @@ async fn fail_no_signature() { &[&context.payer], context.last_blockhash, ); + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = context .banks_client .process_transaction(transaction) .await .err() - .unwrap(); + .unwrap() + .into(); match transaction_error { TransportError::TransactionError(TransactionError::InstructionError( diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index d7152f10..c830e37e 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -358,11 +358,13 @@ async fn fail_with_wrong_stake_program() { &[&payer, &user_transfer_authority], recent_blockhash, ); + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await .err() - .unwrap(); + .unwrap() + .into(); match transaction_error { TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { @@ -453,11 +455,13 @@ async fn fail_with_wrong_token_program_id() { &[&payer, &user_transfer_authority], recent_blockhash, ); + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await .err() - .unwrap(); + .unwrap() + .into(); match transaction_error { TransportError::TransactionError(TransactionError::InstructionError(_, error)) => { From 42d87b6db70e11b214d54b792f85276ce02257bc Mon Sep 17 00:00:00 2001 From: Alexander Ray Date: Thu, 23 Dec 2021 19:34:02 +0100 Subject: [PATCH 0213/1076] [stake-pool] js: web3 stake pool bindings (#2604) * - add stake-pool-web3-bindings (preview) * - update readme * - add tests * - remove package-lock from foreign project * - revert changes from foreign project * - review improvenments * - refactor regarding review suggestions * - fix test - fix readme * Update stake-pool/js/src/instructions.ts Co-authored-by: Jon Cinque * - add withdraw authority as optional parameter Co-authored-by: Jon Cinque --- clients/js-legacy/.gitignore | 2 + clients/js-legacy/.prettierrc | 8 + clients/js-legacy/.prettierrc.yaml | 7 - clients/js-legacy/README.md | 16 +- clients/js-legacy/babel.config.js | 7 + clients/js-legacy/package-lock.json | 6204 ++++++++++------- clients/js-legacy/package.json | 40 +- clients/js-legacy/src/constants.ts | 9 + .../src/copied-from-solana-web3/README.md | 3 + .../copied-from-solana-web3/instruction.ts | 48 + .../src/copied-from-solana-web3/layout.ts | 92 + clients/js-legacy/src/index.ts | 524 +- clients/js-legacy/src/instructions.ts | 381 + clients/js-legacy/src/integration_test.ts | 65 - clients/js-legacy/src/layouts.ts | 152 + clients/js-legacy/src/schema.ts | 139 - clients/js-legacy/src/test.ts | 215 - clients/js-legacy/src/utils/index.ts | 4 + clients/js-legacy/src/utils/math.ts | 24 + .../js-legacy/src/utils/program-address.ts | 53 + clients/js-legacy/src/utils/stake.ts | 196 + clients/js-legacy/src/utils/token.ts | 86 + clients/js-legacy/test/equal.ts | 55 + clients/js-legacy/test/instructions.test.ts | 255 + clients/js-legacy/test/integration.test.ts | 16 + clients/js-legacy/test/layouts.test.ts | 40 + clients/js-legacy/test/mocks.ts | 150 + clients/js-legacy/tsconfig.json | 35 +- 28 files changed, 5647 insertions(+), 3179 deletions(-) create mode 100644 clients/js-legacy/.prettierrc delete mode 100644 clients/js-legacy/.prettierrc.yaml create mode 100644 clients/js-legacy/babel.config.js create mode 100644 clients/js-legacy/src/constants.ts create mode 100644 clients/js-legacy/src/copied-from-solana-web3/README.md create mode 100644 clients/js-legacy/src/copied-from-solana-web3/instruction.ts create mode 100644 clients/js-legacy/src/copied-from-solana-web3/layout.ts create mode 100644 clients/js-legacy/src/instructions.ts delete mode 100644 clients/js-legacy/src/integration_test.ts create mode 100644 clients/js-legacy/src/layouts.ts delete mode 100644 clients/js-legacy/src/schema.ts delete mode 100644 clients/js-legacy/src/test.ts create mode 100644 clients/js-legacy/src/utils/index.ts create mode 100644 clients/js-legacy/src/utils/math.ts create mode 100644 clients/js-legacy/src/utils/program-address.ts create mode 100644 clients/js-legacy/src/utils/stake.ts create mode 100644 clients/js-legacy/src/utils/token.ts create mode 100644 clients/js-legacy/test/equal.ts create mode 100644 clients/js-legacy/test/instructions.test.ts create mode 100644 clients/js-legacy/test/integration.test.ts create mode 100644 clients/js-legacy/test/layouts.test.ts create mode 100644 clients/js-legacy/test/mocks.ts diff --git a/clients/js-legacy/.gitignore b/clients/js-legacy/.gitignore index 1521c8b7..9668d6fe 100644 --- a/clients/js-legacy/.gitignore +++ b/clients/js-legacy/.gitignore @@ -1 +1,3 @@ dist +.idea +node_modules diff --git a/clients/js-legacy/.prettierrc b/clients/js-legacy/.prettierrc new file mode 100644 index 00000000..25d0d320 --- /dev/null +++ b/clients/js-legacy/.prettierrc @@ -0,0 +1,8 @@ +{ + "arrowParens": "avoid", + "bracketSpacing":false, + "singleQuote": true, + "semi": false, + "tabWidth": 2, + "trailingComma": "all" +} diff --git a/clients/js-legacy/.prettierrc.yaml b/clients/js-legacy/.prettierrc.yaml deleted file mode 100644 index 8deef5dd..00000000 --- a/clients/js-legacy/.prettierrc.yaml +++ /dev/null @@ -1,7 +0,0 @@ -arrowParens: "avoid" -bracketSpacing: false -jsxBracketSameLine: false -semi: true -singleQuote: true -tabWidth: 2 -trailingComma: "all" diff --git a/clients/js-legacy/README.md b/clients/js-legacy/README.md index ae7fccbf..42cb1a78 100644 --- a/clients/js-legacy/README.md +++ b/clients/js-legacy/README.md @@ -29,19 +29,5 @@ Sample output: ``` > stake-pool-js@0.0.1 test -> ./node_modules/mocha/bin/mocha -p ./dist - - - schema.decode - StakePoolAccount - ✓ should successfully decode StakePoolAccount account data - ValidatorListAccount - ✓ should successfully decode ValidatorListAccount account data - ✓ should successfully decode ValidatorListAccount with nonempty ValidatorInfo - - index.ts/PrettyPrintPubkey - ✓ should successfully pretty print a pubkey - +``` - 4 passing (610ms) - ``` \ No newline at end of file diff --git a/clients/js-legacy/babel.config.js b/clients/js-legacy/babel.config.js new file mode 100644 index 00000000..20f7fbb6 --- /dev/null +++ b/clients/js-legacy/babel.config.js @@ -0,0 +1,7 @@ +// it's needed for jest - https://jestjs.io/docs/getting-started#using-typescript +module.exports = { + presets: [ + ['@babel/preset-env', {targets: {node: 'current'}}], + '@babel/preset-typescript', + ], +}; diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 49ac49c2..6a555caa 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1,2268 +1,1868 @@ { - "name": "stake-pool-js", - "version": "0.0.1", - "lockfileVersion": 2, + "name": "@solana/spl-stake-pool", + "version": "0.2.1", + "lockfileVersion": 1, "requires": true, - "packages": { - "": { - "name": "stake-pool-js", - "version": "0.0.1", - "license": "ISC", - "dependencies": { - "@solana/web3.js": "^1.18.0", - "assert": "^2.0.0", - "borsh": "^0.4.0", - "buffer": "^6.0.1", - "process": "^0.11.10" - }, - "devDependencies": { - "@types/mocha": "^8.2.2", - "mocha": "^8.4.0", - "prettier": "^2.2.1", - "typescript": "^4.2.4" - } - }, - "../../../solana-repos/borsh-js": { - "name": "borsh", - "version": "0.3.1", - "extraneous": true, - "license": "Apache-2.0", - "dependencies": { - "@types/bn.js": "^4.11.5", - "bn.js": "^5.0.0", - "bs58": "^4.0.0", - "text-encoding-utf-8": "^1.0.2" - }, - "devDependencies": { - "@types/babel__core": "^7.1.2", - "@types/babel__template": "^7.0.2", - "@types/node": "^12.7.3", - "@typescript-eslint/eslint-plugin": "^2.18.0", - "@typescript-eslint/parser": "^2.18.0", - "bs58": "^4.0.0", - "eslint": "^6.5.1", - "jest": "^26.0.1", - "js-sha256": "^0.9.0", - "jsfuzz": "^1.0.14", - "typescript": "^3.6.2" - } - }, - "node_modules/@babel/runtime": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz", - "integrity": "sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==", - "dependencies": { - "regenerator-runtime": "^0.13.4" - } - }, - "node_modules/@solana/web3.js": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.18.0.tgz", - "integrity": "sha512-ijAoRd4Sje1QYoPAwDr7KYlDK40FE7tAUa2V3wT4PGKatWf4ETDXoyYlW89J6vrqOT+mV3GUuaVC76tOFlrXyA==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "bn.js": "^5.0.0", - "borsh": "^0.4.0", - "bs58": "^4.0.1", - "buffer": "6.0.1", - "buffer-layout": "^1.2.0", - "crypto-hash": "^1.2.2", - "jayson": "^3.4.4", - "js-sha3": "^0.8.0", - "node-fetch": "^2.6.1", - "rpc-websockets": "^7.4.2", - "secp256k1": "^4.0.2", - "superstruct": "^0.14.2", - "tweetnacl": "^1.0.0" - } - }, - "node_modules/@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.34", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz", - "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.19.tgz", - "integrity": "sha512-DJOSHzX7pCiSElWaGR8kCprwibCB/3yW6vcT8VG3P0SJjnv19gnWG/AZMfM60Xj/YJIp/YCaDHyvzsFVeniARA==", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" - } - }, - "node_modules/@types/lodash": { - "version": "4.14.168", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.168.tgz", - "integrity": "sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q==" - }, - "node_modules/@types/mocha": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.2.tgz", - "integrity": "sha512-Lwh0lzzqT5Pqh6z61P3c3P5nm6fzQK/MMHl9UKeneAeInVflBSz1O2EkX6gM6xfJd7FBXBY5purtLx7fUiZ7Hw==", - "dev": true - }, - "node_modules/@types/node": { - "version": "15.0.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.1.tgz", - "integrity": "sha512-TMkXt0Ck1y0KKsGr9gJtWGjttxlZnnvDtphxUOSd0bfaR6Q1jle+sPvrzNR1urqYTWMinoKvjKfXUGsumaO1PA==" - }, - "node_modules/@types/qs": { - "version": "6.9.6", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.6.tgz", - "integrity": "sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==" - }, - "node_modules/@types/range-parser": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", - "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==" - }, - "node_modules/@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, - "node_modules/101": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/101/-/101-1.6.3.tgz", - "integrity": "sha512-4dmQ45yY0Dx24Qxp+zAsNLlMF6tteCyfVzgbulvSyC7tCyd3V8sW76sS0tHq8NpcbXfWTKasfyfzU1Kd86oKzw==", - "dependencies": { - "clone": "^1.0.2", - "deep-eql": "^0.1.3", - "keypather": "^1.10.2" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dependencies": { + "@babel/code-frame": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz", + "integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==", "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" + "requires": { + "@babel/highlight": "^7.16.0" } }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "@babel/compat-data": { + "version": "7.16.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.4.tgz", + "integrity": "sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q==", "dev": true }, - "node_modules/array-filter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz", - "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=" - }, - "node_modules/assert": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", - "integrity": "sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==", - "dependencies": { - "es6-object-assign": "^1.1.0", - "is-nan": "^1.2.1", - "object-is": "^1.0.1", - "util": "^0.12.0" - } - }, - "node_modules/assert-args": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/assert-args/-/assert-args-1.2.1.tgz", - "integrity": "sha1-QEEDoUUqMv53iYgR5U5ZCoqTc70=", - "dependencies": { - "101": "^1.2.0", - "compound-subject": "0.0.1", - "debug": "^2.2.0", - "get-prototype-of": "0.0.0", - "is-capitalized": "^1.0.0", - "is-class": "0.0.4" - } - }, - "node_modules/available-typed-arrays": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz", - "integrity": "sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ==", - "dependencies": { - "array-filter": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" + "@babel/core": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.0.tgz", + "integrity": "sha512-mYZEvshBRHGsIAiyH5PzCFTCfbWfoYbO/jcSdXQSUQu1/pW0xDZAUP7KEc32heqWTAfAHhV9j1vH8Sav7l+JNQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.0", + "@babel/generator": "^7.16.0", + "@babel/helper-compilation-targets": "^7.16.0", + "@babel/helper-module-transforms": "^7.16.0", + "@babel/helpers": "^7.16.0", + "@babel/parser": "^7.16.0", + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.0", + "@babel/types": "^7.16.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/base-x": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", - "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==", "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true } - ] - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "node_modules/borsh": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/borsh/-/borsh-0.4.0.tgz", - "integrity": "sha512-aX6qtLya3K0AkT66CmYWCCDr77qsE9arV05OmdFpmat9qu8Pg9J5tBUPDztAW5fNh/d/MyVG/OYziP52Ndzx1g==", - "dependencies": { - "@types/bn.js": "^4.11.5", - "bn.js": "^5.0.0", - "bs58": "^4.0.0", - "text-encoding-utf-8": "^1.0.2" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" } }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "@babel/generator": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.5.tgz", + "integrity": "sha512-kIvCdjZqcdKqoDbVVdt5R99icaRtrtYhYK/xux5qiWCBmfdvEYMFZ68QCrpE5cbFM1JsuArUNs1ZkuKtTtUcZA==", "dev": true, - "dependencies": { - "fill-range": "^7.0.1" + "requires": { + "@babel/types": "^7.16.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" }, - "engines": { - "node": ">=8" - } - }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" - }, - "node_modules/browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "node_modules/bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", "dependencies": { - "base-x": "^3.0.2" - } - }, - "node_modules/buffer": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.1.tgz", - "integrity": "sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/buffer-layout": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/buffer-layout/-/buffer-layout-1.2.1.tgz", - "integrity": "sha512-RUTGEYG1vX0Zp1dStQFl8yeU/LEBPXVtHwzzDbPWkE5zq+Prt9fkFLKNiwmaeHg6BBiRMcQAgj4cynazO6eekw==", - "engines": { - "node": ">=4.5" } }, - "node_modules/bufferutil": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.3.tgz", - "integrity": "sha512-yEYTwGndELGvfXsImMBLop58eaGW+YdONi1fNjTINSY98tmMmFijBG6WXgdkfuLNt4imzQNtIE+eBp1PVpMCSw==", - "hasInstallScript": true, - "optional": true, - "dependencies": { - "node-gyp-build": "^4.2.0" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "@babel/helper-annotate-as-pure": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.0.tgz", + "integrity": "sha512-ItmYF9vR4zA8cByDocY05o0LGUkp1zhbTQOH1NFyl5xXEqlTJQCEJjieriw+aFpxo16swMxUnUiKS7a/r4vtHg==", "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "requires": { + "@babel/types": "^7.16.0" } }, - "node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.5.tgz", + "integrity": "sha512-3JEA9G5dmmnIWdzaT9d0NmFRgYnWUThLsDaL7982H0XqqWr56lRrsmwheXFMjR+TMl7QMBb6mzy9kvgr1lRLUA==", "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "requires": { + "@babel/helper-explode-assignable-expression": "^7.16.0", + "@babel/types": "^7.16.0" } }, - "node_modules/chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "@babel/helper-compilation-targets": { + "version": "7.16.3", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.3.tgz", + "integrity": "sha512-vKsoSQAyBmxS35JUOOt+07cLc6Nk/2ljLIHwmq2/NM6hdioUaqEXq/S+nXvbvXbZkNDlWOymPanJGOc4CBjSJA==", "dev": true, - "dependencies": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.1" + "requires": { + "@babel/compat-data": "^7.16.0", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.17.5", + "semver": "^6.3.0" } }, - "node_modules/circular-json": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.9.tgz", - "integrity": "sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ==", - "deprecated": "CircularJSON is in maintenance only, flatted is its successor." - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "@babel/helper-create-class-features-plugin": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.5.tgz", + "integrity": "sha512-NEohnYA7mkB8L5JhU7BLwcBdU3j83IziR9aseMueWGeAjblbul3zzb8UvJ3a1zuBiqCMObzCJHFqKIQE6hTVmg==", "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.16.0", + "@babel/helper-environment-visitor": "^7.16.5", + "@babel/helper-function-name": "^7.16.0", + "@babel/helper-member-expression-to-functions": "^7.16.5", + "@babel/helper-optimise-call-expression": "^7.16.0", + "@babel/helper-replace-supers": "^7.16.5", + "@babel/helper-split-export-declaration": "^7.16.0" + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.0.tgz", + "integrity": "sha512-3DyG0zAFAZKcOp7aVr33ddwkxJ0Z0Jr5V99y3I690eYLpukJsJvAbzTy1ewoCqsML8SbIrjH14Jc/nSQ4TvNPA==", "dev": true, - "engines": { - "node": ">=8" + "requires": { + "@babel/helper-annotate-as-pure": "^7.16.0", + "regexpu-core": "^4.7.1" } }, - "node_modules/cliui/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "@babel/helper-define-polyfill-provider": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.0.tgz", + "integrity": "sha512-7hfT8lUljl/tM3h+izTX/pO3W3frz2ok6Pk+gzys8iJqDfZrZy2pXjRTZAvG2YmfHun1X4q8/UZRLatMfqc5Tg==", "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "requires": { + "@babel/helper-compilation-targets": "^7.13.0", + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/traverse": "^7.13.0", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + } + }, + "@babel/helper-environment-visitor": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.5.tgz", + "integrity": "sha512-ODQyc5AnxmZWm/R2W7fzhamOk1ey8gSguo5SGvF0zcB3uUzRpTRmM/jmLSm9bDMyPlvbyJ+PwPEK0BWIoZ9wjg==", "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" + "requires": { + "@babel/types": "^7.16.0" } }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "@babel/helper-explode-assignable-expression": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.0.tgz", + "integrity": "sha512-Hk2SLxC9ZbcOhLpg/yMznzJ11W++lg5GMbxt1ev6TXUiJB0N42KPC+7w8a+eWGuqDnUYuwStJoZHM7RgmIOaGQ==", "dev": true, - "dependencies": { - "ansi-regex": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", - "engines": { - "node": ">=0.8" + "requires": { + "@babel/types": "^7.16.0" } }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "@babel/helper-function-name": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.0.tgz", + "integrity": "sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog==", "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "node_modules/compound-subject": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/compound-subject/-/compound-subject-0.0.1.tgz", - "integrity": "sha1-JxVUaYoVrmCLHfyv0wt7oeqJLEs=" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "node_modules/crypto-hash": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/crypto-hash/-/crypto-hash-1.3.0.tgz", - "integrity": "sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" + "requires": { + "@babel/helper-get-function-arity": "^7.16.0", + "@babel/template": "^7.16.0", + "@babel/types": "^7.16.0" } }, - "node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "@babel/helper-get-function-arity": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.0.tgz", + "integrity": "sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ==", "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-eql": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", - "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", - "dependencies": { - "type-detect": "0.1.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dependencies": { - "object-keys": "^1.0.12" - }, - "engines": { - "node": ">= 0.4" + "requires": { + "@babel/types": "^7.16.0" } }, - "node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "@babel/helper-hoist-variables": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.0.tgz", + "integrity": "sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg==", "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/es-abstract": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz", - "integrity": "sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==", - "dependencies": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "is-callable": "^1.2.3", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.2", - "is-string": "^1.0.5", - "object-inspect": "^1.9.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es6-object-assign": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", - "integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=" - }, - "node_modules/es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "node_modules/es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "dependencies": { - "es6-promise": "^4.0.3" + "requires": { + "@babel/types": "^7.16.0" } }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "@babel/helper-member-expression-to-functions": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.5.tgz", + "integrity": "sha512-7fecSXq7ZrLE+TWshbGT+HyCLkxloWNhTbU2QM1NTI/tDqyf0oZiMcEfYtDuUDCo528EOlt39G1rftea4bRZIw==", "dev": true, - "engines": { - "node": ">=6" + "requires": { + "@babel/types": "^7.16.0" } }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "@babel/helper-module-imports": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.0.tgz", + "integrity": "sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg==", "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" - }, - "node_modules/eyes": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", - "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=", - "engines": { - "node": "> 0.1.90" + "requires": { + "@babel/types": "^7.16.0" } }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "@babel/helper-module-transforms": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.5.tgz", + "integrity": "sha512-CkvMxgV4ZyyioElFwcuWnDCcNIeyqTkCm9BxXZi73RR1ozqlpboqsbGUNvRTflgZtFbbJ1v5Emvm+lkjMYY/LQ==", "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "requires": { + "@babel/helper-environment-visitor": "^7.16.5", + "@babel/helper-module-imports": "^7.16.0", + "@babel/helper-simple-access": "^7.16.0", + "@babel/helper-split-export-declaration": "^7.16.0", + "@babel/helper-validator-identifier": "^7.15.7", + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.5", + "@babel/types": "^7.16.0" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.0.tgz", + "integrity": "sha512-SuI467Gi2V8fkofm2JPnZzB/SUuXoJA5zXe/xzyPP2M04686RzFKFHPK6HDVN6JvWBIEW8tt9hPR7fXdn2Lgpw==", "dev": true, - "bin": { - "flat": "cli.js" + "requires": { + "@babel/types": "^7.16.0" } }, - "node_modules/foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "@babel/helper-plugin-utils": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.5.tgz", + "integrity": "sha512-59KHWHXxVA9K4HNF4sbHCf+eJeFe0Te/ZFGqBT4OjXhrwvA04sGfaEGsVTdsjoszq0YTP49RC9UKe5g8uN2RwQ==", "dev": true }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "@babel/helper-remap-async-to-generator": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.5.tgz", + "integrity": "sha512-X+aAJldyxrOmN9v3FKp+Hu1NO69VWgYgDGq6YDykwRPzxs5f2N+X988CBXS7EQahDU+Vpet5QYMqLk+nsp+Qxw==", "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "requires": { + "@babel/helper-annotate-as-pure": "^7.16.0", + "@babel/helper-wrap-function": "^7.16.5", + "@babel/types": "^7.16.0" } }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "@babel/helper-replace-supers": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.5.tgz", + "integrity": "sha512-ao3seGVa/FZCMCCNDuBcqnBFSbdr8N2EW35mzojx3TwfIbdPmNK+JV6+2d5bR0Z71W5ocLnQp9en/cTF7pBJiQ==", "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "requires": { + "@babel/helper-environment-visitor": "^7.16.5", + "@babel/helper-member-expression-to-functions": "^7.16.5", + "@babel/helper-optimise-call-expression": "^7.16.0", + "@babel/traverse": "^7.16.5", + "@babel/types": "^7.16.0" } }, - "node_modules/get-prototype-of": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/get-prototype-of/-/get-prototype-of-0.0.0.tgz", - "integrity": "sha1-mHcr0QcW0W3rSzIlFsRp78oorEQ=" - }, - "node_modules/glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "@babel/helper-simple-access": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.0.tgz", + "integrity": "sha512-o1rjBT/gppAqKsYfUdfHq5Rk03lMQrkPHG1OWzHWpLgVXRH4HnMM9Et9CVdIqwkCQlobnGHEJMsgWP/jE1zUiw==", "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "requires": { + "@babel/types": "^7.16.0" } }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz", + "integrity": "sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw==", "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" + "requires": { + "@babel/types": "^7.16.0" } }, - "node_modules/growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "@babel/helper-split-export-declaration": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz", + "integrity": "sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw==", "dev": true, - "engines": { - "node": ">=4.x" + "requires": { + "@babel/types": "^7.16.0" } }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } + "@babel/helper-validator-identifier": { + "version": "7.15.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", + "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "dev": true }, - "node_modules/has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "@babel/helper-validator-option": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "dev": true }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "@babel/helper-wrap-function": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.16.5.tgz", + "integrity": "sha512-2J2pmLBqUqVdJw78U0KPNdeE2qeuIyKoG4mKV7wAq3mc4jJG282UgjZw4ZYDnqiWQuS3Y3IYdF/AQ6CpyBV3VA==", "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" + "requires": { + "@babel/helper-function-name": "^7.16.0", + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.5", + "@babel/types": "^7.16.0" } }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "@babel/helpers": { + "version": "7.16.3", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.3.tgz", + "integrity": "sha512-Xn8IhDlBPhvYTvgewPKawhADichOsbkZuzN7qz2BusOM0brChsyXMDJvldWaYMMUNiCQdQzNEioXTp3sC8Nt8w==", "dev": true, - "bin": { - "he": "bin/he" + "requires": { + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.3", + "@babel/types": "^7.16.0" } }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "@babel/highlight": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.0.tgz", + "integrity": "sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.15.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true }, - { - "type": "consulting", - "url": "https://feross.org/support" + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } } - ] - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/is-arguments": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", - "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", - "dependencies": { - "call-bind": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-bigint": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.1.tgz", - "integrity": "sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "@babel/parser": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.5.tgz", + "integrity": "sha512-+Ce7T5iPNWzfu9C1aB5tN3Lyafs5xb3Ic7vBWyZL2KXT3QSdD1dD3CvgOzPmQKoNNRt6uauc0XwNJTQtXC2/Mw==", + "dev": true }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.16.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.2.tgz", + "integrity": "sha512-h37CvpLSf8gb2lIJ2CgC3t+EjFbi0t8qS7LCS1xcJIlEXE4czlofwaW7W1HA8zpgOCzI9C1nmoqNR1zWkk0pQg==", "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" } }, - "node_modules/is-boolean-object": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz", - "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==", - "dependencies": { - "call-bind": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.0.tgz", + "integrity": "sha512-4tcFwwicpWTrpl9qjf7UsoosaArgImF85AxqCRZlgc3IQDvkUHjJpruXAL58Wmj+T6fypWTC/BakfEkwIL/pwA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", + "@babel/plugin-proposal-optional-chaining": "^7.16.0" } }, - "node_modules/is-callable": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", - "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.5.tgz", + "integrity": "sha512-C/FX+3HNLV6sz7AqbTQqEo1L9/kfrKjxcVtgyBCmvIgOjvuBVUWooDoi7trsLxOzCEo5FccjRvKHkfDsJFZlfA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-remap-async-to-generator": "^7.16.5", + "@babel/plugin-syntax-async-generators": "^7.8.4" } }, - "node_modules/is-capitalized": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-capitalized/-/is-capitalized-1.0.0.tgz", - "integrity": "sha1-TIRktNkdPk7rRIid0s2PGwrEwTY=" - }, - "node_modules/is-class": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/is-class/-/is-class-0.0.4.tgz", - "integrity": "sha1-4FdFFwW7NOOePjNZjJOpg3KWtzY=" - }, - "node_modules/is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@babel/plugin-proposal-class-properties": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.5.tgz", + "integrity": "sha512-pJD3HjgRv83s5dv1sTnDbZOaTjghKEz8KUn1Kbh2eAIRhGuyQ1XSeI4xVXU3UlIEVA3DAyIdxqT1eRn7Wcn55A==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5" } }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "@babel/plugin-proposal-class-static-block": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.16.5.tgz", + "integrity": "sha512-EEFzuLZcm/rNJ8Q5krK+FRKdVkd6FjfzT9tuSZql9sQn64K0hHA2KLJ0DqVot9/iV6+SsuadC5yI39zWnm+nmQ==", "dev": true, - "engines": { - "node": ">=0.10.0" + "requires": { + "@babel/helper-create-class-features-plugin": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/plugin-syntax-class-static-block": "^7.14.5" } }, - "node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "@babel/plugin-proposal-dynamic-import": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.5.tgz", + "integrity": "sha512-P05/SJZTTvHz79LNYTF8ff5xXge0kk5sIIWAypcWgX4BTRUgyHc8wRxJ/Hk+mU0KXldgOOslKaeqnhthcDJCJQ==", "dev": true, - "engines": { - "node": ">=4" + "requires": { + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" } }, - "node_modules/is-generator-function": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.8.tgz", - "integrity": "sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@babel/plugin-proposal-export-namespace-from": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.5.tgz", + "integrity": "sha512-i+sltzEShH1vsVydvNaTRsgvq2vZsfyrd7K7vPLUU/KgS0D5yZMe6uipM0+izminnkKrEfdUnz7CxMRb6oHZWw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" } }, - "node_modules/is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "@babel/plugin-proposal-json-strings": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.5.tgz", + "integrity": "sha512-QQJueTFa0y9E4qHANqIvMsuxM/qcLQmKttBACtPCQzGUEizsXDACGonlPiSwynHfOa3vNw0FPMVvQzbuXwh4SQ==", "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/plugin-syntax-json-strings": "^7.8.3" } }, - "node_modules/is-nan": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", - "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.5.tgz", + "integrity": "sha512-xqibl7ISO2vjuQM+MzR3rkd0zfNWltk7n9QhaD8ghMmMceVguYrNDt7MikRyj4J4v3QehpnrU8RYLnC7z/gZLA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" } }, - "node_modules/is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.5.tgz", + "integrity": "sha512-YwMsTp/oOviSBhrjwi0vzCUycseCYwoXnLiXIL3YNjHSMBHicGTz7GjVU/IGgz4DtOEXBdCNG72pvCX22ehfqg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" } }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "@babel/plugin-proposal-numeric-separator": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.5.tgz", + "integrity": "sha512-DvB9l/TcsCRvsIV9v4jxR/jVP45cslTVC0PMVHvaJhhNuhn2Y1SOhCSFlPK777qLB5wb8rVDaNoqMTyOqtY5Iw==", "dev": true, - "engines": { - "node": ">=0.12.0" + "requires": { + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" } }, - "node_modules/is-number-object": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", - "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.16.5.tgz", + "integrity": "sha512-UEd6KpChoyPhCoE840KRHOlGhEZFutdPDMGj+0I56yuTTOaT51GzmnEl/0uT41fB/vD2nT+Pci2KjezyE3HmUw==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.16.4", + "@babel/helper-compilation-targets": "^7.16.3", + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.16.5" } }, - "node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.5.tgz", + "integrity": "sha512-ihCMxY1Iljmx4bWy/PIMJGXN4NS4oUj1MKynwO07kiKms23pNvIn1DMB92DNB2R0EA882sw0VXIelYGdtF7xEQ==", "dev": true, - "engines": { - "node": ">=8" + "requires": { + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" } }, - "node_modules/is-regex": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", - "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", - "dependencies": { - "call-bind": "^1.0.2", - "has-symbols": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@babel/plugin-proposal-optional-chaining": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.5.tgz", + "integrity": "sha512-kzdHgnaXRonttiTfKYnSVafbWngPPr2qKw9BWYBESl91W54e+9R5pP70LtWxV56g0f05f/SQrwHYkfvbwcdQ/A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" } }, - "node_modules/is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@babel/plugin-proposal-private-methods": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.5.tgz", + "integrity": "sha512-+yFMO4BGT3sgzXo+lrq7orX5mAZt57DwUK6seqII6AcJnJOIhBJ8pzKH47/ql/d426uQ7YhN8DpUFirQzqYSUA==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5" } }, - "node_modules/is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dependencies": { - "has-symbols": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@babel/plugin-proposal-private-property-in-object": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.5.tgz", + "integrity": "sha512-+YGh5Wbw0NH3y/E5YMu6ci5qTDmAEVNoZ3I54aB6nVEOZ5BQ7QJlwKq5pYVucQilMByGn/bvX0af+uNaPRCabA==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.16.0", + "@babel/helper-create-class-features-plugin": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" } }, - "node_modules/is-typed-array": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.5.tgz", - "integrity": "sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug==", - "dependencies": { - "available-typed-arrays": "^1.0.2", - "call-bind": "^1.0.2", - "es-abstract": "^1.18.0-next.2", - "foreach": "^2.0.5", - "has-symbols": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.5.tgz", + "integrity": "sha512-s5sKtlKQyFSatt781HQwv1hoM5BQ9qRH30r+dK56OLDsHmV74mzwJNX7R1yMuE7VZKG5O6q/gmOGSAO6ikTudg==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.16.0", + "@babel/helper-plugin-utils": "^7.16.5" } }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "node_modules/jayson": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/jayson/-/jayson-3.6.2.tgz", - "integrity": "sha512-hbl+x2xH6FT7nckw+Pq3lKOIJaMBKOgNJEVfvloDBWB8iSfzn/1U2igj1A5rplqNMFN/OnnaTNw8qPKVmoq83Q==", - "dependencies": { - "@types/connect": "^3.4.33", - "@types/express-serve-static-core": "^4.17.9", - "@types/lodash": "^4.14.159", - "@types/node": "^12.12.54", - "commander": "^2.20.3", - "es6-promisify": "^5.0.0", - "eyes": "^0.1.8", - "json-stringify-safe": "^5.0.1", - "JSONStream": "^1.3.5", - "lodash": "^4.17.20", - "uuid": "^3.4.0" - }, - "bin": { - "jayson": "bin/jayson.js" - }, - "engines": { - "node": ">=8" + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" } }, - "node_modules/jayson/node_modules/@types/node": { - "version": "12.20.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.11.tgz", - "integrity": "sha512-gema+apZ6qLQK7k7F0dGkGCWQYsL0qqKORWOQO6tq46q+x+1C0vbOiOqOwRVlh4RAdbQwV/j/ryr3u5NOG1fPQ==" - }, - "node_modules/js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" - }, - "node_modules/js-yaml": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", - "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" } }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "node_modules/jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", - "engines": [ - "node >= 0.2.0" - ] - }, - "node_modules/JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "dependencies": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - }, - "bin": { - "JSONStream": "bin.js" - }, - "engines": { - "node": "*" + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" } }, - "node_modules/keypather": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/keypather/-/keypather-1.10.2.tgz", - "integrity": "sha1-4ESWMtSz5RbyHMAUznxWRP3c5hQ=", - "dependencies": { - "101": "^1.0.0" + "@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/log-symbols": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", - "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", "dev": true, - "dependencies": { - "chalk": "^4.0.0" - }, - "engines": { - "node": ">=10" + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" } }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, - "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" } }, - "node_modules/mocha": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz", - "integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==", + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, - "dependencies": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.1", - "debug": "4.3.1", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.1.6", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "4.0.0", - "log-symbols": "4.0.0", - "minimatch": "3.0.4", - "ms": "2.1.3", - "nanoid": "3.1.20", - "serialize-javascript": "5.0.1", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "which": "2.0.2", - "wide-align": "1.1.3", - "workerpool": "6.1.0", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha" - }, - "engines": { - "node": ">= 10.12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" } }, - "node_modules/mocha/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" } }, - "node_modules/mocha/node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/mocha/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" } }, - "node_modules/mocha/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" } }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/mocha/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" } }, - "node_modules/mocha/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" } }, - "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } }, - "node_modules/nanoid": { - "version": "3.1.20", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", - "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" } }, - "node_modules/node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + "@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } }, - "node_modules/node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", - "engines": { - "node": "4.x || >=6.0.0" + "@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" } }, - "node_modules/node-gyp-build": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", - "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==", - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" + "@babel/plugin-syntax-typescript": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.0.tgz", + "integrity": "sha512-Xv6mEXqVdaqCBfJFyeab0fH2DnUoMsDmhamxsSi4j8nLd4Vtw213WMJr55xxqipC/YVWyPY3K0blJncPYji+dQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" } }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "@babel/plugin-transform-arrow-functions": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.5.tgz", + "integrity": "sha512-8bTHiiZyMOyfZFULjsCnYOWG059FVMes0iljEHSfARhNgFfpsqE92OrCffv3veSw9rwMkYcFe9bj0ZoXU2IGtQ==", "dev": true, - "engines": { - "node": ">=0.10.0" + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" } }, - "node_modules/object-inspect": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.2.tgz", - "integrity": "sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@babel/plugin-transform-async-to-generator": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.5.tgz", + "integrity": "sha512-TMXgfioJnkXU+XRoj7P2ED7rUm5jbnDWwlCuFVTpQboMfbSya5WrmubNBAMlk7KXvywpo8rd8WuYZkis1o2H8w==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.16.0", + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-remap-async-to-generator": "^7.16.5" } }, - "node_modules/object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.5.tgz", + "integrity": "sha512-BxmIyKLjUGksJ99+hJyL/HIxLIGnLKtw772zYDER7UuycDZ+Xvzs98ZQw6NGgM2ss4/hlFAaGiZmMNKvValEjw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" } }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "engines": { - "node": ">= 0.4" + "@babel/plugin-transform-block-scoping": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.5.tgz", + "integrity": "sha512-JxjSPNZSiOtmxjX7PBRBeRJTUKTyJ607YUYeT0QJCNdsedOe+/rXITjP08eG8xUpsLfPirgzdCFN+h0w6RI+pQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" } }, - "node_modules/object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@babel/plugin-transform-classes": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.5.tgz", + "integrity": "sha512-DzJ1vYf/7TaCYy57J3SJ9rV+JEuvmlnvvyvYKFbk5u46oQbBvuB9/0w+YsVsxkOv8zVWKpDmUoj4T5ILHoXevA==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.16.0", + "@babel/helper-environment-visitor": "^7.16.5", + "@babel/helper-function-name": "^7.16.0", + "@babel/helper-optimise-call-expression": "^7.16.0", + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-replace-supers": "^7.16.5", + "@babel/helper-split-export-declaration": "^7.16.0", + "globals": "^11.1.0" + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.5.tgz", + "integrity": "sha512-n1+O7xtU5lSLraRzX88CNcpl7vtGdPakKzww74bVwpAIRgz9JVLJJpOLb0uYqcOaXVM0TL6X0RVeIJGD2CnCkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "@babel/plugin-transform-destructuring": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.5.tgz", + "integrity": "sha512-GuRVAsjq+c9YPK6NeTkRLWyQskDC099XkBSVO+6QzbnOnH2d/4mBVXYStaPrZD3dFRfg00I6BFJ9Atsjfs8mlg==", "dev": true, - "dependencies": { - "wrappy": "1" + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" } }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "@babel/plugin-transform-dotall-regex": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.5.tgz", + "integrity": "sha512-iQiEMt8Q4/5aRGHpGVK2Zc7a6mx7qEAO7qehgSug3SDImnuMzgmm/wtJALXaz25zUj1PmnNHtShjFgk4PDx4nw==", "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.16.0", + "@babel/helper-plugin-utils": "^7.16.5" } }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "@babel/plugin-transform-duplicate-keys": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.5.tgz", + "integrity": "sha512-81tijpDg2a6I1Yhj4aWY1l3O1J4Cg/Pd7LfvuaH2VVInAkXtzibz9+zSPdUM1WvuUi128ksstAP0hM5w48vQgg==", "dev": true, - "engines": { - "node": ">=8" + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.5.tgz", + "integrity": "sha512-12rba2HwemQPa7BLIKCzm1pT2/RuQHtSFHdNl41cFiC6oi4tcrp7gjB07pxQvFpcADojQywSjblQth6gJyE6CA==", "dev": true, - "engines": { - "node": ">=0.10.0" + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5" } }, - "node_modules/picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "@babel/plugin-transform-for-of": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.5.tgz", + "integrity": "sha512-+DpCAJFPAvViR17PIMi9x2AE34dll5wNlXO43wagAX2YcRGgEVHCNFC4azG85b4YyyFarvkc/iD5NPrz4Oneqw==", "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" } }, - "node_modules/prettier": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", - "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", + "@babel/plugin-transform-function-name": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.5.tgz", + "integrity": "sha512-Fuec/KPSpVLbGo6z1RPw4EE1X+z9gZk1uQmnYy7v4xr4TO9p41v1AoUuXEtyqAI7H+xNJYSICzRqZBhDEkd3kQ==", "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" + "requires": { + "@babel/helper-function-name": "^7.16.0", + "@babel/helper-plugin-utils": "^7.16.5" } }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "engines": { - "node": ">= 0.6.0" + "@babel/plugin-transform-literals": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.5.tgz", + "integrity": "sha512-B1j9C/IfvshnPcklsc93AVLTrNVa69iSqztylZH6qnmiAsDDOmmjEYqOm3Ts2lGSgTSywnBNiqC949VdD0/gfw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" } }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "@babel/plugin-transform-member-expression-literals": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.5.tgz", + "integrity": "sha512-d57i3vPHWgIde/9Y8W/xSFUndhvhZN5Wu2TjRrN1MVz5KzdUihKnfDVlfP1U7mS5DNj/WHHhaE4/tTi4hIyHwQ==", "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" } }, - "node_modules/readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "@babel/plugin-transform-modules-amd": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.5.tgz", + "integrity": "sha512-oHI15S/hdJuSCfnwIz+4lm6wu/wBn7oJ8+QrkzPPwSFGXk8kgdI/AIKcbR/XnD1nQVMg/i6eNaXpszbGuwYDRQ==", "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" + "requires": { + "@babel/helper-module-transforms": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5", + "babel-plugin-dynamic-import-node": "^2.3.3" } }, - "node_modules/regenerator-runtime": { - "version": "0.13.7", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", - "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "@babel/plugin-transform-modules-commonjs": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.5.tgz", + "integrity": "sha512-ABhUkxvoQyqhCWyb8xXtfwqNMJD7tx+irIRnUh6lmyFud7Jln1WzONXKlax1fg/ey178EXbs4bSGNd6PngO+SQ==", "dev": true, - "engines": { - "node": ">=0.10.0" + "requires": { + "@babel/helper-module-transforms": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-simple-access": "^7.16.0", + "babel-plugin-dynamic-import-node": "^2.3.3" } }, - "node_modules/rpc-websockets": { - "version": "7.4.11", - "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.4.11.tgz", - "integrity": "sha512-/6yKCkRrEEb+TlJb6Q/pNBD4WdO/tFxE22rQYBl1YyIgz3SpzQDQ/0qAMWWksjFkDayiq3xVxmkP8e/tL422ZA==", - "dependencies": { - "@babel/runtime": "^7.11.2", - "assert-args": "^1.2.1", - "circular-json": "^0.5.9", - "eventemitter3": "^4.0.7", - "uuid": "^8.3.0", - "ws": "^7.3.1" - }, - "funding": { - "type": "paypal", - "url": "https://paypal.me/kozjak" - }, - "optionalDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "@babel/plugin-transform-modules-systemjs": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.5.tgz", + "integrity": "sha512-53gmLdScNN28XpjEVIm7LbWnD/b/TpbwKbLk6KV4KqC9WyU6rq1jnNmVG6UgAdQZVVGZVoik3DqHNxk4/EvrjA==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.16.0", + "@babel/helper-module-transforms": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-validator-identifier": "^7.15.7", + "babel-plugin-dynamic-import-node": "^2.3.3" } }, - "node_modules/rpc-websockets/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" + "@babel/plugin-transform-modules-umd": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.5.tgz", + "integrity": "sha512-qTFnpxHMoenNHkS3VoWRdwrcJ3FhX567GvDA3hRZKF0Dj8Fmg0UzySZp3AP2mShl/bzcywb/UWAMQIjA1bhXvw==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/secp256k1": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", - "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", - "hasInstallScript": true, - "dependencies": { - "elliptic": "^6.5.2", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - }, - "engines": { - "node": ">=10.0.0" + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.5.tgz", + "integrity": "sha512-/wqGDgvFUeKELW6ex6QB7dLVRkd5ehjw34tpXu1nhKC0sFfmaLabIswnpf8JgDyV2NeDmZiwoOb0rAmxciNfjA==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.16.0" } }, - "node_modules/serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "@babel/plugin-transform-new-target": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.5.tgz", + "integrity": "sha512-ZaIrnXF08ZC8jnKR4/5g7YakGVL6go6V9ql6Jl3ecO8PQaQqFE74CuM384kezju7Z9nGCCA20BqZaR1tJ/WvHg==", "dev": true, - "dependencies": { - "randombytes": "^2.1.0" + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" } }, - "node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "@babel/plugin-transform-object-super": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.5.tgz", + "integrity": "sha512-tded+yZEXuxt9Jdtkc1RraW1zMF/GalVxaVVxh41IYwirdRgyAxxxCKZ9XB7LxZqmsjfjALxupNE1MIz9KH+Zg==", "dev": true, - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" + "requires": { + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-replace-supers": "^7.16.5" } }, - "node_modules/string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@babel/plugin-transform-parameters": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.5.tgz", + "integrity": "sha512-B3O6AL5oPop1jAVg8CV+haeUte9oFuY85zu0jwnRNZZi3tVAbJriu5tag/oaO2kGaQM/7q7aGPBlTI5/sr9enA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" } }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@babel/plugin-transform-property-literals": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.5.tgz", + "integrity": "sha512-+IRcVW71VdF9pEH/2R/Apab4a19LVvdVsr/gEeotH00vSDVlKD+XgfSIw+cgGWsjDB/ziqGv/pGoQZBIiQVXHg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" } }, - "node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "@babel/plugin-transform-regenerator": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.5.tgz", + "integrity": "sha512-2z+it2eVWU8TtQQRauvGUqZwLy4+7rTfo6wO4npr+fvvN1SW30ZF3O/ZRCNmTuu4F5MIP8OJhXAhRV5QMJOuYg==", "dev": true, - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" + "requires": { + "regenerator-transform": "^0.14.2" } }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "@babel/plugin-transform-reserved-words": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.5.tgz", + "integrity": "sha512-aIB16u8lNcf7drkhXJRoggOxSTUAuihTSTfAcpynowGJOZiGf+Yvi7RuTwFzVYSYPmWyARsPqUGoZWWWxLiknw==", "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" } }, - "node_modules/superstruct": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-0.14.2.tgz", - "integrity": "sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==" - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "@babel/plugin-transform-shorthand-properties": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.5.tgz", + "integrity": "sha512-ZbuWVcY+MAXJuuW7qDoCwoxDUNClfZxoo7/4swVbOW1s/qYLOMHlm9YRWMsxMFuLs44eXsv4op1vAaBaBaDMVg==", "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" } }, - "node_modules/text-encoding-utf-8": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz", - "integrity": "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==" - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "@babel/plugin-transform-spread": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.5.tgz", + "integrity": "sha512-5d6l/cnG7Lw4tGHEoga4xSkYp1euP7LAtrah1h1PgJ3JY7yNsjybsxQAnVK4JbtReZ/8z6ASVmd3QhYYKLaKZw==", "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" + "requires": { + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0" } }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + "@babel/plugin-transform-sticky-regex": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.5.tgz", + "integrity": "sha512-usYsuO1ID2LXxzuUxifgWtJemP7wL2uZtyrTVM4PKqsmJycdS4U4mGovL5xXkfUheds10Dd2PjoQLXw6zCsCbg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" + } }, - "node_modules/type-detect": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", - "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=", - "engines": { - "node": "*" + "@babel/plugin-transform-template-literals": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.5.tgz", + "integrity": "sha512-gnyKy9RyFhkovex4BjKWL3BVYzUDG6zC0gba7VMLbQoDuqMfJ1SDXs8k/XK41Mmt1Hyp4qNAvGFb9hKzdCqBRQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" } }, - "node_modules/typescript": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", - "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==", + "@babel/plugin-transform-typeof-symbol": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.5.tgz", + "integrity": "sha512-ldxCkW180qbrvyCVDzAUZqB0TAeF8W/vGJoRcaf75awm6By+PxfJKvuqVAnq8N9wz5Xa6mSpM19OfVKKVmGHSQ==", "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" } }, - "node_modules/unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "dependencies": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@babel/plugin-transform-typescript": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.1.tgz", + "integrity": "sha512-NO4XoryBng06jjw/qWEU2LhcLJr1tWkhpMam/H4eas/CDKMX/b2/Ylb6EI256Y7+FVPCawwSM1rrJNOpDiz+Lg==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.16.0", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-typescript": "^7.16.0" } }, - "node_modules/utf-8-validate": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.4.tgz", - "integrity": "sha512-MEF05cPSq3AwJ2C7B7sHAA6i53vONoZbMGX8My5auEVm6W+dJ2Jd/TZPyGJ5CH42V2XtbI5FD28HeHeqlPzZ3Q==", - "hasInstallScript": true, - "optional": true, - "dependencies": { - "node-gyp-build": "^4.2.0" + "@babel/plugin-transform-unicode-escapes": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.5.tgz", + "integrity": "sha512-shiCBHTIIChGLdyojsKQjoAyB8MBwat25lKM7MJjbe1hE0bgIppD+LX9afr41lLHOhqceqeWl4FkLp+Bgn9o1Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" } }, - "node_modules/util": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.3.tgz", - "integrity": "sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog==", - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "safe-buffer": "^5.1.2", - "which-typed-array": "^1.1.2" + "@babel/plugin-transform-unicode-regex": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.5.tgz", + "integrity": "sha512-GTJ4IW012tiPEMMubd7sD07iU9O/LOo8Q/oU4xNhcaq0Xn8+6TcUQaHtC8YxySo1T+ErQ8RaWogIEeFhKGNPzw==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.16.0", + "@babel/helper-plugin-utils": "^7.16.5" } }, - "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "bin": { - "uuid": "bin/uuid" + "@babel/preset-env": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.16.5.tgz", + "integrity": "sha512-MiJJW5pwsktG61NDxpZ4oJ1CKxM1ncam9bzRtx9g40/WkLRkxFP6mhpkYV0/DxcciqoiHicx291+eUQrXb/SfQ==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.16.4", + "@babel/helper-compilation-targets": "^7.16.3", + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-validator-option": "^7.14.5", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.16.2", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.16.0", + "@babel/plugin-proposal-async-generator-functions": "^7.16.5", + "@babel/plugin-proposal-class-properties": "^7.16.5", + "@babel/plugin-proposal-class-static-block": "^7.16.5", + "@babel/plugin-proposal-dynamic-import": "^7.16.5", + "@babel/plugin-proposal-export-namespace-from": "^7.16.5", + "@babel/plugin-proposal-json-strings": "^7.16.5", + "@babel/plugin-proposal-logical-assignment-operators": "^7.16.5", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.5", + "@babel/plugin-proposal-numeric-separator": "^7.16.5", + "@babel/plugin-proposal-object-rest-spread": "^7.16.5", + "@babel/plugin-proposal-optional-catch-binding": "^7.16.5", + "@babel/plugin-proposal-optional-chaining": "^7.16.5", + "@babel/plugin-proposal-private-methods": "^7.16.5", + "@babel/plugin-proposal-private-property-in-object": "^7.16.5", + "@babel/plugin-proposal-unicode-property-regex": "^7.16.5", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-transform-arrow-functions": "^7.16.5", + "@babel/plugin-transform-async-to-generator": "^7.16.5", + "@babel/plugin-transform-block-scoped-functions": "^7.16.5", + "@babel/plugin-transform-block-scoping": "^7.16.5", + "@babel/plugin-transform-classes": "^7.16.5", + "@babel/plugin-transform-computed-properties": "^7.16.5", + "@babel/plugin-transform-destructuring": "^7.16.5", + "@babel/plugin-transform-dotall-regex": "^7.16.5", + "@babel/plugin-transform-duplicate-keys": "^7.16.5", + "@babel/plugin-transform-exponentiation-operator": "^7.16.5", + "@babel/plugin-transform-for-of": "^7.16.5", + "@babel/plugin-transform-function-name": "^7.16.5", + "@babel/plugin-transform-literals": "^7.16.5", + "@babel/plugin-transform-member-expression-literals": "^7.16.5", + "@babel/plugin-transform-modules-amd": "^7.16.5", + "@babel/plugin-transform-modules-commonjs": "^7.16.5", + "@babel/plugin-transform-modules-systemjs": "^7.16.5", + "@babel/plugin-transform-modules-umd": "^7.16.5", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.16.5", + "@babel/plugin-transform-new-target": "^7.16.5", + "@babel/plugin-transform-object-super": "^7.16.5", + "@babel/plugin-transform-parameters": "^7.16.5", + "@babel/plugin-transform-property-literals": "^7.16.5", + "@babel/plugin-transform-regenerator": "^7.16.5", + "@babel/plugin-transform-reserved-words": "^7.16.5", + "@babel/plugin-transform-shorthand-properties": "^7.16.5", + "@babel/plugin-transform-spread": "^7.16.5", + "@babel/plugin-transform-sticky-regex": "^7.16.5", + "@babel/plugin-transform-template-literals": "^7.16.5", + "@babel/plugin-transform-typeof-symbol": "^7.16.5", + "@babel/plugin-transform-unicode-escapes": "^7.16.5", + "@babel/plugin-transform-unicode-regex": "^7.16.5", + "@babel/preset-modules": "^0.1.5", + "@babel/types": "^7.16.0", + "babel-plugin-polyfill-corejs2": "^0.3.0", + "babel-plugin-polyfill-corejs3": "^0.4.0", + "babel-plugin-polyfill-regenerator": "^0.3.0", + "core-js-compat": "^3.19.1", + "semver": "^6.3.0" + } + }, + "@babel/preset-modules": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", + "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" } }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "@babel/preset-typescript": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.16.5.tgz", + "integrity": "sha512-lmAWRoJ9iOSvs3DqOndQpj8XqXkzaiQs50VG/zESiI9D3eoZhGriU675xNCr0UwvsuXrhMAGvyk1w+EVWF3u8Q==", "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" + "requires": { + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-validator-option": "^7.14.5", + "@babel/plugin-transform-typescript": "^7.16.1" } }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@babel/runtime": { + "version": "7.15.4", + "resolved": false, + "integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==", + "requires": { + "regenerator-runtime": "^0.13.4" } }, - "node_modules/which-typed-array": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz", - "integrity": "sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==", - "dependencies": { - "available-typed-arrays": "^1.0.2", - "call-bind": "^1.0.0", - "es-abstract": "^1.18.0-next.1", - "foreach": "^2.0.5", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.1", - "is-typed-array": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@babel/template": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.0.tgz", + "integrity": "sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.0", + "@babel/parser": "^7.16.0", + "@babel/types": "^7.16.0" } }, - "node_modules/wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "@babel/traverse": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.5.tgz", + "integrity": "sha512-FOCODAzqUMROikDYLYxl4nmwiLlu85rNqBML/A5hKRVXG2LV8d0iMqgPzdYTcIpjZEBB7D6UDU9vxRZiriASdQ==", "dev": true, - "dependencies": { - "string-width": "^1.0.2 || 2" + "requires": { + "@babel/code-frame": "^7.16.0", + "@babel/generator": "^7.16.5", + "@babel/helper-environment-visitor": "^7.16.5", + "@babel/helper-function-name": "^7.16.0", + "@babel/helper-hoist-variables": "^7.16.0", + "@babel/helper-split-export-declaration": "^7.16.0", + "@babel/parser": "^7.16.5", + "@babel/types": "^7.16.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.0.tgz", + "integrity": "sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.15.7", + "to-fast-properties": "^2.0.0" } }, - "node_modules/workerpool": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", - "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "@ethersproject/bytes": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.5.0.tgz", + "integrity": "sha512-ABvc7BHWhZU9PNM/tANm/Qx4ostPGadAuQzWTr3doklZOhDlmcBqclrQe/ZXUIj3K8wC28oYeuRa+A37tX9kog==", + "requires": { + "@ethersproject/logger": "^5.5.0" } }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true, - "engines": { - "node": ">=8" - } + "@ethersproject/logger": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.5.0.tgz", + "integrity": "sha512-rIY/6WPm7T8n3qS2vuHTUBPdXHl+rGxWxW5okDfo9J4Z0+gRRZT0msvUdIJkE4/HS29GUMziwGaaKO2bWONBrg==" }, - "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" + "@ethersproject/sha2": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.5.0.tgz", + "integrity": "sha512-B5UBoglbCiHamRVPLA110J+2uqsifpZaTmid2/7W5rbtYVz6gus6/hSDieIU/6gaKIDcOj12WnOdiymEUHIAOA==", + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "hash.js": "1.1.7" } }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, "dependencies": { - "ansi-regex": "^5.0.0" - }, - "engines": { - "node": ">=8" + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + } } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true }, - "node_modules/ws": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", - "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "@jest/console": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.3.1.tgz", + "integrity": "sha512-RkFNWmv0iui+qsOr/29q9dyfKTTT5DCuP31kUwg7rmOKPT/ozLeGLKJKVIiOfbiKyleUZKIrHwhmiZWVe8IMdw==", + "dev": true, + "requires": { + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^27.3.1", + "jest-util": "^27.3.1", + "slash": "^3.0.0" + } + }, + "@jest/core": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.3.1.tgz", + "integrity": "sha512-DMNE90RR5QKx0EA+wqe3/TNEwiRpOkhshKNxtLxd4rt3IZpCt+RSL+FoJsGeblRZmqdK4upHA/mKKGPPRAifhg==", + "dev": true, + "requires": { + "@jest/console": "^27.3.1", + "@jest/reporters": "^27.3.1", + "@jest/test-result": "^27.3.1", + "@jest/transform": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^27.3.0", + "jest-config": "^27.3.1", + "jest-haste-map": "^27.3.1", + "jest-message-util": "^27.3.1", + "jest-regex-util": "^27.0.6", + "jest-resolve": "^27.3.1", + "jest-resolve-dependencies": "^27.3.1", + "jest-runner": "^27.3.1", + "jest-runtime": "^27.3.1", + "jest-snapshot": "^27.3.1", + "jest-util": "^27.3.1", + "jest-validate": "^27.3.1", + "jest-watcher": "^27.3.1", + "micromatch": "^4.0.4", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true }, - "utf-8-validate": { - "optional": true + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } } } }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "@jest/environment": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.3.1.tgz", + "integrity": "sha512-BCKCj4mOVLme6Tanoyc9k0ultp3pnmuyHw73UHRPeeZxirsU/7E3HC4le/VDb/SMzE1JcPnto+XBKFOcoiJzVw==", "dev": true, - "engines": { - "node": ">=10" + "requires": { + "@jest/fake-timers": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/node": "*", + "jest-mock": "^27.3.0" } }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "@jest/fake-timers": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.3.1.tgz", + "integrity": "sha512-M3ZFgwwlqJtWZ+QkBG5NmC23A9w+A6ZxNsO5nJxJsKYt4yguBd3i8TpjQz5NfCX91nEve1KqD9RA2Q+Q1uWqoA==", "dev": true, - "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" - }, - "engines": { - "node": ">=10" + "requires": { + "@jest/types": "^27.2.5", + "@sinonjs/fake-timers": "^8.0.1", + "@types/node": "*", + "jest-message-util": "^27.3.1", + "jest-mock": "^27.3.0", + "jest-util": "^27.3.1" } }, - "node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "@jest/globals": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.3.1.tgz", + "integrity": "sha512-Q651FWiWQAIFiN+zS51xqhdZ8g9b88nGCobC87argAxA7nMfNQq0Q0i9zTfQYgLa6qFXk2cGANEqfK051CZ8Pg==", "dev": true, - "engines": { - "node": ">=10" + "requires": { + "@jest/environment": "^27.3.1", + "@jest/types": "^27.2.5", + "expect": "^27.3.1" } }, - "node_modules/yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "@jest/reporters": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.3.1.tgz", + "integrity": "sha512-m2YxPmL9Qn1emFVgZGEiMwDntDxRRQ2D58tiDQlwYTg5GvbFOKseYCcHtn0WsI8CG4vzPglo3nqbOiT8ySBT/w==", "dev": true, - "dependencies": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "engines": { - "node": ">=10" + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^27.3.1", + "@jest/test-result": "^27.3.1", + "@jest/transform": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^27.3.1", + "jest-resolve": "^27.3.1", + "jest-util": "^27.3.1", + "jest-worker": "^27.3.1", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^8.1.0" + } + }, + "@jest/source-map": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.0.6.tgz", + "integrity": "sha512-Fek4mi5KQrqmlY07T23JRi0e7Z9bXTOOD86V/uS0EIW4PClvPDqZOyFlLpNJheS6QI0FNX1CgmPjtJ4EA/2M+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" } }, - "node_modules/yargs/node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "@jest/test-result": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.3.1.tgz", + "integrity": "sha512-mLn6Thm+w2yl0opM8J/QnPTqrfS4FoXsXF2WIWJb2O/GBSyResL71BRuMYbYRsGt7ELwS5JGcEcGb52BNrumgg==", "dev": true, - "engines": { - "node": ">=8" + "requires": { + "@jest/console": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" } }, - "node_modules/yargs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "@jest/test-sequencer": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.3.1.tgz", + "integrity": "sha512-siySLo07IMEdSjA4fqEnxfIX8lB/lWYsBPwNFtkOvsFQvmBrL3yj3k3uFNZv/JDyApTakRpxbKLJ3CT8UGVCrA==", "dev": true, - "engines": { - "node": ">=8" + "requires": { + "@jest/test-result": "^27.3.1", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.3.1", + "jest-runtime": "^27.3.1" } }, - "node_modules/yargs/node_modules/string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "@jest/transform": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.3.1.tgz", + "integrity": "sha512-3fSvQ02kuvjOI1C1ssqMVBKJpZf6nwoCiSu00zAKh5nrp3SptNtZy/8s5deayHnqxhjD9CWDJ+yqQwuQ0ZafXQ==", "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^27.2.5", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.3.1", + "jest-regex-util": "^27.0.6", + "jest-util": "^27.3.1", + "micromatch": "^4.0.4", + "pirates": "^4.0.1", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + } + }, + "@jest/types": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.2.5.tgz", + "integrity": "sha512-nmuM4VuDtCZcY+eTpw+0nvstwReMsjPoj7ZR80/BbixulhLaiX+fbv8oeLW8WZlJMcsGQsTmMKT/iTZu1Uy/lQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" } }, - "node_modules/yargs/node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.0" - }, - "engines": { - "node": ">=8" + "@project-serum/borsh": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@project-serum/borsh/-/borsh-0.2.2.tgz", + "integrity": "sha512-Ms+aWmGVW6bWd3b0+MWwoaYig2QD0F90h0uhr7AzY3dpCb5e2S6RsRW02vFTfa085pY2VLB7nTZNbFECQ1liTg==", + "requires": { + "bn.js": "^5.1.2", + "buffer-layout": "^1.2.0" + } + }, + "@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "dev": true, + "requires": { + "type-detect": "4.0.8" } }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "@sinonjs/fake-timers": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", + "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "requires": { + "@sinonjs/commons": "^1.7.0" } - } - }, - "dependencies": { - "101": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/101/-/101-1.6.3.tgz", - "integrity": "sha512-4dmQ45yY0Dx24Qxp+zAsNLlMF6tteCyfVzgbulvSyC7tCyd3V8sW76sS0tHq8NpcbXfWTKasfyfzU1Kd86oKzw==", + }, + "@solana/buffer-layout": { + "version": "3.0.0", + "resolved": false, + "integrity": "sha512-MVdgAKKL39tEs0l8je0hKaXLQFb7Rdfb0Xg2LjFZd8Lfdazkg6xiS98uAZrEKvaoF3i4M95ei9RydkGIDMeo3w==", "requires": { - "clone": "^1.0.2", - "deep-eql": "^0.1.3", - "keypather": "^1.10.2" + "buffer": "~6.0.3" } }, - "@babel/runtime": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz", - "integrity": "sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==", + "@solana/spl-token": { + "version": "0.1.8", + "resolved": false, + "integrity": "sha512-LZmYCKcPQDtJgecvWOgT/cnoIQPWjdH+QVyzPcFvyDUiT0DiRjZaam4aqNUyvchLFhzgunv3d9xOoyE34ofdoQ==", "requires": { - "regenerator-runtime": "^0.13.4" + "@babel/runtime": "^7.10.5", + "@solana/web3.js": "^1.21.0", + "bn.js": "^5.1.0", + "buffer": "6.0.3", + "buffer-layout": "^1.2.0", + "dotenv": "10.0.0" } }, "@solana/web3.js": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.18.0.tgz", - "integrity": "sha512-ijAoRd4Sje1QYoPAwDr7KYlDK40FE7tAUa2V3wT4PGKatWf4ETDXoyYlW89J6vrqOT+mV3GUuaVC76tOFlrXyA==", + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.30.2.tgz", + "integrity": "sha512-hznCj+rkfvM5taRP3Z+l5lumB7IQnDrB4l55Wpsg4kDU9Zds8pE5YOH5Z9bbF/pUzZJKQjyBjnY/6kScBm3Ugg==", "requires": { "@babel/runtime": "^7.12.5", + "@ethersproject/sha2": "^5.5.0", + "@solana/buffer-layout": "^3.0.0", "bn.js": "^5.0.0", "borsh": "^0.4.0", "bs58": "^4.0.1", "buffer": "6.0.1", - "buffer-layout": "^1.2.0", - "crypto-hash": "^1.2.2", + "cross-fetch": "^3.1.4", "jayson": "^3.4.4", "js-sha3": "^0.8.0", - "node-fetch": "^2.6.1", "rpc-websockets": "^7.4.2", "secp256k1": "^4.0.2", "superstruct": "^0.14.2", "tweetnacl": "^1.0.0" + }, + "dependencies": { + "@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "requires": { + "@types/node": "*" + } + }, + "borsh": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/borsh/-/borsh-0.4.0.tgz", + "integrity": "sha512-aX6qtLya3K0AkT66CmYWCCDr77qsE9arV05OmdFpmat9qu8Pg9J5tBUPDztAW5fNh/d/MyVG/OYziP52Ndzx1g==", + "requires": { + "@types/bn.js": "^4.11.5", + "bn.js": "^5.0.0", + "bs58": "^4.0.0", + "text-encoding-utf-8": "^1.0.2" + } + }, + "buffer": { + "version": "6.0.1", + "resolved": false, + "integrity": "sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + } + } + }, + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true + }, + "@types/babel__core": { + "version": "7.1.16", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.16.tgz", + "integrity": "sha512-EAEHtisTMM+KaKwfWdC3oyllIqswlznXCIVCt7/oRNrh+DhgT4UEBNC/jlADNjvw7UnfbcdkGQcPVZ1xYiLcrQ==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.3.tgz", + "integrity": "sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", + "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", + "dev": true, + "requires": { + "@babel/types": "^7.3.0" } }, "@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", + "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", + "dev": true, "requires": { "@types/node": "*" } }, "@types/connect": { - "version": "3.4.34", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz", - "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==", + "version": "3.4.35", + "resolved": false, + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", "requires": { "@types/node": "*" } }, "@types/express-serve-static-core": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.19.tgz", - "integrity": "sha512-DJOSHzX7pCiSElWaGR8kCprwibCB/3yW6vcT8VG3P0SJjnv19gnWG/AZMfM60Xj/YJIp/YCaDHyvzsFVeniARA==", + "version": "4.17.24", + "resolved": false, + "integrity": "sha512-3UJuW+Qxhzwjq3xhwXm2onQcFHn76frIYVbTu+kn24LFxI+dEhdfISDFovPB8VpEgW8oQCTpRuCe+0zJxB7NEA==", "requires": { "@types/node": "*", "@types/qs": "*", "@types/range-parser": "*" } }, - "@types/lodash": { - "version": "4.14.168", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.168.tgz", - "integrity": "sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q==" + "@types/graceful-fs": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", + "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "dev": true, + "requires": { + "@types/node": "*" + } }, - "@types/mocha": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.2.tgz", - "integrity": "sha512-Lwh0lzzqT5Pqh6z61P3c3P5nm6fzQK/MMHl9UKeneAeInVflBSz1O2EkX6gM6xfJd7FBXBY5purtLx7fUiZ7Hw==", + "@types/istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", "dev": true }, + "@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/jest": { + "version": "27.0.3", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.0.3.tgz", + "integrity": "sha512-cmmwv9t7gBYt7hNKH5Spu7Kuu/DotGa+Ff+JGRKZ4db5eh8PnKS4LuebJ3YLUoyOyIHraTGyULn23YtEAm0VSg==", + "dev": true, + "requires": { + "jest-diff": "^27.0.0", + "pretty-format": "^27.0.0" + } + }, + "@types/lodash": { + "version": "4.14.172", + "resolved": false, + "integrity": "sha512-/BHF5HAx3em7/KkzVKm3LrsD6HZAXuXO1AJZQ3cRRBZj4oHZDviWPYu0aEplAqDFNHZPW6d3G7KN+ONcCCC7pw==" + }, "@types/node": { - "version": "15.0.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.1.tgz", - "integrity": "sha512-TMkXt0Ck1y0KKsGr9gJtWGjttxlZnnvDtphxUOSd0bfaR6Q1jle+sPvrzNR1urqYTWMinoKvjKfXUGsumaO1PA==" + "version": "16.9.1", + "resolved": false, + "integrity": "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==" + }, + "@types/prettier": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.2.tgz", + "integrity": "sha512-ekoj4qOQYp7CvjX8ZDBgN86w3MqQhLE1hczEJbEIjgFEumDy+na/4AJAbLXfgEWFNB2pKadM5rPFtuSGMWK7xA==", + "dev": true }, "@types/qs": { - "version": "6.9.6", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.6.tgz", - "integrity": "sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==" + "version": "6.9.7", + "resolved": false, + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" }, "@types/range-parser": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", - "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==" + "version": "1.2.4", + "resolved": false, + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, - "@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "@types/ws": { + "version": "7.4.7", + "resolved": false, + "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", + "requires": { + "@types/node": "*" + } + }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "20.2.1", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", + "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", "dev": true }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "JSONStream": { + "version": "1.3.5", + "resolved": false, + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "abab": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", + "dev": true + }, + "acorn": { + "version": "8.5.0", + "resolved": false, + "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", "dev": true }, + "acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true + } + } + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } + }, + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "requires": { + "type-fest": "^0.21.3" + } + }, "ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "resolved": false, "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { @@ -2271,7 +1871,7 @@ }, "anymatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "resolved": false, "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, "requires": { @@ -2279,58 +1879,146 @@ "picomatch": "^2.0.4" } }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true }, - "array-filter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz", - "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=" + "babel-jest": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.3.1.tgz", + "integrity": "sha512-SjIF8hh/ir0peae2D6S6ZKRhUy7q/DnpH7k/V6fT4Bgs/LXXUztOpX4G2tCgq8mLo5HA9mN6NmlFMeYtKmIsTQ==", + "dev": true, + "requires": { + "@jest/transform": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^27.2.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + } + }, + "babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "dev": true, + "requires": { + "object.assign": "^4.1.0" + } }, - "assert": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", - "integrity": "sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==", + "babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, "requires": { - "es6-object-assign": "^1.1.0", - "is-nan": "^1.2.1", - "object-is": "^1.0.1", - "util": "^0.12.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "dependencies": { + "istanbul-lib-instrument": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", + "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", + "dev": true, + "requires": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + } + } } }, - "assert-args": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/assert-args/-/assert-args-1.2.1.tgz", - "integrity": "sha1-QEEDoUUqMv53iYgR5U5ZCoqTc70=", + "babel-plugin-jest-hoist": { + "version": "27.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.2.0.tgz", + "integrity": "sha512-TOux9khNKdi64mW+0OIhcmbAn75tTlzKhxmiNXevQaPbrBYK7YKjP1jl6NHTJ6XR5UgUrJbCnWlKVnJn29dfjw==", + "dev": true, "requires": { - "101": "^1.2.0", - "compound-subject": "0.0.1", - "debug": "^2.2.0", - "get-prototype-of": "0.0.0", - "is-capitalized": "^1.0.0", - "is-class": "0.0.4" + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" } }, - "available-typed-arrays": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz", - "integrity": "sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ==", + "babel-plugin-polyfill-corejs2": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.0.tgz", + "integrity": "sha512-wMDoBJ6uG4u4PNFh72Ty6t3EgfA91puCuAwKIazbQlci+ENb/UU9A3xG5lutjUIiXCIn1CY5L15r9LimiJyrSA==", + "dev": true, "requires": { - "array-filter": "^1.0.0" + "@babel/compat-data": "^7.13.11", + "@babel/helper-define-polyfill-provider": "^0.3.0", + "semver": "^6.1.1" + } + }, + "babel-plugin-polyfill-corejs3": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.4.0.tgz", + "integrity": "sha512-YxFreYwUfglYKdLUGvIF2nJEsGwj+RhWSX/ije3D2vQPOXuyMLMtg/cCGMDpOA7Nd+MwlNdnGODbd2EwUZPlsw==", + "dev": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.3.0", + "core-js-compat": "^3.18.0" + } + }, + "babel-plugin-polyfill-regenerator": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.0.tgz", + "integrity": "sha512-dhAPTDLGoMW5/84wkgwiLRwMnio2i1fUe53EuvtKMv0pn2p3S8OCoV1xAzfJPl0KOX7IB89s2ib85vbYiea3jg==", + "dev": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.3.0" + } + }, + "babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "requires": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + } + }, + "babel-preset-jest": { + "version": "27.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.2.0.tgz", + "integrity": "sha512-z7MgQ3peBwN5L5aCqBKnF6iqdlvZvFUQynEhu0J+X9nHLU72jO3iY331lcYrg+AssJ8q7xsv5/3AICzVmJ/wvg==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^27.2.0", + "babel-preset-current-node-syntax": "^1.0.0" } }, "balanced-match": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "resolved": false, "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "base-x": { "version": "3.0.8", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", + "resolved": false, "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==", "requires": { "safe-buffer": "^5.0.1" @@ -2338,34 +2026,17 @@ }, "base64-js": { "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "resolved": false, "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, "bn.js": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" }, - "borsh": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/borsh/-/borsh-0.4.0.tgz", - "integrity": "sha512-aX6qtLya3K0AkT66CmYWCCDr77qsE9arV05OmdFpmat9qu8Pg9J5tBUPDztAW5fNh/d/MyVG/OYziP52Ndzx1g==", - "requires": { - "@types/bn.js": "^4.11.5", - "bn.js": "^5.0.0", - "bs58": "^4.0.0", - "text-encoding-utf-8": "^1.0.2" - } - }, "brace-expansion": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "resolved": false, "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { @@ -2375,7 +2046,7 @@ }, "braces": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "resolved": false, "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, "requires": { @@ -2384,40 +2055,68 @@ }, "brorand": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "resolved": false, "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", "dev": true }, + "browserslist": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.18.1.tgz", + "integrity": "sha512-8ScCzdpPwR2wQh8IT82CA2VgDwjHyqMovPBZSNH54+tm4Jk2pCuv90gmAdH6J84OCRWi0b4gMe6O6XPXuJnjgQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001280", + "electron-to-chromium": "^1.3.896", + "escalade": "^3.1.1", + "node-releases": "^2.0.1", + "picocolors": "^1.0.0" + } + }, "bs58": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "resolved": false, "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", "requires": { "base-x": "^3.0.2" } }, + "bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "requires": { + "node-int64": "^0.4.0" + } + }, "buffer": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.1.tgz", - "integrity": "sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ==", + "version": "6.0.3", + "resolved": false, + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "requires": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, + "buffer-from": { + "version": "1.1.2", + "resolved": false, + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, "buffer-layout": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/buffer-layout/-/buffer-layout-1.2.1.tgz", - "integrity": "sha512-RUTGEYG1vX0Zp1dStQFl8yeU/LEBPXVtHwzzDbPWkE5zq+Prt9fkFLKNiwmaeHg6BBiRMcQAgj4cynazO6eekw==" + "version": "1.2.2", + "resolved": false, + "integrity": "sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==" }, "bufferutil": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.3.tgz", + "resolved": false, "integrity": "sha512-yEYTwGndELGvfXsImMBLop58eaGW+YdONi1fNjTINSY98tmMmFijBG6WXgdkfuLNt4imzQNtIE+eBp1PVpMCSw==", "optional": true, "requires": { @@ -2428,51 +2127,77 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, "requires": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" } }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, "camelcase": { "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "resolved": false, "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", "dev": true }, + "caniuse-lite": { + "version": "1.0.30001280", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001280.tgz", + "integrity": "sha512-kFXwYvHe5rix25uwueBxC569o53J6TpnGu0BEEn+6Lhl2vsnAumRFWEBhDft1fwyo6m1r4i+RqA4+163FpeFcA==", + "dev": true + }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": false, + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" + }, + "dependencies": { + "supports-color": { + "version": "7.2.0", + "resolved": false, + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, - "chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.3.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" - } + "char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true + }, + "ci-info": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", + "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", + "dev": true }, "circular-json": { "version": "0.5.9", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.9.tgz", + "resolved": false, "integrity": "sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ==" }, + "cjs-module-lexer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", + "dev": true + }, "cliui": { "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "resolved": false, "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { @@ -2483,19 +2208,19 @@ "dependencies": { "ansi-regex": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "resolved": false, "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "resolved": false, "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "string-width": { "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "resolved": false, "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", "dev": true, "requires": { @@ -2506,7 +2231,7 @@ }, "strip-ansi": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "resolved": false, "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { @@ -2515,14 +2240,21 @@ } } }, - "clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=" + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "dev": true }, "color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "resolved": false, "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { @@ -2531,70 +2263,222 @@ }, "color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "resolved": false, "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, "commander": { "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "resolved": false, "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, - "compound-subject": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/compound-subject/-/compound-subject-0.0.1.tgz", - "integrity": "sha1-JxVUaYoVrmCLHfyv0wt7oeqJLEs=" - }, "concat-map": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "resolved": false, "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, - "crypto-hash": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/crypto-hash/-/crypto-hash-1.3.0.tgz", - "integrity": "sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg==" + "convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "core-js-compat": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.19.3.tgz", + "integrity": "sha512-59tYzuWgEEVU9r+SRgceIGXSSUn47JknoiXW6Oq7RW8QHjXWz3/vp8pa7dbtuVu40sewz3OP3JmQEcDdztrLhA==", + "dev": true, + "requires": { + "browserslist": "^4.18.1", + "semver": "7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true + } + } }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "cross-fetch": { + "version": "3.1.4", + "resolved": false, + "integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==", "requires": { - "ms": "2.0.0" + "node-fetch": "2.6.1" } }, - "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", "dev": true }, - "deep-eql": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", - "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", + "cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "requires": { + "cssom": "~0.3.6" + }, + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + } + } + }, + "data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "dev": true, + "requires": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + } + }, + "debug": { + "version": "4.3.1", + "resolved": false, + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, "requires": { - "type-detect": "0.1.1" + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": false, + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } } }, + "decimal.js": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", + "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", + "dev": true + }, + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true + }, "define-properties": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, "requires": { "object-keys": "^1.0.12" } }, - "diff": { + "delay": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "resolved": false, + "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==" + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true + }, + "diff-sequences": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", + "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==", + "dev": true + }, + "domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "dev": true, + "requires": { + "webidl-conversions": "^5.0.0" + }, + "dependencies": { + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true + } + } + }, + "dotenv": { + "version": "10.0.0", + "resolved": false, + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" + }, + "electron-to-chromium": { + "version": "1.3.899", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.899.tgz", + "integrity": "sha512-w16Dtd2zl7VZ4N4Db+FIa7n36sgPGCKjrKvUUmp5ialsikvcQLjcJR9RWnlYNxIyEHLdHaoIZEqKsPxU9MdyBg==", "dev": true }, "elliptic": { "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "resolved": false, "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", "requires": { "bn.js": "^4.11.9", @@ -2608,63 +2492,31 @@ "dependencies": { "bn.js": { "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "resolved": false, "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" } } }, + "emittery": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", + "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", + "dev": true + }, "emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "resolved": false, "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "es-abstract": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz", - "integrity": "sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==", - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "is-callable": "^1.2.3", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.2", - "is-string": "^1.0.5", - "object-inspect": "^1.9.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.0" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-object-assign": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", - "integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=" - }, "es6-promise": { "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "resolved": false, "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" }, "es6-promisify": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "resolved": false, "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", "requires": { "es6-promise": "^4.0.3" @@ -2672,55 +2524,146 @@ }, "escalade": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "resolved": false, "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "escodegen": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "dev": true, + "requires": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, "eventemitter3": { "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "resolved": false, "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" }, + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expect": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.3.1.tgz", + "integrity": "sha512-MrNXV2sL9iDRebWPGOGFdPQRl2eDQNu/uhxIMShjjx74T6kC6jFIkmQ6OqXDtevjGUkyB2IT56RzDBqXf/QPCg==", + "dev": true, + "requires": { + "@jest/types": "^27.2.5", + "ansi-styles": "^5.0.0", + "jest-get-type": "^27.3.1", + "jest-matcher-utils": "^27.3.1", + "jest-message-util": "^27.3.1", + "jest-regex-util": "^27.0.6" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + } + } + }, "eyes": { "version": "0.1.8", - "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "resolved": false, "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=" }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "dev": true, + "requires": { + "bser": "2.1.1" + } + }, "fill-range": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "resolved": false, "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, "requires": { "to-regex-range": "^5.0.1" } }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true - }, - "foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" + "form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } }, "fs.realpath": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "resolved": false, "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, "fsevents": { "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "resolved": false, "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, "optional": true @@ -2728,11 +2671,18 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true }, "get-caller-file": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "resolved": false, "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, @@ -2740,20 +2690,28 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.1" } }, - "get-prototype-of": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/get-prototype-of/-/get-prototype-of-0.0.0.tgz", - "integrity": "sha1-mHcr0QcW0W3rSzIlFsRp78oorEQ=" + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true }, "glob": { "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "resolved": false, "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "dev": true, "requires": { @@ -2765,486 +2723,1080 @@ "path-is-absolute": "^1.0.0" } }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "graceful-fs": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", "dev": true }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "requires": { "function-bind": "^1.1.1" } }, - "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" - }, "has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "resolved": false, "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "has-symbols": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true }, "hash.js": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "resolved": false, "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", "requires": { "inherits": "^2.0.3", "minimalistic-assert": "^1.0.1" } }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "hmac-drbg": { + "version": "1.0.1", + "resolved": false, + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "dev": true, + "requires": { + "whatwg-encoding": "^1.0.5" + } + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + } + }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": false, + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "import-local": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.3.tgz", + "integrity": "sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + } + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": false, + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": false, + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "is-core-module": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", + "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": false, + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": false, + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isomorphic-ws": { + "version": "4.0.1", + "resolved": false, + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==" + }, + "istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", "dev": true }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + } + }, + "istanbul-reports": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.5.tgz", + "integrity": "sha512-5+19PlhnGabNWB7kOFnuxT8H3T/iIyQzIbQMxXsURmmvKg86P2sbkrGOT77VnHw0Qr0gc2XzRaRfMZYYbSQCJQ==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jayson": { + "version": "3.6.4", + "resolved": false, + "integrity": "sha512-GH63DsRFFlodS8krFgAhxwYvQFmSwjsFxKnPrHQtp+BJj/tpeSj3hyBGGqmTkuq043U1Gn6u8VdsVRFZX1EEiQ==", + "requires": { + "@types/connect": "^3.4.33", + "@types/express-serve-static-core": "^4.17.9", + "@types/lodash": "^4.14.159", + "@types/node": "^12.12.54", + "@types/ws": "^7.4.4", + "JSONStream": "^1.3.5", + "commander": "^2.20.3", + "delay": "^5.0.0", + "es6-promisify": "^5.0.0", + "eyes": "^0.1.8", + "isomorphic-ws": "^4.0.1", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.20", + "uuid": "^3.4.0", + "ws": "^7.4.5" + }, + "dependencies": { + "@types/node": { + "version": "12.20.24", + "resolved": false, + "integrity": "sha512-yxDeaQIAJlMav7fH5AQqPH1u8YIuhYJXYBzxaQ4PifsU0GDO38MSdmEDeRlIxrKbC6NbEaaEHDanWb+y30U8SQ==" + } + } + }, + "jest": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.3.1.tgz", + "integrity": "sha512-U2AX0AgQGd5EzMsiZpYt8HyZ+nSVIh5ujQ9CPp9EQZJMjXIiSZpJNweZl0swatKRoqHWgGKM3zaSwm4Zaz87ng==", + "dev": true, "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" + "@jest/core": "^27.3.1", + "import-local": "^3.0.2", + "jest-cli": "^27.3.1" } }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "jest-changed-files": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.3.0.tgz", + "integrity": "sha512-9DJs9garMHv4RhylUMZgbdCJ3+jHSkpL9aaVKp13xtXAD80qLTLrqcDZL1PHA9dYA0bCI86Nv2BhkLpLhrBcPg==", "dev": true, "requires": { - "once": "^1.3.0", - "wrappy": "1" + "@jest/types": "^27.2.5", + "execa": "^5.0.0", + "throat": "^6.0.1" } }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-arguments": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", - "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", + "jest-circus": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.3.1.tgz", + "integrity": "sha512-v1dsM9II6gvXokgqq6Yh2jHCpfg7ZqV4jWY66u7npz24JnhP3NHxI0sKT7+ZMQ7IrOWHYAaeEllOySbDbWsiXw==", + "dev": true, + "requires": { + "@jest/environment": "^27.3.1", + "@jest/test-result": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "expect": "^27.3.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.3.1", + "jest-matcher-utils": "^27.3.1", + "jest-message-util": "^27.3.1", + "jest-runtime": "^27.3.1", + "jest-snapshot": "^27.3.1", + "jest-util": "^27.3.1", + "pretty-format": "^27.3.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3", + "throat": "^6.0.1" + } + }, + "jest-cli": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.3.1.tgz", + "integrity": "sha512-WHnCqpfK+6EvT62me6WVs8NhtbjAS4/6vZJnk7/2+oOr50cwAzG4Wxt6RXX0hu6m1169ZGMlhYYUNeKBXCph/Q==", + "dev": true, + "requires": { + "@jest/core": "^27.3.1", + "@jest/test-result": "^27.3.1", + "@jest/types": "^27.2.5", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "jest-config": "^27.3.1", + "jest-util": "^27.3.1", + "jest-validate": "^27.3.1", + "prompts": "^2.0.1", + "yargs": "^16.2.0" + } + }, + "jest-config": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.3.1.tgz", + "integrity": "sha512-KY8xOIbIACZ/vdYCKSopL44I0xboxC751IX+DXL2+Wx6DKNycyEfV3rryC3BPm5Uq/BBqDoMrKuqLEUNJmMKKg==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^27.3.1", + "@jest/types": "^27.2.5", + "babel-jest": "^27.3.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-circus": "^27.3.1", + "jest-environment-jsdom": "^27.3.1", + "jest-environment-node": "^27.3.1", + "jest-get-type": "^27.3.1", + "jest-jasmine2": "^27.3.1", + "jest-regex-util": "^27.0.6", + "jest-resolve": "^27.3.1", + "jest-runner": "^27.3.1", + "jest-util": "^27.3.1", + "jest-validate": "^27.3.1", + "micromatch": "^4.0.4", + "pretty-format": "^27.3.1" + } + }, + "jest-diff": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.3.1.tgz", + "integrity": "sha512-PCeuAH4AWUo2O5+ksW4pL9v5xJAcIKPUPfIhZBcG1RKv/0+dvaWTQK1Nrau8d67dp65fOqbeMdoil+6PedyEPQ==", + "dev": true, "requires": { - "call-bind": "^1.0.0" + "chalk": "^4.0.0", + "diff-sequences": "^27.0.6", + "jest-get-type": "^27.3.1", + "pretty-format": "^27.3.1" } }, - "is-bigint": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.1.tgz", - "integrity": "sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg==" - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "jest-docblock": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.0.6.tgz", + "integrity": "sha512-Fid6dPcjwepTFraz0YxIMCi7dejjJ/KL9FBjPYhBp4Sv1Y9PdhImlKZqYU555BlN4TQKaTc+F2Av1z+anVyGkA==", "dev": true, "requires": { - "binary-extensions": "^2.0.0" + "detect-newline": "^3.0.0" } }, - "is-boolean-object": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz", - "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==", + "jest-each": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.3.1.tgz", + "integrity": "sha512-E4SwfzKJWYcvOYCjOxhZcxwL+AY0uFMvdCOwvzgutJiaiodFjkxQQDxHm8FQBeTqDnSmKsQWn7ldMRzTn2zJaQ==", + "dev": true, "requires": { - "call-bind": "^1.0.0" + "@jest/types": "^27.2.5", + "chalk": "^4.0.0", + "jest-get-type": "^27.3.1", + "jest-util": "^27.3.1", + "pretty-format": "^27.3.1" } }, - "is-callable": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", - "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==" - }, - "is-capitalized": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-capitalized/-/is-capitalized-1.0.0.tgz", - "integrity": "sha1-TIRktNkdPk7rRIid0s2PGwrEwTY=" - }, - "is-class": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/is-class/-/is-class-0.0.4.tgz", - "integrity": "sha1-4FdFFwW7NOOePjNZjJOpg3KWtzY=" - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" + "jest-environment-jsdom": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.3.1.tgz", + "integrity": "sha512-3MOy8qMzIkQlfb3W1TfrD7uZHj+xx8Olix5vMENkj5djPmRqndMaXtpnaZkxmxM+Qc3lo+yVzJjzuXbCcZjAlg==", + "dev": true, + "requires": { + "@jest/environment": "^27.3.1", + "@jest/fake-timers": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/node": "*", + "jest-mock": "^27.3.0", + "jest-util": "^27.3.1", + "jsdom": "^16.6.0" + } }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true + "jest-environment-node": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.3.1.tgz", + "integrity": "sha512-T89F/FgkE8waqrTSA7/ydMkcc52uYPgZZ6q8OaZgyiZkJb5QNNCF6oPZjH9IfPFfcc9uBWh1574N0kY0pSvTXw==", + "dev": true, + "requires": { + "@jest/environment": "^27.3.1", + "@jest/fake-timers": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/node": "*", + "jest-mock": "^27.3.0", + "jest-util": "^27.3.1" + } }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "jest-get-type": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.3.1.tgz", + "integrity": "sha512-+Ilqi8hgHSAdhlQ3s12CAVNd8H96ZkQBfYoXmArzZnOfAtVAJEiPDBirjByEblvG/4LPJmkL+nBqPO3A1YJAEg==", "dev": true }, - "is-generator-function": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.8.tgz", - "integrity": "sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ==" - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "jest-haste-map": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.3.1.tgz", + "integrity": "sha512-lYfNZIzwPccDJZIyk9Iz5iQMM/MH56NIIcGj7AFU1YyA4ewWFBl8z+YPJuSCRML/ee2cCt2y3W4K3VXPT6Nhzg==", + "dev": true, + "requires": { + "@jest/types": "^27.2.5", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.4", + "jest-regex-util": "^27.0.6", + "jest-serializer": "^27.0.6", + "jest-util": "^27.3.1", + "jest-worker": "^27.3.1", + "micromatch": "^4.0.4", + "walker": "^1.0.7" + } + }, + "jest-jasmine2": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.3.1.tgz", + "integrity": "sha512-WK11ZUetDQaC09w4/j7o4FZDUIp+4iYWH/Lik34Pv7ukL+DuXFGdnmmi7dT58J2ZYKFB5r13GyE0z3NPeyJmsg==", + "dev": true, + "requires": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^27.3.1", + "@jest/source-map": "^27.0.6", + "@jest/test-result": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^27.3.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.3.1", + "jest-matcher-utils": "^27.3.1", + "jest-message-util": "^27.3.1", + "jest-runtime": "^27.3.1", + "jest-snapshot": "^27.3.1", + "jest-util": "^27.3.1", + "pretty-format": "^27.3.1", + "throat": "^6.0.1" + } + }, + "jest-leak-detector": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.3.1.tgz", + "integrity": "sha512-78QstU9tXbaHzwlRlKmTpjP9k4Pvre5l0r8Spo4SbFFVy/4Abg9I6ZjHwjg2QyKEAMg020XcjP+UgLZIY50yEg==", "dev": true, "requires": { - "is-extglob": "^2.1.1" + "jest-get-type": "^27.3.1", + "pretty-format": "^27.3.1" } }, - "is-nan": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", - "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "jest-matcher-utils": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.3.1.tgz", + "integrity": "sha512-hX8N7zXS4k+8bC1Aj0OWpGb7D3gIXxYvPNK1inP5xvE4ztbz3rc4AkI6jGVaerepBnfWB17FL5lWFJT3s7qo8w==", + "dev": true, "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" + "chalk": "^4.0.0", + "jest-diff": "^27.3.1", + "jest-get-type": "^27.3.1", + "pretty-format": "^27.3.1" } }, - "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==" + "jest-message-util": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.3.1.tgz", + "integrity": "sha512-bh3JEmxsTZ/9rTm0jQrPElbY2+y48Rw2t47uMfByNyUVR+OfPh4anuyKsGqsNkXk/TI4JbLRZx+7p7Hdt6q1yg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.2.5", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.4", + "pretty-format": "^27.3.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + } + }, + "jest-mock": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.3.0.tgz", + "integrity": "sha512-ziZiLk0elZOQjD08bLkegBzv5hCABu/c8Ytx45nJKkysQwGaonvmTxwjLqEA4qGdasq9o2I8/HtdGMNnVsMTGw==", + "dev": true, + "requires": { + "@jest/types": "^27.2.5", + "@types/node": "*" + } }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "jest-pnp-resolver": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", "dev": true }, - "is-number-object": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", - "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==" - }, - "is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "jest-regex-util": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.6.tgz", + "integrity": "sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ==", "dev": true }, - "is-regex": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", - "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", + "jest-resolve": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.3.1.tgz", + "integrity": "sha512-Dfzt25CFSPo3Y3GCbxynRBZzxq9AdyNN+x/v2IqYx6KVT5Z6me2Z/PsSGFSv3cOSUZqJ9pHxilao/I/m9FouLw==", + "dev": true, "requires": { - "call-bind": "^1.0.2", - "has-symbols": "^1.0.1" + "@jest/types": "^27.2.5", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.3.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^27.3.1", + "jest-validate": "^27.3.1", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", + "slash": "^3.0.0" + } + }, + "jest-resolve-dependencies": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.3.1.tgz", + "integrity": "sha512-X7iLzY8pCiYOnvYo2YrK3P9oSE8/3N2f4pUZMJ8IUcZnT81vlSonya1KTO9ZfKGuC+svE6FHK/XOb8SsoRUV1A==", + "dev": true, + "requires": { + "@jest/types": "^27.2.5", + "jest-regex-util": "^27.0.6", + "jest-snapshot": "^27.3.1" } }, - "is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "jest-runner": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.3.1.tgz", + "integrity": "sha512-r4W6kBn6sPr3TBwQNmqE94mPlYVn7fLBseeJfo4E2uCTmAyDFm2O5DYAQAFP7Q3YfiA/bMwg8TVsciP7k0xOww==", + "dev": true, "requires": { - "has-symbols": "^1.0.1" + "@jest/console": "^27.3.1", + "@jest/environment": "^27.3.1", + "@jest/test-result": "^27.3.1", + "@jest/transform": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-docblock": "^27.0.6", + "jest-environment-jsdom": "^27.3.1", + "jest-environment-node": "^27.3.1", + "jest-haste-map": "^27.3.1", + "jest-leak-detector": "^27.3.1", + "jest-message-util": "^27.3.1", + "jest-resolve": "^27.3.1", + "jest-runtime": "^27.3.1", + "jest-util": "^27.3.1", + "jest-worker": "^27.3.1", + "source-map-support": "^0.5.6", + "throat": "^6.0.1" + } + }, + "jest-runtime": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.3.1.tgz", + "integrity": "sha512-qtO6VxPbS8umqhEDpjA4pqTkKQ1Hy4ZSi9mDVeE9Za7LKBo2LdW2jmT+Iod3XFaJqINikZQsn2wEi0j9wPRbLg==", + "dev": true, + "requires": { + "@jest/console": "^27.3.1", + "@jest/environment": "^27.3.1", + "@jest/globals": "^27.3.1", + "@jest/source-map": "^27.0.6", + "@jest/test-result": "^27.3.1", + "@jest/transform": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.3.1", + "jest-message-util": "^27.3.1", + "jest-mock": "^27.3.0", + "jest-regex-util": "^27.0.6", + "jest-resolve": "^27.3.1", + "jest-snapshot": "^27.3.1", + "jest-util": "^27.3.1", + "jest-validate": "^27.3.1", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^16.2.0" + }, + "dependencies": { + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + } } }, - "is-typed-array": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.5.tgz", - "integrity": "sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug==", + "jest-serializer": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.0.6.tgz", + "integrity": "sha512-PtGdVK9EGC7dsaziskfqaAPib6wTViY3G8E5wz9tLVPhHyiDNTZn/xjZ4khAw+09QkoOVpn7vF5nPSN6dtBexA==", + "dev": true, "requires": { - "available-typed-arrays": "^1.0.2", - "call-bind": "^1.0.2", - "es-abstract": "^1.18.0-next.2", - "foreach": "^2.0.5", - "has-symbols": "^1.0.1" + "@types/node": "*", + "graceful-fs": "^4.2.4" } }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "jayson": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/jayson/-/jayson-3.6.2.tgz", - "integrity": "sha512-hbl+x2xH6FT7nckw+Pq3lKOIJaMBKOgNJEVfvloDBWB8iSfzn/1U2igj1A5rplqNMFN/OnnaTNw8qPKVmoq83Q==", + "jest-snapshot": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.3.1.tgz", + "integrity": "sha512-APZyBvSgQgOT0XumwfFu7X3G5elj6TGhCBLbBdn3R1IzYustPGPE38F51dBWMQ8hRXa9je0vAdeVDtqHLvB6lg==", + "dev": true, "requires": { - "@types/connect": "^3.4.33", - "@types/express-serve-static-core": "^4.17.9", - "@types/lodash": "^4.14.159", - "@types/node": "^12.12.54", - "commander": "^2.20.3", - "es6-promisify": "^5.0.0", - "eyes": "^0.1.8", - "json-stringify-safe": "^5.0.1", - "JSONStream": "^1.3.5", - "lodash": "^4.17.20", - "uuid": "^3.4.0" + "@babel/core": "^7.7.2", + "@babel/generator": "^7.7.2", + "@babel/parser": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.0.0", + "@jest/transform": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^27.3.1", + "graceful-fs": "^4.2.4", + "jest-diff": "^27.3.1", + "jest-get-type": "^27.3.1", + "jest-haste-map": "^27.3.1", + "jest-matcher-utils": "^27.3.1", + "jest-message-util": "^27.3.1", + "jest-resolve": "^27.3.1", + "jest-util": "^27.3.1", + "natural-compare": "^1.4.0", + "pretty-format": "^27.3.1", + "semver": "^7.3.2" }, "dependencies": { - "@types/node": { - "version": "12.20.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.11.tgz", - "integrity": "sha512-gema+apZ6qLQK7k7F0dGkGCWQYsL0qqKORWOQO6tq46q+x+1C0vbOiOqOwRVlh4RAdbQwV/j/ryr3u5NOG1fPQ==" + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } } } }, + "jest-util": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.3.1.tgz", + "integrity": "sha512-8fg+ifEH3GDryLQf/eKZck1DEs2YuVPBCMOaHQxVVLmQwl/CDhWzrvChTX4efLZxGrw+AA0mSXv78cyytBt/uw==", + "dev": true, + "requires": { + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.4", + "picomatch": "^2.2.3" + } + }, + "jest-validate": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.3.1.tgz", + "integrity": "sha512-3H0XCHDFLA9uDII67Bwi1Vy7AqwA5HqEEjyy934lgVhtJ3eisw6ShOF1MDmRPspyikef5MyExvIm0/TuLzZ86Q==", + "dev": true, + "requires": { + "@jest/types": "^27.2.5", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^27.3.1", + "leven": "^3.1.0", + "pretty-format": "^27.3.1" + } + }, + "jest-watcher": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.3.1.tgz", + "integrity": "sha512-9/xbV6chABsGHWh9yPaAGYVVKurWoP3ZMCv6h+O1v9/+pkOroigs6WzZ0e9gLP/njokUwM7yQhr01LKJVMkaZA==", + "dev": true, + "requires": { + "@jest/test-result": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^27.3.1", + "string-length": "^4.0.1" + } + }, + "jest-worker": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.3.1.tgz", + "integrity": "sha512-ks3WCzsiZaOPJl/oMsDjaf0TRiSv7ctNgs0FqRr2nARsovz6AWWy4oLElwcquGSz692DzgZQrCLScPNs5YlC4g==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + } + }, "js-sha3": { "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "resolved": false, "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" }, - "js-yaml": { + "js-tokens": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", - "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "jsdom": { + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", "dev": true, "requires": { - "argparse": "^2.0.1" - } + "abab": "^2.0.5", + "acorn": "^8.2.4", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.5.0", + "ws": "^7.4.6", + "xml-name-validator": "^3.0.0" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true }, "json-stringify-safe": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "resolved": false, "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, "jsonparse": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "resolved": false, "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=" }, - "JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "requires": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - } + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true }, - "keypather": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/keypather/-/keypather-1.10.2.tgz", - "integrity": "sha1-4ESWMtSz5RbyHMAUznxWRP3c5hQ=", + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, "requires": { - "101": "^1.0.0" + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" } }, "lodash": { "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "resolved": false, "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, - "log-symbols": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", - "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "requires": { - "chalk": "^4.0.0" + "yallist": "^4.0.0" + } + }, + "makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "requires": { + "tmpl": "1.0.5" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, + "mime-db": { + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", + "dev": true + }, + "mime-types": { + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "dev": true, + "requires": { + "mime-db": "1.51.0" } }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, "minimalistic-assert": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "resolved": false, "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" }, "minimalistic-crypto-utils": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "resolved": false, "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" }, "minimatch": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "resolved": false, "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { "brace-expansion": "^1.1.7" } }, - "mocha": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz", - "integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==", - "dev": true, - "requires": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.1", - "debug": "4.3.1", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.1.6", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "4.0.0", - "log-symbols": "4.0.0", - "minimatch": "3.0.4", - "ms": "2.1.3", - "nanoid": "3.1.20", - "serialize-javascript": "5.0.1", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "which": "2.0.2", - "wide-align": "1.1.3", - "workerpool": "6.1.0", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "minimist": { + "version": "1.2.5", + "resolved": false, + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true }, - "nanoid": { - "version": "3.1.20", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", - "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, "node-addon-api": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "resolved": false, "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" }, "node-fetch": { "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "resolved": false, "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" }, "node-gyp-build": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", - "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==" + "version": "4.3.0", + "resolved": false, + "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==" + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "dev": true + }, + "node-releases": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", + "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==", + "dev": true }, "normalize-path": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "resolved": false, "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, - "object-inspect": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.2.tgz", - "integrity": "sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA==" - }, - "object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "path-key": "^3.0.0" } }, + "nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", + "dev": true + }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true }, "object.assign": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, "requires": { "call-bind": "^1.0.0", "define-properties": "^1.1.3", @@ -3254,110 +3806,320 @@ }, "once": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "resolved": false, "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "requires": { "wrappy": "1" } }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dev": true, "requires": { - "yocto-queue": "^0.1.0" + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" } }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, "path-exists": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "resolved": false, "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "path-is-absolute": { + "version": "1.0.1", + "resolved": false, + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", "dev": true }, "picomatch": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "resolved": false, "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", "dev": true }, + "pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "dev": true, + "requires": { + "node-modules-regexp": "^1.0.0" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, "prettier": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", - "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", + "version": "2.4.0", + "resolved": false, + "integrity": "sha512-DsEPLY1dE5HF3BxCRBmD4uYZ+5DCbvatnolqTqcxEgKVZnL2kUfyu7b8pPQ5+hTBkdhU9SLUmK0/pHb07RE4WQ==", "dev": true }, + "pretty-format": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.1.tgz", + "integrity": "sha512-DR/c+pvFc52nLimLROYjnXPtolawm+uWDxr4FjuLDLUn+ktWnSN851KoHwHzzqq6rfCOjkzN8FLgDrSub6UDuA==", + "dev": true, + "requires": { + "@jest/types": "^27.2.5", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + } + } + }, "process": { "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "resolved": false, "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "dev": true, "requires": { - "safe-buffer": "^5.1.0" + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" } }, - "readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz", + "integrity": "sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA==", "dev": true, "requires": { - "picomatch": "^2.2.1" + "regenerate": "^1.4.2" } }, "regenerator-runtime": { - "version": "0.13.7", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", - "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" + "version": "0.13.9", + "resolved": false, + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + }, + "regenerator-transform": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", + "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.8.4" + } + }, + "regexpu-core": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.8.0.tgz", + "integrity": "sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg==", + "dev": true, + "requires": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^9.0.0", + "regjsgen": "^0.5.2", + "regjsparser": "^0.7.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.0.0" + } + }, + "regjsgen": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", + "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", + "dev": true + }, + "regjsparser": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.7.0.tgz", + "integrity": "sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } + } }, "require-directory": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "resolved": false, "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "resolve.exports": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", + "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, "rpc-websockets": { - "version": "7.4.11", - "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.4.11.tgz", - "integrity": "sha512-/6yKCkRrEEb+TlJb6Q/pNBD4WdO/tFxE22rQYBl1YyIgz3SpzQDQ/0qAMWWksjFkDayiq3xVxmkP8e/tL422ZA==", + "version": "7.4.14", + "resolved": false, + "integrity": "sha512-x/2Rwzla6bXAyE8A21yx3sHjn49JUlgBUYfnKurNeqrZQgFxfD43Udo5NkTWQp+TASrssTlks8ipcJfvswgv5g==", "requires": { "@babel/runtime": "^7.11.2", - "assert-args": "^1.2.1", "bufferutil": "^4.0.1", "circular-json": "^0.5.9", "eventemitter3": "^4.0.7", "utf-8-validate": "^5.0.2", "uuid": "^8.3.0", - "ws": "^7.3.1" + "ws": "^7.4.5" }, "dependencies": { "uuid": { "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "resolved": false, "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" } } }, "safe-buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "resolved": false, "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "dev": true, + "requires": { + "xmlchars": "^2.2.0" + } + }, "secp256k1": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", + "resolved": false, "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", "requires": { "elliptic": "^6.5.2", @@ -3365,198 +4127,415 @@ "node-gyp-build": "^4.2.0" } }, - "serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { - "randombytes": "^2.1.0" + "shebang-regex": "^3.0.0" } }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "signal-exit": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", + "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", + "dev": true + }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": false, + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.20", + "resolved": false, + "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", "dev": true, "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, - "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true }, - "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "stack-utils": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", + "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", + "dev": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "escape-string-regexp": "^2.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + } } }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } } }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true }, "superstruct": { "version": "0.14.2", - "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-0.14.2.tgz", + "resolved": false, "integrity": "sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==" }, "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "version": "8.1.1", + "resolved": false, + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "requires": { "has-flag": "^4.0.0" } }, + "supports-hyperlinks": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", + "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "dev": true, + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "dependencies": { + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, + "terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, "text-encoding-utf-8": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz", + "resolved": false, "integrity": "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==" }, + "throat": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", + "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", + "dev": true + }, "through": { "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "resolved": false, "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, + "tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, "to-regex-range": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "resolved": false, "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "requires": { "is-number": "^7.0.0" } }, + "tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "dev": true, + "requires": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + } + }, + "tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "dev": true, + "requires": { + "punycode": "^2.1.1" + } + }, "tweetnacl": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "resolved": false, "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, "type-detect": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", - "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=" + "version": "4.0.8", + "resolved": false, + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true }, - "typescript": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", - "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==", + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true }, - "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" + "is-typedarray": "^1.0.0" } }, - "utf-8-validate": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.4.tgz", - "integrity": "sha512-MEF05cPSq3AwJ2C7B7sHAA6i53vONoZbMGX8My5auEVm6W+dJ2Jd/TZPyGJ5CH42V2XtbI5FD28HeHeqlPzZ3Q==", - "optional": true, + "unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "dev": true + }, + "unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, "requires": { - "node-gyp-build": "^4.2.0" + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" } }, - "util": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.3.tgz", - "integrity": "sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog==", + "unicode-match-property-value-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", + "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==", + "dev": true + }, + "unicode-property-aliases-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz", + "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==", + "dev": true + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "utf-8-validate": { + "version": "5.0.5", + "resolved": false, + "integrity": "sha512-+pnxRYsS/axEpkrrEpzYfNZGXp0IjC/9RIxwM5gntY4Koi8SHmUGSfxfWqxZdRxrtaoVstuOzUp/rbs3JSPELQ==", + "optional": true, "requires": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "safe-buffer": "^5.1.2", - "which-typed-array": "^1.1.2" + "node-gyp-build": "^4.2.0" } }, "uuid": { "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "resolved": false, "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "v8-to-istanbul": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz", + "integrity": "sha512-/PRhfd8aTNp9Ggr62HPzXg2XasNFGy5PBt0Rp04du7/8GNNSgxFL6WBTkgMKSL9bFjH+8kKEG3f37FmxiTqUUA==", "dev": true, "requires": { - "isexe": "^2.0.0" + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } } }, - "which-boxed-primitive": { + "w3c-hr-time": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "dev": true, "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" + "browser-process-hrtime": "^1.0.0" } }, - "which-typed-array": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz", - "integrity": "sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==", + "w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "dev": true, "requires": { - "available-typed-arrays": "^1.0.2", - "call-bind": "^1.0.0", - "es-abstract": "^1.18.0-next.1", - "foreach": "^2.0.5", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.1", - "is-typed-array": "^1.1.3" + "xml-name-validator": "^3.0.0" } }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "dev": true, "requires": { - "string-width": "^1.0.2 || 2" + "makeerror": "1.0.12" } }, - "workerpool": { + "webidl-conversions": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", - "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "dev": true + }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "requires": { + "iconv-lite": "0.4.24" + } + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "dev": true, + "requires": { + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": false, + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true }, "wrap-ansi": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "resolved": false, "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { @@ -3567,19 +4546,19 @@ "dependencies": { "ansi-regex": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "resolved": false, "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "resolved": false, "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "string-width": { "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "resolved": false, "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", "dev": true, "requires": { @@ -3590,7 +4569,7 @@ }, "strip-ansi": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "resolved": false, "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { @@ -3601,25 +4580,54 @@ }, "wrappy": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "resolved": false, "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, "ws": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", - "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==", - "requires": {} + "version": "7.5.5", + "resolved": false, + "integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==" + }, + "xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true }, "y18n": { "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "resolved": false, "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "yargs": { "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "resolved": false, "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "requires": { @@ -3634,19 +4642,19 @@ "dependencies": { "ansi-regex": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "resolved": false, "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "resolved": false, "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "string-width": { "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "resolved": false, "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", "dev": true, "requires": { @@ -3657,7 +4665,7 @@ }, "strip-ansi": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "resolved": false, "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { @@ -3668,27 +4676,9 @@ }, "yargs-parser": { "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "resolved": false, "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", "dev": true - }, - "yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "requires": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - } - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true } } } diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 227e0e5f..fae546ca 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -1,27 +1,37 @@ { "name": "@solana/spl-stake-pool", - "version": "0.1.0", + "version": "0.2.1", "description": "SPL Stake Pool Program JS API", "scripts": { "lint": "npx prettier src/*.ts -w", - "build": "tsc", - "test": "./node_modules/mocha/bin/mocha -p ./dist" + "test": "jest", + "test:watch": "jest --watch", + "test:cov": "jest --coverage" }, "keywords": [], - "author": "Lieu Zheng Hong", + "authors": [ + "Lieu Zheng Hong", + "mFactory Team (https://mfactory.ch)" + ], "license": "ISC", - "devDependencies": { - "@types/mocha": "^8.2.2", - "mocha": "^8.4.0", - "prettier": "^2.2.1", - "typescript": "^4.2.4" - }, "dependencies": { - "@solana/web3.js": "^1.18.0", - "assert": "^2.0.0", - "borsh": "^0.4.0", - "buffer": "^6.0.1", + "@project-serum/borsh": "^0.2.2", + "@solana/spl-token": "^0.1.8", + "@solana/web3.js": "^1.30.2", + "bn.js": "^5.2.0", + "buffer": "^6.0.3", "process": "^0.11.10" }, - "type": "module" + "devDependencies": { + "@babel/preset-env": "^7.16.5", + "@babel/preset-typescript": "^7.16.5", + "@types/bn.js": "^5.1.0", + "@types/jest": "^27.0.3", + "jest": "^27.3.1", + "prettier": "^2.2.1" + }, + "jest": { + "testRegex": ".*\\.test\\.ts$", + "testEnvironment": "node" + } } diff --git a/clients/js-legacy/src/constants.ts b/clients/js-legacy/src/constants.ts new file mode 100644 index 00000000..1451d876 --- /dev/null +++ b/clients/js-legacy/src/constants.ts @@ -0,0 +1,9 @@ +import { Buffer } from "buffer"; +import { PublicKey } from "@solana/web3.js"; +import { solToLamports } from "./utils"; + +export const TRANSIENT_STAKE_SEED_PREFIX = Buffer.from('transient'); + +export const STAKE_POOL_PROGRAM_ID = new PublicKey('SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy'); + +export const MIN_STAKE_BALANCE = solToLamports(0.001); diff --git a/clients/js-legacy/src/copied-from-solana-web3/README.md b/clients/js-legacy/src/copied-from-solana-web3/README.md new file mode 100644 index 00000000..a1388ae6 --- /dev/null +++ b/clients/js-legacy/src/copied-from-solana-web3/README.md @@ -0,0 +1,3 @@ +that files are copied from https://github.com/solana-labs/solana-web3.js + +I think it would be a good idea to export that functionality diff --git a/clients/js-legacy/src/copied-from-solana-web3/instruction.ts b/clients/js-legacy/src/copied-from-solana-web3/instruction.ts new file mode 100644 index 00000000..1985ff7c --- /dev/null +++ b/clients/js-legacy/src/copied-from-solana-web3/instruction.ts @@ -0,0 +1,48 @@ +import { Buffer } from 'buffer'; +import * as BufferLayout from '@solana/buffer-layout'; + +import * as Layout from './layout'; + +/** + * @internal + */ +export type InstructionType = { + /** The Instruction index (from solana upstream program) */ + index: number; + /** The BufferLayout to use to build data */ + layout: BufferLayout.Layout; +}; + +/** + * Populate a buffer of instruction data using an InstructionType + * @internal + */ +export function encodeData(type: InstructionType, fields?: any): Buffer { + const allocLength = type.layout.span >= 0 ? type.layout.span : Layout.getAlloc(type, fields); + const data = Buffer.alloc(allocLength); + const layoutFields = Object.assign({ instruction: type.index }, fields); + type.layout.encode(layoutFields, data); + + return data; +} + +/** + * Decode instruction data buffer using an InstructionType + * @internal + */ +export function decodeData(type: InstructionType, buffer: Buffer): any { + let data; + try { + data = type.layout.decode(buffer); + } catch (err) { + throw new Error('invalid instruction; ' + err); + } + + if (data.instruction !== type.index) { + throw new Error( + `invalid instruction; instruction index mismatch ${data.instruction} != ${type.index}`, + ); + } + + return data; +} diff --git a/clients/js-legacy/src/copied-from-solana-web3/layout.ts b/clients/js-legacy/src/copied-from-solana-web3/layout.ts new file mode 100644 index 00000000..a96c7984 --- /dev/null +++ b/clients/js-legacy/src/copied-from-solana-web3/layout.ts @@ -0,0 +1,92 @@ +import {Buffer} from 'buffer'; +import * as BufferLayout from '@solana/buffer-layout'; + +/** + * Layout for a public key + */ +export const publicKey = ( + property: string = 'publicKey', +): BufferLayout.Layout => { + return BufferLayout.blob(32, property); +}; + +/** + * Layout for a 64bit unsigned value + */ +export const uint64 = (property: string = 'uint64'): BufferLayout.Layout => { + return BufferLayout.blob(8, property); +}; + +/** + * Layout for a Rust String type + */ +export const rustString = (property: string = 'string') => { + const rsl = BufferLayout.struct( + [ + BufferLayout.u32('length'), + BufferLayout.u32('lengthPadding'), + BufferLayout.blob(BufferLayout.offset(BufferLayout.u32(), -8), 'chars'), + ], + property, + ); + const _decode = rsl.decode.bind(rsl); + const _encode = rsl.encode.bind(rsl); + + rsl.decode = (buffer: any, offset: any) => { + const data = _decode(buffer, offset); + return data['chars'].toString('utf8'); + }; + + rsl.encode = (str: any, buffer: any, offset: any) => { + const data = { + chars: Buffer.from(str, 'utf8'), + }; + return _encode(data, buffer, offset); + }; + + (rsl as any).alloc = (str: any) => { + return ( + BufferLayout.u32().span + + BufferLayout.u32().span + + Buffer.from(str, 'utf8').length + ); + }; + + return rsl; +}; + +/** + * Layout for an Authorized object + */ +export const authorized = (property: string = 'authorized') => { + return BufferLayout.struct( + [publicKey('staker'), publicKey('withdrawer')], + property, + ); +}; + +/** + * Layout for a Lockup object + */ +export const lockup = (property: string = 'lockup') => { + return BufferLayout.struct( + [ + BufferLayout.ns64('unixTimestamp'), + BufferLayout.ns64('epoch'), + publicKey('custodian'), + ], + property, + ); +}; + +export function getAlloc(type: any, fields: any): number { + let alloc = 0; + type.layout.fields.forEach((item: any) => { + if (item.span >= 0) { + alloc += item.span; + } else if (typeof item.alloc === 'function') { + alloc += item.alloc(fields[item.property]); + } + }); + return alloc; +} diff --git a/clients/js-legacy/src/index.ts b/clients/js-legacy/src/index.ts index 1a03605e..86ecfaa7 100644 --- a/clients/js-legacy/src/index.ts +++ b/clients/js-legacy/src/index.ts @@ -1,24 +1,59 @@ -import * as schema from './schema.js'; -import solanaWeb3 from '@solana/web3.js'; -import assert from 'assert'; - -export class StakePoolAccounts { - /** - * Wrapper class for a stake pool. - * Each stake pool has a stake pool account and a validator list account. - */ - stakePool: StakePoolAccount; - validatorList: ValidatorListAccount; +import { + AccountInfo, + Connection, + Keypair, + PublicKey, + Signer, StakeProgram, + SystemProgram, + TransactionInstruction, +} from '@solana/web3.js'; +import { + ASSOCIATED_TOKEN_PROGRAM_ID, + TOKEN_PROGRAM_ID, + Token, +} from '@solana/spl-token'; +import { + addAssociatedTokenAccount, + calcLamportsWithdrawAmount, + findStakeProgramAddress, + findWithdrawAuthorityProgramAddress, + getTokenAccount, + newStakeAccount, + prepareWithdrawAccounts, + lamportsToSol, + solToLamports, +} from './utils'; +import { StakePoolInstruction } from './instructions'; +import { StakePoolLayout, ValidatorListLayout, ValidatorList, StakePool } from './layouts'; +import { MIN_STAKE_BALANCE, STAKE_POOL_PROGRAM_ID } from "./constants"; + +export type { StakePool, AccountType, ValidatorList, ValidatorStakeInfo } from './layouts'; +export { STAKE_POOL_PROGRAM_ID } from './constants'; +export * from './instructions'; + +export interface ValidatorListAccount { + pubkey: PublicKey; + account: AccountInfo; } export interface StakePoolAccount { - pubkey: solanaWeb3.PublicKey; - account: solanaWeb3.AccountInfo; + pubkey: PublicKey; + account: AccountInfo; } -export interface ValidatorListAccount { - pubkey: solanaWeb3.PublicKey; - account: solanaWeb3.AccountInfo; +export interface WithdrawAccount { + stakeAddress: PublicKey; + voteAddress?: PublicKey; + poolAmount: number; +} + +/** + * Wrapper class for a stake pool. + * Each stake pool has a stake pool account and a validator list account. + */ +export interface StakePoolAccounts { + stakePool: StakePoolAccount | undefined; + validatorList: ValidatorListAccount | undefined; } /** @@ -27,15 +62,19 @@ export interface ValidatorListAccount { * @param stakePoolPubKey: The public key (address) of the stake pool account. */ export async function getStakePoolAccount( - connection: solanaWeb3.Connection, - stakePoolPubKey: solanaWeb3.PublicKey, + connection: Connection, + stakePoolPubKey: PublicKey, ): Promise { const account = await connection.getAccountInfo(stakePoolPubKey); + if (!account) { + throw new Error('Invalid account'); + } + return { pubkey: stakePoolPubKey, account: { - data: schema.StakePool.decode(account.data), + data: StakePoolLayout.decode(account.data), executable: account.executable, lamports: account.lamports, owner: account.owner, @@ -44,113 +83,392 @@ export async function getStakePoolAccount( } /** - * Retrieves and deserializes a ValidatorList account using a web3js connection and the validator list address. + * Retrieves all StakePool and ValidatorList accounts that are running a particular StakePool program. * @param connection: An active web3js connection. - * @param validatorListPubKey: The public key (address) of the validator list account. + * @param stakePoolProgramAddress: The public key (address) of the StakePool program. */ -export async function getValidatorListAccount( - connection: solanaWeb3.Connection, - validatorListPubKey: solanaWeb3.PublicKey, -): Promise { - try { - const account = await connection.getAccountInfo(validatorListPubKey); +export async function getStakePoolAccounts( + connection: Connection, + stakePoolProgramAddress: PublicKey, +): Promise<(StakePoolAccount | ValidatorListAccount)[] | undefined> { + const response = await connection.getProgramAccounts(stakePoolProgramAddress); + + return response.map(a => { + let decodedData; + + if (a.account.data.readUInt8() === 1) { + try { + decodedData = StakePoolLayout.decode(a.account.data); + } catch (error) { + console.log('Could not decode StakeAccount. Error:', error); + decodedData = undefined; + } + } else if (a.account.data.readUInt8() === 2) { + try { + decodedData = ValidatorListLayout.decode(a.account.data); + } catch (error) { + console.log('Could not decode ValidatorList. Error:', error); + decodedData = undefined; + } + } else { + console.error( + `Could not decode. StakePoolAccount Enum is ${a.account.data.readUInt8()}, expected 1 or 2!`, + ); + decodedData = undefined; + } return { - pubkey: validatorListPubKey, + pubkey: a.pubkey, account: { - data: schema.ValidatorList.decodeUnchecked(account.data), - executable: account.executable, - lamports: account.lamports, - owner: account.owner, + data: decodedData, + executable: a.account.executable, + lamports: a.account.lamports, + owner: a.account.owner, }, }; - } catch (error) { - console.log(error); - } + }); } /** - * Retrieves all StakePool and ValidatorList accounts that are running a particular StakePool program. - * @param connection: An active web3js connection. - * @param stakePoolProgramAddress: The public key (address) of the StakePool program. + * Creates instructions required to deposit sol to stake pool. */ -export async function getStakePoolAccounts( - connection: solanaWeb3.Connection, - stakePoolProgramAddress: solanaWeb3.PublicKey, -): Promise<(StakePoolAccount | ValidatorListAccount)[]> { - try { - let response = await connection.getProgramAccounts(stakePoolProgramAddress); - - const stakePoolAccounts = response.map(a => { - let decodedData; - - if (a.account.data.readUInt8() === 1) { - try { - decodedData = schema.StakePool.decode(a.account.data); - } catch (error) { - console.log('Could not decode StakeAccount. Error:', error); - decodedData = undefined; - } - } else if (a.account.data.readUInt8() === 2) { - try { - decodedData = schema.ValidatorList.decodeUnchecked(a.account.data); - } catch (error) { - console.log('Could not decode ValidatorList. Error:', error); - decodedData = undefined; - } - } else { - console.error( - `Could not decode. StakePoolAccount Enum is ${a.account.data.readUInt8()}, expected 1 or 2!`, - ); - decodedData = undefined; - } +export async function depositSol( + connection: Connection, + stakePoolAddress: PublicKey, + from: PublicKey, + lamports: number, + destinationTokenAccount?: PublicKey, + referrerTokenAccount?: PublicKey, + depositAuthority?: PublicKey +) { + const fromBalance = await connection.getBalance(from, 'confirmed'); + if (fromBalance < lamports) { + throw new Error( + `Not enough SOL to deposit into pool. Maximum deposit amount is ${lamportsToSol( + fromBalance, + )} SOL.`, + ); + } - return { - pubkey: a.pubkey, - account: { - data: decodedData, - executable: a.account.executable, - lamports: a.account.lamports, - owner: a.account.owner, - }, - }; - }); + const stakePoolAccount = await getStakePoolAccount(connection, stakePoolAddress); + const stakePool = stakePoolAccount.account.data; + + // Ephemeral SOL account just to do the transfer + const userSolTransfer = new Keypair(); + const signers: Signer[] = [userSolTransfer]; + const instructions: TransactionInstruction[] = []; - return stakePoolAccounts; - } catch (error) { - console.log(error); + // Create the ephemeral SOL account + instructions.push( + SystemProgram.transfer({ + fromPubkey: from, + toPubkey: userSolTransfer.publicKey, + lamports, + }), + ); + + // Create token account if not specified + if (!destinationTokenAccount) { + destinationTokenAccount = await addAssociatedTokenAccount( + connection, + from, + stakePool.poolMint, + instructions, + ); } + + const withdrawAuthority = await findWithdrawAuthorityProgramAddress( + STAKE_POOL_PROGRAM_ID, + stakePoolAddress, + ); + + instructions.push( + StakePoolInstruction.depositSol({ + stakePool: stakePoolAddress, + reserveStake: stakePool.reserveStake, + fundingAccount: userSolTransfer.publicKey, + destinationPoolAccount: destinationTokenAccount, + managerFeeAccount: stakePool.managerFeeAccount, + referralPoolAccount: referrerTokenAccount ?? destinationTokenAccount, + poolMint: stakePool.poolMint, + lamports: lamports, + withdrawAuthority: withdrawAuthority, + depositAuthority: depositAuthority, + }), + ); + + return { + instructions, + signers, + }; } /** - * Helper function to pretty print a schema.PublicKey - * Pretty prints a PublicKey in base58 format */ -export function prettyPrintPubKey(pubKey: solanaWeb3.PublicKey): string { - return new solanaWeb3.PublicKey( - new solanaWeb3.PublicKey(pubKey.toBuffer()).toBytes().reverse(), - ).toString(); + * Creates instructions required to withdraw stake from a stake pool. + */ +export async function withdrawStake( + connection: Connection, + stakePoolAddress: PublicKey, + tokenOwner: PublicKey, + amount: number, + useReserve = false, + voteAccountAddress?: PublicKey, + stakeReceiver?: PublicKey, + poolTokenAccount?: PublicKey, +) { + const stakePool = await getStakePoolAccount(connection, stakePoolAddress); + const poolAmount = solToLamports(amount); + + if (!poolTokenAccount) { + poolTokenAccount = await Token.getAssociatedTokenAddress( + ASSOCIATED_TOKEN_PROGRAM_ID, + TOKEN_PROGRAM_ID, + stakePool.account.data.poolMint, + tokenOwner, + ); + } + + const tokenAccount = await getTokenAccount( + connection, + poolTokenAccount, + stakePool.account.data.poolMint, + ); + if (!tokenAccount) { + throw new Error('Invalid token account'); + } + + // Check withdrawFrom balance + if (tokenAccount.amount.toNumber() < poolAmount) { + throw new Error( + `Not enough token balance to withdraw ${lamportsToSol(poolAmount)} pool tokens. + Maximum withdraw amount is ${lamportsToSol(tokenAccount.amount.toNumber())} pool tokens.`, + ); + } + + const withdrawAuthority = await findWithdrawAuthorityProgramAddress( + STAKE_POOL_PROGRAM_ID, + stakePoolAddress, + ); + + const withdrawAccounts: WithdrawAccount[] = []; + + if (useReserve) { + withdrawAccounts.push({ + stakeAddress: stakePool.account.data.reserveStake, + voteAddress: undefined, + poolAmount, + }); + } else if (voteAccountAddress) { + const stakeAccountAddress = await findStakeProgramAddress( + STAKE_POOL_PROGRAM_ID, + voteAccountAddress, + stakePoolAddress, + ); + const stakeAccount = await connection.getAccountInfo(stakeAccountAddress); + if (!stakeAccount) { + throw new Error('Invalid Stake Account'); + } + + const availableForWithdrawal = calcLamportsWithdrawAmount( + stakePool.account.data, + stakeAccount.lamports - MIN_STAKE_BALANCE, + ); + + if (availableForWithdrawal < poolAmount) { + // noinspection ExceptionCaughtLocallyJS + throw new Error( + `Not enough lamports available for withdrawal from ${stakeAccountAddress}, + ${poolAmount} asked, ${availableForWithdrawal} available.`, + ); + } + withdrawAccounts.push({ + stakeAddress: stakeAccountAddress, + voteAddress: voteAccountAddress, + poolAmount, + }); + } else { + // Get the list of accounts to withdraw from + withdrawAccounts.push( + ...(await prepareWithdrawAccounts( + connection, + stakePool.account.data, + stakePoolAddress, + poolAmount, + )), + ); + } + + // Construct transaction to withdraw from withdrawAccounts account list + const instructions: TransactionInstruction[] = []; + const userTransferAuthority = Keypair.generate(); + + const signers: Signer[] = [userTransferAuthority]; + + instructions.push( + Token.createApproveInstruction( + TOKEN_PROGRAM_ID, + poolTokenAccount, + userTransferAuthority.publicKey, + tokenOwner, + [], + poolAmount, + ), + ); + + let totalRentFreeBalances = 0; + + // Max 5 accounts to prevent an error: "Transaction too large" + const maxWithdrawAccounts = 5; + let i = 0; + + // Go through prepared accounts and withdraw/claim them + for (const withdrawAccount of withdrawAccounts) { + if (i > maxWithdrawAccounts) { + break; + } + // Convert pool tokens amount to lamports + const solWithdrawAmount = Math.ceil( + calcLamportsWithdrawAmount(stakePool.account.data, withdrawAccount.poolAmount), + ); + + let infoMsg = `Withdrawing â—Ž${solWithdrawAmount}, + from stake account ${withdrawAccount.stakeAddress?.toBase58()}`; + + if (withdrawAccount.voteAddress) { + infoMsg = `${infoMsg}, delegated to ${withdrawAccount.voteAddress?.toBase58()}`; + } + + console.info(infoMsg); + + let stakeToReceive; + + // Use separate mutable variable because withdraw might create a new account + if (!stakeReceiver) { + const stakeReceiverAccountBalance = await connection.getMinimumBalanceForRentExemption( + StakeProgram.space, + ); + const stakeKeypair = newStakeAccount(tokenOwner, instructions, stakeReceiverAccountBalance); + signers.push(stakeKeypair); + totalRentFreeBalances += stakeReceiverAccountBalance; + stakeToReceive = stakeKeypair.publicKey; + } else { + stakeToReceive = stakeReceiver; + } + + instructions.push( + StakePoolInstruction.withdrawStake({ + stakePool: stakePoolAddress, + validatorList: stakePool.account.data.validatorList, + validatorStake: withdrawAccount.stakeAddress, + destinationStake: stakeToReceive, + destinationStakeAuthority: tokenOwner, + sourceTransferAuthority: userTransferAuthority.publicKey, + sourcePoolAccount: poolTokenAccount, + managerFeeAccount: stakePool.account.data.managerFeeAccount, + poolMint: stakePool.account.data.poolMint, + poolTokens: withdrawAccount.poolAmount, + withdrawAuthority, + }) + ); + i++; + } + + return { + instructions, + signers, + stakeReceiver, + totalRentFreeBalances, + }; } /** - * Helper function to pretty print a decoded account + * Creates instructions required to withdraw SOL directly from a stake pool. */ -export function prettyPrintAccount( - account: ValidatorListAccount | StakePoolAccount, -): void { - console.log('Address:', account.pubkey.toString()); - const sp = account.account.data; - if (typeof sp === 'undefined') { - console.log('Account could not be decoded'); +export async function withdrawSol( + connection: Connection, + stakePoolAddress: PublicKey, + tokenOwner: PublicKey, + solReceiver: PublicKey, + amount: number, + solWithdrawAuthority?: PublicKey, +) { + const stakePool = await getStakePoolAccount(connection, stakePoolAddress); + const poolAmount = solToLamports(amount); + + const poolTokenAccount = await Token.getAssociatedTokenAddress( + ASSOCIATED_TOKEN_PROGRAM_ID, + TOKEN_PROGRAM_ID, + stakePool.account.data.poolMint, + tokenOwner, + ); + + const tokenAccount = await getTokenAccount( + connection, + poolTokenAccount, + stakePool.account.data.poolMint, + ); + if (!tokenAccount) { + throw new Error('Invalid token account'); } - for (const val in sp) { - if (sp[val] instanceof solanaWeb3.PublicKey) { - console.log(val, prettyPrintPubKey(sp[val])); - } else { - console.log(val, sp[val]); + // Check withdrawFrom balance + if (tokenAccount.amount.toNumber() < poolAmount) { + throw new Error( + `Not enough token balance to withdraw ${lamportsToSol(poolAmount)} pool tokens. + Maximum withdraw amount is ${lamportsToSol(tokenAccount.amount.toNumber())} pool tokens.`, + ); + } + + // Construct transaction to withdraw from withdrawAccounts account list + const instructions: TransactionInstruction[] = []; + const userTransferAuthority = Keypair.generate(); + const signers: Signer[] = [userTransferAuthority]; + + instructions.push( + Token.createApproveInstruction( + TOKEN_PROGRAM_ID, + poolTokenAccount, + userTransferAuthority.publicKey, + tokenOwner, + [], + poolAmount, + ), + ); + + const poolWithdrawAuthority = await findWithdrawAuthorityProgramAddress( + STAKE_POOL_PROGRAM_ID, + stakePoolAddress, + ); + + if (solWithdrawAuthority) { + const expectedSolWithdrawAuthority = stakePool.account.data.solWithdrawAuthority; + if (!expectedSolWithdrawAuthority) { + throw new Error('SOL withdraw authority specified in arguments but stake pool has none'); + } + if (solWithdrawAuthority.toBase58() != expectedSolWithdrawAuthority.toBase58()) { + throw new Error( + `Invalid deposit withdraw specified, expected ${expectedSolWithdrawAuthority.toBase58()}, received ${solWithdrawAuthority.toBase58()}`, + ); } } - console.log('Executable?:', account.account.executable); - console.log('Lamports:', account.account.lamports); - console.log('Owner PubKey:', account.account.owner.toString()); + + const withdrawTransaction = StakePoolInstruction.withdrawSol({ + stakePool: stakePoolAddress, + withdrawAuthority: poolWithdrawAuthority, + reserveStake: stakePool.account.data.reserveStake, + sourcePoolAccount: poolTokenAccount, + sourceTransferAuthority: userTransferAuthority.publicKey, + destinationSystemAccount: solReceiver, + managerFeeAccount: stakePool.account.data.managerFeeAccount, + poolMint: stakePool.account.data.poolMint, + poolTokens: poolAmount, + solWithdrawAuthority, + }); + + instructions.push(withdrawTransaction); + + return { + instructions, + signers, + }; } diff --git a/clients/js-legacy/src/instructions.ts b/clients/js-legacy/src/instructions.ts new file mode 100644 index 00000000..c1a3a7f7 --- /dev/null +++ b/clients/js-legacy/src/instructions.ts @@ -0,0 +1,381 @@ +/** + * Based on https://github.com/solana-labs/solana-web3.js/blob/master/src/stake-program.ts + */ +import { encodeData, decodeData, InstructionType } from './copied-from-solana-web3/instruction'; +import { + PublicKey, + TransactionInstruction, + StakeProgram, + SystemProgram, + SYSVAR_CLOCK_PUBKEY, + SYSVAR_STAKE_HISTORY_PUBKEY, +} from '@solana/web3.js'; +import * as BufferLayout from '@solana/buffer-layout'; +import { TOKEN_PROGRAM_ID } from '@solana/spl-token'; +import { STAKE_POOL_PROGRAM_ID } from "./constants"; + +/** + * An enumeration of valid StakePoolInstructionType's + */ +export type StakePoolInstructionType = + | 'DepositStake' + | 'DepositSol' + | 'WithdrawStake' + | 'WithdrawSol'; + +/** + * An enumeration of valid stake InstructionType's + * @internal + */ +export const STAKE_POOL_INSTRUCTION_LAYOUTS: { + [type in StakePoolInstructionType]: InstructionType; +} = Object.freeze({ + DepositStake: { + index: 9, + layout: BufferLayout.struct([BufferLayout.u8('instruction')]), + }, + /// Withdraw the token from the pool at the current ratio. + WithdrawStake: { + index: 10, + layout: BufferLayout.struct([BufferLayout.u8('instruction'), BufferLayout.ns64('poolTokens')]), + }, + /// Deposit SOL directly into the pool's reserve account. The output is a "pool" token + /// representing ownership into the pool. Inputs are converted to the current ratio. + DepositSol: { + index: 14, + layout: BufferLayout.struct([BufferLayout.u8('instruction'), BufferLayout.ns64('lamports')]), + }, + /// Withdraw SOL directly from the pool's reserve account. Fails if the + /// reserve does not have enough SOL. + WithdrawSol: { + index: 16, + layout: BufferLayout.struct([BufferLayout.u8('instruction'), BufferLayout.ns64('poolTokens')]), + }, +}); + +/** + * Deposit stake pool instruction params + */ +export type DepositStakeParams = { + stakePool: PublicKey; + validatorList: PublicKey; + depositAuthority: PublicKey; + withdrawAuthority: PublicKey; + depositStake: PublicKey; + validatorStake: PublicKey; + reserveStake: PublicKey; + destinationPoolAccount: PublicKey; + managerFeeAccount: PublicKey; + referralPoolAccount: PublicKey; + poolMint: PublicKey; +}; + +/** + * Withdraw stake pool instruction params + */ +export type WithdrawStakeParams = { + stakePool: PublicKey; + validatorList: PublicKey; + withdrawAuthority: PublicKey; + validatorStake: PublicKey; + destinationStake: PublicKey; + destinationStakeAuthority: PublicKey; + sourceTransferAuthority: PublicKey; + sourcePoolAccount: PublicKey; + managerFeeAccount: PublicKey; + poolMint: PublicKey; + poolTokens: number; +}; + +/** + * Withdraw sol instruction params + */ +export type WithdrawSolParams = { + stakePool: PublicKey; + sourcePoolAccount: PublicKey; + withdrawAuthority: PublicKey; + reserveStake: PublicKey; + destinationSystemAccount: PublicKey; + sourceTransferAuthority: PublicKey; + solWithdrawAuthority?: PublicKey | undefined; + managerFeeAccount: PublicKey; + poolMint: PublicKey; + poolTokens: number; +}; + +/** + * Deposit sol instruction params + */ +export type DepositSolParams = { + stakePool: PublicKey; + depositAuthority?: PublicKey | undefined; + withdrawAuthority: PublicKey; + reserveStake: PublicKey; + fundingAccount: PublicKey; + destinationPoolAccount: PublicKey; + managerFeeAccount: PublicKey; + referralPoolAccount: PublicKey; + poolMint: PublicKey; + lamports: number; +}; + +/** + * Stake Pool Instruction class + */ +export class StakePoolInstruction { + /** + * Creates a transaction instruction to deposit SOL into a stake pool. + */ + static depositStake(params: DepositStakeParams): TransactionInstruction { + const { + stakePool, + validatorList, + depositAuthority, + withdrawAuthority, + depositStake, + validatorStake, + reserveStake, + destinationPoolAccount, + managerFeeAccount, + referralPoolAccount, + poolMint, + } = params; + + const type = STAKE_POOL_INSTRUCTION_LAYOUTS.DepositStake; + const data = encodeData(type); + + const keys = [ + { pubkey: stakePool, isSigner: false, isWritable: true }, + { pubkey: validatorList, isSigner: false, isWritable: true }, + { pubkey: depositAuthority, isSigner: false, isWritable: false }, + { pubkey: withdrawAuthority, isSigner: false, isWritable: false }, + { pubkey: depositStake, isSigner: false, isWritable: true }, + { pubkey: validatorStake, isSigner: false, isWritable: true }, + { pubkey: reserveStake, isSigner: false, isWritable: true }, + { pubkey: destinationPoolAccount, isSigner: false, isWritable: true }, + { pubkey: managerFeeAccount, isSigner: false, isWritable: true }, + { pubkey: referralPoolAccount, isSigner: false, isWritable: true }, + { pubkey: poolMint, isSigner: false, isWritable: true }, + { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false }, + { pubkey: SYSVAR_STAKE_HISTORY_PUBKEY, isSigner: false, isWritable: false }, + { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, + { pubkey: StakeProgram.programId, isSigner: false, isWritable: false }, + ]; + + return new TransactionInstruction({ + programId: STAKE_POOL_PROGRAM_ID, + keys, + data, + }); + } + + /** + * Creates a transaction instruction to withdraw SOL from a stake pool. + */ + static depositSol(params: DepositSolParams): TransactionInstruction { + const { + stakePool, + withdrawAuthority, + depositAuthority, + reserveStake, + fundingAccount, + destinationPoolAccount, + managerFeeAccount, + referralPoolAccount, + poolMint, + lamports, + } = params; + + const type = STAKE_POOL_INSTRUCTION_LAYOUTS.DepositSol; + const data = encodeData(type, { lamports }); + + const keys = [ + { pubkey: stakePool, isSigner: false, isWritable: true }, + { pubkey: withdrawAuthority, isSigner: false, isWritable: false }, + { pubkey: reserveStake, isSigner: false, isWritable: true }, + { pubkey: fundingAccount, isSigner: true, isWritable: true }, + { pubkey: destinationPoolAccount, isSigner: false, isWritable: true }, + { pubkey: managerFeeAccount, isSigner: false, isWritable: true }, + { pubkey: referralPoolAccount, isSigner: false, isWritable: true }, + { pubkey: poolMint, isSigner: false, isWritable: true }, + { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, + { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, + ]; + + if (depositAuthority) { + keys.push({ + pubkey: depositAuthority, + isSigner: true, + isWritable: false, + }); + } + + return new TransactionInstruction({ + programId: STAKE_POOL_PROGRAM_ID, + keys, + data, + }); + } + + /** + * Creates a transaction instruction to withdraw SOL from a stake pool. + */ + static withdrawStake(params: WithdrawStakeParams): TransactionInstruction { + const { + stakePool, + validatorList, + withdrawAuthority, + validatorStake, + destinationStake, + destinationStakeAuthority, + sourceTransferAuthority, + sourcePoolAccount, + managerFeeAccount, + poolMint, + poolTokens, + } = params; + + const type = STAKE_POOL_INSTRUCTION_LAYOUTS.WithdrawStake; + const data = encodeData(type, { poolTokens }); + + const keys = [ + { pubkey: stakePool, isSigner: false, isWritable: true }, + { pubkey: validatorList, isSigner: false, isWritable: true }, + { pubkey: withdrawAuthority, isSigner: false, isWritable: false }, + { pubkey: validatorStake, isSigner: false, isWritable: true }, + { pubkey: destinationStake, isSigner: false, isWritable: true }, + { pubkey: destinationStakeAuthority, isSigner: false, isWritable: false }, + { pubkey: sourceTransferAuthority, isSigner: true, isWritable: false }, + { pubkey: sourcePoolAccount, isSigner: false, isWritable: true }, + { pubkey: managerFeeAccount, isSigner: false, isWritable: true }, + { pubkey: poolMint, isSigner: false, isWritable: true }, + { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false }, + { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, + { pubkey: StakeProgram.programId, isSigner: false, isWritable: false }, + ]; + + return new TransactionInstruction({ + programId: STAKE_POOL_PROGRAM_ID, + keys, + data, + }); + } + + /** + * Creates a transaction instruction to withdraw SOL from a stake pool. + */ + static withdrawSol(params: WithdrawSolParams): TransactionInstruction { + const { + stakePool, + withdrawAuthority, + sourceTransferAuthority, + sourcePoolAccount, + reserveStake, + destinationSystemAccount, + managerFeeAccount, + solWithdrawAuthority, + poolMint, + poolTokens, + } = params; + + const type = STAKE_POOL_INSTRUCTION_LAYOUTS.WithdrawSol; + const data = encodeData(type, { poolTokens }); + + const keys = [ + { pubkey: stakePool, isSigner: false, isWritable: true }, + { pubkey: withdrawAuthority, isSigner: false, isWritable: false }, + { pubkey: sourceTransferAuthority, isSigner: true, isWritable: false }, + { pubkey: sourcePoolAccount, isSigner: false, isWritable: true }, + { pubkey: reserveStake, isSigner: false, isWritable: true }, + { pubkey: destinationSystemAccount, isSigner: false, isWritable: true }, + { pubkey: managerFeeAccount, isSigner: false, isWritable: true }, + { pubkey: poolMint, isSigner: false, isWritable: true }, + { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false }, + { pubkey: SYSVAR_STAKE_HISTORY_PUBKEY, isSigner: false, isWritable: false }, + { pubkey: StakeProgram.programId, isSigner: false, isWritable: false }, + { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, + ]; + + if (solWithdrawAuthority) { + keys.push({ + pubkey: solWithdrawAuthority, + isSigner: true, + isWritable: false, + }); + } + + return new TransactionInstruction({ + programId: STAKE_POOL_PROGRAM_ID, + keys, + data, + }); + } + + /** + * Decode a deposit stake pool instruction and retrieve the instruction params. + */ + static decodeDepositStake(instruction: TransactionInstruction): DepositStakeParams { + this.checkProgramId(instruction.programId); + this.checkKeyLength(instruction.keys, 11); + + decodeData(STAKE_POOL_INSTRUCTION_LAYOUTS.DepositStake, instruction.data); + + return { + stakePool: instruction.keys[0].pubkey, + validatorList: instruction.keys[1].pubkey, + depositAuthority: instruction.keys[2].pubkey, + withdrawAuthority: instruction.keys[3].pubkey, + depositStake: instruction.keys[4].pubkey, + validatorStake: instruction.keys[5].pubkey, + reserveStake: instruction.keys[6].pubkey, + destinationPoolAccount: instruction.keys[7].pubkey, + managerFeeAccount: instruction.keys[8].pubkey, + referralPoolAccount: instruction.keys[9].pubkey, + poolMint: instruction.keys[10].pubkey, + }; + } + + /** + * Decode a deposit sol instruction and retrieve the instruction params. + */ + static decodeDepositSol(instruction: TransactionInstruction): DepositSolParams { + this.checkProgramId(instruction.programId); + this.checkKeyLength(instruction.keys, 9); + + const { amount } = decodeData(STAKE_POOL_INSTRUCTION_LAYOUTS.DepositSol, instruction.data); + + return { + stakePool: instruction.keys[0].pubkey, + depositAuthority: instruction.keys[1].pubkey, + withdrawAuthority: instruction.keys[2].pubkey, + reserveStake: instruction.keys[3].pubkey, + fundingAccount: instruction.keys[4].pubkey, + destinationPoolAccount: instruction.keys[5].pubkey, + managerFeeAccount: instruction.keys[6].pubkey, + referralPoolAccount: instruction.keys[7].pubkey, + poolMint: instruction.keys[8].pubkey, + lamports: amount, + }; + } + + /** + * @internal + */ + private static checkProgramId(programId: PublicKey) { + if (!programId.equals(StakeProgram.programId)) { + throw new Error('Invalid instruction; programId is not StakeProgram'); + } + } + + /** + * @internal + */ + private static checkKeyLength(keys: Array, expectedLength: number) { + if (keys.length < expectedLength) { + throw new Error( + `Invalid instruction; found ${keys.length} keys, expected at least ${expectedLength}`, + ); + } + } +} + diff --git a/clients/js-legacy/src/integration_test.ts b/clients/js-legacy/src/integration_test.ts deleted file mode 100644 index 4102b3cb..00000000 --- a/clients/js-legacy/src/integration_test.ts +++ /dev/null @@ -1,65 +0,0 @@ -import * as index from './index.js'; -import * as schema from './schema.js'; -import BN from 'bn.js'; -import assert, {deepStrictEqual} from 'assert'; -import {SOLANA_SCHEMA, PublicKey, Connection} from '@solana/web3.js'; - -// First populate schema -schema.addStakePoolSchema(SOLANA_SCHEMA); - -describe('Integration test', () => { - it('should successfully decode all validators from devnet', async () => { - /** - * Full integration test: - * Makes a connection to devnet, gets all stake pool accounts there, - * decodes them, and prints their details. - */ - const connection = new Connection( - 'https://api.devnet.solana.com/', - 'confirmed', - ); - const STAKE_POOL_PROGRAM_ADDR = new PublicKey( - 'poo1B9L9nR3CrcaziKVYVpRX6A9Y1LAXYasjjfCbApj', - ); - - const accounts = await index.getStakePoolAccounts( - connection, - STAKE_POOL_PROGRAM_ADDR, - ); - - console.log('Number of stake pool accounts in devnet: ', accounts.length); - - accounts.map(account => { - index.prettyPrintAccount(account); - console.log('\n'); - }); - }); - - it('should successfully decode all validators from testnet', async () => { - /** - * Full integration test: - * Makes a connection to testnet, gets all stake pool accounts there, - * decodes them, and prints their details. - * Testnet presents a greater challenge due to the presence of old stake pool program accounts - */ - const connection = new Connection( - 'https://api.testnet.solana.com/', - 'confirmed', - ); - const STAKE_POOL_PROGRAM_ADDR = new PublicKey( - 'poo1B9L9nR3CrcaziKVYVpRX6A9Y1LAXYasjjfCbApj', - ); - - const accounts = await index.getStakePoolAccounts( - connection, - STAKE_POOL_PROGRAM_ADDR, - ); - - console.log('Number of stake pool accounts in testnet: ', accounts.length); - - accounts.map(account => { - index.prettyPrintAccount(account); - console.log('\n'); - }); - }); -}); diff --git a/clients/js-legacy/src/layouts.ts b/clients/js-legacy/src/layouts.ts new file mode 100644 index 00000000..d500ed4c --- /dev/null +++ b/clients/js-legacy/src/layouts.ts @@ -0,0 +1,152 @@ +import { publicKey, struct, u32, u64, u8, option, vec } from '@project-serum/borsh'; +import { Lockup, PublicKey } from '@solana/web3.js'; +import { AccountInfo } from "@solana/spl-token"; +import BN from 'bn.js'; + +export interface Fee { + denominator: BN; + numerator: BN; +} + +const feeFields = [u64('denominator'), u64('numerator')]; + +/** + * AccountLayout.encode from "@solana/spl-token" doesn't work + */ +export const AccountLayout = struct([ + publicKey('mint'), + publicKey('owner'), + u64('amount'), + u32('delegateOption'), + publicKey('delegate'), + u8('state'), + u32('isNativeOption'), + u64('isNative'), + u64('delegatedAmount'), + u32('closeAuthorityOption'), + publicKey('closeAuthority'), +]); + +export enum AccountType { + Uninitialized, + StakePool, + ValidatorList, +} + +export interface StakePool { + accountType: AccountType; + manager: PublicKey; + staker: PublicKey; + stakeDepositAuthority: PublicKey; + stakeWithdrawBumpSeed: number; + validatorList: PublicKey; + reserveStake: PublicKey; + poolMint: PublicKey; + managerFeeAccount: PublicKey; + tokenProgramId: PublicKey; + totalLamports: BN; + poolTokenSupply: BN; + lastUpdateEpoch: BN; + lockup: Lockup; + epochFee: Fee; + nextEpochFee?: Fee | undefined; + preferredDepositValidatorVoteAddress?: PublicKey | undefined; + preferredWithdrawValidatorVoteAddress?: PublicKey | undefined; + stakeDepositFee: Fee; + stakeWithdrawalFee: Fee; + nextWithdrawalFee?: Fee | undefined; + stakeReferralFee: number; + solDepositAuthority?: PublicKey | undefined; + solDepositFee: Fee; + solReferralFee: number; + solWithdrawAuthority?: PublicKey | undefined; + solWithdrawalFee: Fee; + nextSolWithdrawalFee?: Fee | undefined; + lastEpochPoolTokenSupply: BN; + lastEpochTotalLamports: BN; +} + +export const StakePoolLayout = struct([ + u8('accountType'), + publicKey('manager'), + publicKey('staker'), + publicKey('stakeDepositAuthority'), + u8('stakeWithdrawBumpSeed'), + publicKey('validatorList'), + publicKey('reserveStake'), + publicKey('poolMint'), + publicKey('managerFeeAccount'), + publicKey('tokenProgramId'), + u64('totalLamports'), + u64('poolTokenSupply'), + u64('lastUpdateEpoch'), + struct([u64('unixTimestamp'), u64('epoch'), publicKey('custodian')], 'lockup'), + struct(feeFields, 'epochFee'), + option(struct(feeFields), 'nextEpochFee'), + option(publicKey(), 'preferredDepositValidatorVoteAddress'), + option(publicKey(), 'preferredWithdrawValidatorVoteAddress'), + struct(feeFields, 'stakeDepositFee'), + struct(feeFields, 'stakeWithdrawalFee'), + option(struct(feeFields), 'nextWithdrawalFee'), + u8('stakeReferralFee'), + option(publicKey(), 'solDepositAuthority'), + struct(feeFields, 'solDepositFee'), + u8('solReferralFee'), + option(publicKey(), 'solWithdrawAuthority'), + struct(feeFields, 'solWithdrawalFee'), + option(struct(feeFields), 'nextSolWithdrawalFee'), + u64('lastEpochPoolTokenSupply'), + u64('lastEpochTotalLamports'), +]); + +export enum ValidatorStakeInfoStatus { + Active, + DeactivatingTransient, + ReadyForRemoval, +} + +export interface ValidatorStakeInfo { + status: ValidatorStakeInfoStatus; + voteAccountAddress: PublicKey; + activeStakeLamports: BN; + transientStakeLamports: BN; + transientSeedSuffixStart: BN; + transientSeedSuffixEnd: BN; + lastUpdateEpoch: BN; +} + +export const ValidatorStakeInfoLayout = struct([ + /// Amount of active stake delegated to this validator + /// Note that if `last_update_epoch` does not match the current epoch then + /// this field may not be accurate + u64('activeStakeLamports'), + /// Amount of transient stake delegated to this validator + /// Note that if `last_update_epoch` does not match the current epoch then + /// this field may not be accurate + u64('transientStakeLamports'), + /// Last epoch the active and transient stake lamports fields were updated + u64('lastUpdateEpoch'), + /// Start of the validator transient account seed suffixes + u64('transientSeedSuffixStart'), + /// End of the validator transient account seed suffixes + u64('transientSeedSuffixEnd'), + /// Status of the validator stake account + u8('status'), + /// Validator vote account address + publicKey('voteAccountAddress'), +]); + +export interface ValidatorList { + /// Account type, must be ValidatorList currently + accountType: number; + /// Maximum allowable number of validators + maxValidators: number; + /// List of stake info for each validator in the pool + validators: ValidatorStakeInfo[]; +} + +export const ValidatorListLayout = struct([ + u8('accountType'), + u32('maxValidators'), + vec(ValidatorStakeInfoLayout, 'validators'), +]); diff --git a/clients/js-legacy/src/schema.ts b/clients/js-legacy/src/schema.ts deleted file mode 100644 index f4a4954c..00000000 --- a/clients/js-legacy/src/schema.ts +++ /dev/null @@ -1,139 +0,0 @@ -import {Schema, serialize, deserializeUnchecked} from 'borsh'; -import BN from 'bn.js'; -import {Struct, Enum, PublicKey} from '@solana/web3.js'; - -export class Fee extends Struct { - denominator: BN; - numerator: BN; -} - -export class AccountType extends Enum {} - -export class AccountTypeEnum extends Struct {} - -export enum AccountTypeKind { - Uninitialized = 'Uninitialized', - StakePool = 'StakePool', - ValidatorList = 'ValidatorList', -} - -export class StakePool extends Struct { - accountType: AccountType; - manager: PublicKey; - staker: PublicKey; - depositAuthority: PublicKey; - withdrawBumpSeed: number; - validatorList: PublicKey; - reserveStake: PublicKey; - poolMint: PublicKey; - managerFeeAccount: PublicKey; - totalStakeLamports: BN; - poolTokenSupply: BN; - lastUpdateEpoch: BN; - fee: Fee; -} - -export class ValidatorList extends Struct { - accountType: AccountType; - maxValidators: number; - validators: [ValidatorStakeInfo]; -} -export class ValidatorStakeInfo extends Struct { - status: StakeStatus; - voteAccountAddress: PublicKey; - stakeLamports: BN; - lastUpdateEpoch: BN; -} -export class StakeStatus extends Enum {} - -export class StakeStatusEnum extends Struct {} - -export enum StakeStatusKind { - Active = 'Active', - DeactivatingTransient = 'DeactivatingTransient', - ReadyForRemoval = 'ReadyForRemoval', -} - -export function addStakePoolSchema(schema: Schema): void { - /** - * Borsh requires something called a Schema, - * which is a Map (key-value pairs) that tell borsh how to deserialise the raw data - * This function adds a new schema to an existing schema object. - */ - schema.set(PublicKey, { - kind: 'struct', - fields: [['_bn', 'u256']], - }); - - schema.set(Fee, { - kind: 'struct', - fields: [ - ['denominator', 'u64'], - ['numerator', 'u64'], - ], - }); - - schema.set(AccountType, { - kind: 'enum', - field: 'enum', - values: [ - // if the account has not been initialized, the enum will be 0 - [AccountTypeKind.Uninitialized, AccountTypeEnum], - [AccountTypeKind.StakePool, AccountTypeEnum], - [AccountTypeKind.ValidatorList, AccountTypeEnum], - ], - }); - - schema.set(AccountTypeEnum, {kind: 'struct', fields: []}); - - schema.set(StakePool, { - kind: 'struct', - fields: [ - ['accountType', AccountType], - ['manager', PublicKey], - ['staker', PublicKey], - ['depositAuthority', PublicKey], - ['withdrawBumpSeed', 'u8'], - ['validatorList', PublicKey], - ['reserveStake', PublicKey], - ['poolMint', PublicKey], - ['managerFeeAccount', PublicKey], - ['tokenProgramId', PublicKey], - ['totalStakeLamports', 'u64'], - ['poolTokenSupply', 'u64'], - ['lastUpdateEpoch', 'u64'], - ['fee', Fee], - ], - }); - - schema.set(ValidatorList, { - kind: 'struct', - fields: [ - ['accountType', AccountType], - ['maxValidators', 'u32'], - ['validators', [ValidatorStakeInfo]], - ], - }); - - schema.set(StakeStatus, { - kind: 'enum', - field: 'enum', - values: [ - [StakeStatusKind.Active, StakeStatusEnum], - [StakeStatusKind.DeactivatingTransient, StakeStatusEnum], - [StakeStatusKind.ReadyForRemoval, StakeStatusEnum], - ], - }); - - schema.set(StakeStatusEnum, {kind: 'struct', fields: []}); - - schema.set(ValidatorStakeInfo, { - kind: 'struct', - fields: [ - ['status', StakeStatus], - ['voteAccountAddress', PublicKey], - ['stakeLamports', 'u64'], - ['lastUpdateEpoch', 'u64'], - ], - }); -} diff --git a/clients/js-legacy/src/test.ts b/clients/js-legacy/src/test.ts deleted file mode 100644 index 293b9f8a..00000000 --- a/clients/js-legacy/src/test.ts +++ /dev/null @@ -1,215 +0,0 @@ -import * as index from './index.js'; -import * as schema from './schema.js'; -import BN from 'bn.js'; -import assert, {deepStrictEqual} from 'assert'; -import {SOLANA_SCHEMA, PublicKey, Connection} from '@solana/web3.js'; - -// First populate schema -schema.addStakePoolSchema(SOLANA_SCHEMA); - -function deepStrictEqualBN(decodedData: object, expectedData: object) { - /** - * Helper function to do deep equality check because BNs are not equal. - * TODO: write this function recursively. For now, sufficient. - */ - for (const key in decodedData) { - if (expectedData[key] instanceof BN) { - assert.ok(expectedData[key].eq(decodedData[key])); - } else { - if (decodedData[key] instanceof Object) { - for (const subkey in decodedData[key]) { - if (decodedData[key][subkey] instanceof Object) { - if (decodedData[key][subkey] instanceof BN) { - assert.ok(decodedData[key][subkey].eq(expectedData[key][subkey])); - } else { - for (const subsubkey in decodedData[key][subkey]) { - console.log(decodedData[key][subkey][subsubkey]); - if (decodedData[key][subkey][subsubkey] instanceof BN) { - assert.ok( - decodedData[key][subkey][subsubkey].eq( - expectedData[key][subkey][subsubkey], - ), - ); - } else { - assert.deepStrictEqual( - expectedData[key][subkey][subsubkey], - decodedData[key][subkey][subsubkey], - ); - } - } - } - } else { - assert.strictEqual( - decodedData[key][subkey], - expectedData[key][subkey], - ); - } - } - } else { - assert.strictEqual(decodedData[key], expectedData[key]); - } - } - } -} - -describe('schema.decode', () => { - describe('StakePoolAccount', () => { - it('should successfully decode StakePoolAccount account data', () => { - const expectedData = new schema.StakePool({ - accountType: new schema.AccountType({ - StakePool: new schema.AccountTypeEnum({}), - }), - manager: new PublicKey( - new BN( - 'dc23cda2ad09ddec126f89ed7f67d06a4d167cca996503f1a1b3b5a13625964f', - 'hex', - ), - ), - staker: new PublicKey( - new BN( - 'dc23cda2ad09ddec126f89ed7f67d06a4d167cca996503f1a1b3b5a13625964f', - 'hex', - ), - ), - depositAuthority: new PublicKey( - new BN( - new Buffer( - '5911e7451a1a854fdc9e495081790f293eba623f8ec7e2b9d34a5fd25c7009bb', - 'hex', - ), - ), - ), - withdrawBumpSeed: 255, - validatorList: new PublicKey( - new BN( - '7103ba4895b8804263197364da9e791db96ec8f0c8ca184dd666e69013838610', - 'hex', - ), - ), - reserveStake: new PublicKey( - new BN( - '74a5b1ab8442103baa8bd39ab8494eb034e96035ac664e1693bb3eef458761ee', - 'hex', - ), - ), - poolMint: new PublicKey( - new BN( - '8722bf107b95d2620008d256b18c13fa3a46ab7f643c24cf7656f57267563e00', - 'hex', - ), - ), - managerFeeAccount: new PublicKey( - new BN( - new Buffer( - 'b783b4dcd341cbca22e781bbd49b2d16908a844a21b98e26b69d44fc50e1db0f', - 'hex', - ), - ), - ), - tokenProgramId: new PublicKey( - new BN( - 'a900ff7e85f58c3a91375b5fed85b41cac79ebce46e1cbd993a165d7e1f6dd06', - 'hex', - ), - ), - totalStakeLamports: new BN('0', 'hex'), - poolTokenSupply: new BN('0', 'hex'), - lastUpdateEpoch: new BN('7c', 'hex'), - fee: new schema.Fee({ - denominator: new BN('3e8', 'hex'), - numerator: new BN('38', 'hex'), - }), - }); - - const decodedData = schema.StakePool.decode(expectedData.encode()); - - deepStrictEqualBN(decodedData, expectedData); - }); - }); - - describe('ValidatorListAccount', () => { - it('should successfully decode ValidatorListAccount account data', () => { - const expectedData = new schema.ValidatorList({ - accountType: new schema.AccountType({ - ValidatorList: new schema.AccountTypeEnum({}), - }), - maxValidators: 10, - validators: [], - }); - - const decodedData = schema.ValidatorList.decode(expectedData.encode()); - assert.deepStrictEqual(decodedData, expectedData); - }); - - it('should successfully decode ValidatorListAccount with nonempty ValidatorInfo', () => { - // TODO also test for decoding ValidatorListAccount with actual ValidatorInfo - // Do this once we have a stake pool with validators deployed on testnet - - const expectedData = new schema.ValidatorList({ - accountType: new schema.AccountType({ - ValidatorList: new schema.AccountTypeEnum({}), - }), - maxValidators: 100, - validators: [ - new schema.ValidatorStakeInfo({ - status: new schema.StakeStatus({ - Active: new schema.StakeStatusEnum({}), - }), - voteAccountAddress: new PublicKey( - new BN( - 'a9946a889af14fd3c9b33d5df309489d9699271a6b09ff3190fcb41cf21a2f8c', - 'hex', - ), - ), - stakeLamports: new BN('0', 'hex'), - lastUpdateEpoch: new BN('c3', 'hex'), - }), - new schema.ValidatorStakeInfo({ - status: new schema.StakeStatus({ - Active: new schema.StakeStatusEnum({}), - }), - voteAccountAddress: new PublicKey( - new BN( - '3796d40645ee07e3c64117e3f73430471d4c40465f696ebc9b034c1fc06a9f7d', - 'hex', - ), - ), - stakeLamports: new BN('0', 'hex'), - lastUpdateEpoch: new BN('c3', 'hex'), - }), - new schema.ValidatorStakeInfo({ - status: new schema.StakeStatus({ - Active: new schema.StakeStatusEnum({}), - }), - voteAccountAddress: new PublicKey( - new BN( - 'e4e37d6f2e80c0bb0f3da8a06304e57be5cda6efa2825b86780aa320d9784cf8', - 'hex', - ), - ), - stakeLamports: new BN('0', 'hex'), - lastUpdateEpoch: new BN('c3', 'hex'), - }), - ], - }); - - const decodedData = schema.ValidatorList.decode(expectedData.encode()); - deepStrictEqualBN(decodedData, expectedData); - }); - }); -}); - -describe('index.ts/PrettyPrintPubkey', () => { - it('should successfully pretty print a pubkey', () => { - assert.equal( - index.prettyPrintPubKey( - new PublicKey( - new BN( - '99572085579321386496717000324290408927851378839748241098946587626478579848783', - ), - ), - ), - '6MfzrQUzB2mozveRWU9a77zMoQzSrYa4Gq46KswjupQB', - ); - }); -}); diff --git a/clients/js-legacy/src/utils/index.ts b/clients/js-legacy/src/utils/index.ts new file mode 100644 index 00000000..f280f312 --- /dev/null +++ b/clients/js-legacy/src/utils/index.ts @@ -0,0 +1,4 @@ +export * from './math' +export * from './program-address' +export * from './stake' +export * from './token' diff --git a/clients/js-legacy/src/utils/math.ts b/clients/js-legacy/src/utils/math.ts new file mode 100644 index 00000000..3bbe11ff --- /dev/null +++ b/clients/js-legacy/src/utils/math.ts @@ -0,0 +1,24 @@ +import BN from "bn.js"; +import { LAMPORTS_PER_SOL } from "@solana/web3.js"; + +export function solToLamports(amount: number): number { + if (isNaN(amount)) return Number(0); + return Number(amount * LAMPORTS_PER_SOL); +} + +export function lamportsToSol(lamports: number | BN): number { + if (typeof lamports === 'number') { + return Math.abs(lamports) / LAMPORTS_PER_SOL; + } + + let signMultiplier = 1; + if (lamports.isNeg()) { + signMultiplier = -1; + } + + const absLamports = lamports.abs(); + const lamportsString = absLamports.toString(10).padStart(10, '0'); + const splitIndex = lamportsString.length - 9; + const solString = lamportsString.slice(0, splitIndex) + '.' + lamportsString.slice(splitIndex); + return signMultiplier * parseFloat(solString); +} diff --git a/clients/js-legacy/src/utils/program-address.ts b/clients/js-legacy/src/utils/program-address.ts new file mode 100644 index 00000000..7de23082 --- /dev/null +++ b/clients/js-legacy/src/utils/program-address.ts @@ -0,0 +1,53 @@ +import { PublicKey } from "@solana/web3.js"; +import BN from "bn.js"; +import { TRANSIENT_STAKE_SEED_PREFIX } from "../constants"; + +/** + * Generates the withdraw authority program address for the stake pool + */ +export async function findWithdrawAuthorityProgramAddress( + programId: PublicKey, + stakePoolAddress: PublicKey, +) { + const [publicKey] = await PublicKey.findProgramAddress( + [stakePoolAddress.toBuffer(), Buffer.from('withdraw')], + programId, + ); + return publicKey; +} + +/** + * Generates the stake program address for a validator's vote account + */ +export async function findStakeProgramAddress( + programId: PublicKey, + voteAccountAddress: PublicKey, + stakePoolAddress: PublicKey, +) { + const [publicKey] = await PublicKey.findProgramAddress( + [voteAccountAddress.toBuffer(), stakePoolAddress.toBuffer()], + programId, + ); + return publicKey; +} + +/** + * Generates the stake program address for a validator's vote account + */ +export async function findTransientStakeProgramAddress( + programId: PublicKey, + voteAccountAddress: PublicKey, + stakePoolAddress: PublicKey, + seed: BN, +) { + const [publicKey] = await PublicKey.findProgramAddress( + [ + TRANSIENT_STAKE_SEED_PREFIX, + voteAccountAddress.toBuffer(), + stakePoolAddress.toBuffer(), + new Uint8Array(seed.toArray('le', 8)), + ], + programId, + ); + return publicKey; +} diff --git a/clients/js-legacy/src/utils/stake.ts b/clients/js-legacy/src/utils/stake.ts new file mode 100644 index 00000000..a21d7bb4 --- /dev/null +++ b/clients/js-legacy/src/utils/stake.ts @@ -0,0 +1,196 @@ +import { + Connection, + Keypair, + PublicKey, StakeProgram, + SystemProgram, + TransactionInstruction +} from "@solana/web3.js"; +import { findStakeProgramAddress, findTransientStakeProgramAddress } from "./program-address"; +import BN from "bn.js"; + +import { lamportsToSol } from "./math"; +import { WithdrawAccount } from "../index"; +import { + StakePool, + ValidatorList, + ValidatorListLayout, + ValidatorStakeInfoStatus +} from "../layouts"; +import { STAKE_POOL_PROGRAM_ID } from "../constants"; + +export async function prepareWithdrawAccounts( + connection: Connection, + stakePool: StakePool, + stakePoolAddress: PublicKey, + amount: number, +): Promise { + const validatorListAcc = await connection.getAccountInfo(stakePool.validatorList); + const validatorList = ValidatorListLayout.decode(validatorListAcc!.data) as ValidatorList; + + if (!validatorList?.validators || validatorList?.validators.length == 0) { + throw new Error('No accounts found'); + } + + let accounts = [] as Array<{ + type: 'preferred' | 'active' | 'transient' | 'reserve'; + voteAddress?: PublicKey | undefined; + stakeAddress: PublicKey; + lamports: number; + }>; + + // Prepare accounts + for (const validator of validatorList.validators) { + + if (validator.status !== ValidatorStakeInfoStatus.Active) { + continue; + } + + const stakeAccountAddress = await findStakeProgramAddress( + STAKE_POOL_PROGRAM_ID, + validator.voteAccountAddress, + stakePoolAddress, + ); + + if (!validator.activeStakeLamports.isZero()) { + const isPreferred = + stakePool.preferredWithdrawValidatorVoteAddress && + stakePool.preferredWithdrawValidatorVoteAddress!.toBase58() == + validator.voteAccountAddress.toBase58(); + accounts.push({ + type: isPreferred ? 'preferred' : 'active', + voteAddress: validator.voteAccountAddress, + stakeAddress: stakeAccountAddress, + lamports: validator.activeStakeLamports.toNumber(), + }); + } + + const transientStakeAccountAddress = await findTransientStakeProgramAddress( + STAKE_POOL_PROGRAM_ID, + validator.voteAccountAddress, + stakePoolAddress, + validator.transientSeedSuffixStart!, + ); + + if (!validator.transientStakeLamports?.isZero()) { + accounts.push({ + type: 'transient', + voteAddress: validator.voteAccountAddress, + stakeAddress: transientStakeAccountAddress, + lamports: validator.transientStakeLamports!.toNumber(), + }); + } + } + + // Sort from highest to lowest balance + accounts = accounts.sort((a, b) => b.lamports - a.lamports); + + const reserveStake = await connection.getAccountInfo(stakePool.reserveStake); + if (reserveStake && reserveStake.lamports > 0) { + console.log('Reserve Stake: ', reserveStake.lamports); + accounts.push({ + type: 'reserve', + stakeAddress: stakePool.reserveStake, + lamports: reserveStake?.lamports, + }); + } + + // Prepare the list of accounts to withdraw from + const withdrawFrom: WithdrawAccount[] = []; + let remainingAmount = amount; + + for (const type of ['preferred', 'active', 'transient', 'reserve']) { + const filteredAccounts = accounts.filter(a => a.type == type); + + for (const { stakeAddress, voteAddress, lamports } of filteredAccounts) { + let availableForWithdrawal = Math.floor(calcPoolTokensForDeposit(stakePool, lamports)); + if (!stakePool.stakeWithdrawalFee.denominator.isZero()) { + availableForWithdrawal = divideBnToNumber( + new BN(availableForWithdrawal).mul(stakePool.stakeWithdrawalFee.denominator), + stakePool.stakeWithdrawalFee.denominator.sub(stakePool.stakeWithdrawalFee.numerator), + ); + } + + const poolAmount = Math.min(availableForWithdrawal, remainingAmount); + if (poolAmount <= 0) { + continue; + } + + // Those accounts will be withdrawn completely with `claim` instruction + withdrawFrom.push({ stakeAddress, voteAddress, poolAmount }); + remainingAmount -= poolAmount; + if (remainingAmount == 0) { + break; + } + } + if (remainingAmount == 0) { + break; + } + } + + // Not enough stake to withdraw the specified amount + if (remainingAmount > 0) { + throw new Error( + `No stake accounts found in this pool with enough balance to withdraw ${lamportsToSol(amount)} pool tokens.` + ); + } + + return withdrawFrom; +} + +/** + * Calculate the pool tokens that should be minted for a deposit of `stakeLamports` + */ +export function calcPoolTokensForDeposit(stakePool: StakePool, stakeLamports: number): number { + if (stakePool.poolTokenSupply.isZero() || stakePool.totalLamports.isZero()) { + return stakeLamports; + } + return divideBnToNumber( + new BN(stakeLamports).mul(stakePool.poolTokenSupply), + stakePool.totalLamports, + ); +} + +/** + * Calculate lamports amount on withdrawal + */ +export function calcLamportsWithdrawAmount(stakePool: StakePool, poolTokens: number): number { + const numerator = new BN(poolTokens).mul(stakePool.totalLamports); + const denominator = stakePool.poolTokenSupply; + if (numerator.lt(denominator)) { + return 0; + } + return divideBnToNumber(numerator, denominator); +} + +export function divideBnToNumber(numerator: BN, denominator: BN): number { + if (denominator.isZero()) { + return 0; + } + const quotient = numerator.div(denominator).toNumber(); + const rem = numerator.umod(denominator); + const gcd = rem.gcd(denominator); + return quotient + rem.div(gcd).toNumber() / denominator.div(gcd).toNumber(); +} + +export function newStakeAccount( + feePayer: PublicKey, + instructions: TransactionInstruction[], + lamports: number, +): Keypair { + // Account for tokens not specified, creating one + const stakeReceiverKeypair = Keypair.generate(); + console.log(`Creating account to receive stake ${stakeReceiverKeypair.publicKey}`); + + instructions.push( + // Creating new account + SystemProgram.createAccount({ + fromPubkey: feePayer, + newAccountPubkey: stakeReceiverKeypair.publicKey, + lamports, + space: StakeProgram.space, + programId: StakeProgram.programId, + }), + ); + + return stakeReceiverKeypair; +} diff --git a/clients/js-legacy/src/utils/token.ts b/clients/js-legacy/src/utils/token.ts new file mode 100644 index 00000000..ac16b11a --- /dev/null +++ b/clients/js-legacy/src/utils/token.ts @@ -0,0 +1,86 @@ +import { Connection, PublicKey, TransactionInstruction } from "@solana/web3.js"; +import { + AccountInfo, + ASSOCIATED_TOKEN_PROGRAM_ID, + Token, + TOKEN_PROGRAM_ID +} from "@solana/spl-token"; +import { AccountLayout } from "../layouts"; + +const FAILED_TO_FIND_ACCOUNT = 'Failed to find account'; +const INVALID_ACCOUNT_OWNER = 'Invalid account owner'; + +/** + * Retrieve the associated account or create one if not found. + * This account may then be used as a `transfer()` or `approve()` destination + */ +export async function addAssociatedTokenAccount( + connection: Connection, + owner: PublicKey, + mint: PublicKey, + instructions: TransactionInstruction[], +) { + const associatedAddress = await Token.getAssociatedTokenAddress( + ASSOCIATED_TOKEN_PROGRAM_ID, + TOKEN_PROGRAM_ID, + mint, + owner, + ); + + // This is the optimum logic, considering TX fee, client-side computation, + // RPC roundtrips and guaranteed idempotent. + // Sadly we can't do this atomically; + try { + const account = await connection.getAccountInfo(associatedAddress); + if (!account) { + // noinspection ExceptionCaughtLocallyJS + throw new Error(FAILED_TO_FIND_ACCOUNT); + } + } catch (err: any) { + // INVALID_ACCOUNT_OWNER can be possible if the associatedAddress has + // already been received some lamports (= became system accounts). + // Assuming program derived addressing is safe, this is the only case + // for the INVALID_ACCOUNT_OWNER in this code-path + if (err.message === FAILED_TO_FIND_ACCOUNT || err.message === INVALID_ACCOUNT_OWNER) { + instructions.push( + Token.createAssociatedTokenAccountInstruction( + ASSOCIATED_TOKEN_PROGRAM_ID, + TOKEN_PROGRAM_ID, + mint, + associatedAddress, + owner, + owner, + ), + ); + } else { + throw err; + } + console.warn(err); + } + + return associatedAddress; +} + +export async function getTokenAccount( + connection: Connection, + tokenAccountAddress: PublicKey, + expectedTokenMint: PublicKey, +): Promise { + try { + const account = await connection.getAccountInfo(tokenAccountAddress); + if (!account) { + // noinspection ExceptionCaughtLocallyJS + throw new Error(`Invalid account ${tokenAccountAddress.toBase58()}`); + } + const tokenAccount = AccountLayout.decode(account.data) as AccountInfo; + if (tokenAccount.mint?.toBase58() != expectedTokenMint.toBase58()) { + // noinspection ExceptionCaughtLocallyJS + throw new Error( + `Invalid token mint for ${tokenAccountAddress}, expected mint is ${expectedTokenMint}`, + ); + } + return tokenAccount; + } catch (error) { + console.log(error); + } +} diff --git a/clients/js-legacy/test/equal.ts b/clients/js-legacy/test/equal.ts new file mode 100644 index 00000000..14825d4a --- /dev/null +++ b/clients/js-legacy/test/equal.ts @@ -0,0 +1,55 @@ +import { Connection, PublicKey } from "@solana/web3.js"; +import BN from "bn.js"; +import { StakePoolAccount, getStakePoolAccounts } from "../src"; + +export function isStakePoolAccount(account: any): account is StakePoolAccount { + return (account !== undefined) && + (account.account !== undefined) && + (account.account.data !== undefined) && + ('manager' in account.account.data); +} + +export async function getFirstStakePoolAccount( + connection: Connection, + stakePoolProgramAddress: PublicKey, +): Promise { + const accounts = await getStakePoolAccounts(connection, stakePoolProgramAddress); + + return accounts! + .filter(account => isStakePoolAccount(account)) + .pop() as StakePoolAccount; +} + +/** + * Helper function to do deep equality check because BNs are not equal. + * TODO: write this function recursively. For now, sufficient. + */ +export function deepStrictEqualBN(a: any, b: any) { + for (const key in a) { + if (b[key] instanceof BN) { + expect(b[key].toString()).toEqual(a[key].toString()); + } else { + if (a[key] instanceof Object) { + for (const subkey in a[key]) { + if (a[key][subkey] instanceof Object) { + if (a[key][subkey] instanceof BN) { + expect(b[key][subkey].toString()).toEqual(a[key][subkey].toString()); + } else { + for (const subsubkey in a[key][subkey]) { + if (a[key][subkey][subsubkey] instanceof BN) { + expect(b[key][subkey][subsubkey].toString()).toEqual(a[key][subkey][subsubkey].toString()); + } else { + expect(b[key][subkey][subsubkey]).toStrictEqual(a[key][subkey][subsubkey]); + } + } + } + } else { + expect(b[key][subkey]).toStrictEqual(a[key][subkey]); + } + } + } else { + expect(b[key]).toStrictEqual(a[key]); + } + } + } +} diff --git a/clients/js-legacy/test/instructions.test.ts b/clients/js-legacy/test/instructions.test.ts new file mode 100644 index 00000000..40cd39a4 --- /dev/null +++ b/clients/js-legacy/test/instructions.test.ts @@ -0,0 +1,255 @@ +import { + PublicKey, + Connection, + Keypair, + SystemProgram, AccountInfo, LAMPORTS_PER_SOL +} from '@solana/web3.js'; +import { StakePoolLayout } from '../src/layouts'; +import { STAKE_POOL_PROGRAM_ID } from '../src/constants'; +import { decodeData } from '../src/copied-from-solana-web3/instruction'; +import { + STAKE_POOL_INSTRUCTION_LAYOUTS, + DepositSolParams, + StakePoolInstruction, + depositSol, + withdrawSol, + withdrawStake +} from "../src"; + +import { mockTokenAccount, mockValidatorList, stakePoolMock } from "./mocks"; + +describe('StakePoolProgram', () => { + + const connection = new Connection('http://127.0.0.1:8899'); + + connection.getMinimumBalanceForRentExemption = jest.fn(async () => 10000); + + const stakePoolPubkey = new PublicKey( + 'SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy', + ); + + const data = Buffer.alloc(1024); + StakePoolLayout.encode(stakePoolMock, data) + + const stakePoolAccount = >{ + executable: true, + owner: stakePoolPubkey, + lamports: 99999, + data, + }; + + it('StakePoolInstruction.depositSol', () => { + + const payload: DepositSolParams = { + stakePool: stakePoolPubkey, + withdrawAuthority: Keypair.generate().publicKey, + reserveStake: Keypair.generate().publicKey, + fundingAccount: Keypair.generate().publicKey, + destinationPoolAccount: Keypair.generate().publicKey, + managerFeeAccount: Keypair.generate().publicKey, + referralPoolAccount: Keypair.generate().publicKey, + poolMint: Keypair.generate().publicKey, + lamports: 99999, + }; + + const instruction = StakePoolInstruction.depositSol(payload); + + expect(instruction.keys).toHaveLength(10); + expect(instruction.keys[0].pubkey.toBase58()).toEqual(payload.stakePool.toBase58()); + expect(instruction.keys[1].pubkey.toBase58()).toEqual(payload.withdrawAuthority.toBase58()); + expect(instruction.keys[3].pubkey.toBase58()).toEqual(payload.fundingAccount.toBase58()); + expect(instruction.keys[4].pubkey.toBase58()).toEqual(payload.destinationPoolAccount.toBase58()); + expect(instruction.keys[5].pubkey.toBase58()).toEqual(payload.managerFeeAccount.toBase58()); + expect(instruction.keys[6].pubkey.toBase58()).toEqual(payload.referralPoolAccount.toBase58()); + expect(instruction.keys[8].pubkey.toBase58()).toEqual(SystemProgram.programId.toBase58()); + expect(instruction.keys[9].pubkey.toBase58()).toEqual(STAKE_POOL_PROGRAM_ID.toBase58()); + + const decodedData = decodeData(STAKE_POOL_INSTRUCTION_LAYOUTS.DepositSol, instruction.data); + + expect(decodedData.instruction).toEqual(STAKE_POOL_INSTRUCTION_LAYOUTS.DepositSol.index); + expect(decodedData.lamports).toEqual(payload.lamports); + + payload.depositAuthority = Keypair.generate().publicKey; + + const instruction2 = StakePoolInstruction.depositSol(payload); + + expect(instruction2.keys).toHaveLength(11); + expect(instruction2.keys[10].pubkey.toBase58()).toEqual(payload.depositAuthority.toBase58()); + + }); + + describe('depositSol', () => { + const from = Keypair.generate().publicKey; + const balance = 10000; + + connection.getBalance = jest.fn(async () => balance); + + connection.getAccountInfo = jest.fn(async (pubKey) => { + if (pubKey == stakePoolPubkey) { + return stakePoolAccount + } + return >{ + executable: true, + owner: from, + lamports: balance, + data: null, + } + }); + + it.only('should throw an error with invalid balance', async () => { + await expect( + depositSol(connection, stakePoolPubkey, from, balance + 1) + ).rejects.toThrow(Error('Not enough SOL to deposit into pool. Maximum deposit amount is 0.00001 SOL.')); + }); + + it.only('should throw an error with invalid account', async () => { + connection.getAccountInfo = jest.fn(async () => null); + await expect( + depositSol(connection, stakePoolPubkey, from, balance) + ).rejects.toThrow(Error('Invalid account')); + }); + + it.only('should call successfully', async () => { + connection.getAccountInfo = jest.fn(async (pubKey) => { + if (pubKey == stakePoolPubkey) { + return stakePoolAccount + } + return >{ + executable: true, + owner: from, + lamports: balance, + data: null, + } + }); + + const res = await depositSol(connection, stakePoolPubkey, from, balance) + + expect((connection.getAccountInfo as jest.Mock).mock.calls.length).toBe(2); + expect(res.instructions).toHaveLength(2); + expect(res.signers).toHaveLength(1); + }); + + }); + + describe('withdrawSol', () => { + const tokenOwner = new PublicKey(0); + const solReceiver = new PublicKey(1); + + it.only('should throw an error with invalid stake pool account', async () => { + connection.getAccountInfo = jest.fn(async () => null); + await expect( + withdrawSol(connection, stakePoolPubkey, tokenOwner, solReceiver, 1) + ).rejects.toThrowError('Invalid account'); + }); + + it.only('should throw an error with invalid token account', async () => { + connection.getAccountInfo = jest.fn(async (pubKey: PublicKey) => { + if (pubKey == stakePoolPubkey) { + return stakePoolAccount + } + if (pubKey.toBase58() == '9q2rZU5RujvyD9dmYKhzJAZfG4aGBbvQ8rWY52jCNBai') { + return null + } + return null; + }); + + await expect( + withdrawSol(connection, stakePoolPubkey, tokenOwner, solReceiver, 1) + ).rejects.toThrow(Error('Invalid token account')); + }); + + it.only('should throw an error with invalid token account balance', async () => { + connection.getAccountInfo = jest.fn(async (pubKey: PublicKey) => { + if (pubKey == stakePoolPubkey) { + return stakePoolAccount + } + if (pubKey.toBase58() == 'GQkqTamwqjaNDfsbNm7r3aXPJ4oTSqKC3d5t2PF9Smqd') { + return mockTokenAccount(0); + } + return null; + }); + + await expect( + withdrawSol(connection, stakePoolPubkey, tokenOwner, solReceiver, 1) + ).rejects.toThrow(Error('Not enough token balance to withdraw 1 pool tokens.\n Maximum withdraw amount is 0 pool tokens.')); + }); + + it.only('should call successfully', async () => { + connection.getAccountInfo = jest.fn(async (pubKey: PublicKey) => { + if (pubKey == stakePoolPubkey) { + return stakePoolAccount + } + if (pubKey.toBase58() == 'GQkqTamwqjaNDfsbNm7r3aXPJ4oTSqKC3d5t2PF9Smqd') { + return mockTokenAccount(LAMPORTS_PER_SOL); + } + return null; + }); + const res = await withdrawSol(connection, stakePoolPubkey, tokenOwner, solReceiver, 1) + + expect((connection.getAccountInfo as jest.Mock).mock.calls.length).toBe(2); + expect(res.instructions).toHaveLength(2); + expect(res.signers).toHaveLength(1); + }); + + }) + + describe('withdrawStake', () => { + + const tokenOwner = new PublicKey(0); + + it.only('should throw an error with invalid token account', async () => { + connection.getAccountInfo = jest.fn(async (pubKey: PublicKey) => { + if (pubKey == stakePoolPubkey) { + return stakePoolAccount + } + return null; + }); + + await expect( + withdrawStake(connection, stakePoolPubkey, tokenOwner, 1) + ).rejects.toThrow(Error('Invalid token account')); + }); + + it.only('should throw an error with invalid token account balance', async () => { + connection.getAccountInfo = jest.fn(async (pubKey: PublicKey) => { + if (pubKey == stakePoolPubkey) { + return stakePoolAccount + } + if (pubKey.toBase58() == 'GQkqTamwqjaNDfsbNm7r3aXPJ4oTSqKC3d5t2PF9Smqd') { + return mockTokenAccount(0); + } + return null; + }); + + await expect( + withdrawStake(connection, stakePoolPubkey, tokenOwner, 1) + ).rejects.toThrow(Error('Not enough token balance to withdraw 1 pool tokens.\n' + + ' Maximum withdraw amount is 0 pool tokens.')); + }); + + it.only('should call successfully', async () => { + connection.getAccountInfo = jest.fn(async (pubKey: PublicKey) => { + if (pubKey == stakePoolPubkey) { + return stakePoolAccount + } + if (pubKey.toBase58() == 'GQkqTamwqjaNDfsbNm7r3aXPJ4oTSqKC3d5t2PF9Smqd') { + return mockTokenAccount(LAMPORTS_PER_SOL * 2); + } + if (pubKey.toBase58() == stakePoolMock.validatorList.toBase58()) { + return mockValidatorList(); + } + return null; + }); + + const res = await withdrawStake(connection, stakePoolPubkey, tokenOwner, 1); + + expect((connection.getAccountInfo as jest.Mock).mock.calls.length).toBe(4); + expect(res.instructions).toHaveLength(3); + expect(res.signers).toHaveLength(2); + expect(res.stakeReceiver).toEqual(undefined); + expect(res.totalRentFreeBalances).toEqual(10000); + }); + + }); + +}); diff --git a/clients/js-legacy/test/integration.test.ts b/clients/js-legacy/test/integration.test.ts new file mode 100644 index 00000000..9c39ec63 --- /dev/null +++ b/clients/js-legacy/test/integration.test.ts @@ -0,0 +1,16 @@ +/** + * TODO: https://github.com/solana-labs/solana-program-library/pull/2604 + * @joncinque + * These tests could be extremely flaky because of the devnet connection, so we could probably just remove them. + * It doesn't need to be done in this PR, but eventually we should have tests that create a stake pool / deposit / withdraw, + * all only accessing a local test validator. Same as with the token and token-swap js tests. + */ + +// @ts-ignore +describe('Integration test', () => { + + it('should be implemented', () => { + + }) + +}); diff --git a/clients/js-legacy/test/layouts.test.ts b/clients/js-legacy/test/layouts.test.ts new file mode 100644 index 00000000..a3f64feb --- /dev/null +++ b/clients/js-legacy/test/layouts.test.ts @@ -0,0 +1,40 @@ +import { + StakePoolLayout, + ValidatorListLayout, + ValidatorList, +} from '../src/layouts'; +import { deepStrictEqualBN } from "./equal"; +import { stakePoolMock, validatorListMock } from "./mocks"; + +describe('layouts', () => { + + describe('StakePoolAccount', () => { + it('should successfully decode StakePoolAccount data', () => { + const encodedData = Buffer.alloc(1024); + StakePoolLayout.encode(stakePoolMock, encodedData); + const decodedData = StakePoolLayout.decode(encodedData); + deepStrictEqualBN(decodedData, stakePoolMock); + }); + }); + + describe('ValidatorListAccount', () => { + it('should successfully decode ValidatorListAccount account data', () => { + const expectedData: ValidatorList = { + accountType: 0, + maxValidators: 10, + validators: [], + }; + const encodedData = Buffer.alloc(64); + ValidatorListLayout.encode(expectedData, encodedData); + const decodedData = ValidatorListLayout.decode(encodedData); + expect(decodedData).toEqual(expectedData); + }); + + it('should successfully decode ValidatorListAccount with nonempty ValidatorInfo', () => { + const encodedData = Buffer.alloc(1024); + ValidatorListLayout.encode(validatorListMock, encodedData); + const decodedData = ValidatorListLayout.decode(encodedData); + deepStrictEqualBN(decodedData, validatorListMock); + }); + }); +}); diff --git a/clients/js-legacy/test/mocks.ts b/clients/js-legacy/test/mocks.ts new file mode 100644 index 00000000..250d5c6c --- /dev/null +++ b/clients/js-legacy/test/mocks.ts @@ -0,0 +1,150 @@ +import { AccountInfo, LAMPORTS_PER_SOL, PublicKey } from "@solana/web3.js"; +import BN from "bn.js"; +import { ValidatorStakeInfo } from "../src"; +import { ValidatorStakeInfoStatus, AccountLayout, ValidatorListLayout } from "../src/layouts"; + +export const stakePoolMock = { + accountType: 1, + manager: new PublicKey(11), + staker: new PublicKey(12), + stakeDepositAuthority: new PublicKey(13), + stakeWithdrawBumpSeed: 255, + validatorList: new PublicKey(14), + reserveStake: new PublicKey(15), + poolMint: new PublicKey(16), + managerFeeAccount: new PublicKey(17), + tokenProgramId: new PublicKey(18), + totalLamports: new BN(LAMPORTS_PER_SOL * 999), + poolTokenSupply: new BN(LAMPORTS_PER_SOL * 100), + lastUpdateEpoch: new BN('7c', 'hex'), + lockup: { + unixTimestamp: new BN(Date.now()), + epoch: new BN(1), + custodian: new PublicKey(0), + }, + epochFee: { + denominator: new BN(0), + numerator: new BN(0), + }, + nextEpochFee: { + denominator: new BN(0), + numerator: new BN(0), + }, + preferredDepositValidatorVoteAddress: new PublicKey(1), + preferredWithdrawValidatorVoteAddress: new PublicKey(2), + stakeDepositFee: { + denominator: new BN(0), + numerator: new BN(0), + }, + stakeWithdrawalFee: { + denominator: new BN(0), + numerator: new BN(0), + }, + nextWithdrawalFee: { + denominator: new BN(0), + numerator: new BN(0), + }, + stakeReferralFee: 0, + solDepositAuthority: new PublicKey(0), + solDepositFee: { + denominator: new BN(0), + numerator: new BN(0), + }, + solReferralFee: 0, + solWithdrawAuthority: new PublicKey(0), + solWithdrawalFee: { + denominator: new BN(0), + numerator: new BN(0), + }, + nextSolWithdrawalFee: { + denominator: new BN(0), + numerator: new BN(0), + }, + lastEpochPoolTokenSupply: new BN(0), + lastEpochTotalLamports: new BN(0), +}; + +export const validatorListMock = { + accountType: 0, + maxValidators: 100, + validators: [ + { + status: ValidatorStakeInfoStatus.ReadyForRemoval, + voteAccountAddress: new PublicKey( + new BN( + 'a9946a889af14fd3c9b33d5df309489d9699271a6b09ff3190fcb41cf21a2f8c', + 'hex', + ), + ), + lastUpdateEpoch: new BN('c3', 'hex'), + activeStakeLamports: new BN(123), + transientStakeLamports: new BN(999), + transientSeedSuffixStart: new BN(999), + transientSeedSuffixEnd: new BN(999), + }, + { + status: ValidatorStakeInfoStatus.Active, + voteAccountAddress: new PublicKey( + new BN( + '3796d40645ee07e3c64117e3f73430471d4c40465f696ebc9b034c1fc06a9f7d', + 'hex', + ), + ), + lastUpdateEpoch: new BN('c3', 'hex'), + activeStakeLamports: new BN(LAMPORTS_PER_SOL * 100), + transientStakeLamports: new BN(22), + transientSeedSuffixStart: new BN(0), + transientSeedSuffixEnd: new BN(0), + }, + { + status: ValidatorStakeInfoStatus.Active, + voteAccountAddress: new PublicKey( + new BN( + 'e4e37d6f2e80c0bb0f3da8a06304e57be5cda6efa2825b86780aa320d9784cf8', + 'hex', + ), + ), + lastUpdateEpoch: new BN('c3', 'hex'), + activeStakeLamports: new BN(0), + transientStakeLamports: new BN(0), + transientSeedSuffixStart: new BN('a', 'hex'), + transientSeedSuffixEnd: new BN('a', 'hex'), + }, + ], +} + +export function mockTokenAccount(amount = 0) { + const data = Buffer.alloc(1024); + AccountLayout.encode({ + state: 0, + mint: stakePoolMock.poolMint, + owner: new PublicKey(0), + amount: new BN(amount), + // address: new PublicKey(0), + // delegate: null, + // delegatedAmount: new BN(0), + // isInitialized: true, + // isFrozen: false, + // isNative: false, + // rentExemptReserve: null, + // closeAuthority: null, + }, data) + + return >{ + executable: true, + owner: new PublicKey(0), + lamports: amount, + data, + } +} + +export function mockValidatorList() { + const data = Buffer.alloc(1024); + ValidatorListLayout.encode(validatorListMock, data) + return >{ + executable: true, + owner: new PublicKey(0), + lamports: 0, + data, + } +} diff --git a/clients/js-legacy/tsconfig.json b/clients/js-legacy/tsconfig.json index 39f1d962..1eaf4071 100644 --- a/clients/js-legacy/tsconfig.json +++ b/clients/js-legacy/tsconfig.json @@ -1,14 +1,23 @@ { - "compilerOptions": { - "target": "ES6", - "module": "ES6", - "esModuleInterop": true, - "moduleResolution": "Node", - "outDir": "dist", - "declaration": true, - "declarationMap": true, - }, - "include": [ - "src/**/*.ts" - ] -} \ No newline at end of file + "compilerOptions": { + "target": "es2019", + "allowJs": true, + "declaration": true, + "declarationDir": "declarations", + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "baseUrl": "src", + "noFallthroughCasesInSwitch": true, + "noImplicitReturns": true + }, + "include": [ + "test", + "src" + ] +} From 3a2bd3f3e9daadd9e6b6d2b95ab6515cd1f3bda4 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 28 Dec 2021 23:02:47 -0500 Subject: [PATCH 0214/1076] Update SDK to 1.9.2, fix warnings (#2674) * Update SDK to 1.9.2, fix warnings * Upgrade honggfuzz * Use `get_latest_blockhash` correctly --- clients/cli/Cargo.toml | 18 +++++----- clients/cli/src/main.rs | 66 +++++++++++++++++++++++++++---------- program/Cargo.toml | 8 ++--- program/tests/initialize.rs | 4 +-- program/tests/vsa_add.rs | 2 +- program/tests/vsa_remove.rs | 2 +- program/tests/withdraw.rs | 2 +- 7 files changed, 66 insertions(+), 36 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 699f3cd7..265523db 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -14,15 +14,15 @@ clap = "2.33.3" serde = "1.0.130" serde_derive = "1.0.130" serde_json = "1.0.68" -solana-account-decoder = "=1.8.1" -solana-clap-utils = "=1.8.1" -solana-cli-config = "=1.8.1" -solana-cli-output = "1.8.1" -solana-client = "=1.8.1" -solana-logger = "=1.8.1" -solana-program = "=1.8.1" -solana-remote-wallet = "=1.8.1" -solana-sdk = "=1.8.1" +solana-account-decoder = "=1.9.2" +solana-clap-utils = "=1.9.2" +solana-cli-config = "=1.9.2" +solana-cli-output = "1.9.2" +solana-client = "=1.9.2" +solana-logger = "=1.9.2" +solana-program = "=1.9.2" +solana-remote-wallet = "=1.9.2" +solana-sdk = "=1.9.2" spl-associated-token-account = { version = "1.0", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "0.6", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "3.2", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 8aa67df0..cde16a1c 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -144,15 +144,19 @@ fn checked_transaction_with_signers( instructions: &[Instruction], signers: &T, ) -> Result { - let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + let recent_blockhash = config.rpc_client.get_latest_blockhash()?; let transaction = Transaction::new_signed_with_payer( instructions, Some(&config.fee_payer.pubkey()), signers, recent_blockhash, ); - - check_fee_payer_balance(config, fee_calculator.calculate_fee(transaction.message()))?; + check_fee_payer_balance( + config, + config + .rpc_client + .get_fee_for_message(transaction.message())?, + )?; Ok(transaction) } @@ -331,12 +335,16 @@ fn command_create_pool( Some(&config.fee_payer.pubkey()), ); - let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + let recent_blockhash = config.rpc_client.get_latest_blockhash()?; check_fee_payer_balance( config, total_rent_free_balances - + fee_calculator.calculate_fee(setup_transaction.message()) - + fee_calculator.calculate_fee(initialize_transaction.message()), + + config + .rpc_client + .get_fee_for_message(setup_transaction.message())? + + config + .rpc_client + .get_fee_for_message(initialize_transaction.message())?, )?; let mut setup_signers = vec![config.fee_payer.as_ref(), &mint_keypair, &reserve_keypair]; unique_signers!(setup_signers); @@ -723,10 +731,13 @@ fn command_deposit_stake( let mut transaction = Transaction::new_with_payer(&instructions, Some(&config.fee_payer.pubkey())); - let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + let recent_blockhash = config.rpc_client.get_latest_blockhash()?; check_fee_payer_balance( config, - total_rent_free_balances + fee_calculator.calculate_fee(transaction.message()), + total_rent_free_balances + + config + .rpc_client + .get_fee_for_message(transaction.message())?, )?; unique_signers!(signers); transaction.sign(&signers, recent_blockhash); @@ -761,7 +772,7 @@ fn command_deposit_all_stake( &mut total_rent_free_balances, )); if !create_token_account_instructions.is_empty() { - let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + let recent_blockhash = config.rpc_client.get_latest_blockhash()?; let transaction = Transaction::new_signed_with_payer( &create_token_account_instructions, Some(&config.fee_payer.pubkey()), @@ -770,7 +781,10 @@ fn command_deposit_all_stake( ); check_fee_payer_balance( config, - total_rent_free_balances + fee_calculator.calculate_fee(transaction.message()), + total_rent_free_balances + + config + .rpc_client + .get_fee_for_message(transaction.message())?, )?; send_transaction(config, transaction)?; } @@ -859,14 +873,19 @@ fn command_deposit_all_stake( ) }; - let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + let recent_blockhash = config.rpc_client.get_latest_blockhash()?; let transaction = Transaction::new_signed_with_payer( &instructions, Some(&config.fee_payer.pubkey()), &signers, recent_blockhash, ); - check_fee_payer_balance(config, fee_calculator.calculate_fee(transaction.message()))?; + check_fee_payer_balance( + config, + config + .rpc_client + .get_fee_for_message(transaction.message())?, + )?; send_transaction(config, transaction)?; } @@ -985,10 +1004,13 @@ fn command_deposit_sol( let mut transaction = Transaction::new_with_payer(&instructions, Some(&config.fee_payer.pubkey())); - let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + let recent_blockhash = config.rpc_client.get_latest_blockhash()?; check_fee_payer_balance( config, - total_rent_free_balances + fee_calculator.calculate_fee(transaction.message()), + total_rent_free_balances + + config + .rpc_client + .get_fee_for_message(transaction.message())?, )?; unique_signers!(signers); transaction.sign(&signers, recent_blockhash); @@ -1443,10 +1465,13 @@ fn command_withdraw_stake( let mut transaction = Transaction::new_with_payer(&instructions, Some(&config.fee_payer.pubkey())); - let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + let recent_blockhash = config.rpc_client.get_latest_blockhash()?; check_fee_payer_balance( config, - total_rent_free_balances + fee_calculator.calculate_fee(transaction.message()), + total_rent_free_balances + + config + .rpc_client + .get_fee_for_message(transaction.message())?, )?; for new_stake_keypair in &new_stake_keypairs { signers.push(new_stake_keypair); @@ -1565,8 +1590,13 @@ fn command_withdraw_sol( let mut transaction = Transaction::new_with_payer(&instructions, Some(&config.fee_payer.pubkey())); - let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; - check_fee_payer_balance(config, fee_calculator.calculate_fee(transaction.message()))?; + let recent_blockhash = config.rpc_client.get_latest_blockhash()?; + check_fee_payer_balance( + config, + config + .rpc_client + .get_fee_for_message(transaction.message())?, + )?; unique_signers!(signers); transaction.sign(&signers, recent_blockhash); send_transaction(config, transaction)?; diff --git a/program/Cargo.toml b/program/Cargo.toml index 67cb93f3..795085ef 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -19,7 +19,7 @@ num-traits = "0.2" num_enum = "0.5.4" serde = "1.0.130" serde_derive = "1.0.103" -solana-program = "1.8.1" +solana-program = "1.9.2" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-token = { version = "3.2", path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" @@ -27,9 +27,9 @@ bincode = "1.3.1" [dev-dependencies] proptest = "1.0" -solana-program-test = "1.8.1" -solana-sdk = "1.8.1" -solana-vote-program = "1.8.1" +solana-program-test = "1.9.2" +solana-sdk = "1.9.2" +solana-vote-program = "1.9.2" [lib] crate-type = ["cdylib", "lib"] diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index d65937bf..85f2142a 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -97,7 +97,7 @@ async fn fail_double_initialize() { .await .unwrap(); - let latest_blockhash = banks_client.get_recent_blockhash().await.unwrap(); + let latest_blockhash = banks_client.get_latest_blockhash().await.unwrap(); let mut second_stake_pool_accounts = StakePoolAccounts::new(); second_stake_pool_accounts.stake_pool = stake_pool_accounts.stake_pool; @@ -128,7 +128,7 @@ async fn fail_with_already_initialized_validator_list() { .await .unwrap(); - let latest_blockhash = banks_client.get_recent_blockhash().await.unwrap(); + let latest_blockhash = banks_client.get_latest_blockhash().await.unwrap(); let mut second_stake_pool_accounts = StakePoolAccounts::new(); second_stake_pool_accounts.validator_list = stake_pool_accounts.validator_list; diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index 4f108786..48d27ea6 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -172,7 +172,7 @@ async fn fail_double_add() { ) .await; - let latest_blockhash = banks_client.get_recent_blockhash().await.unwrap(); + let latest_blockhash = banks_client.get_latest_blockhash().await.unwrap(); let transaction_error = stake_pool_accounts .add_validator_to_pool( diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 83e35d46..a0dde372 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -302,7 +302,7 @@ async fn fail_double_remove() { .await; assert!(error.is_none()); - let _latest_blockhash = context.banks_client.get_recent_blockhash().await.unwrap(); + let _latest_blockhash = context.banks_client.get_latest_blockhash().await.unwrap(); let destination_stake = Keypair::new(); let error = stake_pool_accounts diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index c830e37e..1b120599 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -595,7 +595,7 @@ async fn fail_double_withdraw_to_the_same_account() { .await; assert!(error.is_none()); - let latest_blockhash = banks_client.get_recent_blockhash().await.unwrap(); + let latest_blockhash = banks_client.get_latest_blockhash().await.unwrap(); // Delegate tokens for burning delegate_tokens( From 6bccec322d14be295764313205f79700007c5bce Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 30 Dec 2021 12:55:09 -0500 Subject: [PATCH 0215/1076] stake-pool-js: Prepare package for release (#2681) * stake-pool-js: Prepare package for release * Upgrade node version for new npm * Regenerate package-lock.json * Update README, fix build to remove test files --- clients/js-legacy/.eslintignore | 1 + clients/js-legacy/.eslintrc.js | 31 + clients/js-legacy/.prettierrc | 2 +- clients/js-legacy/README.md | 11 +- clients/js-legacy/package-lock.json | 13882 ++++++++++++++-- clients/js-legacy/package.json | 30 +- clients/js-legacy/src/buffer-layout.d.ts | 16 + clients/js-legacy/src/constants.ts | 10 +- .../src/copied-from-solana-web3/README.md | 3 - .../copied-from-solana-web3/instruction.ts | 14 +- .../src/copied-from-solana-web3/layout.ts | 92 - clients/js-legacy/src/index.ts | 75 +- clients/js-legacy/src/instructions.ts | 146 +- clients/js-legacy/src/layouts.ts | 19 +- clients/js-legacy/src/utils/index.ts | 8 +- clients/js-legacy/src/utils/math.ts | 9 +- .../js-legacy/src/utils/program-address.ts | 6 +- clients/js-legacy/src/utils/stake.ts | 75 +- clients/js-legacy/src/utils/token.ts | 13 +- clients/js-legacy/test/equal.ts | 38 +- clients/js-legacy/test/instructions.test.ts | 188 +- clients/js-legacy/test/integration.test.ts | 16 - clients/js-legacy/test/layouts.test.ts | 5 +- clients/js-legacy/test/mocks.ts | 51 +- clients/js-legacy/tsconfig.json | 8 +- 25 files changed, 13123 insertions(+), 1626 deletions(-) create mode 100644 clients/js-legacy/.eslintignore create mode 100644 clients/js-legacy/.eslintrc.js create mode 100644 clients/js-legacy/src/buffer-layout.d.ts delete mode 100644 clients/js-legacy/src/copied-from-solana-web3/README.md delete mode 100644 clients/js-legacy/src/copied-from-solana-web3/layout.ts delete mode 100644 clients/js-legacy/test/integration.test.ts diff --git a/clients/js-legacy/.eslintignore b/clients/js-legacy/.eslintignore new file mode 100644 index 00000000..9b1c8b13 --- /dev/null +++ b/clients/js-legacy/.eslintignore @@ -0,0 +1 @@ +/dist diff --git a/clients/js-legacy/.eslintrc.js b/clients/js-legacy/.eslintrc.js new file mode 100644 index 00000000..317d0253 --- /dev/null +++ b/clients/js-legacy/.eslintrc.js @@ -0,0 +1,31 @@ +module.exports = { + "env": { + "es2021": true, + "node": true + }, + "extends": [ + "eslint:recommended", + "plugin:react/recommended", + "plugin:@typescript-eslint/recommended" + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaFeatures": { + "jsx": true + }, + "ecmaVersion": 13, + "sourceType": "module" + }, + "plugins": [ + "react", + "@typescript-eslint" + ], + "rules": { + "@typescript-eslint/no-explicit-any": "off" + }, + "settings": { + "react": { + "version": "detect" + } + } +}; diff --git a/clients/js-legacy/.prettierrc b/clients/js-legacy/.prettierrc index 25d0d320..583011bb 100644 --- a/clients/js-legacy/.prettierrc +++ b/clients/js-legacy/.prettierrc @@ -2,7 +2,7 @@ "arrowParens": "avoid", "bracketSpacing":false, "singleQuote": true, - "semi": false, + "semi": true, "tabWidth": 2, "trailingComma": "all" } diff --git a/clients/js-legacy/README.md b/clients/js-legacy/README.md index 42cb1a78..e9ca4911 100644 --- a/clients/js-legacy/README.md +++ b/clients/js-legacy/README.md @@ -13,7 +13,7 @@ npm install In the `js` folder: ``` -npm run compile +npm run build npm run lint node dist/index.js ``` @@ -21,13 +21,6 @@ node dist/index.js ## Test ``` -npm run compile +npm run build npm test ``` - -Sample output: - -``` -> stake-pool-js@0.0.1 test -``` - diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 6a555caa..5700d5bf 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1,38 +1,71 @@ { "name": "@solana/spl-stake-pool", - "version": "0.2.1", - "lockfileVersion": 1, + "version": "0.6.3", + "lockfileVersion": 2, "requires": true, - "dependencies": { - "@babel/code-frame": { + "packages": { + "": { + "name": "@solana/spl-stake-pool", + "version": "0.6.3", + "license": "ISC", + "dependencies": { + "@project-serum/borsh": "^0.2.2", + "@solana/buffer-layout": "^4.0.0", + "@solana/spl-token": "^0.1.8", + "@solana/web3.js": "^1.30.2", + "bn.js": "^5.2.0", + "buffer": "^6.0.3", + "process": "^0.11.10" + }, + "devDependencies": { + "@babel/preset-env": "^7.16.5", + "@babel/preset-typescript": "^7.16.5", + "@types/bn.js": "^5.1.0", + "@types/jest": "^27.0.3", + "@typescript-eslint/eslint-plugin": "^5.8.1", + "@typescript-eslint/parser": "^5.8.1", + "eslint": "^8.5.0", + "eslint-plugin-react": "^7.28.0", + "jest": "^27.3.1", + "prettier": "^2.2.1", + "typescript": "^4.5.4" + } + }, + "node_modules/@babel/code-frame": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz", "integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==", "dev": true, - "requires": { + "dependencies": { "@babel/highlight": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/compat-data": { + "node_modules/@babel/compat-data": { "version": "7.16.4", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.4.tgz", "integrity": "sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q==", - "dev": true + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, - "@babel/core": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.0.tgz", - "integrity": "sha512-mYZEvshBRHGsIAiyH5PzCFTCfbWfoYbO/jcSdXQSUQu1/pW0xDZAUP7KEc32heqWTAfAHhV9j1vH8Sav7l+JNQ==", + "node_modules/@babel/core": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.5.tgz", + "integrity": "sha512-wUcenlLzuWMZ9Zt8S0KmFwGlH6QKRh3vsm/dhDA3CHkiTA45YuG1XkHRcNRl73EFPXDp/d5kVOU0/y7x2w6OaQ==", "dev": true, - "requires": { + "dependencies": { "@babel/code-frame": "^7.16.0", - "@babel/generator": "^7.16.0", - "@babel/helper-compilation-targets": "^7.16.0", - "@babel/helper-module-transforms": "^7.16.0", - "@babel/helpers": "^7.16.0", - "@babel/parser": "^7.16.0", + "@babel/generator": "^7.16.5", + "@babel/helper-compilation-targets": "^7.16.3", + "@babel/helper-module-transforms": "^7.16.5", + "@babel/helpers": "^7.16.5", + "@babel/parser": "^7.16.5", "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.0", + "@babel/traverse": "^7.16.5", "@babel/types": "^7.16.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", @@ -41,71 +74,77 @@ "semver": "^6.3.0", "source-map": "^0.5.0" }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" } }, - "@babel/generator": { + "node_modules/@babel/generator": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.5.tgz", "integrity": "sha512-kIvCdjZqcdKqoDbVVdt5R99icaRtrtYhYK/xux5qiWCBmfdvEYMFZ68QCrpE5cbFM1JsuArUNs1ZkuKtTtUcZA==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.16.0", "jsesc": "^2.5.1", "source-map": "^0.5.0" }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-annotate-as-pure": { + "node_modules/@babel/helper-annotate-as-pure": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.0.tgz", "integrity": "sha512-ItmYF9vR4zA8cByDocY05o0LGUkp1zhbTQOH1NFyl5xXEqlTJQCEJjieriw+aFpxo16swMxUnUiKS7a/r4vtHg==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-builder-binary-assignment-operator-visitor": { + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.5.tgz", "integrity": "sha512-3JEA9G5dmmnIWdzaT9d0NmFRgYnWUThLsDaL7982H0XqqWr56lRrsmwheXFMjR+TMl7QMBb6mzy9kvgr1lRLUA==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-explode-assignable-expression": "^7.16.0", "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-compilation-targets": { + "node_modules/@babel/helper-compilation-targets": { "version": "7.16.3", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.3.tgz", "integrity": "sha512-vKsoSQAyBmxS35JUOOt+07cLc6Nk/2ljLIHwmq2/NM6hdioUaqEXq/S+nXvbvXbZkNDlWOymPanJGOc4CBjSJA==", "dev": true, - "requires": { + "dependencies": { "@babel/compat-data": "^7.16.0", "@babel/helper-validator-option": "^7.14.5", "browserslist": "^4.17.5", "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "@babel/helper-create-class-features-plugin": { + "node_modules/@babel/helper-create-class-features-plugin": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.5.tgz", "integrity": "sha512-NEohnYA7mkB8L5JhU7BLwcBdU3j83IziR9aseMueWGeAjblbul3zzb8UvJ3a1zuBiqCMObzCJHFqKIQE6hTVmg==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-annotate-as-pure": "^7.16.0", "@babel/helper-environment-visitor": "^7.16.5", "@babel/helper-function-name": "^7.16.0", @@ -113,24 +152,36 @@ "@babel/helper-optimise-call-expression": "^7.16.0", "@babel/helper-replace-supers": "^7.16.5", "@babel/helper-split-export-declaration": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "@babel/helper-create-regexp-features-plugin": { + "node_modules/@babel/helper-create-regexp-features-plugin": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.0.tgz", "integrity": "sha512-3DyG0zAFAZKcOp7aVr33ddwkxJ0Z0Jr5V99y3I690eYLpukJsJvAbzTy1ewoCqsML8SbIrjH14Jc/nSQ4TvNPA==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-annotate-as-pure": "^7.16.0", "regexpu-core": "^4.7.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "@babel/helper-define-polyfill-provider": { + "node_modules/@babel/helper-define-polyfill-provider": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.0.tgz", "integrity": "sha512-7hfT8lUljl/tM3h+izTX/pO3W3frz2ok6Pk+gzys8iJqDfZrZy2pXjRTZAvG2YmfHun1X4q8/UZRLatMfqc5Tg==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-compilation-targets": "^7.13.0", "@babel/helper-module-imports": "^7.12.13", "@babel/helper-plugin-utils": "^7.13.0", @@ -139,79 +190,103 @@ "lodash.debounce": "^4.0.8", "resolve": "^1.14.2", "semver": "^6.1.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0-0" } }, - "@babel/helper-environment-visitor": { + "node_modules/@babel/helper-environment-visitor": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.5.tgz", "integrity": "sha512-ODQyc5AnxmZWm/R2W7fzhamOk1ey8gSguo5SGvF0zcB3uUzRpTRmM/jmLSm9bDMyPlvbyJ+PwPEK0BWIoZ9wjg==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-explode-assignable-expression": { + "node_modules/@babel/helper-explode-assignable-expression": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.0.tgz", "integrity": "sha512-Hk2SLxC9ZbcOhLpg/yMznzJ11W++lg5GMbxt1ev6TXUiJB0N42KPC+7w8a+eWGuqDnUYuwStJoZHM7RgmIOaGQ==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-function-name": { + "node_modules/@babel/helper-function-name": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.0.tgz", "integrity": "sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-get-function-arity": "^7.16.0", "@babel/template": "^7.16.0", "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-get-function-arity": { + "node_modules/@babel/helper-get-function-arity": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.0.tgz", "integrity": "sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-hoist-variables": { + "node_modules/@babel/helper-hoist-variables": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.0.tgz", "integrity": "sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-member-expression-to-functions": { + "node_modules/@babel/helper-member-expression-to-functions": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.5.tgz", "integrity": "sha512-7fecSXq7ZrLE+TWshbGT+HyCLkxloWNhTbU2QM1NTI/tDqyf0oZiMcEfYtDuUDCo528EOlt39G1rftea4bRZIw==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-module-imports": { + "node_modules/@babel/helper-module-imports": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.0.tgz", "integrity": "sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-module-transforms": { + "node_modules/@babel/helper-module-transforms": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.5.tgz", "integrity": "sha512-CkvMxgV4ZyyioElFwcuWnDCcNIeyqTkCm9BxXZi73RR1ozqlpboqsbGUNvRTflgZtFbbJ1v5Emvm+lkjMYY/LQ==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-environment-visitor": "^7.16.5", "@babel/helper-module-imports": "^7.16.0", "@babel/helper-simple-access": "^7.16.0", @@ -220,559 +295,735 @@ "@babel/template": "^7.16.0", "@babel/traverse": "^7.16.5", "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-optimise-call-expression": { + "node_modules/@babel/helper-optimise-call-expression": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.0.tgz", "integrity": "sha512-SuI467Gi2V8fkofm2JPnZzB/SUuXoJA5zXe/xzyPP2M04686RzFKFHPK6HDVN6JvWBIEW8tt9hPR7fXdn2Lgpw==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-plugin-utils": { + "node_modules/@babel/helper-plugin-utils": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.5.tgz", "integrity": "sha512-59KHWHXxVA9K4HNF4sbHCf+eJeFe0Te/ZFGqBT4OjXhrwvA04sGfaEGsVTdsjoszq0YTP49RC9UKe5g8uN2RwQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, - "@babel/helper-remap-async-to-generator": { + "node_modules/@babel/helper-remap-async-to-generator": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.5.tgz", "integrity": "sha512-X+aAJldyxrOmN9v3FKp+Hu1NO69VWgYgDGq6YDykwRPzxs5f2N+X988CBXS7EQahDU+Vpet5QYMqLk+nsp+Qxw==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-annotate-as-pure": "^7.16.0", "@babel/helper-wrap-function": "^7.16.5", "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-replace-supers": { + "node_modules/@babel/helper-replace-supers": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.5.tgz", "integrity": "sha512-ao3seGVa/FZCMCCNDuBcqnBFSbdr8N2EW35mzojx3TwfIbdPmNK+JV6+2d5bR0Z71W5ocLnQp9en/cTF7pBJiQ==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-environment-visitor": "^7.16.5", "@babel/helper-member-expression-to-functions": "^7.16.5", "@babel/helper-optimise-call-expression": "^7.16.0", "@babel/traverse": "^7.16.5", "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-simple-access": { + "node_modules/@babel/helper-simple-access": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.0.tgz", "integrity": "sha512-o1rjBT/gppAqKsYfUdfHq5Rk03lMQrkPHG1OWzHWpLgVXRH4HnMM9Et9CVdIqwkCQlobnGHEJMsgWP/jE1zUiw==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-skip-transparent-expression-wrappers": { + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz", "integrity": "sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-split-export-declaration": { + "node_modules/@babel/helper-split-export-declaration": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz", "integrity": "sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-validator-identifier": { + "node_modules/@babel/helper-validator-identifier": { "version": "7.15.7", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", - "dev": true + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, - "@babel/helper-validator-option": { + "node_modules/@babel/helper-validator-option": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", - "dev": true + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, - "@babel/helper-wrap-function": { + "node_modules/@babel/helper-wrap-function": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.16.5.tgz", "integrity": "sha512-2J2pmLBqUqVdJw78U0KPNdeE2qeuIyKoG4mKV7wAq3mc4jJG282UgjZw4ZYDnqiWQuS3Y3IYdF/AQ6CpyBV3VA==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-function-name": "^7.16.0", "@babel/template": "^7.16.0", "@babel/traverse": "^7.16.5", "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helpers": { - "version": "7.16.3", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.3.tgz", - "integrity": "sha512-Xn8IhDlBPhvYTvgewPKawhADichOsbkZuzN7qz2BusOM0brChsyXMDJvldWaYMMUNiCQdQzNEioXTp3sC8Nt8w==", + "node_modules/@babel/helpers": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.5.tgz", + "integrity": "sha512-TLgi6Lh71vvMZGEkFuIxzaPsyeYCHQ5jJOOX1f0xXn0uciFuE8cEk0wyBquMcCxBXZ5BJhE2aUB7pnWTD150Tw==", "dev": true, - "requires": { + "dependencies": { "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.3", + "@babel/traverse": "^7.16.5", "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/highlight": { + "node_modules/@babel/highlight": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.0.tgz", "integrity": "sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-validator-identifier": "^7.15.7", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "engines": { + "node": ">=6.9.0" } }, - "@babel/parser": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.5.tgz", - "integrity": "sha512-+Ce7T5iPNWzfu9C1aB5tN3Lyafs5xb3Ic7vBWyZL2KXT3QSdD1dD3CvgOzPmQKoNNRt6uauc0XwNJTQtXC2/Mw==", - "dev": true + "node_modules/@babel/parser": { + "version": "7.16.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.6.tgz", + "integrity": "sha512-Gr86ujcNuPDnNOY8mi383Hvi8IYrJVJYuf3XcuBM/Dgd+bINn/7tHqsj+tKkoreMbmGsFLsltI/JJd8fOFWGDQ==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } }, - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { "version": "7.16.2", "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.2.tgz", "integrity": "sha512-h37CvpLSf8gb2lIJ2CgC3t+EjFbi0t8qS7LCS1xcJIlEXE4czlofwaW7W1HA8zpgOCzI9C1nmoqNR1zWkk0pQg==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.0.tgz", "integrity": "sha512-4tcFwwicpWTrpl9qjf7UsoosaArgImF85AxqCRZlgc3IQDvkUHjJpruXAL58Wmj+T6fypWTC/BakfEkwIL/pwA==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.14.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", "@babel/plugin-proposal-optional-chaining": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" } }, - "@babel/plugin-proposal-async-generator-functions": { + "node_modules/@babel/plugin-proposal-async-generator-functions": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.5.tgz", "integrity": "sha512-C/FX+3HNLV6sz7AqbTQqEo1L9/kfrKjxcVtgyBCmvIgOjvuBVUWooDoi7trsLxOzCEo5FccjRvKHkfDsJFZlfA==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.16.5", "@babel/helper-remap-async-to-generator": "^7.16.5", "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-class-properties": { + "node_modules/@babel/plugin-proposal-class-properties": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.5.tgz", "integrity": "sha512-pJD3HjgRv83s5dv1sTnDbZOaTjghKEz8KUn1Kbh2eAIRhGuyQ1XSeI4xVXU3UlIEVA3DAyIdxqT1eRn7Wcn55A==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-create-class-features-plugin": "^7.16.5", "@babel/helper-plugin-utils": "^7.16.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-class-static-block": { + "node_modules/@babel/plugin-proposal-class-static-block": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.16.5.tgz", "integrity": "sha512-EEFzuLZcm/rNJ8Q5krK+FRKdVkd6FjfzT9tuSZql9sQn64K0hHA2KLJ0DqVot9/iV6+SsuadC5yI39zWnm+nmQ==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-create-class-features-plugin": "^7.16.5", "@babel/helper-plugin-utils": "^7.16.5", "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" } }, - "@babel/plugin-proposal-dynamic-import": { + "node_modules/@babel/plugin-proposal-dynamic-import": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.5.tgz", "integrity": "sha512-P05/SJZTTvHz79LNYTF8ff5xXge0kk5sIIWAypcWgX4BTRUgyHc8wRxJ/Hk+mU0KXldgOOslKaeqnhthcDJCJQ==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.16.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-export-namespace-from": { + "node_modules/@babel/plugin-proposal-export-namespace-from": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.5.tgz", "integrity": "sha512-i+sltzEShH1vsVydvNaTRsgvq2vZsfyrd7K7vPLUU/KgS0D5yZMe6uipM0+izminnkKrEfdUnz7CxMRb6oHZWw==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.16.5", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-json-strings": { + "node_modules/@babel/plugin-proposal-json-strings": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.5.tgz", "integrity": "sha512-QQJueTFa0y9E4qHANqIvMsuxM/qcLQmKttBACtPCQzGUEizsXDACGonlPiSwynHfOa3vNw0FPMVvQzbuXwh4SQ==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.16.5", "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-logical-assignment-operators": { + "node_modules/@babel/plugin-proposal-logical-assignment-operators": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.5.tgz", "integrity": "sha512-xqibl7ISO2vjuQM+MzR3rkd0zfNWltk7n9QhaD8ghMmMceVguYrNDt7MikRyj4J4v3QehpnrU8RYLnC7z/gZLA==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.16.5", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-nullish-coalescing-operator": { + "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.5.tgz", "integrity": "sha512-YwMsTp/oOviSBhrjwi0vzCUycseCYwoXnLiXIL3YNjHSMBHicGTz7GjVU/IGgz4DtOEXBdCNG72pvCX22ehfqg==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.16.5", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-numeric-separator": { + "node_modules/@babel/plugin-proposal-numeric-separator": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.5.tgz", "integrity": "sha512-DvB9l/TcsCRvsIV9v4jxR/jVP45cslTVC0PMVHvaJhhNuhn2Y1SOhCSFlPK777qLB5wb8rVDaNoqMTyOqtY5Iw==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.16.5", "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-object-rest-spread": { + "node_modules/@babel/plugin-proposal-object-rest-spread": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.16.5.tgz", "integrity": "sha512-UEd6KpChoyPhCoE840KRHOlGhEZFutdPDMGj+0I56yuTTOaT51GzmnEl/0uT41fB/vD2nT+Pci2KjezyE3HmUw==", "dev": true, - "requires": { + "dependencies": { "@babel/compat-data": "^7.16.4", "@babel/helper-compilation-targets": "^7.16.3", "@babel/helper-plugin-utils": "^7.16.5", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-transform-parameters": "^7.16.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-optional-catch-binding": { + "node_modules/@babel/plugin-proposal-optional-catch-binding": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.5.tgz", "integrity": "sha512-ihCMxY1Iljmx4bWy/PIMJGXN4NS4oUj1MKynwO07kiKms23pNvIn1DMB92DNB2R0EA882sw0VXIelYGdtF7xEQ==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.16.5", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-optional-chaining": { + "node_modules/@babel/plugin-proposal-optional-chaining": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.5.tgz", "integrity": "sha512-kzdHgnaXRonttiTfKYnSVafbWngPPr2qKw9BWYBESl91W54e+9R5pP70LtWxV56g0f05f/SQrwHYkfvbwcdQ/A==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.16.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-private-methods": { + "node_modules/@babel/plugin-proposal-private-methods": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.5.tgz", "integrity": "sha512-+yFMO4BGT3sgzXo+lrq7orX5mAZt57DwUK6seqII6AcJnJOIhBJ8pzKH47/ql/d426uQ7YhN8DpUFirQzqYSUA==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-create-class-features-plugin": "^7.16.5", "@babel/helper-plugin-utils": "^7.16.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-private-property-in-object": { + "node_modules/@babel/plugin-proposal-private-property-in-object": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.5.tgz", "integrity": "sha512-+YGh5Wbw0NH3y/E5YMu6ci5qTDmAEVNoZ3I54aB6nVEOZ5BQ7QJlwKq5pYVucQilMByGn/bvX0af+uNaPRCabA==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-annotate-as-pure": "^7.16.0", "@babel/helper-create-class-features-plugin": "^7.16.5", "@babel/helper-plugin-utils": "^7.16.5", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-proposal-unicode-property-regex": { + "node_modules/@babel/plugin-proposal-unicode-property-regex": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.5.tgz", "integrity": "sha512-s5sKtlKQyFSatt781HQwv1hoM5BQ9qRH30r+dK56OLDsHmV74mzwJNX7R1yMuE7VZKG5O6q/gmOGSAO6ikTudg==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.16.0", "@babel/helper-plugin-utils": "^7.16.5" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-async-generators": { + "node_modules/@babel/plugin-syntax-async-generators": { "version": "7.8.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-bigint": { + "node_modules/@babel/plugin-syntax-bigint": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-class-properties": { + "node_modules/@babel/plugin-syntax-class-properties": { "version": "7.12.13", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-class-static-block": { + "node_modules/@babel/plugin-syntax-class-static-block": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-dynamic-import": { + "node_modules/@babel/plugin-syntax-dynamic-import": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-export-namespace-from": { + "node_modules/@babel/plugin-syntax-export-namespace-from": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-import-meta": { + "node_modules/@babel/plugin-syntax-import-meta": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-json-strings": { + "node_modules/@babel/plugin-syntax-json-strings": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-logical-assignment-operators": { + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-nullish-coalescing-operator": { + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-numeric-separator": { + "node_modules/@babel/plugin-syntax-numeric-separator": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-object-rest-spread": { + "node_modules/@babel/plugin-syntax-object-rest-spread": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-optional-catch-binding": { + "node_modules/@babel/plugin-syntax-optional-catch-binding": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-optional-chaining": { + "node_modules/@babel/plugin-syntax-optional-chaining": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-private-property-in-object": { + "node_modules/@babel/plugin-syntax-private-property-in-object": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-top-level-await": { + "node_modules/@babel/plugin-syntax-top-level-await": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-typescript": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.0.tgz", - "integrity": "sha512-Xv6mEXqVdaqCBfJFyeab0fH2DnUoMsDmhamxsSi4j8nLd4Vtw213WMJr55xxqipC/YVWyPY3K0blJncPYji+dQ==", + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.5.tgz", + "integrity": "sha512-/d4//lZ1Vqb4mZ5xTep3dDK888j7BGM/iKqBmndBaoYAFPlPKrGU608VVBz5JeyAb6YQDjRu1UKqj86UhwWVgw==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-arrow-functions": { + "node_modules/@babel/plugin-transform-arrow-functions": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.5.tgz", "integrity": "sha512-8bTHiiZyMOyfZFULjsCnYOWG059FVMes0iljEHSfARhNgFfpsqE92OrCffv3veSw9rwMkYcFe9bj0ZoXU2IGtQ==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.16.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-async-to-generator": { + "node_modules/@babel/plugin-transform-async-to-generator": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.5.tgz", "integrity": "sha512-TMXgfioJnkXU+XRoj7P2ED7rUm5jbnDWwlCuFVTpQboMfbSya5WrmubNBAMlk7KXvywpo8rd8WuYZkis1o2H8w==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-module-imports": "^7.16.0", "@babel/helper-plugin-utils": "^7.16.5", "@babel/helper-remap-async-to-generator": "^7.16.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-block-scoped-functions": { + "node_modules/@babel/plugin-transform-block-scoped-functions": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.5.tgz", "integrity": "sha512-BxmIyKLjUGksJ99+hJyL/HIxLIGnLKtw772zYDER7UuycDZ+Xvzs98ZQw6NGgM2ss4/hlFAaGiZmMNKvValEjw==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.16.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-block-scoping": { + "node_modules/@babel/plugin-transform-block-scoping": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.5.tgz", "integrity": "sha512-JxjSPNZSiOtmxjX7PBRBeRJTUKTyJ607YUYeT0QJCNdsedOe+/rXITjP08eG8xUpsLfPirgzdCFN+h0w6RI+pQ==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.16.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-classes": { + "node_modules/@babel/plugin-transform-classes": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.5.tgz", "integrity": "sha512-DzJ1vYf/7TaCYy57J3SJ9rV+JEuvmlnvvyvYKFbk5u46oQbBvuB9/0w+YsVsxkOv8zVWKpDmUoj4T5ILHoXevA==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-annotate-as-pure": "^7.16.0", "@babel/helper-environment-visitor": "^7.16.5", "@babel/helper-function-name": "^7.16.0", @@ -781,284 +1032,458 @@ "@babel/helper-replace-supers": "^7.16.5", "@babel/helper-split-export-declaration": "^7.16.0", "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-computed-properties": { + "node_modules/@babel/plugin-transform-computed-properties": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.5.tgz", "integrity": "sha512-n1+O7xtU5lSLraRzX88CNcpl7vtGdPakKzww74bVwpAIRgz9JVLJJpOLb0uYqcOaXVM0TL6X0RVeIJGD2CnCkg==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.16.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-destructuring": { + "node_modules/@babel/plugin-transform-destructuring": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.5.tgz", "integrity": "sha512-GuRVAsjq+c9YPK6NeTkRLWyQskDC099XkBSVO+6QzbnOnH2d/4mBVXYStaPrZD3dFRfg00I6BFJ9Atsjfs8mlg==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.16.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-dotall-regex": { + "node_modules/@babel/plugin-transform-dotall-regex": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.5.tgz", "integrity": "sha512-iQiEMt8Q4/5aRGHpGVK2Zc7a6mx7qEAO7qehgSug3SDImnuMzgmm/wtJALXaz25zUj1PmnNHtShjFgk4PDx4nw==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.16.0", "@babel/helper-plugin-utils": "^7.16.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-duplicate-keys": { + "node_modules/@babel/plugin-transform-duplicate-keys": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.5.tgz", "integrity": "sha512-81tijpDg2a6I1Yhj4aWY1l3O1J4Cg/Pd7LfvuaH2VVInAkXtzibz9+zSPdUM1WvuUi128ksstAP0hM5w48vQgg==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.16.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-exponentiation-operator": { + "node_modules/@babel/plugin-transform-exponentiation-operator": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.5.tgz", "integrity": "sha512-12rba2HwemQPa7BLIKCzm1pT2/RuQHtSFHdNl41cFiC6oi4tcrp7gjB07pxQvFpcADojQywSjblQth6gJyE6CA==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-builder-binary-assignment-operator-visitor": "^7.16.5", "@babel/helper-plugin-utils": "^7.16.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-for-of": { + "node_modules/@babel/plugin-transform-for-of": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.5.tgz", "integrity": "sha512-+DpCAJFPAvViR17PIMi9x2AE34dll5wNlXO43wagAX2YcRGgEVHCNFC4azG85b4YyyFarvkc/iD5NPrz4Oneqw==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.16.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-function-name": { + "node_modules/@babel/plugin-transform-function-name": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.5.tgz", "integrity": "sha512-Fuec/KPSpVLbGo6z1RPw4EE1X+z9gZk1uQmnYy7v4xr4TO9p41v1AoUuXEtyqAI7H+xNJYSICzRqZBhDEkd3kQ==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-function-name": "^7.16.0", "@babel/helper-plugin-utils": "^7.16.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-literals": { + "node_modules/@babel/plugin-transform-literals": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.5.tgz", "integrity": "sha512-B1j9C/IfvshnPcklsc93AVLTrNVa69iSqztylZH6qnmiAsDDOmmjEYqOm3Ts2lGSgTSywnBNiqC949VdD0/gfw==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.16.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-member-expression-literals": { + "node_modules/@babel/plugin-transform-member-expression-literals": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.5.tgz", "integrity": "sha512-d57i3vPHWgIde/9Y8W/xSFUndhvhZN5Wu2TjRrN1MVz5KzdUihKnfDVlfP1U7mS5DNj/WHHhaE4/tTi4hIyHwQ==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.16.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-modules-amd": { + "node_modules/@babel/plugin-transform-modules-amd": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.5.tgz", "integrity": "sha512-oHI15S/hdJuSCfnwIz+4lm6wu/wBn7oJ8+QrkzPPwSFGXk8kgdI/AIKcbR/XnD1nQVMg/i6eNaXpszbGuwYDRQ==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-module-transforms": "^7.16.5", "@babel/helper-plugin-utils": "^7.16.5", "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-modules-commonjs": { + "node_modules/@babel/plugin-transform-modules-commonjs": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.5.tgz", "integrity": "sha512-ABhUkxvoQyqhCWyb8xXtfwqNMJD7tx+irIRnUh6lmyFud7Jln1WzONXKlax1fg/ey178EXbs4bSGNd6PngO+SQ==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-module-transforms": "^7.16.5", "@babel/helper-plugin-utils": "^7.16.5", "@babel/helper-simple-access": "^7.16.0", "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-modules-systemjs": { + "node_modules/@babel/plugin-transform-modules-systemjs": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.5.tgz", "integrity": "sha512-53gmLdScNN28XpjEVIm7LbWnD/b/TpbwKbLk6KV4KqC9WyU6rq1jnNmVG6UgAdQZVVGZVoik3DqHNxk4/EvrjA==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-hoist-variables": "^7.16.0", "@babel/helper-module-transforms": "^7.16.5", "@babel/helper-plugin-utils": "^7.16.5", "@babel/helper-validator-identifier": "^7.15.7", "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-modules-umd": { + "node_modules/@babel/plugin-transform-modules-umd": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.5.tgz", "integrity": "sha512-qTFnpxHMoenNHkS3VoWRdwrcJ3FhX567GvDA3hRZKF0Dj8Fmg0UzySZp3AP2mShl/bzcywb/UWAMQIjA1bhXvw==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-module-transforms": "^7.16.5", "@babel/helper-plugin-utils": "^7.16.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-named-capturing-groups-regex": { + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.5.tgz", "integrity": "sha512-/wqGDgvFUeKELW6ex6QB7dLVRkd5ehjw34tpXu1nhKC0sFfmaLabIswnpf8JgDyV2NeDmZiwoOb0rAmxciNfjA==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "@babel/plugin-transform-new-target": { + "node_modules/@babel/plugin-transform-new-target": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.5.tgz", "integrity": "sha512-ZaIrnXF08ZC8jnKR4/5g7YakGVL6go6V9ql6Jl3ecO8PQaQqFE74CuM384kezju7Z9nGCCA20BqZaR1tJ/WvHg==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.16.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-object-super": { + "node_modules/@babel/plugin-transform-object-super": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.5.tgz", "integrity": "sha512-tded+yZEXuxt9Jdtkc1RraW1zMF/GalVxaVVxh41IYwirdRgyAxxxCKZ9XB7LxZqmsjfjALxupNE1MIz9KH+Zg==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.16.5", "@babel/helper-replace-supers": "^7.16.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-parameters": { + "node_modules/@babel/plugin-transform-parameters": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.5.tgz", "integrity": "sha512-B3O6AL5oPop1jAVg8CV+haeUte9oFuY85zu0jwnRNZZi3tVAbJriu5tag/oaO2kGaQM/7q7aGPBlTI5/sr9enA==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.16.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-property-literals": { + "node_modules/@babel/plugin-transform-property-literals": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.5.tgz", "integrity": "sha512-+IRcVW71VdF9pEH/2R/Apab4a19LVvdVsr/gEeotH00vSDVlKD+XgfSIw+cgGWsjDB/ziqGv/pGoQZBIiQVXHg==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.16.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-regenerator": { + "node_modules/@babel/plugin-transform-regenerator": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.5.tgz", "integrity": "sha512-2z+it2eVWU8TtQQRauvGUqZwLy4+7rTfo6wO4npr+fvvN1SW30ZF3O/ZRCNmTuu4F5MIP8OJhXAhRV5QMJOuYg==", "dev": true, - "requires": { + "dependencies": { "regenerator-transform": "^0.14.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-reserved-words": { + "node_modules/@babel/plugin-transform-reserved-words": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.5.tgz", "integrity": "sha512-aIB16u8lNcf7drkhXJRoggOxSTUAuihTSTfAcpynowGJOZiGf+Yvi7RuTwFzVYSYPmWyARsPqUGoZWWWxLiknw==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.16.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-shorthand-properties": { + "node_modules/@babel/plugin-transform-shorthand-properties": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.5.tgz", "integrity": "sha512-ZbuWVcY+MAXJuuW7qDoCwoxDUNClfZxoo7/4swVbOW1s/qYLOMHlm9YRWMsxMFuLs44eXsv4op1vAaBaBaDMVg==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.16.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-spread": { + "node_modules/@babel/plugin-transform-spread": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.5.tgz", "integrity": "sha512-5d6l/cnG7Lw4tGHEoga4xSkYp1euP7LAtrah1h1PgJ3JY7yNsjybsxQAnVK4JbtReZ/8z6ASVmd3QhYYKLaKZw==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.16.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-sticky-regex": { + "node_modules/@babel/plugin-transform-sticky-regex": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.5.tgz", "integrity": "sha512-usYsuO1ID2LXxzuUxifgWtJemP7wL2uZtyrTVM4PKqsmJycdS4U4mGovL5xXkfUheds10Dd2PjoQLXw6zCsCbg==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.16.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-template-literals": { + "node_modules/@babel/plugin-transform-template-literals": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.5.tgz", "integrity": "sha512-gnyKy9RyFhkovex4BjKWL3BVYzUDG6zC0gba7VMLbQoDuqMfJ1SDXs8k/XK41Mmt1Hyp4qNAvGFb9hKzdCqBRQ==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.16.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-typeof-symbol": { + "node_modules/@babel/plugin-transform-typeof-symbol": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.5.tgz", "integrity": "sha512-ldxCkW180qbrvyCVDzAUZqB0TAeF8W/vGJoRcaf75awm6By+PxfJKvuqVAnq8N9wz5Xa6mSpM19OfVKKVmGHSQ==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.16.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-typescript": { + "node_modules/@babel/plugin-transform-typescript": { "version": "7.16.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.1.tgz", "integrity": "sha512-NO4XoryBng06jjw/qWEU2LhcLJr1tWkhpMam/H4eas/CDKMX/b2/Ylb6EI256Y7+FVPCawwSM1rrJNOpDiz+Lg==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-create-class-features-plugin": "^7.16.0", "@babel/helper-plugin-utils": "^7.14.5", "@babel/plugin-syntax-typescript": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-unicode-escapes": { + "node_modules/@babel/plugin-transform-unicode-escapes": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.5.tgz", "integrity": "sha512-shiCBHTIIChGLdyojsKQjoAyB8MBwat25lKM7MJjbe1hE0bgIppD+LX9afr41lLHOhqceqeWl4FkLp+Bgn9o1Q==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.16.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-transform-unicode-regex": { + "node_modules/@babel/plugin-transform-unicode-regex": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.5.tgz", "integrity": "sha512-GTJ4IW012tiPEMMubd7sD07iU9O/LOo8Q/oU4xNhcaq0Xn8+6TcUQaHtC8YxySo1T+ErQ8RaWogIEeFhKGNPzw==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.16.0", "@babel/helper-plugin-utils": "^7.16.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/preset-env": { + "node_modules/@babel/preset-env": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.16.5.tgz", "integrity": "sha512-MiJJW5pwsktG61NDxpZ4oJ1CKxM1ncam9bzRtx9g40/WkLRkxFP6mhpkYV0/DxcciqoiHicx291+eUQrXb/SfQ==", "dev": true, - "requires": { + "dependencies": { "@babel/compat-data": "^7.16.4", "@babel/helper-compilation-targets": "^7.16.3", "@babel/helper-plugin-utils": "^7.16.5", @@ -1133,57 +1558,78 @@ "babel-plugin-polyfill-regenerator": "^0.3.0", "core-js-compat": "^3.19.1", "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/preset-modules": { + "node_modules/@babel/preset-modules": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", "@babel/plugin-transform-dotall-regex": "^7.4.4", "@babel/types": "^7.4.4", "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/preset-typescript": { + "node_modules/@babel/preset-typescript": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.16.5.tgz", "integrity": "sha512-lmAWRoJ9iOSvs3DqOndQpj8XqXkzaiQs50VG/zESiI9D3eoZhGriU675xNCr0UwvsuXrhMAGvyk1w+EVWF3u8Q==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.16.5", "@babel/helper-validator-option": "^7.14.5", "@babel/plugin-transform-typescript": "^7.16.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/runtime": { - "version": "7.15.4", - "resolved": false, - "integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==", - "requires": { + "node_modules/@babel/runtime": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz", + "integrity": "sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==", + "dependencies": { "regenerator-runtime": "^0.13.4" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/template": { + "node_modules/@babel/template": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.0.tgz", "integrity": "sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A==", "dev": true, - "requires": { + "dependencies": { "@babel/code-frame": "^7.16.0", "@babel/parser": "^7.16.0", "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/traverse": { + "node_modules/@babel/traverse": { "version": "7.16.5", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.5.tgz", "integrity": "sha512-FOCODAzqUMROikDYLYxl4nmwiLlu85rNqBML/A5hKRVXG2LV8d0iMqgPzdYTcIpjZEBB7D6UDU9vxRZiriASdQ==", "dev": true, - "requires": { + "dependencies": { "@babel/code-frame": "^7.16.0", "@babel/generator": "^7.16.5", "@babel/helper-environment-visitor": "^7.16.5", @@ -1194,245 +1640,467 @@ "@babel/types": "^7.16.0", "debug": "^4.1.0", "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/types": { + "node_modules/@babel/types": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.0.tgz", "integrity": "sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-validator-identifier": "^7.15.7", "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@bcoe/v8-coverage": { + "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "@ethersproject/bytes": { + "node_modules/@eslint/eslintrc": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz", + "integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.2.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", + "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@ethersproject/bytes": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.5.0.tgz", "integrity": "sha512-ABvc7BHWhZU9PNM/tANm/Qx4ostPGadAuQzWTr3doklZOhDlmcBqclrQe/ZXUIj3K8wC28oYeuRa+A37tX9kog==", - "requires": { + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { "@ethersproject/logger": "^5.5.0" } }, - "@ethersproject/logger": { + "node_modules/@ethersproject/logger": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.5.0.tgz", - "integrity": "sha512-rIY/6WPm7T8n3qS2vuHTUBPdXHl+rGxWxW5okDfo9J4Z0+gRRZT0msvUdIJkE4/HS29GUMziwGaaKO2bWONBrg==" + "integrity": "sha512-rIY/6WPm7T8n3qS2vuHTUBPdXHl+rGxWxW5okDfo9J4Z0+gRRZT0msvUdIJkE4/HS29GUMziwGaaKO2bWONBrg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ] }, - "@ethersproject/sha2": { + "node_modules/@ethersproject/sha2": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.5.0.tgz", "integrity": "sha512-B5UBoglbCiHamRVPLA110J+2uqsifpZaTmid2/7W5rbtYVz6gus6/hSDieIU/6gaKIDcOj12WnOdiymEUHIAOA==", - "requires": { + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { "@ethersproject/bytes": "^5.5.0", "@ethersproject/logger": "^5.5.0", "hash.js": "1.1.7" } }, - "@istanbuljs/load-nyc-config": { + "node_modules/@humanwhocodes/config-array": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.2.tgz", + "integrity": "sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, - "requires": { + "dependencies": { "camelcase": "^5.3.1", "find-up": "^4.1.0", "get-package-type": "^0.1.0", "js-yaml": "^3.13.1", "resolve-from": "^5.0.0" }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, "dependencies": { - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - } + "sprintf-js": "~1.0.2" } }, - "@istanbuljs/schema": { + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "@jest/console": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.3.1.tgz", - "integrity": "sha512-RkFNWmv0iui+qsOr/29q9dyfKTTT5DCuP31kUwg7rmOKPT/ozLeGLKJKVIiOfbiKyleUZKIrHwhmiZWVe8IMdw==", + "node_modules/@jest/console": { + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.4.2.tgz", + "integrity": "sha512-xknHThRsPB/To1FUbi6pCe43y58qFC03zfb6R7fDb/FfC7k2R3i1l+izRBJf8DI46KhYGRaF14Eo9A3qbBoixg==", "dev": true, - "requires": { - "@jest/types": "^27.2.5", + "dependencies": { + "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^27.3.1", - "jest-util": "^27.3.1", + "jest-message-util": "^27.4.2", + "jest-util": "^27.4.2", "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "@jest/core": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.3.1.tgz", - "integrity": "sha512-DMNE90RR5QKx0EA+wqe3/TNEwiRpOkhshKNxtLxd4rt3IZpCt+RSL+FoJsGeblRZmqdK4upHA/mKKGPPRAifhg==", + "node_modules/@jest/console/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "requires": { - "@jest/console": "^27.3.1", - "@jest/reporters": "^27.3.1", - "@jest/test-result": "^27.3.1", - "@jest/transform": "^27.3.1", - "@jest/types": "^27.2.5", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/console/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/console/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/console/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/console/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core": { + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.4.5.tgz", + "integrity": "sha512-3tm/Pevmi8bDsgvo73nX8p/WPng6KWlCyScW10FPEoN1HU4pwI83tJ3TsFvi1FfzsjwUlMNEPowgb/rPau/LTQ==", + "dev": true, + "dependencies": { + "@jest/console": "^27.4.2", + "@jest/reporters": "^27.4.5", + "@jest/test-result": "^27.4.2", + "@jest/transform": "^27.4.5", + "@jest/types": "^27.4.2", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "emittery": "^0.8.1", "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-changed-files": "^27.3.0", - "jest-config": "^27.3.1", - "jest-haste-map": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.3.1", - "jest-resolve-dependencies": "^27.3.1", - "jest-runner": "^27.3.1", - "jest-runtime": "^27.3.1", - "jest-snapshot": "^27.3.1", - "jest-util": "^27.3.1", - "jest-validate": "^27.3.1", - "jest-watcher": "^27.3.1", + "jest-changed-files": "^27.4.2", + "jest-config": "^27.4.5", + "jest-haste-map": "^27.4.5", + "jest-message-util": "^27.4.2", + "jest-regex-util": "^27.4.0", + "jest-resolve": "^27.4.5", + "jest-resolve-dependencies": "^27.4.5", + "jest-runner": "^27.4.5", + "jest-runtime": "^27.4.5", + "jest-snapshot": "^27.4.5", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.2", + "jest-watcher": "^27.4.2", "micromatch": "^4.0.4", "rimraf": "^3.0.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true } } }, - "@jest/environment": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.3.1.tgz", - "integrity": "sha512-BCKCj4mOVLme6Tanoyc9k0ultp3pnmuyHw73UHRPeeZxirsU/7E3HC4le/VDb/SMzE1JcPnto+XBKFOcoiJzVw==", + "node_modules/@jest/core/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "requires": { - "@jest/fake-timers": "^27.3.1", - "@jest/types": "^27.2.5", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/core/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/core/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/environment": { + "version": "27.4.4", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.4.4.tgz", + "integrity": "sha512-q+niMx7cJgt/t/b6dzLOh4W8Ef/8VyKG7hxASK39jakijJzbFBGpptx3RXz13FFV7OishQ9lTbv+dQ5K3EhfDQ==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^27.4.2", + "@jest/types": "^27.4.2", "@types/node": "*", - "jest-mock": "^27.3.0" + "jest-mock": "^27.4.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "@jest/fake-timers": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.3.1.tgz", - "integrity": "sha512-M3ZFgwwlqJtWZ+QkBG5NmC23A9w+A6ZxNsO5nJxJsKYt4yguBd3i8TpjQz5NfCX91nEve1KqD9RA2Q+Q1uWqoA==", + "node_modules/@jest/fake-timers": { + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.4.2.tgz", + "integrity": "sha512-f/Xpzn5YQk5adtqBgvw1V6bF8Nx3hY0OIRRpCvWcfPl0EAjdqWPdhH3t/3XpiWZqtjIEHDyMKP9ajpva1l4Zmg==", "dev": true, - "requires": { - "@jest/types": "^27.2.5", + "dependencies": { + "@jest/types": "^27.4.2", "@sinonjs/fake-timers": "^8.0.1", "@types/node": "*", - "jest-message-util": "^27.3.1", - "jest-mock": "^27.3.0", - "jest-util": "^27.3.1" + "jest-message-util": "^27.4.2", + "jest-mock": "^27.4.2", + "jest-util": "^27.4.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "@jest/globals": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.3.1.tgz", - "integrity": "sha512-Q651FWiWQAIFiN+zS51xqhdZ8g9b88nGCobC87argAxA7nMfNQq0Q0i9zTfQYgLa6qFXk2cGANEqfK051CZ8Pg==", + "node_modules/@jest/globals": { + "version": "27.4.4", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.4.4.tgz", + "integrity": "sha512-bqpqQhW30BOreXM8bA8t8JbOQzsq/WnPTnBl+It3UxAD9J8yxEAaBEylHx1dtBapAr/UBk8GidXbzmqnee8tYQ==", "dev": true, - "requires": { - "@jest/environment": "^27.3.1", - "@jest/types": "^27.2.5", - "expect": "^27.3.1" + "dependencies": { + "@jest/environment": "^27.4.4", + "@jest/types": "^27.4.2", + "expect": "^27.4.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "@jest/reporters": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.3.1.tgz", - "integrity": "sha512-m2YxPmL9Qn1emFVgZGEiMwDntDxRRQ2D58tiDQlwYTg5GvbFOKseYCcHtn0WsI8CG4vzPglo3nqbOiT8ySBT/w==", + "node_modules/@jest/reporters": { + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.4.5.tgz", + "integrity": "sha512-3orsG4vi8zXuBqEoy2LbnC1kuvkg1KQUgqNxmxpQgIOQEPeV0onvZu+qDQnEoX8qTQErtqn/xzcnbpeTuOLSiA==", "dev": true, - "requires": { + "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.3.1", - "@jest/test-result": "^27.3.1", - "@jest/transform": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/console": "^27.4.2", + "@jest/test-result": "^27.4.2", + "@jest/transform": "^27.4.5", + "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", @@ -1444,79 +2112,8819 @@ "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.0.2", - "jest-haste-map": "^27.3.1", - "jest-resolve": "^27.3.1", - "jest-util": "^27.3.1", - "jest-worker": "^27.3.1", + "jest-haste-map": "^27.4.5", + "jest-resolve": "^27.4.5", + "jest-util": "^27.4.2", + "jest-worker": "^27.4.5", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^4.0.1", "terminal-link": "^2.0.0", "v8-to-istanbul": "^8.1.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "@jest/source-map": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.0.6.tgz", - "integrity": "sha512-Fek4mi5KQrqmlY07T23JRi0e7Z9bXTOOD86V/uS0EIW4PClvPDqZOyFlLpNJheS6QI0FNX1CgmPjtJ4EA/2M+g==", + "node_modules/@jest/reporters/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" - } - }, - "@jest/test-result": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.3.1.tgz", - "integrity": "sha512-mLn6Thm+w2yl0opM8J/QnPTqrfS4FoXsXF2WIWJb2O/GBSyResL71BRuMYbYRsGt7ELwS5JGcEcGb52BNrumgg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/reporters/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/reporters/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/reporters/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/reporters/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/reporters/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/reporters/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/source-map": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.4.0.tgz", + "integrity": "sha512-Ntjx9jzP26Bvhbm93z/AKcPRj/9wrkI88/gK60glXDx1q+IeI0rf7Lw2c89Ch6ofonB0On/iRDreQuQ6te9pgQ==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/source-map/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/test-result": { + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.4.2.tgz", + "integrity": "sha512-kr+bCrra9jfTgxHXHa2UwoQjxvQk3Am6QbpAiJ5x/50LW8llOYrxILkqY0lZRW/hu8FXesnudbql263+EW9iNA==", + "dev": true, + "dependencies": { + "@jest/console": "^27.4.2", + "@jest/types": "^27.4.2", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.4.5.tgz", + "integrity": "sha512-n5woIn/1v+FT+9hniymHPARA9upYUmfi5Pw9ewVwXCDlK4F5/Gkees9v8vdjGdAIJ2MPHLHodiajLpZZanWzEQ==", + "dev": true, + "dependencies": { + "@jest/test-result": "^27.4.2", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.4.5", + "jest-runtime": "^27.4.5" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.4.5.tgz", + "integrity": "sha512-PuMet2UlZtlGzwc6L+aZmR3I7CEBpqadO03pU40l2RNY2fFJ191b9/ITB44LNOhVtsyykx0OZvj0PCyuLm7Eew==", + "dev": true, + "dependencies": { + "@babel/core": "^7.1.0", + "@jest/types": "^27.4.2", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.4.5", + "jest-regex-util": "^27.4.0", + "jest-util": "^27.4.2", + "micromatch": "^4.0.4", + "pirates": "^4.0.1", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/transform/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/transform/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/transform/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/transform/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/transform/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/transform/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/transform/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types": { + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.4.2.tgz", + "integrity": "sha512-j35yw0PMTPpZsUoOBiuHzr1zTYoad1cVIE0ajEjcrJONxxrko/IRGKkXx3os0Nsi4Hu3+5VmDbVfq5WhG/pWAg==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/types/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/types/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/types/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@project-serum/borsh": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@project-serum/borsh/-/borsh-0.2.3.tgz", + "integrity": "sha512-lH9zEYADZE3cxrgiFym8+jbUE3NM/LH+WOKYcUjs65CT10Q64Hv45bcAAa/phwYk4Tpz0uQ1x+ergFaAoGt67Q==", + "dependencies": { + "bn.js": "^5.1.2", + "buffer-layout": "^1.2.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@solana/web3.js": "^1.2.0" + } + }, + "node_modules/@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", + "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/@solana/buffer-layout": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.0.tgz", + "integrity": "sha512-lR0EMP2HC3+Mxwd4YcnZb0smnaDw7Bl2IQWZiTevRH5ZZBZn6VRWn3/92E3qdU4SSImJkA6IDHawOHAnx/qUvQ==", + "dependencies": { + "buffer": "~6.0.3" + }, + "engines": { + "node": ">=5.10" + } + }, + "node_modules/@solana/spl-token": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.1.8.tgz", + "integrity": "sha512-LZmYCKcPQDtJgecvWOgT/cnoIQPWjdH+QVyzPcFvyDUiT0DiRjZaam4aqNUyvchLFhzgunv3d9xOoyE34ofdoQ==", + "dependencies": { + "@babel/runtime": "^7.10.5", + "@solana/web3.js": "^1.21.0", + "bn.js": "^5.1.0", + "buffer": "6.0.3", + "buffer-layout": "^1.2.0", + "dotenv": "10.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@solana/web3.js": { + "version": "1.31.0", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.31.0.tgz", + "integrity": "sha512-7nHHx1JNFnrt15e9y8m38I/EJCbaB+bFC3KZVM1+QhybCikFxGMtGA5r7PDC3GEL1R2RZA8yKoLkDKo3vzzqnw==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@ethersproject/sha2": "^5.5.0", + "@solana/buffer-layout": "^3.0.0", + "bn.js": "^5.0.0", + "borsh": "^0.4.0", + "bs58": "^4.0.1", + "buffer": "6.0.1", + "cross-fetch": "^3.1.4", + "jayson": "^3.4.4", + "js-sha3": "^0.8.0", + "rpc-websockets": "^7.4.2", + "secp256k1": "^4.0.2", + "superstruct": "^0.14.2", + "tweetnacl": "^1.0.0" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/@solana/web3.js/node_modules/@solana/buffer-layout": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-3.0.0.tgz", + "integrity": "sha512-MVdgAKKL39tEs0l8je0hKaXLQFb7Rdfb0Xg2LjFZd8Lfdazkg6xiS98uAZrEKvaoF3i4M95ei9RydkGIDMeo3w==", + "dependencies": { + "buffer": "~6.0.3" + }, + "engines": { + "node": ">=5.10" + } + }, + "node_modules/@solana/web3.js/node_modules/@solana/buffer-layout/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/@solana/web3.js/node_modules/buffer": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.1.tgz", + "integrity": "sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@types/babel__core": { + "version": "7.1.17", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.17.tgz", + "integrity": "sha512-6zzkezS9QEIL8yCBvXWxPTJPNuMeECJVxSOhxNY/jfq9LxOTHivaYTqr37n9LknWWRTIkzqH2UilS5QFvfa90A==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", + "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.3.0" + } + }, + "node_modules/@types/bn.js": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", + "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.27", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.27.tgz", + "integrity": "sha512-e/sVallzUTPdyOTiqi8O8pMdBBphscvI6E4JYaKlja4Lm+zh7UFSSdW5VMkRbhDtmrONqOUHOXRguPsDckzxNA==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", + "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "27.0.3", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.0.3.tgz", + "integrity": "sha512-cmmwv9t7gBYt7hNKH5Spu7Kuu/DotGa+Ff+JGRKZ4db5eh8PnKS4LuebJ3YLUoyOyIHraTGyULn23YtEAm0VSg==", + "dev": true, + "dependencies": { + "jest-diff": "^27.0.0", + "pretty-format": "^27.0.0" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "dev": true + }, + "node_modules/@types/lodash": { + "version": "4.14.178", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.178.tgz", + "integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==" + }, + "node_modules/@types/node": { + "version": "17.0.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.5.tgz", + "integrity": "sha512-w3mrvNXLeDYV1GKTZorGJQivK6XLCoGwpnyJFbJVK/aTBQUxOCaa/GlFAAN3OTDFcb7h5tiFG+YXCO2By+riZw==" + }, + "node_modules/@types/prettier": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.2.tgz", + "integrity": "sha512-ekoj4qOQYp7CvjX8ZDBgN86w3MqQhLE1hczEJbEIjgFEumDy+na/4AJAbLXfgEWFNB2pKadM5rPFtuSGMWK7xA==", + "dev": true + }, + "node_modules/@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" + }, + "node_modules/@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" + }, + "node_modules/@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "node_modules/@types/ws": { + "version": "7.4.7", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", + "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "20.2.1", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", + "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.8.1.tgz", + "integrity": "sha512-wTZ5oEKrKj/8/366qTM366zqhIKAp6NCMweoRONtfuC07OAU9nVI2GZZdqQ1qD30WAAtcPdkH+npDwtRFdp4Rw==", + "dev": true, + "dependencies": { + "@typescript-eslint/experimental-utils": "5.8.1", + "@typescript-eslint/scope-manager": "5.8.1", + "debug": "^4.3.2", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.1.8", + "regexpp": "^3.2.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/experimental-utils": { + "version": "5.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.8.1.tgz", + "integrity": "sha512-fbodVnjIDU4JpeXWRDsG5IfIjYBxEvs8EBO8W1+YVdtrc2B9ppfof5sZhVEDOtgTfFHnYQJDI8+qdqLYO4ceww==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.8.1", + "@typescript-eslint/types": "5.8.1", + "@typescript-eslint/typescript-estree": "5.8.1", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/experimental-utils/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@typescript-eslint/experimental-utils/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.8.1.tgz", + "integrity": "sha512-K1giKHAjHuyB421SoXMXFHHVI4NdNY603uKw92++D3qyxSeYvC10CBJ/GE5Thpo4WTUvu1mmJI2/FFkz38F2Gw==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.8.1", + "@typescript-eslint/types": "5.8.1", + "@typescript-eslint/typescript-estree": "5.8.1", + "debug": "^4.3.2" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.8.1.tgz", + "integrity": "sha512-DGxJkNyYruFH3NIZc3PwrzwOQAg7vvgsHsHCILOLvUpupgkwDZdNq/cXU3BjF4LNrCsVg0qxEyWasys5AiJ85Q==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.8.1", + "@typescript-eslint/visitor-keys": "5.8.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.8.1.tgz", + "integrity": "sha512-L/FlWCCgnjKOLefdok90/pqInkomLnAcF9UAzNr+DSqMC3IffzumHTQTrINXhP1gVp9zlHiYYjvozVZDPleLcA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.8.1.tgz", + "integrity": "sha512-26lQ8l8tTbG7ri7xEcCFT9ijU5Fk+sx/KRRyyzCv7MQ+rZZlqiDPtMKWLC8P7o+dtCnby4c+OlxuX1tp8WfafQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.8.1", + "@typescript-eslint/visitor-keys": "5.8.1", + "debug": "^4.3.2", + "globby": "^11.0.4", + "is-glob": "^4.0.3", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.8.1.tgz", + "integrity": "sha512-SWgiWIwocK6NralrJarPZlWdr0hZnj5GXHIgfdm8hNkyKvpeQuFyLP6YjSIe9kf3YBIfU6OHSZLYkQ+smZwtNg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.8.1", + "eslint-visitor-keys": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/abab": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dev": true, + "dependencies": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "node_modules/acorn-globals/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/array-includes": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", + "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.5.tgz", + "integrity": "sha512-08u6rVyi1Lj7oqWbS9nUxliETrtIROT4XGTA4D/LWGten6E3ocm7cy9SIrmNHOL5XVbVuckUp3X6Xyg8/zpvHA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "node_modules/babel-jest": { + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.4.5.tgz", + "integrity": "sha512-3uuUTjXbgtODmSv/DXO9nZfD52IyC2OYTFaXGRzL0kpykzroaquCrD5+lZNafTvZlnNqZHt5pb0M08qVBZnsnA==", + "dev": true, + "dependencies": { + "@jest/transform": "^27.4.5", + "@jest/types": "^27.4.2", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^27.4.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-jest/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/babel-jest/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/babel-jest/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/babel-jest/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/babel-jest/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-jest/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "dev": true, + "dependencies": { + "object.assign": "^4.1.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", + "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.4.0.tgz", + "integrity": "sha512-Jcu7qS4OX5kTWBc45Hz7BMmgXuJqRnhatqpUhnzGC3OBYpOmf2tv6jFNwZpwM7wU7MUuv2r9IPS/ZlYOuburVw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.0.tgz", + "integrity": "sha512-wMDoBJ6uG4u4PNFh72Ty6t3EgfA91puCuAwKIazbQlci+ENb/UU9A3xG5lutjUIiXCIn1CY5L15r9LimiJyrSA==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.13.11", + "@babel/helper-define-polyfill-provider": "^0.3.0", + "semver": "^6.1.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.4.0.tgz", + "integrity": "sha512-YxFreYwUfglYKdLUGvIF2nJEsGwj+RhWSX/ije3D2vQPOXuyMLMtg/cCGMDpOA7Nd+MwlNdnGODbd2EwUZPlsw==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.3.0", + "core-js-compat": "^3.18.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.0.tgz", + "integrity": "sha512-dhAPTDLGoMW5/84wkgwiLRwMnio2i1fUe53EuvtKMv0pn2p3S8OCoV1xAzfJPl0KOX7IB89s2ib85vbYiea3jg==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.3.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.4.0.tgz", + "integrity": "sha512-NK4jGYpnBvNxcGo7/ZpZJr51jCGT+3bwwpVIDY2oNfTxJJldRtB4VAcYdgp1loDE50ODuTu+yBjpMAswv5tlpg==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^27.4.0", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base-x": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" + }, + "node_modules/borsh": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/borsh/-/borsh-0.4.0.tgz", + "integrity": "sha512-aX6qtLya3K0AkT66CmYWCCDr77qsE9arV05OmdFpmat9qu8Pg9J5tBUPDztAW5fNh/d/MyVG/OYziP52Ndzx1g==", + "dependencies": { + "@types/bn.js": "^4.11.5", + "bn.js": "^5.0.0", + "bs58": "^4.0.0", + "text-encoding-utf-8": "^1.0.2" + } + }, + "node_modules/borsh/node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "node_modules/browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "dev": true + }, + "node_modules/browserslist": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", + "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==", + "dev": true, + "dependencies": { + "caniuse-lite": "^1.0.30001286", + "electron-to-chromium": "^1.4.17", + "escalade": "^3.1.1", + "node-releases": "^2.0.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/buffer-layout": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/buffer-layout/-/buffer-layout-1.2.2.tgz", + "integrity": "sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==", + "engines": { + "node": ">=4.5" + } + }, + "node_modules/bufferutil": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.5.tgz", + "integrity": "sha512-HTm14iMQKK2FjFLRTM5lAVcyaUzOnqbPtesFIvREgXpJHdQm8bWS+GkQgIkfaBYRHuCnea7w8UVNfwiAQhlr9A==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001294", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001294.tgz", + "integrity": "sha512-LiMlrs1nSKZ8qkNhpUf5KD0Al1KCBE3zaT7OLOwEkagXMEDij98SiOovn9wxVGQpklk9vVC/pUSqgYmkmKOS8g==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", + "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", + "dev": true + }, + "node_modules/circular-json": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.9.tgz", + "integrity": "sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ==", + "deprecated": "CircularJSON is in maintenance only, flatted is its successor." + }, + "node_modules/cjs-module-lexer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", + "dev": true + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "dev": true + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/convert-source-map/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/core-js-compat": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.20.1.tgz", + "integrity": "sha512-AVhKZNpqMV3Jz8hU0YEXXE06qoxtQGsAqU0u1neUngz5IusDJRX/ZJ6t3i7mS7QxNyEONbCo14GprkBrxPlTZA==", + "dev": true, + "dependencies": { + "browserslist": "^4.19.1", + "semver": "7.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat/node_modules/semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/cross-fetch": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz", + "integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==", + "dependencies": { + "node-fetch": "2.6.1" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "dev": true + }, + "node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + }, + "node_modules/data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", + "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", + "dev": true + }, + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/delay": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", + "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/diff-sequences": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.4.0.tgz", + "integrity": "sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "dev": true, + "dependencies": { + "webidl-conversions": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/domexception/node_modules/webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "engines": { + "node": ">=10" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.30", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.30.tgz", + "integrity": "sha512-609z9sIMxDHg+TcR/VB3MXwH+uwtrYyeAwWc/orhnr90ixs6WVGSrt85CDLGUdNnLqCA7liv426V20EecjvflQ==", + "dev": true + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/emittery": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", + "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/es-abstract": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", + "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", + "is-string": "^1.0.7", + "is-weakref": "^1.0.1", + "object-inspect": "^1.11.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, + "node_modules/es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "dependencies": { + "es6-promise": "^4.0.3" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escodegen": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/escodegen/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/eslint": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.5.0.tgz", + "integrity": "sha512-tVGSkgNbOfiHyVte8bCM8OmX+xG9PzVG/B4UCF60zx7j61WIVY/AqJECDgpLD4DbbESD0e174gOg3ZlrX15GDg==", + "dev": true, + "dependencies": { + "@eslint/eslintrc": "^1.0.5", + "@humanwhocodes/config-array": "^0.9.2", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.0", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.1.0", + "espree": "^9.2.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.2.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.28.0.tgz", + "integrity": "sha512-IOlFIRHzWfEQQKcAD4iyYDndHwTQiCMcJVJjxempf203jnNLUnW34AXLrV33+nEXoifJE2ZEGmcjKPL8957eSw==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.4", + "array.prototype.flatmap": "^1.2.5", + "doctrine": "^2.1.0", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.0.4", + "object.entries": "^1.1.5", + "object.fromentries": "^2.0.5", + "object.hasown": "^1.1.0", + "object.values": "^1.1.5", + "prop-types": "^15.7.2", + "resolve": "^2.0.0-next.3", + "semver": "^6.3.0", + "string.prototype.matchall": "^4.0.6" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz", + "integrity": "sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==", + "dev": true, + "dependencies": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-scope": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.0.tgz", + "integrity": "sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz", + "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", + "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/espree": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.2.0.tgz", + "integrity": "sha512-oP3utRkynpZWF/F2x/HZJ+AGtnIclaR7z1pYPxy7NYM2fSO6LgK/Rkny8anRSPK/VwEA1eqm2squui0T7ZMOBg==", + "dev": true, + "dependencies": { + "acorn": "^8.6.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^3.1.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.4.2.tgz", + "integrity": "sha512-BjAXIDC6ZOW+WBFNg96J22D27Nq5ohn+oGcuP2rtOtcjuxNoV9McpQ60PcQWhdFOSBIQdR72e+4HdnbZTFSTyg==", + "dev": true, + "dependencies": { + "@jest/types": "^27.4.2", + "ansi-styles": "^5.0.0", + "jest-get-type": "^27.4.0", + "jest-matcher-utils": "^27.4.2", + "jest-message-util": "^27.4.2", + "jest-regex-util": "^27.4.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/expect/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eyes": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=", + "engines": { + "node": "> 0.1.90" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "node_modules/fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz", + "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==", + "dev": true + }, + "node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^1.0.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-local": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.3.tgz", + "integrity": "sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", + "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", + "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", + "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/isomorphic-ws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.3.tgz", + "integrity": "sha512-x9LtDVtfm/t1GFiLl3NffC7hz+I1ragvgX1P/Lg1NlIagifZDKUkuuaAxH/qpwj2IuEfD8G2Bs/UKp+sZ/pKkg==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jayson": { + "version": "3.6.6", + "resolved": "https://registry.npmjs.org/jayson/-/jayson-3.6.6.tgz", + "integrity": "sha512-f71uvrAWTtrwoww6MKcl9phQTC+56AopLyEenWvKVAIMz+q0oVGj6tenLZ7Z6UiPBkJtKLj4kt0tACllFQruGQ==", + "dependencies": { + "@types/connect": "^3.4.33", + "@types/express-serve-static-core": "^4.17.9", + "@types/lodash": "^4.14.159", + "@types/node": "^12.12.54", + "@types/ws": "^7.4.4", + "commander": "^2.20.3", + "delay": "^5.0.0", + "es6-promisify": "^5.0.0", + "eyes": "^0.1.8", + "isomorphic-ws": "^4.0.1", + "json-stringify-safe": "^5.0.1", + "JSONStream": "^1.3.5", + "lodash": "^4.17.20", + "uuid": "^8.3.2", + "ws": "^7.4.5" + }, + "bin": { + "jayson": "bin/jayson.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jayson/node_modules/@types/node": { + "version": "12.20.39", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.39.tgz", + "integrity": "sha512-U7PMwkDmc3bnL0e4U8oA0POpi1vfsYDc+DEUS2+rPxm9NlLcW1dBa5JcRhO633PoPUcCSWMNXrMsqhmAVEo+IQ==" + }, + "node_modules/jest": { + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.4.5.tgz", + "integrity": "sha512-uT5MiVN3Jppt314kidCk47MYIRilJjA/l2mxwiuzzxGUeJIvA8/pDaJOAX5KWvjAo7SCydcW0/4WEtgbLMiJkg==", + "dev": true, + "dependencies": { + "@jest/core": "^27.4.5", + "import-local": "^3.0.2", + "jest-cli": "^27.4.5" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.4.2.tgz", + "integrity": "sha512-/9x8MjekuzUQoPjDHbBiXbNEBauhrPU2ct7m8TfCg69ywt1y/N+yYwGh3gCpnqUS3klYWDU/lSNgv+JhoD2k1A==", + "dev": true, + "dependencies": { + "@jest/types": "^27.4.2", + "execa": "^5.0.0", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus": { + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.4.5.tgz", + "integrity": "sha512-eTNWa9wsvBwPykhMMShheafbwyakcdHZaEYh5iRrQ0PFJxkDP/e3U/FvzGuKWu2WpwUA3C3hPlfpuzvOdTVqnw==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.4.4", + "@jest/test-result": "^27.4.2", + "@jest/types": "^27.4.2", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "expect": "^27.4.2", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.4.2", + "jest-matcher-utils": "^27.4.2", + "jest-message-util": "^27.4.2", + "jest-runtime": "^27.4.5", + "jest-snapshot": "^27.4.5", + "jest-util": "^27.4.2", + "pretty-format": "^27.4.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.3", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-circus/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-circus/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-circus/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-cli": { + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.4.5.tgz", + "integrity": "sha512-hrky3DSgE0u7sQxaCL7bdebEPHx5QzYmrGuUjaPLmPE8jx5adtvGuOlRspvMoVLTTDOHRnZDoRLYJuA+VCI7Hg==", + "dev": true, + "dependencies": { + "@jest/core": "^27.4.5", + "@jest/test-result": "^27.4.2", + "@jest/types": "^27.4.2", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "jest-config": "^27.4.5", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.2", + "prompts": "^2.0.1", + "yargs": "^16.2.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-cli/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-cli/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-cli/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-cli/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-cli/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-cli/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config": { + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.4.5.tgz", + "integrity": "sha512-t+STVJtPt+fpqQ8GBw850NtSQbnDOw/UzdPfzDaHQ48/AylQlW7LHj3dH+ndxhC1UxJ0Q3qkq7IH+nM1skwTwA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^27.4.5", + "@jest/types": "^27.4.2", + "babel-jest": "^27.4.5", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-circus": "^27.4.5", + "jest-environment-jsdom": "^27.4.4", + "jest-environment-node": "^27.4.4", + "jest-get-type": "^27.4.0", + "jest-jasmine2": "^27.4.5", + "jest-regex-util": "^27.4.0", + "jest-resolve": "^27.4.5", + "jest-runner": "^27.4.5", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.2", + "micromatch": "^4.0.4", + "pretty-format": "^27.4.2", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-config/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-config/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-config/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff": { + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.4.2.tgz", + "integrity": "sha512-ujc9ToyUZDh9KcqvQDkk/gkbf6zSaeEg9AiBxtttXW59H/AcqEYp1ciXAtJp+jXWva5nAf/ePtSsgWwE5mqp4Q==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.4.0", + "jest-get-type": "^27.4.0", + "pretty-format": "^27.4.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-diff/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-diff/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-docblock": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.4.0.tgz", + "integrity": "sha512-7TBazUdCKGV7svZ+gh7C8esAnweJoG+SvcF6Cjqj4l17zA2q1cMwx2JObSioubk317H+cjcHgP+7fTs60paulg==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-each": { + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.4.2.tgz", + "integrity": "sha512-53V2MNyW28CTruB3lXaHNk6PkiIFuzdOC9gR3C6j8YE/ACfrPnz+slB0s17AgU1TtxNzLuHyvNlLJ+8QYw9nBg==", + "dev": true, + "dependencies": { + "@jest/types": "^27.4.2", + "chalk": "^4.0.0", + "jest-get-type": "^27.4.0", + "jest-util": "^27.4.2", + "pretty-format": "^27.4.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-each/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-each/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-each/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-each/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-jsdom": { + "version": "27.4.4", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.4.4.tgz", + "integrity": "sha512-cYR3ndNfHBqQgFvS1RL7dNqSvD//K56j/q1s2ygNHcfTCAp12zfIromO1w3COmXrxS8hWAh7+CmZmGCIoqGcGA==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.4.4", + "@jest/fake-timers": "^27.4.2", + "@jest/types": "^27.4.2", + "@types/node": "*", + "jest-mock": "^27.4.2", + "jest-util": "^27.4.2", + "jsdom": "^16.6.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-environment-node": { + "version": "27.4.4", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.4.4.tgz", + "integrity": "sha512-D+v3lbJ2GjQTQR23TK0kY3vFVmSeea05giInI41HHOaJnAwOnmUHTZgUaZL+VxUB43pIzoa7PMwWtCVlIUoVoA==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.4.4", + "@jest/fake-timers": "^27.4.2", + "@jest/types": "^27.4.2", + "@types/node": "*", + "jest-mock": "^27.4.2", + "jest-util": "^27.4.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.4.0.tgz", + "integrity": "sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.4.5.tgz", + "integrity": "sha512-oJm1b5qhhPs78K24EDGifWS0dELYxnoBiDhatT/FThgB9yxqUm5F6li3Pv+Q+apMBmmPNzOBnZ7ZxWMB1Leq1Q==", + "dev": true, + "dependencies": { + "@jest/types": "^27.4.2", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-regex-util": "^27.4.0", + "jest-serializer": "^27.4.0", + "jest-util": "^27.4.2", + "jest-worker": "^27.4.5", + "micromatch": "^4.0.4", + "walker": "^1.0.7" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-jasmine2": { + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.4.5.tgz", + "integrity": "sha512-oUnvwhJDj2LhOiUB1kdnJjkx8C5PwgUZQb9urF77mELH9DGR4e2GqpWQKBOYXWs5+uTN9BGDqRz3Aeg5Wts7aw==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^27.4.4", + "@jest/source-map": "^27.4.0", + "@jest/test-result": "^27.4.2", + "@jest/types": "^27.4.2", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^27.4.2", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.4.2", + "jest-matcher-utils": "^27.4.2", + "jest-message-util": "^27.4.2", + "jest-runtime": "^27.4.5", + "jest-snapshot": "^27.4.5", + "jest-util": "^27.4.2", + "pretty-format": "^27.4.2", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-jasmine2/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-jasmine2/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-jasmine2/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-jasmine2/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-jasmine2/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-jasmine2/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-leak-detector": { + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.4.2.tgz", + "integrity": "sha512-ml0KvFYZllzPBJWDei3mDzUhyp/M4ubKebX++fPaudpe8OsxUE+m+P6ciVLboQsrzOCWDjE20/eXew9QMx/VGw==", + "dev": true, + "dependencies": { + "jest-get-type": "^27.4.0", + "pretty-format": "^27.4.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.4.2.tgz", + "integrity": "sha512-jyP28er3RRtMv+fmYC/PKG8wvAmfGcSNproVTW2Y0P/OY7/hWUOmsPfxN1jOhM+0u2xU984u2yEagGivz9OBGQ==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^27.4.2", + "jest-get-type": "^27.4.0", + "pretty-format": "^27.4.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-matcher-utils/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-matcher-utils/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util": { + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.4.2.tgz", + "integrity": "sha512-OMRqRNd9E0DkBLZpFtZkAGYOXl6ZpoMtQJWTAREJKDOFa0M6ptB7L67tp+cszMBkvSgKOhNtQp2Vbcz3ZZKo/w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.4.2", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.4", + "pretty-format": "^27.4.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-message-util/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-message-util/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-mock": { + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.4.2.tgz", + "integrity": "sha512-PDDPuyhoukk20JrQKeofK12hqtSka7mWH0QQuxSNgrdiPsrnYYLS6wbzu/HDlxZRzji5ylLRULeuI/vmZZDrYA==", + "dev": true, + "dependencies": { + "@jest/types": "^27.4.2", + "@types/node": "*" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.4.0.tgz", + "integrity": "sha512-WeCpMpNnqJYMQoOjm1nTtsgbR4XHAk1u00qDoNBQoykM280+/TmgA5Qh5giC1ecy6a5d4hbSsHzpBtu5yvlbEg==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.4.5.tgz", + "integrity": "sha512-xU3z1BuOz/hUhVUL+918KqUgK+skqOuUsAi7A+iwoUldK6/+PW+utK8l8cxIWT9AW7IAhGNXjSAh1UYmjULZZw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.4.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.4.5", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.2", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.4.5.tgz", + "integrity": "sha512-elEVvkvRK51y037NshtEkEnukMBWvlPzZHiL847OrIljJ8yIsujD2GXRPqDXC4rEVKbcdsy7W0FxoZb4WmEs7w==", + "dev": true, + "dependencies": { + "@jest/types": "^27.4.2", + "jest-regex-util": "^27.4.0", + "jest-snapshot": "^27.4.5" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-resolve/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-resolve/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-resolve/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-resolve/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner": { + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.4.5.tgz", + "integrity": "sha512-/irauncTfmY1WkTaRQGRWcyQLzK1g98GYG/8QvIPviHgO1Fqz1JYeEIsSfF+9mc/UTA6S+IIHFgKyvUrtiBIZg==", + "dev": true, + "dependencies": { + "@jest/console": "^27.4.2", + "@jest/environment": "^27.4.4", + "@jest/test-result": "^27.4.2", + "@jest/transform": "^27.4.5", + "@jest/types": "^27.4.2", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-docblock": "^27.4.0", + "jest-environment-jsdom": "^27.4.4", + "jest-environment-node": "^27.4.4", + "jest-haste-map": "^27.4.5", + "jest-leak-detector": "^27.4.2", + "jest-message-util": "^27.4.2", + "jest-resolve": "^27.4.5", + "jest-runtime": "^27.4.5", + "jest-util": "^27.4.2", + "jest-worker": "^27.4.5", + "source-map-support": "^0.5.6", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runner/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-runner/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-runner/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-runner/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-runner/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime": { + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.4.5.tgz", + "integrity": "sha512-CIYqwuJQXHQtPd/idgrx4zgJ6iCb6uBjQq1RSAGQrw2S8XifDmoM1Ot8NRd80ooAm+ZNdHVwsktIMGlA1F1FAQ==", + "dev": true, + "dependencies": { + "@jest/console": "^27.4.2", + "@jest/environment": "^27.4.4", + "@jest/globals": "^27.4.4", + "@jest/source-map": "^27.4.0", + "@jest/test-result": "^27.4.2", + "@jest/transform": "^27.4.5", + "@jest/types": "^27.4.2", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.4.5", + "jest-message-util": "^27.4.2", + "jest-mock": "^27.4.2", + "jest-regex-util": "^27.4.0", + "jest-resolve": "^27.4.5", + "jest-snapshot": "^27.4.5", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.2", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^16.2.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runtime/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-runtime/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-runtime/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-runtime/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-runtime/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-serializer": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.4.0.tgz", + "integrity": "sha512-RDhpcn5f1JYTX2pvJAGDcnsNTnsV9bjYPU8xcV+xPwOXnUPOQwf4ZEuiU6G9H1UztH+OapMgu/ckEVwO87PwnQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "graceful-fs": "^4.2.4" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.4.5.tgz", + "integrity": "sha512-eCi/iM1YJFrJWiT9de4+RpWWWBqsHiYxFG9V9o/n0WXs6GpW4lUt4FAHAgFPTLPqCUVzrMQmSmTZSgQzwqR7IQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.7.2", + "@babel/generator": "^7.7.2", + "@babel/parser": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.0.0", + "@jest/transform": "^27.4.5", + "@jest/types": "^27.4.2", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^27.4.2", + "graceful-fs": "^4.2.4", + "jest-diff": "^27.4.2", + "jest-get-type": "^27.4.0", + "jest-haste-map": "^27.4.5", + "jest-matcher-utils": "^27.4.2", + "jest-message-util": "^27.4.2", + "jest-resolve": "^27.4.5", + "jest-util": "^27.4.2", + "natural-compare": "^1.4.0", + "pretty-format": "^27.4.2", + "semver": "^7.3.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-snapshot/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-snapshot/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util": { + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.4.2.tgz", + "integrity": "sha512-YuxxpXU6nlMan9qyLuxHaMMOzXAl5aGZWCSzben5DhLHemYQxCc4YK+4L3ZrCutT8GPQ+ui9k5D8rUJoDioMnA==", + "dev": true, + "dependencies": { + "@jest/types": "^27.4.2", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.4", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-util/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-util/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-util/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-validate": { + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.4.2.tgz", + "integrity": "sha512-hWYsSUej+Fs8ZhOm5vhWzwSLmVaPAxRy+Mr+z5MzeaHm9AxUpXdoVMEW4R86y5gOobVfBsMFLk4Rb+QkiEpx1A==", + "dev": true, + "dependencies": { + "@jest/types": "^27.4.2", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^27.4.0", + "leven": "^3.1.0", + "pretty-format": "^27.4.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-validate/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.1.tgz", + "integrity": "sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-validate/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-validate/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-validate/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-validate/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watcher": { + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.4.2.tgz", + "integrity": "sha512-NJvMVyyBeXfDezhWzUOCOYZrUmkSCiatpjpm+nFUid74OZEHk6aMLrZAukIiFDwdbqp6mTM6Ui1w4oc+8EobQg==", + "dev": true, + "dependencies": { + "@jest/test-result": "^27.4.2", + "@jest/types": "^27.4.2", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^27.4.2", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-watcher/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-watcher/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-watcher/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-watcher/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-watcher/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watcher/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker": { + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.5.tgz", + "integrity": "sha512-f2s8kEdy15cv9r7q4KkzGXvlY0JTcmCbMHZBfSQDwW77REr45IDWwd0lksDFeVHH2jJ5pqb90T77XscrjeGzzg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsdom": { + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", + "dev": true, + "dependencies": { + "abab": "^2.0.5", + "acorn": "^8.2.4", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.5.0", + "ws": "^7.4.6", + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "node_modules/json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "engines": [ + "node >= 0.2.0" + ] + }, + "node_modules/JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.1.tgz", + "integrity": "sha512-uP5vu8xfy2F9A6LGC22KO7e2/vGTS1MhP+18f++ZNlf0Ohaxbc9nIEwHAsejlJKyzfZzU5UIhe5ItYkitcZnZA==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.3", + "object.assign": "^4.1.2" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "dev": true, + "dependencies": { + "mime-db": "1.51.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + }, + "node_modules/node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "engines": { + "node": "4.x || >=6.0.0" + } + }, + "node_modules/node-gyp-build": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", + "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", + "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", + "dev": true + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz", + "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.5.tgz", + "integrity": "sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.hasown": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.0.tgz", + "integrity": "sha512-MhjYRfj3GBlhSkDHo6QmvgjRLXQ2zndabdf3nX0yTyZK9rPfxb6uRpAac8HXNLy1GpqWtZ81Qh4v3uOls2sRAg==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.4.tgz", + "integrity": "sha512-ZIrVPH+A52Dw84R0L3/VS9Op04PuQ2SEoJL6bkshmiTic/HldyW9Tf7oH5mhJZBK7NmDx27vSMrYEXPXclpDKw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz", + "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/pretty-format": { + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.2.tgz", + "integrity": "sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.4.2", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prop-types": { + "version": "15.8.0", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.0.tgz", + "integrity": "sha512-fDGekdaHh65eI3lMi5OnErU6a8Ighg2KjcjQxO7m8VHyWjcPyj5kiOgV1LQDOOOgVy3+5FgjXvdSSX7B8/5/4g==", + "dev": true, + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + }, + "node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "node_modules/regenerate-unicode-properties": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz", + "integrity": "sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + }, + "node_modules/regenerator-transform": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", + "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", + "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/regexpu-core": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.8.0.tgz", + "integrity": "sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^9.0.0", + "regjsgen": "^0.5.2", + "regjsparser": "^0.7.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsgen": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", + "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", + "dev": true + }, + "node_modules/regjsparser": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.7.0.tgz", + "integrity": "sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ==", + "dev": true, + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "dependencies": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve.exports": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", + "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rpc-websockets": { + "version": "7.4.16", + "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.4.16.tgz", + "integrity": "sha512-0b7OVhutzwRIaYAtJo5tqtaQTWKfwAsKnaThOSOy+VkhVdleNUgb8eZnWSdWITRZZEigV5uPEIDr5KZe4DBrdQ==", + "dependencies": { + "@babel/runtime": "^7.11.2", + "circular-json": "^0.5.9", + "eventemitter3": "^4.0.7", + "uuid": "^8.3.0", + "ws": "^7.4.5" + }, + "funding": { + "type": "paypal", + "url": "https://paypal.me/kozjak" + }, + "optionalDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "dev": true, + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/secp256k1": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", + "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", + "hasInstallScript": true, + "dependencies": { + "elliptic": "^6.5.2", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", + "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", + "dev": true + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/stack-utils": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", + "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.6.tgz", + "integrity": "sha512-6WgDX8HmQqvEd7J+G6VtAahhsQIssiZ8zl7zKh1VDMFyL3hRTJP4FTNA3RbIp2TOQ9AYNDcc7e3fH0Qbup+DBg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1", + "get-intrinsic": "^1.1.1", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.3.1", + "side-channel": "^1.0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/superstruct": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-0.14.2.tgz", + "integrity": "sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==" + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-hyperlinks": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", + "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, + "node_modules/terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-encoding-utf-8": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz", + "integrity": "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==" + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "node_modules/throat": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", + "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "dev": true, + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "dev": true, + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz", + "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", + "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz", + "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/utf-8-validate": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.7.tgz", + "integrity": "sha512-vLt1O5Pp+flcArHGIyKEQq883nBt8nN8tVBcoL0qUXj2XT1n7p70yGIq2VK98I5FdZ1YHc0wk/koOnHjnXWk1Q==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "node_modules/v8-to-istanbul": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz", + "integrity": "sha512-/PRhfd8aTNp9Ggr62HPzXg2XasNFGy5PBt0Rp04du7/8GNNSgxFL6WBTkgMKSL9bFjH+8kKEG3f37FmxiTqUUA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/v8-to-istanbul/node_modules/source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "dev": true, + "dependencies": { + "browser-process-hrtime": "^1.0.0" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "dev": true, + "dependencies": { + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "dev": true, + "engines": { + "node": ">=10.4" + } + }, + "node_modules/whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "dependencies": { + "iconv-lite": "0.4.24" + } + }, + "node_modules/whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "node_modules/whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "dev": true, + "dependencies": { + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/ws": { + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz", + "integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "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" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + } + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz", + "integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==", + "dev": true, + "requires": { + "@babel/highlight": "^7.16.0" + } + }, + "@babel/compat-data": { + "version": "7.16.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.4.tgz", + "integrity": "sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q==", + "dev": true + }, + "@babel/core": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.5.tgz", + "integrity": "sha512-wUcenlLzuWMZ9Zt8S0KmFwGlH6QKRh3vsm/dhDA3CHkiTA45YuG1XkHRcNRl73EFPXDp/d5kVOU0/y7x2w6OaQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.0", + "@babel/generator": "^7.16.5", + "@babel/helper-compilation-targets": "^7.16.3", + "@babel/helper-module-transforms": "^7.16.5", + "@babel/helpers": "^7.16.5", + "@babel/parser": "^7.16.5", + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.5", + "@babel/types": "^7.16.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + } + }, + "@babel/generator": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.5.tgz", + "integrity": "sha512-kIvCdjZqcdKqoDbVVdt5R99icaRtrtYhYK/xux5qiWCBmfdvEYMFZ68QCrpE5cbFM1JsuArUNs1ZkuKtTtUcZA==", + "dev": true, + "requires": { + "@babel/types": "^7.16.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.0.tgz", + "integrity": "sha512-ItmYF9vR4zA8cByDocY05o0LGUkp1zhbTQOH1NFyl5xXEqlTJQCEJjieriw+aFpxo16swMxUnUiKS7a/r4vtHg==", + "dev": true, + "requires": { + "@babel/types": "^7.16.0" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.5.tgz", + "integrity": "sha512-3JEA9G5dmmnIWdzaT9d0NmFRgYnWUThLsDaL7982H0XqqWr56lRrsmwheXFMjR+TMl7QMBb6mzy9kvgr1lRLUA==", + "dev": true, + "requires": { + "@babel/helper-explode-assignable-expression": "^7.16.0", + "@babel/types": "^7.16.0" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.16.3", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.3.tgz", + "integrity": "sha512-vKsoSQAyBmxS35JUOOt+07cLc6Nk/2ljLIHwmq2/NM6hdioUaqEXq/S+nXvbvXbZkNDlWOymPanJGOc4CBjSJA==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.16.0", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.17.5", + "semver": "^6.3.0" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.5.tgz", + "integrity": "sha512-NEohnYA7mkB8L5JhU7BLwcBdU3j83IziR9aseMueWGeAjblbul3zzb8UvJ3a1zuBiqCMObzCJHFqKIQE6hTVmg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.16.0", + "@babel/helper-environment-visitor": "^7.16.5", + "@babel/helper-function-name": "^7.16.0", + "@babel/helper-member-expression-to-functions": "^7.16.5", + "@babel/helper-optimise-call-expression": "^7.16.0", + "@babel/helper-replace-supers": "^7.16.5", + "@babel/helper-split-export-declaration": "^7.16.0" + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.0.tgz", + "integrity": "sha512-3DyG0zAFAZKcOp7aVr33ddwkxJ0Z0Jr5V99y3I690eYLpukJsJvAbzTy1ewoCqsML8SbIrjH14Jc/nSQ4TvNPA==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.16.0", + "regexpu-core": "^4.7.1" + } + }, + "@babel/helper-define-polyfill-provider": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.0.tgz", + "integrity": "sha512-7hfT8lUljl/tM3h+izTX/pO3W3frz2ok6Pk+gzys8iJqDfZrZy2pXjRTZAvG2YmfHun1X4q8/UZRLatMfqc5Tg==", + "dev": true, + "requires": { + "@babel/helper-compilation-targets": "^7.13.0", + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/traverse": "^7.13.0", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + } + }, + "@babel/helper-environment-visitor": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.5.tgz", + "integrity": "sha512-ODQyc5AnxmZWm/R2W7fzhamOk1ey8gSguo5SGvF0zcB3uUzRpTRmM/jmLSm9bDMyPlvbyJ+PwPEK0BWIoZ9wjg==", + "dev": true, + "requires": { + "@babel/types": "^7.16.0" + } + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.0.tgz", + "integrity": "sha512-Hk2SLxC9ZbcOhLpg/yMznzJ11W++lg5GMbxt1ev6TXUiJB0N42KPC+7w8a+eWGuqDnUYuwStJoZHM7RgmIOaGQ==", + "dev": true, + "requires": { + "@babel/types": "^7.16.0" + } + }, + "@babel/helper-function-name": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.0.tgz", + "integrity": "sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.16.0", + "@babel/template": "^7.16.0", + "@babel/types": "^7.16.0" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.0.tgz", + "integrity": "sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ==", + "dev": true, + "requires": { + "@babel/types": "^7.16.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.0.tgz", + "integrity": "sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg==", + "dev": true, + "requires": { + "@babel/types": "^7.16.0" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.5.tgz", + "integrity": "sha512-7fecSXq7ZrLE+TWshbGT+HyCLkxloWNhTbU2QM1NTI/tDqyf0oZiMcEfYtDuUDCo528EOlt39G1rftea4bRZIw==", + "dev": true, + "requires": { + "@babel/types": "^7.16.0" + } + }, + "@babel/helper-module-imports": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.0.tgz", + "integrity": "sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg==", + "dev": true, + "requires": { + "@babel/types": "^7.16.0" + } + }, + "@babel/helper-module-transforms": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.5.tgz", + "integrity": "sha512-CkvMxgV4ZyyioElFwcuWnDCcNIeyqTkCm9BxXZi73RR1ozqlpboqsbGUNvRTflgZtFbbJ1v5Emvm+lkjMYY/LQ==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.16.5", + "@babel/helper-module-imports": "^7.16.0", + "@babel/helper-simple-access": "^7.16.0", + "@babel/helper-split-export-declaration": "^7.16.0", + "@babel/helper-validator-identifier": "^7.15.7", + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.5", + "@babel/types": "^7.16.0" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.0.tgz", + "integrity": "sha512-SuI467Gi2V8fkofm2JPnZzB/SUuXoJA5zXe/xzyPP2M04686RzFKFHPK6HDVN6JvWBIEW8tt9hPR7fXdn2Lgpw==", + "dev": true, + "requires": { + "@babel/types": "^7.16.0" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.5.tgz", + "integrity": "sha512-59KHWHXxVA9K4HNF4sbHCf+eJeFe0Te/ZFGqBT4OjXhrwvA04sGfaEGsVTdsjoszq0YTP49RC9UKe5g8uN2RwQ==", + "dev": true + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.5.tgz", + "integrity": "sha512-X+aAJldyxrOmN9v3FKp+Hu1NO69VWgYgDGq6YDykwRPzxs5f2N+X988CBXS7EQahDU+Vpet5QYMqLk+nsp+Qxw==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.16.0", + "@babel/helper-wrap-function": "^7.16.5", + "@babel/types": "^7.16.0" + } + }, + "@babel/helper-replace-supers": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.5.tgz", + "integrity": "sha512-ao3seGVa/FZCMCCNDuBcqnBFSbdr8N2EW35mzojx3TwfIbdPmNK+JV6+2d5bR0Z71W5ocLnQp9en/cTF7pBJiQ==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.16.5", + "@babel/helper-member-expression-to-functions": "^7.16.5", + "@babel/helper-optimise-call-expression": "^7.16.0", + "@babel/traverse": "^7.16.5", + "@babel/types": "^7.16.0" + } + }, + "@babel/helper-simple-access": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.0.tgz", + "integrity": "sha512-o1rjBT/gppAqKsYfUdfHq5Rk03lMQrkPHG1OWzHWpLgVXRH4HnMM9Et9CVdIqwkCQlobnGHEJMsgWP/jE1zUiw==", + "dev": true, + "requires": { + "@babel/types": "^7.16.0" + } + }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz", + "integrity": "sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw==", + "dev": true, + "requires": { + "@babel/types": "^7.16.0" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz", + "integrity": "sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw==", + "dev": true, + "requires": { + "@babel/types": "^7.16.0" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.15.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", + "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "dev": true + }, + "@babel/helper-wrap-function": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.16.5.tgz", + "integrity": "sha512-2J2pmLBqUqVdJw78U0KPNdeE2qeuIyKoG4mKV7wAq3mc4jJG282UgjZw4ZYDnqiWQuS3Y3IYdF/AQ6CpyBV3VA==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.16.0", + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.5", + "@babel/types": "^7.16.0" + } + }, + "@babel/helpers": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.5.tgz", + "integrity": "sha512-TLgi6Lh71vvMZGEkFuIxzaPsyeYCHQ5jJOOX1f0xXn0uciFuE8cEk0wyBquMcCxBXZ5BJhE2aUB7pnWTD150Tw==", + "dev": true, + "requires": { + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.5", + "@babel/types": "^7.16.0" + } + }, + "@babel/highlight": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.0.tgz", + "integrity": "sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.15.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.16.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.6.tgz", + "integrity": "sha512-Gr86ujcNuPDnNOY8mi383Hvi8IYrJVJYuf3XcuBM/Dgd+bINn/7tHqsj+tKkoreMbmGsFLsltI/JJd8fOFWGDQ==", + "dev": true + }, + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.16.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.2.tgz", + "integrity": "sha512-h37CvpLSf8gb2lIJ2CgC3t+EjFbi0t8qS7LCS1xcJIlEXE4czlofwaW7W1HA8zpgOCzI9C1nmoqNR1zWkk0pQg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.0.tgz", + "integrity": "sha512-4tcFwwicpWTrpl9qjf7UsoosaArgImF85AxqCRZlgc3IQDvkUHjJpruXAL58Wmj+T6fypWTC/BakfEkwIL/pwA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", + "@babel/plugin-proposal-optional-chaining": "^7.16.0" + } + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.5.tgz", + "integrity": "sha512-C/FX+3HNLV6sz7AqbTQqEo1L9/kfrKjxcVtgyBCmvIgOjvuBVUWooDoi7trsLxOzCEo5FccjRvKHkfDsJFZlfA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-remap-async-to-generator": "^7.16.5", + "@babel/plugin-syntax-async-generators": "^7.8.4" + } + }, + "@babel/plugin-proposal-class-properties": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.5.tgz", + "integrity": "sha512-pJD3HjgRv83s5dv1sTnDbZOaTjghKEz8KUn1Kbh2eAIRhGuyQ1XSeI4xVXU3UlIEVA3DAyIdxqT1eRn7Wcn55A==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5" + } + }, + "@babel/plugin-proposal-class-static-block": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.16.5.tgz", + "integrity": "sha512-EEFzuLZcm/rNJ8Q5krK+FRKdVkd6FjfzT9tuSZql9sQn64K0hHA2KLJ0DqVot9/iV6+SsuadC5yI39zWnm+nmQ==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + } + }, + "@babel/plugin-proposal-dynamic-import": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.5.tgz", + "integrity": "sha512-P05/SJZTTvHz79LNYTF8ff5xXge0kk5sIIWAypcWgX4BTRUgyHc8wRxJ/Hk+mU0KXldgOOslKaeqnhthcDJCJQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + } + }, + "@babel/plugin-proposal-export-namespace-from": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.5.tgz", + "integrity": "sha512-i+sltzEShH1vsVydvNaTRsgvq2vZsfyrd7K7vPLUU/KgS0D5yZMe6uipM0+izminnkKrEfdUnz7CxMRb6oHZWw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + } + }, + "@babel/plugin-proposal-json-strings": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.5.tgz", + "integrity": "sha512-QQJueTFa0y9E4qHANqIvMsuxM/qcLQmKttBACtPCQzGUEizsXDACGonlPiSwynHfOa3vNw0FPMVvQzbuXwh4SQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/plugin-syntax-json-strings": "^7.8.3" + } + }, + "@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.5.tgz", + "integrity": "sha512-xqibl7ISO2vjuQM+MzR3rkd0zfNWltk7n9QhaD8ghMmMceVguYrNDt7MikRyj4J4v3QehpnrU8RYLnC7z/gZLA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + } + }, + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.5.tgz", + "integrity": "sha512-YwMsTp/oOviSBhrjwi0vzCUycseCYwoXnLiXIL3YNjHSMBHicGTz7GjVU/IGgz4DtOEXBdCNG72pvCX22ehfqg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + } + }, + "@babel/plugin-proposal-numeric-separator": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.5.tgz", + "integrity": "sha512-DvB9l/TcsCRvsIV9v4jxR/jVP45cslTVC0PMVHvaJhhNuhn2Y1SOhCSFlPK777qLB5wb8rVDaNoqMTyOqtY5Iw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.16.5.tgz", + "integrity": "sha512-UEd6KpChoyPhCoE840KRHOlGhEZFutdPDMGj+0I56yuTTOaT51GzmnEl/0uT41fB/vD2nT+Pci2KjezyE3HmUw==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.16.4", + "@babel/helper-compilation-targets": "^7.16.3", + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.16.5" + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.5.tgz", + "integrity": "sha512-ihCMxY1Iljmx4bWy/PIMJGXN4NS4oUj1MKynwO07kiKms23pNvIn1DMB92DNB2R0EA882sw0VXIelYGdtF7xEQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + } + }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.5.tgz", + "integrity": "sha512-kzdHgnaXRonttiTfKYnSVafbWngPPr2qKw9BWYBESl91W54e+9R5pP70LtWxV56g0f05f/SQrwHYkfvbwcdQ/A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + } + }, + "@babel/plugin-proposal-private-methods": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.5.tgz", + "integrity": "sha512-+yFMO4BGT3sgzXo+lrq7orX5mAZt57DwUK6seqII6AcJnJOIhBJ8pzKH47/ql/d426uQ7YhN8DpUFirQzqYSUA==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5" + } + }, + "@babel/plugin-proposal-private-property-in-object": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.5.tgz", + "integrity": "sha512-+YGh5Wbw0NH3y/E5YMu6ci5qTDmAEVNoZ3I54aB6nVEOZ5BQ7QJlwKq5pYVucQilMByGn/bvX0af+uNaPRCabA==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.16.0", + "@babel/helper-create-class-features-plugin": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + } + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.5.tgz", + "integrity": "sha512-s5sKtlKQyFSatt781HQwv1hoM5BQ9qRH30r+dK56OLDsHmV74mzwJNX7R1yMuE7VZKG5O6q/gmOGSAO6ikTudg==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.16.0", + "@babel/helper-plugin-utils": "^7.16.5" + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-typescript": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.5.tgz", + "integrity": "sha512-/d4//lZ1Vqb4mZ5xTep3dDK888j7BGM/iKqBmndBaoYAFPlPKrGU608VVBz5JeyAb6YQDjRu1UKqj86UhwWVgw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.5.tgz", + "integrity": "sha512-8bTHiiZyMOyfZFULjsCnYOWG059FVMes0iljEHSfARhNgFfpsqE92OrCffv3veSw9rwMkYcFe9bj0ZoXU2IGtQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.5.tgz", + "integrity": "sha512-TMXgfioJnkXU+XRoj7P2ED7rUm5jbnDWwlCuFVTpQboMfbSya5WrmubNBAMlk7KXvywpo8rd8WuYZkis1o2H8w==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.16.0", + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-remap-async-to-generator": "^7.16.5" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.5.tgz", + "integrity": "sha512-BxmIyKLjUGksJ99+hJyL/HIxLIGnLKtw772zYDER7UuycDZ+Xvzs98ZQw6NGgM2ss4/hlFAaGiZmMNKvValEjw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.5.tgz", + "integrity": "sha512-JxjSPNZSiOtmxjX7PBRBeRJTUKTyJ607YUYeT0QJCNdsedOe+/rXITjP08eG8xUpsLfPirgzdCFN+h0w6RI+pQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.5.tgz", + "integrity": "sha512-DzJ1vYf/7TaCYy57J3SJ9rV+JEuvmlnvvyvYKFbk5u46oQbBvuB9/0w+YsVsxkOv8zVWKpDmUoj4T5ILHoXevA==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.16.0", + "@babel/helper-environment-visitor": "^7.16.5", + "@babel/helper-function-name": "^7.16.0", + "@babel/helper-optimise-call-expression": "^7.16.0", + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-replace-supers": "^7.16.5", + "@babel/helper-split-export-declaration": "^7.16.0", + "globals": "^11.1.0" + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.5.tgz", + "integrity": "sha512-n1+O7xtU5lSLraRzX88CNcpl7vtGdPakKzww74bVwpAIRgz9JVLJJpOLb0uYqcOaXVM0TL6X0RVeIJGD2CnCkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.5.tgz", + "integrity": "sha512-GuRVAsjq+c9YPK6NeTkRLWyQskDC099XkBSVO+6QzbnOnH2d/4mBVXYStaPrZD3dFRfg00I6BFJ9Atsjfs8mlg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.5.tgz", + "integrity": "sha512-iQiEMt8Q4/5aRGHpGVK2Zc7a6mx7qEAO7qehgSug3SDImnuMzgmm/wtJALXaz25zUj1PmnNHtShjFgk4PDx4nw==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.16.0", + "@babel/helper-plugin-utils": "^7.16.5" + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.5.tgz", + "integrity": "sha512-81tijpDg2a6I1Yhj4aWY1l3O1J4Cg/Pd7LfvuaH2VVInAkXtzibz9+zSPdUM1WvuUi128ksstAP0hM5w48vQgg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.5.tgz", + "integrity": "sha512-12rba2HwemQPa7BLIKCzm1pT2/RuQHtSFHdNl41cFiC6oi4tcrp7gjB07pxQvFpcADojQywSjblQth6gJyE6CA==", + "dev": true, + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.5.tgz", + "integrity": "sha512-+DpCAJFPAvViR17PIMi9x2AE34dll5wNlXO43wagAX2YcRGgEVHCNFC4azG85b4YyyFarvkc/iD5NPrz4Oneqw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.5.tgz", + "integrity": "sha512-Fuec/KPSpVLbGo6z1RPw4EE1X+z9gZk1uQmnYy7v4xr4TO9p41v1AoUuXEtyqAI7H+xNJYSICzRqZBhDEkd3kQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.16.0", + "@babel/helper-plugin-utils": "^7.16.5" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.5.tgz", + "integrity": "sha512-B1j9C/IfvshnPcklsc93AVLTrNVa69iSqztylZH6qnmiAsDDOmmjEYqOm3Ts2lGSgTSywnBNiqC949VdD0/gfw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.5.tgz", + "integrity": "sha512-d57i3vPHWgIde/9Y8W/xSFUndhvhZN5Wu2TjRrN1MVz5KzdUihKnfDVlfP1U7mS5DNj/WHHhaE4/tTi4hIyHwQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.5.tgz", + "integrity": "sha512-oHI15S/hdJuSCfnwIz+4lm6wu/wBn7oJ8+QrkzPPwSFGXk8kgdI/AIKcbR/XnD1nQVMg/i6eNaXpszbGuwYDRQ==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.5.tgz", + "integrity": "sha512-ABhUkxvoQyqhCWyb8xXtfwqNMJD7tx+irIRnUh6lmyFud7Jln1WzONXKlax1fg/ey178EXbs4bSGNd6PngO+SQ==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-simple-access": "^7.16.0", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.5.tgz", + "integrity": "sha512-53gmLdScNN28XpjEVIm7LbWnD/b/TpbwKbLk6KV4KqC9WyU6rq1jnNmVG6UgAdQZVVGZVoik3DqHNxk4/EvrjA==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.16.0", + "@babel/helper-module-transforms": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-validator-identifier": "^7.15.7", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.5.tgz", + "integrity": "sha512-qTFnpxHMoenNHkS3VoWRdwrcJ3FhX567GvDA3hRZKF0Dj8Fmg0UzySZp3AP2mShl/bzcywb/UWAMQIjA1bhXvw==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.16.5", + "@babel/helper-plugin-utils": "^7.16.5" + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.5.tgz", + "integrity": "sha512-/wqGDgvFUeKELW6ex6QB7dLVRkd5ehjw34tpXu1nhKC0sFfmaLabIswnpf8JgDyV2NeDmZiwoOb0rAmxciNfjA==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.16.0" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.5.tgz", + "integrity": "sha512-ZaIrnXF08ZC8jnKR4/5g7YakGVL6go6V9ql6Jl3ecO8PQaQqFE74CuM384kezju7Z9nGCCA20BqZaR1tJ/WvHg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.5.tgz", + "integrity": "sha512-tded+yZEXuxt9Jdtkc1RraW1zMF/GalVxaVVxh41IYwirdRgyAxxxCKZ9XB7LxZqmsjfjALxupNE1MIz9KH+Zg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-replace-supers": "^7.16.5" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.5.tgz", + "integrity": "sha512-B3O6AL5oPop1jAVg8CV+haeUte9oFuY85zu0jwnRNZZi3tVAbJriu5tag/oaO2kGaQM/7q7aGPBlTI5/sr9enA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.5.tgz", + "integrity": "sha512-+IRcVW71VdF9pEH/2R/Apab4a19LVvdVsr/gEeotH00vSDVlKD+XgfSIw+cgGWsjDB/ziqGv/pGoQZBIiQVXHg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.5.tgz", + "integrity": "sha512-2z+it2eVWU8TtQQRauvGUqZwLy4+7rTfo6wO4npr+fvvN1SW30ZF3O/ZRCNmTuu4F5MIP8OJhXAhRV5QMJOuYg==", + "dev": true, + "requires": { + "regenerator-transform": "^0.14.2" + } + }, + "@babel/plugin-transform-reserved-words": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.5.tgz", + "integrity": "sha512-aIB16u8lNcf7drkhXJRoggOxSTUAuihTSTfAcpynowGJOZiGf+Yvi7RuTwFzVYSYPmWyARsPqUGoZWWWxLiknw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.5.tgz", + "integrity": "sha512-ZbuWVcY+MAXJuuW7qDoCwoxDUNClfZxoo7/4swVbOW1s/qYLOMHlm9YRWMsxMFuLs44eXsv4op1vAaBaBaDMVg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.5.tgz", + "integrity": "sha512-5d6l/cnG7Lw4tGHEoga4xSkYp1euP7LAtrah1h1PgJ3JY7yNsjybsxQAnVK4JbtReZ/8z6ASVmd3QhYYKLaKZw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.5.tgz", + "integrity": "sha512-usYsuO1ID2LXxzuUxifgWtJemP7wL2uZtyrTVM4PKqsmJycdS4U4mGovL5xXkfUheds10Dd2PjoQLXw6zCsCbg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.5.tgz", + "integrity": "sha512-gnyKy9RyFhkovex4BjKWL3BVYzUDG6zC0gba7VMLbQoDuqMfJ1SDXs8k/XK41Mmt1Hyp4qNAvGFb9hKzdCqBRQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.5.tgz", + "integrity": "sha512-ldxCkW180qbrvyCVDzAUZqB0TAeF8W/vGJoRcaf75awm6By+PxfJKvuqVAnq8N9wz5Xa6mSpM19OfVKKVmGHSQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" + } + }, + "@babel/plugin-transform-typescript": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.1.tgz", + "integrity": "sha512-NO4XoryBng06jjw/qWEU2LhcLJr1tWkhpMam/H4eas/CDKMX/b2/Ylb6EI256Y7+FVPCawwSM1rrJNOpDiz+Lg==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.16.0", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-typescript": "^7.16.0" + } + }, + "@babel/plugin-transform-unicode-escapes": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.5.tgz", + "integrity": "sha512-shiCBHTIIChGLdyojsKQjoAyB8MBwat25lKM7MJjbe1hE0bgIppD+LX9afr41lLHOhqceqeWl4FkLp+Bgn9o1Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.5.tgz", + "integrity": "sha512-GTJ4IW012tiPEMMubd7sD07iU9O/LOo8Q/oU4xNhcaq0Xn8+6TcUQaHtC8YxySo1T+ErQ8RaWogIEeFhKGNPzw==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.16.0", + "@babel/helper-plugin-utils": "^7.16.5" + } + }, + "@babel/preset-env": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.16.5.tgz", + "integrity": "sha512-MiJJW5pwsktG61NDxpZ4oJ1CKxM1ncam9bzRtx9g40/WkLRkxFP6mhpkYV0/DxcciqoiHicx291+eUQrXb/SfQ==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.16.4", + "@babel/helper-compilation-targets": "^7.16.3", + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-validator-option": "^7.14.5", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.16.2", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.16.0", + "@babel/plugin-proposal-async-generator-functions": "^7.16.5", + "@babel/plugin-proposal-class-properties": "^7.16.5", + "@babel/plugin-proposal-class-static-block": "^7.16.5", + "@babel/plugin-proposal-dynamic-import": "^7.16.5", + "@babel/plugin-proposal-export-namespace-from": "^7.16.5", + "@babel/plugin-proposal-json-strings": "^7.16.5", + "@babel/plugin-proposal-logical-assignment-operators": "^7.16.5", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.5", + "@babel/plugin-proposal-numeric-separator": "^7.16.5", + "@babel/plugin-proposal-object-rest-spread": "^7.16.5", + "@babel/plugin-proposal-optional-catch-binding": "^7.16.5", + "@babel/plugin-proposal-optional-chaining": "^7.16.5", + "@babel/plugin-proposal-private-methods": "^7.16.5", + "@babel/plugin-proposal-private-property-in-object": "^7.16.5", + "@babel/plugin-proposal-unicode-property-regex": "^7.16.5", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-transform-arrow-functions": "^7.16.5", + "@babel/plugin-transform-async-to-generator": "^7.16.5", + "@babel/plugin-transform-block-scoped-functions": "^7.16.5", + "@babel/plugin-transform-block-scoping": "^7.16.5", + "@babel/plugin-transform-classes": "^7.16.5", + "@babel/plugin-transform-computed-properties": "^7.16.5", + "@babel/plugin-transform-destructuring": "^7.16.5", + "@babel/plugin-transform-dotall-regex": "^7.16.5", + "@babel/plugin-transform-duplicate-keys": "^7.16.5", + "@babel/plugin-transform-exponentiation-operator": "^7.16.5", + "@babel/plugin-transform-for-of": "^7.16.5", + "@babel/plugin-transform-function-name": "^7.16.5", + "@babel/plugin-transform-literals": "^7.16.5", + "@babel/plugin-transform-member-expression-literals": "^7.16.5", + "@babel/plugin-transform-modules-amd": "^7.16.5", + "@babel/plugin-transform-modules-commonjs": "^7.16.5", + "@babel/plugin-transform-modules-systemjs": "^7.16.5", + "@babel/plugin-transform-modules-umd": "^7.16.5", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.16.5", + "@babel/plugin-transform-new-target": "^7.16.5", + "@babel/plugin-transform-object-super": "^7.16.5", + "@babel/plugin-transform-parameters": "^7.16.5", + "@babel/plugin-transform-property-literals": "^7.16.5", + "@babel/plugin-transform-regenerator": "^7.16.5", + "@babel/plugin-transform-reserved-words": "^7.16.5", + "@babel/plugin-transform-shorthand-properties": "^7.16.5", + "@babel/plugin-transform-spread": "^7.16.5", + "@babel/plugin-transform-sticky-regex": "^7.16.5", + "@babel/plugin-transform-template-literals": "^7.16.5", + "@babel/plugin-transform-typeof-symbol": "^7.16.5", + "@babel/plugin-transform-unicode-escapes": "^7.16.5", + "@babel/plugin-transform-unicode-regex": "^7.16.5", + "@babel/preset-modules": "^0.1.5", + "@babel/types": "^7.16.0", + "babel-plugin-polyfill-corejs2": "^0.3.0", + "babel-plugin-polyfill-corejs3": "^0.4.0", + "babel-plugin-polyfill-regenerator": "^0.3.0", + "core-js-compat": "^3.19.1", + "semver": "^6.3.0" + } + }, + "@babel/preset-modules": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", + "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + } + }, + "@babel/preset-typescript": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.16.5.tgz", + "integrity": "sha512-lmAWRoJ9iOSvs3DqOndQpj8XqXkzaiQs50VG/zESiI9D3eoZhGriU675xNCr0UwvsuXrhMAGvyk1w+EVWF3u8Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-validator-option": "^7.14.5", + "@babel/plugin-transform-typescript": "^7.16.1" + } + }, + "@babel/runtime": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz", + "integrity": "sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/template": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.0.tgz", + "integrity": "sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.0", + "@babel/parser": "^7.16.0", + "@babel/types": "^7.16.0" + } + }, + "@babel/traverse": { + "version": "7.16.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.5.tgz", + "integrity": "sha512-FOCODAzqUMROikDYLYxl4nmwiLlu85rNqBML/A5hKRVXG2LV8d0iMqgPzdYTcIpjZEBB7D6UDU9vxRZiriASdQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.0", + "@babel/generator": "^7.16.5", + "@babel/helper-environment-visitor": "^7.16.5", + "@babel/helper-function-name": "^7.16.0", + "@babel/helper-hoist-variables": "^7.16.0", + "@babel/helper-split-export-declaration": "^7.16.0", + "@babel/parser": "^7.16.5", + "@babel/types": "^7.16.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.0.tgz", + "integrity": "sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.15.7", + "to-fast-properties": "^2.0.0" + } + }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "@eslint/eslintrc": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz", + "integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.2.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "globals": { + "version": "13.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", + "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } + } + }, + "@ethersproject/bytes": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.5.0.tgz", + "integrity": "sha512-ABvc7BHWhZU9PNM/tANm/Qx4ostPGadAuQzWTr3doklZOhDlmcBqclrQe/ZXUIj3K8wC28oYeuRa+A37tX9kog==", + "requires": { + "@ethersproject/logger": "^5.5.0" + } + }, + "@ethersproject/logger": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.5.0.tgz", + "integrity": "sha512-rIY/6WPm7T8n3qS2vuHTUBPdXHl+rGxWxW5okDfo9J4Z0+gRRZT0msvUdIJkE4/HS29GUMziwGaaKO2bWONBrg==" + }, + "@ethersproject/sha2": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.5.0.tgz", + "integrity": "sha512-B5UBoglbCiHamRVPLA110J+2uqsifpZaTmid2/7W5rbtYVz6gus6/hSDieIU/6gaKIDcOj12WnOdiymEUHIAOA==", + "requires": { + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "hash.js": "1.1.7" + } + }, + "@humanwhocodes/config-array": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.2.tgz", + "integrity": "sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } + }, + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true + }, + "@jest/console": { + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.4.2.tgz", + "integrity": "sha512-xknHThRsPB/To1FUbi6pCe43y58qFC03zfb6R7fDb/FfC7k2R3i1l+izRBJf8DI46KhYGRaF14Eo9A3qbBoixg==", + "dev": true, + "requires": { + "@jest/types": "^27.4.2", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^27.4.2", + "jest-util": "^27.4.2", + "slash": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/core": { + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.4.5.tgz", + "integrity": "sha512-3tm/Pevmi8bDsgvo73nX8p/WPng6KWlCyScW10FPEoN1HU4pwI83tJ3TsFvi1FfzsjwUlMNEPowgb/rPau/LTQ==", + "dev": true, + "requires": { + "@jest/console": "^27.4.2", + "@jest/reporters": "^27.4.5", + "@jest/test-result": "^27.4.2", + "@jest/transform": "^27.4.5", + "@jest/types": "^27.4.2", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^27.4.2", + "jest-config": "^27.4.5", + "jest-haste-map": "^27.4.5", + "jest-message-util": "^27.4.2", + "jest-regex-util": "^27.4.0", + "jest-resolve": "^27.4.5", + "jest-resolve-dependencies": "^27.4.5", + "jest-runner": "^27.4.5", + "jest-runtime": "^27.4.5", + "jest-snapshot": "^27.4.5", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.2", + "jest-watcher": "^27.4.2", + "micromatch": "^4.0.4", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/environment": { + "version": "27.4.4", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.4.4.tgz", + "integrity": "sha512-q+niMx7cJgt/t/b6dzLOh4W8Ef/8VyKG7hxASK39jakijJzbFBGpptx3RXz13FFV7OishQ9lTbv+dQ5K3EhfDQ==", + "dev": true, + "requires": { + "@jest/fake-timers": "^27.4.2", + "@jest/types": "^27.4.2", + "@types/node": "*", + "jest-mock": "^27.4.2" + } + }, + "@jest/fake-timers": { + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.4.2.tgz", + "integrity": "sha512-f/Xpzn5YQk5adtqBgvw1V6bF8Nx3hY0OIRRpCvWcfPl0EAjdqWPdhH3t/3XpiWZqtjIEHDyMKP9ajpva1l4Zmg==", + "dev": true, + "requires": { + "@jest/types": "^27.4.2", + "@sinonjs/fake-timers": "^8.0.1", + "@types/node": "*", + "jest-message-util": "^27.4.2", + "jest-mock": "^27.4.2", + "jest-util": "^27.4.2" + } + }, + "@jest/globals": { + "version": "27.4.4", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.4.4.tgz", + "integrity": "sha512-bqpqQhW30BOreXM8bA8t8JbOQzsq/WnPTnBl+It3UxAD9J8yxEAaBEylHx1dtBapAr/UBk8GidXbzmqnee8tYQ==", + "dev": true, + "requires": { + "@jest/environment": "^27.4.4", + "@jest/types": "^27.4.2", + "expect": "^27.4.2" + } + }, + "@jest/reporters": { + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.4.5.tgz", + "integrity": "sha512-3orsG4vi8zXuBqEoy2LbnC1kuvkg1KQUgqNxmxpQgIOQEPeV0onvZu+qDQnEoX8qTQErtqn/xzcnbpeTuOLSiA==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^27.4.2", + "@jest/test-result": "^27.4.2", + "@jest/transform": "^27.4.5", + "@jest/types": "^27.4.2", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^27.4.5", + "jest-resolve": "^27.4.5", + "jest-util": "^27.4.2", + "jest-worker": "^27.4.5", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^8.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/source-map": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.4.0.tgz", + "integrity": "sha512-Ntjx9jzP26Bvhbm93z/AKcPRj/9wrkI88/gK60glXDx1q+IeI0rf7Lw2c89Ch6ofonB0On/iRDreQuQ6te9pgQ==", + "dev": true, + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "@jest/test-result": { + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.4.2.tgz", + "integrity": "sha512-kr+bCrra9jfTgxHXHa2UwoQjxvQk3Am6QbpAiJ5x/50LW8llOYrxILkqY0lZRW/hu8FXesnudbql263+EW9iNA==", "dev": true, "requires": { - "@jest/console": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/console": "^27.4.2", + "@jest/types": "^27.4.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/test-sequencer": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.3.1.tgz", - "integrity": "sha512-siySLo07IMEdSjA4fqEnxfIX8lB/lWYsBPwNFtkOvsFQvmBrL3yj3k3uFNZv/JDyApTakRpxbKLJ3CT8UGVCrA==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.4.5.tgz", + "integrity": "sha512-n5woIn/1v+FT+9hniymHPARA9upYUmfi5Pw9ewVwXCDlK4F5/Gkees9v8vdjGdAIJ2MPHLHodiajLpZZanWzEQ==", "dev": true, "requires": { - "@jest/test-result": "^27.3.1", + "@jest/test-result": "^27.4.2", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.1", - "jest-runtime": "^27.3.1" + "jest-haste-map": "^27.4.5", + "jest-runtime": "^27.4.5" } }, "@jest/transform": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.3.1.tgz", - "integrity": "sha512-3fSvQ02kuvjOI1C1ssqMVBKJpZf6nwoCiSu00zAKh5nrp3SptNtZy/8s5deayHnqxhjD9CWDJ+yqQwuQ0ZafXQ==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.4.5.tgz", + "integrity": "sha512-PuMet2UlZtlGzwc6L+aZmR3I7CEBpqadO03pU40l2RNY2fFJ191b9/ITB44LNOhVtsyykx0OZvj0PCyuLm7Eew==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "babel-plugin-istanbul": "^6.0.0", "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.1", - "jest-regex-util": "^27.0.6", - "jest-util": "^27.3.1", + "jest-haste-map": "^27.4.5", + "jest-regex-util": "^27.4.0", + "jest-util": "^27.4.2", "micromatch": "^4.0.4", "pirates": "^4.0.1", "slash": "^3.0.0", "source-map": "^0.6.1", "write-file-atomic": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "@jest/types": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.2.5.tgz", - "integrity": "sha512-nmuM4VuDtCZcY+eTpw+0nvstwReMsjPoj7ZR80/BbixulhLaiX+fbv8oeLW8WZlJMcsGQsTmMKT/iTZu1Uy/lQ==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.4.2.tgz", + "integrity": "sha512-j35yw0PMTPpZsUoOBiuHzr1zTYoad1cVIE0ajEjcrJONxxrko/IRGKkXx3os0Nsi4Hu3+5VmDbVfq5WhG/pWAg==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -1524,12 +10932,89 @@ "@types/node": "*", "@types/yargs": "^16.0.0", "chalk": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" } }, "@project-serum/borsh": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@project-serum/borsh/-/borsh-0.2.2.tgz", - "integrity": "sha512-Ms+aWmGVW6bWd3b0+MWwoaYig2QD0F90h0uhr7AzY3dpCb5e2S6RsRW02vFTfa085pY2VLB7nTZNbFECQ1liTg==", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@project-serum/borsh/-/borsh-0.2.3.tgz", + "integrity": "sha512-lH9zEYADZE3cxrgiFym8+jbUE3NM/LH+WOKYcUjs65CT10Q64Hv45bcAAa/phwYk4Tpz0uQ1x+ergFaAoGt67Q==", "requires": { "bn.js": "^5.1.2", "buffer-layout": "^1.2.0" @@ -1554,16 +11039,16 @@ } }, "@solana/buffer-layout": { - "version": "3.0.0", - "resolved": false, - "integrity": "sha512-MVdgAKKL39tEs0l8je0hKaXLQFb7Rdfb0Xg2LjFZd8Lfdazkg6xiS98uAZrEKvaoF3i4M95ei9RydkGIDMeo3w==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.0.tgz", + "integrity": "sha512-lR0EMP2HC3+Mxwd4YcnZb0smnaDw7Bl2IQWZiTevRH5ZZBZn6VRWn3/92E3qdU4SSImJkA6IDHawOHAnx/qUvQ==", "requires": { "buffer": "~6.0.3" } }, "@solana/spl-token": { "version": "0.1.8", - "resolved": false, + "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.1.8.tgz", "integrity": "sha512-LZmYCKcPQDtJgecvWOgT/cnoIQPWjdH+QVyzPcFvyDUiT0DiRjZaam4aqNUyvchLFhzgunv3d9xOoyE34ofdoQ==", "requires": { "@babel/runtime": "^7.10.5", @@ -1575,9 +11060,9 @@ } }, "@solana/web3.js": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.30.2.tgz", - "integrity": "sha512-hznCj+rkfvM5taRP3Z+l5lumB7IQnDrB4l55Wpsg4kDU9Zds8pE5YOH5Z9bbF/pUzZJKQjyBjnY/6kScBm3Ugg==", + "version": "1.31.0", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.31.0.tgz", + "integrity": "sha512-7nHHx1JNFnrt15e9y8m38I/EJCbaB+bFC3KZVM1+QhybCikFxGMtGA5r7PDC3GEL1R2RZA8yKoLkDKo3vzzqnw==", "requires": { "@babel/runtime": "^7.12.5", "@ethersproject/sha2": "^5.5.0", @@ -1595,28 +11080,28 @@ "tweetnacl": "^1.0.0" }, "dependencies": { - "@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "requires": { - "@types/node": "*" - } - }, - "borsh": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/borsh/-/borsh-0.4.0.tgz", - "integrity": "sha512-aX6qtLya3K0AkT66CmYWCCDr77qsE9arV05OmdFpmat9qu8Pg9J5tBUPDztAW5fNh/d/MyVG/OYziP52Ndzx1g==", + "@solana/buffer-layout": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-3.0.0.tgz", + "integrity": "sha512-MVdgAKKL39tEs0l8je0hKaXLQFb7Rdfb0Xg2LjFZd8Lfdazkg6xiS98uAZrEKvaoF3i4M95ei9RydkGIDMeo3w==", "requires": { - "@types/bn.js": "^4.11.5", - "bn.js": "^5.0.0", - "bs58": "^4.0.0", - "text-encoding-utf-8": "^1.0.2" + "buffer": "~6.0.3" + }, + "dependencies": { + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + } } }, "buffer": { "version": "6.0.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.1.tgz", "integrity": "sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ==", "requires": { "base64-js": "^1.3.1", @@ -1632,9 +11117,9 @@ "dev": true }, "@types/babel__core": { - "version": "7.1.16", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.16.tgz", - "integrity": "sha512-EAEHtisTMM+KaKwfWdC3oyllIqswlznXCIVCt7/oRNrh+DhgT4UEBNC/jlADNjvw7UnfbcdkGQcPVZ1xYiLcrQ==", + "version": "7.1.17", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.17.tgz", + "integrity": "sha512-6zzkezS9QEIL8yCBvXWxPTJPNuMeECJVxSOhxNY/jfq9LxOTHivaYTqr37n9LknWWRTIkzqH2UilS5QFvfa90A==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -1645,9 +11130,9 @@ } }, "@types/babel__generator": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.3.tgz", - "integrity": "sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", "dev": true, "requires": { "@babel/types": "^7.0.0" @@ -1683,16 +11168,16 @@ }, "@types/connect": { "version": "3.4.35", - "resolved": false, + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", "requires": { "@types/node": "*" } }, "@types/express-serve-static-core": { - "version": "4.17.24", - "resolved": false, - "integrity": "sha512-3UJuW+Qxhzwjq3xhwXm2onQcFHn76frIYVbTu+kn24LFxI+dEhdfISDFovPB8VpEgW8oQCTpRuCe+0zJxB7NEA==", + "version": "4.17.27", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.27.tgz", + "integrity": "sha512-e/sVallzUTPdyOTiqi8O8pMdBBphscvI6E4JYaKlja4Lm+zh7UFSSdW5VMkRbhDtmrONqOUHOXRguPsDckzxNA==", "requires": { "@types/node": "*", "@types/qs": "*", @@ -1709,9 +11194,9 @@ } }, "@types/istanbul-lib-coverage": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", "dev": true }, "@types/istanbul-lib-report": { @@ -1742,15 +11227,21 @@ "pretty-format": "^27.0.0" } }, + "@types/json-schema": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "dev": true + }, "@types/lodash": { - "version": "4.14.172", - "resolved": false, - "integrity": "sha512-/BHF5HAx3em7/KkzVKm3LrsD6HZAXuXO1AJZQ3cRRBZj4oHZDviWPYu0aEplAqDFNHZPW6d3G7KN+ONcCCC7pw==" + "version": "4.14.178", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.178.tgz", + "integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==" }, "@types/node": { - "version": "16.9.1", - "resolved": false, - "integrity": "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==" + "version": "17.0.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.5.tgz", + "integrity": "sha512-w3mrvNXLeDYV1GKTZorGJQivK6XLCoGwpnyJFbJVK/aTBQUxOCaa/GlFAAN3OTDFcb7h5tiFG+YXCO2By+riZw==" }, "@types/prettier": { "version": "2.4.2", @@ -1760,12 +11251,12 @@ }, "@types/qs": { "version": "6.9.7", - "resolved": false, + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" }, "@types/range-parser": { "version": "1.2.4", - "resolved": false, + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, "@types/stack-utils": { @@ -1776,7 +11267,7 @@ }, "@types/ws": { "version": "7.4.7", - "resolved": false, + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", "requires": { "@types/node": "*" @@ -1797,13 +11288,133 @@ "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", "dev": true }, - "JSONStream": { - "version": "1.3.5", - "resolved": false, - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "@typescript-eslint/eslint-plugin": { + "version": "5.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.8.1.tgz", + "integrity": "sha512-wTZ5oEKrKj/8/366qTM366zqhIKAp6NCMweoRONtfuC07OAU9nVI2GZZdqQ1qD30WAAtcPdkH+npDwtRFdp4Rw==", + "dev": true, "requires": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" + "@typescript-eslint/experimental-utils": "5.8.1", + "@typescript-eslint/scope-manager": "5.8.1", + "debug": "^4.3.2", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.1.8", + "regexpp": "^3.2.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "dependencies": { + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "@typescript-eslint/experimental-utils": { + "version": "5.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.8.1.tgz", + "integrity": "sha512-fbodVnjIDU4JpeXWRDsG5IfIjYBxEvs8EBO8W1+YVdtrc2B9ppfof5sZhVEDOtgTfFHnYQJDI8+qdqLYO4ceww==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.8.1", + "@typescript-eslint/types": "5.8.1", + "@typescript-eslint/typescript-estree": "5.8.1", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "dependencies": { + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + } + } + }, + "@typescript-eslint/parser": { + "version": "5.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.8.1.tgz", + "integrity": "sha512-K1giKHAjHuyB421SoXMXFHHVI4NdNY603uKw92++D3qyxSeYvC10CBJ/GE5Thpo4WTUvu1mmJI2/FFkz38F2Gw==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.8.1", + "@typescript-eslint/types": "5.8.1", + "@typescript-eslint/typescript-estree": "5.8.1", + "debug": "^4.3.2" + } + }, + "@typescript-eslint/scope-manager": { + "version": "5.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.8.1.tgz", + "integrity": "sha512-DGxJkNyYruFH3NIZc3PwrzwOQAg7vvgsHsHCILOLvUpupgkwDZdNq/cXU3BjF4LNrCsVg0qxEyWasys5AiJ85Q==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.8.1", + "@typescript-eslint/visitor-keys": "5.8.1" + } + }, + "@typescript-eslint/types": { + "version": "5.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.8.1.tgz", + "integrity": "sha512-L/FlWCCgnjKOLefdok90/pqInkomLnAcF9UAzNr+DSqMC3IffzumHTQTrINXhP1gVp9zlHiYYjvozVZDPleLcA==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.8.1.tgz", + "integrity": "sha512-26lQ8l8tTbG7ri7xEcCFT9ijU5Fk+sx/KRRyyzCv7MQ+rZZlqiDPtMKWLC8P7o+dtCnby4c+OlxuX1tp8WfafQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.8.1", + "@typescript-eslint/visitor-keys": "5.8.1", + "debug": "^4.3.2", + "globby": "^11.0.4", + "is-glob": "^4.0.3", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "dependencies": { + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.8.1.tgz", + "integrity": "sha512-SWgiWIwocK6NralrJarPZlWdr0hZnj5GXHIgfdm8hNkyKvpeQuFyLP6YjSIe9kf3YBIfU6OHSZLYkQ+smZwtNg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.8.1", + "eslint-visitor-keys": "^3.0.0" } }, "abab": { @@ -1813,9 +11424,9 @@ "dev": true }, "acorn": { - "version": "8.5.0", - "resolved": false, - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", "dev": true }, "acorn-globals": { @@ -1833,15 +11444,22 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true - }, - "acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "dev": true } } }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "requires": {} + }, + "acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true + }, "agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -1851,6 +11469,24 @@ "debug": "4" } }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, "ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -1860,23 +11496,65 @@ "type-fest": "^0.21.3" } }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, "ansi-styles": { - "version": "4.3.0", - "resolved": false, - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "color-convert": "^2.0.1" + "color-convert": "^1.9.0" } }, "anymatch": { "version": "3.1.2", - "resolved": false, + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "array-includes": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", + "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.7" + } + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "array.prototype.flatmap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.5.tgz", + "integrity": "sha512-08u6rVyi1Lj7oqWbS9nUxliETrtIROT4XGTA4D/LWGten6E3ocm7cy9SIrmNHOL5XVbVuckUp3X6Xyg8/zpvHA==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0" } }, "asynckit": { @@ -1886,19 +11564,70 @@ "dev": true }, "babel-jest": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.3.1.tgz", - "integrity": "sha512-SjIF8hh/ir0peae2D6S6ZKRhUy7q/DnpH7k/V6fT4Bgs/LXXUztOpX4G2tCgq8mLo5HA9mN6NmlFMeYtKmIsTQ==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.4.5.tgz", + "integrity": "sha512-3uuUTjXbgtODmSv/DXO9nZfD52IyC2OYTFaXGRzL0kpykzroaquCrD5+lZNafTvZlnNqZHt5pb0M08qVBZnsnA==", "dev": true, "requires": { - "@jest/transform": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/transform": "^27.4.5", + "@jest/types": "^27.4.2", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^27.2.0", + "babel-preset-jest": "^27.4.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "slash": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "babel-plugin-dynamic-import-node": { @@ -1939,9 +11668,9 @@ } }, "babel-plugin-jest-hoist": { - "version": "27.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.2.0.tgz", - "integrity": "sha512-TOux9khNKdi64mW+0OIhcmbAn75tTlzKhxmiNXevQaPbrBYK7YKjP1jl6NHTJ6XR5UgUrJbCnWlKVnJn29dfjw==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.4.0.tgz", + "integrity": "sha512-Jcu7qS4OX5kTWBc45Hz7BMmgXuJqRnhatqpUhnzGC3OBYpOmf2tv6jFNwZpwM7wU7MUuv2r9IPS/ZlYOuburVw==", "dev": true, "requires": { "@babel/template": "^7.3.3", @@ -2001,32 +11730,32 @@ } }, "babel-preset-jest": { - "version": "27.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.2.0.tgz", - "integrity": "sha512-z7MgQ3peBwN5L5aCqBKnF6iqdlvZvFUQynEhu0J+X9nHLU72jO3iY331lcYrg+AssJ8q7xsv5/3AICzVmJ/wvg==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.4.0.tgz", + "integrity": "sha512-NK4jGYpnBvNxcGo7/ZpZJr51jCGT+3bwwpVIDY2oNfTxJJldRtB4VAcYdgp1loDE50ODuTu+yBjpMAswv5tlpg==", "dev": true, "requires": { - "babel-plugin-jest-hoist": "^27.2.0", + "babel-plugin-jest-hoist": "^27.4.0", "babel-preset-current-node-syntax": "^1.0.0" } }, "balanced-match": { "version": "1.0.2", - "resolved": false, + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "base-x": { - "version": "3.0.8", - "resolved": false, - "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", "requires": { "safe-buffer": "^5.0.1" } }, "base64-js": { "version": "1.5.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, "bn.js": { @@ -2034,9 +11763,30 @@ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" }, + "borsh": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/borsh/-/borsh-0.4.0.tgz", + "integrity": "sha512-aX6qtLya3K0AkT66CmYWCCDr77qsE9arV05OmdFpmat9qu8Pg9J5tBUPDztAW5fNh/d/MyVG/OYziP52Ndzx1g==", + "requires": { + "@types/bn.js": "^4.11.5", + "bn.js": "^5.0.0", + "bs58": "^4.0.0", + "text-encoding-utf-8": "^1.0.2" + }, + "dependencies": { + "@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "requires": { + "@types/node": "*" + } + } + } + }, "brace-expansion": { "version": "1.1.11", - "resolved": false, + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { @@ -2046,7 +11796,7 @@ }, "braces": { "version": "3.0.2", - "resolved": false, + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, "requires": { @@ -2055,7 +11805,7 @@ }, "brorand": { "version": "1.1.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" }, "browser-process-hrtime": { @@ -2065,13 +11815,13 @@ "dev": true }, "browserslist": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.18.1.tgz", - "integrity": "sha512-8ScCzdpPwR2wQh8IT82CA2VgDwjHyqMovPBZSNH54+tm4Jk2pCuv90gmAdH6J84OCRWi0b4gMe6O6XPXuJnjgQ==", + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", + "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001280", - "electron-to-chromium": "^1.3.896", + "caniuse-lite": "^1.0.30001286", + "electron-to-chromium": "^1.4.17", "escalade": "^3.1.1", "node-releases": "^2.0.1", "picocolors": "^1.0.0" @@ -2079,7 +11829,7 @@ }, "bs58": { "version": "4.0.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", "requires": { "base-x": "^3.0.2" @@ -2096,7 +11846,7 @@ }, "buffer": { "version": "6.0.3", - "resolved": false, + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "requires": { "base64-js": "^1.3.1", @@ -2105,22 +11855,22 @@ }, "buffer-from": { "version": "1.1.2", - "resolved": false, + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, "buffer-layout": { "version": "1.2.2", - "resolved": false, + "resolved": "https://registry.npmjs.org/buffer-layout/-/buffer-layout-1.2.2.tgz", "integrity": "sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==" }, "bufferutil": { - "version": "4.0.3", - "resolved": false, - "integrity": "sha512-yEYTwGndELGvfXsImMBLop58eaGW+YdONi1fNjTINSY98tmMmFijBG6WXgdkfuLNt4imzQNtIE+eBp1PVpMCSw==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.5.tgz", + "integrity": "sha512-HTm14iMQKK2FjFLRTM5lAVcyaUzOnqbPtesFIvREgXpJHdQm8bWS+GkQgIkfaBYRHuCnea7w8UVNfwiAQhlr9A==", "optional": true, "requires": { - "node-gyp-build": "^4.2.0" + "node-gyp-build": "^4.3.0" } }, "call-bind": { @@ -2140,36 +11890,26 @@ "dev": true }, "camelcase": { - "version": "6.2.0", - "resolved": false, - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, "caniuse-lite": { - "version": "1.0.30001280", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001280.tgz", - "integrity": "sha512-kFXwYvHe5rix25uwueBxC569o53J6TpnGu0BEEn+6Lhl2vsnAumRFWEBhDft1fwyo6m1r4i+RqA4+163FpeFcA==", + "version": "1.0.30001294", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001294.tgz", + "integrity": "sha512-LiMlrs1nSKZ8qkNhpUf5KD0Al1KCBE3zaT7OLOwEkagXMEDij98SiOovn9wxVGQpklk9vVC/pUSqgYmkmKOS8g==", "dev": true }, "chalk": { - "version": "4.1.2", - "resolved": false, - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "dependencies": { - "supports-color": { - "version": "7.2.0", - "resolved": false, - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, "char-regex": { @@ -2179,14 +11919,14 @@ "dev": true }, "ci-info": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", - "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", + "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", "dev": true }, "circular-json": { "version": "0.5.9", - "resolved": false, + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.9.tgz", "integrity": "sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ==" }, "cjs-module-lexer": { @@ -2197,47 +11937,13 @@ }, "cliui": { "version": "7.0.4", - "resolved": false, + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": false, - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": false, - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.2", - "resolved": false, - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": false, - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } } }, "co": { @@ -2253,18 +11959,18 @@ "dev": true }, "color-convert": { - "version": "2.0.1", - "resolved": false, - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "requires": { - "color-name": "~1.1.4" + "color-name": "1.1.3" } }, "color-name": { - "version": "1.1.4", - "resolved": false, - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, "combined-stream": { @@ -2278,12 +11984,12 @@ }, "commander": { "version": "2.20.3", - "resolved": false, + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, "concat-map": { "version": "0.0.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, @@ -2305,12 +12011,12 @@ } }, "core-js-compat": { - "version": "3.19.3", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.19.3.tgz", - "integrity": "sha512-59tYzuWgEEVU9r+SRgceIGXSSUn47JknoiXW6Oq7RW8QHjXWz3/vp8pa7dbtuVu40sewz3OP3JmQEcDdztrLhA==", + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.20.1.tgz", + "integrity": "sha512-AVhKZNpqMV3Jz8hU0YEXXE06qoxtQGsAqU0u1neUngz5IusDJRX/ZJ6t3i7mS7QxNyEONbCo14GprkBrxPlTZA==", "dev": true, "requires": { - "browserslist": "^4.18.1", + "browserslist": "^4.19.1", "semver": "7.0.0" }, "dependencies": { @@ -2324,7 +12030,7 @@ }, "cross-fetch": { "version": "3.1.4", - "resolved": false, + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz", "integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==", "requires": { "node-fetch": "2.6.1" @@ -2376,20 +12082,12 @@ } }, "debug": { - "version": "4.3.1", - "resolved": false, - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, "requires": { "ms": "2.1.2" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "resolved": false, - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } } }, "decimal.js": { @@ -2427,7 +12125,7 @@ }, "delay": { "version": "5.0.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==" }, "delayed-stream": { @@ -2443,11 +12141,29 @@ "dev": true }, "diff-sequences": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", - "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.4.0.tgz", + "integrity": "sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww==", "dev": true }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, "domexception": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", @@ -2467,18 +12183,18 @@ }, "dotenv": { "version": "10.0.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" }, "electron-to-chromium": { - "version": "1.3.899", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.899.tgz", - "integrity": "sha512-w16Dtd2zl7VZ4N4Db+FIa7n36sgPGCKjrKvUUmp5ialsikvcQLjcJR9RWnlYNxIyEHLdHaoIZEqKsPxU9MdyBg==", + "version": "1.4.30", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.30.tgz", + "integrity": "sha512-609z9sIMxDHg+TcR/VB3MXwH+uwtrYyeAwWc/orhnr90ixs6WVGSrt85CDLGUdNnLqCA7liv426V20EecjvflQ==", "dev": true }, "elliptic": { "version": "6.5.4", - "resolved": false, + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", "requires": { "bn.js": "^4.11.9", @@ -2490,55 +12206,371 @@ "minimalistic-crypto-utils": "^1.0.1" }, "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": false, - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + } + } + }, + "emittery": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", + "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "es-abstract": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", + "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", + "is-string": "^1.0.7", + "is-weakref": "^1.0.1", + "object-inspect": "^1.11.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "requires": { + "es6-promise": "^4.0.3" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "escodegen": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "dev": true, + "requires": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + } + } + }, + "eslint": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.5.0.tgz", + "integrity": "sha512-tVGSkgNbOfiHyVte8bCM8OmX+xG9PzVG/B4UCF60zx7j61WIVY/AqJECDgpLD4DbbESD0e174gOg3ZlrX15GDg==", + "dev": true, + "requires": { + "@eslint/eslintrc": "^1.0.5", + "@humanwhocodes/config-array": "^0.9.2", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.0", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.1.0", + "espree": "^9.2.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.2.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "globals": { + "version": "13.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", + "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } + } + }, + "eslint-plugin-react": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.28.0.tgz", + "integrity": "sha512-IOlFIRHzWfEQQKcAD4iyYDndHwTQiCMcJVJjxempf203jnNLUnW34AXLrV33+nEXoifJE2ZEGmcjKPL8957eSw==", + "dev": true, + "requires": { + "array-includes": "^3.1.4", + "array.prototype.flatmap": "^1.2.5", + "doctrine": "^2.1.0", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.0.4", + "object.entries": "^1.1.5", + "object.fromentries": "^2.0.5", + "object.hasown": "^1.1.0", + "object.values": "^1.1.5", + "prop-types": "^15.7.2", + "resolve": "^2.0.0-next.3", + "semver": "^6.3.0", + "string.prototype.matchall": "^4.0.6" + }, + "dependencies": { + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "resolve": { + "version": "2.0.0-next.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz", + "integrity": "sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } } } }, - "emittery": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", - "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": false, - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "es6-promise": { - "version": "4.2.8", - "resolved": false, - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + "eslint-scope": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.0.tgz", + "integrity": "sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } }, - "es6-promisify": { - "version": "5.0.0", - "resolved": false, - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, "requires": { - "es6-promise": "^4.0.3" + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + } } }, - "escalade": { - "version": "3.1.1", - "resolved": false, - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "eslint-visitor-keys": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz", + "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==", "dev": true }, - "escodegen": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", - "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "espree": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.2.0.tgz", + "integrity": "sha512-oP3utRkynpZWF/F2x/HZJ+AGtnIclaR7z1pYPxy7NYM2fSO6LgK/Rkny8anRSPK/VwEA1eqm2squui0T7ZMOBg==", "dev": true, "requires": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" + "acorn": "^8.6.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^3.1.0" } }, "esprima": { @@ -2547,6 +12579,24 @@ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + } + }, "estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", @@ -2561,7 +12611,7 @@ }, "eventemitter3": { "version": "4.0.7", - "resolved": false, + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" }, "execa": { @@ -2588,17 +12638,17 @@ "dev": true }, "expect": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.3.1.tgz", - "integrity": "sha512-MrNXV2sL9iDRebWPGOGFdPQRl2eDQNu/uhxIMShjjx74T6kC6jFIkmQ6OqXDtevjGUkyB2IT56RzDBqXf/QPCg==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.4.2.tgz", + "integrity": "sha512-BjAXIDC6ZOW+WBFNg96J22D27Nq5ohn+oGcuP2rtOtcjuxNoV9McpQ60PcQWhdFOSBIQdR72e+4HdnbZTFSTyg==", "dev": true, "requires": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "ansi-styles": "^5.0.0", - "jest-get-type": "^27.3.1", - "jest-matcher-utils": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-regex-util": "^27.0.6" + "jest-get-type": "^27.4.0", + "jest-matcher-utils": "^27.4.2", + "jest-message-util": "^27.4.2", + "jest-regex-util": "^27.4.0" }, "dependencies": { "ansi-styles": { @@ -2611,9 +12661,39 @@ }, "eyes": { "version": "0.1.8", - "resolved": false, + "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=" }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-glob": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -2626,6 +12706,15 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, "fb-watchman": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", @@ -2635,15 +12724,50 @@ "bser": "2.1.1" } }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, "fill-range": { "version": "7.0.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, "requires": { "to-regex-range": "^5.0.1" } }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz", + "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==", + "dev": true + }, "form-data": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", @@ -2657,13 +12781,13 @@ }, "fs.realpath": { "version": "1.0.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, "fsevents": { "version": "2.3.2", - "resolved": false, + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, "optional": true @@ -2674,6 +12798,12 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -2682,7 +12812,7 @@ }, "get-caller-file": { "version": "2.0.5", - "resolved": false, + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, @@ -2709,10 +12839,20 @@ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true }, + "get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, "glob": { - "version": "7.1.6", - "resolved": false, - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -2723,12 +12863,43 @@ "path-is-absolute": "^1.0.0" } }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, + "globby": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "dependencies": { + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true + } + } + }, "graceful-fs": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", @@ -2744,10 +12915,16 @@ "function-bind": "^1.1.1" } }, + "has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true + }, "has-flag": { - "version": "4.0.0", - "resolved": false, - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, "has-symbols": { @@ -2756,9 +12933,18 @@ "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", "dev": true }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, "hash.js": { "version": "1.1.7", - "resolved": false, + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", "requires": { "inherits": "^2.0.3", @@ -2767,7 +12953,7 @@ }, "hmac-drbg": { "version": "1.0.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", "requires": { "hash.js": "^1.0.3", @@ -2828,9 +13014,25 @@ }, "ieee754": { "version": "1.2.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, "import-local": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.3.tgz", @@ -2839,54 +13041,6 @@ "requires": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - } } }, "imurmurhash": { @@ -2897,7 +13051,7 @@ }, "inflight": { "version": "1.0.6", - "resolved": false, + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "requires": { @@ -2907,9 +13061,45 @@ }, "inherits": { "version": "2.0.4", - "resolved": false, + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + } + }, + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "requires": { + "has-bigints": "^1.0.1" + } + }, + "is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "dev": true + }, "is-core-module": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", @@ -2919,46 +13109,135 @@ "has": "^1.0.3" } }, + "is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, "is-generator-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true + }, "is-number": { "version": "7.0.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "is-number-object": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", + "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, "is-potential-custom-element-name": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", "dev": true }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-shared-array-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", + "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", + "dev": true + }, "is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, + "is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, "isexe": { "version": "2.0.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, "isomorphic-ws": { "version": "4.0.1", - "resolved": false, - "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==" + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", + "requires": {} }, "istanbul-lib-coverage": { "version": "3.2.0", @@ -2989,14 +13268,11 @@ "supports-color": "^7.1.0" }, "dependencies": { - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - } + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true }, "supports-color": { "version": "7.2.0", @@ -3018,12 +13294,20 @@ "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, "istanbul-reports": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.5.tgz", - "integrity": "sha512-5+19PlhnGabNWB7kOFnuxT8H3T/iIyQzIbQMxXsURmmvKg86P2sbkrGOT77VnHw0Qr0gc2XzRaRfMZYYbSQCJQ==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.3.tgz", + "integrity": "sha512-x9LtDVtfm/t1GFiLl3NffC7hz+I1ragvgX1P/Lg1NlIagifZDKUkuuaAxH/qpwj2IuEfD8G2Bs/UKp+sZ/pKkg==", "dev": true, "requires": { "html-escaper": "^2.0.0", @@ -3031,294 +13315,703 @@ } }, "jayson": { - "version": "3.6.4", - "resolved": false, - "integrity": "sha512-GH63DsRFFlodS8krFgAhxwYvQFmSwjsFxKnPrHQtp+BJj/tpeSj3hyBGGqmTkuq043U1Gn6u8VdsVRFZX1EEiQ==", + "version": "3.6.6", + "resolved": "https://registry.npmjs.org/jayson/-/jayson-3.6.6.tgz", + "integrity": "sha512-f71uvrAWTtrwoww6MKcl9phQTC+56AopLyEenWvKVAIMz+q0oVGj6tenLZ7Z6UiPBkJtKLj4kt0tACllFQruGQ==", "requires": { "@types/connect": "^3.4.33", "@types/express-serve-static-core": "^4.17.9", "@types/lodash": "^4.14.159", "@types/node": "^12.12.54", "@types/ws": "^7.4.4", - "JSONStream": "^1.3.5", "commander": "^2.20.3", "delay": "^5.0.0", "es6-promisify": "^5.0.0", "eyes": "^0.1.8", "isomorphic-ws": "^4.0.1", "json-stringify-safe": "^5.0.1", + "JSONStream": "^1.3.5", "lodash": "^4.17.20", - "uuid": "^3.4.0", + "uuid": "^8.3.2", "ws": "^7.4.5" }, "dependencies": { "@types/node": { - "version": "12.20.24", - "resolved": false, - "integrity": "sha512-yxDeaQIAJlMav7fH5AQqPH1u8YIuhYJXYBzxaQ4PifsU0GDO38MSdmEDeRlIxrKbC6NbEaaEHDanWb+y30U8SQ==" + "version": "12.20.39", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.39.tgz", + "integrity": "sha512-U7PMwkDmc3bnL0e4U8oA0POpi1vfsYDc+DEUS2+rPxm9NlLcW1dBa5JcRhO633PoPUcCSWMNXrMsqhmAVEo+IQ==" } } }, "jest": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.3.1.tgz", - "integrity": "sha512-U2AX0AgQGd5EzMsiZpYt8HyZ+nSVIh5ujQ9CPp9EQZJMjXIiSZpJNweZl0swatKRoqHWgGKM3zaSwm4Zaz87ng==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.4.5.tgz", + "integrity": "sha512-uT5MiVN3Jppt314kidCk47MYIRilJjA/l2mxwiuzzxGUeJIvA8/pDaJOAX5KWvjAo7SCydcW0/4WEtgbLMiJkg==", "dev": true, "requires": { - "@jest/core": "^27.3.1", + "@jest/core": "^27.4.5", "import-local": "^3.0.2", - "jest-cli": "^27.3.1" + "jest-cli": "^27.4.5" } }, "jest-changed-files": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.3.0.tgz", - "integrity": "sha512-9DJs9garMHv4RhylUMZgbdCJ3+jHSkpL9aaVKp13xtXAD80qLTLrqcDZL1PHA9dYA0bCI86Nv2BhkLpLhrBcPg==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.4.2.tgz", + "integrity": "sha512-/9x8MjekuzUQoPjDHbBiXbNEBauhrPU2ct7m8TfCg69ywt1y/N+yYwGh3gCpnqUS3klYWDU/lSNgv+JhoD2k1A==", "dev": true, "requires": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "execa": "^5.0.0", "throat": "^6.0.1" } }, "jest-circus": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.3.1.tgz", - "integrity": "sha512-v1dsM9II6gvXokgqq6Yh2jHCpfg7ZqV4jWY66u7npz24JnhP3NHxI0sKT7+ZMQ7IrOWHYAaeEllOySbDbWsiXw==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.4.5.tgz", + "integrity": "sha512-eTNWa9wsvBwPykhMMShheafbwyakcdHZaEYh5iRrQ0PFJxkDP/e3U/FvzGuKWu2WpwUA3C3hPlfpuzvOdTVqnw==", "dev": true, "requires": { - "@jest/environment": "^27.3.1", - "@jest/test-result": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/environment": "^27.4.4", + "@jest/test-result": "^27.4.2", + "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", - "expect": "^27.3.1", + "expect": "^27.4.2", "is-generator-fn": "^2.0.0", - "jest-each": "^27.3.1", - "jest-matcher-utils": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-runtime": "^27.3.1", - "jest-snapshot": "^27.3.1", - "jest-util": "^27.3.1", - "pretty-format": "^27.3.1", + "jest-each": "^27.4.2", + "jest-matcher-utils": "^27.4.2", + "jest-message-util": "^27.4.2", + "jest-runtime": "^27.4.5", + "jest-snapshot": "^27.4.5", + "jest-util": "^27.4.2", + "pretty-format": "^27.4.2", "slash": "^3.0.0", "stack-utils": "^2.0.3", "throat": "^6.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "jest-cli": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.3.1.tgz", - "integrity": "sha512-WHnCqpfK+6EvT62me6WVs8NhtbjAS4/6vZJnk7/2+oOr50cwAzG4Wxt6RXX0hu6m1169ZGMlhYYUNeKBXCph/Q==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.4.5.tgz", + "integrity": "sha512-hrky3DSgE0u7sQxaCL7bdebEPHx5QzYmrGuUjaPLmPE8jx5adtvGuOlRspvMoVLTTDOHRnZDoRLYJuA+VCI7Hg==", "dev": true, "requires": { - "@jest/core": "^27.3.1", - "@jest/test-result": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/core": "^27.4.5", + "@jest/test-result": "^27.4.2", + "@jest/types": "^27.4.2", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.4", "import-local": "^3.0.2", - "jest-config": "^27.3.1", - "jest-util": "^27.3.1", - "jest-validate": "^27.3.1", + "jest-config": "^27.4.5", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.2", "prompts": "^2.0.1", "yargs": "^16.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "jest-config": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.3.1.tgz", - "integrity": "sha512-KY8xOIbIACZ/vdYCKSopL44I0xboxC751IX+DXL2+Wx6DKNycyEfV3rryC3BPm5Uq/BBqDoMrKuqLEUNJmMKKg==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.4.5.tgz", + "integrity": "sha512-t+STVJtPt+fpqQ8GBw850NtSQbnDOw/UzdPfzDaHQ48/AylQlW7LHj3dH+ndxhC1UxJ0Q3qkq7IH+nM1skwTwA==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^27.3.1", - "@jest/types": "^27.2.5", - "babel-jest": "^27.3.1", + "@jest/test-sequencer": "^27.4.5", + "@jest/types": "^27.4.2", + "babel-jest": "^27.4.5", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.1", "graceful-fs": "^4.2.4", - "jest-circus": "^27.3.1", - "jest-environment-jsdom": "^27.3.1", - "jest-environment-node": "^27.3.1", - "jest-get-type": "^27.3.1", - "jest-jasmine2": "^27.3.1", - "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.3.1", - "jest-runner": "^27.3.1", - "jest-util": "^27.3.1", - "jest-validate": "^27.3.1", + "jest-circus": "^27.4.5", + "jest-environment-jsdom": "^27.4.4", + "jest-environment-node": "^27.4.4", + "jest-get-type": "^27.4.0", + "jest-jasmine2": "^27.4.5", + "jest-regex-util": "^27.4.0", + "jest-resolve": "^27.4.5", + "jest-runner": "^27.4.5", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.2", "micromatch": "^4.0.4", - "pretty-format": "^27.3.1" + "pretty-format": "^27.4.2", + "slash": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "jest-diff": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.3.1.tgz", - "integrity": "sha512-PCeuAH4AWUo2O5+ksW4pL9v5xJAcIKPUPfIhZBcG1RKv/0+dvaWTQK1Nrau8d67dp65fOqbeMdoil+6PedyEPQ==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.4.2.tgz", + "integrity": "sha512-ujc9ToyUZDh9KcqvQDkk/gkbf6zSaeEg9AiBxtttXW59H/AcqEYp1ciXAtJp+jXWva5nAf/ePtSsgWwE5mqp4Q==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^27.0.6", - "jest-get-type": "^27.3.1", - "pretty-format": "^27.3.1" + "diff-sequences": "^27.4.0", + "jest-get-type": "^27.4.0", + "pretty-format": "^27.4.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "jest-docblock": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.0.6.tgz", - "integrity": "sha512-Fid6dPcjwepTFraz0YxIMCi7dejjJ/KL9FBjPYhBp4Sv1Y9PdhImlKZqYU555BlN4TQKaTc+F2Av1z+anVyGkA==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.4.0.tgz", + "integrity": "sha512-7TBazUdCKGV7svZ+gh7C8esAnweJoG+SvcF6Cjqj4l17zA2q1cMwx2JObSioubk317H+cjcHgP+7fTs60paulg==", "dev": true, "requires": { "detect-newline": "^3.0.0" } }, "jest-each": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.3.1.tgz", - "integrity": "sha512-E4SwfzKJWYcvOYCjOxhZcxwL+AY0uFMvdCOwvzgutJiaiodFjkxQQDxHm8FQBeTqDnSmKsQWn7ldMRzTn2zJaQ==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.4.2.tgz", + "integrity": "sha512-53V2MNyW28CTruB3lXaHNk6PkiIFuzdOC9gR3C6j8YE/ACfrPnz+slB0s17AgU1TtxNzLuHyvNlLJ+8QYw9nBg==", "dev": true, "requires": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "chalk": "^4.0.0", - "jest-get-type": "^27.3.1", - "jest-util": "^27.3.1", - "pretty-format": "^27.3.1" + "jest-get-type": "^27.4.0", + "jest-util": "^27.4.2", + "pretty-format": "^27.4.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "jest-environment-jsdom": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.3.1.tgz", - "integrity": "sha512-3MOy8qMzIkQlfb3W1TfrD7uZHj+xx8Olix5vMENkj5djPmRqndMaXtpnaZkxmxM+Qc3lo+yVzJjzuXbCcZjAlg==", + "version": "27.4.4", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.4.4.tgz", + "integrity": "sha512-cYR3ndNfHBqQgFvS1RL7dNqSvD//K56j/q1s2ygNHcfTCAp12zfIromO1w3COmXrxS8hWAh7+CmZmGCIoqGcGA==", "dev": true, "requires": { - "@jest/environment": "^27.3.1", - "@jest/fake-timers": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/environment": "^27.4.4", + "@jest/fake-timers": "^27.4.2", + "@jest/types": "^27.4.2", "@types/node": "*", - "jest-mock": "^27.3.0", - "jest-util": "^27.3.1", + "jest-mock": "^27.4.2", + "jest-util": "^27.4.2", "jsdom": "^16.6.0" } }, "jest-environment-node": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.3.1.tgz", - "integrity": "sha512-T89F/FgkE8waqrTSA7/ydMkcc52uYPgZZ6q8OaZgyiZkJb5QNNCF6oPZjH9IfPFfcc9uBWh1574N0kY0pSvTXw==", + "version": "27.4.4", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.4.4.tgz", + "integrity": "sha512-D+v3lbJ2GjQTQR23TK0kY3vFVmSeea05giInI41HHOaJnAwOnmUHTZgUaZL+VxUB43pIzoa7PMwWtCVlIUoVoA==", "dev": true, "requires": { - "@jest/environment": "^27.3.1", - "@jest/fake-timers": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/environment": "^27.4.4", + "@jest/fake-timers": "^27.4.2", + "@jest/types": "^27.4.2", "@types/node": "*", - "jest-mock": "^27.3.0", - "jest-util": "^27.3.1" + "jest-mock": "^27.4.2", + "jest-util": "^27.4.2" } }, "jest-get-type": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.3.1.tgz", - "integrity": "sha512-+Ilqi8hgHSAdhlQ3s12CAVNd8H96ZkQBfYoXmArzZnOfAtVAJEiPDBirjByEblvG/4LPJmkL+nBqPO3A1YJAEg==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.4.0.tgz", + "integrity": "sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ==", "dev": true }, "jest-haste-map": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.3.1.tgz", - "integrity": "sha512-lYfNZIzwPccDJZIyk9Iz5iQMM/MH56NIIcGj7AFU1YyA4ewWFBl8z+YPJuSCRML/ee2cCt2y3W4K3VXPT6Nhzg==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.4.5.tgz", + "integrity": "sha512-oJm1b5qhhPs78K24EDGifWS0dELYxnoBiDhatT/FThgB9yxqUm5F6li3Pv+Q+apMBmmPNzOBnZ7ZxWMB1Leq1Q==", "dev": true, "requires": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "@types/graceful-fs": "^4.1.2", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "fsevents": "^2.3.2", "graceful-fs": "^4.2.4", - "jest-regex-util": "^27.0.6", - "jest-serializer": "^27.0.6", - "jest-util": "^27.3.1", - "jest-worker": "^27.3.1", + "jest-regex-util": "^27.4.0", + "jest-serializer": "^27.4.0", + "jest-util": "^27.4.2", + "jest-worker": "^27.4.5", "micromatch": "^4.0.4", "walker": "^1.0.7" } }, "jest-jasmine2": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.3.1.tgz", - "integrity": "sha512-WK11ZUetDQaC09w4/j7o4FZDUIp+4iYWH/Lik34Pv7ukL+DuXFGdnmmi7dT58J2ZYKFB5r13GyE0z3NPeyJmsg==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.4.5.tgz", + "integrity": "sha512-oUnvwhJDj2LhOiUB1kdnJjkx8C5PwgUZQb9urF77mELH9DGR4e2GqpWQKBOYXWs5+uTN9BGDqRz3Aeg5Wts7aw==", "dev": true, "requires": { "@babel/traverse": "^7.1.0", - "@jest/environment": "^27.3.1", - "@jest/source-map": "^27.0.6", - "@jest/test-result": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/environment": "^27.4.4", + "@jest/source-map": "^27.4.0", + "@jest/test-result": "^27.4.2", + "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "expect": "^27.3.1", + "expect": "^27.4.2", "is-generator-fn": "^2.0.0", - "jest-each": "^27.3.1", - "jest-matcher-utils": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-runtime": "^27.3.1", - "jest-snapshot": "^27.3.1", - "jest-util": "^27.3.1", - "pretty-format": "^27.3.1", + "jest-each": "^27.4.2", + "jest-matcher-utils": "^27.4.2", + "jest-message-util": "^27.4.2", + "jest-runtime": "^27.4.5", + "jest-snapshot": "^27.4.5", + "jest-util": "^27.4.2", + "pretty-format": "^27.4.2", "throat": "^6.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "jest-leak-detector": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.3.1.tgz", - "integrity": "sha512-78QstU9tXbaHzwlRlKmTpjP9k4Pvre5l0r8Spo4SbFFVy/4Abg9I6ZjHwjg2QyKEAMg020XcjP+UgLZIY50yEg==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.4.2.tgz", + "integrity": "sha512-ml0KvFYZllzPBJWDei3mDzUhyp/M4ubKebX++fPaudpe8OsxUE+m+P6ciVLboQsrzOCWDjE20/eXew9QMx/VGw==", "dev": true, "requires": { - "jest-get-type": "^27.3.1", - "pretty-format": "^27.3.1" + "jest-get-type": "^27.4.0", + "pretty-format": "^27.4.2" } }, "jest-matcher-utils": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.3.1.tgz", - "integrity": "sha512-hX8N7zXS4k+8bC1Aj0OWpGb7D3gIXxYvPNK1inP5xvE4ztbz3rc4AkI6jGVaerepBnfWB17FL5lWFJT3s7qo8w==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.4.2.tgz", + "integrity": "sha512-jyP28er3RRtMv+fmYC/PKG8wvAmfGcSNproVTW2Y0P/OY7/hWUOmsPfxN1jOhM+0u2xU984u2yEagGivz9OBGQ==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^27.3.1", - "jest-get-type": "^27.3.1", - "pretty-format": "^27.3.1" + "jest-diff": "^27.4.2", + "jest-get-type": "^27.4.0", + "pretty-format": "^27.4.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "jest-message-util": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.3.1.tgz", - "integrity": "sha512-bh3JEmxsTZ/9rTm0jQrPElbY2+y48Rw2t47uMfByNyUVR+OfPh4anuyKsGqsNkXk/TI4JbLRZx+7p7Hdt6q1yg==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.4.2.tgz", + "integrity": "sha512-OMRqRNd9E0DkBLZpFtZkAGYOXl6ZpoMtQJWTAREJKDOFa0M6ptB7L67tp+cszMBkvSgKOhNtQp2Vbcz3ZZKo/w==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.4", - "pretty-format": "^27.3.1", + "pretty-format": "^27.4.2", "slash": "^3.0.0", "stack-utils": "^2.0.3" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "jest-mock": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.3.0.tgz", - "integrity": "sha512-ziZiLk0elZOQjD08bLkegBzv5hCABu/c8Ytx45nJKkysQwGaonvmTxwjLqEA4qGdasq9o2I8/HtdGMNnVsMTGw==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.4.2.tgz", + "integrity": "sha512-PDDPuyhoukk20JrQKeofK12hqtSka7mWH0QQuxSNgrdiPsrnYYLS6wbzu/HDlxZRzji5ylLRULeuI/vmZZDrYA==", "dev": true, "requires": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "@types/node": "*" } }, @@ -3326,86 +14019,189 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true + "dev": true, + "requires": {} }, "jest-regex-util": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.6.tgz", - "integrity": "sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.4.0.tgz", + "integrity": "sha512-WeCpMpNnqJYMQoOjm1nTtsgbR4XHAk1u00qDoNBQoykM280+/TmgA5Qh5giC1ecy6a5d4hbSsHzpBtu5yvlbEg==", "dev": true }, "jest-resolve": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.3.1.tgz", - "integrity": "sha512-Dfzt25CFSPo3Y3GCbxynRBZzxq9AdyNN+x/v2IqYx6KVT5Z6me2Z/PsSGFSv3cOSUZqJ9pHxilao/I/m9FouLw==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.4.5.tgz", + "integrity": "sha512-xU3z1BuOz/hUhVUL+918KqUgK+skqOuUsAi7A+iwoUldK6/+PW+utK8l8cxIWT9AW7IAhGNXjSAh1UYmjULZZw==", "dev": true, "requires": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.1", + "jest-haste-map": "^27.4.5", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.3.1", - "jest-validate": "^27.3.1", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.2", "resolve": "^1.20.0", "resolve.exports": "^1.1.0", "slash": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "jest-resolve-dependencies": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.3.1.tgz", - "integrity": "sha512-X7iLzY8pCiYOnvYo2YrK3P9oSE8/3N2f4pUZMJ8IUcZnT81vlSonya1KTO9ZfKGuC+svE6FHK/XOb8SsoRUV1A==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.4.5.tgz", + "integrity": "sha512-elEVvkvRK51y037NshtEkEnukMBWvlPzZHiL847OrIljJ8yIsujD2GXRPqDXC4rEVKbcdsy7W0FxoZb4WmEs7w==", "dev": true, "requires": { - "@jest/types": "^27.2.5", - "jest-regex-util": "^27.0.6", - "jest-snapshot": "^27.3.1" + "@jest/types": "^27.4.2", + "jest-regex-util": "^27.4.0", + "jest-snapshot": "^27.4.5" } }, "jest-runner": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.3.1.tgz", - "integrity": "sha512-r4W6kBn6sPr3TBwQNmqE94mPlYVn7fLBseeJfo4E2uCTmAyDFm2O5DYAQAFP7Q3YfiA/bMwg8TVsciP7k0xOww==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.4.5.tgz", + "integrity": "sha512-/irauncTfmY1WkTaRQGRWcyQLzK1g98GYG/8QvIPviHgO1Fqz1JYeEIsSfF+9mc/UTA6S+IIHFgKyvUrtiBIZg==", "dev": true, "requires": { - "@jest/console": "^27.3.1", - "@jest/environment": "^27.3.1", - "@jest/test-result": "^27.3.1", - "@jest/transform": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/console": "^27.4.2", + "@jest/environment": "^27.4.4", + "@jest/test-result": "^27.4.2", + "@jest/transform": "^27.4.5", + "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", "emittery": "^0.8.1", "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-docblock": "^27.0.6", - "jest-environment-jsdom": "^27.3.1", - "jest-environment-node": "^27.3.1", - "jest-haste-map": "^27.3.1", - "jest-leak-detector": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-resolve": "^27.3.1", - "jest-runtime": "^27.3.1", - "jest-util": "^27.3.1", - "jest-worker": "^27.3.1", + "jest-docblock": "^27.4.0", + "jest-environment-jsdom": "^27.4.4", + "jest-environment-node": "^27.4.4", + "jest-haste-map": "^27.4.5", + "jest-leak-detector": "^27.4.2", + "jest-message-util": "^27.4.2", + "jest-resolve": "^27.4.5", + "jest-runtime": "^27.4.5", + "jest-util": "^27.4.2", + "jest-worker": "^27.4.5", "source-map-support": "^0.5.6", "throat": "^6.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "jest-runtime": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.3.1.tgz", - "integrity": "sha512-qtO6VxPbS8umqhEDpjA4pqTkKQ1Hy4ZSi9mDVeE9Za7LKBo2LdW2jmT+Iod3XFaJqINikZQsn2wEi0j9wPRbLg==", - "dev": true, - "requires": { - "@jest/console": "^27.3.1", - "@jest/environment": "^27.3.1", - "@jest/globals": "^27.3.1", - "@jest/source-map": "^27.0.6", - "@jest/test-result": "^27.3.1", - "@jest/transform": "^27.3.1", - "@jest/types": "^27.2.5", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.4.5.tgz", + "integrity": "sha512-CIYqwuJQXHQtPd/idgrx4zgJ6iCb6uBjQq1RSAGQrw2S8XifDmoM1Ot8NRd80ooAm+ZNdHVwsktIMGlA1F1FAQ==", + "dev": true, + "requires": { + "@jest/console": "^27.4.2", + "@jest/environment": "^27.4.4", + "@jest/globals": "^27.4.4", + "@jest/source-map": "^27.4.0", + "@jest/test-result": "^27.4.2", + "@jest/transform": "^27.4.5", + "@jest/types": "^27.4.2", "@types/yargs": "^16.0.0", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", @@ -3414,31 +14210,74 @@ "exit": "^0.1.2", "glob": "^7.1.3", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-mock": "^27.3.0", - "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.3.1", - "jest-snapshot": "^27.3.1", - "jest-util": "^27.3.1", - "jest-validate": "^27.3.1", + "jest-haste-map": "^27.4.5", + "jest-message-util": "^27.4.2", + "jest-mock": "^27.4.2", + "jest-regex-util": "^27.4.0", + "jest-resolve": "^27.4.5", + "jest-snapshot": "^27.4.5", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.2", "slash": "^3.0.0", "strip-bom": "^4.0.0", "yargs": "^16.2.0" }, "dependencies": { - "strip-bom": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } } } }, "jest-serializer": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.0.6.tgz", - "integrity": "sha512-PtGdVK9EGC7dsaziskfqaAPib6wTViY3G8E5wz9tLVPhHyiDNTZn/xjZ4khAw+09QkoOVpn7vF5nPSN6dtBexA==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.4.0.tgz", + "integrity": "sha512-RDhpcn5f1JYTX2pvJAGDcnsNTnsV9bjYPU8xcV+xPwOXnUPOQwf4ZEuiU6G9H1UztH+OapMgu/ckEVwO87PwnQ==", "dev": true, "requires": { "@types/node": "*", @@ -3446,9 +14285,9 @@ } }, "jest-snapshot": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.3.1.tgz", - "integrity": "sha512-APZyBvSgQgOT0XumwfFu7X3G5elj6TGhCBLbBdn3R1IzYustPGPE38F51dBWMQ8hRXa9je0vAdeVDtqHLvB6lg==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.4.5.tgz", + "integrity": "sha512-eCi/iM1YJFrJWiT9de4+RpWWWBqsHiYxFG9V9o/n0WXs6GpW4lUt4FAHAgFPTLPqCUVzrMQmSmTZSgQzwqR7IQ==", "dev": true, "requires": { "@babel/core": "^7.7.2", @@ -3457,26 +14296,66 @@ "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.0.0", - "@jest/transform": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/transform": "^27.4.5", + "@jest/types": "^27.4.2", "@types/babel__traverse": "^7.0.4", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^27.3.1", + "expect": "^27.4.2", "graceful-fs": "^4.2.4", - "jest-diff": "^27.3.1", - "jest-get-type": "^27.3.1", - "jest-haste-map": "^27.3.1", - "jest-matcher-utils": "^27.3.1", - "jest-message-util": "^27.3.1", - "jest-resolve": "^27.3.1", - "jest-util": "^27.3.1", + "jest-diff": "^27.4.2", + "jest-get-type": "^27.4.0", + "jest-haste-map": "^27.4.5", + "jest-matcher-utils": "^27.4.2", + "jest-message-util": "^27.4.2", + "jest-resolve": "^27.4.5", + "jest-util": "^27.4.2", "natural-compare": "^1.4.0", - "pretty-format": "^27.3.1", + "pretty-format": "^27.4.2", "semver": "^7.3.2" }, "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, "semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", @@ -3485,66 +14364,251 @@ "requires": { "lru-cache": "^6.0.0" } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } } } }, "jest-util": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.3.1.tgz", - "integrity": "sha512-8fg+ifEH3GDryLQf/eKZck1DEs2YuVPBCMOaHQxVVLmQwl/CDhWzrvChTX4efLZxGrw+AA0mSXv78cyytBt/uw==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.4.2.tgz", + "integrity": "sha512-YuxxpXU6nlMan9qyLuxHaMMOzXAl5aGZWCSzben5DhLHemYQxCc4YK+4L3ZrCutT8GPQ+ui9k5D8rUJoDioMnA==", "dev": true, "requires": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", "graceful-fs": "^4.2.4", "picomatch": "^2.2.3" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "jest-validate": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.3.1.tgz", - "integrity": "sha512-3H0XCHDFLA9uDII67Bwi1Vy7AqwA5HqEEjyy934lgVhtJ3eisw6ShOF1MDmRPspyikef5MyExvIm0/TuLzZ86Q==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.4.2.tgz", + "integrity": "sha512-hWYsSUej+Fs8ZhOm5vhWzwSLmVaPAxRy+Mr+z5MzeaHm9AxUpXdoVMEW4R86y5gOobVfBsMFLk4Rb+QkiEpx1A==", "dev": true, "requires": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-get-type": "^27.3.1", + "jest-get-type": "^27.4.0", "leven": "^3.1.0", - "pretty-format": "^27.3.1" + "pretty-format": "^27.4.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "camelcase": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.1.tgz", + "integrity": "sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA==", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "jest-watcher": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.3.1.tgz", - "integrity": "sha512-9/xbV6chABsGHWh9yPaAGYVVKurWoP3ZMCv6h+O1v9/+pkOroigs6WzZ0e9gLP/njokUwM7yQhr01LKJVMkaZA==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.4.2.tgz", + "integrity": "sha512-NJvMVyyBeXfDezhWzUOCOYZrUmkSCiatpjpm+nFUid74OZEHk6aMLrZAukIiFDwdbqp6mTM6Ui1w4oc+8EobQg==", "dev": true, "requires": { - "@jest/test-result": "^27.3.1", - "@jest/types": "^27.2.5", + "@jest/test-result": "^27.4.2", + "@jest/types": "^27.4.2", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "jest-util": "^27.3.1", + "jest-util": "^27.4.2", "string-length": "^4.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "jest-worker": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.3.1.tgz", - "integrity": "sha512-ks3WCzsiZaOPJl/oMsDjaf0TRiSv7ctNgs0FqRr2nARsovz6AWWy4oLElwcquGSz692DzgZQrCLScPNs5YlC4g==", + "version": "27.4.5", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.5.tgz", + "integrity": "sha512-f2s8kEdy15cv9r7q4KkzGXvlY0JTcmCbMHZBfSQDwW77REr45IDWwd0lksDFeVHH2jJ5pqb90T77XscrjeGzzg==", "dev": true, "requires": { "@types/node": "*", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "js-sha3": { "version": "0.8.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" }, "js-tokens": { @@ -3553,6 +14617,15 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, "jsdom": { "version": "16.7.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", @@ -3594,9 +14667,21 @@ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, "json-stringify-safe": { "version": "5.0.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, "json5": { @@ -3605,14 +14690,33 @@ "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", "dev": true, "requires": { - "minimist": "^1.2.5" + "minimist": "^1.2.5" + } + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=" + }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "jsx-ast-utils": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.1.tgz", + "integrity": "sha512-uP5vu8xfy2F9A6LGC22KO7e2/vGTS1MhP+18f++ZNlf0Ohaxbc9nIEwHAsejlJKyzfZzU5UIhe5ItYkitcZnZA==", + "dev": true, + "requires": { + "array-includes": "^3.1.3", + "object.assign": "^4.1.2" } }, - "jsonparse": { - "version": "1.3.1", - "resolved": false, - "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=" - }, "kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -3626,18 +14730,27 @@ "dev": true }, "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" } }, "lodash": { "version": "4.17.21", - "resolved": false, + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "lodash.debounce": { @@ -3646,6 +14759,21 @@ "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", "dev": true }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -3655,6 +14783,15 @@ "yallist": "^4.0.0" } }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, "makeerror": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", @@ -3670,6 +14807,12 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, "micromatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", @@ -3703,17 +14846,17 @@ }, "minimalistic-assert": { "version": "1.0.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" }, "minimalistic-crypto-utils": { "version": "1.0.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" }, "minimatch": { "version": "3.0.4", - "resolved": false, + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { @@ -3722,10 +14865,16 @@ }, "minimist": { "version": "1.2.5", - "resolved": false, + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -3734,17 +14883,17 @@ }, "node-addon-api": { "version": "2.0.2", - "resolved": false, + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" }, "node-fetch": { "version": "2.6.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" }, "node-gyp-build": { "version": "4.3.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==" }, "node-int64": { @@ -3753,12 +14902,6 @@ "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", "dev": true }, - "node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", - "dev": true - }, "node-releases": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", @@ -3767,7 +14910,7 @@ }, "normalize-path": { "version": "3.0.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, @@ -3786,6 +14929,18 @@ "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", "dev": true }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-inspect": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", + "dev": true + }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", @@ -3804,9 +14959,52 @@ "object-keys": "^1.1.1" } }, + "object.entries": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz", + "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + } + }, + "object.fromentries": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.5.tgz", + "integrity": "sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + } + }, + "object.hasown": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.0.tgz", + "integrity": "sha512-MhjYRfj3GBlhSkDHo6QmvgjRLXQ2zndabdf3nX0yTyZK9rPfxb6uRpAac8HXNLy1GpqWtZ81Qh4v3uOls2sRAg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + } + }, + "object.values": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + } + }, "once": { "version": "1.4.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "requires": { @@ -3823,17 +15021,35 @@ } }, "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" } }, "p-try": { @@ -3842,6 +15058,15 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, "parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", @@ -3850,13 +15075,13 @@ }, "path-exists": { "version": "4.0.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, "path-is-absolute": { "version": "1.0.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, @@ -3872,6 +15097,12 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, "picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -3880,49 +15111,49 @@ }, "picomatch": { "version": "2.3.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", "dev": true }, "pirates": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", - "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.4.tgz", + "integrity": "sha512-ZIrVPH+A52Dw84R0L3/VS9Op04PuQ2SEoJL6bkshmiTic/HldyW9Tf7oH5mhJZBK7NmDx27vSMrYEXPXclpDKw==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, "requires": { - "node-modules-regexp": "^1.0.0" + "find-up": "^4.0.0" } }, "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, "prettier": { - "version": "2.4.0", - "resolved": false, - "integrity": "sha512-DsEPLY1dE5HF3BxCRBmD4uYZ+5DCbvatnolqTqcxEgKVZnL2kUfyu7b8pPQ5+hTBkdhU9SLUmK0/pHb07RE4WQ==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz", + "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==", "dev": true }, "pretty-format": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.1.tgz", - "integrity": "sha512-DR/c+pvFc52nLimLROYjnXPtolawm+uWDxr4FjuLDLUn+ktWnSN851KoHwHzzqq6rfCOjkzN8FLgDrSub6UDuA==", + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.2.tgz", + "integrity": "sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw==", "dev": true, "requires": { - "@jest/types": "^27.2.5", + "@jest/types": "^27.4.2", "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" }, "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, "ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", @@ -3933,9 +15164,15 @@ }, "process": { "version": "0.11.10", - "resolved": false, + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, "prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -3946,6 +15183,25 @@ "sisteransi": "^1.0.5" } }, + "prop-types": { + "version": "15.8.0", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.0.tgz", + "integrity": "sha512-fDGekdaHh65eI3lMi5OnErU6a8Ighg2KjcjQxO7m8VHyWjcPyj5kiOgV1LQDOOOgVy3+5FgjXvdSSX7B8/5/4g==", + "dev": true, + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + }, + "dependencies": { + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + } + } + }, "psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -3958,6 +15214,12 @@ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, "react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -3981,7 +15243,7 @@ }, "regenerator-runtime": { "version": "0.13.9", - "resolved": false, + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" }, "regenerator-transform": { @@ -3993,6 +15255,22 @@ "@babel/runtime": "^7.8.4" } }, + "regexp.prototype.flags": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", + "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, "regexpu-core": { "version": "4.8.0", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.8.0.tgz", @@ -4032,7 +15310,7 @@ }, "require-directory": { "version": "2.1.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, @@ -4053,12 +15331,20 @@ "dev": true, "requires": { "resolve-from": "^5.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } } }, "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, "resolve.exports": { @@ -4067,6 +15353,12 @@ "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", "dev": true }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -4077,9 +15369,9 @@ } }, "rpc-websockets": { - "version": "7.4.14", - "resolved": false, - "integrity": "sha512-x/2Rwzla6bXAyE8A21yx3sHjn49JUlgBUYfnKurNeqrZQgFxfD43Udo5NkTWQp+TASrssTlks8ipcJfvswgv5g==", + "version": "7.4.16", + "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.4.16.tgz", + "integrity": "sha512-0b7OVhutzwRIaYAtJo5tqtaQTWKfwAsKnaThOSOy+VkhVdleNUgb8eZnWSdWITRZZEigV5uPEIDr5KZe4DBrdQ==", "requires": { "@babel/runtime": "^7.11.2", "bufferutil": "^4.0.1", @@ -4088,18 +15380,20 @@ "utf-8-validate": "^5.0.2", "uuid": "^8.3.0", "ws": "^7.4.5" - }, - "dependencies": { - "uuid": { - "version": "8.3.2", - "resolved": false, - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" - } + } + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" } }, "safe-buffer": { "version": "5.2.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, "safer-buffer": { @@ -4119,7 +15413,7 @@ }, "secp256k1": { "version": "4.0.2", - "resolved": false, + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", "requires": { "elliptic": "^6.5.2", @@ -4148,6 +15442,17 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, "signal-exit": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", @@ -4167,19 +15472,27 @@ "dev": true }, "source-map": { - "version": "0.6.1", - "resolved": false, - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, "source-map-support": { - "version": "0.5.20", - "resolved": false, - "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, "sprintf-js": { @@ -4213,43 +15526,94 @@ "requires": { "char-regex": "^1.0.2", "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } } }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "string.prototype.matchall": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.6.tgz", + "integrity": "sha512-6WgDX8HmQqvEd7J+G6VtAahhsQIssiZ8zl7zKh1VDMFyL3hRTJP4FTNA3RbIp2TOQ9AYNDcc7e3fH0Qbup+DBg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1", + "get-intrinsic": "^1.1.1", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.3.1", + "side-channel": "^1.0.4" + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + }, "strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, "superstruct": { "version": "0.14.2", - "resolved": false, + "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-0.14.2.tgz", "integrity": "sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==" }, "supports-color": { - "version": "8.1.1", - "resolved": false, - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "has-flag": "^4.0.0" + "has-flag": "^3.0.0" } }, "supports-hyperlinks": { @@ -4262,6 +15626,12 @@ "supports-color": "^7.0.0" }, "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -4302,9 +15672,15 @@ }, "text-encoding-utf-8": { "version": "1.0.2", - "resolved": false, + "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz", "integrity": "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==" }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, "throat": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", @@ -4313,7 +15689,7 @@ }, "through": { "version": "2.3.8", - "resolved": false, + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, "tmpl": { @@ -4330,7 +15706,7 @@ }, "to-regex-range": { "version": "5.0.1", - "resolved": false, + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "requires": { @@ -4357,23 +15733,38 @@ "punycode": "^2.1.1" } }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, "tweetnacl": { "version": "1.0.3", - "resolved": false, + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" }, "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "requires": { - "prelude-ls": "~1.1.2" + "prelude-ls": "^1.2.1" } }, "type-detect": { "version": "4.0.8", - "resolved": false, + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, @@ -4392,6 +15783,24 @@ "is-typedarray": "^1.0.0" } }, + "typescript": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz", + "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==", + "dev": true + }, + "unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + } + }, "unicode-canonical-property-names-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", @@ -4426,19 +15835,34 @@ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, "utf-8-validate": { - "version": "5.0.5", - "resolved": false, - "integrity": "sha512-+pnxRYsS/axEpkrrEpzYfNZGXp0IjC/9RIxwM5gntY4Koi8SHmUGSfxfWqxZdRxrtaoVstuOzUp/rbs3JSPELQ==", + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.7.tgz", + "integrity": "sha512-vLt1O5Pp+flcArHGIyKEQq883nBt8nN8tVBcoL0qUXj2XT1n7p70yGIq2VK98I5FdZ1YHc0wk/koOnHjnXWk1Q==", "optional": true, "requires": { - "node-gyp-build": "^4.2.0" + "node-gyp-build": "^4.3.0" } }, "uuid": { - "version": "3.4.0", - "resolved": false, - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true }, "v8-to-istanbul": { "version": "8.1.0", @@ -4520,13 +15944,26 @@ }, "which": { "version": "2.0.2", - "resolved": false, + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" } }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -4535,7 +15972,7 @@ }, "wrap-ansi": { "version": "7.0.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { @@ -4544,43 +15981,35 @@ "strip-ansi": "^6.0.0" }, "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": false, - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": false, - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.2", - "resolved": false, - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" + "color-convert": "^2.0.1" } }, - "strip-ansi": { - "version": "6.0.0", - "resolved": false, - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "ansi-regex": "^5.0.0" + "color-name": "~1.1.4" } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true } } }, "wrappy": { "version": "1.0.2", - "resolved": false, + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, @@ -4597,9 +16026,10 @@ } }, "ws": { - "version": "7.5.5", - "resolved": false, - "integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==" + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz", + "integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==", + "requires": {} }, "xml-name-validator": { "version": "3.0.0", @@ -4615,7 +16045,7 @@ }, "y18n": { "version": "5.0.8", - "resolved": false, + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, @@ -4627,7 +16057,7 @@ }, "yargs": { "version": "16.2.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "requires": { @@ -4638,46 +16068,12 @@ "string-width": "^4.2.0", "y18n": "^5.0.5", "yargs-parser": "^20.2.2" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": false, - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": false, - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.2", - "resolved": false, - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": false, - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } } }, "yargs-parser": { - "version": "20.2.4", - "resolved": false, - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true } } diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index fae546ca..f69a5ffb 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -1,21 +1,40 @@ { "name": "@solana/spl-stake-pool", - "version": "0.2.1", + "version": "0.6.3", "description": "SPL Stake Pool Program JS API", "scripts": { - "lint": "npx prettier src/*.ts -w", + "build": "tsc", + "lint": "npm run pretty && eslint .", + "lint:fix": "npm run pretty:fix && eslint . --fix", + "pretty": "prettier --check '{,src/**/,test/**/}*.ts'", + "pretty:fix": "prettier -w '{,src/**/,test/**/}*.ts'", "test": "jest", "test:watch": "jest --watch", "test:cov": "jest --coverage" }, "keywords": [], "authors": [ + "Solana Maintainers ", "Lieu Zheng Hong", "mFactory Team (https://mfactory.ch)" ], + "homepage": "https://solana.com", + "repository": { + "type": "git", + "url": "https://github.com/solana-labs/solana-program-library" + }, + "publishConfig": { + "access": "public" + }, + "main": "dist/index.js", + "types": "dist/index.d.ts", + "files": [ + "/dist" + ], "license": "ISC", "dependencies": { "@project-serum/borsh": "^0.2.2", + "@solana/buffer-layout": "^4.0.0", "@solana/spl-token": "^0.1.8", "@solana/web3.js": "^1.30.2", "bn.js": "^5.2.0", @@ -27,8 +46,13 @@ "@babel/preset-typescript": "^7.16.5", "@types/bn.js": "^5.1.0", "@types/jest": "^27.0.3", + "@typescript-eslint/eslint-plugin": "^5.8.1", + "@typescript-eslint/parser": "^5.8.1", + "eslint": "^8.5.0", + "eslint-plugin-react": "^7.28.0", "jest": "^27.3.1", - "prettier": "^2.2.1" + "prettier": "^2.2.1", + "typescript": "^4.5.4" }, "jest": { "testRegex": ".*\\.test\\.ts$", diff --git a/clients/js-legacy/src/buffer-layout.d.ts b/clients/js-legacy/src/buffer-layout.d.ts new file mode 100644 index 00000000..0e506a0f --- /dev/null +++ b/clients/js-legacy/src/buffer-layout.d.ts @@ -0,0 +1,16 @@ +declare module 'buffer-layout' { + export class Layout {} + export class UInt {} + /* eslint-disable @typescript-eslint/no-unused-vars */ + export function struct( + fields: any, + property?: string, + decodePrefixes?: boolean, + ): any; + export function s32(property?: string): UInt; + export function u32(property?: string): UInt; + export function s16(property?: string): UInt; + export function u16(property?: string): UInt; + export function s8(property?: string): UInt; + export function u8(property?: string): UInt; +} diff --git a/clients/js-legacy/src/constants.ts b/clients/js-legacy/src/constants.ts index 1451d876..4b1f5a1f 100644 --- a/clients/js-legacy/src/constants.ts +++ b/clients/js-legacy/src/constants.ts @@ -1,9 +1,11 @@ -import { Buffer } from "buffer"; -import { PublicKey } from "@solana/web3.js"; -import { solToLamports } from "./utils"; +import {Buffer} from 'buffer'; +import {PublicKey} from '@solana/web3.js'; +import {solToLamports} from './utils'; export const TRANSIENT_STAKE_SEED_PREFIX = Buffer.from('transient'); -export const STAKE_POOL_PROGRAM_ID = new PublicKey('SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy'); +export const STAKE_POOL_PROGRAM_ID = new PublicKey( + 'SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy', +); export const MIN_STAKE_BALANCE = solToLamports(0.001); diff --git a/clients/js-legacy/src/copied-from-solana-web3/README.md b/clients/js-legacy/src/copied-from-solana-web3/README.md deleted file mode 100644 index a1388ae6..00000000 --- a/clients/js-legacy/src/copied-from-solana-web3/README.md +++ /dev/null @@ -1,3 +0,0 @@ -that files are copied from https://github.com/solana-labs/solana-web3.js - -I think it would be a good idea to export that functionality diff --git a/clients/js-legacy/src/copied-from-solana-web3/instruction.ts b/clients/js-legacy/src/copied-from-solana-web3/instruction.ts index 1985ff7c..ec1a6353 100644 --- a/clients/js-legacy/src/copied-from-solana-web3/instruction.ts +++ b/clients/js-legacy/src/copied-from-solana-web3/instruction.ts @@ -1,7 +1,5 @@ -import { Buffer } from 'buffer'; -import * as BufferLayout from '@solana/buffer-layout'; - -import * as Layout from './layout'; +import {Buffer} from 'buffer'; +import {Layout} from '@solana/buffer-layout'; /** * @internal @@ -10,7 +8,7 @@ export type InstructionType = { /** The Instruction index (from solana upstream program) */ index: number; /** The BufferLayout to use to build data */ - layout: BufferLayout.Layout; + layout: Layout; // NOTE do this better }; /** @@ -18,9 +16,9 @@ export type InstructionType = { * @internal */ export function encodeData(type: InstructionType, fields?: any): Buffer { - const allocLength = type.layout.span >= 0 ? type.layout.span : Layout.getAlloc(type, fields); + const allocLength = type.layout.span; const data = Buffer.alloc(allocLength); - const layoutFields = Object.assign({ instruction: type.index }, fields); + const layoutFields = Object.assign({instruction: type.index}, fields); type.layout.encode(layoutFields, data); return data; @@ -40,7 +38,7 @@ export function decodeData(type: InstructionType, buffer: Buffer): any { if (data.instruction !== type.index) { throw new Error( - `invalid instruction; instruction index mismatch ${data.instruction} != ${type.index}`, + `invalid instruction; instruction index mismatch ${data.instruction} != ${type.index}`, ); } diff --git a/clients/js-legacy/src/copied-from-solana-web3/layout.ts b/clients/js-legacy/src/copied-from-solana-web3/layout.ts deleted file mode 100644 index a96c7984..00000000 --- a/clients/js-legacy/src/copied-from-solana-web3/layout.ts +++ /dev/null @@ -1,92 +0,0 @@ -import {Buffer} from 'buffer'; -import * as BufferLayout from '@solana/buffer-layout'; - -/** - * Layout for a public key - */ -export const publicKey = ( - property: string = 'publicKey', -): BufferLayout.Layout => { - return BufferLayout.blob(32, property); -}; - -/** - * Layout for a 64bit unsigned value - */ -export const uint64 = (property: string = 'uint64'): BufferLayout.Layout => { - return BufferLayout.blob(8, property); -}; - -/** - * Layout for a Rust String type - */ -export const rustString = (property: string = 'string') => { - const rsl = BufferLayout.struct( - [ - BufferLayout.u32('length'), - BufferLayout.u32('lengthPadding'), - BufferLayout.blob(BufferLayout.offset(BufferLayout.u32(), -8), 'chars'), - ], - property, - ); - const _decode = rsl.decode.bind(rsl); - const _encode = rsl.encode.bind(rsl); - - rsl.decode = (buffer: any, offset: any) => { - const data = _decode(buffer, offset); - return data['chars'].toString('utf8'); - }; - - rsl.encode = (str: any, buffer: any, offset: any) => { - const data = { - chars: Buffer.from(str, 'utf8'), - }; - return _encode(data, buffer, offset); - }; - - (rsl as any).alloc = (str: any) => { - return ( - BufferLayout.u32().span + - BufferLayout.u32().span + - Buffer.from(str, 'utf8').length - ); - }; - - return rsl; -}; - -/** - * Layout for an Authorized object - */ -export const authorized = (property: string = 'authorized') => { - return BufferLayout.struct( - [publicKey('staker'), publicKey('withdrawer')], - property, - ); -}; - -/** - * Layout for a Lockup object - */ -export const lockup = (property: string = 'lockup') => { - return BufferLayout.struct( - [ - BufferLayout.ns64('unixTimestamp'), - BufferLayout.ns64('epoch'), - publicKey('custodian'), - ], - property, - ); -}; - -export function getAlloc(type: any, fields: any): number { - let alloc = 0; - type.layout.fields.forEach((item: any) => { - if (item.span >= 0) { - alloc += item.span; - } else if (typeof item.alloc === 'function') { - alloc += item.alloc(fields[item.property]); - } - }); - return alloc; -} diff --git a/clients/js-legacy/src/index.ts b/clients/js-legacy/src/index.ts index 86ecfaa7..f4c22eb4 100644 --- a/clients/js-legacy/src/index.ts +++ b/clients/js-legacy/src/index.ts @@ -3,7 +3,8 @@ import { Connection, Keypair, PublicKey, - Signer, StakeProgram, + Signer, + StakeProgram, SystemProgram, TransactionInstruction, } from '@solana/web3.js'; @@ -23,12 +24,22 @@ import { lamportsToSol, solToLamports, } from './utils'; -import { StakePoolInstruction } from './instructions'; -import { StakePoolLayout, ValidatorListLayout, ValidatorList, StakePool } from './layouts'; -import { MIN_STAKE_BALANCE, STAKE_POOL_PROGRAM_ID } from "./constants"; - -export type { StakePool, AccountType, ValidatorList, ValidatorStakeInfo } from './layouts'; -export { STAKE_POOL_PROGRAM_ID } from './constants'; +import {StakePoolInstruction} from './instructions'; +import { + StakePoolLayout, + ValidatorListLayout, + ValidatorList, + StakePool, +} from './layouts'; +import {MIN_STAKE_BALANCE, STAKE_POOL_PROGRAM_ID} from './constants'; + +export type { + StakePool, + AccountType, + ValidatorList, + ValidatorStakeInfo, +} from './layouts'; +export {STAKE_POOL_PROGRAM_ID} from './constants'; export * from './instructions'; export interface ValidatorListAccount { @@ -139,7 +150,7 @@ export async function depositSol( lamports: number, destinationTokenAccount?: PublicKey, referrerTokenAccount?: PublicKey, - depositAuthority?: PublicKey + depositAuthority?: PublicKey, ) { const fromBalance = await connection.getBalance(from, 'confirmed'); if (fromBalance < lamports) { @@ -150,7 +161,10 @@ export async function depositSol( ); } - const stakePoolAccount = await getStakePoolAccount(connection, stakePoolAddress); + const stakePoolAccount = await getStakePoolAccount( + connection, + stakePoolAddress, + ); const stakePool = stakePoolAccount.account.data; // Ephemeral SOL account just to do the transfer @@ -240,8 +254,12 @@ export async function withdrawStake( // Check withdrawFrom balance if (tokenAccount.amount.toNumber() < poolAmount) { throw new Error( - `Not enough token balance to withdraw ${lamportsToSol(poolAmount)} pool tokens. - Maximum withdraw amount is ${lamportsToSol(tokenAccount.amount.toNumber())} pool tokens.`, + `Not enough token balance to withdraw ${lamportsToSol( + poolAmount, + )} pool tokens. + Maximum withdraw amount is ${lamportsToSol( + tokenAccount.amount.toNumber(), + )} pool tokens.`, ); } @@ -328,7 +346,10 @@ export async function withdrawStake( } // Convert pool tokens amount to lamports const solWithdrawAmount = Math.ceil( - calcLamportsWithdrawAmount(stakePool.account.data, withdrawAccount.poolAmount), + calcLamportsWithdrawAmount( + stakePool.account.data, + withdrawAccount.poolAmount, + ), ); let infoMsg = `Withdrawing â—Ž${solWithdrawAmount}, @@ -344,10 +365,13 @@ export async function withdrawStake( // Use separate mutable variable because withdraw might create a new account if (!stakeReceiver) { - const stakeReceiverAccountBalance = await connection.getMinimumBalanceForRentExemption( - StakeProgram.space, + const stakeReceiverAccountBalance = + await connection.getMinimumBalanceForRentExemption(StakeProgram.space); + const stakeKeypair = newStakeAccount( + tokenOwner, + instructions, + stakeReceiverAccountBalance, ); - const stakeKeypair = newStakeAccount(tokenOwner, instructions, stakeReceiverAccountBalance); signers.push(stakeKeypair); totalRentFreeBalances += stakeReceiverAccountBalance; stakeToReceive = stakeKeypair.publicKey; @@ -368,7 +392,7 @@ export async function withdrawStake( poolMint: stakePool.account.data.poolMint, poolTokens: withdrawAccount.poolAmount, withdrawAuthority, - }) + }), ); i++; } @@ -414,8 +438,12 @@ export async function withdrawSol( // Check withdrawFrom balance if (tokenAccount.amount.toNumber() < poolAmount) { throw new Error( - `Not enough token balance to withdraw ${lamportsToSol(poolAmount)} pool tokens. - Maximum withdraw amount is ${lamportsToSol(tokenAccount.amount.toNumber())} pool tokens.`, + `Not enough token balance to withdraw ${lamportsToSol( + poolAmount, + )} pool tokens. + Maximum withdraw amount is ${lamportsToSol( + tokenAccount.amount.toNumber(), + )} pool tokens.`, ); } @@ -441,11 +469,16 @@ export async function withdrawSol( ); if (solWithdrawAuthority) { - const expectedSolWithdrawAuthority = stakePool.account.data.solWithdrawAuthority; + const expectedSolWithdrawAuthority = + stakePool.account.data.solWithdrawAuthority; if (!expectedSolWithdrawAuthority) { - throw new Error('SOL withdraw authority specified in arguments but stake pool has none'); + throw new Error( + 'SOL withdraw authority specified in arguments but stake pool has none', + ); } - if (solWithdrawAuthority.toBase58() != expectedSolWithdrawAuthority.toBase58()) { + if ( + solWithdrawAuthority.toBase58() != expectedSolWithdrawAuthority.toBase58() + ) { throw new Error( `Invalid deposit withdraw specified, expected ${expectedSolWithdrawAuthority.toBase58()}, received ${solWithdrawAuthority.toBase58()}`, ); diff --git a/clients/js-legacy/src/instructions.ts b/clients/js-legacy/src/instructions.ts index c1a3a7f7..ccf1e438 100644 --- a/clients/js-legacy/src/instructions.ts +++ b/clients/js-legacy/src/instructions.ts @@ -1,7 +1,11 @@ /** * Based on https://github.com/solana-labs/solana-web3.js/blob/master/src/stake-program.ts */ -import { encodeData, decodeData, InstructionType } from './copied-from-solana-web3/instruction'; +import { + encodeData, + decodeData, + InstructionType, +} from './copied-from-solana-web3/instruction'; import { PublicKey, TransactionInstruction, @@ -10,9 +14,9 @@ import { SYSVAR_CLOCK_PUBKEY, SYSVAR_STAKE_HISTORY_PUBKEY, } from '@solana/web3.js'; -import * as BufferLayout from '@solana/buffer-layout'; -import { TOKEN_PROGRAM_ID } from '@solana/spl-token'; -import { STAKE_POOL_PROGRAM_ID } from "./constants"; +import {struct, u8, nu64} from '@solana/buffer-layout'; +import {TOKEN_PROGRAM_ID} from '@solana/spl-token'; +import {STAKE_POOL_PROGRAM_ID} from './constants'; /** * An enumeration of valid StakePoolInstructionType's @@ -32,24 +36,30 @@ export const STAKE_POOL_INSTRUCTION_LAYOUTS: { } = Object.freeze({ DepositStake: { index: 9, - layout: BufferLayout.struct([BufferLayout.u8('instruction')]), + layout: struct([u8('instruction') as any]), // NOTE do this better }, /// Withdraw the token from the pool at the current ratio. WithdrawStake: { index: 10, - layout: BufferLayout.struct([BufferLayout.u8('instruction'), BufferLayout.ns64('poolTokens')]), + layout: struct([ + u8('instruction') as any, // NOTE do this better + nu64('poolTokens'), + ]), }, /// Deposit SOL directly into the pool's reserve account. The output is a "pool" token /// representing ownership into the pool. Inputs are converted to the current ratio. DepositSol: { index: 14, - layout: BufferLayout.struct([BufferLayout.u8('instruction'), BufferLayout.ns64('lamports')]), + layout: struct([ + u8('instruction') as any, // NOTE do this better + nu64('lamports'), + ]), }, /// Withdraw SOL directly from the pool's reserve account. Fails if the /// reserve does not have enough SOL. WithdrawSol: { index: 16, - layout: BufferLayout.struct([BufferLayout.u8('instruction'), BufferLayout.ns64('poolTokens')]), + layout: struct([u8('instruction') as any, nu64('poolTokens')]), }, }); @@ -145,21 +155,21 @@ export class StakePoolInstruction { const data = encodeData(type); const keys = [ - { pubkey: stakePool, isSigner: false, isWritable: true }, - { pubkey: validatorList, isSigner: false, isWritable: true }, - { pubkey: depositAuthority, isSigner: false, isWritable: false }, - { pubkey: withdrawAuthority, isSigner: false, isWritable: false }, - { pubkey: depositStake, isSigner: false, isWritable: true }, - { pubkey: validatorStake, isSigner: false, isWritable: true }, - { pubkey: reserveStake, isSigner: false, isWritable: true }, - { pubkey: destinationPoolAccount, isSigner: false, isWritable: true }, - { pubkey: managerFeeAccount, isSigner: false, isWritable: true }, - { pubkey: referralPoolAccount, isSigner: false, isWritable: true }, - { pubkey: poolMint, isSigner: false, isWritable: true }, - { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false }, - { pubkey: SYSVAR_STAKE_HISTORY_PUBKEY, isSigner: false, isWritable: false }, - { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, - { pubkey: StakeProgram.programId, isSigner: false, isWritable: false }, + {pubkey: stakePool, isSigner: false, isWritable: true}, + {pubkey: validatorList, isSigner: false, isWritable: true}, + {pubkey: depositAuthority, isSigner: false, isWritable: false}, + {pubkey: withdrawAuthority, isSigner: false, isWritable: false}, + {pubkey: depositStake, isSigner: false, isWritable: true}, + {pubkey: validatorStake, isSigner: false, isWritable: true}, + {pubkey: reserveStake, isSigner: false, isWritable: true}, + {pubkey: destinationPoolAccount, isSigner: false, isWritable: true}, + {pubkey: managerFeeAccount, isSigner: false, isWritable: true}, + {pubkey: referralPoolAccount, isSigner: false, isWritable: true}, + {pubkey: poolMint, isSigner: false, isWritable: true}, + {pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false}, + {pubkey: SYSVAR_STAKE_HISTORY_PUBKEY, isSigner: false, isWritable: false}, + {pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false}, + {pubkey: StakeProgram.programId, isSigner: false, isWritable: false}, ]; return new TransactionInstruction({ @@ -187,19 +197,19 @@ export class StakePoolInstruction { } = params; const type = STAKE_POOL_INSTRUCTION_LAYOUTS.DepositSol; - const data = encodeData(type, { lamports }); + const data = encodeData(type, {lamports}); const keys = [ - { pubkey: stakePool, isSigner: false, isWritable: true }, - { pubkey: withdrawAuthority, isSigner: false, isWritable: false }, - { pubkey: reserveStake, isSigner: false, isWritable: true }, - { pubkey: fundingAccount, isSigner: true, isWritable: true }, - { pubkey: destinationPoolAccount, isSigner: false, isWritable: true }, - { pubkey: managerFeeAccount, isSigner: false, isWritable: true }, - { pubkey: referralPoolAccount, isSigner: false, isWritable: true }, - { pubkey: poolMint, isSigner: false, isWritable: true }, - { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, - { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, + {pubkey: stakePool, isSigner: false, isWritable: true}, + {pubkey: withdrawAuthority, isSigner: false, isWritable: false}, + {pubkey: reserveStake, isSigner: false, isWritable: true}, + {pubkey: fundingAccount, isSigner: true, isWritable: true}, + {pubkey: destinationPoolAccount, isSigner: false, isWritable: true}, + {pubkey: managerFeeAccount, isSigner: false, isWritable: true}, + {pubkey: referralPoolAccount, isSigner: false, isWritable: true}, + {pubkey: poolMint, isSigner: false, isWritable: true}, + {pubkey: SystemProgram.programId, isSigner: false, isWritable: false}, + {pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false}, ]; if (depositAuthority) { @@ -236,22 +246,22 @@ export class StakePoolInstruction { } = params; const type = STAKE_POOL_INSTRUCTION_LAYOUTS.WithdrawStake; - const data = encodeData(type, { poolTokens }); + const data = encodeData(type, {poolTokens}); const keys = [ - { pubkey: stakePool, isSigner: false, isWritable: true }, - { pubkey: validatorList, isSigner: false, isWritable: true }, - { pubkey: withdrawAuthority, isSigner: false, isWritable: false }, - { pubkey: validatorStake, isSigner: false, isWritable: true }, - { pubkey: destinationStake, isSigner: false, isWritable: true }, - { pubkey: destinationStakeAuthority, isSigner: false, isWritable: false }, - { pubkey: sourceTransferAuthority, isSigner: true, isWritable: false }, - { pubkey: sourcePoolAccount, isSigner: false, isWritable: true }, - { pubkey: managerFeeAccount, isSigner: false, isWritable: true }, - { pubkey: poolMint, isSigner: false, isWritable: true }, - { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false }, - { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, - { pubkey: StakeProgram.programId, isSigner: false, isWritable: false }, + {pubkey: stakePool, isSigner: false, isWritable: true}, + {pubkey: validatorList, isSigner: false, isWritable: true}, + {pubkey: withdrawAuthority, isSigner: false, isWritable: false}, + {pubkey: validatorStake, isSigner: false, isWritable: true}, + {pubkey: destinationStake, isSigner: false, isWritable: true}, + {pubkey: destinationStakeAuthority, isSigner: false, isWritable: false}, + {pubkey: sourceTransferAuthority, isSigner: true, isWritable: false}, + {pubkey: sourcePoolAccount, isSigner: false, isWritable: true}, + {pubkey: managerFeeAccount, isSigner: false, isWritable: true}, + {pubkey: poolMint, isSigner: false, isWritable: true}, + {pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false}, + {pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false}, + {pubkey: StakeProgram.programId, isSigner: false, isWritable: false}, ]; return new TransactionInstruction({ @@ -279,21 +289,21 @@ export class StakePoolInstruction { } = params; const type = STAKE_POOL_INSTRUCTION_LAYOUTS.WithdrawSol; - const data = encodeData(type, { poolTokens }); + const data = encodeData(type, {poolTokens}); const keys = [ - { pubkey: stakePool, isSigner: false, isWritable: true }, - { pubkey: withdrawAuthority, isSigner: false, isWritable: false }, - { pubkey: sourceTransferAuthority, isSigner: true, isWritable: false }, - { pubkey: sourcePoolAccount, isSigner: false, isWritable: true }, - { pubkey: reserveStake, isSigner: false, isWritable: true }, - { pubkey: destinationSystemAccount, isSigner: false, isWritable: true }, - { pubkey: managerFeeAccount, isSigner: false, isWritable: true }, - { pubkey: poolMint, isSigner: false, isWritable: true }, - { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false }, - { pubkey: SYSVAR_STAKE_HISTORY_PUBKEY, isSigner: false, isWritable: false }, - { pubkey: StakeProgram.programId, isSigner: false, isWritable: false }, - { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, + {pubkey: stakePool, isSigner: false, isWritable: true}, + {pubkey: withdrawAuthority, isSigner: false, isWritable: false}, + {pubkey: sourceTransferAuthority, isSigner: true, isWritable: false}, + {pubkey: sourcePoolAccount, isSigner: false, isWritable: true}, + {pubkey: reserveStake, isSigner: false, isWritable: true}, + {pubkey: destinationSystemAccount, isSigner: false, isWritable: true}, + {pubkey: managerFeeAccount, isSigner: false, isWritable: true}, + {pubkey: poolMint, isSigner: false, isWritable: true}, + {pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false}, + {pubkey: SYSVAR_STAKE_HISTORY_PUBKEY, isSigner: false, isWritable: false}, + {pubkey: StakeProgram.programId, isSigner: false, isWritable: false}, + {pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false}, ]; if (solWithdrawAuthority) { @@ -314,7 +324,9 @@ export class StakePoolInstruction { /** * Decode a deposit stake pool instruction and retrieve the instruction params. */ - static decodeDepositStake(instruction: TransactionInstruction): DepositStakeParams { + static decodeDepositStake( + instruction: TransactionInstruction, + ): DepositStakeParams { this.checkProgramId(instruction.programId); this.checkKeyLength(instruction.keys, 11); @@ -338,11 +350,16 @@ export class StakePoolInstruction { /** * Decode a deposit sol instruction and retrieve the instruction params. */ - static decodeDepositSol(instruction: TransactionInstruction): DepositSolParams { + static decodeDepositSol( + instruction: TransactionInstruction, + ): DepositSolParams { this.checkProgramId(instruction.programId); this.checkKeyLength(instruction.keys, 9); - const { amount } = decodeData(STAKE_POOL_INSTRUCTION_LAYOUTS.DepositSol, instruction.data); + const {amount} = decodeData( + STAKE_POOL_INSTRUCTION_LAYOUTS.DepositSol, + instruction.data, + ); return { stakePool: instruction.keys[0].pubkey, @@ -378,4 +395,3 @@ export class StakePoolInstruction { } } } - diff --git a/clients/js-legacy/src/layouts.ts b/clients/js-legacy/src/layouts.ts index d500ed4c..fafdde3e 100644 --- a/clients/js-legacy/src/layouts.ts +++ b/clients/js-legacy/src/layouts.ts @@ -1,6 +1,14 @@ -import { publicKey, struct, u32, u64, u8, option, vec } from '@project-serum/borsh'; -import { Lockup, PublicKey } from '@solana/web3.js'; -import { AccountInfo } from "@solana/spl-token"; +import { + publicKey, + struct, + u32, + u64, + u8, + option, + vec, +} from '@project-serum/borsh'; +import {Lockup, PublicKey} from '@solana/web3.js'; +import {AccountInfo} from '@solana/spl-token'; import BN from 'bn.js'; export interface Fee { @@ -80,7 +88,10 @@ export const StakePoolLayout = struct([ u64('totalLamports'), u64('poolTokenSupply'), u64('lastUpdateEpoch'), - struct([u64('unixTimestamp'), u64('epoch'), publicKey('custodian')], 'lockup'), + struct( + [u64('unixTimestamp'), u64('epoch'), publicKey('custodian')], + 'lockup', + ), struct(feeFields, 'epochFee'), option(struct(feeFields), 'nextEpochFee'), option(publicKey(), 'preferredDepositValidatorVoteAddress'), diff --git a/clients/js-legacy/src/utils/index.ts b/clients/js-legacy/src/utils/index.ts index f280f312..49665079 100644 --- a/clients/js-legacy/src/utils/index.ts +++ b/clients/js-legacy/src/utils/index.ts @@ -1,4 +1,4 @@ -export * from './math' -export * from './program-address' -export * from './stake' -export * from './token' +export * from './math'; +export * from './program-address'; +export * from './stake'; +export * from './token'; diff --git a/clients/js-legacy/src/utils/math.ts b/clients/js-legacy/src/utils/math.ts index 3bbe11ff..b0ba6250 100644 --- a/clients/js-legacy/src/utils/math.ts +++ b/clients/js-legacy/src/utils/math.ts @@ -1,5 +1,5 @@ -import BN from "bn.js"; -import { LAMPORTS_PER_SOL } from "@solana/web3.js"; +import BN from 'bn.js'; +import {LAMPORTS_PER_SOL} from '@solana/web3.js'; export function solToLamports(amount: number): number { if (isNaN(amount)) return Number(0); @@ -19,6 +19,9 @@ export function lamportsToSol(lamports: number | BN): number { const absLamports = lamports.abs(); const lamportsString = absLamports.toString(10).padStart(10, '0'); const splitIndex = lamportsString.length - 9; - const solString = lamportsString.slice(0, splitIndex) + '.' + lamportsString.slice(splitIndex); + const solString = + lamportsString.slice(0, splitIndex) + + '.' + + lamportsString.slice(splitIndex); return signMultiplier * parseFloat(solString); } diff --git a/clients/js-legacy/src/utils/program-address.ts b/clients/js-legacy/src/utils/program-address.ts index 7de23082..87383817 100644 --- a/clients/js-legacy/src/utils/program-address.ts +++ b/clients/js-legacy/src/utils/program-address.ts @@ -1,6 +1,6 @@ -import { PublicKey } from "@solana/web3.js"; -import BN from "bn.js"; -import { TRANSIENT_STAKE_SEED_PREFIX } from "../constants"; +import {PublicKey} from '@solana/web3.js'; +import BN from 'bn.js'; +import {TRANSIENT_STAKE_SEED_PREFIX} from '../constants'; /** * Generates the withdraw authority program address for the stake pool diff --git a/clients/js-legacy/src/utils/stake.ts b/clients/js-legacy/src/utils/stake.ts index a21d7bb4..c4f54811 100644 --- a/clients/js-legacy/src/utils/stake.ts +++ b/clients/js-legacy/src/utils/stake.ts @@ -1,22 +1,26 @@ import { Connection, Keypair, - PublicKey, StakeProgram, + PublicKey, + StakeProgram, SystemProgram, - TransactionInstruction -} from "@solana/web3.js"; -import { findStakeProgramAddress, findTransientStakeProgramAddress } from "./program-address"; -import BN from "bn.js"; + TransactionInstruction, +} from '@solana/web3.js'; +import { + findStakeProgramAddress, + findTransientStakeProgramAddress, +} from './program-address'; +import BN from 'bn.js'; -import { lamportsToSol } from "./math"; -import { WithdrawAccount } from "../index"; +import {lamportsToSol} from './math'; +import {WithdrawAccount} from '../index'; import { StakePool, ValidatorList, ValidatorListLayout, - ValidatorStakeInfoStatus -} from "../layouts"; -import { STAKE_POOL_PROGRAM_ID } from "../constants"; + ValidatorStakeInfoStatus, +} from '../layouts'; +import {STAKE_POOL_PROGRAM_ID} from '../constants'; export async function prepareWithdrawAccounts( connection: Connection, @@ -24,8 +28,12 @@ export async function prepareWithdrawAccounts( stakePoolAddress: PublicKey, amount: number, ): Promise { - const validatorListAcc = await connection.getAccountInfo(stakePool.validatorList); - const validatorList = ValidatorListLayout.decode(validatorListAcc!.data) as ValidatorList; + const validatorListAcc = await connection.getAccountInfo( + stakePool.validatorList, + ); + const validatorList = ValidatorListLayout.decode( + validatorListAcc?.data, + ) as ValidatorList; if (!validatorList?.validators || validatorList?.validators.length == 0) { throw new Error('No accounts found'); @@ -40,7 +48,6 @@ export async function prepareWithdrawAccounts( // Prepare accounts for (const validator of validatorList.validators) { - if (validator.status !== ValidatorStakeInfoStatus.Active) { continue; } @@ -54,8 +61,8 @@ export async function prepareWithdrawAccounts( if (!validator.activeStakeLamports.isZero()) { const isPreferred = stakePool.preferredWithdrawValidatorVoteAddress && - stakePool.preferredWithdrawValidatorVoteAddress!.toBase58() == - validator.voteAccountAddress.toBase58(); + stakePool.preferredWithdrawValidatorVoteAddress.toBase58() == + validator.voteAccountAddress.toBase58(); accounts.push({ type: isPreferred ? 'preferred' : 'active', voteAddress: validator.voteAccountAddress, @@ -68,7 +75,7 @@ export async function prepareWithdrawAccounts( STAKE_POOL_PROGRAM_ID, validator.voteAccountAddress, stakePoolAddress, - validator.transientSeedSuffixStart!, + validator.transientSeedSuffixStart, ); if (!validator.transientStakeLamports?.isZero()) { @@ -76,7 +83,7 @@ export async function prepareWithdrawAccounts( type: 'transient', voteAddress: validator.voteAccountAddress, stakeAddress: transientStakeAccountAddress, - lamports: validator.transientStakeLamports!.toNumber(), + lamports: validator.transientStakeLamports.toNumber(), }); } } @@ -101,12 +108,18 @@ export async function prepareWithdrawAccounts( for (const type of ['preferred', 'active', 'transient', 'reserve']) { const filteredAccounts = accounts.filter(a => a.type == type); - for (const { stakeAddress, voteAddress, lamports } of filteredAccounts) { - let availableForWithdrawal = Math.floor(calcPoolTokensForDeposit(stakePool, lamports)); + for (const {stakeAddress, voteAddress, lamports} of filteredAccounts) { + let availableForWithdrawal = Math.floor( + calcPoolTokensForDeposit(stakePool, lamports), + ); if (!stakePool.stakeWithdrawalFee.denominator.isZero()) { availableForWithdrawal = divideBnToNumber( - new BN(availableForWithdrawal).mul(stakePool.stakeWithdrawalFee.denominator), - stakePool.stakeWithdrawalFee.denominator.sub(stakePool.stakeWithdrawalFee.numerator), + new BN(availableForWithdrawal).mul( + stakePool.stakeWithdrawalFee.denominator, + ), + stakePool.stakeWithdrawalFee.denominator.sub( + stakePool.stakeWithdrawalFee.numerator, + ), ); } @@ -116,7 +129,7 @@ export async function prepareWithdrawAccounts( } // Those accounts will be withdrawn completely with `claim` instruction - withdrawFrom.push({ stakeAddress, voteAddress, poolAmount }); + withdrawFrom.push({stakeAddress, voteAddress, poolAmount}); remainingAmount -= poolAmount; if (remainingAmount == 0) { break; @@ -130,7 +143,9 @@ export async function prepareWithdrawAccounts( // Not enough stake to withdraw the specified amount if (remainingAmount > 0) { throw new Error( - `No stake accounts found in this pool with enough balance to withdraw ${lamportsToSol(amount)} pool tokens.` + `No stake accounts found in this pool with enough balance to withdraw ${lamportsToSol( + amount, + )} pool tokens.`, ); } @@ -140,7 +155,10 @@ export async function prepareWithdrawAccounts( /** * Calculate the pool tokens that should be minted for a deposit of `stakeLamports` */ -export function calcPoolTokensForDeposit(stakePool: StakePool, stakeLamports: number): number { +export function calcPoolTokensForDeposit( + stakePool: StakePool, + stakeLamports: number, +): number { if (stakePool.poolTokenSupply.isZero() || stakePool.totalLamports.isZero()) { return stakeLamports; } @@ -153,7 +171,10 @@ export function calcPoolTokensForDeposit(stakePool: StakePool, stakeLamports: nu /** * Calculate lamports amount on withdrawal */ -export function calcLamportsWithdrawAmount(stakePool: StakePool, poolTokens: number): number { +export function calcLamportsWithdrawAmount( + stakePool: StakePool, + poolTokens: number, +): number { const numerator = new BN(poolTokens).mul(stakePool.totalLamports); const denominator = stakePool.poolTokenSupply; if (numerator.lt(denominator)) { @@ -179,7 +200,9 @@ export function newStakeAccount( ): Keypair { // Account for tokens not specified, creating one const stakeReceiverKeypair = Keypair.generate(); - console.log(`Creating account to receive stake ${stakeReceiverKeypair.publicKey}`); + console.log( + `Creating account to receive stake ${stakeReceiverKeypair.publicKey}`, + ); instructions.push( // Creating new account diff --git a/clients/js-legacy/src/utils/token.ts b/clients/js-legacy/src/utils/token.ts index ac16b11a..f05859e0 100644 --- a/clients/js-legacy/src/utils/token.ts +++ b/clients/js-legacy/src/utils/token.ts @@ -1,11 +1,11 @@ -import { Connection, PublicKey, TransactionInstruction } from "@solana/web3.js"; +import {Connection, PublicKey, TransactionInstruction} from '@solana/web3.js'; import { AccountInfo, ASSOCIATED_TOKEN_PROGRAM_ID, Token, - TOKEN_PROGRAM_ID -} from "@solana/spl-token"; -import { AccountLayout } from "../layouts"; + TOKEN_PROGRAM_ID, +} from '@solana/spl-token'; +import {AccountLayout} from '../layouts'; const FAILED_TO_FIND_ACCOUNT = 'Failed to find account'; const INVALID_ACCOUNT_OWNER = 'Invalid account owner'; @@ -41,7 +41,10 @@ export async function addAssociatedTokenAccount( // already been received some lamports (= became system accounts). // Assuming program derived addressing is safe, this is the only case // for the INVALID_ACCOUNT_OWNER in this code-path - if (err.message === FAILED_TO_FIND_ACCOUNT || err.message === INVALID_ACCOUNT_OWNER) { + if ( + err.message === FAILED_TO_FIND_ACCOUNT || + err.message === INVALID_ACCOUNT_OWNER + ) { instructions.push( Token.createAssociatedTokenAccountInstruction( ASSOCIATED_TOKEN_PROGRAM_ID, diff --git a/clients/js-legacy/test/equal.ts b/clients/js-legacy/test/equal.ts index 14825d4a..49e84993 100644 --- a/clients/js-legacy/test/equal.ts +++ b/clients/js-legacy/test/equal.ts @@ -1,23 +1,13 @@ -import { Connection, PublicKey } from "@solana/web3.js"; -import BN from "bn.js"; -import { StakePoolAccount, getStakePoolAccounts } from "../src"; +import BN from 'bn.js'; +import {StakePoolAccount} from '../src'; export function isStakePoolAccount(account: any): account is StakePoolAccount { - return (account !== undefined) && - (account.account !== undefined) && - (account.account.data !== undefined) && - ('manager' in account.account.data); -} - -export async function getFirstStakePoolAccount( - connection: Connection, - stakePoolProgramAddress: PublicKey, -): Promise { - const accounts = await getStakePoolAccounts(connection, stakePoolProgramAddress); - - return accounts! - .filter(account => isStakePoolAccount(account)) - .pop() as StakePoolAccount; + return ( + account !== undefined && + account.account !== undefined && + account.account.data !== undefined && + 'manager' in account.account.data + ); } /** @@ -33,13 +23,19 @@ export function deepStrictEqualBN(a: any, b: any) { for (const subkey in a[key]) { if (a[key][subkey] instanceof Object) { if (a[key][subkey] instanceof BN) { - expect(b[key][subkey].toString()).toEqual(a[key][subkey].toString()); + expect(b[key][subkey].toString()).toEqual( + a[key][subkey].toString(), + ); } else { for (const subsubkey in a[key][subkey]) { if (a[key][subkey][subsubkey] instanceof BN) { - expect(b[key][subkey][subsubkey].toString()).toEqual(a[key][subkey][subsubkey].toString()); + expect(b[key][subkey][subsubkey].toString()).toEqual( + a[key][subkey][subsubkey].toString(), + ); } else { - expect(b[key][subkey][subsubkey]).toStrictEqual(a[key][subkey][subsubkey]); + expect(b[key][subkey][subsubkey]).toStrictEqual( + a[key][subkey][subsubkey], + ); } } } diff --git a/clients/js-legacy/test/instructions.test.ts b/clients/js-legacy/test/instructions.test.ts index 40cd39a4..b21d6f71 100644 --- a/clients/js-legacy/test/instructions.test.ts +++ b/clients/js-legacy/test/instructions.test.ts @@ -2,24 +2,25 @@ import { PublicKey, Connection, Keypair, - SystemProgram, AccountInfo, LAMPORTS_PER_SOL + SystemProgram, + AccountInfo, + LAMPORTS_PER_SOL, } from '@solana/web3.js'; -import { StakePoolLayout } from '../src/layouts'; -import { STAKE_POOL_PROGRAM_ID } from '../src/constants'; -import { decodeData } from '../src/copied-from-solana-web3/instruction'; +import {StakePoolLayout} from '../src/layouts'; +import {STAKE_POOL_PROGRAM_ID} from '../src/constants'; +import {decodeData} from '../src/copied-from-solana-web3/instruction'; import { STAKE_POOL_INSTRUCTION_LAYOUTS, DepositSolParams, StakePoolInstruction, depositSol, withdrawSol, - withdrawStake -} from "../src"; + withdrawStake, +} from '../src'; -import { mockTokenAccount, mockValidatorList, stakePoolMock } from "./mocks"; +import {mockTokenAccount, mockValidatorList, stakePoolMock} from './mocks'; describe('StakePoolProgram', () => { - const connection = new Connection('http://127.0.0.1:8899'); connection.getMinimumBalanceForRentExemption = jest.fn(async () => 10000); @@ -29,7 +30,7 @@ describe('StakePoolProgram', () => { ); const data = Buffer.alloc(1024); - StakePoolLayout.encode(stakePoolMock, data) + StakePoolLayout.encode(stakePoolMock, data); const stakePoolAccount = >{ executable: true, @@ -39,7 +40,6 @@ describe('StakePoolProgram', () => { }; it('StakePoolInstruction.depositSol', () => { - const payload: DepositSolParams = { stakePool: stakePoolPubkey, withdrawAuthority: Keypair.generate().publicKey, @@ -55,18 +55,39 @@ describe('StakePoolProgram', () => { const instruction = StakePoolInstruction.depositSol(payload); expect(instruction.keys).toHaveLength(10); - expect(instruction.keys[0].pubkey.toBase58()).toEqual(payload.stakePool.toBase58()); - expect(instruction.keys[1].pubkey.toBase58()).toEqual(payload.withdrawAuthority.toBase58()); - expect(instruction.keys[3].pubkey.toBase58()).toEqual(payload.fundingAccount.toBase58()); - expect(instruction.keys[4].pubkey.toBase58()).toEqual(payload.destinationPoolAccount.toBase58()); - expect(instruction.keys[5].pubkey.toBase58()).toEqual(payload.managerFeeAccount.toBase58()); - expect(instruction.keys[6].pubkey.toBase58()).toEqual(payload.referralPoolAccount.toBase58()); - expect(instruction.keys[8].pubkey.toBase58()).toEqual(SystemProgram.programId.toBase58()); - expect(instruction.keys[9].pubkey.toBase58()).toEqual(STAKE_POOL_PROGRAM_ID.toBase58()); - - const decodedData = decodeData(STAKE_POOL_INSTRUCTION_LAYOUTS.DepositSol, instruction.data); - - expect(decodedData.instruction).toEqual(STAKE_POOL_INSTRUCTION_LAYOUTS.DepositSol.index); + expect(instruction.keys[0].pubkey.toBase58()).toEqual( + payload.stakePool.toBase58(), + ); + expect(instruction.keys[1].pubkey.toBase58()).toEqual( + payload.withdrawAuthority.toBase58(), + ); + expect(instruction.keys[3].pubkey.toBase58()).toEqual( + payload.fundingAccount.toBase58(), + ); + expect(instruction.keys[4].pubkey.toBase58()).toEqual( + payload.destinationPoolAccount.toBase58(), + ); + expect(instruction.keys[5].pubkey.toBase58()).toEqual( + payload.managerFeeAccount.toBase58(), + ); + expect(instruction.keys[6].pubkey.toBase58()).toEqual( + payload.referralPoolAccount.toBase58(), + ); + expect(instruction.keys[8].pubkey.toBase58()).toEqual( + SystemProgram.programId.toBase58(), + ); + expect(instruction.keys[9].pubkey.toBase58()).toEqual( + STAKE_POOL_PROGRAM_ID.toBase58(), + ); + + const decodedData = decodeData( + STAKE_POOL_INSTRUCTION_LAYOUTS.DepositSol, + instruction.data, + ); + + expect(decodedData.instruction).toEqual( + STAKE_POOL_INSTRUCTION_LAYOUTS.DepositSol.index, + ); expect(decodedData.lamports).toEqual(payload.lamports); payload.depositAuthority = Keypair.generate().publicKey; @@ -74,8 +95,9 @@ describe('StakePoolProgram', () => { const instruction2 = StakePoolInstruction.depositSol(payload); expect(instruction2.keys).toHaveLength(11); - expect(instruction2.keys[10].pubkey.toBase58()).toEqual(payload.depositAuthority.toBase58()); - + expect(instruction2.keys[10].pubkey.toBase58()).toEqual( + payload.depositAuthority.toBase58(), + ); }); describe('depositSol', () => { @@ -84,51 +106,56 @@ describe('StakePoolProgram', () => { connection.getBalance = jest.fn(async () => balance); - connection.getAccountInfo = jest.fn(async (pubKey) => { + connection.getAccountInfo = jest.fn(async pubKey => { if (pubKey == stakePoolPubkey) { - return stakePoolAccount + return stakePoolAccount; } return >{ executable: true, owner: from, lamports: balance, data: null, - } + }; }); it.only('should throw an error with invalid balance', async () => { await expect( - depositSol(connection, stakePoolPubkey, from, balance + 1) - ).rejects.toThrow(Error('Not enough SOL to deposit into pool. Maximum deposit amount is 0.00001 SOL.')); + depositSol(connection, stakePoolPubkey, from, balance + 1), + ).rejects.toThrow( + Error( + 'Not enough SOL to deposit into pool. Maximum deposit amount is 0.00001 SOL.', + ), + ); }); it.only('should throw an error with invalid account', async () => { connection.getAccountInfo = jest.fn(async () => null); await expect( - depositSol(connection, stakePoolPubkey, from, balance) + depositSol(connection, stakePoolPubkey, from, balance), ).rejects.toThrow(Error('Invalid account')); }); it.only('should call successfully', async () => { - connection.getAccountInfo = jest.fn(async (pubKey) => { + connection.getAccountInfo = jest.fn(async pubKey => { if (pubKey == stakePoolPubkey) { - return stakePoolAccount + return stakePoolAccount; } return >{ executable: true, owner: from, lamports: balance, data: null, - } + }; }); - const res = await depositSol(connection, stakePoolPubkey, from, balance) + const res = await depositSol(connection, stakePoolPubkey, from, balance); - expect((connection.getAccountInfo as jest.Mock).mock.calls.length).toBe(2); + expect((connection.getAccountInfo as jest.Mock).mock.calls.length).toBe( + 2, + ); expect(res.instructions).toHaveLength(2); expect(res.signers).toHaveLength(1); }); - }); describe('withdrawSol', () => { @@ -138,101 +165,125 @@ describe('StakePoolProgram', () => { it.only('should throw an error with invalid stake pool account', async () => { connection.getAccountInfo = jest.fn(async () => null); await expect( - withdrawSol(connection, stakePoolPubkey, tokenOwner, solReceiver, 1) + withdrawSol(connection, stakePoolPubkey, tokenOwner, solReceiver, 1), ).rejects.toThrowError('Invalid account'); }); it.only('should throw an error with invalid token account', async () => { connection.getAccountInfo = jest.fn(async (pubKey: PublicKey) => { if (pubKey == stakePoolPubkey) { - return stakePoolAccount + return stakePoolAccount; } - if (pubKey.toBase58() == '9q2rZU5RujvyD9dmYKhzJAZfG4aGBbvQ8rWY52jCNBai') { - return null + if ( + pubKey.toBase58() == '9q2rZU5RujvyD9dmYKhzJAZfG4aGBbvQ8rWY52jCNBai' + ) { + return null; } return null; }); await expect( - withdrawSol(connection, stakePoolPubkey, tokenOwner, solReceiver, 1) + withdrawSol(connection, stakePoolPubkey, tokenOwner, solReceiver, 1), ).rejects.toThrow(Error('Invalid token account')); }); it.only('should throw an error with invalid token account balance', async () => { connection.getAccountInfo = jest.fn(async (pubKey: PublicKey) => { if (pubKey == stakePoolPubkey) { - return stakePoolAccount + return stakePoolAccount; } - if (pubKey.toBase58() == 'GQkqTamwqjaNDfsbNm7r3aXPJ4oTSqKC3d5t2PF9Smqd') { + if ( + pubKey.toBase58() == 'GQkqTamwqjaNDfsbNm7r3aXPJ4oTSqKC3d5t2PF9Smqd' + ) { return mockTokenAccount(0); } return null; }); await expect( - withdrawSol(connection, stakePoolPubkey, tokenOwner, solReceiver, 1) - ).rejects.toThrow(Error('Not enough token balance to withdraw 1 pool tokens.\n Maximum withdraw amount is 0 pool tokens.')); + withdrawSol(connection, stakePoolPubkey, tokenOwner, solReceiver, 1), + ).rejects.toThrow( + Error( + 'Not enough token balance to withdraw 1 pool tokens.\n Maximum withdraw amount is 0 pool tokens.', + ), + ); }); it.only('should call successfully', async () => { connection.getAccountInfo = jest.fn(async (pubKey: PublicKey) => { if (pubKey == stakePoolPubkey) { - return stakePoolAccount + return stakePoolAccount; } - if (pubKey.toBase58() == 'GQkqTamwqjaNDfsbNm7r3aXPJ4oTSqKC3d5t2PF9Smqd') { + if ( + pubKey.toBase58() == 'GQkqTamwqjaNDfsbNm7r3aXPJ4oTSqKC3d5t2PF9Smqd' + ) { return mockTokenAccount(LAMPORTS_PER_SOL); } return null; }); - const res = await withdrawSol(connection, stakePoolPubkey, tokenOwner, solReceiver, 1) - - expect((connection.getAccountInfo as jest.Mock).mock.calls.length).toBe(2); + const res = await withdrawSol( + connection, + stakePoolPubkey, + tokenOwner, + solReceiver, + 1, + ); + + expect((connection.getAccountInfo as jest.Mock).mock.calls.length).toBe( + 2, + ); expect(res.instructions).toHaveLength(2); expect(res.signers).toHaveLength(1); }); - - }) + }); describe('withdrawStake', () => { - const tokenOwner = new PublicKey(0); it.only('should throw an error with invalid token account', async () => { connection.getAccountInfo = jest.fn(async (pubKey: PublicKey) => { if (pubKey == stakePoolPubkey) { - return stakePoolAccount + return stakePoolAccount; } return null; }); await expect( - withdrawStake(connection, stakePoolPubkey, tokenOwner, 1) + withdrawStake(connection, stakePoolPubkey, tokenOwner, 1), ).rejects.toThrow(Error('Invalid token account')); }); it.only('should throw an error with invalid token account balance', async () => { connection.getAccountInfo = jest.fn(async (pubKey: PublicKey) => { if (pubKey == stakePoolPubkey) { - return stakePoolAccount + return stakePoolAccount; } - if (pubKey.toBase58() == 'GQkqTamwqjaNDfsbNm7r3aXPJ4oTSqKC3d5t2PF9Smqd') { + if ( + pubKey.toBase58() == 'GQkqTamwqjaNDfsbNm7r3aXPJ4oTSqKC3d5t2PF9Smqd' + ) { return mockTokenAccount(0); } return null; }); await expect( - withdrawStake(connection, stakePoolPubkey, tokenOwner, 1) - ).rejects.toThrow(Error('Not enough token balance to withdraw 1 pool tokens.\n' + - ' Maximum withdraw amount is 0 pool tokens.')); + withdrawStake(connection, stakePoolPubkey, tokenOwner, 1), + ).rejects.toThrow( + Error( + 'Not enough token balance to withdraw 1 pool tokens.\n' + + ' Maximum withdraw amount is 0 pool tokens.', + ), + ); }); it.only('should call successfully', async () => { connection.getAccountInfo = jest.fn(async (pubKey: PublicKey) => { if (pubKey == stakePoolPubkey) { - return stakePoolAccount + return stakePoolAccount; } - if (pubKey.toBase58() == 'GQkqTamwqjaNDfsbNm7r3aXPJ4oTSqKC3d5t2PF9Smqd') { + if ( + pubKey.toBase58() == 'GQkqTamwqjaNDfsbNm7r3aXPJ4oTSqKC3d5t2PF9Smqd' + ) { return mockTokenAccount(LAMPORTS_PER_SOL * 2); } if (pubKey.toBase58() == stakePoolMock.validatorList.toBase58()) { @@ -241,15 +292,20 @@ describe('StakePoolProgram', () => { return null; }); - const res = await withdrawStake(connection, stakePoolPubkey, tokenOwner, 1); + const res = await withdrawStake( + connection, + stakePoolPubkey, + tokenOwner, + 1, + ); - expect((connection.getAccountInfo as jest.Mock).mock.calls.length).toBe(4); + expect((connection.getAccountInfo as jest.Mock).mock.calls.length).toBe( + 4, + ); expect(res.instructions).toHaveLength(3); expect(res.signers).toHaveLength(2); expect(res.stakeReceiver).toEqual(undefined); expect(res.totalRentFreeBalances).toEqual(10000); }); - }); - }); diff --git a/clients/js-legacy/test/integration.test.ts b/clients/js-legacy/test/integration.test.ts deleted file mode 100644 index 9c39ec63..00000000 --- a/clients/js-legacy/test/integration.test.ts +++ /dev/null @@ -1,16 +0,0 @@ -/** - * TODO: https://github.com/solana-labs/solana-program-library/pull/2604 - * @joncinque - * These tests could be extremely flaky because of the devnet connection, so we could probably just remove them. - * It doesn't need to be done in this PR, but eventually we should have tests that create a stake pool / deposit / withdraw, - * all only accessing a local test validator. Same as with the token and token-swap js tests. - */ - -// @ts-ignore -describe('Integration test', () => { - - it('should be implemented', () => { - - }) - -}); diff --git a/clients/js-legacy/test/layouts.test.ts b/clients/js-legacy/test/layouts.test.ts index a3f64feb..292a95f6 100644 --- a/clients/js-legacy/test/layouts.test.ts +++ b/clients/js-legacy/test/layouts.test.ts @@ -3,11 +3,10 @@ import { ValidatorListLayout, ValidatorList, } from '../src/layouts'; -import { deepStrictEqualBN } from "./equal"; -import { stakePoolMock, validatorListMock } from "./mocks"; +import {deepStrictEqualBN} from './equal'; +import {stakePoolMock, validatorListMock} from './mocks'; describe('layouts', () => { - describe('StakePoolAccount', () => { it('should successfully decode StakePoolAccount data', () => { const encodedData = Buffer.alloc(1024); diff --git a/clients/js-legacy/test/mocks.ts b/clients/js-legacy/test/mocks.ts index 250d5c6c..52716773 100644 --- a/clients/js-legacy/test/mocks.ts +++ b/clients/js-legacy/test/mocks.ts @@ -1,7 +1,11 @@ -import { AccountInfo, LAMPORTS_PER_SOL, PublicKey } from "@solana/web3.js"; -import BN from "bn.js"; -import { ValidatorStakeInfo } from "../src"; -import { ValidatorStakeInfoStatus, AccountLayout, ValidatorListLayout } from "../src/layouts"; +import {AccountInfo, LAMPORTS_PER_SOL, PublicKey} from '@solana/web3.js'; +import BN from 'bn.js'; +import {ValidatorStakeInfo} from '../src'; +import { + ValidatorStakeInfoStatus, + AccountLayout, + ValidatorListLayout, +} from '../src/layouts'; export const stakePoolMock = { accountType: 1, @@ -111,40 +115,43 @@ export const validatorListMock = { transientSeedSuffixEnd: new BN('a', 'hex'), }, ], -} +}; export function mockTokenAccount(amount = 0) { const data = Buffer.alloc(1024); - AccountLayout.encode({ - state: 0, - mint: stakePoolMock.poolMint, - owner: new PublicKey(0), - amount: new BN(amount), - // address: new PublicKey(0), - // delegate: null, - // delegatedAmount: new BN(0), - // isInitialized: true, - // isFrozen: false, - // isNative: false, - // rentExemptReserve: null, - // closeAuthority: null, - }, data) + AccountLayout.encode( + { + state: 0, + mint: stakePoolMock.poolMint, + owner: new PublicKey(0), + amount: new BN(amount), + // address: new PublicKey(0), + // delegate: null, + // delegatedAmount: new BN(0), + // isInitialized: true, + // isFrozen: false, + // isNative: false, + // rentExemptReserve: null, + // closeAuthority: null, + }, + data, + ); return >{ executable: true, owner: new PublicKey(0), lamports: amount, data, - } + }; } export function mockValidatorList() { const data = Buffer.alloc(1024); - ValidatorListLayout.encode(validatorListMock, data) + ValidatorListLayout.encode(validatorListMock, data); return >{ executable: true, owner: new PublicKey(0), lamports: 0, data, - } + }; } diff --git a/clients/js-legacy/tsconfig.json b/clients/js-legacy/tsconfig.json index 1eaf4071..59a6767e 100644 --- a/clients/js-legacy/tsconfig.json +++ b/clients/js-legacy/tsconfig.json @@ -3,12 +3,13 @@ "target": "es2019", "allowJs": true, "declaration": true, - "declarationDir": "declarations", + "declarationDir": "dist", + "outDir": "dist", "esModuleInterop": true, "allowSyntheticDefaultImports": true, "strict": true, "forceConsistentCasingInFileNames": true, - "module": "esnext", + "module": "commonjs", "moduleResolution": "node", "resolveJsonModule": true, "isolatedModules": true, @@ -17,7 +18,6 @@ "noImplicitReturns": true }, "include": [ - "test", - "src" + "src/**/*" ] } From 4ffc24bd13439242b5d0fd387d57051b37012196 Mon Sep 17 00:00:00 2001 From: Dmitri Makarov Date: Wed, 5 Jan 2022 14:26:13 -0800 Subject: [PATCH 0216/1076] Decrease the stake pool size due to the new mem op syscall base cost (#2705) --- clients/cli/scripts/setup-stake-pool.sh | 2 +- clients/py/stake_pool/actions.py | 2 +- program/tests/huge_pool.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clients/cli/scripts/setup-stake-pool.sh b/clients/cli/scripts/setup-stake-pool.sh index 35205150..0aacb09d 100755 --- a/clients/cli/scripts/setup-stake-pool.sh +++ b/clients/cli/scripts/setup-stake-pool.sh @@ -25,7 +25,7 @@ command_args+=( --deposit-fee-denominator 0 ) command_args+=( --referral-fee 0 ) # Percentage of deposit fee that goes towards the referrer (a number between 0 and 100, inclusive) -command_args+=( --max-validators 3825 ) # Maximum number of validators in the stake pool, 3825 is the current maximum possible +command_args+=( --max-validators 2950 ) # Maximum number of validators in the stake pool, 2950 is the current maximum possible # (Optional) Deposit authority, required to sign all deposits into the pool. # Setting this variable makes the pool "private" or "restricted". diff --git a/clients/py/stake_pool/actions.py b/clients/py/stake_pool/actions.py index e78e0f95..acfce4f8 100644 --- a/clients/py/stake_pool/actions.py +++ b/clients/py/stake_pool/actions.py @@ -45,7 +45,7 @@ async def create(client: AsyncClient, manager: Keypair, ) ) ) - max_validators = 3825 # current supported max by the program, go big! + max_validators = 2950 # current supported max by the program, go big! validator_list_size = ValidatorList.calculate_validator_list_size(max_validators) resp = await client.get_minimum_balance_for_rent_exemption(validator_list_size) validator_list_balance = resp['result'] diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index 0de44add..67f8366a 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -30,7 +30,7 @@ use { spl_token::state::{Account as SplAccount, AccountState as SplAccountState, Mint}, }; -const HUGE_POOL_SIZE: u32 = 3_825; +const HUGE_POOL_SIZE: u32 = 2_950; const ACCOUNT_RENT_EXEMPTION: u64 = 1_000_000_000; // go with something big to be safe const STAKE_AMOUNT: u64 = 200_000_000_000; const STAKE_ACCOUNT_RENT_EXEMPTION: u64 = 2_282_880; From b88fcac34404eeb30598416869c432365d2d9040 Mon Sep 17 00:00:00 2001 From: Tyera Eulberg Date: Sat, 8 Jan 2022 15:51:17 -0700 Subject: [PATCH 0217/1076] Fix up helper to create rent-exempt accounts (#2720) --- program/tests/helpers/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index b4319e89..6b81275c 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -426,7 +426,7 @@ pub async fn create_vote( let mut instructions = vec![system_instruction::create_account( &payer.pubkey(), &validator.pubkey(), - 42, + rent.minimum_balance(0), 0, &system_program::id(), )]; From a2bfee5ea59dc2af9987216e9468a7a91e761df3 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 11 Jan 2022 01:24:16 +0100 Subject: [PATCH 0218/1076] stake-pool-cli: Add best practices for fees, prevent zero fees (#2670) * stake-pool-cli: Add best practices for fees, prevent zero fees * Address feedback --- clients/cli/src/main.rs | 50 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index cde16a1c..e5d4a846 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -89,6 +89,32 @@ fn check_fee_payer_balance(config: &Config, required_balance: u64) -> Result<(), } } +const FEES_REFERENCE: &str = "Consider setting a minimal fee. \ + See https://spl.solana.com/stake-pool/fees for more \ + information about fees and best practices. If you are \ + aware of the possible risks of a stake pool with no fees, \ + you may force pool creation with the --unsafe-fees flag."; + +fn check_stake_pool_fees( + epoch_fee: &Fee, + withdrawal_fee: &Fee, + deposit_fee: &Fee, +) -> Result<(), Error> { + if epoch_fee.numerator == 0 || epoch_fee.denominator == 0 { + return Err(format!("Epoch fee should not be 0. {}", FEES_REFERENCE,).into()); + } + let is_withdrawal_fee_zero = withdrawal_fee.numerator == 0 || withdrawal_fee.denominator == 0; + let is_deposit_fee_zero = deposit_fee.numerator == 0 || deposit_fee.denominator == 0; + if is_withdrawal_fee_zero && is_deposit_fee_zero { + return Err(format!( + "Withdrawal and deposit fee should not both be 0. {}", + FEES_REFERENCE, + ) + .into()); + } + Ok(()) +} + fn get_signer( matches: &ArgMatches<'_>, keypair_name: &str, @@ -192,15 +218,19 @@ fn command_create_pool( config: &Config, deposit_authority: Option, epoch_fee: Fee, - stake_withdrawal_fee: Fee, - stake_deposit_fee: Fee, - stake_referral_fee: u8, + withdrawal_fee: Fee, + deposit_fee: Fee, + referral_fee: u8, max_validators: u32, stake_pool_keypair: Option, validator_list_keypair: Option, mint_keypair: Option, reserve_keypair: Option, + unsafe_fees: bool, ) -> CommandResult { + if !unsafe_fees { + check_stake_pool_fees(&epoch_fee, &withdrawal_fee, &deposit_fee)?; + } let reserve_keypair = reserve_keypair.unwrap_or_else(Keypair::new); println!("Creating reserve stake {}", reserve_keypair.pubkey()); @@ -326,9 +356,9 @@ fn command_create_pool( &spl_token::id(), deposit_authority.as_ref().map(|x| x.pubkey()), epoch_fee, - stake_withdrawal_fee, - stake_deposit_fee, - stake_referral_fee, + withdrawal_fee, + deposit_fee, + referral_fee, max_validators, ), ], @@ -1958,6 +1988,12 @@ fn main() { .takes_value(true) .help("Stake pool reserve keypair [default: new keypair]"), ) + .arg( + Arg::with_name("unsafe_fees") + .long("unsafe-fees") + .takes_value(false) + .help("Bypass fee checks, allowing pool to be created with unsafe fees"), + ) ) .subcommand(SubCommand::with_name("add-validator") .about("Add validator account to the stake pool. Must be signed by the pool staker.") @@ -2657,6 +2693,7 @@ fn main() { let validator_list_keypair = keypair_of(arg_matches, "validator_list_keypair"); let mint_keypair = keypair_of(arg_matches, "mint_keypair"); let reserve_keypair = keypair_of(arg_matches, "reserve_keypair"); + let unsafe_fees = arg_matches.is_present("unsafe_fees"); command_create_pool( &config, deposit_authority, @@ -2678,6 +2715,7 @@ fn main() { validator_list_keypair, mint_keypair, reserve_keypair, + unsafe_fees, ) } ("add-validator", Some(arg_matches)) => { From cca9496dbf76b1600b49f8f7c4855f77706c89f3 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 20 Jan 2022 14:36:19 +0100 Subject: [PATCH 0219/1076] stake-pool-cli: Sign messages before checking fee (#2759) --- clients/cli/src/main.rs | 79 ++++++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 36 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index e5d4a846..f023e64c 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -30,6 +30,7 @@ use { solana_remote_wallet::remote_wallet::RemoteWalletManager, solana_sdk::{ commitment_config::CommitmentConfig, + hash::Hash, native_token::{self, Sol}, signature::{Keypair, Signer}, signers::Signers, @@ -135,6 +136,12 @@ fn get_signer( }) } +fn get_latest_blockhash(client: &RpcClient) -> Result { + Ok(client + .get_latest_blockhash_with_commitment(CommitmentConfig::confirmed())? + .0) +} + fn send_transaction_no_wait( config: &Config, transaction: Transaction, @@ -170,7 +177,7 @@ fn checked_transaction_with_signers( instructions: &[Instruction], signers: &T, ) -> Result { - let recent_blockhash = config.rpc_client.get_latest_blockhash()?; + let recent_blockhash = get_latest_blockhash(&config.rpc_client)?; let transaction = Transaction::new_signed_with_payer( instructions, Some(&config.fee_payer.pubkey()), @@ -365,27 +372,10 @@ fn command_create_pool( Some(&config.fee_payer.pubkey()), ); - let recent_blockhash = config.rpc_client.get_latest_blockhash()?; - check_fee_payer_balance( - config, - total_rent_free_balances - + config - .rpc_client - .get_fee_for_message(setup_transaction.message())? - + config - .rpc_client - .get_fee_for_message(initialize_transaction.message())?, - )?; + let recent_blockhash = get_latest_blockhash(&config.rpc_client)?; let mut setup_signers = vec![config.fee_payer.as_ref(), &mint_keypair, &reserve_keypair]; unique_signers!(setup_signers); setup_transaction.sign(&setup_signers, recent_blockhash); - send_transaction(config, setup_transaction)?; - - println!( - "Creating stake pool {} with validator list {}", - stake_pool_keypair.pubkey(), - validator_list_keypair.pubkey() - ); let mut initialize_signers = vec![ config.fee_payer.as_ref(), &stake_pool_keypair, @@ -405,6 +395,23 @@ fn command_create_pool( unique_signers!(initialize_signers); initialize_transaction.sign(&initialize_signers, recent_blockhash); } + check_fee_payer_balance( + config, + total_rent_free_balances + + config + .rpc_client + .get_fee_for_message(setup_transaction.message())? + + config + .rpc_client + .get_fee_for_message(initialize_transaction.message())?, + )?; + send_transaction(config, setup_transaction)?; + + println!( + "Creating stake pool {} with validator list {}", + stake_pool_keypair.pubkey(), + validator_list_keypair.pubkey() + ); send_transaction(config, initialize_transaction)?; Ok(()) } @@ -761,7 +768,9 @@ fn command_deposit_stake( let mut transaction = Transaction::new_with_payer(&instructions, Some(&config.fee_payer.pubkey())); - let recent_blockhash = config.rpc_client.get_latest_blockhash()?; + let recent_blockhash = get_latest_blockhash(&config.rpc_client)?; + unique_signers!(signers); + transaction.sign(&signers, recent_blockhash); check_fee_payer_balance( config, total_rent_free_balances @@ -769,8 +778,6 @@ fn command_deposit_stake( .rpc_client .get_fee_for_message(transaction.message())?, )?; - unique_signers!(signers); - transaction.sign(&signers, recent_blockhash); send_transaction(config, transaction)?; Ok(()) } @@ -802,7 +809,7 @@ fn command_deposit_all_stake( &mut total_rent_free_balances, )); if !create_token_account_instructions.is_empty() { - let recent_blockhash = config.rpc_client.get_latest_blockhash()?; + let recent_blockhash = get_latest_blockhash(&config.rpc_client)?; let transaction = Transaction::new_signed_with_payer( &create_token_account_instructions, Some(&config.fee_payer.pubkey()), @@ -903,7 +910,7 @@ fn command_deposit_all_stake( ) }; - let recent_blockhash = config.rpc_client.get_latest_blockhash()?; + let recent_blockhash = get_latest_blockhash(&config.rpc_client)?; let transaction = Transaction::new_signed_with_payer( &instructions, Some(&config.fee_payer.pubkey()), @@ -1034,7 +1041,9 @@ fn command_deposit_sol( let mut transaction = Transaction::new_with_payer(&instructions, Some(&config.fee_payer.pubkey())); - let recent_blockhash = config.rpc_client.get_latest_blockhash()?; + let recent_blockhash = get_latest_blockhash(&config.rpc_client)?; + unique_signers!(signers); + transaction.sign(&signers, recent_blockhash); check_fee_payer_balance( config, total_rent_free_balances @@ -1042,8 +1051,6 @@ fn command_deposit_sol( .rpc_client .get_fee_for_message(transaction.message())?, )?; - unique_signers!(signers); - transaction.sign(&signers, recent_blockhash); send_transaction(config, transaction)?; Ok(()) } @@ -1495,7 +1502,12 @@ fn command_withdraw_stake( let mut transaction = Transaction::new_with_payer(&instructions, Some(&config.fee_payer.pubkey())); - let recent_blockhash = config.rpc_client.get_latest_blockhash()?; + let recent_blockhash = get_latest_blockhash(&config.rpc_client)?; + for new_stake_keypair in &new_stake_keypairs { + signers.push(new_stake_keypair); + } + unique_signers!(signers); + transaction.sign(&signers, recent_blockhash); check_fee_payer_balance( config, total_rent_free_balances @@ -1503,11 +1515,6 @@ fn command_withdraw_stake( .rpc_client .get_fee_for_message(transaction.message())?, )?; - for new_stake_keypair in &new_stake_keypairs { - signers.push(new_stake_keypair); - } - unique_signers!(signers); - transaction.sign(&signers, recent_blockhash); send_transaction(config, transaction)?; Ok(()) } @@ -1620,15 +1627,15 @@ fn command_withdraw_sol( let mut transaction = Transaction::new_with_payer(&instructions, Some(&config.fee_payer.pubkey())); - let recent_blockhash = config.rpc_client.get_latest_blockhash()?; + let recent_blockhash = get_latest_blockhash(&config.rpc_client)?; + unique_signers!(signers); + transaction.sign(&signers, recent_blockhash); check_fee_payer_balance( config, config .rpc_client .get_fee_for_message(transaction.message())?, )?; - unique_signers!(signers); - transaction.sign(&signers, recent_blockhash); send_transaction(config, transaction)?; Ok(()) } From b2e8d02cdb168e57cf2baff4f887972d04f87d22 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 21 Jan 2022 01:47:02 +0100 Subject: [PATCH 0220/1076] token: Bump version to 3.3.0 (#2765) --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 265523db..50d5e264 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -25,7 +25,7 @@ solana-remote-wallet = "=1.9.2" solana-sdk = "=1.9.2" spl-associated-token-account = { version = "1.0", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "0.6", path="../program", features = [ "no-entrypoint" ] } -spl-token = { version = "3.2", path="../../token/program", features = [ "no-entrypoint" ] } +spl-token = { version = "3.3", path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" bincode = "1.3.1" diff --git a/program/Cargo.toml b/program/Cargo.toml index 795085ef..cd81e5b9 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -21,7 +21,7 @@ serde = "1.0.130" serde_derive = "1.0.103" solana-program = "1.9.2" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } -spl-token = { version = "3.2", path = "../../token/program", features = [ "no-entrypoint" ] } +spl-token = { version = "3.3", path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" bincode = "1.3.1" From 01abed92589310ea375794960aa3959eb2914dee Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 21 Jan 2022 11:01:06 +0100 Subject: [PATCH 0221/1076] associated-token-account: Bump dependent token version to 3.3 (#2766) * associated-token-account: Bump dependent token version to 3.3 * Fix uses of deprecated instruction --- clients/cli/src/main.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index f023e64c..db5202d5 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -37,7 +37,9 @@ use { system_instruction, transaction::Transaction, }, - spl_associated_token_account::{create_associated_token_account, get_associated_token_address}, + spl_associated_token_account::{ + get_associated_token_address, instruction::create_associated_token_account, + }, spl_stake_pool::state::ValidatorStakeInfo, spl_stake_pool::{ self, find_stake_program_address, find_transient_stake_program_address, From de5717bdd98c7cdd83405d2f284f5eb4b91d1682 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Sat, 22 Jan 2022 01:11:58 +0100 Subject: [PATCH 0222/1076] stake-pool-cli / token-lending-cli: Sign after balance check (#2773) --- clients/cli/src/main.rs | 147 +++++++++++++++++----------------------- 1 file changed, 63 insertions(+), 84 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index db5202d5..b0cb15c4 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -31,6 +31,7 @@ use { solana_sdk::{ commitment_config::CommitmentConfig, hash::Hash, + message::Message, native_token::{self, Sol}, signature::{Keypair, Signer}, signers::Signers, @@ -180,18 +181,13 @@ fn checked_transaction_with_signers( signers: &T, ) -> Result { let recent_blockhash = get_latest_blockhash(&config.rpc_client)?; - let transaction = Transaction::new_signed_with_payer( + let message = Message::new_with_blockhash( instructions, Some(&config.fee_payer.pubkey()), - signers, - recent_blockhash, + &recent_blockhash, ); - check_fee_payer_balance( - config, - config - .rpc_client - .get_fee_for_message(transaction.message())?, - )?; + check_fee_payer_balance(config, config.rpc_client.get_fee_for_message(&message)?)?; + let transaction = Transaction::new(signers, message, recent_blockhash); Ok(transaction) } @@ -330,10 +326,13 @@ fn command_create_pool( ); println!("Creating pool fee collection account {}", pool_fee_account); - let mut setup_transaction = - Transaction::new_with_payer(&instructions, Some(&config.fee_payer.pubkey())); - - let mut initialize_transaction = Transaction::new_with_payer( + let recent_blockhash = get_latest_blockhash(&config.rpc_client)?; + let setup_message = Message::new_with_blockhash( + &instructions, + Some(&config.fee_payer.pubkey()), + &recent_blockhash, + ); + let initialize_message = Message::new_with_blockhash( &[ // Validator stake account list storage system_instruction::create_account( @@ -372,19 +371,24 @@ fn command_create_pool( ), ], Some(&config.fee_payer.pubkey()), + &recent_blockhash, ); - - let recent_blockhash = get_latest_blockhash(&config.rpc_client)?; + check_fee_payer_balance( + config, + total_rent_free_balances + + config.rpc_client.get_fee_for_message(&setup_message)? + + config.rpc_client.get_fee_for_message(&initialize_message)?, + )?; let mut setup_signers = vec![config.fee_payer.as_ref(), &mint_keypair, &reserve_keypair]; unique_signers!(setup_signers); - setup_transaction.sign(&setup_signers, recent_blockhash); + let setup_transaction = Transaction::new(&setup_signers, setup_message, recent_blockhash); let mut initialize_signers = vec![ config.fee_payer.as_ref(), &stake_pool_keypair, &validator_list_keypair, config.manager.as_ref(), ]; - if let Some(deposit_authority) = deposit_authority { + let initialize_transaction = if let Some(deposit_authority) = deposit_authority { println!( "Deposits will be restricted to {} only, this can be changed using the set-funding-authority command.", deposit_authority.pubkey() @@ -392,21 +396,11 @@ fn command_create_pool( let mut initialize_signers = initialize_signers.clone(); initialize_signers.push(&deposit_authority); unique_signers!(initialize_signers); - initialize_transaction.sign(&initialize_signers, recent_blockhash); + Transaction::new(&initialize_signers, initialize_message, recent_blockhash) } else { unique_signers!(initialize_signers); - initialize_transaction.sign(&initialize_signers, recent_blockhash); - } - check_fee_payer_balance( - config, - total_rent_free_balances - + config - .rpc_client - .get_fee_for_message(setup_transaction.message())? - + config - .rpc_client - .get_fee_for_message(initialize_transaction.message())?, - )?; + Transaction::new(&initialize_signers, initialize_message, recent_blockhash) + }; send_transaction(config, setup_transaction)?; println!( @@ -767,19 +761,18 @@ fn command_deposit_stake( instructions.append(&mut deposit_instructions); - let mut transaction = - Transaction::new_with_payer(&instructions, Some(&config.fee_payer.pubkey())); - let recent_blockhash = get_latest_blockhash(&config.rpc_client)?; - unique_signers!(signers); - transaction.sign(&signers, recent_blockhash); + let message = Message::new_with_blockhash( + &instructions, + Some(&config.fee_payer.pubkey()), + &recent_blockhash, + ); check_fee_payer_balance( config, - total_rent_free_balances - + config - .rpc_client - .get_fee_for_message(transaction.message())?, + total_rent_free_balances + config.rpc_client.get_fee_for_message(&message)?, )?; + unique_signers!(signers); + let transaction = Transaction::new(&signers, message, recent_blockhash); send_transaction(config, transaction)?; Ok(()) } @@ -812,19 +805,16 @@ fn command_deposit_all_stake( )); if !create_token_account_instructions.is_empty() { let recent_blockhash = get_latest_blockhash(&config.rpc_client)?; - let transaction = Transaction::new_signed_with_payer( + let message = Message::new_with_blockhash( &create_token_account_instructions, Some(&config.fee_payer.pubkey()), - &[config.fee_payer.as_ref()], - recent_blockhash, + &recent_blockhash, ); check_fee_payer_balance( config, - total_rent_free_balances - + config - .rpc_client - .get_fee_for_message(transaction.message())?, + total_rent_free_balances + config.rpc_client.get_fee_for_message(&message)?, )?; + let transaction = Transaction::new(&[config.fee_payer.as_ref()], message, recent_blockhash); send_transaction(config, transaction)?; } @@ -913,19 +903,13 @@ fn command_deposit_all_stake( }; let recent_blockhash = get_latest_blockhash(&config.rpc_client)?; - let transaction = Transaction::new_signed_with_payer( + let message = Message::new_with_blockhash( &instructions, Some(&config.fee_payer.pubkey()), - &signers, - recent_blockhash, + &recent_blockhash, ); - check_fee_payer_balance( - config, - config - .rpc_client - .get_fee_for_message(transaction.message())?, - )?; - + check_fee_payer_balance(config, config.rpc_client.get_fee_for_message(&message)?)?; + let transaction = Transaction::new(&signers, message, recent_blockhash); send_transaction(config, transaction)?; } Ok(()) @@ -1040,19 +1024,18 @@ fn command_deposit_sol( instructions.push(deposit_instruction); - let mut transaction = - Transaction::new_with_payer(&instructions, Some(&config.fee_payer.pubkey())); - let recent_blockhash = get_latest_blockhash(&config.rpc_client)?; - unique_signers!(signers); - transaction.sign(&signers, recent_blockhash); + let message = Message::new_with_blockhash( + &instructions, + Some(&config.fee_payer.pubkey()), + &recent_blockhash, + ); check_fee_payer_balance( config, - total_rent_free_balances - + config - .rpc_client - .get_fee_for_message(transaction.message())?, + total_rent_free_balances + config.rpc_client.get_fee_for_message(&message)?, )?; + unique_signers!(signers); + let transaction = Transaction::new(&signers, message, recent_blockhash); send_transaction(config, transaction)?; Ok(()) } @@ -1501,22 +1484,21 @@ fn command_withdraw_stake( )); } - let mut transaction = - Transaction::new_with_payer(&instructions, Some(&config.fee_payer.pubkey())); - let recent_blockhash = get_latest_blockhash(&config.rpc_client)?; + let message = Message::new_with_blockhash( + &instructions, + Some(&config.fee_payer.pubkey()), + &recent_blockhash, + ); for new_stake_keypair in &new_stake_keypairs { signers.push(new_stake_keypair); } - unique_signers!(signers); - transaction.sign(&signers, recent_blockhash); check_fee_payer_balance( config, - total_rent_free_balances - + config - .rpc_client - .get_fee_for_message(transaction.message())?, + total_rent_free_balances + config.rpc_client.get_fee_for_message(&message)?, )?; + unique_signers!(signers); + let transaction = Transaction::new(&signers, message, recent_blockhash); send_transaction(config, transaction)?; Ok(()) } @@ -1626,18 +1608,15 @@ fn command_withdraw_sol( instructions.push(withdraw_instruction); - let mut transaction = - Transaction::new_with_payer(&instructions, Some(&config.fee_payer.pubkey())); - let recent_blockhash = get_latest_blockhash(&config.rpc_client)?; + let message = Message::new_with_blockhash( + &instructions, + Some(&config.fee_payer.pubkey()), + &recent_blockhash, + ); + check_fee_payer_balance(config, config.rpc_client.get_fee_for_message(&message)?)?; unique_signers!(signers); - transaction.sign(&signers, recent_blockhash); - check_fee_payer_balance( - config, - config - .rpc_client - .get_fee_for_message(transaction.message())?, - )?; + let transaction = Transaction::new(&signers, message, recent_blockhash); send_transaction(config, transaction)?; Ok(()) } From 01ac5f1aafd63e2b8aca478c4aad60d3f7f0d7de Mon Sep 17 00:00:00 2001 From: Tyera Eulberg Date: Fri, 21 Jan 2022 22:52:10 -0700 Subject: [PATCH 0223/1076] Bump solana crates to v1.9.5 (#2780) * Bump solana crates to v1.9.5 * Update sol_set_return_data type signature and un-ignore test --- clients/cli/Cargo.toml | 18 +++++++++--------- program/Cargo.toml | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 50d5e264..94050847 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -14,15 +14,15 @@ clap = "2.33.3" serde = "1.0.130" serde_derive = "1.0.130" serde_json = "1.0.68" -solana-account-decoder = "=1.9.2" -solana-clap-utils = "=1.9.2" -solana-cli-config = "=1.9.2" -solana-cli-output = "1.9.2" -solana-client = "=1.9.2" -solana-logger = "=1.9.2" -solana-program = "=1.9.2" -solana-remote-wallet = "=1.9.2" -solana-sdk = "=1.9.2" +solana-account-decoder = "=1.9.5" +solana-clap-utils = "=1.9.5" +solana-cli-config = "=1.9.5" +solana-cli-output = "1.9.5" +solana-client = "=1.9.5" +solana-logger = "=1.9.5" +solana-program = "=1.9.5" +solana-remote-wallet = "=1.9.5" +solana-sdk = "=1.9.5" spl-associated-token-account = { version = "1.0", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "0.6", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "3.3", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/program/Cargo.toml b/program/Cargo.toml index cd81e5b9..523793a5 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -19,7 +19,7 @@ num-traits = "0.2" num_enum = "0.5.4" serde = "1.0.130" serde_derive = "1.0.103" -solana-program = "1.9.2" +solana-program = "1.9.5" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-token = { version = "3.3", path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" @@ -27,9 +27,9 @@ bincode = "1.3.1" [dev-dependencies] proptest = "1.0" -solana-program-test = "1.9.2" -solana-sdk = "1.9.2" -solana-vote-program = "1.9.2" +solana-program-test = "1.9.5" +solana-sdk = "1.9.5" +solana-vote-program = "1.9.5" [lib] crate-type = ["cdylib", "lib"] From 6b9f17b7ac5bf142c7989605170e3b7d9e711693 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Mon, 24 Jan 2022 13:59:42 -0800 Subject: [PATCH 0224/1076] Drop _program_id --- clients/cli/Cargo.toml | 2 +- clients/cli/src/main.rs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 94050847..2e64358d 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -23,7 +23,7 @@ solana-logger = "=1.9.5" solana-program = "=1.9.5" solana-remote-wallet = "=1.9.5" solana-sdk = "=1.9.5" -spl-associated-token-account = { version = "1.0", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } +spl-associated-token-account = { version = "1.0.5", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "0.6", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "3.3", path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index b0cb15c4..25424ab6 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -641,6 +641,7 @@ fn add_associated_token_account( &config.fee_payer.pubkey(), owner, mint, + &spl_token::id(), )); *rent_free_balances += min_account_balance; From 4fc76a92b15c8de950e6653edc104b3b8d73066e Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 27 Jan 2022 17:50:22 +0100 Subject: [PATCH 0225/1076] stake-pool-cli: Use old ATA creation instruction (#2819) --- clients/cli/src/main.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 25424ab6..5457325c 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -38,9 +38,7 @@ use { system_instruction, transaction::Transaction, }, - spl_associated_token_account::{ - get_associated_token_address, instruction::create_associated_token_account, - }, + spl_associated_token_account::get_associated_token_address, spl_stake_pool::state::ValidatorStakeInfo, spl_stake_pool::{ self, find_stake_program_address, find_transient_stake_program_address, @@ -52,6 +50,9 @@ use { std::cmp::Ordering, std::{process::exit, sync::Arc}, }; +// use instruction::create_associated_token_account once ATA 1.0.5 is released +#[allow(deprecated)] +use spl_associated_token_account::create_associated_token_account; pub(crate) struct Config { rpc_client: RpcClient, @@ -637,11 +638,11 @@ fn add_associated_token_account( .get_minimum_balance_for_rent_exemption(spl_token::state::Account::LEN) .unwrap(); + #[allow(deprecated)] instructions.push(create_associated_token_account( &config.fee_payer.pubkey(), owner, mint, - &spl_token::id(), )); *rent_free_balances += min_account_balance; From df31f474ed4b987b493fc93bc94a02df09482c4c Mon Sep 17 00:00:00 2001 From: Kabir R Date: Fri, 28 Jan 2022 10:15:51 -0800 Subject: [PATCH 0226/1076] Add stake-pool browser build commands and documentation (#2804) * Add browser build commands and documentation * Improve rollup configuration * Remove unused external import from rollup configuration * Move from Babel to Typescript plugin Co-authored-by: Jon Cinque --- clients/js-legacy/.gitignore | 1 + clients/js-legacy/README.md | 34 +- clients/js-legacy/package-lock.json | 1962 ++++++++++++++++++--------- clients/js-legacy/package.json | 37 +- clients/js-legacy/rollup.config.js | 125 ++ clients/js-legacy/tsconfig.json | 2 +- 6 files changed, 1502 insertions(+), 659 deletions(-) create mode 100644 clients/js-legacy/rollup.config.js diff --git a/clients/js-legacy/.gitignore b/clients/js-legacy/.gitignore index 9668d6fe..6edc39b0 100644 --- a/clients/js-legacy/.gitignore +++ b/clients/js-legacy/.gitignore @@ -1,3 +1,4 @@ dist +dist.browser .idea node_modules diff --git a/clients/js-legacy/README.md b/clients/js-legacy/README.md index e9ca4911..b4030d23 100644 --- a/clients/js-legacy/README.md +++ b/clients/js-legacy/README.md @@ -14,13 +14,41 @@ In the `js` folder: ``` npm run build -npm run lint -node dist/index.js +``` + +The build is available at `dist/index.js` (or `dist.browser/index.iife.js` in the browser). + +## Browser bundle +```html + + + + + ``` ## Test ``` -npm run build npm test ``` + +## Usage + +### JavaScript +```javascript +const solanaStakePool = require('@solana/spl-stake-pool'); +console.log(solanaStakePool); +``` + +### ES6 +```javascript +import * as solanaStakePool from '@solana/spl-stake-pool'; +console.log(solanaStakePool); +``` + +### Browser bundle +```javascript +// `solanaStakePool` is provided in the global namespace by the script bundle. +console.log(solanaStakePool); +``` \ No newline at end of file diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 5700d5bf..e5693aca 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -14,20 +14,33 @@ "@solana/spl-token": "^0.1.8", "@solana/web3.js": "^1.30.2", "bn.js": "^5.2.0", - "buffer": "^6.0.3", - "process": "^0.11.10" + "buffer": "^6.0.3" }, "devDependencies": { + "@babel/core": "^7.16.5", "@babel/preset-env": "^7.16.5", "@babel/preset-typescript": "^7.16.5", + "@rollup/plugin-alias": "^3.1.9", + "@rollup/plugin-commonjs": "^21.0.1", + "@rollup/plugin-json": "^4.1.0", + "@rollup/plugin-multi-entry": "^4.1.0", + "@rollup/plugin-node-resolve": "^13.1.3", + "@rollup/plugin-typescript": "^8.3.0", "@types/bn.js": "^5.1.0", "@types/jest": "^27.0.3", "@typescript-eslint/eslint-plugin": "^5.8.1", "@typescript-eslint/parser": "^5.8.1", + "babel-jest": "^27.4.6", + "cross-env": "^7.0.3", "eslint": "^8.5.0", "eslint-plugin-react": "^7.28.0", - "jest": "^27.3.1", + "jest": "^27.4.7", "prettier": "^2.2.1", + "rimraf": "^3.0.2", + "rollup": "^2.66.1", + "rollup-plugin-dts": "^4.1.0", + "rollup-plugin-node-polyfills": "^0.2.1", + "rollup-plugin-terser": "^7.0.2", "typescript": "^4.5.4" } }, @@ -177,9 +190,9 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.0.tgz", - "integrity": "sha512-7hfT8lUljl/tM3h+izTX/pO3W3frz2ok6Pk+gzys8iJqDfZrZy2pXjRTZAvG2YmfHun1X4q8/UZRLatMfqc5Tg==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz", + "integrity": "sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA==", "dev": true, "dependencies": { "@babel/helper-compilation-targets": "^7.13.0", @@ -270,12 +283,12 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.0.tgz", - "integrity": "sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", + "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", "dev": true, "dependencies": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -313,9 +326,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.5.tgz", - "integrity": "sha512-59KHWHXxVA9K4HNF4sbHCf+eJeFe0Te/ZFGqBT4OjXhrwvA04sGfaEGsVTdsjoszq0YTP49RC9UKe5g8uN2RwQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", + "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", "dev": true, "engines": { "node": ">=6.9.0" @@ -388,9 +401,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", - "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", "dev": true, "engines": { "node": ">=6.9.0" @@ -1646,12 +1659,12 @@ } }, "node_modules/@babel/types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.0.tgz", - "integrity": "sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.8.tgz", + "integrity": "sha512-smN2DQc5s4M7fntyjGtyIPbRJv6wW4rU/94fmYJ7PKQuZkC0qGMHXJbg6sNGt12JmVr4k5YaptI/XtiLJBnmIg==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.15.7", + "@babel/helper-validator-identifier": "^7.16.7", "to-fast-properties": "^2.0.0" }, "engines": { @@ -1841,15 +1854,15 @@ } }, "node_modules/@jest/console": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.4.2.tgz", - "integrity": "sha512-xknHThRsPB/To1FUbi6pCe43y58qFC03zfb6R7fDb/FfC7k2R3i1l+izRBJf8DI46KhYGRaF14Eo9A3qbBoixg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.4.6.tgz", + "integrity": "sha512-jauXyacQD33n47A44KrlOVeiXHEXDqapSdfb9kTekOchH/Pd18kBIO1+xxJQRLuG+LUuljFCwTG92ra4NW7SpA==", "dev": true, "dependencies": { "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^27.4.2", + "jest-message-util": "^27.4.6", "jest-util": "^27.4.2", "slash": "^3.0.0" }, @@ -1928,15 +1941,15 @@ } }, "node_modules/@jest/core": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.4.5.tgz", - "integrity": "sha512-3tm/Pevmi8bDsgvo73nX8p/WPng6KWlCyScW10FPEoN1HU4pwI83tJ3TsFvi1FfzsjwUlMNEPowgb/rPau/LTQ==", + "version": "27.4.7", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.4.7.tgz", + "integrity": "sha512-n181PurSJkVMS+kClIFSX/LLvw9ExSb+4IMtD6YnfxZVerw9ANYtW0bPrm0MJu2pfe9SY9FJ9FtQ+MdZkrZwjg==", "dev": true, "dependencies": { - "@jest/console": "^27.4.2", - "@jest/reporters": "^27.4.5", - "@jest/test-result": "^27.4.2", - "@jest/transform": "^27.4.5", + "@jest/console": "^27.4.6", + "@jest/reporters": "^27.4.6", + "@jest/test-result": "^27.4.6", + "@jest/transform": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", "ansi-escapes": "^4.2.1", @@ -1945,18 +1958,18 @@ "exit": "^0.1.2", "graceful-fs": "^4.2.4", "jest-changed-files": "^27.4.2", - "jest-config": "^27.4.5", - "jest-haste-map": "^27.4.5", - "jest-message-util": "^27.4.2", + "jest-config": "^27.4.7", + "jest-haste-map": "^27.4.6", + "jest-message-util": "^27.4.6", "jest-regex-util": "^27.4.0", - "jest-resolve": "^27.4.5", - "jest-resolve-dependencies": "^27.4.5", - "jest-runner": "^27.4.5", - "jest-runtime": "^27.4.5", - "jest-snapshot": "^27.4.5", + "jest-resolve": "^27.4.6", + "jest-resolve-dependencies": "^27.4.6", + "jest-runner": "^27.4.6", + "jest-runtime": "^27.4.6", + "jest-snapshot": "^27.4.6", "jest-util": "^27.4.2", - "jest-validate": "^27.4.2", - "jest-watcher": "^27.4.2", + "jest-validate": "^27.4.6", + "jest-watcher": "^27.4.6", "micromatch": "^4.0.4", "rimraf": "^3.0.0", "slash": "^3.0.0", @@ -2045,31 +2058,31 @@ } }, "node_modules/@jest/environment": { - "version": "27.4.4", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.4.4.tgz", - "integrity": "sha512-q+niMx7cJgt/t/b6dzLOh4W8Ef/8VyKG7hxASK39jakijJzbFBGpptx3RXz13FFV7OishQ9lTbv+dQ5K3EhfDQ==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.4.6.tgz", + "integrity": "sha512-E6t+RXPfATEEGVidr84WngLNWZ8ffCPky8RqqRK6u1Bn0LK92INe0MDttyPl/JOzaq92BmDzOeuqk09TvM22Sg==", "dev": true, "dependencies": { - "@jest/fake-timers": "^27.4.2", + "@jest/fake-timers": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", - "jest-mock": "^27.4.2" + "jest-mock": "^27.4.6" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/fake-timers": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.4.2.tgz", - "integrity": "sha512-f/Xpzn5YQk5adtqBgvw1V6bF8Nx3hY0OIRRpCvWcfPl0EAjdqWPdhH3t/3XpiWZqtjIEHDyMKP9ajpva1l4Zmg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.4.6.tgz", + "integrity": "sha512-mfaethuYF8scV8ntPpiVGIHQgS0XIALbpY2jt2l7wb/bvq4Q5pDLk4EP4D7SAvYT1QrPOPVZAtbdGAOOyIgs7A==", "dev": true, "dependencies": { "@jest/types": "^27.4.2", "@sinonjs/fake-timers": "^8.0.1", "@types/node": "*", - "jest-message-util": "^27.4.2", - "jest-mock": "^27.4.2", + "jest-message-util": "^27.4.6", + "jest-mock": "^27.4.6", "jest-util": "^27.4.2" }, "engines": { @@ -2077,29 +2090,29 @@ } }, "node_modules/@jest/globals": { - "version": "27.4.4", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.4.4.tgz", - "integrity": "sha512-bqpqQhW30BOreXM8bA8t8JbOQzsq/WnPTnBl+It3UxAD9J8yxEAaBEylHx1dtBapAr/UBk8GidXbzmqnee8tYQ==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.4.6.tgz", + "integrity": "sha512-kAiwMGZ7UxrgPzu8Yv9uvWmXXxsy0GciNejlHvfPIfWkSxChzv6bgTS3YqBkGuHcis+ouMFI2696n2t+XYIeFw==", "dev": true, "dependencies": { - "@jest/environment": "^27.4.4", + "@jest/environment": "^27.4.6", "@jest/types": "^27.4.2", - "expect": "^27.4.2" + "expect": "^27.4.6" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/reporters": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.4.5.tgz", - "integrity": "sha512-3orsG4vi8zXuBqEoy2LbnC1kuvkg1KQUgqNxmxpQgIOQEPeV0onvZu+qDQnEoX8qTQErtqn/xzcnbpeTuOLSiA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.4.6.tgz", + "integrity": "sha512-+Zo9gV81R14+PSq4wzee4GC2mhAN9i9a7qgJWL90Gpx7fHYkWpTBvwWNZUXvJByYR9tAVBdc8VxDWqfJyIUrIQ==", "dev": true, "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.4.2", - "@jest/test-result": "^27.4.2", - "@jest/transform": "^27.4.5", + "@jest/console": "^27.4.6", + "@jest/test-result": "^27.4.6", + "@jest/transform": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", @@ -2108,14 +2121,14 @@ "glob": "^7.1.2", "graceful-fs": "^4.2.4", "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-instrument": "^5.1.0", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "jest-haste-map": "^27.4.5", - "jest-resolve": "^27.4.5", + "istanbul-reports": "^3.1.3", + "jest-haste-map": "^27.4.6", + "jest-resolve": "^27.4.6", "jest-util": "^27.4.2", - "jest-worker": "^27.4.5", + "jest-worker": "^27.4.6", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^4.0.1", @@ -2237,12 +2250,12 @@ } }, "node_modules/@jest/test-result": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.4.2.tgz", - "integrity": "sha512-kr+bCrra9jfTgxHXHa2UwoQjxvQk3Am6QbpAiJ5x/50LW8llOYrxILkqY0lZRW/hu8FXesnudbql263+EW9iNA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.4.6.tgz", + "integrity": "sha512-fi9IGj3fkOrlMmhQqa/t9xum8jaJOOAi/lZlm6JXSc55rJMXKHxNDN1oCP39B0/DhNOa2OMupF9BcKZnNtXMOQ==", "dev": true, "dependencies": { - "@jest/console": "^27.4.2", + "@jest/console": "^27.4.6", "@jest/types": "^27.4.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" @@ -2252,38 +2265,38 @@ } }, "node_modules/@jest/test-sequencer": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.4.5.tgz", - "integrity": "sha512-n5woIn/1v+FT+9hniymHPARA9upYUmfi5Pw9ewVwXCDlK4F5/Gkees9v8vdjGdAIJ2MPHLHodiajLpZZanWzEQ==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.4.6.tgz", + "integrity": "sha512-3GL+nsf6E1PsyNsJuvPyIz+DwFuCtBdtvPpm/LMXVkBJbdFvQYCDpccYT56qq5BGniXWlE81n2qk1sdXfZebnw==", "dev": true, "dependencies": { - "@jest/test-result": "^27.4.2", + "@jest/test-result": "^27.4.6", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.5", - "jest-runtime": "^27.4.5" + "jest-haste-map": "^27.4.6", + "jest-runtime": "^27.4.6" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/transform": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.4.5.tgz", - "integrity": "sha512-PuMet2UlZtlGzwc6L+aZmR3I7CEBpqadO03pU40l2RNY2fFJ191b9/ITB44LNOhVtsyykx0OZvj0PCyuLm7Eew==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.4.6.tgz", + "integrity": "sha512-9MsufmJC8t5JTpWEQJ0OcOOAXaH5ioaIX6uHVBLBMoCZPfKKQF+EqP8kACAvCZ0Y1h2Zr3uOccg8re+Dr5jxyw==", "dev": true, "dependencies": { "@babel/core": "^7.1.0", "@jest/types": "^27.4.2", - "babel-plugin-istanbul": "^6.0.0", + "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.5", + "jest-haste-map": "^27.4.6", "jest-regex-util": "^27.4.0", "jest-util": "^27.4.2", "micromatch": "^4.0.4", - "pirates": "^4.0.1", + "pirates": "^4.0.4", "slash": "^3.0.0", "source-map": "^0.6.1", "write-file-atomic": "^3.0.0" @@ -2507,6 +2520,140 @@ "@solana/web3.js": "^1.2.0" } }, + "node_modules/@rollup/plugin-alias": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-3.1.9.tgz", + "integrity": "sha512-QI5fsEvm9bDzt32k39wpOwZhVzRcL5ydcffUHMyLVaVaLeC70I8TJZ17F1z1eMoLu4E/UOcH9BWVkKpIKdrfiw==", + "dev": true, + "dependencies": { + "slash": "^3.0.0" + }, + "engines": { + "node": ">=8.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@rollup/plugin-commonjs": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-21.0.1.tgz", + "integrity": "sha512-EA+g22lbNJ8p5kuZJUYyhhDK7WgJckW5g4pNN7n4mAFUM96VuwUnNT3xr2Db2iCZPI1pJPbGyfT5mS9T1dHfMg==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "commondir": "^1.0.1", + "estree-walker": "^2.0.1", + "glob": "^7.1.6", + "is-reference": "^1.2.1", + "magic-string": "^0.25.7", + "resolve": "^1.17.0" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^2.38.3" + } + }, + "node_modules/@rollup/plugin-commonjs/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, + "node_modules/@rollup/plugin-json": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-4.1.0.tgz", + "integrity": "sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^3.0.8" + }, + "peerDependencies": { + "rollup": "^1.20.0 || ^2.0.0" + } + }, + "node_modules/@rollup/plugin-multi-entry": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-multi-entry/-/plugin-multi-entry-4.1.0.tgz", + "integrity": "sha512-nellK5pr50W0JA2+bDJbG8F79GBP802J40YRoC0wyfpTAeAn5mJ4eaFiB/MN+YoX9hgb/6RJoZl9leDjZnUFKw==", + "dev": true, + "dependencies": { + "@rollup/plugin-virtual": "^2.0.3", + "matched": "^5.0.0" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0 || ^2.0.0" + } + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "13.1.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.1.3.tgz", + "integrity": "sha512-BdxNk+LtmElRo5d06MGY4zoepyrXX1tkzX2hrnPEZ53k78GuOMWLqmJDGIIOPwVRIFZrLQOo+Yr6KtCuLIA0AQ==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "@types/resolve": "1.17.1", + "builtin-modules": "^3.1.0", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "rollup": "^2.42.0" + } + }, + "node_modules/@rollup/plugin-typescript": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-8.3.0.tgz", + "integrity": "sha512-I5FpSvLbtAdwJ+naznv+B4sjXZUcIvLLceYpITAn7wAP8W0wqc5noLdGIp9HGVntNhRWXctwPYrSSFQxtl0FPA==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "resolve": "^1.17.0" + }, + "engines": { + "node": ">=8.0.0" + }, + "peerDependencies": { + "rollup": "^2.14.0", + "tslib": "*", + "typescript": ">=3.7.0" + } + }, + "node_modules/@rollup/plugin-virtual": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-virtual/-/plugin-virtual-2.0.3.tgz", + "integrity": "sha512-pw6ziJcyjZtntQ//bkad9qXaBx665SgEL8C8KI5wO8G5iU5MPxvdWrQyVaAvjojGm9tJoS8M9Z/EEepbqieYmw==", + "dev": true, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dev": true, + "dependencies": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, "node_modules/@sinonjs/commons": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", @@ -2700,6 +2847,12 @@ "@types/node": "*" } }, + "node_modules/@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true + }, "node_modules/@types/express-serve-static-core": { "version": "4.17.27", "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.27.tgz", @@ -2770,9 +2923,9 @@ "integrity": "sha512-w3mrvNXLeDYV1GKTZorGJQivK6XLCoGwpnyJFbJVK/aTBQUxOCaa/GlFAAN3OTDFcb7h5tiFG+YXCO2By+riZw==" }, "node_modules/@types/prettier": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.2.tgz", - "integrity": "sha512-ekoj4qOQYp7CvjX8ZDBgN86w3MqQhLE1hczEJbEIjgFEumDy+na/4AJAbLXfgEWFNB2pKadM5rPFtuSGMWK7xA==", + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.3.tgz", + "integrity": "sha512-QzSuZMBuG5u8HqYz01qtMdg/Jfctlnvj1z/lYnIDXs/golxw0fxtRAHd9KrzjR7Yxz1qVeI00o0kiO3PmVdJ9w==", "dev": true }, "node_modules/@types/qs": { @@ -2785,6 +2938,15 @@ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, + "node_modules/@types/resolve": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", + "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/stack-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", @@ -3234,15 +3396,15 @@ "dev": true }, "node_modules/babel-jest": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.4.5.tgz", - "integrity": "sha512-3uuUTjXbgtODmSv/DXO9nZfD52IyC2OYTFaXGRzL0kpykzroaquCrD5+lZNafTvZlnNqZHt5pb0M08qVBZnsnA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.4.6.tgz", + "integrity": "sha512-qZL0JT0HS1L+lOuH+xC2DVASR3nunZi/ozGhpgauJHgmI7f8rudxf6hUjEHympdQ/J64CdKmPkgfJ+A3U6QCrg==", "dev": true, "dependencies": { - "@jest/transform": "^27.4.5", + "@jest/transform": "^27.4.6", "@jest/types": "^27.4.2", "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.0.0", + "babel-plugin-istanbul": "^6.1.1", "babel-preset-jest": "^27.4.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", @@ -3350,22 +3512,6 @@ "node": ">=8" } }, - "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", - "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", - "dev": true, - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/babel-plugin-jest-hoist": { "version": "27.4.0", "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.4.0.tgz", @@ -3639,6 +3785,18 @@ "node": ">=6.14.2" } }, + "node_modules/builtin-modules": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", + "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -3780,6 +3938,12 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -3824,6 +3988,24 @@ "semver": "bin/semver.js" } }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, "node_modules/cross-fetch": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz", @@ -4592,6 +4774,12 @@ "node": ">=4.0" } }, + "node_modules/estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "dev": true + }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -4639,34 +4827,20 @@ } }, "node_modules/expect": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.4.2.tgz", - "integrity": "sha512-BjAXIDC6ZOW+WBFNg96J22D27Nq5ohn+oGcuP2rtOtcjuxNoV9McpQ60PcQWhdFOSBIQdR72e+4HdnbZTFSTyg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.4.6.tgz", + "integrity": "sha512-1M/0kAALIaj5LaG66sFJTbRsWTADnylly82cu4bspI0nl+pgP4E6Bh/aqdHlTUjul06K7xQnnrAoqfxVU0+/ag==", "dev": true, "dependencies": { "@jest/types": "^27.4.2", - "ansi-styles": "^5.0.0", "jest-get-type": "^27.4.0", - "jest-matcher-utils": "^27.4.2", - "jest-message-util": "^27.4.2", - "jest-regex-util": "^27.4.0" + "jest-matcher-utils": "^27.4.6", + "jest-message-util": "^27.4.6" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/expect/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/eyes": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", @@ -5173,9 +5347,9 @@ } }, "node_modules/import-local": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.3.tgz", - "integrity": "sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", "dev": true, "dependencies": { "pkg-dir": "^4.2.0", @@ -5186,6 +5360,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/imurmurhash": { @@ -5332,6 +5509,12 @@ "node": ">=0.10.0" } }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", + "dev": true + }, "node_modules/is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", @@ -5374,6 +5557,15 @@ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", "dev": true }, + "node_modules/is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", + "dev": true, + "dependencies": { + "@types/estree": "*" + } + }, "node_modules/is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -5483,14 +5675,15 @@ } }, "node_modules/istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", + "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", "dev": true, "dependencies": { - "@babel/core": "^7.7.5", + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-coverage": "^3.2.0", "semver": "^6.3.0" }, "engines": { @@ -5602,14 +5795,14 @@ "integrity": "sha512-U7PMwkDmc3bnL0e4U8oA0POpi1vfsYDc+DEUS2+rPxm9NlLcW1dBa5JcRhO633PoPUcCSWMNXrMsqhmAVEo+IQ==" }, "node_modules/jest": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.4.5.tgz", - "integrity": "sha512-uT5MiVN3Jppt314kidCk47MYIRilJjA/l2mxwiuzzxGUeJIvA8/pDaJOAX5KWvjAo7SCydcW0/4WEtgbLMiJkg==", + "version": "27.4.7", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.4.7.tgz", + "integrity": "sha512-8heYvsx7nV/m8m24Vk26Y87g73Ba6ueUd0MWed/NXMhSZIm62U/llVbS0PJe1SHunbyXjJ/BqG1z9bFjGUIvTg==", "dev": true, "dependencies": { - "@jest/core": "^27.4.5", + "@jest/core": "^27.4.7", "import-local": "^3.0.2", - "jest-cli": "^27.4.5" + "jest-cli": "^27.4.7" }, "bin": { "jest": "bin/jest.js" @@ -5641,27 +5834,27 @@ } }, "node_modules/jest-circus": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.4.5.tgz", - "integrity": "sha512-eTNWa9wsvBwPykhMMShheafbwyakcdHZaEYh5iRrQ0PFJxkDP/e3U/FvzGuKWu2WpwUA3C3hPlfpuzvOdTVqnw==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.4.6.tgz", + "integrity": "sha512-UA7AI5HZrW4wRM72Ro80uRR2Fg+7nR0GESbSI/2M+ambbzVuA63mn5T1p3Z/wlhntzGpIG1xx78GP2YIkf6PhQ==", "dev": true, "dependencies": { - "@jest/environment": "^27.4.4", - "@jest/test-result": "^27.4.2", + "@jest/environment": "^27.4.6", + "@jest/test-result": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", - "expect": "^27.4.2", + "expect": "^27.4.6", "is-generator-fn": "^2.0.0", - "jest-each": "^27.4.2", - "jest-matcher-utils": "^27.4.2", - "jest-message-util": "^27.4.2", - "jest-runtime": "^27.4.5", - "jest-snapshot": "^27.4.5", + "jest-each": "^27.4.6", + "jest-matcher-utils": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-runtime": "^27.4.6", + "jest-snapshot": "^27.4.6", "jest-util": "^27.4.2", - "pretty-format": "^27.4.2", + "pretty-format": "^27.4.6", "slash": "^3.0.0", "stack-utils": "^2.0.3", "throat": "^6.0.1" @@ -5741,21 +5934,21 @@ } }, "node_modules/jest-cli": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.4.5.tgz", - "integrity": "sha512-hrky3DSgE0u7sQxaCL7bdebEPHx5QzYmrGuUjaPLmPE8jx5adtvGuOlRspvMoVLTTDOHRnZDoRLYJuA+VCI7Hg==", + "version": "27.4.7", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.4.7.tgz", + "integrity": "sha512-zREYhvjjqe1KsGV15mdnxjThKNDgza1fhDT+iUsXWLCq3sxe9w5xnvyctcYVT5PcdLSjv7Y5dCwTS3FCF1tiuw==", "dev": true, "dependencies": { - "@jest/core": "^27.4.5", - "@jest/test-result": "^27.4.2", + "@jest/core": "^27.4.7", + "@jest/test-result": "^27.4.6", "@jest/types": "^27.4.2", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.4", "import-local": "^3.0.2", - "jest-config": "^27.4.5", + "jest-config": "^27.4.7", "jest-util": "^27.4.2", - "jest-validate": "^27.4.2", + "jest-validate": "^27.4.6", "prompts": "^2.0.1", "yargs": "^16.2.0" }, @@ -5845,32 +6038,32 @@ } }, "node_modules/jest-config": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.4.5.tgz", - "integrity": "sha512-t+STVJtPt+fpqQ8GBw850NtSQbnDOw/UzdPfzDaHQ48/AylQlW7LHj3dH+ndxhC1UxJ0Q3qkq7IH+nM1skwTwA==", + "version": "27.4.7", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.4.7.tgz", + "integrity": "sha512-xz/o/KJJEedHMrIY9v2ParIoYSrSVY6IVeE4z5Z3i101GoA5XgfbJz+1C8EYPsv7u7f39dS8F9v46BHDhn0vlw==", "dev": true, "dependencies": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^27.4.5", + "@babel/core": "^7.8.0", + "@jest/test-sequencer": "^27.4.6", "@jest/types": "^27.4.2", - "babel-jest": "^27.4.5", + "babel-jest": "^27.4.6", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.1", "graceful-fs": "^4.2.4", - "jest-circus": "^27.4.5", - "jest-environment-jsdom": "^27.4.4", - "jest-environment-node": "^27.4.4", + "jest-circus": "^27.4.6", + "jest-environment-jsdom": "^27.4.6", + "jest-environment-node": "^27.4.6", "jest-get-type": "^27.4.0", - "jest-jasmine2": "^27.4.5", + "jest-jasmine2": "^27.4.6", "jest-regex-util": "^27.4.0", - "jest-resolve": "^27.4.5", - "jest-runner": "^27.4.5", + "jest-resolve": "^27.4.6", + "jest-runner": "^27.4.6", "jest-util": "^27.4.2", - "jest-validate": "^27.4.2", + "jest-validate": "^27.4.6", "micromatch": "^4.0.4", - "pretty-format": "^27.4.2", + "pretty-format": "^27.4.6", "slash": "^3.0.0" }, "engines": { @@ -5956,15 +6149,15 @@ } }, "node_modules/jest-diff": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.4.2.tgz", - "integrity": "sha512-ujc9ToyUZDh9KcqvQDkk/gkbf6zSaeEg9AiBxtttXW59H/AcqEYp1ciXAtJp+jXWva5nAf/ePtSsgWwE5mqp4Q==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.4.6.tgz", + "integrity": "sha512-zjaB0sh0Lb13VyPsd92V7HkqF6yKRH9vm33rwBt7rPYrpQvS1nCvlIy2pICbKta+ZjWngYLNn4cCK4nyZkjS/w==", "dev": true, "dependencies": { "chalk": "^4.0.0", "diff-sequences": "^27.4.0", "jest-get-type": "^27.4.0", - "pretty-format": "^27.4.2" + "pretty-format": "^27.4.6" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" @@ -6053,16 +6246,16 @@ } }, "node_modules/jest-each": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.4.2.tgz", - "integrity": "sha512-53V2MNyW28CTruB3lXaHNk6PkiIFuzdOC9gR3C6j8YE/ACfrPnz+slB0s17AgU1TtxNzLuHyvNlLJ+8QYw9nBg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.4.6.tgz", + "integrity": "sha512-n6QDq8y2Hsmn22tRkgAk+z6MCX7MeVlAzxmZDshfS2jLcaBlyhpF3tZSJLR+kXmh23GEvS0ojMR8i6ZeRvpQcA==", "dev": true, "dependencies": { "@jest/types": "^27.4.2", "chalk": "^4.0.0", "jest-get-type": "^27.4.0", "jest-util": "^27.4.2", - "pretty-format": "^27.4.2" + "pretty-format": "^27.4.6" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" @@ -6139,16 +6332,16 @@ } }, "node_modules/jest-environment-jsdom": { - "version": "27.4.4", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.4.4.tgz", - "integrity": "sha512-cYR3ndNfHBqQgFvS1RL7dNqSvD//K56j/q1s2ygNHcfTCAp12zfIromO1w3COmXrxS8hWAh7+CmZmGCIoqGcGA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.4.6.tgz", + "integrity": "sha512-o3dx5p/kHPbUlRvSNjypEcEtgs6LmvESMzgRFQE6c+Prwl2JLA4RZ7qAnxc5VM8kutsGRTB15jXeeSbJsKN9iA==", "dev": true, "dependencies": { - "@jest/environment": "^27.4.4", - "@jest/fake-timers": "^27.4.2", + "@jest/environment": "^27.4.6", + "@jest/fake-timers": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", - "jest-mock": "^27.4.2", + "jest-mock": "^27.4.6", "jest-util": "^27.4.2", "jsdom": "^16.6.0" }, @@ -6157,16 +6350,16 @@ } }, "node_modules/jest-environment-node": { - "version": "27.4.4", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.4.4.tgz", - "integrity": "sha512-D+v3lbJ2GjQTQR23TK0kY3vFVmSeea05giInI41HHOaJnAwOnmUHTZgUaZL+VxUB43pIzoa7PMwWtCVlIUoVoA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.4.6.tgz", + "integrity": "sha512-yfHlZ9m+kzTKZV0hVfhVu6GuDxKAYeFHrfulmy7Jxwsq4V7+ZK7f+c0XP/tbVDMQW7E4neG2u147hFkuVz0MlQ==", "dev": true, "dependencies": { - "@jest/environment": "^27.4.4", - "@jest/fake-timers": "^27.4.2", + "@jest/environment": "^27.4.6", + "@jest/fake-timers": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", - "jest-mock": "^27.4.2", + "jest-mock": "^27.4.6", "jest-util": "^27.4.2" }, "engines": { @@ -6183,9 +6376,9 @@ } }, "node_modules/jest-haste-map": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.4.5.tgz", - "integrity": "sha512-oJm1b5qhhPs78K24EDGifWS0dELYxnoBiDhatT/FThgB9yxqUm5F6li3Pv+Q+apMBmmPNzOBnZ7ZxWMB1Leq1Q==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.4.6.tgz", + "integrity": "sha512-0tNpgxg7BKurZeFkIOvGCkbmOHbLFf4LUQOxrQSMjvrQaQe3l6E8x6jYC1NuWkGo5WDdbr8FEzUxV2+LWNawKQ==", "dev": true, "dependencies": { "@jest/types": "^27.4.2", @@ -6197,7 +6390,7 @@ "jest-regex-util": "^27.4.0", "jest-serializer": "^27.4.0", "jest-util": "^27.4.2", - "jest-worker": "^27.4.5", + "jest-worker": "^27.4.6", "micromatch": "^4.0.4", "walker": "^1.0.7" }, @@ -6209,28 +6402,27 @@ } }, "node_modules/jest-jasmine2": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.4.5.tgz", - "integrity": "sha512-oUnvwhJDj2LhOiUB1kdnJjkx8C5PwgUZQb9urF77mELH9DGR4e2GqpWQKBOYXWs5+uTN9BGDqRz3Aeg5Wts7aw==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.4.6.tgz", + "integrity": "sha512-uAGNXF644I/whzhsf7/qf74gqy9OuhvJ0XYp8SDecX2ooGeaPnmJMjXjKt0mqh1Rl5dtRGxJgNrHlBQIBfS5Nw==", "dev": true, "dependencies": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^27.4.4", + "@jest/environment": "^27.4.6", "@jest/source-map": "^27.4.0", - "@jest/test-result": "^27.4.2", + "@jest/test-result": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "expect": "^27.4.2", + "expect": "^27.4.6", "is-generator-fn": "^2.0.0", - "jest-each": "^27.4.2", - "jest-matcher-utils": "^27.4.2", - "jest-message-util": "^27.4.2", - "jest-runtime": "^27.4.5", - "jest-snapshot": "^27.4.5", + "jest-each": "^27.4.6", + "jest-matcher-utils": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-runtime": "^27.4.6", + "jest-snapshot": "^27.4.6", "jest-util": "^27.4.2", - "pretty-format": "^27.4.2", + "pretty-format": "^27.4.6", "throat": "^6.0.1" }, "engines": { @@ -6308,28 +6500,28 @@ } }, "node_modules/jest-leak-detector": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.4.2.tgz", - "integrity": "sha512-ml0KvFYZllzPBJWDei3mDzUhyp/M4ubKebX++fPaudpe8OsxUE+m+P6ciVLboQsrzOCWDjE20/eXew9QMx/VGw==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.4.6.tgz", + "integrity": "sha512-kkaGixDf9R7CjHm2pOzfTxZTQQQ2gHTIWKY/JZSiYTc90bZp8kSZnUMS3uLAfwTZwc0tcMRoEX74e14LG1WapA==", "dev": true, "dependencies": { "jest-get-type": "^27.4.0", - "pretty-format": "^27.4.2" + "pretty-format": "^27.4.6" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-matcher-utils": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.4.2.tgz", - "integrity": "sha512-jyP28er3RRtMv+fmYC/PKG8wvAmfGcSNproVTW2Y0P/OY7/hWUOmsPfxN1jOhM+0u2xU984u2yEagGivz9OBGQ==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.4.6.tgz", + "integrity": "sha512-XD4PKT3Wn1LQnRAq7ZsTI0VRuEc9OrCPFiO1XL7bftTGmfNF0DcEwMHRgqiu7NGf8ZoZDREpGrCniDkjt79WbA==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^27.4.2", + "jest-diff": "^27.4.6", "jest-get-type": "^27.4.0", - "pretty-format": "^27.4.2" + "pretty-format": "^27.4.6" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" @@ -6406,9 +6598,9 @@ } }, "node_modules/jest-message-util": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.4.2.tgz", - "integrity": "sha512-OMRqRNd9E0DkBLZpFtZkAGYOXl6ZpoMtQJWTAREJKDOFa0M6ptB7L67tp+cszMBkvSgKOhNtQp2Vbcz3ZZKo/w==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.4.6.tgz", + "integrity": "sha512-0p5szriFU0U74czRSFjH6RyS7UYIAkn/ntwMuOwTGWrQIOh5NzXXrq72LOqIkJKKvFbPq+byZKuBz78fjBERBA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", @@ -6417,7 +6609,7 @@ "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.4", - "pretty-format": "^27.4.2", + "pretty-format": "^27.4.6", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -6496,9 +6688,9 @@ } }, "node_modules/jest-mock": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.4.2.tgz", - "integrity": "sha512-PDDPuyhoukk20JrQKeofK12hqtSka7mWH0QQuxSNgrdiPsrnYYLS6wbzu/HDlxZRzji5ylLRULeuI/vmZZDrYA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.4.6.tgz", + "integrity": "sha512-kvojdYRkst8iVSZ1EJ+vc1RRD9llueBjKzXzeCytH3dMM7zvPV/ULcfI2nr0v0VUgm3Bjt3hBCQvOeaBz+ZTHw==", "dev": true, "dependencies": { "@jest/types": "^27.4.2", @@ -6535,18 +6727,18 @@ } }, "node_modules/jest-resolve": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.4.5.tgz", - "integrity": "sha512-xU3z1BuOz/hUhVUL+918KqUgK+skqOuUsAi7A+iwoUldK6/+PW+utK8l8cxIWT9AW7IAhGNXjSAh1UYmjULZZw==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.4.6.tgz", + "integrity": "sha512-SFfITVApqtirbITKFAO7jOVN45UgFzcRdQanOFzjnbd+CACDoyeX7206JyU92l4cRr73+Qy/TlW51+4vHGt+zw==", "dev": true, "dependencies": { "@jest/types": "^27.4.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.5", + "jest-haste-map": "^27.4.6", "jest-pnp-resolver": "^1.2.2", "jest-util": "^27.4.2", - "jest-validate": "^27.4.2", + "jest-validate": "^27.4.6", "resolve": "^1.20.0", "resolve.exports": "^1.1.0", "slash": "^3.0.0" @@ -6556,14 +6748,14 @@ } }, "node_modules/jest-resolve-dependencies": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.4.5.tgz", - "integrity": "sha512-elEVvkvRK51y037NshtEkEnukMBWvlPzZHiL847OrIljJ8yIsujD2GXRPqDXC4rEVKbcdsy7W0FxoZb4WmEs7w==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.4.6.tgz", + "integrity": "sha512-W85uJZcFXEVZ7+MZqIPCscdjuctruNGXUZ3OHSXOfXR9ITgbUKeHj+uGcies+0SsvI5GtUfTw4dY7u9qjTvQOw==", "dev": true, "dependencies": { "@jest/types": "^27.4.2", "jest-regex-util": "^27.4.0", - "jest-snapshot": "^27.4.5" + "jest-snapshot": "^27.4.6" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" @@ -6640,15 +6832,15 @@ } }, "node_modules/jest-runner": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.4.5.tgz", - "integrity": "sha512-/irauncTfmY1WkTaRQGRWcyQLzK1g98GYG/8QvIPviHgO1Fqz1JYeEIsSfF+9mc/UTA6S+IIHFgKyvUrtiBIZg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.4.6.tgz", + "integrity": "sha512-IDeFt2SG4DzqalYBZRgbbPmpwV3X0DcntjezPBERvnhwKGWTW7C5pbbA5lVkmvgteeNfdd/23gwqv3aiilpYPg==", "dev": true, "dependencies": { - "@jest/console": "^27.4.2", - "@jest/environment": "^27.4.4", - "@jest/test-result": "^27.4.2", - "@jest/transform": "^27.4.5", + "@jest/console": "^27.4.6", + "@jest/environment": "^27.4.6", + "@jest/test-result": "^27.4.6", + "@jest/transform": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", @@ -6656,15 +6848,15 @@ "exit": "^0.1.2", "graceful-fs": "^4.2.4", "jest-docblock": "^27.4.0", - "jest-environment-jsdom": "^27.4.4", - "jest-environment-node": "^27.4.4", - "jest-haste-map": "^27.4.5", - "jest-leak-detector": "^27.4.2", - "jest-message-util": "^27.4.2", - "jest-resolve": "^27.4.5", - "jest-runtime": "^27.4.5", + "jest-environment-jsdom": "^27.4.6", + "jest-environment-node": "^27.4.6", + "jest-haste-map": "^27.4.6", + "jest-leak-detector": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-resolve": "^27.4.6", + "jest-runtime": "^27.4.6", "jest-util": "^27.4.2", - "jest-worker": "^27.4.5", + "jest-worker": "^27.4.6", "source-map-support": "^0.5.6", "throat": "^6.0.1" }, @@ -6743,37 +6935,33 @@ } }, "node_modules/jest-runtime": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.4.5.tgz", - "integrity": "sha512-CIYqwuJQXHQtPd/idgrx4zgJ6iCb6uBjQq1RSAGQrw2S8XifDmoM1Ot8NRd80ooAm+ZNdHVwsktIMGlA1F1FAQ==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.4.6.tgz", + "integrity": "sha512-eXYeoR/MbIpVDrjqy5d6cGCFOYBFFDeKaNWqTp0h6E74dK0zLHzASQXJpl5a2/40euBmKnprNLJ0Kh0LCndnWQ==", "dev": true, "dependencies": { - "@jest/console": "^27.4.2", - "@jest/environment": "^27.4.4", - "@jest/globals": "^27.4.4", + "@jest/environment": "^27.4.6", + "@jest/fake-timers": "^27.4.6", + "@jest/globals": "^27.4.6", "@jest/source-map": "^27.4.0", - "@jest/test-result": "^27.4.2", - "@jest/transform": "^27.4.5", + "@jest/test-result": "^27.4.6", + "@jest/transform": "^27.4.6", "@jest/types": "^27.4.2", - "@types/yargs": "^16.0.0", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", "execa": "^5.0.0", - "exit": "^0.1.2", "glob": "^7.1.3", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.5", - "jest-message-util": "^27.4.2", - "jest-mock": "^27.4.2", + "jest-haste-map": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-mock": "^27.4.6", "jest-regex-util": "^27.4.0", - "jest-resolve": "^27.4.5", - "jest-snapshot": "^27.4.5", + "jest-resolve": "^27.4.6", + "jest-snapshot": "^27.4.6", "jest-util": "^27.4.2", - "jest-validate": "^27.4.2", "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^16.2.0" + "strip-bom": "^4.0.0" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" @@ -6863,34 +7051,32 @@ } }, "node_modules/jest-snapshot": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.4.5.tgz", - "integrity": "sha512-eCi/iM1YJFrJWiT9de4+RpWWWBqsHiYxFG9V9o/n0WXs6GpW4lUt4FAHAgFPTLPqCUVzrMQmSmTZSgQzwqR7IQ==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.4.6.tgz", + "integrity": "sha512-fafUCDLQfzuNP9IRcEqaFAMzEe7u5BF7mude51wyWv7VRex60WznZIC7DfKTgSIlJa8aFzYmXclmN328aqSDmQ==", "dev": true, "dependencies": { "@babel/core": "^7.7.2", "@babel/generator": "^7.7.2", - "@babel/parser": "^7.7.2", "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.0.0", - "@jest/transform": "^27.4.5", + "@jest/transform": "^27.4.6", "@jest/types": "^27.4.2", "@types/babel__traverse": "^7.0.4", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^27.4.2", + "expect": "^27.4.6", "graceful-fs": "^4.2.4", - "jest-diff": "^27.4.2", + "jest-diff": "^27.4.6", "jest-get-type": "^27.4.0", - "jest-haste-map": "^27.4.5", - "jest-matcher-utils": "^27.4.2", - "jest-message-util": "^27.4.2", - "jest-resolve": "^27.4.5", + "jest-haste-map": "^27.4.6", + "jest-matcher-utils": "^27.4.6", + "jest-message-util": "^27.4.6", "jest-util": "^27.4.2", "natural-compare": "^1.4.0", - "pretty-format": "^27.4.2", + "pretty-format": "^27.4.6", "semver": "^7.3.2" }, "engines": { @@ -7070,9 +7256,9 @@ } }, "node_modules/jest-validate": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.4.2.tgz", - "integrity": "sha512-hWYsSUej+Fs8ZhOm5vhWzwSLmVaPAxRy+Mr+z5MzeaHm9AxUpXdoVMEW4R86y5gOobVfBsMFLk4Rb+QkiEpx1A==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.4.6.tgz", + "integrity": "sha512-872mEmCPVlBqbA5dToC57vA3yJaMRfIdpCoD3cyHWJOMx+SJwLNw0I71EkWs41oza/Er9Zno9XuTkRYCPDUJXQ==", "dev": true, "dependencies": { "@jest/types": "^27.4.2", @@ -7080,7 +7266,7 @@ "chalk": "^4.0.0", "jest-get-type": "^27.4.0", "leven": "^3.1.0", - "pretty-format": "^27.4.2" + "pretty-format": "^27.4.6" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" @@ -7102,9 +7288,9 @@ } }, "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.1.tgz", - "integrity": "sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, "engines": { "node": ">=10" @@ -7169,12 +7355,12 @@ } }, "node_modules/jest-watcher": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.4.2.tgz", - "integrity": "sha512-NJvMVyyBeXfDezhWzUOCOYZrUmkSCiatpjpm+nFUid74OZEHk6aMLrZAukIiFDwdbqp6mTM6Ui1w4oc+8EobQg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.4.6.tgz", + "integrity": "sha512-yKQ20OMBiCDigbD0quhQKLkBO+ObGN79MO4nT7YaCuQ5SM+dkBNWE8cZX0FjU6czwMvWw6StWbe+Wv4jJPJ+fw==", "dev": true, "dependencies": { - "@jest/test-result": "^27.4.2", + "@jest/test-result": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", "ansi-escapes": "^4.2.1", @@ -7257,9 +7443,9 @@ } }, "node_modules/jest-worker": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.5.tgz", - "integrity": "sha512-f2s8kEdy15cv9r7q4KkzGXvlY0JTcmCbMHZBfSQDwW77REr45IDWwd0lksDFeVHH2jJ5pqb90T77XscrjeGzzg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.6.tgz", + "integrity": "sha512-gHWJF/6Xi5CTG5QCvROr6GcmpIqNYpDJyc8A1h/DyXqH1tD6SnRCM0d3U5msV31D2LB/U+E0M+W4oyvKV44oNw==", "dev": true, "dependencies": { "@types/node": "*", @@ -7527,6 +7713,15 @@ "node": ">=10" } }, + "node_modules/magic-string": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", + "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", + "dev": true, + "dependencies": { + "sourcemap-codec": "^1.4.4" + } + }, "node_modules/make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -7551,6 +7746,22 @@ "tmpl": "1.0.5" } }, + "node_modules/matched": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/matched/-/matched-5.0.1.tgz", + "integrity": "sha512-E1fhSTPRyhAlNaNvGXAgZQlq1hL0bgYMTk/6bktVlIhzUnX/SZs7296ACdVeNJE8xFNGSuvd9IpI7vSnmcqLvw==", + "dev": true, + "dependencies": { + "glob": "^7.1.6", + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -8015,12 +8226,11 @@ } }, "node_modules/pretty-format": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.2.tgz", - "integrity": "sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.6.tgz", + "integrity": "sha512-NblstegA1y/RJW2VyML+3LlpFjzx62cUrtBIKIWDXEDkjNeleA7Od7nrzcs/VLQvAeV4CgSYhrN39DRN88Qi/g==", "dev": true, "dependencies": { - "@jest/types": "^27.4.2", "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" @@ -8041,14 +8251,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "engines": { - "node": ">= 0.6.0" - } - }, "node_modules/progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", @@ -8123,6 +8325,15 @@ } ] }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -8319,59 +8530,188 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/rpc-websockets": { - "version": "7.4.16", - "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.4.16.tgz", - "integrity": "sha512-0b7OVhutzwRIaYAtJo5tqtaQTWKfwAsKnaThOSOy+VkhVdleNUgb8eZnWSdWITRZZEigV5uPEIDr5KZe4DBrdQ==", + "node_modules/rollup": { + "version": "2.66.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.66.1.tgz", + "integrity": "sha512-crSgLhSkLMnKr4s9iZ/1qJCplgAgrRY+igWv8KhG/AjKOJ0YX/WpmANyn8oxrw+zenF3BXWDLa7Xl/QZISH+7w==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup-plugin-dts": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-4.1.0.tgz", + "integrity": "sha512-rriXIm3jdUiYeiAAd1Fv+x2AxK6Kq6IybB2Z/IdoAW95fb4uRUurYsEYKa8L1seedezDeJhy8cfo8FEL9aZzqg==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.11.2", - "circular-json": "^0.5.9", - "eventemitter3": "^4.0.7", - "uuid": "^8.3.0", - "ws": "^7.4.5" + "magic-string": "^0.25.7" + }, + "engines": { + "node": ">=v12.22.7" }, "funding": { - "type": "paypal", - "url": "https://paypal.me/kozjak" + "url": "https://github.com/sponsors/Swatinem" }, "optionalDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "@babel/code-frame": "^7.16.0" + }, + "peerDependencies": { + "rollup": "^2.55", + "typescript": "~4.1 || ~4.2 || ~4.3 || ~4.4 || ~4.5" } }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "node_modules/rollup-plugin-inject": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-inject/-/rollup-plugin-inject-3.0.2.tgz", + "integrity": "sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==", + "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject.", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], "dependencies": { - "queue-microtask": "^1.2.2" + "estree-walker": "^0.6.1", + "magic-string": "^0.25.3", + "rollup-pluginutils": "^2.8.1" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { + "node_modules/rollup-plugin-inject/node_modules/estree-walker": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", + "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", + "dev": true + }, + "node_modules/rollup-plugin-node-polyfills": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/rollup-plugin-node-polyfills/-/rollup-plugin-node-polyfills-0.2.1.tgz", + "integrity": "sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==", + "dev": true, + "dependencies": { + "rollup-plugin-inject": "^3.0.0" + } + }, + "node_modules/rollup-plugin-terser": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", + "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "jest-worker": "^26.2.1", + "serialize-javascript": "^4.0.0", + "terser": "^5.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0" + } + }, + "node_modules/rollup-plugin-terser/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/rollup-plugin-terser/node_modules/jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/rollup-plugin-terser/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/rollup-pluginutils": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", + "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", + "dev": true, + "dependencies": { + "estree-walker": "^0.6.1" + } + }, + "node_modules/rollup-pluginutils/node_modules/estree-walker": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", + "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", + "dev": true + }, + "node_modules/rpc-websockets": { + "version": "7.4.16", + "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.4.16.tgz", + "integrity": "sha512-0b7OVhutzwRIaYAtJo5tqtaQTWKfwAsKnaThOSOy+VkhVdleNUgb8eZnWSdWITRZZEigV5uPEIDr5KZe4DBrdQ==", + "dependencies": { + "@babel/runtime": "^7.11.2", + "circular-json": "^0.5.9", + "eventemitter3": "^4.0.7", + "uuid": "^8.3.0", + "ws": "^7.4.5" + }, + "funding": { + "type": "paypal", + "url": "https://paypal.me/kozjak" + }, + "optionalDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { "type": "patreon", "url": "https://www.patreon.com/feross" }, @@ -8422,6 +8762,15 @@ "semver": "bin/semver.js" } }, + "node_modules/serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -8506,6 +8855,12 @@ "node": ">=0.10.0" } }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "dev": true + }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -8720,6 +9075,40 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/terser": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.10.0.tgz", + "integrity": "sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA==", + "dev": true, + "dependencies": { + "commander": "^2.20.0", + "source-map": "~0.7.2", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "acorn": "^8.5.0" + }, + "peerDependenciesMeta": { + "acorn": { + "optional": true + } + } + }, + "node_modules/terser/node_modules/source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -8991,9 +9380,9 @@ "dev": true }, "node_modules/v8-to-istanbul": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz", - "integrity": "sha512-/PRhfd8aTNp9Ggr62HPzXg2XasNFGy5PBt0Rp04du7/8GNNSgxFL6WBTkgMKSL9bFjH+8kKEG3f37FmxiTqUUA==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", + "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.1", @@ -9371,9 +9760,9 @@ } }, "@babel/helper-define-polyfill-provider": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.0.tgz", - "integrity": "sha512-7hfT8lUljl/tM3h+izTX/pO3W3frz2ok6Pk+gzys8iJqDfZrZy2pXjRTZAvG2YmfHun1X4q8/UZRLatMfqc5Tg==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz", + "integrity": "sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA==", "dev": true, "requires": { "@babel/helper-compilation-targets": "^7.13.0", @@ -9443,12 +9832,12 @@ } }, "@babel/helper-module-imports": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.0.tgz", - "integrity": "sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", + "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", "dev": true, "requires": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" } }, "@babel/helper-module-transforms": { @@ -9477,9 +9866,9 @@ } }, "@babel/helper-plugin-utils": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.5.tgz", - "integrity": "sha512-59KHWHXxVA9K4HNF4sbHCf+eJeFe0Te/ZFGqBT4OjXhrwvA04sGfaEGsVTdsjoszq0YTP49RC9UKe5g8uN2RwQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", + "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", "dev": true }, "@babel/helper-remap-async-to-generator": { @@ -9534,9 +9923,9 @@ } }, "@babel/helper-validator-identifier": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", - "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", "dev": true }, "@babel/helper-validator-option": { @@ -10384,12 +10773,12 @@ } }, "@babel/types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.0.tgz", - "integrity": "sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.8.tgz", + "integrity": "sha512-smN2DQc5s4M7fntyjGtyIPbRJv6wW4rU/94fmYJ7PKQuZkC0qGMHXJbg6sNGt12JmVr4k5YaptI/XtiLJBnmIg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.15.7", + "@babel/helper-validator-identifier": "^7.16.7", "to-fast-properties": "^2.0.0" } }, @@ -10520,15 +10909,15 @@ "dev": true }, "@jest/console": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.4.2.tgz", - "integrity": "sha512-xknHThRsPB/To1FUbi6pCe43y58qFC03zfb6R7fDb/FfC7k2R3i1l+izRBJf8DI46KhYGRaF14Eo9A3qbBoixg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.4.6.tgz", + "integrity": "sha512-jauXyacQD33n47A44KrlOVeiXHEXDqapSdfb9kTekOchH/Pd18kBIO1+xxJQRLuG+LUuljFCwTG92ra4NW7SpA==", "dev": true, "requires": { "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^27.4.2", + "jest-message-util": "^27.4.6", "jest-util": "^27.4.2", "slash": "^3.0.0" }, @@ -10585,15 +10974,15 @@ } }, "@jest/core": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.4.5.tgz", - "integrity": "sha512-3tm/Pevmi8bDsgvo73nX8p/WPng6KWlCyScW10FPEoN1HU4pwI83tJ3TsFvi1FfzsjwUlMNEPowgb/rPau/LTQ==", + "version": "27.4.7", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.4.7.tgz", + "integrity": "sha512-n181PurSJkVMS+kClIFSX/LLvw9ExSb+4IMtD6YnfxZVerw9ANYtW0bPrm0MJu2pfe9SY9FJ9FtQ+MdZkrZwjg==", "dev": true, "requires": { - "@jest/console": "^27.4.2", - "@jest/reporters": "^27.4.5", - "@jest/test-result": "^27.4.2", - "@jest/transform": "^27.4.5", + "@jest/console": "^27.4.6", + "@jest/reporters": "^27.4.6", + "@jest/test-result": "^27.4.6", + "@jest/transform": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", "ansi-escapes": "^4.2.1", @@ -10602,18 +10991,18 @@ "exit": "^0.1.2", "graceful-fs": "^4.2.4", "jest-changed-files": "^27.4.2", - "jest-config": "^27.4.5", - "jest-haste-map": "^27.4.5", - "jest-message-util": "^27.4.2", + "jest-config": "^27.4.7", + "jest-haste-map": "^27.4.6", + "jest-message-util": "^27.4.6", "jest-regex-util": "^27.4.0", - "jest-resolve": "^27.4.5", - "jest-resolve-dependencies": "^27.4.5", - "jest-runner": "^27.4.5", - "jest-runtime": "^27.4.5", - "jest-snapshot": "^27.4.5", + "jest-resolve": "^27.4.6", + "jest-resolve-dependencies": "^27.4.6", + "jest-runner": "^27.4.6", + "jest-runtime": "^27.4.6", + "jest-snapshot": "^27.4.6", "jest-util": "^27.4.2", - "jest-validate": "^27.4.2", - "jest-watcher": "^27.4.2", + "jest-validate": "^27.4.6", + "jest-watcher": "^27.4.6", "micromatch": "^4.0.4", "rimraf": "^3.0.0", "slash": "^3.0.0", @@ -10672,52 +11061,52 @@ } }, "@jest/environment": { - "version": "27.4.4", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.4.4.tgz", - "integrity": "sha512-q+niMx7cJgt/t/b6dzLOh4W8Ef/8VyKG7hxASK39jakijJzbFBGpptx3RXz13FFV7OishQ9lTbv+dQ5K3EhfDQ==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.4.6.tgz", + "integrity": "sha512-E6t+RXPfATEEGVidr84WngLNWZ8ffCPky8RqqRK6u1Bn0LK92INe0MDttyPl/JOzaq92BmDzOeuqk09TvM22Sg==", "dev": true, "requires": { - "@jest/fake-timers": "^27.4.2", + "@jest/fake-timers": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", - "jest-mock": "^27.4.2" + "jest-mock": "^27.4.6" } }, "@jest/fake-timers": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.4.2.tgz", - "integrity": "sha512-f/Xpzn5YQk5adtqBgvw1V6bF8Nx3hY0OIRRpCvWcfPl0EAjdqWPdhH3t/3XpiWZqtjIEHDyMKP9ajpva1l4Zmg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.4.6.tgz", + "integrity": "sha512-mfaethuYF8scV8ntPpiVGIHQgS0XIALbpY2jt2l7wb/bvq4Q5pDLk4EP4D7SAvYT1QrPOPVZAtbdGAOOyIgs7A==", "dev": true, "requires": { "@jest/types": "^27.4.2", "@sinonjs/fake-timers": "^8.0.1", "@types/node": "*", - "jest-message-util": "^27.4.2", - "jest-mock": "^27.4.2", + "jest-message-util": "^27.4.6", + "jest-mock": "^27.4.6", "jest-util": "^27.4.2" } }, "@jest/globals": { - "version": "27.4.4", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.4.4.tgz", - "integrity": "sha512-bqpqQhW30BOreXM8bA8t8JbOQzsq/WnPTnBl+It3UxAD9J8yxEAaBEylHx1dtBapAr/UBk8GidXbzmqnee8tYQ==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.4.6.tgz", + "integrity": "sha512-kAiwMGZ7UxrgPzu8Yv9uvWmXXxsy0GciNejlHvfPIfWkSxChzv6bgTS3YqBkGuHcis+ouMFI2696n2t+XYIeFw==", "dev": true, "requires": { - "@jest/environment": "^27.4.4", + "@jest/environment": "^27.4.6", "@jest/types": "^27.4.2", - "expect": "^27.4.2" + "expect": "^27.4.6" } }, "@jest/reporters": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.4.5.tgz", - "integrity": "sha512-3orsG4vi8zXuBqEoy2LbnC1kuvkg1KQUgqNxmxpQgIOQEPeV0onvZu+qDQnEoX8qTQErtqn/xzcnbpeTuOLSiA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.4.6.tgz", + "integrity": "sha512-+Zo9gV81R14+PSq4wzee4GC2mhAN9i9a7qgJWL90Gpx7fHYkWpTBvwWNZUXvJByYR9tAVBdc8VxDWqfJyIUrIQ==", "dev": true, "requires": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.4.2", - "@jest/test-result": "^27.4.2", - "@jest/transform": "^27.4.5", + "@jest/console": "^27.4.6", + "@jest/test-result": "^27.4.6", + "@jest/transform": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", @@ -10726,14 +11115,14 @@ "glob": "^7.1.2", "graceful-fs": "^4.2.4", "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-instrument": "^5.1.0", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "jest-haste-map": "^27.4.5", - "jest-resolve": "^27.4.5", + "istanbul-reports": "^3.1.3", + "jest-haste-map": "^27.4.6", + "jest-resolve": "^27.4.6", "jest-util": "^27.4.2", - "jest-worker": "^27.4.5", + "jest-worker": "^27.4.6", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^4.0.1", @@ -10818,47 +11207,47 @@ } }, "@jest/test-result": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.4.2.tgz", - "integrity": "sha512-kr+bCrra9jfTgxHXHa2UwoQjxvQk3Am6QbpAiJ5x/50LW8llOYrxILkqY0lZRW/hu8FXesnudbql263+EW9iNA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.4.6.tgz", + "integrity": "sha512-fi9IGj3fkOrlMmhQqa/t9xum8jaJOOAi/lZlm6JXSc55rJMXKHxNDN1oCP39B0/DhNOa2OMupF9BcKZnNtXMOQ==", "dev": true, "requires": { - "@jest/console": "^27.4.2", + "@jest/console": "^27.4.6", "@jest/types": "^27.4.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/test-sequencer": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.4.5.tgz", - "integrity": "sha512-n5woIn/1v+FT+9hniymHPARA9upYUmfi5Pw9ewVwXCDlK4F5/Gkees9v8vdjGdAIJ2MPHLHodiajLpZZanWzEQ==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.4.6.tgz", + "integrity": "sha512-3GL+nsf6E1PsyNsJuvPyIz+DwFuCtBdtvPpm/LMXVkBJbdFvQYCDpccYT56qq5BGniXWlE81n2qk1sdXfZebnw==", "dev": true, "requires": { - "@jest/test-result": "^27.4.2", + "@jest/test-result": "^27.4.6", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.5", - "jest-runtime": "^27.4.5" + "jest-haste-map": "^27.4.6", + "jest-runtime": "^27.4.6" } }, "@jest/transform": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.4.5.tgz", - "integrity": "sha512-PuMet2UlZtlGzwc6L+aZmR3I7CEBpqadO03pU40l2RNY2fFJ191b9/ITB44LNOhVtsyykx0OZvj0PCyuLm7Eew==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.4.6.tgz", + "integrity": "sha512-9MsufmJC8t5JTpWEQJ0OcOOAXaH5ioaIX6uHVBLBMoCZPfKKQF+EqP8kACAvCZ0Y1h2Zr3uOccg8re+Dr5jxyw==", "dev": true, "requires": { "@babel/core": "^7.1.0", "@jest/types": "^27.4.2", - "babel-plugin-istanbul": "^6.0.0", + "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.5", + "jest-haste-map": "^27.4.6", "jest-regex-util": "^27.4.0", "jest-util": "^27.4.2", "micromatch": "^4.0.4", - "pirates": "^4.0.1", + "pirates": "^4.0.4", "slash": "^3.0.0", "source-map": "^0.6.1", "write-file-atomic": "^3.0.0" @@ -11020,6 +11409,99 @@ "buffer-layout": "^1.2.0" } }, + "@rollup/plugin-alias": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-3.1.9.tgz", + "integrity": "sha512-QI5fsEvm9bDzt32k39wpOwZhVzRcL5ydcffUHMyLVaVaLeC70I8TJZ17F1z1eMoLu4E/UOcH9BWVkKpIKdrfiw==", + "dev": true, + "requires": { + "slash": "^3.0.0" + } + }, + "@rollup/plugin-commonjs": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-21.0.1.tgz", + "integrity": "sha512-EA+g22lbNJ8p5kuZJUYyhhDK7WgJckW5g4pNN7n4mAFUM96VuwUnNT3xr2Db2iCZPI1pJPbGyfT5mS9T1dHfMg==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.1.0", + "commondir": "^1.0.1", + "estree-walker": "^2.0.1", + "glob": "^7.1.6", + "is-reference": "^1.2.1", + "magic-string": "^0.25.7", + "resolve": "^1.17.0" + }, + "dependencies": { + "estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + } + } + }, + "@rollup/plugin-json": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-4.1.0.tgz", + "integrity": "sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.0.8" + } + }, + "@rollup/plugin-multi-entry": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-multi-entry/-/plugin-multi-entry-4.1.0.tgz", + "integrity": "sha512-nellK5pr50W0JA2+bDJbG8F79GBP802J40YRoC0wyfpTAeAn5mJ4eaFiB/MN+YoX9hgb/6RJoZl9leDjZnUFKw==", + "dev": true, + "requires": { + "@rollup/plugin-virtual": "^2.0.3", + "matched": "^5.0.0" + } + }, + "@rollup/plugin-node-resolve": { + "version": "13.1.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.1.3.tgz", + "integrity": "sha512-BdxNk+LtmElRo5d06MGY4zoepyrXX1tkzX2hrnPEZ53k78GuOMWLqmJDGIIOPwVRIFZrLQOo+Yr6KtCuLIA0AQ==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.1.0", + "@types/resolve": "1.17.1", + "builtin-modules": "^3.1.0", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.19.0" + } + }, + "@rollup/plugin-typescript": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-8.3.0.tgz", + "integrity": "sha512-I5FpSvLbtAdwJ+naznv+B4sjXZUcIvLLceYpITAn7wAP8W0wqc5noLdGIp9HGVntNhRWXctwPYrSSFQxtl0FPA==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.1.0", + "resolve": "^1.17.0" + } + }, + "@rollup/plugin-virtual": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-virtual/-/plugin-virtual-2.0.3.tgz", + "integrity": "sha512-pw6ziJcyjZtntQ//bkad9qXaBx665SgEL8C8KI5wO8G5iU5MPxvdWrQyVaAvjojGm9tJoS8M9Z/EEepbqieYmw==", + "dev": true, + "requires": {} + }, + "@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dev": true, + "requires": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + } + }, "@sinonjs/commons": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", @@ -11174,6 +11656,12 @@ "@types/node": "*" } }, + "@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true + }, "@types/express-serve-static-core": { "version": "4.17.27", "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.27.tgz", @@ -11244,9 +11732,9 @@ "integrity": "sha512-w3mrvNXLeDYV1GKTZorGJQivK6XLCoGwpnyJFbJVK/aTBQUxOCaa/GlFAAN3OTDFcb7h5tiFG+YXCO2By+riZw==" }, "@types/prettier": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.2.tgz", - "integrity": "sha512-ekoj4qOQYp7CvjX8ZDBgN86w3MqQhLE1hczEJbEIjgFEumDy+na/4AJAbLXfgEWFNB2pKadM5rPFtuSGMWK7xA==", + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.3.tgz", + "integrity": "sha512-QzSuZMBuG5u8HqYz01qtMdg/Jfctlnvj1z/lYnIDXs/golxw0fxtRAHd9KrzjR7Yxz1qVeI00o0kiO3PmVdJ9w==", "dev": true }, "@types/qs": { @@ -11259,6 +11747,15 @@ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, + "@types/resolve": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", + "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/stack-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", @@ -11564,15 +12061,15 @@ "dev": true }, "babel-jest": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.4.5.tgz", - "integrity": "sha512-3uuUTjXbgtODmSv/DXO9nZfD52IyC2OYTFaXGRzL0kpykzroaquCrD5+lZNafTvZlnNqZHt5pb0M08qVBZnsnA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.4.6.tgz", + "integrity": "sha512-qZL0JT0HS1L+lOuH+xC2DVASR3nunZi/ozGhpgauJHgmI7f8rudxf6hUjEHympdQ/J64CdKmPkgfJ+A3U6QCrg==", "dev": true, "requires": { - "@jest/transform": "^27.4.5", + "@jest/transform": "^27.4.6", "@jest/types": "^27.4.2", "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.0.0", + "babel-plugin-istanbul": "^6.1.1", "babel-preset-jest": "^27.4.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", @@ -11650,21 +12147,6 @@ "@istanbuljs/schema": "^0.1.2", "istanbul-lib-instrument": "^5.0.4", "test-exclude": "^6.0.0" - }, - "dependencies": { - "istanbul-lib-instrument": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", - "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", - "dev": true, - "requires": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - } - } } }, "babel-plugin-jest-hoist": { @@ -11873,6 +12355,12 @@ "node-gyp-build": "^4.3.0" } }, + "builtin-modules": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", + "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", + "dev": true + }, "call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -11987,6 +12475,12 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -12028,6 +12522,15 @@ } } }, + "cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.1" + } + }, "cross-fetch": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz", @@ -12603,6 +13106,12 @@ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true }, + "estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "dev": true + }, "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -12638,25 +13147,15 @@ "dev": true }, "expect": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.4.2.tgz", - "integrity": "sha512-BjAXIDC6ZOW+WBFNg96J22D27Nq5ohn+oGcuP2rtOtcjuxNoV9McpQ60PcQWhdFOSBIQdR72e+4HdnbZTFSTyg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.4.6.tgz", + "integrity": "sha512-1M/0kAALIaj5LaG66sFJTbRsWTADnylly82cu4bspI0nl+pgP4E6Bh/aqdHlTUjul06K7xQnnrAoqfxVU0+/ag==", "dev": true, "requires": { "@jest/types": "^27.4.2", - "ansi-styles": "^5.0.0", "jest-get-type": "^27.4.0", - "jest-matcher-utils": "^27.4.2", - "jest-message-util": "^27.4.2", - "jest-regex-util": "^27.4.0" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - } + "jest-matcher-utils": "^27.4.6", + "jest-message-util": "^27.4.6" } }, "eyes": { @@ -13034,9 +13533,9 @@ } }, "import-local": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.3.tgz", - "integrity": "sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", "dev": true, "requires": { "pkg-dir": "^4.2.0", @@ -13145,6 +13644,12 @@ "is-extglob": "^2.1.1" } }, + "is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", + "dev": true + }, "is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", @@ -13172,6 +13677,15 @@ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", "dev": true }, + "is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", + "dev": true, + "requires": { + "@types/estree": "*" + } + }, "is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -13246,14 +13760,15 @@ "dev": true }, "istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", + "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", "dev": true, "requires": { - "@babel/core": "^7.7.5", + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-coverage": "^3.2.0", "semver": "^6.3.0" } }, @@ -13344,14 +13859,14 @@ } }, "jest": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.4.5.tgz", - "integrity": "sha512-uT5MiVN3Jppt314kidCk47MYIRilJjA/l2mxwiuzzxGUeJIvA8/pDaJOAX5KWvjAo7SCydcW0/4WEtgbLMiJkg==", + "version": "27.4.7", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.4.7.tgz", + "integrity": "sha512-8heYvsx7nV/m8m24Vk26Y87g73Ba6ueUd0MWed/NXMhSZIm62U/llVbS0PJe1SHunbyXjJ/BqG1z9bFjGUIvTg==", "dev": true, "requires": { - "@jest/core": "^27.4.5", + "@jest/core": "^27.4.7", "import-local": "^3.0.2", - "jest-cli": "^27.4.5" + "jest-cli": "^27.4.7" } }, "jest-changed-files": { @@ -13366,27 +13881,27 @@ } }, "jest-circus": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.4.5.tgz", - "integrity": "sha512-eTNWa9wsvBwPykhMMShheafbwyakcdHZaEYh5iRrQ0PFJxkDP/e3U/FvzGuKWu2WpwUA3C3hPlfpuzvOdTVqnw==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.4.6.tgz", + "integrity": "sha512-UA7AI5HZrW4wRM72Ro80uRR2Fg+7nR0GESbSI/2M+ambbzVuA63mn5T1p3Z/wlhntzGpIG1xx78GP2YIkf6PhQ==", "dev": true, "requires": { - "@jest/environment": "^27.4.4", - "@jest/test-result": "^27.4.2", + "@jest/environment": "^27.4.6", + "@jest/test-result": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", - "expect": "^27.4.2", + "expect": "^27.4.6", "is-generator-fn": "^2.0.0", - "jest-each": "^27.4.2", - "jest-matcher-utils": "^27.4.2", - "jest-message-util": "^27.4.2", - "jest-runtime": "^27.4.5", - "jest-snapshot": "^27.4.5", + "jest-each": "^27.4.6", + "jest-matcher-utils": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-runtime": "^27.4.6", + "jest-snapshot": "^27.4.6", "jest-util": "^27.4.2", - "pretty-format": "^27.4.2", + "pretty-format": "^27.4.6", "slash": "^3.0.0", "stack-utils": "^2.0.3", "throat": "^6.0.1" @@ -13444,21 +13959,21 @@ } }, "jest-cli": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.4.5.tgz", - "integrity": "sha512-hrky3DSgE0u7sQxaCL7bdebEPHx5QzYmrGuUjaPLmPE8jx5adtvGuOlRspvMoVLTTDOHRnZDoRLYJuA+VCI7Hg==", + "version": "27.4.7", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.4.7.tgz", + "integrity": "sha512-zREYhvjjqe1KsGV15mdnxjThKNDgza1fhDT+iUsXWLCq3sxe9w5xnvyctcYVT5PcdLSjv7Y5dCwTS3FCF1tiuw==", "dev": true, "requires": { - "@jest/core": "^27.4.5", - "@jest/test-result": "^27.4.2", + "@jest/core": "^27.4.7", + "@jest/test-result": "^27.4.6", "@jest/types": "^27.4.2", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.4", "import-local": "^3.0.2", - "jest-config": "^27.4.5", + "jest-config": "^27.4.7", "jest-util": "^27.4.2", - "jest-validate": "^27.4.2", + "jest-validate": "^27.4.6", "prompts": "^2.0.1", "yargs": "^16.2.0" }, @@ -13515,32 +14030,32 @@ } }, "jest-config": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.4.5.tgz", - "integrity": "sha512-t+STVJtPt+fpqQ8GBw850NtSQbnDOw/UzdPfzDaHQ48/AylQlW7LHj3dH+ndxhC1UxJ0Q3qkq7IH+nM1skwTwA==", + "version": "27.4.7", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.4.7.tgz", + "integrity": "sha512-xz/o/KJJEedHMrIY9v2ParIoYSrSVY6IVeE4z5Z3i101GoA5XgfbJz+1C8EYPsv7u7f39dS8F9v46BHDhn0vlw==", "dev": true, "requires": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^27.4.5", + "@babel/core": "^7.8.0", + "@jest/test-sequencer": "^27.4.6", "@jest/types": "^27.4.2", - "babel-jest": "^27.4.5", + "babel-jest": "^27.4.6", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.1", "graceful-fs": "^4.2.4", - "jest-circus": "^27.4.5", - "jest-environment-jsdom": "^27.4.4", - "jest-environment-node": "^27.4.4", + "jest-circus": "^27.4.6", + "jest-environment-jsdom": "^27.4.6", + "jest-environment-node": "^27.4.6", "jest-get-type": "^27.4.0", - "jest-jasmine2": "^27.4.5", + "jest-jasmine2": "^27.4.6", "jest-regex-util": "^27.4.0", - "jest-resolve": "^27.4.5", - "jest-runner": "^27.4.5", + "jest-resolve": "^27.4.6", + "jest-runner": "^27.4.6", "jest-util": "^27.4.2", - "jest-validate": "^27.4.2", + "jest-validate": "^27.4.6", "micromatch": "^4.0.4", - "pretty-format": "^27.4.2", + "pretty-format": "^27.4.6", "slash": "^3.0.0" }, "dependencies": { @@ -13596,15 +14111,15 @@ } }, "jest-diff": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.4.2.tgz", - "integrity": "sha512-ujc9ToyUZDh9KcqvQDkk/gkbf6zSaeEg9AiBxtttXW59H/AcqEYp1ciXAtJp+jXWva5nAf/ePtSsgWwE5mqp4Q==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.4.6.tgz", + "integrity": "sha512-zjaB0sh0Lb13VyPsd92V7HkqF6yKRH9vm33rwBt7rPYrpQvS1nCvlIy2pICbKta+ZjWngYLNn4cCK4nyZkjS/w==", "dev": true, "requires": { "chalk": "^4.0.0", "diff-sequences": "^27.4.0", "jest-get-type": "^27.4.0", - "pretty-format": "^27.4.2" + "pretty-format": "^27.4.6" }, "dependencies": { "ansi-styles": { @@ -13668,16 +14183,16 @@ } }, "jest-each": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.4.2.tgz", - "integrity": "sha512-53V2MNyW28CTruB3lXaHNk6PkiIFuzdOC9gR3C6j8YE/ACfrPnz+slB0s17AgU1TtxNzLuHyvNlLJ+8QYw9nBg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.4.6.tgz", + "integrity": "sha512-n6QDq8y2Hsmn22tRkgAk+z6MCX7MeVlAzxmZDshfS2jLcaBlyhpF3tZSJLR+kXmh23GEvS0ojMR8i6ZeRvpQcA==", "dev": true, "requires": { "@jest/types": "^27.4.2", "chalk": "^4.0.0", "jest-get-type": "^27.4.0", "jest-util": "^27.4.2", - "pretty-format": "^27.4.2" + "pretty-format": "^27.4.6" }, "dependencies": { "ansi-styles": { @@ -13732,31 +14247,31 @@ } }, "jest-environment-jsdom": { - "version": "27.4.4", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.4.4.tgz", - "integrity": "sha512-cYR3ndNfHBqQgFvS1RL7dNqSvD//K56j/q1s2ygNHcfTCAp12zfIromO1w3COmXrxS8hWAh7+CmZmGCIoqGcGA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.4.6.tgz", + "integrity": "sha512-o3dx5p/kHPbUlRvSNjypEcEtgs6LmvESMzgRFQE6c+Prwl2JLA4RZ7qAnxc5VM8kutsGRTB15jXeeSbJsKN9iA==", "dev": true, "requires": { - "@jest/environment": "^27.4.4", - "@jest/fake-timers": "^27.4.2", + "@jest/environment": "^27.4.6", + "@jest/fake-timers": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", - "jest-mock": "^27.4.2", + "jest-mock": "^27.4.6", "jest-util": "^27.4.2", "jsdom": "^16.6.0" } }, "jest-environment-node": { - "version": "27.4.4", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.4.4.tgz", - "integrity": "sha512-D+v3lbJ2GjQTQR23TK0kY3vFVmSeea05giInI41HHOaJnAwOnmUHTZgUaZL+VxUB43pIzoa7PMwWtCVlIUoVoA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.4.6.tgz", + "integrity": "sha512-yfHlZ9m+kzTKZV0hVfhVu6GuDxKAYeFHrfulmy7Jxwsq4V7+ZK7f+c0XP/tbVDMQW7E4neG2u147hFkuVz0MlQ==", "dev": true, "requires": { - "@jest/environment": "^27.4.4", - "@jest/fake-timers": "^27.4.2", + "@jest/environment": "^27.4.6", + "@jest/fake-timers": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", - "jest-mock": "^27.4.2", + "jest-mock": "^27.4.6", "jest-util": "^27.4.2" } }, @@ -13767,9 +14282,9 @@ "dev": true }, "jest-haste-map": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.4.5.tgz", - "integrity": "sha512-oJm1b5qhhPs78K24EDGifWS0dELYxnoBiDhatT/FThgB9yxqUm5F6li3Pv+Q+apMBmmPNzOBnZ7ZxWMB1Leq1Q==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.4.6.tgz", + "integrity": "sha512-0tNpgxg7BKurZeFkIOvGCkbmOHbLFf4LUQOxrQSMjvrQaQe3l6E8x6jYC1NuWkGo5WDdbr8FEzUxV2+LWNawKQ==", "dev": true, "requires": { "@jest/types": "^27.4.2", @@ -13782,34 +14297,33 @@ "jest-regex-util": "^27.4.0", "jest-serializer": "^27.4.0", "jest-util": "^27.4.2", - "jest-worker": "^27.4.5", + "jest-worker": "^27.4.6", "micromatch": "^4.0.4", "walker": "^1.0.7" } }, "jest-jasmine2": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.4.5.tgz", - "integrity": "sha512-oUnvwhJDj2LhOiUB1kdnJjkx8C5PwgUZQb9urF77mELH9DGR4e2GqpWQKBOYXWs5+uTN9BGDqRz3Aeg5Wts7aw==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.4.6.tgz", + "integrity": "sha512-uAGNXF644I/whzhsf7/qf74gqy9OuhvJ0XYp8SDecX2ooGeaPnmJMjXjKt0mqh1Rl5dtRGxJgNrHlBQIBfS5Nw==", "dev": true, "requires": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^27.4.4", + "@jest/environment": "^27.4.6", "@jest/source-map": "^27.4.0", - "@jest/test-result": "^27.4.2", + "@jest/test-result": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "expect": "^27.4.2", + "expect": "^27.4.6", "is-generator-fn": "^2.0.0", - "jest-each": "^27.4.2", - "jest-matcher-utils": "^27.4.2", - "jest-message-util": "^27.4.2", - "jest-runtime": "^27.4.5", - "jest-snapshot": "^27.4.5", + "jest-each": "^27.4.6", + "jest-matcher-utils": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-runtime": "^27.4.6", + "jest-snapshot": "^27.4.6", "jest-util": "^27.4.2", - "pretty-format": "^27.4.2", + "pretty-format": "^27.4.6", "throat": "^6.0.1" }, "dependencies": { @@ -13865,25 +14379,25 @@ } }, "jest-leak-detector": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.4.2.tgz", - "integrity": "sha512-ml0KvFYZllzPBJWDei3mDzUhyp/M4ubKebX++fPaudpe8OsxUE+m+P6ciVLboQsrzOCWDjE20/eXew9QMx/VGw==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.4.6.tgz", + "integrity": "sha512-kkaGixDf9R7CjHm2pOzfTxZTQQQ2gHTIWKY/JZSiYTc90bZp8kSZnUMS3uLAfwTZwc0tcMRoEX74e14LG1WapA==", "dev": true, "requires": { "jest-get-type": "^27.4.0", - "pretty-format": "^27.4.2" + "pretty-format": "^27.4.6" } }, "jest-matcher-utils": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.4.2.tgz", - "integrity": "sha512-jyP28er3RRtMv+fmYC/PKG8wvAmfGcSNproVTW2Y0P/OY7/hWUOmsPfxN1jOhM+0u2xU984u2yEagGivz9OBGQ==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.4.6.tgz", + "integrity": "sha512-XD4PKT3Wn1LQnRAq7ZsTI0VRuEc9OrCPFiO1XL7bftTGmfNF0DcEwMHRgqiu7NGf8ZoZDREpGrCniDkjt79WbA==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^27.4.2", + "jest-diff": "^27.4.6", "jest-get-type": "^27.4.0", - "pretty-format": "^27.4.2" + "pretty-format": "^27.4.6" }, "dependencies": { "ansi-styles": { @@ -13938,9 +14452,9 @@ } }, "jest-message-util": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.4.2.tgz", - "integrity": "sha512-OMRqRNd9E0DkBLZpFtZkAGYOXl6ZpoMtQJWTAREJKDOFa0M6ptB7L67tp+cszMBkvSgKOhNtQp2Vbcz3ZZKo/w==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.4.6.tgz", + "integrity": "sha512-0p5szriFU0U74czRSFjH6RyS7UYIAkn/ntwMuOwTGWrQIOh5NzXXrq72LOqIkJKKvFbPq+byZKuBz78fjBERBA==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", @@ -13949,7 +14463,7 @@ "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.4", - "pretty-format": "^27.4.2", + "pretty-format": "^27.4.6", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -14006,9 +14520,9 @@ } }, "jest-mock": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.4.2.tgz", - "integrity": "sha512-PDDPuyhoukk20JrQKeofK12hqtSka7mWH0QQuxSNgrdiPsrnYYLS6wbzu/HDlxZRzji5ylLRULeuI/vmZZDrYA==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.4.6.tgz", + "integrity": "sha512-kvojdYRkst8iVSZ1EJ+vc1RRD9llueBjKzXzeCytH3dMM7zvPV/ULcfI2nr0v0VUgm3Bjt3hBCQvOeaBz+ZTHw==", "dev": true, "requires": { "@jest/types": "^27.4.2", @@ -14029,18 +14543,18 @@ "dev": true }, "jest-resolve": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.4.5.tgz", - "integrity": "sha512-xU3z1BuOz/hUhVUL+918KqUgK+skqOuUsAi7A+iwoUldK6/+PW+utK8l8cxIWT9AW7IAhGNXjSAh1UYmjULZZw==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.4.6.tgz", + "integrity": "sha512-SFfITVApqtirbITKFAO7jOVN45UgFzcRdQanOFzjnbd+CACDoyeX7206JyU92l4cRr73+Qy/TlW51+4vHGt+zw==", "dev": true, "requires": { "@jest/types": "^27.4.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.5", + "jest-haste-map": "^27.4.6", "jest-pnp-resolver": "^1.2.2", "jest-util": "^27.4.2", - "jest-validate": "^27.4.2", + "jest-validate": "^27.4.6", "resolve": "^1.20.0", "resolve.exports": "^1.1.0", "slash": "^3.0.0" @@ -14098,26 +14612,26 @@ } }, "jest-resolve-dependencies": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.4.5.tgz", - "integrity": "sha512-elEVvkvRK51y037NshtEkEnukMBWvlPzZHiL847OrIljJ8yIsujD2GXRPqDXC4rEVKbcdsy7W0FxoZb4WmEs7w==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.4.6.tgz", + "integrity": "sha512-W85uJZcFXEVZ7+MZqIPCscdjuctruNGXUZ3OHSXOfXR9ITgbUKeHj+uGcies+0SsvI5GtUfTw4dY7u9qjTvQOw==", "dev": true, "requires": { "@jest/types": "^27.4.2", "jest-regex-util": "^27.4.0", - "jest-snapshot": "^27.4.5" + "jest-snapshot": "^27.4.6" } }, "jest-runner": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.4.5.tgz", - "integrity": "sha512-/irauncTfmY1WkTaRQGRWcyQLzK1g98GYG/8QvIPviHgO1Fqz1JYeEIsSfF+9mc/UTA6S+IIHFgKyvUrtiBIZg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.4.6.tgz", + "integrity": "sha512-IDeFt2SG4DzqalYBZRgbbPmpwV3X0DcntjezPBERvnhwKGWTW7C5pbbA5lVkmvgteeNfdd/23gwqv3aiilpYPg==", "dev": true, "requires": { - "@jest/console": "^27.4.2", - "@jest/environment": "^27.4.4", - "@jest/test-result": "^27.4.2", - "@jest/transform": "^27.4.5", + "@jest/console": "^27.4.6", + "@jest/environment": "^27.4.6", + "@jest/test-result": "^27.4.6", + "@jest/transform": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", "chalk": "^4.0.0", @@ -14125,15 +14639,15 @@ "exit": "^0.1.2", "graceful-fs": "^4.2.4", "jest-docblock": "^27.4.0", - "jest-environment-jsdom": "^27.4.4", - "jest-environment-node": "^27.4.4", - "jest-haste-map": "^27.4.5", - "jest-leak-detector": "^27.4.2", - "jest-message-util": "^27.4.2", - "jest-resolve": "^27.4.5", - "jest-runtime": "^27.4.5", + "jest-environment-jsdom": "^27.4.6", + "jest-environment-node": "^27.4.6", + "jest-haste-map": "^27.4.6", + "jest-leak-detector": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-resolve": "^27.4.6", + "jest-runtime": "^27.4.6", "jest-util": "^27.4.2", - "jest-worker": "^27.4.5", + "jest-worker": "^27.4.6", "source-map-support": "^0.5.6", "throat": "^6.0.1" }, @@ -14190,37 +14704,33 @@ } }, "jest-runtime": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.4.5.tgz", - "integrity": "sha512-CIYqwuJQXHQtPd/idgrx4zgJ6iCb6uBjQq1RSAGQrw2S8XifDmoM1Ot8NRd80ooAm+ZNdHVwsktIMGlA1F1FAQ==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.4.6.tgz", + "integrity": "sha512-eXYeoR/MbIpVDrjqy5d6cGCFOYBFFDeKaNWqTp0h6E74dK0zLHzASQXJpl5a2/40euBmKnprNLJ0Kh0LCndnWQ==", "dev": true, "requires": { - "@jest/console": "^27.4.2", - "@jest/environment": "^27.4.4", - "@jest/globals": "^27.4.4", + "@jest/environment": "^27.4.6", + "@jest/fake-timers": "^27.4.6", + "@jest/globals": "^27.4.6", "@jest/source-map": "^27.4.0", - "@jest/test-result": "^27.4.2", - "@jest/transform": "^27.4.5", + "@jest/test-result": "^27.4.6", + "@jest/transform": "^27.4.6", "@jest/types": "^27.4.2", - "@types/yargs": "^16.0.0", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", "execa": "^5.0.0", - "exit": "^0.1.2", "glob": "^7.1.3", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.5", - "jest-message-util": "^27.4.2", - "jest-mock": "^27.4.2", + "jest-haste-map": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-mock": "^27.4.6", "jest-regex-util": "^27.4.0", - "jest-resolve": "^27.4.5", - "jest-snapshot": "^27.4.5", + "jest-resolve": "^27.4.6", + "jest-snapshot": "^27.4.6", "jest-util": "^27.4.2", - "jest-validate": "^27.4.2", "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^16.2.0" + "strip-bom": "^4.0.0" }, "dependencies": { "ansi-styles": { @@ -14285,34 +14795,32 @@ } }, "jest-snapshot": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.4.5.tgz", - "integrity": "sha512-eCi/iM1YJFrJWiT9de4+RpWWWBqsHiYxFG9V9o/n0WXs6GpW4lUt4FAHAgFPTLPqCUVzrMQmSmTZSgQzwqR7IQ==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.4.6.tgz", + "integrity": "sha512-fafUCDLQfzuNP9IRcEqaFAMzEe7u5BF7mude51wyWv7VRex60WznZIC7DfKTgSIlJa8aFzYmXclmN328aqSDmQ==", "dev": true, "requires": { "@babel/core": "^7.7.2", "@babel/generator": "^7.7.2", - "@babel/parser": "^7.7.2", "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.0.0", - "@jest/transform": "^27.4.5", + "@jest/transform": "^27.4.6", "@jest/types": "^27.4.2", "@types/babel__traverse": "^7.0.4", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^27.4.2", + "expect": "^27.4.6", "graceful-fs": "^4.2.4", - "jest-diff": "^27.4.2", + "jest-diff": "^27.4.6", "jest-get-type": "^27.4.0", - "jest-haste-map": "^27.4.5", - "jest-matcher-utils": "^27.4.2", - "jest-message-util": "^27.4.2", - "jest-resolve": "^27.4.5", + "jest-haste-map": "^27.4.6", + "jest-matcher-utils": "^27.4.6", + "jest-message-util": "^27.4.6", "jest-util": "^27.4.2", "natural-compare": "^1.4.0", - "pretty-format": "^27.4.2", + "pretty-format": "^27.4.6", "semver": "^7.3.2" }, "dependencies": { @@ -14442,9 +14950,9 @@ } }, "jest-validate": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.4.2.tgz", - "integrity": "sha512-hWYsSUej+Fs8ZhOm5vhWzwSLmVaPAxRy+Mr+z5MzeaHm9AxUpXdoVMEW4R86y5gOobVfBsMFLk4Rb+QkiEpx1A==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.4.6.tgz", + "integrity": "sha512-872mEmCPVlBqbA5dToC57vA3yJaMRfIdpCoD3cyHWJOMx+SJwLNw0I71EkWs41oza/Er9Zno9XuTkRYCPDUJXQ==", "dev": true, "requires": { "@jest/types": "^27.4.2", @@ -14452,7 +14960,7 @@ "chalk": "^4.0.0", "jest-get-type": "^27.4.0", "leven": "^3.1.0", - "pretty-format": "^27.4.2" + "pretty-format": "^27.4.6" }, "dependencies": { "ansi-styles": { @@ -14465,9 +14973,9 @@ } }, "camelcase": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.1.tgz", - "integrity": "sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true }, "chalk": { @@ -14513,12 +15021,12 @@ } }, "jest-watcher": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.4.2.tgz", - "integrity": "sha512-NJvMVyyBeXfDezhWzUOCOYZrUmkSCiatpjpm+nFUid74OZEHk6aMLrZAukIiFDwdbqp6mTM6Ui1w4oc+8EobQg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.4.6.tgz", + "integrity": "sha512-yKQ20OMBiCDigbD0quhQKLkBO+ObGN79MO4nT7YaCuQ5SM+dkBNWE8cZX0FjU6czwMvWw6StWbe+Wv4jJPJ+fw==", "dev": true, "requires": { - "@jest/test-result": "^27.4.2", + "@jest/test-result": "^27.4.6", "@jest/types": "^27.4.2", "@types/node": "*", "ansi-escapes": "^4.2.1", @@ -14579,9 +15087,9 @@ } }, "jest-worker": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.5.tgz", - "integrity": "sha512-f2s8kEdy15cv9r7q4KkzGXvlY0JTcmCbMHZBfSQDwW77REr45IDWwd0lksDFeVHH2jJ5pqb90T77XscrjeGzzg==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.6.tgz", + "integrity": "sha512-gHWJF/6Xi5CTG5QCvROr6GcmpIqNYpDJyc8A1h/DyXqH1tD6SnRCM0d3U5msV31D2LB/U+E0M+W4oyvKV44oNw==", "dev": true, "requires": { "@types/node": "*", @@ -14783,6 +15291,15 @@ "yallist": "^4.0.0" } }, + "magic-string": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", + "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", + "dev": true, + "requires": { + "sourcemap-codec": "^1.4.4" + } + }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -14801,6 +15318,16 @@ "tmpl": "1.0.5" } }, + "matched": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/matched/-/matched-5.0.1.tgz", + "integrity": "sha512-E1fhSTPRyhAlNaNvGXAgZQlq1hL0bgYMTk/6bktVlIhzUnX/SZs7296ACdVeNJE8xFNGSuvd9IpI7vSnmcqLvw==", + "dev": true, + "requires": { + "glob": "^7.1.6", + "picomatch": "^2.2.1" + } + }, "merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -15143,12 +15670,11 @@ "dev": true }, "pretty-format": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.2.tgz", - "integrity": "sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw==", + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.6.tgz", + "integrity": "sha512-NblstegA1y/RJW2VyML+3LlpFjzx62cUrtBIKIWDXEDkjNeleA7Od7nrzcs/VLQvAeV4CgSYhrN39DRN88Qi/g==", "dev": true, "requires": { - "@jest/types": "^27.4.2", "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" @@ -15162,11 +15688,6 @@ } } }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" - }, "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", @@ -15220,6 +15741,15 @@ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, "react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -15368,6 +15898,110 @@ "glob": "^7.1.3" } }, + "rollup": { + "version": "2.66.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.66.1.tgz", + "integrity": "sha512-crSgLhSkLMnKr4s9iZ/1qJCplgAgrRY+igWv8KhG/AjKOJ0YX/WpmANyn8oxrw+zenF3BXWDLa7Xl/QZISH+7w==", + "dev": true, + "requires": { + "fsevents": "~2.3.2" + } + }, + "rollup-plugin-dts": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-4.1.0.tgz", + "integrity": "sha512-rriXIm3jdUiYeiAAd1Fv+x2AxK6Kq6IybB2Z/IdoAW95fb4uRUurYsEYKa8L1seedezDeJhy8cfo8FEL9aZzqg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.0", + "magic-string": "^0.25.7" + } + }, + "rollup-plugin-inject": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-inject/-/rollup-plugin-inject-3.0.2.tgz", + "integrity": "sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==", + "dev": true, + "requires": { + "estree-walker": "^0.6.1", + "magic-string": "^0.25.3", + "rollup-pluginutils": "^2.8.1" + }, + "dependencies": { + "estree-walker": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", + "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", + "dev": true + } + } + }, + "rollup-plugin-node-polyfills": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/rollup-plugin-node-polyfills/-/rollup-plugin-node-polyfills-0.2.1.tgz", + "integrity": "sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==", + "dev": true, + "requires": { + "rollup-plugin-inject": "^3.0.0" + } + }, + "rollup-plugin-terser": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", + "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "jest-worker": "^26.2.1", + "serialize-javascript": "^4.0.0", + "terser": "^5.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "rollup-pluginutils": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", + "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", + "dev": true, + "requires": { + "estree-walker": "^0.6.1" + }, + "dependencies": { + "estree-walker": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", + "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", + "dev": true + } + } + }, "rpc-websockets": { "version": "7.4.16", "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.4.16.tgz", @@ -15427,6 +16061,15 @@ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, + "serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -15495,6 +16138,12 @@ } } }, + "sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "dev": true + }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -15659,6 +16308,25 @@ "supports-hyperlinks": "^2.0.0" } }, + "terser": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.10.0.tgz", + "integrity": "sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.7.2", + "source-map-support": "~0.5.20" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } + } + }, "test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -15865,9 +16533,9 @@ "dev": true }, "v8-to-istanbul": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz", - "integrity": "sha512-/PRhfd8aTNp9Ggr62HPzXg2XasNFGy5PBt0Rp04du7/8GNNSgxFL6WBTkgMKSL9bFjH+8kKEG3f37FmxiTqUUA==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", + "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.1", diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index f69a5ffb..3b7c5ac6 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -3,20 +3,22 @@ "version": "0.6.3", "description": "SPL Stake Pool Program JS API", "scripts": { - "build": "tsc", + "build": "npm run clean; tsc; cross-env NODE_ENV=production rollup -c", "lint": "npm run pretty && eslint .", "lint:fix": "npm run pretty:fix && eslint . --fix", "pretty": "prettier --check '{,src/**/,test/**/}*.ts'", "pretty:fix": "prettier -w '{,src/**/,test/**/}*.ts'", "test": "jest", "test:watch": "jest --watch", - "test:cov": "jest --coverage" + "test:cov": "jest --coverage", + "clean": "rimraf ./dist ./dist.browser" }, "keywords": [], - "authors": [ + "contributors": [ "Solana Maintainers ", "Lieu Zheng Hong", - "mFactory Team (https://mfactory.ch)" + "mFactory Team (https://mfactory.ch/)", + "SolBlaze (https://solblaze.org/)" ], "homepage": "https://solana.com", "repository": { @@ -26,10 +28,16 @@ "publishConfig": { "access": "public" }, + "browser": "dist.browser/index.js", "main": "dist/index.js", "types": "dist/index.d.ts", + "browserslist": [ + "defaults", + "not IE 11" + ], "files": [ - "/dist" + "/dist", + "/dist.browser" ], "license": "ISC", "dependencies": { @@ -38,20 +46,33 @@ "@solana/spl-token": "^0.1.8", "@solana/web3.js": "^1.30.2", "bn.js": "^5.2.0", - "buffer": "^6.0.3", - "process": "^0.11.10" + "buffer": "^6.0.3" }, "devDependencies": { + "@babel/core": "^7.16.5", "@babel/preset-env": "^7.16.5", "@babel/preset-typescript": "^7.16.5", + "@rollup/plugin-alias": "^3.1.9", + "@rollup/plugin-commonjs": "^21.0.1", + "@rollup/plugin-json": "^4.1.0", + "@rollup/plugin-multi-entry": "^4.1.0", + "@rollup/plugin-node-resolve": "^13.1.3", + "@rollup/plugin-typescript": "^8.3.0", "@types/bn.js": "^5.1.0", "@types/jest": "^27.0.3", "@typescript-eslint/eslint-plugin": "^5.8.1", "@typescript-eslint/parser": "^5.8.1", + "babel-jest": "^27.4.6", + "cross-env": "^7.0.3", "eslint": "^8.5.0", "eslint-plugin-react": "^7.28.0", - "jest": "^27.3.1", + "jest": "^27.4.7", "prettier": "^2.2.1", + "rimraf": "^3.0.2", + "rollup": "^2.66.1", + "rollup-plugin-dts": "^4.1.0", + "rollup-plugin-node-polyfills": "^0.2.1", + "rollup-plugin-terser": "^7.0.2", "typescript": "^4.5.4" }, "jest": { diff --git a/clients/js-legacy/rollup.config.js b/clients/js-legacy/rollup.config.js new file mode 100644 index 00000000..680ba5d7 --- /dev/null +++ b/clients/js-legacy/rollup.config.js @@ -0,0 +1,125 @@ +import typescript from '@rollup/plugin-typescript'; +import commonjs from '@rollup/plugin-commonjs'; +import json from '@rollup/plugin-json'; +import nodeResolve from '@rollup/plugin-node-resolve'; +import {terser} from 'rollup-plugin-terser'; + +const extensions = ['.js', '.ts']; + +function generateConfig(configType, format) { + const browser = configType === 'browser'; + + const config = { + input: 'src/index.ts', + plugins: [ + commonjs(), + nodeResolve({ + browser, + dedupe: ['bn.js', 'buffer'], + extensions, + preferBuiltins: !browser, + }), + typescript(), + ], + onwarn: function (warning, rollupWarn) { + if (warning.code !== 'CIRCULAR_DEPENDENCY') { + rollupWarn(warning); + } + }, + treeshake: { + moduleSideEffects: false, + }, + }; + + if (configType !== 'browser') { + // Prevent dependencies from being bundled + config.external = [ + '@project-serum/borsh', + '@solana/buffer-layout', + '@solana/spl-token', + '@solana/web3.js', + 'bn.js', + 'buffer' + ]; + } + + switch (configType) { + case 'browser': + switch (format) { + case 'esm': { + config.output = [ + { + file: 'dist.browser/index.browser.esm.js', + format: 'es', + sourcemap: true, + }, + ]; + + // Prevent dependencies from being bundled + config.external = [ + '@project-serum/borsh', + '@solana/buffer-layout', + '@solana/spl-token', + '@solana/web3.js', + 'bn.js', + 'buffer' + ]; + + break; + } + case 'iife': { + config.external = ['http', 'https']; + + config.output = [ + { + file: 'dist.browser/index.iife.js', + format: 'iife', + name: 'solanaStakePool', + sourcemap: true, + }, + { + file: 'dist.browser/index.iife.min.js', + format: 'iife', + name: 'solanaStakePool', + sourcemap: true, + plugins: [terser({mangle: false, compress: false})], + }, + ]; + + break; + } + default: + throw new Error(`Unknown format: ${format}`); + } + + // TODO: Find a workaround to avoid resolving the following JSON file: + // `node_modules/secp256k1/node_modules/elliptic/package.json` + config.plugins.push(json()); + + break; + case 'node': + config.output = [ + { + file: 'dist.browser/index.cjs.js', + format: 'cjs', + sourcemap: true, + }, + { + file: 'dist.browser/index.esm.js', + format: 'es', + sourcemap: true, + }, + ]; + break; + default: + throw new Error(`Unknown configType: ${configType}`); + } + + return config; +} + +export default [ + generateConfig('node'), + generateConfig('browser', 'esm'), + generateConfig('browser', 'iife'), +]; diff --git a/clients/js-legacy/tsconfig.json b/clients/js-legacy/tsconfig.json index 59a6767e..eb622f76 100644 --- a/clients/js-legacy/tsconfig.json +++ b/clients/js-legacy/tsconfig.json @@ -9,7 +9,7 @@ "allowSyntheticDefaultImports": true, "strict": true, "forceConsistentCasingInFileNames": true, - "module": "commonjs", + "module": "esnext", "moduleResolution": "node", "resolveJsonModule": true, "isolatedModules": true, From 6912a7b37adba5f0113f1f9905809780a6d5bcd8 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Sat, 29 Jan 2022 00:39:28 +0100 Subject: [PATCH 0227/1076] stake-pool-js: Bump version for release (#2832) --- clients/js-legacy/package-lock.json | 4 ++-- clients/js-legacy/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index e5693aca..443c309e 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1,12 +1,12 @@ { "name": "@solana/spl-stake-pool", - "version": "0.6.3", + "version": "0.6.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@solana/spl-stake-pool", - "version": "0.6.3", + "version": "0.6.4", "license": "ISC", "dependencies": { "@project-serum/borsh": "^0.2.2", diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 3b7c5ac6..13839f1c 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-stake-pool", - "version": "0.6.3", + "version": "0.6.4", "description": "SPL Stake Pool Program JS API", "scripts": { "build": "npm run clean; tsc; cross-env NODE_ENV=production rollup -c", From 8af8d4bbc8e9e8b7ceff1b2758cbe9abc4e18d38 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Mon, 31 Jan 2022 20:15:28 +0100 Subject: [PATCH 0228/1076] stake-pool-cli: Fix mismatched output fields (#2846) --- clients/cli/src/output.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/src/output.rs b/clients/cli/src/output.rs index 81ddbd8d..2a9f0577 100644 --- a/clients/cli/src/output.rs +++ b/clients/cli/src/output.rs @@ -483,9 +483,9 @@ impl From<(Pubkey, StakePool, ValidatorList, Pubkey)> for CliStakePool { .map(CliStakePoolFee::from), stake_referral_fee: stake_pool.stake_referral_fee, sol_deposit_authority: stake_pool.sol_deposit_authority.map(|x| x.to_string()), - sol_deposit_fee: CliStakePoolFee::from(stake_pool.stake_deposit_fee), + sol_deposit_fee: CliStakePoolFee::from(stake_pool.sol_deposit_fee), sol_referral_fee: stake_pool.sol_referral_fee, - sol_withdraw_authority: stake_pool.sol_deposit_authority.map(|x| x.to_string()), + sol_withdraw_authority: stake_pool.sol_withdraw_authority.map(|x| x.to_string()), sol_withdrawal_fee: CliStakePoolFee::from(stake_pool.sol_withdrawal_fee), next_sol_withdrawal_fee: stake_pool .next_sol_withdrawal_fee From 64d57705baf213470d6cb287ca702c0da7c7bed5 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Mon, 7 Feb 2022 22:26:23 +0100 Subject: [PATCH 0229/1076] stake-pool-py: Add more waits to solidify tests (#2882) --- clients/py/stake/state.py | 74 ++++++++++++++++++- clients/py/tests/conftest.py | 18 ++--- .../py/tests/test_deposit_withdraw_stake.py | 19 ++--- 3 files changed, 92 insertions(+), 19 deletions(-) diff --git a/clients/py/stake/state.py b/clients/py/stake/state.py index 38932e8d..4911de76 100644 --- a/clients/py/stake/state.py +++ b/clients/py/stake/state.py @@ -2,9 +2,10 @@ from enum import IntEnum from typing import NamedTuple, Dict -from construct import Container, Struct, Int64ul # type: ignore +from construct import Container, Struct, Float64l, Int32ul, Int64ul # type: ignore from solana.publickey import PublicKey +from solana.utils.helpers import decode_byte_string from solana._layouts.shared import PUBLIC_KEY_LAYOUT @@ -46,6 +47,29 @@ class StakeAuthorize(IntEnum): WITHDRAWER = 1 +class StakeStateType(IntEnum): + """Stake State Types.""" + UNINITIALIZED = 0 + INITIALIZED = 1 + STAKE = 2 + REWARDS_POOL = 3 + + +class StakeState(NamedTuple): + state_type: StakeStateType + state: Container + + """Stake state.""" + @classmethod + def decode(cls, data: str, encoding: str): + data_bytes = decode_byte_string(data, encoding) + parsed = STAKE_STATE_LAYOUT.parse(data_bytes) + return StakeState( + state_type=parsed['state_type'], + state=parsed['state'], + ) + + LOCKUP_LAYOUT = Struct( "unix_timestamp" / Int64ul, "epoch" / Int64ul, @@ -57,3 +81,51 @@ class StakeAuthorize(IntEnum): "staker" / PUBLIC_KEY_LAYOUT, "withdrawer" / PUBLIC_KEY_LAYOUT, ) + +META_LAYOUT = Struct( + "rent_exempt_reserve" / Int64ul, + "authorized" / AUTHORIZED_LAYOUT, + "lockup" / LOCKUP_LAYOUT, +) + +META_LAYOUT = Struct( + "rent_exempt_reserve" / Int64ul, + "authorized" / AUTHORIZED_LAYOUT, + "lockup" / LOCKUP_LAYOUT, +) + +DELEGATION_LAYOUT = Struct( + "voter_pubkey" / PUBLIC_KEY_LAYOUT, + "stake" / Int64ul, + "activation_epoch" / Int64ul, + "deactivation_epoch" / Int64ul, + "warmup_cooldown_rate" / Float64l, +) + +STAKE_LAYOUT = Struct( + "delegation" / DELEGATION_LAYOUT, + "credits_observed" / Int64ul, +) + +STAKE_AND_META_LAYOUT = Struct( + "meta" / META_LAYOUT, + "stake" / STAKE_LAYOUT, +) + +STAKE_STATE_LAYOUT = Struct( + "state_type" / Int32ul, + "state" / STAKE_AND_META_LAYOUT, + # NOTE: This can be done better, but was mainly needed for testing. Ideally, + # we would have something like: + # + # Switch( + # lambda this: this.state, + # { + # StakeStateType.UNINITIALIZED: Pass, + # StakeStateType.INITIALIZED: META_LAYOUT, + # StakeStateType.STAKE: STAKE_AND_META_LAYOUT, + # } + # ), + # + # Unfortunately, it didn't work. +) diff --git a/clients/py/tests/conftest.py b/clients/py/tests/conftest.py index 60a263fa..b55be25b 100644 --- a/clients/py/tests/conftest.py +++ b/clients/py/tests/conftest.py @@ -42,28 +42,28 @@ def solana_test_validator(): def validators(event_loop, async_client, payer) -> List[PublicKey]: num_validators = 3 validators = [] - futures = [] for i in range(num_validators): vote = Keypair() node = Keypair() - futures.append(create_vote(async_client, payer, vote, node, payer.public_key, payer.public_key, 10)) + event_loop.run_until_complete( + create_vote(async_client, payer, vote, node, payer.public_key, payer.public_key, 10) + ) validators.append(vote.public_key) - event_loop.run_until_complete(asyncio.gather(*futures)) return validators @pytest.fixture -def stake_pool_addresses(event_loop, async_client, payer, validators) -> Tuple[PublicKey, PublicKey]: +def stake_pool_addresses(event_loop, async_client, payer, validators, waiter) -> Tuple[PublicKey, PublicKey]: fee = Fee(numerator=1, denominator=1000) referral_fee = 20 + event_loop.run_until_complete(waiter.wait_for_next_epoch_if_soon(async_client)) stake_pool_addresses = event_loop.run_until_complete( create_all(async_client, payer, fee, referral_fee) ) - futures = [ - add_validator_to_pool(async_client, payer, stake_pool_addresses[0], validator) - for validator in validators - ] - event_loop.run_until_complete(asyncio.gather(*futures)) + for validator in validators: + event_loop.run_until_complete( + add_validator_to_pool(async_client, payer, stake_pool_addresses[0], validator) + ) return stake_pool_addresses diff --git a/clients/py/tests/test_deposit_withdraw_stake.py b/clients/py/tests/test_deposit_withdraw_stake.py index 0e260ff7..7a0ebf51 100644 --- a/clients/py/tests/test_deposit_withdraw_stake.py +++ b/clients/py/tests/test_deposit_withdraw_stake.py @@ -5,6 +5,7 @@ from stake.actions import create_stake, delegate_stake from stake.constants import STAKE_LEN +from stake.state import StakeState from stake_pool.actions import deposit_stake, withdraw_stake, update_stake_pool from stake_pool.state import StakePool @@ -15,26 +16,26 @@ async def test_deposit_withdraw_stake(async_client, validators, payer, stake_poo resp = await async_client.get_account_info(stake_pool_address, commitment=Confirmed) data = resp['result']['value']['data'] stake_pool = StakePool.decode(data[0], data[1]) - token_account = get_associated_token_address(payer.public_key, stake_pool.pool_mint) - - resp = await async_client.get_minimum_balance_for_rent_exemption(STAKE_LEN) - stake_rent_exemption = resp['result'] - waited = await waiter.wait_for_next_epoch_if_soon(async_client) - if waited: - await update_stake_pool(async_client, payer, stake_pool_address) - validator = next(iter(validators)) stake_amount = 1_000_000 stake = Keypair() await create_stake(async_client, payer, stake, payer.public_key, stake_amount) stake = stake.public_key await delegate_stake(async_client, payer, payer, stake, validator) + resp = await async_client.get_account_info(stake, commitment=Confirmed) + data = resp['result']['value']['data'] + stake_state = StakeState.decode(data[0], data[1]) + print(stake_state) + await waiter.wait_for_next_epoch(async_client) + await update_stake_pool(async_client, payer, stake_pool_address) + token_account = get_associated_token_address(payer.public_key, stake_pool.pool_mint) await deposit_stake(async_client, payer, stake_pool_address, validator, stake, token_account) - pool_token_balance = await async_client.get_token_account_balance(token_account, Confirmed) pool_token_balance = pool_token_balance['result']['value']['amount'] + resp = await async_client.get_minimum_balance_for_rent_exemption(STAKE_LEN) + stake_rent_exemption = resp['result'] assert pool_token_balance == str(stake_amount + stake_rent_exemption) destination_stake = Keypair() From 44b6d04830889dd49cd0c2abf822bd0ec53723d0 Mon Sep 17 00:00:00 2001 From: Alexander Ray Date: Tue, 15 Feb 2022 21:45:32 +0100 Subject: [PATCH 0230/1076] stake_pool: fix wrong available_for_withdrawal_wo_fee calculation (#2900) * - fix wrong available_for_withdrawal_wo_fee calculation by prepare_withdraw_accounts * - fix formatting * - refactor * - fix sub issue --- clients/cli/src/main.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 5457325c..aca6d19c 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -1257,7 +1257,9 @@ fn prepare_withdraw_accounts( ( transient_stake_account_address, - validator.transient_stake_lamports, + validator + .transient_stake_lamports + .saturating_sub(min_balance), Some(validator.vote_account_address), ) }, @@ -1265,7 +1267,13 @@ fn prepare_withdraw_accounts( let reserve_stake = rpc_client.get_account(&stake_pool.reserve_stake)?; - accounts.push((stake_pool.reserve_stake, reserve_stake.lamports, None)); + accounts.push(( + stake_pool.reserve_stake, + reserve_stake.lamports + - rpc_client.get_minimum_balance_for_rent_exemption(STAKE_STATE_LEN)? + - 1, + None, + )); // Prepare the list of accounts to withdraw from let mut withdraw_from: Vec = vec![]; From 7c2c9ac6fca15658281e39cc2f3e18078aecc7af Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 16 Feb 2022 16:22:46 +0100 Subject: [PATCH 0231/1076] stake-pool: Option to use transfer + allocate + assign for PDA (#2920) --- program/src/processor.rs | 76 +++++++++++++++++++++++++++++++++------- program/tests/vsa_add.rs | 43 +++++++++++++++++++++++ 2 files changed, 106 insertions(+), 13 deletions(-) diff --git a/program/src/processor.rs b/program/src/processor.rs index 9a5ad43d..dea314a4 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -160,6 +160,59 @@ fn create_transient_stake_account<'a>( ) } +/// Create an account on a program-derived address +fn create_pda_account<'a>( + payer: &AccountInfo<'a>, + required_lamports: u64, + space: usize, + owner: &Pubkey, + system_program: &AccountInfo<'a>, + new_pda_account: &AccountInfo<'a>, + new_pda_signer_seeds: &[&[u8]], +) -> ProgramResult { + if new_pda_account.lamports() > 0 { + let required_lamports = required_lamports.saturating_sub(new_pda_account.lamports()); + if required_lamports > 0 { + invoke( + &system_instruction::transfer(payer.key, new_pda_account.key, required_lamports), + &[ + payer.clone(), + new_pda_account.clone(), + system_program.clone(), + ], + )?; + } + + invoke_signed( + &system_instruction::allocate(new_pda_account.key, space as u64), + &[new_pda_account.clone(), system_program.clone()], + &[new_pda_signer_seeds], + )?; + + invoke_signed( + &system_instruction::assign(new_pda_account.key, owner), + &[new_pda_account.clone(), system_program.clone()], + &[new_pda_signer_seeds], + ) + } else { + invoke_signed( + &system_instruction::create_account( + payer.key, + new_pda_account.key, + required_lamports, + space as u64, + owner, + ), + &[ + payer.clone(), + new_pda_account.clone(), + system_program.clone(), + ], + &[new_pda_signer_seeds], + ) + } +} + /// Program state handler. pub struct Processor {} impl Processor { @@ -798,22 +851,19 @@ impl Processor { ]; // Fund the stake account with the minimum + rent-exempt balance - let required_lamports = MINIMUM_ACTIVE_STAKE - + rent.minimum_balance(std::mem::size_of::()); + let space = std::mem::size_of::(); + let required_lamports = MINIMUM_ACTIVE_STAKE + rent.minimum_balance(space); // Create new stake account - invoke_signed( - &system_instruction::create_account( - funder_info.key, - stake_info.key, - required_lamports, - std::mem::size_of::() as u64, - &stake::program::id(), - ), - &[funder_info.clone(), stake_info.clone()], - &[stake_account_signer_seeds], + create_pda_account( + funder_info, + required_lamports, + space, + &stake::program::id(), + system_program_info, + stake_info, + stake_account_signer_seeds, )?; - invoke( &stake::instruction::initialize( stake_info.key, diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index 48d27ea6..e6070676 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -500,3 +500,46 @@ async fn fail_on_incorrectly_derived_stake_account() { ) ); } + +#[tokio::test] +async fn success_with_lamports_in_account() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = + setup().await; + + transfer( + &mut banks_client, + &payer, + &recent_blockhash, + &validator_stake.stake_account, + 1_000_000, + ) + .await; + + let error = stake_pool_accounts + .add_validator_to_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &validator_stake.stake_account, + &validator_stake.vote.pubkey(), + ) + .await; + assert!(error.is_none()); + + // Check stake account existence and authority + let stake = get_account(&mut banks_client, &validator_stake.stake_account).await; + let stake_state = deserialize::(&stake.data).unwrap(); + match stake_state { + stake::state::StakeState::Stake(meta, _) => { + assert_eq!( + &meta.authorized.staker, + &stake_pool_accounts.withdraw_authority + ); + assert_eq!( + &meta.authorized.withdrawer, + &stake_pool_accounts.withdraw_authority + ); + } + _ => panic!(), + } +} From 348d4a1dcc3b56b677602774608f17369558eae0 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 16 Feb 2022 17:03:39 +0100 Subject: [PATCH 0232/1076] stake-pool: Bump version, add to Anchor (#2921) --- clients/cli/Cargo.toml | 10 +++++----- program/Cargo.toml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 2e64358d..02407bf3 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -6,7 +6,7 @@ homepage = "https://spl.solana.com/stake-pool" license = "Apache-2.0" name = "spl-stake-pool-cli" repository = "https://github.com/solana-labs/solana-program-library" -version = "0.6.3" +version = "0.6.4" [dependencies] borsh = "0.9" @@ -17,15 +17,15 @@ serde_json = "1.0.68" solana-account-decoder = "=1.9.5" solana-clap-utils = "=1.9.5" solana-cli-config = "=1.9.5" -solana-cli-output = "1.9.5" +solana-cli-output = "=1.9.5" solana-client = "=1.9.5" solana-logger = "=1.9.5" solana-program = "=1.9.5" solana-remote-wallet = "=1.9.5" solana-sdk = "=1.9.5" -spl-associated-token-account = { version = "1.0.5", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } -spl-stake-pool = { version = "0.6", path="../program", features = [ "no-entrypoint" ] } -spl-token = { version = "3.3", path="../../token/program", features = [ "no-entrypoint" ] } +spl-associated-token-account = { version = "=1.0.5", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } +spl-stake-pool = { version = "=0.6.4", path="../program", features = [ "no-entrypoint" ] } +spl-token = { version = "=3.3.0", path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" bincode = "1.3.1" diff --git a/program/Cargo.toml b/program/Cargo.toml index 523793a5..04518402 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "spl-stake-pool" -version = "0.6.3" +version = "0.6.4" description = "Solana Program Library Stake Pool" authors = ["Solana Maintainers "] repository = "https://github.com/solana-labs/solana-program-library" From f40809c389a9cca7f291ba0e30e246ee9b153fd5 Mon Sep 17 00:00:00 2001 From: Alexander Ray Date: Wed, 23 Feb 2022 04:41:18 +0100 Subject: [PATCH 0233/1076] stake-pool: add bindings to js (#2806) * stake-pool: add new bindings | 'IncreaseValidatorStake' | 'DecreaseValidatorStake' | 'UpdateValidatorListBalance' | 'UpdateStakePoolBalance' | 'CleanupRemovedValidatorEntries' * stake-pool: add new bindings | 'IncreaseValidatorStake' | 'DecreaseValidatorStake' | 'UpdateValidatorListBalance' | 'UpdateStakePoolBalance' | 'CleanupRemovedValidatorEntries' * - merge upstream with local changes * - merge package.json * - update package.json * - fix lint issues * - fix lint issues * - another lint fix * - fix & try * - force rebuild * - merge from upstream * fix lint issues * - update package.json * - add debug info to prettier * - update prettier settings * cleanup package json * - refactor according PR suggestions * - refactor * - refactor * - force pr action * - fix withdraw stake issue * - fix issue --- clients/js-legacy/.eslintignore | 5 +- clients/js-legacy/.eslintrc.js | 48 +- clients/js-legacy/.gitignore | 22 +- clients/js-legacy/.prettierrc | 8 - clients/js-legacy/.prettierrc.js | 7 + clients/js-legacy/babel.config.js | 7 - clients/js-legacy/package-lock.json | 16599 +++++----------- clients/js-legacy/package.json | 53 +- clients/js-legacy/rollup.config.js | 18 +- clients/js-legacy/src/constants.ts | 20 +- clients/js-legacy/src/index.ts | 521 +- clients/js-legacy/src/instructions.ts | 448 +- clients/js-legacy/src/layouts.ts | 23 +- .../src/{ => types}/buffer-layout.d.ts | 6 +- clients/js-legacy/src/utils/index.ts | 9 + .../instruction.ts | 8 +- clients/js-legacy/src/utils/math.ts | 7 +- .../js-legacy/src/utils/program-address.ts | 5 +- clients/js-legacy/src/utils/stake.ts | 135 +- clients/js-legacy/src/utils/token.ts | 27 +- clients/js-legacy/test/equal.ts | 18 +- clients/js-legacy/test/instructions.test.ts | 159 +- clients/js-legacy/test/layouts.test.ts | 10 +- clients/js-legacy/test/mocks.ts | 27 +- clients/js-legacy/tsconfig.json | 9 +- 25 files changed, 6512 insertions(+), 11687 deletions(-) delete mode 100644 clients/js-legacy/.prettierrc create mode 100644 clients/js-legacy/.prettierrc.js delete mode 100644 clients/js-legacy/babel.config.js rename clients/js-legacy/src/{ => types}/buffer-layout.d.ts (79%) rename clients/js-legacy/src/{copied-from-solana-web3 => utils}/instruction.ts (82%) diff --git a/clients/js-legacy/.eslintignore b/clients/js-legacy/.eslintignore index 9b1c8b13..58542507 100644 --- a/clients/js-legacy/.eslintignore +++ b/clients/js-legacy/.eslintignore @@ -1 +1,4 @@ -/dist +dist +node_modules +.vscode +.idea diff --git a/clients/js-legacy/.eslintrc.js b/clients/js-legacy/.eslintrc.js index 317d0253..63db7b84 100644 --- a/clients/js-legacy/.eslintrc.js +++ b/clients/js-legacy/.eslintrc.js @@ -1,31 +1,21 @@ module.exports = { - "env": { - "es2021": true, - "node": true - }, - "extends": [ - "eslint:recommended", - "plugin:react/recommended", - "plugin:@typescript-eslint/recommended" - ], - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaFeatures": { - "jsx": true - }, - "ecmaVersion": 13, - "sourceType": "module" - }, - "plugins": [ - "react", - "@typescript-eslint" - ], - "rules": { - "@typescript-eslint/no-explicit-any": "off" - }, - "settings": { - "react": { - "version": "detect" - } - } + root: true, + env: { + es6: true, + node: true, + jest: true, + }, + extends: ['plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended'], + plugins: ['@typescript-eslint/eslint-plugin'], + parser: '@typescript-eslint/parser', + parserOptions: { + sourceType: 'module', + }, + rules: { + '@typescript-eslint/interface-name-prefix': 'off', + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/ban-ts-comment': 'off', + }, }; diff --git a/clients/js-legacy/.gitignore b/clients/js-legacy/.gitignore index 6edc39b0..3764afb8 100644 --- a/clients/js-legacy/.gitignore +++ b/clients/js-legacy/.gitignore @@ -1,4 +1,22 @@ -dist -dist.browser +# IDE & OS specific +.DS_Store .idea +.vscode + +# Logs +logs +*.log + +# Dependencies node_modules + +# Coverage +coverage +.nyc_output + +# Release +dist +dist.browser + +# TypeScript +declarations diff --git a/clients/js-legacy/.prettierrc b/clients/js-legacy/.prettierrc deleted file mode 100644 index 583011bb..00000000 --- a/clients/js-legacy/.prettierrc +++ /dev/null @@ -1,8 +0,0 @@ -{ - "arrowParens": "avoid", - "bracketSpacing":false, - "singleQuote": true, - "semi": true, - "tabWidth": 2, - "trailingComma": "all" -} diff --git a/clients/js-legacy/.prettierrc.js b/clients/js-legacy/.prettierrc.js new file mode 100644 index 00000000..8446d684 --- /dev/null +++ b/clients/js-legacy/.prettierrc.js @@ -0,0 +1,7 @@ +module.exports = { + singleQuote: true, + trailingComma: 'all', + printWidth: 100, + endOfLine: 'lf', + semi: true, +}; diff --git a/clients/js-legacy/babel.config.js b/clients/js-legacy/babel.config.js deleted file mode 100644 index 20f7fbb6..00000000 --- a/clients/js-legacy/babel.config.js +++ /dev/null @@ -1,7 +0,0 @@ -// it's needed for jest - https://jestjs.io/docs/getting-started#using-typescript -module.exports = { - presets: [ - ['@babel/preset-env', {targets: {node: 'current'}}], - '@babel/preset-typescript', - ], -}; diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 443c309e..6550b98c 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -17,9 +17,6 @@ "buffer": "^6.0.3" }, "devDependencies": { - "@babel/core": "^7.16.5", - "@babel/preset-env": "^7.16.5", - "@babel/preset-typescript": "^7.16.5", "@rollup/plugin-alias": "^3.1.9", "@rollup/plugin-commonjs": "^21.0.1", "@rollup/plugin-json": "^4.1.0", @@ -27,65 +24,78 @@ "@rollup/plugin-node-resolve": "^13.1.3", "@rollup/plugin-typescript": "^8.3.0", "@types/bn.js": "^5.1.0", - "@types/jest": "^27.0.3", - "@typescript-eslint/eslint-plugin": "^5.8.1", - "@typescript-eslint/parser": "^5.8.1", - "babel-jest": "^27.4.6", + "@types/jest": "^27.4.0", + "@typescript-eslint/eslint-plugin": "^5.11.0", + "@typescript-eslint/parser": "^5.11.0", "cross-env": "^7.0.3", - "eslint": "^8.5.0", - "eslint-plugin-react": "^7.28.0", - "jest": "^27.4.7", - "prettier": "^2.2.1", + "eslint": "^8.8.0", + "eslint-config-prettier": "^8.3.0", + "eslint-plugin-prettier": "^4.0.0", + "jest": "^27.5.1", + "prettier": "^2.5.1", "rimraf": "^3.0.2", "rollup": "^2.66.1", "rollup-plugin-dts": "^4.1.0", "rollup-plugin-node-polyfills": "^0.2.1", "rollup-plugin-terser": "^7.0.2", + "ts-jest": "^27.1.3", "typescript": "^4.5.4" } }, + "node_modules/@ampproject/remapping": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.0.tgz", + "integrity": "sha512-d5RysTlJ7hmw5Tw4UxgxcY3lkMe92n8sXCcuLPAyIAHK6j8DefDwtGnVVDgOnv+RnEosulDJ9NPKQL27bDId0g==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@babel/code-frame": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz", - "integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", "dev": true, "dependencies": { - "@babel/highlight": "^7.16.0" + "@babel/highlight": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.16.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.4.tgz", - "integrity": "sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.0.tgz", + "integrity": "sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.5.tgz", - "integrity": "sha512-wUcenlLzuWMZ9Zt8S0KmFwGlH6QKRh3vsm/dhDA3CHkiTA45YuG1XkHRcNRl73EFPXDp/d5kVOU0/y7x2w6OaQ==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.16.0", - "@babel/generator": "^7.16.5", - "@babel/helper-compilation-targets": "^7.16.3", - "@babel/helper-module-transforms": "^7.16.5", - "@babel/helpers": "^7.16.5", - "@babel/parser": "^7.16.5", - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0", + "version": "7.17.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.2.tgz", + "integrity": "sha512-R3VH5G42VSDolRHyUO4V2cfag8WHcZyxdq5Z/m8Xyb92lW/Erm/6kM+XtRFGf3Mulre3mveni2NHfEUws8wSvw==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.0.0", + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.0", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helpers": "^7.17.2", + "@babel/parser": "^7.17.0", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.0", + "@babel/types": "^7.17.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.1.2", - "semver": "^6.3.0", - "source-map": "^0.5.0" + "semver": "^6.3.0" }, "engines": { "node": ">=6.9.0" @@ -95,53 +105,46 @@ "url": "https://opencollective.com/babel" } }, - "node_modules/@babel/generator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.5.tgz", - "integrity": "sha512-kIvCdjZqcdKqoDbVVdt5R99icaRtrtYhYK/xux5qiWCBmfdvEYMFZ68QCrpE5cbFM1JsuArUNs1ZkuKtTtUcZA==", + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, - "dependencies": { - "@babel/types": "^7.16.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - }, - "engines": { - "node": ">=6.9.0" + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.0.tgz", - "integrity": "sha512-ItmYF9vR4zA8cByDocY05o0LGUkp1zhbTQOH1NFyl5xXEqlTJQCEJjieriw+aFpxo16swMxUnUiKS7a/r4vtHg==", + "node_modules/@babel/generator": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.0.tgz", + "integrity": "sha512-I3Omiv6FGOC29dtlZhkfXO6pgkmukJSlT26QjVvS1DGZe/NzSVCPG41X0tS21oZkJYlovfj9qDWgKP+Cn4bXxw==", "dev": true, "dependencies": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.17.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.5.tgz", - "integrity": "sha512-3JEA9G5dmmnIWdzaT9d0NmFRgYnWUThLsDaL7982H0XqqWr56lRrsmwheXFMjR+TMl7QMBb6mzy9kvgr1lRLUA==", + "node_modules/@babel/generator/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true, - "dependencies": { - "@babel/helper-explode-assignable-expression": "^7.16.0", - "@babel/types": "^7.16.0" - }, "engines": { - "node": ">=6.9.0" + "node": ">=0.10.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.16.3", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.3.tgz", - "integrity": "sha512-vKsoSQAyBmxS35JUOOt+07cLc6Nk/2ljLIHwmq2/NM6hdioUaqEXq/S+nXvbvXbZkNDlWOymPanJGOc4CBjSJA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", + "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.16.0", - "@babel/helper-validator-option": "^7.14.5", + "@babel/compat-data": "^7.16.4", + "@babel/helper-validator-option": "^7.16.7", "browserslist": "^4.17.5", "semver": "^6.3.0" }, @@ -152,131 +155,60 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.5.tgz", - "integrity": "sha512-NEohnYA7mkB8L5JhU7BLwcBdU3j83IziR9aseMueWGeAjblbul3zzb8UvJ3a1zuBiqCMObzCJHFqKIQE6hTVmg==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-environment-visitor": "^7.16.5", - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-member-expression-to-functions": "^7.16.5", - "@babel/helper-optimise-call-expression": "^7.16.0", - "@babel/helper-replace-supers": "^7.16.5", - "@babel/helper-split-export-declaration": "^7.16.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.0.tgz", - "integrity": "sha512-3DyG0zAFAZKcOp7aVr33ddwkxJ0Z0Jr5V99y3I690eYLpukJsJvAbzTy1ewoCqsML8SbIrjH14Jc/nSQ4TvNPA==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "regexpu-core": "^4.7.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz", - "integrity": "sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA==", + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, - "dependencies": { - "@babel/helper-compilation-targets": "^7.13.0", - "@babel/helper-module-imports": "^7.12.13", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/traverse": "^7.13.0", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2", - "semver": "^6.1.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0-0" + "bin": { + "semver": "bin/semver.js" } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.5.tgz", - "integrity": "sha512-ODQyc5AnxmZWm/R2W7fzhamOk1ey8gSguo5SGvF0zcB3uUzRpTRmM/jmLSm9bDMyPlvbyJ+PwPEK0BWIoZ9wjg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.16.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-explode-assignable-expression": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.0.tgz", - "integrity": "sha512-Hk2SLxC9ZbcOhLpg/yMznzJ11W++lg5GMbxt1ev6TXUiJB0N42KPC+7w8a+eWGuqDnUYuwStJoZHM7RgmIOaGQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", + "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", "dev": true, "dependencies": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.0.tgz", - "integrity": "sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", + "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", "dev": true, "dependencies": { - "@babel/helper-get-function-arity": "^7.16.0", - "@babel/template": "^7.16.0", - "@babel/types": "^7.16.0" + "@babel/helper-get-function-arity": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-get-function-arity": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.0.tgz", - "integrity": "sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", + "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", "dev": true, "dependencies": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.0.tgz", - "integrity": "sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.16.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.5.tgz", - "integrity": "sha512-7fecSXq7ZrLE+TWshbGT+HyCLkxloWNhTbU2QM1NTI/tDqyf0oZiMcEfYtDuUDCo528EOlt39G1rftea4bRZIw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", + "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", "dev": true, "dependencies": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -295,31 +227,19 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.5.tgz", - "integrity": "sha512-CkvMxgV4ZyyioElFwcuWnDCcNIeyqTkCm9BxXZi73RR1ozqlpboqsbGUNvRTflgZtFbbJ1v5Emvm+lkjMYY/LQ==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.16.5", - "@babel/helper-module-imports": "^7.16.0", - "@babel/helper-simple-access": "^7.16.0", - "@babel/helper-split-export-declaration": "^7.16.0", - "@babel/helper-validator-identifier": "^7.15.7", - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.0.tgz", - "integrity": "sha512-SuI467Gi2V8fkofm2JPnZzB/SUuXoJA5zXe/xzyPP2M04686RzFKFHPK6HDVN6JvWBIEW8tt9hPR7fXdn2Lgpw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz", + "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==", "dev": true, "dependencies": { - "@babel/types": "^7.16.0" + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-simple-access": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -334,67 +254,25 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.5.tgz", - "integrity": "sha512-X+aAJldyxrOmN9v3FKp+Hu1NO69VWgYgDGq6YDykwRPzxs5f2N+X988CBXS7EQahDU+Vpet5QYMqLk+nsp+Qxw==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-wrap-function": "^7.16.5", - "@babel/types": "^7.16.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.5.tgz", - "integrity": "sha512-ao3seGVa/FZCMCCNDuBcqnBFSbdr8N2EW35mzojx3TwfIbdPmNK+JV6+2d5bR0Z71W5ocLnQp9en/cTF7pBJiQ==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.16.5", - "@babel/helper-member-expression-to-functions": "^7.16.5", - "@babel/helper-optimise-call-expression": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-simple-access": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.0.tgz", - "integrity": "sha512-o1rjBT/gppAqKsYfUdfHq5Rk03lMQrkPHG1OWzHWpLgVXRH4HnMM9Et9CVdIqwkCQlobnGHEJMsgWP/jE1zUiw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.16.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz", - "integrity": "sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", + "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", "dev": true, "dependencies": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz", - "integrity": "sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", + "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", "dev": true, "dependencies": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -410,50 +288,35 @@ } }, "node_modules/@babel/helper-validator-option": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", - "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-wrap-function": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.16.5.tgz", - "integrity": "sha512-2J2pmLBqUqVdJw78U0KPNdeE2qeuIyKoG4mKV7wAq3mc4jJG282UgjZw4ZYDnqiWQuS3Y3IYdF/AQ6CpyBV3VA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", + "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", "dev": true, - "dependencies": { - "@babel/helper-function-name": "^7.16.0", - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0" - }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.5.tgz", - "integrity": "sha512-TLgi6Lh71vvMZGEkFuIxzaPsyeYCHQ5jJOOX1f0xXn0uciFuE8cEk0wyBquMcCxBXZ5BJhE2aUB7pnWTD150Tw==", + "version": "7.17.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.2.tgz", + "integrity": "sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ==", "dev": true, "dependencies": { - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0" + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.0", + "@babel/types": "^7.17.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.0.tgz", - "integrity": "sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==", + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.15.7", + "@babel/helper-validator-identifier": "^7.16.7", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -461,413 +324,165 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/parser": { - "version": "7.16.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.6.tgz", - "integrity": "sha512-Gr86ujcNuPDnNOY8mi383Hvi8IYrJVJYuf3XcuBM/Dgd+bINn/7tHqsj+tKkoreMbmGsFLsltI/JJd8fOFWGDQ==", + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "bin": { - "parser": "bin/babel-parser.js" + "dependencies": { + "color-convert": "^1.9.0" }, "engines": { - "node": ">=6.0.0" + "node": ">=4" } }, - "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.16.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.2.tgz", - "integrity": "sha512-h37CvpLSf8gb2lIJ2CgC3t+EjFbi0t8qS7LCS1xcJIlEXE4czlofwaW7W1HA8zpgOCzI9C1nmoqNR1zWkk0pQg==", + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "node": ">=4" } }, - "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.0.tgz", - "integrity": "sha512-4tcFwwicpWTrpl9qjf7UsoosaArgImF85AxqCRZlgc3IQDvkUHjJpruXAL58Wmj+T6fypWTC/BakfEkwIL/pwA==", + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", - "@babel/plugin-proposal-optional-chaining": "^7.16.0" - }, + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.13.0" + "node": ">=0.8.0" } }, - "node_modules/@babel/plugin-proposal-async-generator-functions": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.5.tgz", - "integrity": "sha512-C/FX+3HNLV6sz7AqbTQqEo1L9/kfrKjxcVtgyBCmvIgOjvuBVUWooDoi7trsLxOzCEo5FccjRvKHkfDsJFZlfA==", + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-remap-async-to-generator": "^7.16.5", - "@babel/plugin-syntax-async-generators": "^7.8.4" - }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=4" } }, - "node_modules/@babel/plugin-proposal-class-properties": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.5.tgz", - "integrity": "sha512-pJD3HjgRv83s5dv1sTnDbZOaTjghKEz8KUn1Kbh2eAIRhGuyQ1XSeI4xVXU3UlIEVA3DAyIdxqT1eRn7Wcn55A==", + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5" + "has-flag": "^3.0.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=4" } }, - "node_modules/@babel/plugin-proposal-class-static-block": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.16.5.tgz", - "integrity": "sha512-EEFzuLZcm/rNJ8Q5krK+FRKdVkd6FjfzT9tuSZql9sQn64K0hHA2KLJ0DqVot9/iV6+SsuadC5yI39zWnm+nmQ==", + "node_modules/@babel/parser": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.0.tgz", + "integrity": "sha512-VKXSCQx5D8S04ej+Dqsr1CzYvvWgf20jIw2D+YhQCrIlr2UZGaDds23Y0xg75/skOxpLCRpUZvk/1EAVkGoDOw==", "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-class-static-block": "^7.14.5" + "bin": { + "parser": "bin/babel-parser.js" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" + "node": ">=6.0.0" } }, - "node_modules/@babel/plugin-proposal-dynamic-import": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.5.tgz", - "integrity": "sha512-P05/SJZTTvHz79LNYTF8ff5xXge0kk5sIIWAypcWgX4BTRUgyHc8wRxJ/Hk+mU0KXldgOOslKaeqnhthcDJCJQ==", + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" + "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-export-namespace-from": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.5.tgz", - "integrity": "sha512-i+sltzEShH1vsVydvNaTRsgvq2vZsfyrd7K7vPLUU/KgS0D5yZMe6uipM0+izminnkKrEfdUnz7CxMRb6oHZWw==", + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" + "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-json-strings": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.5.tgz", - "integrity": "sha512-QQJueTFa0y9E4qHANqIvMsuxM/qcLQmKttBACtPCQzGUEizsXDACGonlPiSwynHfOa3vNw0FPMVvQzbuXwh4SQ==", + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-json-strings": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" + "@babel/helper-plugin-utils": "^7.12.13" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.5.tgz", - "integrity": "sha512-xqibl7ISO2vjuQM+MzR3rkd0zfNWltk7n9QhaD8ghMmMceVguYrNDt7MikRyj4J4v3QehpnrU8RYLnC7z/gZLA==", + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" + "@babel/helper-plugin-utils": "^7.10.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.5.tgz", - "integrity": "sha512-YwMsTp/oOviSBhrjwi0vzCUycseCYwoXnLiXIL3YNjHSMBHicGTz7GjVU/IGgz4DtOEXBdCNG72pvCX22ehfqg==", + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" + "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-numeric-separator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.5.tgz", - "integrity": "sha512-DvB9l/TcsCRvsIV9v4jxR/jVP45cslTVC0PMVHvaJhhNuhn2Y1SOhCSFlPK777qLB5wb8rVDaNoqMTyOqtY5Iw==", + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" + "@babel/helper-plugin-utils": "^7.10.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.16.5.tgz", - "integrity": "sha512-UEd6KpChoyPhCoE840KRHOlGhEZFutdPDMGj+0I56yuTTOaT51GzmnEl/0uT41fB/vD2nT+Pci2KjezyE3HmUw==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.16.4", - "@babel/helper-compilation-targets": "^7.16.3", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.16.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-optional-catch-binding": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.5.tgz", - "integrity": "sha512-ihCMxY1Iljmx4bWy/PIMJGXN4NS4oUj1MKynwO07kiKms23pNvIn1DMB92DNB2R0EA882sw0VXIelYGdtF7xEQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.5.tgz", - "integrity": "sha512-kzdHgnaXRonttiTfKYnSVafbWngPPr2qKw9BWYBESl91W54e+9R5pP70LtWxV56g0f05f/SQrwHYkfvbwcdQ/A==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-private-methods": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.5.tgz", - "integrity": "sha512-+yFMO4BGT3sgzXo+lrq7orX5mAZt57DwUK6seqII6AcJnJOIhBJ8pzKH47/ql/d426uQ7YhN8DpUFirQzqYSUA==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.5.tgz", - "integrity": "sha512-+YGh5Wbw0NH3y/E5YMu6ci5qTDmAEVNoZ3I54aB6nVEOZ5BQ7QJlwKq5pYVucQilMByGn/bvX0af+uNaPRCabA==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-create-class-features-plugin": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-unicode-property-regex": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.5.tgz", - "integrity": "sha512-s5sKtlKQyFSatt781HQwv1hoM5BQ9qRH30r+dK56OLDsHmV74mzwJNX7R1yMuE7VZKG5O6q/gmOGSAO6ikTudg==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -924,21 +539,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-top-level-await": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", @@ -955,12 +555,12 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.5.tgz", - "integrity": "sha512-/d4//lZ1Vqb4mZ5xTep3dDK888j7BGM/iKqBmndBaoYAFPlPKrGU608VVBz5JeyAb6YQDjRu1UKqj86UhwWVgw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz", + "integrity": "sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -969,1343 +569,1316 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.5.tgz", - "integrity": "sha512-8bTHiiZyMOyfZFULjsCnYOWG059FVMes0iljEHSfARhNgFfpsqE92OrCffv3veSw9rwMkYcFe9bj0ZoXU2IGtQ==", - "dev": true, + "node_modules/@babel/runtime": { + "version": "7.17.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz", + "integrity": "sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "regenerator-runtime": "^0.13.4" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.5.tgz", - "integrity": "sha512-TMXgfioJnkXU+XRoj7P2ED7rUm5jbnDWwlCuFVTpQboMfbSya5WrmubNBAMlk7KXvywpo8rd8WuYZkis1o2H8w==", + "node_modules/@babel/template": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", + "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-remap-async-to-generator": "^7.16.5" + "@babel/code-frame": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.5.tgz", - "integrity": "sha512-BxmIyKLjUGksJ99+hJyL/HIxLIGnLKtw772zYDER7UuycDZ+Xvzs98ZQw6NGgM2ss4/hlFAaGiZmMNKvValEjw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "node_modules/@babel/traverse": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.0.tgz", + "integrity": "sha512-fpFIXvqD6kC7c7PUNnZ0Z8cQXlarCLtCUpt2S1Dx7PjoRtCFffvOkHHSom+m5HIxMZn5bIBVb71lhabcmjEsqg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.0", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/parser": "^7.17.0", + "@babel/types": "^7.17.0", + "debug": "^4.1.0", + "globals": "^11.1.0" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.5.tgz", - "integrity": "sha512-JxjSPNZSiOtmxjX7PBRBeRJTUKTyJ607YUYeT0QJCNdsedOe+/rXITjP08eG8xUpsLfPirgzdCFN+h0w6RI+pQ==", + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" - }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=4" } }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.5.tgz", - "integrity": "sha512-DzJ1vYf/7TaCYy57J3SJ9rV+JEuvmlnvvyvYKFbk5u46oQbBvuB9/0w+YsVsxkOv8zVWKpDmUoj4T5ILHoXevA==", + "node_modules/@babel/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-environment-visitor": "^7.16.5", - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-optimise-call-expression": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-replace-supers": "^7.16.5", - "@babel/helper-split-export-declaration": "^7.16.0", - "globals": "^11.1.0" + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.5.tgz", - "integrity": "sha512-n1+O7xtU5lSLraRzX88CNcpl7vtGdPakKzww74bVwpAIRgz9JVLJJpOLb0uYqcOaXVM0TL6X0RVeIJGD2CnCkg==", + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@eslint/eslintrc": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz", + "integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.2.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.5.tgz", - "integrity": "sha512-GuRVAsjq+c9YPK6NeTkRLWyQskDC099XkBSVO+6QzbnOnH2d/4mBVXYStaPrZD3dFRfg00I6BFJ9Atsjfs8mlg==", + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" - }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">= 4" } }, - "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.5.tgz", - "integrity": "sha512-iQiEMt8Q4/5aRGHpGVK2Zc7a6mx7qEAO7qehgSug3SDImnuMzgmm/wtJALXaz25zUj1PmnNHtShjFgk4PDx4nw==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node_modules/@ethersproject/bytes": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.5.0.tgz", + "integrity": "sha512-ABvc7BHWhZU9PNM/tANm/Qx4ostPGadAuQzWTr3doklZOhDlmcBqclrQe/ZXUIj3K8wC28oYeuRa+A37tX9kog==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.5.0" } }, - "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.5.tgz", - "integrity": "sha512-81tijpDg2a6I1Yhj4aWY1l3O1J4Cg/Pd7LfvuaH2VVInAkXtzibz9+zSPdUM1WvuUi128ksstAP0hM5w48vQgg==", - "dev": true, + "node_modules/@ethersproject/logger": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.5.0.tgz", + "integrity": "sha512-rIY/6WPm7T8n3qS2vuHTUBPdXHl+rGxWxW5okDfo9J4Z0+gRRZT0msvUdIJkE4/HS29GUMziwGaaKO2bWONBrg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ] + }, + "node_modules/@ethersproject/sha2": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.5.0.tgz", + "integrity": "sha512-B5UBoglbCiHamRVPLA110J+2uqsifpZaTmid2/7W5rbtYVz6gus6/hSDieIU/6gaKIDcOj12WnOdiymEUHIAOA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "hash.js": "1.1.7" } }, - "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.5.tgz", - "integrity": "sha512-12rba2HwemQPa7BLIKCzm1pT2/RuQHtSFHdNl41cFiC6oi4tcrp7gjB07pxQvFpcADojQywSjblQth6gJyE6CA==", + "node_modules/@humanwhocodes/config-array": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.3.tgz", + "integrity": "sha512-3xSMlXHh03hCcCmFc0rbKp3Ivt2PFEJnQUJDDMTJQ2wkECZWdq4GePs2ctc5H8zV+cHPaq8k2vU8mrQjA6iHdQ==", "dev": true, "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5" + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=10.10.0" } }, - "node_modules/@babel/plugin-transform-for-of": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.5.tgz", - "integrity": "sha512-+DpCAJFPAvViR17PIMi9x2AE34dll5wNlXO43wagAX2YcRGgEVHCNFC4azG85b4YyyFarvkc/iD5NPrz4Oneqw==", + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=8" } }, - "node_modules/@babel/plugin-transform-function-name": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.5.tgz", - "integrity": "sha512-Fuec/KPSpVLbGo6z1RPw4EE1X+z9gZk1uQmnYy7v4xr4TO9p41v1AoUuXEtyqAI7H+xNJYSICzRqZBhDEkd3kQ==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "dependencies": { - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "sprintf-js": "~1.0.2" } }, - "node_modules/@babel/plugin-transform-literals": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.5.tgz", - "integrity": "sha512-B1j9C/IfvshnPcklsc93AVLTrNVa69iSqztylZH6qnmiAsDDOmmjEYqOm3Ts2lGSgTSywnBNiqC949VdD0/gfw==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" - }, - "engines": { - "node": ">=6.9.0" + "argparse": "^1.0.7", + "esprima": "^4.0.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.5.tgz", - "integrity": "sha512-d57i3vPHWgIde/9Y8W/xSFUndhvhZN5Wu2TjRrN1MVz5KzdUihKnfDVlfP1U7mS5DNj/WHHhaE4/tTi4hIyHwQ==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" - }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=8" } }, - "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.5.tgz", - "integrity": "sha512-oHI15S/hdJuSCfnwIz+4lm6wu/wBn7oJ8+QrkzPPwSFGXk8kgdI/AIKcbR/XnD1nQVMg/i6eNaXpszbGuwYDRQ==", + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5", - "babel-plugin-dynamic-import-node": "^2.3.3" - }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=8" } }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.5.tgz", - "integrity": "sha512-ABhUkxvoQyqhCWyb8xXtfwqNMJD7tx+irIRnUh6lmyFud7Jln1WzONXKlax1fg/ey178EXbs4bSGNd6PngO+SQ==", + "node_modules/@jest/console": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", + "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-simple-access": "^7.16.0", - "babel-plugin-dynamic-import-node": "^2.3.3" + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", + "slash": "^3.0.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.5.tgz", - "integrity": "sha512-53gmLdScNN28XpjEVIm7LbWnD/b/TpbwKbLk6KV4KqC9WyU6rq1jnNmVG6UgAdQZVVGZVoik3DqHNxk4/EvrjA==", + "node_modules/@jest/core": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", + "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", "dev": true, "dependencies": { - "@babel/helper-hoist-variables": "^7.16.0", - "@babel/helper-module-transforms": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-validator-identifier": "^7.15.7", - "babel-plugin-dynamic-import-node": "^2.3.3" + "@jest/console": "^27.5.1", + "@jest/reporters": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^27.5.1", + "jest-config": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-resolve-dependencies": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "jest-watcher": "^27.5.1", + "micromatch": "^4.0.4", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=6.9.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.5.tgz", - "integrity": "sha512-qTFnpxHMoenNHkS3VoWRdwrcJ3FhX567GvDA3hRZKF0Dj8Fmg0UzySZp3AP2mShl/bzcywb/UWAMQIjA1bhXvw==", + "node_modules/@jest/environment": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", + "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5" + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.5.tgz", - "integrity": "sha512-/wqGDgvFUeKELW6ex6QB7dLVRkd5ehjw34tpXu1nhKC0sFfmaLabIswnpf8JgDyV2NeDmZiwoOb0rAmxciNfjA==", + "node_modules/@jest/fake-timers": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", + "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.16.0" + "@jest/types": "^27.5.1", + "@sinonjs/fake-timers": "^8.0.1", + "@types/node": "*", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@babel/plugin-transform-new-target": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.5.tgz", - "integrity": "sha512-ZaIrnXF08ZC8jnKR4/5g7YakGVL6go6V9ql6Jl3ecO8PQaQqFE74CuM384kezju7Z9nGCCA20BqZaR1tJ/WvHg==", + "node_modules/@jest/globals": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", + "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@jest/environment": "^27.5.1", + "@jest/types": "^27.5.1", + "expect": "^27.5.1" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@babel/plugin-transform-object-super": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.5.tgz", - "integrity": "sha512-tded+yZEXuxt9Jdtkc1RraW1zMF/GalVxaVVxh41IYwirdRgyAxxxCKZ9XB7LxZqmsjfjALxupNE1MIz9KH+Zg==", + "node_modules/@jest/reporters": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", + "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-replace-supers": "^7.16.5" + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-haste-map": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^8.1.0" }, "engines": { - "node": ">=6.9.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/@babel/plugin-transform-parameters": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.5.tgz", - "integrity": "sha512-B3O6AL5oPop1jAVg8CV+haeUte9oFuY85zu0jwnRNZZi3tVAbJriu5tag/oaO2kGaQM/7q7aGPBlTI5/sr9enA==", + "node_modules/@jest/source-map": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", + "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9", + "source-map": "^0.6.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.5.tgz", - "integrity": "sha512-+IRcVW71VdF9pEH/2R/Apab4a19LVvdVsr/gEeotH00vSDVlKD+XgfSIw+cgGWsjDB/ziqGv/pGoQZBIiQVXHg==", + "node_modules/@jest/test-result": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", + "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@jest/console": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.5.tgz", - "integrity": "sha512-2z+it2eVWU8TtQQRauvGUqZwLy4+7rTfo6wO4npr+fvvN1SW30ZF3O/ZRCNmTuu4F5MIP8OJhXAhRV5QMJOuYg==", + "node_modules/@jest/test-sequencer": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", + "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", "dev": true, "dependencies": { - "regenerator-transform": "^0.14.2" + "@jest/test-result": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-runtime": "^27.5.1" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.5.tgz", - "integrity": "sha512-aIB16u8lNcf7drkhXJRoggOxSTUAuihTSTfAcpynowGJOZiGf+Yvi7RuTwFzVYSYPmWyARsPqUGoZWWWxLiknw==", + "node_modules/@jest/transform": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", + "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/core": "^7.1.0", + "@jest/types": "^27.5.1", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-util": "^27.5.1", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.5.tgz", - "integrity": "sha512-ZbuWVcY+MAXJuuW7qDoCwoxDUNClfZxoo7/4swVbOW1s/qYLOMHlm9YRWMsxMFuLs44eXsv4op1vAaBaBaDMVg==", + "node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@babel/plugin-transform-spread": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.5.tgz", - "integrity": "sha512-5d6l/cnG7Lw4tGHEoga4xSkYp1euP7LAtrah1h1PgJ3JY7yNsjybsxQAnVK4JbtReZ/8z6ASVmd3QhYYKLaKZw==", + "node_modules/@jridgewell/resolve-uri": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.4.tgz", + "integrity": "sha512-cz8HFjOFfUBtvN+NXYSFMHYRdxZMaEl0XypVrhzxBgadKIXhIkRd8aMeHhmF56Sl7SuS8OnUpQ73/k9LE4VnLg==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.10.tgz", + "integrity": "sha512-Ht8wIW5v165atIX1p+JvKR5ONzUyF4Ac8DZIQ5kZs9zrb6M8SJNXpx1zn04rn65VjBMygRoMXcyYwNK0fT7bEg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", + "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0" + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" } }, - "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.5.tgz", - "integrity": "sha512-usYsuO1ID2LXxzuUxifgWtJemP7wL2uZtyrTVM4PKqsmJycdS4U4mGovL5xXkfUheds10Dd2PjoQLXw6zCsCbg==", + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" }, "engines": { - "node": ">=6.9.0" + "node": ">= 8" + } + }, + "node_modules/@project-serum/borsh": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@project-serum/borsh/-/borsh-0.2.4.tgz", + "integrity": "sha512-tQPc1ktAp1Jtn9D72DmObAfhAic9ivfYBOS5b+T4H7MvkQ84uML88LY1LfvGep30mCy+ua5rf+X9ocPfg6u9MA==", + "dependencies": { + "bn.js": "^5.1.2", + "buffer-layout": "^1.2.0" + }, + "engines": { + "node": ">=10" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@solana/web3.js": "^1.2.0" } }, - "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.5.tgz", - "integrity": "sha512-gnyKy9RyFhkovex4BjKWL3BVYzUDG6zC0gba7VMLbQoDuqMfJ1SDXs8k/XK41Mmt1Hyp4qNAvGFb9hKzdCqBRQ==", + "node_modules/@rollup/plugin-alias": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-3.1.9.tgz", + "integrity": "sha512-QI5fsEvm9bDzt32k39wpOwZhVzRcL5ydcffUHMyLVaVaLeC70I8TJZ17F1z1eMoLu4E/UOcH9BWVkKpIKdrfiw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "slash": "^3.0.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=8.0.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "rollup": "^1.20.0||^2.0.0" } }, - "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.5.tgz", - "integrity": "sha512-ldxCkW180qbrvyCVDzAUZqB0TAeF8W/vGJoRcaf75awm6By+PxfJKvuqVAnq8N9wz5Xa6mSpM19OfVKKVmGHSQ==", + "node_modules/@rollup/plugin-commonjs": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-21.0.1.tgz", + "integrity": "sha512-EA+g22lbNJ8p5kuZJUYyhhDK7WgJckW5g4pNN7n4mAFUM96VuwUnNT3xr2Db2iCZPI1pJPbGyfT5mS9T1dHfMg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@rollup/pluginutils": "^3.1.0", + "commondir": "^1.0.1", + "estree-walker": "^2.0.1", + "glob": "^7.1.6", + "is-reference": "^1.2.1", + "magic-string": "^0.25.7", + "resolve": "^1.17.0" }, "engines": { - "node": ">=6.9.0" + "node": ">= 8.0.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "rollup": "^2.38.3" } }, - "node_modules/@babel/plugin-transform-typescript": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.1.tgz", - "integrity": "sha512-NO4XoryBng06jjw/qWEU2LhcLJr1tWkhpMam/H4eas/CDKMX/b2/Ylb6EI256Y7+FVPCawwSM1rrJNOpDiz+Lg==", + "node_modules/@rollup/plugin-json": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-4.1.0.tgz", + "integrity": "sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.16.0", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-typescript": "^7.16.0" - }, - "engines": { - "node": ">=6.9.0" + "@rollup/pluginutils": "^3.0.8" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "rollup": "^1.20.0 || ^2.0.0" } }, - "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.5.tgz", - "integrity": "sha512-shiCBHTIIChGLdyojsKQjoAyB8MBwat25lKM7MJjbe1hE0bgIppD+LX9afr41lLHOhqceqeWl4FkLp+Bgn9o1Q==", + "node_modules/@rollup/plugin-multi-entry": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-multi-entry/-/plugin-multi-entry-4.1.0.tgz", + "integrity": "sha512-nellK5pr50W0JA2+bDJbG8F79GBP802J40YRoC0wyfpTAeAn5mJ4eaFiB/MN+YoX9hgb/6RJoZl9leDjZnUFKw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@rollup/plugin-virtual": "^2.0.3", + "matched": "^5.0.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=10.0.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "rollup": "^1.20.0 || ^2.0.0" } }, - "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.5.tgz", - "integrity": "sha512-GTJ4IW012tiPEMMubd7sD07iU9O/LOo8Q/oU4xNhcaq0Xn8+6TcUQaHtC8YxySo1T+ErQ8RaWogIEeFhKGNPzw==", + "node_modules/@rollup/plugin-node-resolve": { + "version": "13.1.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.1.3.tgz", + "integrity": "sha512-BdxNk+LtmElRo5d06MGY4zoepyrXX1tkzX2hrnPEZ53k78GuOMWLqmJDGIIOPwVRIFZrLQOo+Yr6KtCuLIA0AQ==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5" + "@rollup/pluginutils": "^3.1.0", + "@types/resolve": "1.17.1", + "builtin-modules": "^3.1.0", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.19.0" }, "engines": { - "node": ">=6.9.0" + "node": ">= 10.0.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "rollup": "^2.42.0" } }, - "node_modules/@babel/preset-env": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.16.5.tgz", - "integrity": "sha512-MiJJW5pwsktG61NDxpZ4oJ1CKxM1ncam9bzRtx9g40/WkLRkxFP6mhpkYV0/DxcciqoiHicx291+eUQrXb/SfQ==", + "node_modules/@rollup/plugin-typescript": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-8.3.0.tgz", + "integrity": "sha512-I5FpSvLbtAdwJ+naznv+B4sjXZUcIvLLceYpITAn7wAP8W0wqc5noLdGIp9HGVntNhRWXctwPYrSSFQxtl0FPA==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.16.4", - "@babel/helper-compilation-targets": "^7.16.3", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-validator-option": "^7.14.5", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.16.2", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.16.0", - "@babel/plugin-proposal-async-generator-functions": "^7.16.5", - "@babel/plugin-proposal-class-properties": "^7.16.5", - "@babel/plugin-proposal-class-static-block": "^7.16.5", - "@babel/plugin-proposal-dynamic-import": "^7.16.5", - "@babel/plugin-proposal-export-namespace-from": "^7.16.5", - "@babel/plugin-proposal-json-strings": "^7.16.5", - "@babel/plugin-proposal-logical-assignment-operators": "^7.16.5", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.5", - "@babel/plugin-proposal-numeric-separator": "^7.16.5", - "@babel/plugin-proposal-object-rest-spread": "^7.16.5", - "@babel/plugin-proposal-optional-catch-binding": "^7.16.5", - "@babel/plugin-proposal-optional-chaining": "^7.16.5", - "@babel/plugin-proposal-private-methods": "^7.16.5", - "@babel/plugin-proposal-private-property-in-object": "^7.16.5", - "@babel/plugin-proposal-unicode-property-regex": "^7.16.5", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.16.5", - "@babel/plugin-transform-async-to-generator": "^7.16.5", - "@babel/plugin-transform-block-scoped-functions": "^7.16.5", - "@babel/plugin-transform-block-scoping": "^7.16.5", - "@babel/plugin-transform-classes": "^7.16.5", - "@babel/plugin-transform-computed-properties": "^7.16.5", - "@babel/plugin-transform-destructuring": "^7.16.5", - "@babel/plugin-transform-dotall-regex": "^7.16.5", - "@babel/plugin-transform-duplicate-keys": "^7.16.5", - "@babel/plugin-transform-exponentiation-operator": "^7.16.5", - "@babel/plugin-transform-for-of": "^7.16.5", - "@babel/plugin-transform-function-name": "^7.16.5", - "@babel/plugin-transform-literals": "^7.16.5", - "@babel/plugin-transform-member-expression-literals": "^7.16.5", - "@babel/plugin-transform-modules-amd": "^7.16.5", - "@babel/plugin-transform-modules-commonjs": "^7.16.5", - "@babel/plugin-transform-modules-systemjs": "^7.16.5", - "@babel/plugin-transform-modules-umd": "^7.16.5", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.16.5", - "@babel/plugin-transform-new-target": "^7.16.5", - "@babel/plugin-transform-object-super": "^7.16.5", - "@babel/plugin-transform-parameters": "^7.16.5", - "@babel/plugin-transform-property-literals": "^7.16.5", - "@babel/plugin-transform-regenerator": "^7.16.5", - "@babel/plugin-transform-reserved-words": "^7.16.5", - "@babel/plugin-transform-shorthand-properties": "^7.16.5", - "@babel/plugin-transform-spread": "^7.16.5", - "@babel/plugin-transform-sticky-regex": "^7.16.5", - "@babel/plugin-transform-template-literals": "^7.16.5", - "@babel/plugin-transform-typeof-symbol": "^7.16.5", - "@babel/plugin-transform-unicode-escapes": "^7.16.5", - "@babel/plugin-transform-unicode-regex": "^7.16.5", - "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.16.0", - "babel-plugin-polyfill-corejs2": "^0.3.0", - "babel-plugin-polyfill-corejs3": "^0.4.0", - "babel-plugin-polyfill-regenerator": "^0.3.0", - "core-js-compat": "^3.19.1", - "semver": "^6.3.0" + "@rollup/pluginutils": "^3.1.0", + "resolve": "^1.17.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=8.0.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "rollup": "^2.14.0", + "tslib": "*", + "typescript": ">=3.7.0" } }, - "node_modules/@babel/preset-modules": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", - "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", + "node_modules/@rollup/plugin-virtual": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-virtual/-/plugin-virtual-2.0.3.tgz", + "integrity": "sha512-pw6ziJcyjZtntQ//bkad9qXaBx665SgEL8C8KI5wO8G5iU5MPxvdWrQyVaAvjojGm9tJoS8M9Z/EEepbqieYmw==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "rollup": "^1.20.0||^2.0.0" } }, - "node_modules/@babel/preset-typescript": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.16.5.tgz", - "integrity": "sha512-lmAWRoJ9iOSvs3DqOndQpj8XqXkzaiQs50VG/zESiI9D3eoZhGriU675xNCr0UwvsuXrhMAGvyk1w+EVWF3u8Q==", + "node_modules/@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-validator-option": "^7.14.5", - "@babel/plugin-transform-typescript": "^7.16.1" + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" }, "engines": { - "node": ">=6.9.0" + "node": ">= 8.0.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "rollup": "^1.20.0||^2.0.0" } }, - "node_modules/@babel/runtime": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz", - "integrity": "sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==", + "node_modules/@rollup/pluginutils/node_modules/estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "dev": true + }, + "node_modules/@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "dev": true, "dependencies": { - "regenerator-runtime": "^0.13.4" - }, - "engines": { - "node": ">=6.9.0" + "type-detect": "4.0.8" } }, - "node_modules/@babel/template": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.0.tgz", - "integrity": "sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A==", + "node_modules/@sinonjs/fake-timers": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", + "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.16.0", - "@babel/parser": "^7.16.0", - "@babel/types": "^7.16.0" - }, - "engines": { - "node": ">=6.9.0" + "@sinonjs/commons": "^1.7.0" } }, - "node_modules/@babel/traverse": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.5.tgz", - "integrity": "sha512-FOCODAzqUMROikDYLYxl4nmwiLlu85rNqBML/A5hKRVXG2LV8d0iMqgPzdYTcIpjZEBB7D6UDU9vxRZiriASdQ==", - "dev": true, + "node_modules/@solana/buffer-layout": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.0.tgz", + "integrity": "sha512-lR0EMP2HC3+Mxwd4YcnZb0smnaDw7Bl2IQWZiTevRH5ZZBZn6VRWn3/92E3qdU4SSImJkA6IDHawOHAnx/qUvQ==", "dependencies": { - "@babel/code-frame": "^7.16.0", - "@babel/generator": "^7.16.5", - "@babel/helper-environment-visitor": "^7.16.5", - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-hoist-variables": "^7.16.0", - "@babel/helper-split-export-declaration": "^7.16.0", - "@babel/parser": "^7.16.5", - "@babel/types": "^7.16.0", - "debug": "^4.1.0", - "globals": "^11.1.0" + "buffer": "~6.0.3" }, "engines": { - "node": ">=6.9.0" + "node": ">=5.10" } }, - "node_modules/@babel/types": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.8.tgz", - "integrity": "sha512-smN2DQc5s4M7fntyjGtyIPbRJv6wW4rU/94fmYJ7PKQuZkC0qGMHXJbg6sNGt12JmVr4k5YaptI/XtiLJBnmIg==", - "dev": true, + "node_modules/@solana/spl-token": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.1.8.tgz", + "integrity": "sha512-LZmYCKcPQDtJgecvWOgT/cnoIQPWjdH+QVyzPcFvyDUiT0DiRjZaam4aqNUyvchLFhzgunv3d9xOoyE34ofdoQ==", "dependencies": { - "@babel/helper-validator-identifier": "^7.16.7", - "to-fast-properties": "^2.0.0" + "@babel/runtime": "^7.10.5", + "@solana/web3.js": "^1.21.0", + "bn.js": "^5.1.0", + "buffer": "6.0.3", + "buffer-layout": "^1.2.0", + "dotenv": "10.0.0" }, "engines": { - "node": ">=6.9.0" + "node": ">= 10" } }, - "node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "node_modules/@eslint/eslintrc": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz", - "integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==", - "dev": true, + "node_modules/@solana/web3.js": { + "version": "1.34.0", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.34.0.tgz", + "integrity": "sha512-6QvqN2DqEELvuV+5yUQM8P9fRiSG+6SzQ58HjumJqODu14r7eu5HXVWEymvKAvMLGME+0TmAdJHjw9xD5NgUWA==", "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.2.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" + "@babel/runtime": "^7.12.5", + "@ethersproject/sha2": "^5.5.0", + "@solana/buffer-layout": "^3.0.0", + "bn.js": "^5.0.0", + "borsh": "^0.4.0", + "bs58": "^4.0.1", + "buffer": "6.0.1", + "cross-fetch": "^3.1.4", + "jayson": "^3.4.4", + "js-sha3": "^0.8.0", + "rpc-websockets": "^7.4.2", + "secp256k1": "^4.0.2", + "superstruct": "^0.14.2", + "tweetnacl": "^1.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=12.20.0" } }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", - "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", - "dev": true, + "node_modules/@solana/web3.js/node_modules/@solana/buffer-layout": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-3.0.0.tgz", + "integrity": "sha512-MVdgAKKL39tEs0l8je0hKaXLQFb7Rdfb0Xg2LjFZd8Lfdazkg6xiS98uAZrEKvaoF3i4M95ei9RydkGIDMeo3w==", "dependencies": { - "type-fest": "^0.20.2" + "buffer": "~6.0.3" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=5.10" } }, - "node_modules/@eslint/eslintrc/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@ethersproject/bytes": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.5.0.tgz", - "integrity": "sha512-ABvc7BHWhZU9PNM/tANm/Qx4ostPGadAuQzWTr3doklZOhDlmcBqclrQe/ZXUIj3K8wC28oYeuRa+A37tX9kog==", + "node_modules/@solana/web3.js/node_modules/@solana/buffer-layout/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "funding": [ { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + "type": "github", + "url": "https://github.com/sponsors/feross" }, { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" } ], "dependencies": { - "@ethersproject/logger": "^5.5.0" + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" } }, - "node_modules/@ethersproject/logger": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.5.0.tgz", - "integrity": "sha512-rIY/6WPm7T8n3qS2vuHTUBPdXHl+rGxWxW5okDfo9J4Z0+gRRZT0msvUdIJkE4/HS29GUMziwGaaKO2bWONBrg==", + "node_modules/@solana/web3.js/node_modules/buffer": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.1.tgz", + "integrity": "sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ==", "funding": [ { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + "type": "github", + "url": "https://github.com/sponsors/feross" }, { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ] - }, - "node_modules/@ethersproject/sha2": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.5.0.tgz", - "integrity": "sha512-B5UBoglbCiHamRVPLA110J+2uqsifpZaTmid2/7W5rbtYVz6gus6/hSDieIU/6gaKIDcOj12WnOdiymEUHIAOA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + "type": "patreon", + "url": "https://www.patreon.com/feross" }, { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" + "type": "consulting", + "url": "https://feross.org/support" } ], "dependencies": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "hash.js": "1.1.7" + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.2.tgz", - "integrity": "sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA==", + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - }, "engines": { - "node": ">=10.10.0" + "node": ">= 6" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "node_modules/@types/babel__core": { + "version": "7.1.18", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.18.tgz", + "integrity": "sha512-S7unDjm/C7z2A2R9NzfKCK1I+BAALDtxEmsJBwlB3EzNfb929ykjL++1CK9LO++EIp2fQrC8O+BwjKvz6UeDyQ==", "dev": true, "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "node_modules/@types/babel__generator": { + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", "dev": true, "dependencies": { - "sprintf-js": "~1.0.2" + "@babel/types": "^7.0.0" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "node_modules/@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", "dev": true, "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" } }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "node_modules/@types/babel__traverse": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", + "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "@babel/types": "^7.3.0" } }, - "node_modules/@jest/console": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.4.6.tgz", - "integrity": "sha512-jauXyacQD33n47A44KrlOVeiXHEXDqapSdfb9kTekOchH/Pd18kBIO1+xxJQRLuG+LUuljFCwTG92ra4NW7SpA==", + "node_modules/@types/bn.js": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", + "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", "dev": true, "dependencies": { - "@jest/types": "^27.4.2", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^27.4.6", - "jest-util": "^27.4.2", - "slash": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "@types/node": "*" } }, - "node_modules/@jest/console/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, + "node_modules/@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "@types/node": "*" } }, - "node_modules/@jest/console/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, + "node_modules/@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.28", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", + "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" } }, - "node_modules/@jest/console/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/@types/graceful-fs": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", + "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", "dev": true, "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" + "@types/node": "*" } }, - "node_modules/@jest/console/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", "dev": true }, - "node_modules/@jest/console/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "@types/istanbul-lib-coverage": "*" } }, - "node_modules/@jest/console/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" + "@types/istanbul-lib-report": "*" } }, - "node_modules/@jest/core": { - "version": "27.4.7", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.4.7.tgz", - "integrity": "sha512-n181PurSJkVMS+kClIFSX/LLvw9ExSb+4IMtD6YnfxZVerw9ANYtW0bPrm0MJu2pfe9SY9FJ9FtQ+MdZkrZwjg==", + "node_modules/@types/jest": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.0.tgz", + "integrity": "sha512-gHl8XuC1RZ8H2j5sHv/JqsaxXkDDM9iDOgu0Wp8sjs4u/snb2PVehyWXJPr+ORA0RPpgw231mnutWI1+0hgjIQ==", "dev": true, "dependencies": { - "@jest/console": "^27.4.6", - "@jest/reporters": "^27.4.6", - "@jest/test-result": "^27.4.6", - "@jest/transform": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-changed-files": "^27.4.2", - "jest-config": "^27.4.7", - "jest-haste-map": "^27.4.6", - "jest-message-util": "^27.4.6", - "jest-regex-util": "^27.4.0", - "jest-resolve": "^27.4.6", - "jest-resolve-dependencies": "^27.4.6", - "jest-runner": "^27.4.6", - "jest-runtime": "^27.4.6", - "jest-snapshot": "^27.4.6", - "jest-util": "^27.4.2", - "jest-validate": "^27.4.6", - "jest-watcher": "^27.4.6", - "micromatch": "^4.0.4", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "jest-diff": "^27.0.0", + "pretty-format": "^27.0.0" } }, - "node_modules/@jest/core/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/@types/json-schema": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "dev": true + }, + "node_modules/@types/lodash": { + "version": "4.14.178", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.178.tgz", + "integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==" + }, + "node_modules/@types/node": { + "version": "17.0.17", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.17.tgz", + "integrity": "sha512-e8PUNQy1HgJGV3iU/Bp2+D/DXh3PYeyli8LgIwsQcs1Ar1LoaWHSIT6Rw+H2rNJmiq6SNWiDytfx8+gYj7wDHw==" + }, + "node_modules/@types/prettier": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.4.tgz", + "integrity": "sha512-ReVR2rLTV1kvtlWFyuot+d1pkpG2Fw/XKE3PDAdj57rbM97ttSp9JZ2UsP+2EHTylra9cUf6JA7tGwW1INzUrA==", + "dev": true + }, + "node_modules/@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" + }, + "node_modules/@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" + }, + "node_modules/@types/resolve": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", + "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", "dev": true, "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "@types/node": "*" } }, - "node_modules/@jest/core/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, + "node_modules/@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "node_modules/@types/ws": { + "version": "7.4.7", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", + "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "@types/node": "*" } }, - "node_modules/@jest/core/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", "dev": true, "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" + "@types/yargs-parser": "*" } }, - "node_modules/@jest/core/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "node_modules/@types/yargs-parser": { + "version": "20.2.1", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", + "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", "dev": true }, - "node_modules/@jest/core/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.11.0.tgz", + "integrity": "sha512-HJh33bgzXe6jGRocOj4FmefD7hRY4itgjzOrSs3JPrTNXsX7j5+nQPciAUj/1nZtwo2kAc3C75jZO+T23gzSGw==", "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.11.0", + "@typescript-eslint/type-utils": "5.11.0", + "@typescript-eslint/utils": "5.11.0", + "debug": "^4.3.2", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.1.8", + "regexpp": "^3.2.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, "engines": { - "node": ">=8" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@jest/core/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/@typescript-eslint/parser": { + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.11.0.tgz", + "integrity": "sha512-x0DCjetHZYBRovJdr3U0zG9OOdNXUaFLJ82ehr1AlkArljJuwEsgnud+Q7umlGDFLFrs8tU8ybQDFocp/eX8mQ==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "@typescript-eslint/scope-manager": "5.11.0", + "@typescript-eslint/types": "5.11.0", + "@typescript-eslint/typescript-estree": "5.11.0", + "debug": "^4.3.2" }, "engines": { - "node": ">=8" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@jest/environment": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.4.6.tgz", - "integrity": "sha512-E6t+RXPfATEEGVidr84WngLNWZ8ffCPky8RqqRK6u1Bn0LK92INe0MDttyPl/JOzaq92BmDzOeuqk09TvM22Sg==", + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.11.0.tgz", + "integrity": "sha512-z+K4LlahDFVMww20t/0zcA7gq/NgOawaLuxgqGRVKS0PiZlCTIUtX0EJbC0BK1JtR4CelmkPK67zuCgpdlF4EA==", "dev": true, "dependencies": { - "@jest/fake-timers": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/node": "*", - "jest-mock": "^27.4.6" + "@typescript-eslint/types": "5.11.0", + "@typescript-eslint/visitor-keys": "5.11.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@jest/fake-timers": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.4.6.tgz", - "integrity": "sha512-mfaethuYF8scV8ntPpiVGIHQgS0XIALbpY2jt2l7wb/bvq4Q5pDLk4EP4D7SAvYT1QrPOPVZAtbdGAOOyIgs7A==", + "node_modules/@typescript-eslint/type-utils": { + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.11.0.tgz", + "integrity": "sha512-wDqdsYO6ofLaD4DsGZ0jGwxp4HrzD2YKulpEZXmgN3xo4BHJwf7kq49JTRpV0Gx6bxkSUmc9s0EIK1xPbFFpIA==", "dev": true, "dependencies": { - "@jest/types": "^27.4.2", - "@sinonjs/fake-timers": "^8.0.1", - "@types/node": "*", - "jest-message-util": "^27.4.6", - "jest-mock": "^27.4.6", - "jest-util": "^27.4.2" + "@typescript-eslint/utils": "5.11.0", + "debug": "^4.3.2", + "tsutils": "^3.21.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@jest/globals": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.4.6.tgz", - "integrity": "sha512-kAiwMGZ7UxrgPzu8Yv9uvWmXXxsy0GciNejlHvfPIfWkSxChzv6bgTS3YqBkGuHcis+ouMFI2696n2t+XYIeFw==", + "node_modules/@typescript-eslint/types": { + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.11.0.tgz", + "integrity": "sha512-cxgBFGSRCoBEhvSVLkKw39+kMzUKHlJGVwwMbPcTZX3qEhuXhrjwaZXWMxVfxDgyMm+b5Q5b29Llo2yow8Y7xQ==", "dev": true, - "dependencies": { - "@jest/environment": "^27.4.6", - "@jest/types": "^27.4.2", - "expect": "^27.4.6" - }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@jest/reporters": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.4.6.tgz", - "integrity": "sha512-+Zo9gV81R14+PSq4wzee4GC2mhAN9i9a7qgJWL90Gpx7fHYkWpTBvwWNZUXvJByYR9tAVBdc8VxDWqfJyIUrIQ==", + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.11.0.tgz", + "integrity": "sha512-yVH9hKIv3ZN3lw8m/Jy5I4oXO4ZBMqijcXCdA4mY8ull6TPTAoQnKKrcZ0HDXg7Bsl0Unwwx7jcXMuNZc0m4lg==", "dev": true, "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.4.6", - "@jest/test-result": "^27.4.6", - "@jest/transform": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.4", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-haste-map": "^27.4.6", - "jest-resolve": "^27.4.6", - "jest-util": "^27.4.2", - "jest-worker": "^27.4.6", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^8.1.0" + "@typescript-eslint/types": "5.11.0", + "@typescript-eslint/visitor-keys": "5.11.0", + "debug": "^4.3.2", + "globby": "^11.0.4", + "is-glob": "^4.0.3", + "semver": "^7.3.5", + "tsutils": "^3.21.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependenciesMeta": { - "node-notifier": { + "typescript": { "optional": true } } }, - "node_modules/@jest/reporters/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/@typescript-eslint/utils": { + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.11.0.tgz", + "integrity": "sha512-g2I480tFE1iYRDyMhxPAtLQ9HAn0jjBtipgTCZmd9I9s11OV8CTsG+YfFciuNDcHqm4csbAgC2aVZCHzLxMSUw==", "dev": true, "dependencies": { - "color-convert": "^2.0.1" + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.11.0", + "@typescript-eslint/types": "5.11.0", + "@typescript-eslint/typescript-estree": "5.11.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" }, "engines": { - "node": ">=8" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/@jest/reporters/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.11.0.tgz", + "integrity": "sha512-E8w/vJReMGuloGxJDkpPlGwhxocxOpSVgSvjiLO5IxZPmxZF30weOeJYyPSEACwM+X4NziYS9q+WkN/2DHYQwA==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@typescript-eslint/types": "5.11.0", + "eslint-visitor-keys": "^3.0.0" }, "engines": { - "node": ">=10" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@jest/reporters/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/abab": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", "dev": true, - "dependencies": { - "color-name": "~1.1.4" + "bin": { + "acorn": "bin/acorn" }, "engines": { - "node": ">=7.0.0" + "node": ">=0.4.0" } }, - "node_modules/@jest/reporters/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "node_modules/acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dev": true, + "dependencies": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } }, - "node_modules/@jest/reporters/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/acorn-globals/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true, + "bin": { + "acorn": "bin/acorn" + }, "engines": { - "node": ">=8" + "node": ">=0.4.0" } }, - "node_modules/@jest/reporters/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, - "engines": { - "node": ">=0.10.0" + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/@jest/reporters/node_modules/supports-color": { + "node_modules/acorn-walk": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, "engines": { - "node": ">=8" + "node": ">=0.4.0" } }, - "node_modules/@jest/source-map": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.4.0.tgz", - "integrity": "sha512-Ntjx9jzP26Bvhbm93z/AKcPRj/9wrkI88/gK60glXDx1q+IeI0rf7Lw2c89Ch6ofonB0On/iRDreQuQ6te9pgQ==", + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dev": true, "dependencies": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" + "debug": "4" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">= 6.0.0" } }, - "node_modules/@jest/source-map/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@jest/test-result": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.4.6.tgz", - "integrity": "sha512-fi9IGj3fkOrlMmhQqa/t9xum8jaJOOAi/lZlm6JXSc55rJMXKHxNDN1oCP39B0/DhNOa2OMupF9BcKZnNtXMOQ==", + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, "dependencies": { - "@jest/console": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "type-fest": "^0.21.3" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@jest/test-sequencer": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.4.6.tgz", - "integrity": "sha512-3GL+nsf6E1PsyNsJuvPyIz+DwFuCtBdtvPpm/LMXVkBJbdFvQYCDpccYT56qq5BGniXWlE81n2qk1sdXfZebnw==", + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, - "dependencies": { - "@jest/test-result": "^27.4.6", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.6", - "jest-runtime": "^27.4.6" - }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@jest/transform": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.4.6.tgz", - "integrity": "sha512-9MsufmJC8t5JTpWEQJ0OcOOAXaH5ioaIX6uHVBLBMoCZPfKKQF+EqP8kACAvCZ0Y1h2Zr3uOccg8re+Dr5jxyw==", + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, - "dependencies": { - "@babel/core": "^7.1.0", - "@jest/types": "^27.4.2", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.6", - "jest-regex-util": "^27.4.0", - "jest-util": "^27.4.2", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=8" } }, - "node_modules/@jest/transform/node_modules/ansi-styles": { + "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", @@ -2320,4463 +1893,365 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@jest/transform/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">= 8" } }, - "node_modules/@jest/transform/node_modules/color-convert": { + "node_modules/argparse": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/transform/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "node_modules/@jest/transform/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, "engines": { "node": ">=8" } }, - "node_modules/@jest/transform/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "node_modules/babel-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", + "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", "dev": true, + "dependencies": { + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^27.5.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" } }, - "node_modules/@jest/transform/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" }, "engines": { "node": ">=8" } }, - "node_modules/@jest/types": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.4.2.tgz", - "integrity": "sha512-j35yw0PMTPpZsUoOBiuHzr1zTYoad1cVIE0ajEjcrJONxxrko/IRGKkXx3os0Nsi4Hu3+5VmDbVfq5WhG/pWAg==", + "node_modules/babel-plugin-jest-hoist": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", + "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@jest/types/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", "dev": true, "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@jest/types/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/babel-preset-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", + "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "babel-plugin-jest-hoist": "^27.5.1", + "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { - "node": ">=10" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@jest/types/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base-x": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/types/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/@jest/types/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/types/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@project-serum/borsh": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@project-serum/borsh/-/borsh-0.2.3.tgz", - "integrity": "sha512-lH9zEYADZE3cxrgiFym8+jbUE3NM/LH+WOKYcUjs65CT10Q64Hv45bcAAa/phwYk4Tpz0uQ1x+ergFaAoGt67Q==", - "dependencies": { - "bn.js": "^5.1.2", - "buffer-layout": "^1.2.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@solana/web3.js": "^1.2.0" - } - }, - "node_modules/@rollup/plugin-alias": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-3.1.9.tgz", - "integrity": "sha512-QI5fsEvm9bDzt32k39wpOwZhVzRcL5ydcffUHMyLVaVaLeC70I8TJZ17F1z1eMoLu4E/UOcH9BWVkKpIKdrfiw==", - "dev": true, - "dependencies": { - "slash": "^3.0.0" - }, - "engines": { - "node": ">=8.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0" - } - }, - "node_modules/@rollup/plugin-commonjs": { - "version": "21.0.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-21.0.1.tgz", - "integrity": "sha512-EA+g22lbNJ8p5kuZJUYyhhDK7WgJckW5g4pNN7n4mAFUM96VuwUnNT3xr2Db2iCZPI1pJPbGyfT5mS9T1dHfMg==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^3.1.0", - "commondir": "^1.0.1", - "estree-walker": "^2.0.1", - "glob": "^7.1.6", - "is-reference": "^1.2.1", - "magic-string": "^0.25.7", - "resolve": "^1.17.0" - }, - "engines": { - "node": ">= 8.0.0" - }, - "peerDependencies": { - "rollup": "^2.38.3" - } - }, - "node_modules/@rollup/plugin-commonjs/node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true - }, - "node_modules/@rollup/plugin-json": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-4.1.0.tgz", - "integrity": "sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^3.0.8" - }, - "peerDependencies": { - "rollup": "^1.20.0 || ^2.0.0" - } - }, - "node_modules/@rollup/plugin-multi-entry": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-multi-entry/-/plugin-multi-entry-4.1.0.tgz", - "integrity": "sha512-nellK5pr50W0JA2+bDJbG8F79GBP802J40YRoC0wyfpTAeAn5mJ4eaFiB/MN+YoX9hgb/6RJoZl9leDjZnUFKw==", - "dev": true, - "dependencies": { - "@rollup/plugin-virtual": "^2.0.3", - "matched": "^5.0.0" - }, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0 || ^2.0.0" - } - }, - "node_modules/@rollup/plugin-node-resolve": { - "version": "13.1.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.1.3.tgz", - "integrity": "sha512-BdxNk+LtmElRo5d06MGY4zoepyrXX1tkzX2hrnPEZ53k78GuOMWLqmJDGIIOPwVRIFZrLQOo+Yr6KtCuLIA0AQ==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^3.1.0", - "@types/resolve": "1.17.1", - "builtin-modules": "^3.1.0", - "deepmerge": "^4.2.2", - "is-module": "^1.0.0", - "resolve": "^1.19.0" - }, - "engines": { - "node": ">= 10.0.0" - }, - "peerDependencies": { - "rollup": "^2.42.0" - } - }, - "node_modules/@rollup/plugin-typescript": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-8.3.0.tgz", - "integrity": "sha512-I5FpSvLbtAdwJ+naznv+B4sjXZUcIvLLceYpITAn7wAP8W0wqc5noLdGIp9HGVntNhRWXctwPYrSSFQxtl0FPA==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^3.1.0", - "resolve": "^1.17.0" - }, - "engines": { - "node": ">=8.0.0" - }, - "peerDependencies": { - "rollup": "^2.14.0", - "tslib": "*", - "typescript": ">=3.7.0" - } - }, - "node_modules/@rollup/plugin-virtual": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-virtual/-/plugin-virtual-2.0.3.tgz", - "integrity": "sha512-pw6ziJcyjZtntQ//bkad9qXaBx665SgEL8C8KI5wO8G5iU5MPxvdWrQyVaAvjojGm9tJoS8M9Z/EEepbqieYmw==", - "dev": true, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0" - } - }, - "node_modules/@rollup/pluginutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", - "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", - "dev": true, - "dependencies": { - "@types/estree": "0.0.39", - "estree-walker": "^1.0.1", - "picomatch": "^2.2.2" - }, - "engines": { - "node": ">= 8.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0" - } - }, - "node_modules/@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", - "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, - "node_modules/@solana/buffer-layout": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.0.tgz", - "integrity": "sha512-lR0EMP2HC3+Mxwd4YcnZb0smnaDw7Bl2IQWZiTevRH5ZZBZn6VRWn3/92E3qdU4SSImJkA6IDHawOHAnx/qUvQ==", - "dependencies": { - "buffer": "~6.0.3" - }, - "engines": { - "node": ">=5.10" - } - }, - "node_modules/@solana/spl-token": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.1.8.tgz", - "integrity": "sha512-LZmYCKcPQDtJgecvWOgT/cnoIQPWjdH+QVyzPcFvyDUiT0DiRjZaam4aqNUyvchLFhzgunv3d9xOoyE34ofdoQ==", - "dependencies": { - "@babel/runtime": "^7.10.5", - "@solana/web3.js": "^1.21.0", - "bn.js": "^5.1.0", - "buffer": "6.0.3", - "buffer-layout": "^1.2.0", - "dotenv": "10.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/@solana/web3.js": { - "version": "1.31.0", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.31.0.tgz", - "integrity": "sha512-7nHHx1JNFnrt15e9y8m38I/EJCbaB+bFC3KZVM1+QhybCikFxGMtGA5r7PDC3GEL1R2RZA8yKoLkDKo3vzzqnw==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "@ethersproject/sha2": "^5.5.0", - "@solana/buffer-layout": "^3.0.0", - "bn.js": "^5.0.0", - "borsh": "^0.4.0", - "bs58": "^4.0.1", - "buffer": "6.0.1", - "cross-fetch": "^3.1.4", - "jayson": "^3.4.4", - "js-sha3": "^0.8.0", - "rpc-websockets": "^7.4.2", - "secp256k1": "^4.0.2", - "superstruct": "^0.14.2", - "tweetnacl": "^1.0.0" - }, - "engines": { - "node": ">=12.20.0" - } - }, - "node_modules/@solana/web3.js/node_modules/@solana/buffer-layout": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-3.0.0.tgz", - "integrity": "sha512-MVdgAKKL39tEs0l8je0hKaXLQFb7Rdfb0Xg2LjFZd8Lfdazkg6xiS98uAZrEKvaoF3i4M95ei9RydkGIDMeo3w==", - "dependencies": { - "buffer": "~6.0.3" - }, - "engines": { - "node": ">=5.10" - } - }, - "node_modules/@solana/web3.js/node_modules/@solana/buffer-layout/node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/@solana/web3.js/node_modules/buffer": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.1.tgz", - "integrity": "sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@types/babel__core": { - "version": "7.1.17", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.17.tgz", - "integrity": "sha512-6zzkezS9QEIL8yCBvXWxPTJPNuMeECJVxSOhxNY/jfq9LxOTHivaYTqr37n9LknWWRTIkzqH2UilS5QFvfa90A==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", - "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", - "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.3.0" - } - }, - "node_modules/@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", - "dev": true - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.17.27", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.27.tgz", - "integrity": "sha512-e/sVallzUTPdyOTiqi8O8pMdBBphscvI6E4JYaKlja4Lm+zh7UFSSdW5VMkRbhDtmrONqOUHOXRguPsDckzxNA==", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" - } - }, - "node_modules/@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", - "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", - "dev": true - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/jest": { - "version": "27.0.3", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.0.3.tgz", - "integrity": "sha512-cmmwv9t7gBYt7hNKH5Spu7Kuu/DotGa+Ff+JGRKZ4db5eh8PnKS4LuebJ3YLUoyOyIHraTGyULn23YtEAm0VSg==", - "dev": true, - "dependencies": { - "jest-diff": "^27.0.0", - "pretty-format": "^27.0.0" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", - "dev": true - }, - "node_modules/@types/lodash": { - "version": "4.14.178", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.178.tgz", - "integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==" - }, - "node_modules/@types/node": { - "version": "17.0.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.5.tgz", - "integrity": "sha512-w3mrvNXLeDYV1GKTZorGJQivK6XLCoGwpnyJFbJVK/aTBQUxOCaa/GlFAAN3OTDFcb7h5tiFG+YXCO2By+riZw==" - }, - "node_modules/@types/prettier": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.3.tgz", - "integrity": "sha512-QzSuZMBuG5u8HqYz01qtMdg/Jfctlnvj1z/lYnIDXs/golxw0fxtRAHd9KrzjR7Yxz1qVeI00o0kiO3PmVdJ9w==", - "dev": true - }, - "node_modules/@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" - }, - "node_modules/@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" - }, - "node_modules/@types/resolve": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", - "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/stack-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", - "dev": true - }, - "node_modules/@types/ws": { - "version": "7.4.7", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", - "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/yargs": { - "version": "16.0.4", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", - "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", - "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", - "dev": true - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.8.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.8.1.tgz", - "integrity": "sha512-wTZ5oEKrKj/8/366qTM366zqhIKAp6NCMweoRONtfuC07OAU9nVI2GZZdqQ1qD30WAAtcPdkH+npDwtRFdp4Rw==", - "dev": true, - "dependencies": { - "@typescript-eslint/experimental-utils": "5.8.1", - "@typescript-eslint/scope-manager": "5.8.1", - "debug": "^4.3.2", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", - "regexpp": "^3.2.0", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/experimental-utils": { - "version": "5.8.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.8.1.tgz", - "integrity": "sha512-fbodVnjIDU4JpeXWRDsG5IfIjYBxEvs8EBO8W1+YVdtrc2B9ppfof5sZhVEDOtgTfFHnYQJDI8+qdqLYO4ceww==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.8.1", - "@typescript-eslint/types": "5.8.1", - "@typescript-eslint/typescript-estree": "5.8.1", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "5.8.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.8.1.tgz", - "integrity": "sha512-K1giKHAjHuyB421SoXMXFHHVI4NdNY603uKw92++D3qyxSeYvC10CBJ/GE5Thpo4WTUvu1mmJI2/FFkz38F2Gw==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "5.8.1", - "@typescript-eslint/types": "5.8.1", - "@typescript-eslint/typescript-estree": "5.8.1", - "debug": "^4.3.2" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.8.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.8.1.tgz", - "integrity": "sha512-DGxJkNyYruFH3NIZc3PwrzwOQAg7vvgsHsHCILOLvUpupgkwDZdNq/cXU3BjF4LNrCsVg0qxEyWasys5AiJ85Q==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.8.1", - "@typescript-eslint/visitor-keys": "5.8.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "5.8.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.8.1.tgz", - "integrity": "sha512-L/FlWCCgnjKOLefdok90/pqInkomLnAcF9UAzNr+DSqMC3IffzumHTQTrINXhP1gVp9zlHiYYjvozVZDPleLcA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.8.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.8.1.tgz", - "integrity": "sha512-26lQ8l8tTbG7ri7xEcCFT9ijU5Fk+sx/KRRyyzCv7MQ+rZZlqiDPtMKWLC8P7o+dtCnby4c+OlxuX1tp8WfafQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.8.1", - "@typescript-eslint/visitor-keys": "5.8.1", - "debug": "^4.3.2", - "globby": "^11.0.4", - "is-glob": "^4.0.3", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.8.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.8.1.tgz", - "integrity": "sha512-SWgiWIwocK6NralrJarPZlWdr0hZnj5GXHIgfdm8hNkyKvpeQuFyLP6YjSIe9kf3YBIfU6OHSZLYkQ+smZwtNg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.8.1", - "eslint-visitor-keys": "^3.0.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/abab": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", - "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", - "dev": true - }, - "node_modules/acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "dev": true, - "dependencies": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } - }, - "node_modules/acorn-globals/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/array-includes": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", - "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/array.prototype.flatmap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.5.tgz", - "integrity": "sha512-08u6rVyi1Lj7oqWbS9nUxliETrtIROT4XGTA4D/LWGten6E3ocm7cy9SIrmNHOL5XVbVuckUp3X6Xyg8/zpvHA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "node_modules/babel-jest": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.4.6.tgz", - "integrity": "sha512-qZL0JT0HS1L+lOuH+xC2DVASR3nunZi/ozGhpgauJHgmI7f8rudxf6hUjEHympdQ/J64CdKmPkgfJ+A3U6QCrg==", - "dev": true, - "dependencies": { - "@jest/transform": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^27.4.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "slash": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.8.0" - } - }, - "node_modules/babel-jest/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/babel-jest/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/babel-jest/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/babel-jest/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/babel-jest/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-jest/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", - "dev": true, - "dependencies": { - "object.assign": "^4.1.0" - } - }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-jest-hoist": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.4.0.tgz", - "integrity": "sha512-Jcu7qS4OX5kTWBc45Hz7BMmgXuJqRnhatqpUhnzGC3OBYpOmf2tv6jFNwZpwM7wU7MUuv2r9IPS/ZlYOuburVw==", - "dev": true, - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.0.tgz", - "integrity": "sha512-wMDoBJ6uG4u4PNFh72Ty6t3EgfA91puCuAwKIazbQlci+ENb/UU9A3xG5lutjUIiXCIn1CY5L15r9LimiJyrSA==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.13.11", - "@babel/helper-define-polyfill-provider": "^0.3.0", - "semver": "^6.1.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.4.0.tgz", - "integrity": "sha512-YxFreYwUfglYKdLUGvIF2nJEsGwj+RhWSX/ije3D2vQPOXuyMLMtg/cCGMDpOA7Nd+MwlNdnGODbd2EwUZPlsw==", - "dev": true, - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.0", - "core-js-compat": "^3.18.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.0.tgz", - "integrity": "sha512-dhAPTDLGoMW5/84wkgwiLRwMnio2i1fUe53EuvtKMv0pn2p3S8OCoV1xAzfJPl0KOX7IB89s2ib85vbYiea3jg==", - "dev": true, - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dev": true, - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-preset-jest": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.4.0.tgz", - "integrity": "sha512-NK4jGYpnBvNxcGo7/ZpZJr51jCGT+3bwwpVIDY2oNfTxJJldRtB4VAcYdgp1loDE50ODuTu+yBjpMAswv5tlpg==", - "dev": true, - "dependencies": { - "babel-plugin-jest-hoist": "^27.4.0", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/base-x": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", - "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "node_modules/borsh": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/borsh/-/borsh-0.4.0.tgz", - "integrity": "sha512-aX6qtLya3K0AkT66CmYWCCDr77qsE9arV05OmdFpmat9qu8Pg9J5tBUPDztAW5fNh/d/MyVG/OYziP52Ndzx1g==", - "dependencies": { - "@types/bn.js": "^4.11.5", - "bn.js": "^5.0.0", - "bs58": "^4.0.0", - "text-encoding-utf-8": "^1.0.2" - } - }, - "node_modules/borsh/node_modules/@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" - }, - "node_modules/browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true - }, - "node_modules/browserslist": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", - "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==", - "dev": true, - "dependencies": { - "caniuse-lite": "^1.0.30001286", - "electron-to-chromium": "^1.4.17", - "escalade": "^3.1.1", - "node-releases": "^2.0.1", - "picocolors": "^1.0.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - } - }, - "node_modules/bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", - "dependencies": { - "base-x": "^3.0.2" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "dependencies": { - "node-int64": "^0.4.0" - } - }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/buffer-layout": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/buffer-layout/-/buffer-layout-1.2.2.tgz", - "integrity": "sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==", - "engines": { - "node": ">=4.5" - } - }, - "node_modules/bufferutil": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.5.tgz", - "integrity": "sha512-HTm14iMQKK2FjFLRTM5lAVcyaUzOnqbPtesFIvREgXpJHdQm8bWS+GkQgIkfaBYRHuCnea7w8UVNfwiAQhlr9A==", - "hasInstallScript": true, - "optional": true, - "dependencies": { - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">=6.14.2" - } - }, - "node_modules/builtin-modules": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", - "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001294", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001294.tgz", - "integrity": "sha512-LiMlrs1nSKZ8qkNhpUf5KD0Al1KCBE3zaT7OLOwEkagXMEDij98SiOovn9wxVGQpklk9vVC/pUSqgYmkmKOS8g==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - } - }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/ci-info": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", - "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", - "dev": true - }, - "node_modules/circular-json": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.9.tgz", - "integrity": "sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ==", - "deprecated": "CircularJSON is in maintenance only, flatted is its successor." - }, - "node_modules/cjs-module-lexer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", - "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", - "dev": true - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true, - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", - "dev": true - }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "node_modules/convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.1" - } - }, - "node_modules/convert-source-map/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/core-js-compat": { - "version": "3.20.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.20.1.tgz", - "integrity": "sha512-AVhKZNpqMV3Jz8hU0YEXXE06qoxtQGsAqU0u1neUngz5IusDJRX/ZJ6t3i7mS7QxNyEONbCo14GprkBrxPlTZA==", - "dev": true, - "dependencies": { - "browserslist": "^4.19.1", - "semver": "7.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-js-compat/node_modules/semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/cross-env": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", - "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "bin": { - "cross-env": "src/bin/cross-env.js", - "cross-env-shell": "src/bin/cross-env-shell.js" - }, - "engines": { - "node": ">=10.14", - "npm": ">=6", - "yarn": ">=1" - } - }, - "node_modules/cross-fetch": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz", - "integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==", - "dependencies": { - "node-fetch": "2.6.1" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", - "dev": true - }, - "node_modules/cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dev": true, - "dependencies": { - "cssom": "~0.3.6" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cssstyle/node_modules/cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true - }, - "node_modules/data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dev": true, - "dependencies": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decimal.js": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", - "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", - "dev": true - }, - "node_modules/dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", - "dev": true - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "dependencies": { - "object-keys": "^1.0.12" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/delay": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", - "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/diff-sequences": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.4.0.tgz", - "integrity": "sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww==", - "dev": true, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", - "dev": true, - "dependencies": { - "webidl-conversions": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/domexception/node_modules/webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/dotenv": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", - "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", - "engines": { - "node": ">=10" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.4.30", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.30.tgz", - "integrity": "sha512-609z9sIMxDHg+TcR/VB3MXwH+uwtrYyeAwWc/orhnr90ixs6WVGSrt85CDLGUdNnLqCA7liv426V20EecjvflQ==", - "dev": true - }, - "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/emittery": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", - "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/es-abstract": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", - "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", - "is-string": "^1.0.7", - "is-weakref": "^1.0.1", - "object-inspect": "^1.11.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "node_modules/es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "dependencies": { - "es6-promise": "^4.0.3" - } - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/escodegen": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", - "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", - "dev": true, - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/escodegen/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/escodegen/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/eslint": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.5.0.tgz", - "integrity": "sha512-tVGSkgNbOfiHyVte8bCM8OmX+xG9PzVG/B4UCF60zx7j61WIVY/AqJECDgpLD4DbbESD0e174gOg3ZlrX15GDg==", - "dev": true, - "dependencies": { - "@eslint/eslintrc": "^1.0.5", - "@humanwhocodes/config-array": "^0.9.2", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.0", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.1.0", - "espree": "^9.2.0", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.2.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-plugin-react": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.28.0.tgz", - "integrity": "sha512-IOlFIRHzWfEQQKcAD4iyYDndHwTQiCMcJVJjxempf203jnNLUnW34AXLrV33+nEXoifJE2ZEGmcjKPL8957eSw==", - "dev": true, - "dependencies": { - "array-includes": "^3.1.4", - "array.prototype.flatmap": "^1.2.5", - "doctrine": "^2.1.0", - "estraverse": "^5.3.0", - "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "minimatch": "^3.0.4", - "object.entries": "^1.1.5", - "object.fromentries": "^2.0.5", - "object.hasown": "^1.1.0", - "object.values": "^1.1.5", - "prop-types": "^15.7.2", - "resolve": "^2.0.0-next.3", - "semver": "^6.3.0", - "string.prototype.matchall": "^4.0.6" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" - } - }, - "node_modules/eslint-plugin-react/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-react/node_modules/resolve": { - "version": "2.0.0-next.3", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz", - "integrity": "sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==", - "dev": true, - "dependencies": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/eslint-scope": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.0.tgz", - "integrity": "sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz", - "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/eslint/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/eslint/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/globals": { - "version": "13.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", - "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/espree": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.2.0.tgz", - "integrity": "sha512-oP3utRkynpZWF/F2x/HZJ+AGtnIclaR7z1pYPxy7NYM2fSO6LgK/Rkny8anRSPK/VwEA1eqm2squui0T7ZMOBg==", - "dev": true, - "dependencies": { - "acorn": "^8.6.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^3.1.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estree-walker": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", - "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", - "dev": true - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" - }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/expect": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.4.6.tgz", - "integrity": "sha512-1M/0kAALIaj5LaG66sFJTbRsWTADnylly82cu4bspI0nl+pgP4E6Bh/aqdHlTUjul06K7xQnnrAoqfxVU0+/ag==", - "dev": true, - "dependencies": { - "@jest/types": "^27.4.2", - "jest-get-type": "^27.4.0", - "jest-matcher-utils": "^27.4.6", - "jest-message-util": "^27.4.6" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/eyes": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", - "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=", - "engines": { - "node": "> 0.1.90" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", - "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "node_modules/fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", - "dev": true, - "dependencies": { - "bser": "2.1.1" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz", - "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==", - "dev": true - }, - "node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/globby": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", - "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby/node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", - "dev": true - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "dev": true, - "dependencies": { - "whatwg-encoding": "^1.0.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dev": true, - "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "dev": true, - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "dev": true, - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", - "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", - "dev": true - }, - "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-number-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true - }, - "node_modules/is-reference": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", - "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", - "dev": true, - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "node_modules/isomorphic-ws": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", - "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", - "peerDependencies": { - "ws": "*" - } - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", - "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", - "dev": true, - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-source-maps/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/istanbul-reports": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.3.tgz", - "integrity": "sha512-x9LtDVtfm/t1GFiLl3NffC7hz+I1ragvgX1P/Lg1NlIagifZDKUkuuaAxH/qpwj2IuEfD8G2Bs/UKp+sZ/pKkg==", - "dev": true, - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jayson": { - "version": "3.6.6", - "resolved": "https://registry.npmjs.org/jayson/-/jayson-3.6.6.tgz", - "integrity": "sha512-f71uvrAWTtrwoww6MKcl9phQTC+56AopLyEenWvKVAIMz+q0oVGj6tenLZ7Z6UiPBkJtKLj4kt0tACllFQruGQ==", - "dependencies": { - "@types/connect": "^3.4.33", - "@types/express-serve-static-core": "^4.17.9", - "@types/lodash": "^4.14.159", - "@types/node": "^12.12.54", - "@types/ws": "^7.4.4", - "commander": "^2.20.3", - "delay": "^5.0.0", - "es6-promisify": "^5.0.0", - "eyes": "^0.1.8", - "isomorphic-ws": "^4.0.1", - "json-stringify-safe": "^5.0.1", - "JSONStream": "^1.3.5", - "lodash": "^4.17.20", - "uuid": "^8.3.2", - "ws": "^7.4.5" - }, - "bin": { - "jayson": "bin/jayson.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jayson/node_modules/@types/node": { - "version": "12.20.39", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.39.tgz", - "integrity": "sha512-U7PMwkDmc3bnL0e4U8oA0POpi1vfsYDc+DEUS2+rPxm9NlLcW1dBa5JcRhO633PoPUcCSWMNXrMsqhmAVEo+IQ==" - }, - "node_modules/jest": { - "version": "27.4.7", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.4.7.tgz", - "integrity": "sha512-8heYvsx7nV/m8m24Vk26Y87g73Ba6ueUd0MWed/NXMhSZIm62U/llVbS0PJe1SHunbyXjJ/BqG1z9bFjGUIvTg==", - "dev": true, - "dependencies": { - "@jest/core": "^27.4.7", - "import-local": "^3.0.2", - "jest-cli": "^27.4.7" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-changed-files": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.4.2.tgz", - "integrity": "sha512-/9x8MjekuzUQoPjDHbBiXbNEBauhrPU2ct7m8TfCg69ywt1y/N+yYwGh3gCpnqUS3klYWDU/lSNgv+JhoD2k1A==", - "dev": true, - "dependencies": { - "@jest/types": "^27.4.2", - "execa": "^5.0.0", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-circus": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.4.6.tgz", - "integrity": "sha512-UA7AI5HZrW4wRM72Ro80uRR2Fg+7nR0GESbSI/2M+ambbzVuA63mn5T1p3Z/wlhntzGpIG1xx78GP2YIkf6PhQ==", - "dev": true, - "dependencies": { - "@jest/environment": "^27.4.6", - "@jest/test-result": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "expect": "^27.4.6", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.4.6", - "jest-matcher-utils": "^27.4.6", - "jest-message-util": "^27.4.6", - "jest-runtime": "^27.4.6", - "jest-snapshot": "^27.4.6", - "jest-util": "^27.4.2", - "pretty-format": "^27.4.6", - "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-circus/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-circus/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-circus/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-circus/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-circus/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-circus/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-cli": { - "version": "27.4.7", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.4.7.tgz", - "integrity": "sha512-zREYhvjjqe1KsGV15mdnxjThKNDgza1fhDT+iUsXWLCq3sxe9w5xnvyctcYVT5PcdLSjv7Y5dCwTS3FCF1tiuw==", - "dev": true, - "dependencies": { - "@jest/core": "^27.4.7", - "@jest/test-result": "^27.4.6", - "@jest/types": "^27.4.2", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "import-local": "^3.0.2", - "jest-config": "^27.4.7", - "jest-util": "^27.4.2", - "jest-validate": "^27.4.6", - "prompts": "^2.0.1", - "yargs": "^16.2.0" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-cli/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-cli/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-cli/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-cli/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-cli/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-cli/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-config": { - "version": "27.4.7", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.4.7.tgz", - "integrity": "sha512-xz/o/KJJEedHMrIY9v2ParIoYSrSVY6IVeE4z5Z3i101GoA5XgfbJz+1C8EYPsv7u7f39dS8F9v46BHDhn0vlw==", - "dev": true, - "dependencies": { - "@babel/core": "^7.8.0", - "@jest/test-sequencer": "^27.4.6", - "@jest/types": "^27.4.2", - "babel-jest": "^27.4.6", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-circus": "^27.4.6", - "jest-environment-jsdom": "^27.4.6", - "jest-environment-node": "^27.4.6", - "jest-get-type": "^27.4.0", - "jest-jasmine2": "^27.4.6", - "jest-regex-util": "^27.4.0", - "jest-resolve": "^27.4.6", - "jest-runner": "^27.4.6", - "jest-util": "^27.4.2", - "jest-validate": "^27.4.6", - "micromatch": "^4.0.4", - "pretty-format": "^27.4.6", - "slash": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - } - } - }, - "node_modules/jest-config/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-config/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-config/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-config/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-config/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-config/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-diff": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.4.6.tgz", - "integrity": "sha512-zjaB0sh0Lb13VyPsd92V7HkqF6yKRH9vm33rwBt7rPYrpQvS1nCvlIy2pICbKta+ZjWngYLNn4cCK4nyZkjS/w==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^27.4.0", - "jest-get-type": "^27.4.0", - "pretty-format": "^27.4.6" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-diff/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-diff/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-diff/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-diff/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-diff/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-diff/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-docblock": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.4.0.tgz", - "integrity": "sha512-7TBazUdCKGV7svZ+gh7C8esAnweJoG+SvcF6Cjqj4l17zA2q1cMwx2JObSioubk317H+cjcHgP+7fTs60paulg==", - "dev": true, - "dependencies": { - "detect-newline": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-each": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.4.6.tgz", - "integrity": "sha512-n6QDq8y2Hsmn22tRkgAk+z6MCX7MeVlAzxmZDshfS2jLcaBlyhpF3tZSJLR+kXmh23GEvS0ojMR8i6ZeRvpQcA==", - "dev": true, - "dependencies": { - "@jest/types": "^27.4.2", - "chalk": "^4.0.0", - "jest-get-type": "^27.4.0", - "jest-util": "^27.4.2", - "pretty-format": "^27.4.6" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-each/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-each/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-each/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-each/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-each/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-each/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-environment-jsdom": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.4.6.tgz", - "integrity": "sha512-o3dx5p/kHPbUlRvSNjypEcEtgs6LmvESMzgRFQE6c+Prwl2JLA4RZ7qAnxc5VM8kutsGRTB15jXeeSbJsKN9iA==", - "dev": true, - "dependencies": { - "@jest/environment": "^27.4.6", - "@jest/fake-timers": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/node": "*", - "jest-mock": "^27.4.6", - "jest-util": "^27.4.2", - "jsdom": "^16.6.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-environment-node": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.4.6.tgz", - "integrity": "sha512-yfHlZ9m+kzTKZV0hVfhVu6GuDxKAYeFHrfulmy7Jxwsq4V7+ZK7f+c0XP/tbVDMQW7E4neG2u147hFkuVz0MlQ==", - "dev": true, - "dependencies": { - "@jest/environment": "^27.4.6", - "@jest/fake-timers": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/node": "*", - "jest-mock": "^27.4.6", - "jest-util": "^27.4.2" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-get-type": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.4.0.tgz", - "integrity": "sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ==", - "dev": true, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-haste-map": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.4.6.tgz", - "integrity": "sha512-0tNpgxg7BKurZeFkIOvGCkbmOHbLFf4LUQOxrQSMjvrQaQe3l6E8x6jYC1NuWkGo5WDdbr8FEzUxV2+LWNawKQ==", - "dev": true, - "dependencies": { - "@jest/types": "^27.4.2", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^27.4.0", - "jest-serializer": "^27.4.0", - "jest-util": "^27.4.2", - "jest-worker": "^27.4.6", - "micromatch": "^4.0.4", - "walker": "^1.0.7" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - } - }, - "node_modules/jest-jasmine2": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.4.6.tgz", - "integrity": "sha512-uAGNXF644I/whzhsf7/qf74gqy9OuhvJ0XYp8SDecX2ooGeaPnmJMjXjKt0mqh1Rl5dtRGxJgNrHlBQIBfS5Nw==", - "dev": true, - "dependencies": { - "@jest/environment": "^27.4.6", - "@jest/source-map": "^27.4.0", - "@jest/test-result": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^27.4.6", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.4.6", - "jest-matcher-utils": "^27.4.6", - "jest-message-util": "^27.4.6", - "jest-runtime": "^27.4.6", - "jest-snapshot": "^27.4.6", - "jest-util": "^27.4.2", - "pretty-format": "^27.4.6", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-jasmine2/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-jasmine2/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-jasmine2/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-jasmine2/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-jasmine2/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" + "safe-buffer": "^5.0.1" } }, - "node_modules/jest-jasmine2/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, - "node_modules/jest-leak-detector": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.4.6.tgz", - "integrity": "sha512-kkaGixDf9R7CjHm2pOzfTxZTQQQ2gHTIWKY/JZSiYTc90bZp8kSZnUMS3uLAfwTZwc0tcMRoEX74e14LG1WapA==", - "dev": true, - "dependencies": { - "jest-get-type": "^27.4.0", - "pretty-format": "^27.4.6" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } + "node_modules/bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" }, - "node_modules/jest-matcher-utils": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.4.6.tgz", - "integrity": "sha512-XD4PKT3Wn1LQnRAq7ZsTI0VRuEc9OrCPFiO1XL7bftTGmfNF0DcEwMHRgqiu7NGf8ZoZDREpGrCniDkjt79WbA==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^27.4.6", - "jest-get-type": "^27.4.0", - "pretty-format": "^27.4.6" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node_modules/borsh": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/borsh/-/borsh-0.4.0.tgz", + "integrity": "sha512-aX6qtLya3K0AkT66CmYWCCDr77qsE9arV05OmdFpmat9qu8Pg9J5tBUPDztAW5fNh/d/MyVG/OYziP52Ndzx1g==", + "dependencies": { + "@types/bn.js": "^4.11.5", + "bn.js": "^5.0.0", + "bs58": "^4.0.0", + "text-encoding-utf-8": "^1.0.2" } }, - "node_modules/jest-matcher-utils/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, + "node_modules/borsh/node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "@types/node": "*" } }, - "node_modules/jest-matcher-utils/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/jest-matcher-utils/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, "dependencies": { - "color-name": "~1.1.4" + "fill-range": "^7.0.1" }, "engines": { - "node": ">=7.0.0" + "node": ">=8" } }, - "node_modules/jest-matcher-utils/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" }, - "node_modules/jest-matcher-utils/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } + "node_modules/browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "dev": true }, - "node_modules/jest-matcher-utils/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/browserslist": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", + "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "caniuse-lite": "^1.0.30001286", + "electron-to-chromium": "^1.4.17", + "escalade": "^3.1.1", + "node-releases": "^2.0.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist": "cli.js" }, "engines": { - "node": ">=8" + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" } }, - "node_modules/jest-message-util": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.4.6.tgz", - "integrity": "sha512-0p5szriFU0U74czRSFjH6RyS7UYIAkn/ntwMuOwTGWrQIOh5NzXXrq72LOqIkJKKvFbPq+byZKuBz78fjBERBA==", + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.4.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.4", - "pretty-format": "^27.4.6", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" + "fast-json-stable-stringify": "2.x" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">= 6" } }, - "node_modules/jest-message-util/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, + "node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "base-x": "^3.0.2" } }, - "node_modules/jest-message-util/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node-int64": "^0.4.0" } }, - "node_modules/jest-message-util/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" } }, - "node_modules/jest-message-util/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, - "node_modules/jest-message-util/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-message-util/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, + "node_modules/buffer-layout": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/buffer-layout/-/buffer-layout-1.2.2.tgz", + "integrity": "sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==", "engines": { - "node": ">=8" + "node": ">=4.5" } }, - "node_modules/jest-mock": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.4.6.tgz", - "integrity": "sha512-kvojdYRkst8iVSZ1EJ+vc1RRD9llueBjKzXzeCytH3dMM7zvPV/ULcfI2nr0v0VUgm3Bjt3hBCQvOeaBz+ZTHw==", - "dev": true, + "node_modules/bufferutil": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.6.tgz", + "integrity": "sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw==", + "hasInstallScript": true, + "optional": true, "dependencies": { - "@jest/types": "^27.4.2", - "@types/node": "*" + "node-gyp-build": "^4.3.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=6.14.2" } }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "node_modules/builtin-modules": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", + "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", "dev": true, "engines": { "node": ">=6" }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } - } - }, - "node_modules/jest-regex-util": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.4.0.tgz", - "integrity": "sha512-WeCpMpNnqJYMQoOjm1nTtsgbR4XHAk1u00qDoNBQoykM280+/TmgA5Qh5giC1ecy6a5d4hbSsHzpBtu5yvlbEg==", - "dev": true, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-resolve": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.4.6.tgz", - "integrity": "sha512-SFfITVApqtirbITKFAO7jOVN45UgFzcRdQanOFzjnbd+CACDoyeX7206JyU92l4cRr73+Qy/TlW51+4vHGt+zw==", + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, - "dependencies": { - "@jest/types": "^27.4.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.6", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.4.2", - "jest-validate": "^27.4.6", - "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", - "slash": "^3.0.0" - }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=6" } }, - "node_modules/jest-resolve-dependencies": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.4.6.tgz", - "integrity": "sha512-W85uJZcFXEVZ7+MZqIPCscdjuctruNGXUZ3OHSXOfXR9ITgbUKeHj+uGcies+0SsvI5GtUfTw4dY7u9qjTvQOw==", + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, - "dependencies": { - "@jest/types": "^27.4.2", - "jest-regex-util": "^27.4.0", - "jest-snapshot": "^27.4.6" - }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=6" } - }, - "node_modules/jest-resolve/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001311", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001311.tgz", + "integrity": "sha512-mleTFtFKfykEeW34EyfhGIFjGCqzhh38Y0LhdQ9aWF+HorZTtdgKV/1hEE0NlFkG2ubvisPV6l400tlbPys98A==", + "dev": true, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "type": "opencollective", + "url": "https://opencollective.com/browserslist" } }, - "node_modules/jest-resolve/node_modules/chalk": { + "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", @@ -6792,7 +2267,61 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-resolve/node_modules/color-convert": { + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", + "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", + "dev": true + }, + "node_modules/circular-json": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.9.tgz", + "integrity": "sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ==", + "deprecated": "CircularJSON is in maintenance only, flatted is its successor." + }, + "node_modules/cjs-module-lexer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", + "dev": true + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "dev": true + }, + "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", @@ -6804,3978 +2333,4384 @@ "node": ">=7.0.0" } }, - "node_modules/jest-resolve/node_modules/color-name": { + "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/jest-resolve/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, "engines": { - "node": ">=8" + "node": ">= 0.8" } }, - "node_modules/jest-resolve/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "safe-buffer": "~5.1.1" + } + }, + "node_modules/convert-source-map/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" }, "engines": { - "node": ">=8" + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" } }, - "node_modules/jest-runner": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.4.6.tgz", - "integrity": "sha512-IDeFt2SG4DzqalYBZRgbbPmpwV3X0DcntjezPBERvnhwKGWTW7C5pbbA5lVkmvgteeNfdd/23gwqv3aiilpYPg==", + "node_modules/cross-fetch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", + "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "dependencies": { + "node-fetch": "2.6.7" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "dependencies": { - "@jest/console": "^27.4.6", - "@jest/environment": "^27.4.6", - "@jest/test-result": "^27.4.6", - "@jest/transform": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-docblock": "^27.4.0", - "jest-environment-jsdom": "^27.4.6", - "jest-environment-node": "^27.4.6", - "jest-haste-map": "^27.4.6", - "jest-leak-detector": "^27.4.6", - "jest-message-util": "^27.4.6", - "jest-resolve": "^27.4.6", - "jest-runtime": "^27.4.6", - "jest-util": "^27.4.2", - "jest-worker": "^27.4.6", - "source-map-support": "^0.5.6", - "throat": "^6.0.1" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">= 8" } }, - "node_modules/jest-runner/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "dev": true + }, + "node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", "dev": true, "dependencies": { - "color-convert": "^2.0.1" + "cssom": "~0.3.6" }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-runner/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + }, + "node_modules/data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-runner/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, "dependencies": { - "color-name": "~1.1.4" + "ms": "2.1.2" }, "engines": { - "node": ">=7.0.0" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/jest-runner/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "node_modules/decimal.js": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", + "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", "dev": true }, - "node_modules/jest-runner/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", "dev": true, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/jest-runner/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" + "node_modules/delay": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", + "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==", + "engines": { + "node": ">=10" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, "engines": { "node": ">=8" } }, - "node_modules/jest-runtime": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.4.6.tgz", - "integrity": "sha512-eXYeoR/MbIpVDrjqy5d6cGCFOYBFFDeKaNWqTp0h6E74dK0zLHzASQXJpl5a2/40euBmKnprNLJ0Kh0LCndnWQ==", - "dev": true, - "dependencies": { - "@jest/environment": "^27.4.6", - "@jest/fake-timers": "^27.4.6", - "@jest/globals": "^27.4.6", - "@jest/source-map": "^27.4.0", - "@jest/test-result": "^27.4.6", - "@jest/transform": "^27.4.6", - "@jest/types": "^27.4.2", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "execa": "^5.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.6", - "jest-message-util": "^27.4.6", - "jest-mock": "^27.4.6", - "jest-regex-util": "^27.4.0", - "jest-resolve": "^27.4.6", - "jest-snapshot": "^27.4.6", - "jest-util": "^27.4.2", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - }, + "node_modules/diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "dev": true, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-runtime/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, "dependencies": { - "color-convert": "^2.0.1" + "path-type": "^4.0.0" }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-runtime/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "esutils": "^2.0.2" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">=6.0.0" } }, - "node_modules/jest-runtime/node_modules/color-convert": { + "node_modules/domexception": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", "dev": true, "dependencies": { - "color-name": "~1.1.4" + "webidl-conversions": "^5.0.0" }, "engines": { - "node": ">=7.0.0" + "node": ">=8" } }, - "node_modules/jest-runtime/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-runtime/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/domexception/node_modules/webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", "dev": true, "engines": { "node": ">=8" } }, - "node_modules/jest-runtime/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, + "node_modules/dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", "engines": { - "node": ">=8" + "node": ">=10" } }, - "node_modules/jest-serializer": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.4.0.tgz", - "integrity": "sha512-RDhpcn5f1JYTX2pvJAGDcnsNTnsV9bjYPU8xcV+xPwOXnUPOQwf4ZEuiU6G9H1UztH+OapMgu/ckEVwO87PwnQ==", - "dev": true, + "node_modules/electron-to-chromium": { + "version": "1.4.68", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.68.tgz", + "integrity": "sha512-cId+QwWrV8R1UawO6b9BR1hnkJ4EJPCPAr4h315vliHUtVUJDk39Sg1PMNnaWKfj5x+93ssjeJ9LKL6r8LaMiA==", + "dev": true + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", "dependencies": { - "@types/node": "*", - "graceful-fs": "^4.2.4" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" } }, - "node_modules/jest-snapshot": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.4.6.tgz", - "integrity": "sha512-fafUCDLQfzuNP9IRcEqaFAMzEe7u5BF7mude51wyWv7VRex60WznZIC7DfKTgSIlJa8aFzYmXclmN328aqSDmQ==", + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/emittery": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", + "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", "dev": true, - "dependencies": { - "@babel/core": "^7.7.2", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.0.0", - "@jest/transform": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^27.4.6", - "graceful-fs": "^4.2.4", - "jest-diff": "^27.4.6", - "jest-get-type": "^27.4.0", - "jest-haste-map": "^27.4.6", - "jest-matcher-utils": "^27.4.6", - "jest-message-util": "^27.4.6", - "jest-util": "^27.4.2", - "natural-compare": "^1.4.0", - "pretty-format": "^27.4.6", - "semver": "^7.3.2" - }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" } }, - "node_modules/jest-snapshot/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, "dependencies": { - "color-convert": "^2.0.1" - }, + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, + "node_modules/es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "dependencies": { + "es6-promise": "^4.0.3" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">=6" } }, - "node_modules/jest-snapshot/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-snapshot/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/escodegen": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", "dev": true, "dependencies": { - "color-name": "~1.1.4" + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" }, "engines": { - "node": ">=7.0.0" + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" } }, - "node_modules/jest-snapshot/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-snapshot/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/escodegen/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "engines": { - "node": ">=8" + "node": ">=4.0" } }, - "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "node_modules/escodegen/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true, "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" }, "engines": { - "node": ">=10" + "node": ">= 0.8.0" } }, - "node_modules/jest-snapshot/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/escodegen/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" }, "engines": { - "node": ">=8" + "node": ">= 0.8.0" } }, - "node_modules/jest-util": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.4.2.tgz", - "integrity": "sha512-YuxxpXU6nlMan9qyLuxHaMMOzXAl5aGZWCSzben5DhLHemYQxCc4YK+4L3ZrCutT8GPQ+ui9k5D8rUJoDioMnA==", + "node_modules/escodegen/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true, - "dependencies": { - "@jest/types": "^27.4.2", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.4", - "picomatch": "^2.2.3" - }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">= 0.8.0" } }, - "node_modules/jest-util/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/escodegen/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "dependencies": { - "color-convert": "^2.0.1" + "prelude-ls": "~1.1.2" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">= 0.8.0" } }, - "node_modules/jest-util/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/eslint": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.8.0.tgz", + "integrity": "sha512-H3KXAzQGBH1plhYS3okDix2ZthuYJlQQEGE5k0IKuEqUSiyu4AmxxlJ2MtTYeJ3xB4jDhcYCwGOg2TXYdnDXlQ==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@eslint/eslintrc": "^1.0.5", + "@humanwhocodes/config-array": "^0.9.2", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.0", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.2.0", + "espree": "^9.3.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.6.0", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" }, "engines": { - "node": ">=10" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://opencollective.com/eslint" } }, - "node_modules/jest-util/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/eslint-config-prettier": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz", + "integrity": "sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==", "dev": true, - "dependencies": { - "color-name": "~1.1.4" + "bin": { + "eslint-config-prettier": "bin/cli.js" }, - "engines": { - "node": ">=7.0.0" + "peerDependencies": { + "eslint": ">=7.0.0" } }, - "node_modules/jest-util/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-util/node_modules/has-flag": { + "node_modules/eslint-plugin-prettier": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-util/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.0.0.tgz", + "integrity": "sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "prettier-linter-helpers": "^1.0.0" }, "engines": { - "node": ">=8" + "node": ">=6.0.0" + }, + "peerDependencies": { + "eslint": ">=7.28.0", + "prettier": ">=2.0.0" + }, + "peerDependenciesMeta": { + "eslint-config-prettier": { + "optional": true + } } }, - "node_modules/jest-validate": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.4.6.tgz", - "integrity": "sha512-872mEmCPVlBqbA5dToC57vA3yJaMRfIdpCoD3cyHWJOMx+SJwLNw0I71EkWs41oza/Er9Zno9XuTkRYCPDUJXQ==", + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "dependencies": { - "@jest/types": "^27.4.2", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^27.4.0", - "leven": "^3.1.0", - "pretty-format": "^27.4.6" + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=8.0.0" } }, - "node_modules/jest-validate/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, "dependencies": { - "color-convert": "^2.0.1" + "eslint-visitor-keys": "^2.0.0" }, "engines": { - "node": ">=8" + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" } }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-validate/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/eslint-visitor-keys": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.2.0.tgz", + "integrity": "sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ==", "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/jest-validate/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/eslint/node_modules/eslint-scope": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.0.tgz", + "integrity": "sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==", "dev": true, "dependencies": { - "color-name": "~1.1.4" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "engines": { - "node": ">=7.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/jest-validate/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-validate/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "engines": { - "node": ">=8" + "node": ">=4.0" } }, - "node_modules/jest-validate/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/espree": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.0.tgz", + "integrity": "sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "acorn": "^8.7.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^3.1.0" }, "engines": { - "node": ">=8" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/jest-watcher": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.4.6.tgz", - "integrity": "sha512-yKQ20OMBiCDigbD0quhQKLkBO+ObGN79MO4nT7YaCuQ5SM+dkBNWE8cZX0FjU6czwMvWw6StWbe+Wv4jJPJ+fw==", + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, - "dependencies": { - "@jest/test-result": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^27.4.2", - "string-length": "^4.0.1" + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=4" } }, - "node_modules/jest-watcher/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, "dependencies": { - "color-convert": "^2.0.1" + "estraverse": "^5.1.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">=0.10" } }, - "node_modules/jest-watcher/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">=4.0" } }, - "node_modules/jest-watcher/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "dependencies": { - "color-name": "~1.1.4" + "estraverse": "^5.2.0" }, "engines": { - "node": ">=7.0.0" + "node": ">=4.0" } }, - "node_modules/jest-watcher/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } }, - "node_modules/jest-watcher/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, "engines": { - "node": ">=8" + "node": ">=4.0" } }, - "node_modules/jest-watcher/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/jest-worker": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.6.tgz", - "integrity": "sha512-gHWJF/6Xi5CTG5QCvROr6GcmpIqNYpDJyc8A1h/DyXqH1tD6SnRCM0d3U5msV31D2LB/U+E0M+W4oyvKV44oNw==", + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, "dependencies": { - "@types/node": "*", + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" }, "engines": { - "node": ">= 10.13.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/jest-worker/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", "dev": true, "engines": { - "node": ">=8" + "node": ">= 0.8.0" } }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "node_modules/expect": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", + "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "@jest/types": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + "node_modules/eyes": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=", + "engines": { + "node": "> 0.1.90" + } }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } + "node_modules/fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true }, - "node_modules/jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", + "node_modules/fast-glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", "dev": true, "dependencies": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" }, "engines": { - "node": ">=10" - }, - "peerDependencies": { - "canvas": "^2.5.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } + "node": ">=8.6.0" } }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, - "bin": { - "jsesc": "bin/jsesc" + "dependencies": { + "is-glob": "^4.0.1" }, "engines": { - "node": ">=4" + "node": ">= 6" } }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "node_modules/json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "node_modules/fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", "dev": true, "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" + "reusify": "^1.0.4" } }, - "node_modules/jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", - "engines": [ - "node >= 0.2.0" - ] - }, - "node_modules/JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "node_modules/fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "dev": true, "dependencies": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - }, - "bin": { - "JSONStream": "bin.js" - }, - "engines": { - "node": "*" + "bser": "2.1.1" } }, - "node_modules/jsx-ast-utils": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.1.tgz", - "integrity": "sha512-uP5vu8xfy2F9A6LGC22KO7e2/vGTS1MhP+18f++ZNlf0Ohaxbc9nIEwHAsejlJKyzfZzU5UIhe5ItYkitcZnZA==", + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "dependencies": { - "array-includes": "^3.1.3", - "object.assign": "^4.1.2" + "flat-cache": "^3.0.4" }, "engines": { - "node": ">=4.0" + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" }, "engines": { - "node": ">= 0.8.0" + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "node_modules/flatted": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", + "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", + "dev": true + }, + "node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", "dev": true, "dependencies": { - "p-locate": "^4.1.0" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" }, "engines": { - "node": ">=8" + "node": ">= 6" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" + "engines": { + "node": ">=6.9.0" } }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, "engines": { - "node": ">=10" + "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/magic-string": { - "version": "0.25.7", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", - "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true, - "dependencies": { - "sourcemap-codec": "^1.4.4" + "engines": { + "node": ">=8.0.0" } }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, - "dependencies": { - "semver": "^6.0.0" - }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, - "dependencies": { - "tmpl": "1.0.5" - } - }, - "node_modules/matched": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/matched/-/matched-5.0.1.tgz", - "integrity": "sha512-E1fhSTPRyhAlNaNvGXAgZQlq1hL0bgYMTk/6bktVlIhzUnX/SZs7296ACdVeNJE8xFNGSuvd9IpI7vSnmcqLvw==", + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, "dependencies": { - "glob": "^7.1.6", - "picomatch": "^2.2.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" }, "engines": { - "node": ">=10" + "node": "*" }, "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, "engines": { - "node": ">= 8" + "node": ">=10.13.0" } }, - "node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "node_modules/globals": { + "version": "13.12.1", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz", + "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==", "dev": true, "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "type-fest": "^0.20.2" }, "engines": { - "node": ">=8.6" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, "engines": { - "node": ">= 0.6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "node_modules/graceful-fs": { + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", + "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, "dependencies": { - "mime-db": "1.51.0" + "function-bind": "^1.1.1" }, "engines": { - "node": ">= 0.6" + "node": ">= 0.4.0" } }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, - "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "node_modules/node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" - }, - "node_modules/node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", - "engines": { - "node": "4.x || >=6.0.0" + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" } }, - "node_modules/node-gyp-build": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", - "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==", - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" } }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", - "dev": true - }, - "node_modules/node-releases": { + "node_modules/html-encoding-sniffer": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", - "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==", - "dev": true - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", "dev": true, + "dependencies": { + "whatwg-encoding": "^1.0.5" + }, "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/npm-run-path": { + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/http-proxy-agent": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", "dev": true, "dependencies": { - "path-key": "^3.0.0" + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" }, "engines": { - "node": ">=8" + "node": ">= 6" } }, - "node_modules/nwsapi": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", - "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", - "dev": true + "node_modules/https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=10.17.0" } }, - "node_modules/object-inspect": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", - "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true, "engines": { - "node": ">= 0.4" + "node": ">= 4" } }, - "node_modules/object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=6" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/object.entries": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz", - "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" }, "engines": { - "node": ">= 0.4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/object.fromentries": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.5.tgz", - "integrity": "sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==", + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.8.19" } }, - "node_modules/object.hasown": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.0.tgz", - "integrity": "sha512-MhjYRfj3GBlhSkDHo6QmvgjRLXQ2zndabdf3nX0yTyZK9rPfxb6uRpAac8HXNLy1GpqWtZ81Qh4v3uOls2sRAg==", + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "once": "^1.3.0", + "wrappy": "1" } }, - "node_modules/object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "node_modules/is-core-module": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", + "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - }, - "engines": { - "node": ">= 0.4" + "has": "^1.0.3" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true, - "dependencies": { - "wrappy": "1" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, "engines": { "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "is-extglob": "^2.1.1" }, "engines": { - "node": ">= 0.8.0" + "node": ">=0.10.0" + } + }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", + "dev": true + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true + }, + "node_modules/is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", + "dev": true, + "dependencies": { + "@types/estree": "*" } }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, "engines": { - "node": ">=6" + "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/isomorphic-ws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", + "peerDependencies": { + "ws": "*" } }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "node_modules/istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", "dev": true, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "node_modules/istanbul-lib-instrument": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", + "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", "dev": true, "dependencies": { - "callsites": "^3.0.0" + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, "engines": { "node": ">=8" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "node_modules/istanbul-reports": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz", + "integrity": "sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==", "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, "engines": { "node": ">=8" } }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, + "node_modules/jayson": { + "version": "3.6.6", + "resolved": "https://registry.npmjs.org/jayson/-/jayson-3.6.6.tgz", + "integrity": "sha512-f71uvrAWTtrwoww6MKcl9phQTC+56AopLyEenWvKVAIMz+q0oVGj6tenLZ7Z6UiPBkJtKLj4kt0tACllFQruGQ==", + "dependencies": { + "@types/connect": "^3.4.33", + "@types/express-serve-static-core": "^4.17.9", + "@types/lodash": "^4.14.159", + "@types/node": "^12.12.54", + "@types/ws": "^7.4.4", + "commander": "^2.20.3", + "delay": "^5.0.0", + "es6-promisify": "^5.0.0", + "eyes": "^0.1.8", + "isomorphic-ws": "^4.0.1", + "json-stringify-safe": "^5.0.1", + "JSONStream": "^1.3.5", + "lodash": "^4.17.20", + "uuid": "^8.3.2", + "ws": "^7.4.5" + }, + "bin": { + "jayson": "bin/jayson.js" + }, "engines": { "node": ">=8" } }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "node_modules/jayson/node_modules/@types/node": { + "version": "12.20.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.45.tgz", + "integrity": "sha512-1Jg2Qv5tuxBqgQV04+wO5u+wmSHbHgpORCJdeCLM+E+YdPElpdHhgywU+M1V1InL8rfOtpqtOjswk+uXTKwx7w==" }, - "node_modules/picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "node_modules/jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", + "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", "dev": true, + "dependencies": { + "@jest/core": "^27.5.1", + "import-local": "^3.0.2", + "jest-cli": "^27.5.1" + }, + "bin": { + "jest": "bin/jest.js" + }, "engines": { - "node": ">=8.6" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/pirates": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.4.tgz", - "integrity": "sha512-ZIrVPH+A52Dw84R0L3/VS9Op04PuQ2SEoJL6bkshmiTic/HldyW9Tf7oH5mhJZBK7NmDx27vSMrYEXPXclpDKw==", + "node_modules/jest-changed-files": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", + "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "execa": "^5.0.0", + "throat": "^6.0.1" + }, "engines": { - "node": ">= 6" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "node_modules/jest-circus": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", + "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", "dev": true, "dependencies": { - "find-up": "^4.0.0" + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "expect": "^27.5.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3", + "throat": "^6.0.1" }, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "node_modules/jest-cli": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", + "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", "dev": true, + "dependencies": { + "@jest/core": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "prompts": "^2.0.1", + "yargs": "^16.2.0" + }, + "bin": { + "jest": "bin/jest.js" + }, "engines": { - "node": ">= 0.8.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/prettier": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz", - "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==", + "node_modules/jest-config": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", + "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", "dev": true, - "bin": { - "prettier": "bin-prettier.js" + "dependencies": { + "@babel/core": "^7.8.0", + "@jest/test-sequencer": "^27.5.1", + "@jest/types": "^27.5.1", + "babel-jest": "^27.5.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.9", + "jest-circus": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-jasmine2": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" }, "engines": { - "node": ">=10.13.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + } } }, - "node_modules/pretty-format": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.6.tgz", - "integrity": "sha512-NblstegA1y/RJW2VyML+3LlpFjzx62cUrtBIKIWDXEDkjNeleA7Od7nrzcs/VLQvAeV4CgSYhrN39DRN88Qi/g==", + "node_modules/jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", "dev": true, "dependencies": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "node_modules/jest-docblock": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", + "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", "dev": true, - "engines": { - "node": ">=10" + "dependencies": { + "detect-newline": "^3.0.0" }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, "engines": { - "node": ">=0.4.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "node_modules/jest-each": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", + "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", "dev": true, "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "jest-get-type": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1" }, "engines": { - "node": ">= 6" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/prop-types": { - "version": "15.8.0", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.0.tgz", - "integrity": "sha512-fDGekdaHh65eI3lMi5OnErU6a8Ighg2KjcjQxO7m8VHyWjcPyj5kiOgV1LQDOOOgVy3+5FgjXvdSSX7B8/5/4g==", + "node_modules/jest-environment-jsdom": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", + "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", "dev": true, "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, - "node_modules/prop-types/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true - }, - "node_modules/psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true - }, - "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1", + "jsdom": "^16.6.0" + }, "engines": { - "node": ">=6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "node_modules/regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true - }, - "node_modules/regenerate-unicode-properties": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz", - "integrity": "sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA==", + "node_modules/jest-environment-node": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", + "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", "dev": true, "dependencies": { - "regenerate": "^1.4.2" + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" }, "engines": { - "node": ">=4" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" - }, - "node_modules/regenerator-transform": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", - "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", + "node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", "dev": true, - "dependencies": { - "@babel/runtime": "^7.8.4" + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/regexp.prototype.flags": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", - "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", + "node_modules/jest-haste-map": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", + "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "@jest/types": "^27.5.1", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^27.5.1", + "jest-serializer": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "micromatch": "^4.0.4", + "walker": "^1.0.7" }, "engines": { - "node": ">= 0.4" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "optionalDependencies": { + "fsevents": "^2.3.2" } }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "node_modules/jest-jasmine2": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", + "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^27.5.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "throat": "^6.0.1" }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/regexpu-core": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.8.0.tgz", - "integrity": "sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg==", + "node_modules/jest-leak-detector": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", + "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", "dev": true, "dependencies": { - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^9.0.0", - "regjsgen": "^0.5.2", - "regjsparser": "^0.7.0", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.0.0" + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" }, "engines": { - "node": ">=4" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/regjsgen": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", - "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", - "dev": true - }, - "node_modules/regjsparser": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.7.0.tgz", - "integrity": "sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ==", + "node_modules/jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", "dev": true, "dependencies": { - "jsesc": "~0.5.0" + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true, "engines": { - "node": ">=0.10.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", "dev": true, "dependencies": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "node_modules/jest-mock": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", + "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", "dev": true, "dependencies": { - "resolve-from": "^5.0.0" + "@jest/types": "^27.5.1", + "@types/node": "*" }, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/resolve-cwd/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "node_modules/jest-pnp-resolver": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", "dev": true, "engines": { - "node": ">=8" + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } } }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "node_modules/jest-regex-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", + "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", "dev": true, "engines": { - "node": ">=4" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/resolve.exports": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", - "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", + "node_modules/jest-resolve": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", + "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", + "slash": "^3.0.0" + }, "engines": { - "node": ">=10" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "node_modules/jest-resolve-dependencies": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", + "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-snapshot": "^27.5.1" + }, "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "node_modules/jest-runner": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", + "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", "dev": true, "dependencies": { - "glob": "^7.1.3" + "@jest/console": "^27.5.1", + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-leak-detector": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "source-map-support": "^0.5.6", + "throat": "^6.0.1" }, - "bin": { - "rimraf": "bin.js" + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", + "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/globals": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/rollup": { - "version": "2.66.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.66.1.tgz", - "integrity": "sha512-crSgLhSkLMnKr4s9iZ/1qJCplgAgrRY+igWv8KhG/AjKOJ0YX/WpmANyn8oxrw+zenF3BXWDLa7Xl/QZISH+7w==", + "node_modules/jest-serializer": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", + "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", "dev": true, - "bin": { - "rollup": "dist/bin/rollup" + "dependencies": { + "@types/node": "*", + "graceful-fs": "^4.2.9" }, "engines": { - "node": ">=10.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/rollup-plugin-dts": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-4.1.0.tgz", - "integrity": "sha512-rriXIm3jdUiYeiAAd1Fv+x2AxK6Kq6IybB2Z/IdoAW95fb4uRUurYsEYKa8L1seedezDeJhy8cfo8FEL9aZzqg==", + "node_modules/jest-snapshot": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", + "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", "dev": true, "dependencies": { - "magic-string": "^0.25.7" + "@babel/core": "^7.7.2", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.0.0", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", + "natural-compare": "^1.4.0", + "pretty-format": "^27.5.1", + "semver": "^7.3.2" }, "engines": { - "node": ">=v12.22.7" - }, - "funding": { - "url": "https://github.com/sponsors/Swatinem" - }, - "optionalDependencies": { - "@babel/code-frame": "^7.16.0" - }, - "peerDependencies": { - "rollup": "^2.55", - "typescript": "~4.1 || ~4.2 || ~4.3 || ~4.4 || ~4.5" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/rollup-plugin-inject": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rollup-plugin-inject/-/rollup-plugin-inject-3.0.2.tgz", - "integrity": "sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==", - "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject.", + "node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", "dev": true, "dependencies": { - "estree-walker": "^0.6.1", - "magic-string": "^0.25.3", - "rollup-pluginutils": "^2.8.1" + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/rollup-plugin-inject/node_modules/estree-walker": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", - "dev": true - }, - "node_modules/rollup-plugin-node-polyfills": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/rollup-plugin-node-polyfills/-/rollup-plugin-node-polyfills-0.2.1.tgz", - "integrity": "sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==", + "node_modules/jest-validate": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", + "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", "dev": true, "dependencies": { - "rollup-plugin-inject": "^3.0.0" + "@jest/types": "^27.5.1", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^27.5.1", + "leven": "^3.1.0", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/rollup-plugin-terser": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", - "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, - "dependencies": { - "@babel/code-frame": "^7.10.4", - "jest-worker": "^26.2.1", - "serialize-javascript": "^4.0.0", - "terser": "^5.0.0" + "engines": { + "node": ">=10" }, - "peerDependencies": { - "rollup": "^2.0.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/rollup-plugin-terser/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/jest-watcher": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", + "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", "dev": true, + "dependencies": { + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^27.5.1", + "string-length": "^4.0.1" + }, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/rollup-plugin-terser/node_modules/jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dev": true, "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" + "supports-color": "^8.0.0" }, "engines": { "node": ">= 10.13.0" } }, - "node_modules/rollup-plugin-terser/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "dependencies": { "has-flag": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/rollup-pluginutils": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", - "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", - "dev": true, - "dependencies": { - "estree-walker": "^0.6.1" - } + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" }, - "node_modules/rollup-pluginutils/node_modules/estree-walker": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, - "node_modules/rpc-websockets": { - "version": "7.4.16", - "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.4.16.tgz", - "integrity": "sha512-0b7OVhutzwRIaYAtJo5tqtaQTWKfwAsKnaThOSOy+VkhVdleNUgb8eZnWSdWITRZZEigV5uPEIDr5KZe4DBrdQ==", + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.11.2", - "circular-json": "^0.5.9", - "eventemitter3": "^4.0.7", - "uuid": "^8.3.0", - "ws": "^7.4.5" - }, - "funding": { - "type": "paypal", - "url": "https://paypal.me/kozjak" + "argparse": "^2.0.1" }, - "optionalDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "node_modules/jsdom": { + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], "dependencies": { - "queue-microtask": "^1.2.2" + "abab": "^2.0.5", + "acorn": "^8.2.4", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.5.0", + "ws": "^7.4.6", + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, - "node_modules/saxes": { + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "node_modules/json-stringify-safe": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "node_modules/json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", "dev": true, "dependencies": { - "xmlchars": "^2.2.0" + "minimist": "^1.2.5" + }, + "bin": { + "json5": "lib/cli.js" }, "engines": { - "node": ">=10" + "node": ">=6" } }, - "node_modules/secp256k1": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", - "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", - "hasInstallScript": true, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "engines": [ + "node >= 0.2.0" + ] + }, + "node_modules/JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", "dependencies": { - "elliptic": "^6.5.2", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" }, "engines": { - "node": ">=10.0.0" + "node": "*" } }, - "node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true, - "bin": { - "semver": "bin/semver.js" + "engines": { + "node": ">=6" } }, - "node_modules/serialize-javascript": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", - "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true, - "dependencies": { - "randombytes": "^2.1.0" + "engines": { + "node": ">=6" } }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "dependencies": { - "shebang-regex": "^3.0.0" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" }, "engines": { - "node": ">=8" + "node": ">= 0.8.0" } }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "p-locate": "^4.1.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=8" } }, - "node_modules/signal-exit": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", - "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", "dev": true }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, "engines": { - "node": ">=8" + "node": ">=10" } }, - "node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "node_modules/magic-string": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", + "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", "dev": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "sourcemap-codec": "^1.4.4" } }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, - "engines": { - "node": ">=0.10.0" + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "dependencies": { + "tmpl": "1.0.5" + } }, - "node_modules/stack-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", + "node_modules/matched": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/matched/-/matched-5.0.1.tgz", + "integrity": "sha512-E1fhSTPRyhAlNaNvGXAgZQlq1hL0bgYMTk/6bktVlIhzUnX/SZs7296ACdVeNJE8xFNGSuvd9IpI7vSnmcqLvw==", "dev": true, "dependencies": { - "escape-string-regexp": "^2.0.0" + "glob": "^7.1.6", + "picomatch": "^2.2.1" }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { + "node_modules/merge-stream": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, "engines": { - "node": ">=8" + "node": ">= 8" } }, - "node_modules/string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "node_modules/micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", "dev": true, "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" + "braces": "^3.0.1", + "picomatch": "^2.2.3" }, "engines": { - "node": ">=10" + "node": ">=8.6" } }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "node_modules/mime-db": { + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, "engines": { - "node": ">=8" + "node": ">= 0.6" } }, - "node_modules/string.prototype.matchall": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.6.tgz", - "integrity": "sha512-6WgDX8HmQqvEd7J+G6VtAahhsQIssiZ8zl7zKh1VDMFyL3hRTJP4FTNA3RbIp2TOQ9AYNDcc7e3fH0Qbup+DBg==", + "node_modules/mime-types": { + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", - "get-intrinsic": "^1.1.1", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "regexp.prototype.flags": "^1.3.1", - "side-channel": "^1.0.4" + "mime-db": "1.51.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">= 0.6" } }, - "node_modules/string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=6" } }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "node_modules/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "brace-expansion": "^1.1.7" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "*" } }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", "dependencies": { - "ansi-regex": "^5.0.1" + "whatwg-url": "^5.0.0" }, "engines": { - "node": ">=8" + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } } }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "engines": { - "node": ">=8" + "node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" } }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "engines": { - "node": ">=6" + "node_modules/node-gyp-build": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", + "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" } }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", + "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=0.10.0" } }, - "node_modules/superstruct": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-0.14.2.tgz", - "integrity": "sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==" - }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, "dependencies": { - "has-flag": "^3.0.0" + "path-key": "^3.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/supports-hyperlinks": { + "node_modules/nwsapi": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", - "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", + "dev": true + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">=8" + "wrappy": "1" } }, - "node_modules/supports-hyperlinks/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, "engines": { - "node": ">=8" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/supports-hyperlinks/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" }, "engines": { - "node": ">=8" + "node": ">= 0.8.0" } }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true - }, - "node_modules/terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "dependencies": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" + "p-try": "^2.0.0" }, "engines": { - "node": ">=8" + "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/terser": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.10.0.tgz", - "integrity": "sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA==", + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "dependencies": { - "commander": "^2.20.0", - "source-map": "~0.7.2", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" + "p-limit": "^2.2.0" }, "engines": { - "node": ">=10" - }, - "peerDependencies": { - "acorn": "^8.5.0" - }, - "peerDependenciesMeta": { - "acorn": { - "optional": true - } + "node": ">=8" } }, - "node_modules/terser/node_modules/source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, "engines": { - "node": ">= 8" + "node": ">=6" } }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/text-encoding-utf-8": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz", - "integrity": "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==" - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "node_modules/throat": { + "node_modules/parse5": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", - "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", - "dev": true - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", "dev": true }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, "engines": { - "node": ">=8.0" + "node": ">=0.10.0" } }, - "node_modules/tough-cookie": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", - "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.1.2" - }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, - "dependencies": { - "punycode": "^2.1.1" - }, "engines": { "node": ">=8" } }, - "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", "dev": true }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, "engines": { - "node": ">= 6" + "node": ">=8.6" }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + "node_modules/pirates": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", + "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "dev": true, + "engines": { + "node": ">= 6" + } }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, "dependencies": { - "prelude-ls": "^1.2.1" + "find-up": "^4.0.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">=8" } }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, "engines": { - "node": ">=4" + "node": ">= 0.8.0" } }, - "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "node_modules/prettier": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz", + "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==", "dev": true, - "engines": { - "node": ">=10" + "bin": { + "prettier": "bin-prettier.js" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=10.13.0" } }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", "dev": true, "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/typescript": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz", - "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" + "fast-diff": "^1.1.2" }, "engines": { - "node": ">=4.2.0" + "node": ">=6.0.0" } }, - "node_modules/unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "dev": true, "dependencies": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" }, "engines": { - "node": ">=4" + "node": ">= 6" } }, - "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", - "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==", + "node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true, "engines": { - "node": ">=4" + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" } }, - "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz", - "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==", + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" } }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true, "engines": { - "node": ">= 4.0.0" + "node": ">=0.10.0" } }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "node_modules/resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", "dev": true, "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/utf-8-validate": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.7.tgz", - "integrity": "sha512-vLt1O5Pp+flcArHGIyKEQq883nBt8nN8tVBcoL0qUXj2XT1n7p70yGIq2VK98I5FdZ1YHc0wk/koOnHjnXWk1Q==", - "hasInstallScript": true, - "optional": true, - "dependencies": { - "node-gyp-build": "^4.3.0" + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" }, - "engines": { - "node": ">=6.14.2" - } - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "bin": { - "uuid": "dist/bin/uuid" + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "node_modules/v8-to-istanbul": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", - "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" + "resolve-from": "^5.0.0" }, "engines": { - "node": ">=10.12.0" + "node": ">=8" } }, - "node_modules/v8-to-istanbul/node_modules/source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, "engines": { - "node": ">= 8" + "node": ">=8" } }, - "node_modules/w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, - "dependencies": { - "browser-process-hrtime": "^1.0.0" + "engines": { + "node": ">=4" } }, - "node_modules/w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "node_modules/resolve.exports": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", + "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", "dev": true, - "dependencies": { - "xml-name-validator": "^3.0.0" - }, "engines": { "node": ">=10" } }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, - "dependencies": { - "makeerror": "1.0.12" - } - }, - "node_modules/webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, "engines": { - "node": ">=10.4" - } - }, - "node_modules/whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dev": true, - "dependencies": { - "iconv-lite": "0.4.24" + "iojs": ">=1.0.0", + "node": ">=0.10.0" } }, - "node_modules/whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "dev": true - }, - "node_modules/whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "dependencies": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" + "glob": "^7.1.3" }, - "engines": { - "node": ">=10" + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "node_modules/rollup": { + "version": "2.67.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.67.2.tgz", + "integrity": "sha512-hoEiBWwZtf1QdK3jZIq59L0FJj4Fiv4RplCO4pvCRC86qsoFurWB4hKQIjoRf3WvJmk5UZ9b0y5ton+62fC7Tw==", "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, "bin": { - "node-which": "bin/node-which" + "rollup": "dist/bin/rollup" }, "engines": { - "node": ">= 8" + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" } }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "node_modules/rollup-plugin-dts": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-4.1.0.tgz", + "integrity": "sha512-rriXIm3jdUiYeiAAd1Fv+x2AxK6Kq6IybB2Z/IdoAW95fb4uRUurYsEYKa8L1seedezDeJhy8cfo8FEL9aZzqg==", "dev": true, "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" + "magic-string": "^0.25.7" + }, + "engines": { + "node": ">=v12.22.7" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/Swatinem" + }, + "optionalDependencies": { + "@babel/code-frame": "^7.16.0" + }, + "peerDependencies": { + "rollup": "^2.55", + "typescript": "~4.1 || ~4.2 || ~4.3 || ~4.4 || ~4.5" } }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "node_modules/rollup-plugin-inject": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-inject/-/rollup-plugin-inject-3.0.2.tgz", + "integrity": "sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==", + "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject.", "dev": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "estree-walker": "^0.6.1", + "magic-string": "^0.25.3", + "rollup-pluginutils": "^2.8.1" } }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "node_modules/rollup-plugin-inject/node_modules/estree-walker": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", + "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", + "dev": true + }, + "node_modules/rollup-plugin-node-polyfills": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/rollup-plugin-node-polyfills/-/rollup-plugin-node-polyfills-0.2.1.tgz", + "integrity": "sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==", "dev": true, "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "rollup-plugin-inject": "^3.0.0" } }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/rollup-plugin-terser": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", + "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", "dev": true, "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" + "@babel/code-frame": "^7.10.4", + "jest-worker": "^26.2.1", + "serialize-javascript": "^4.0.0", + "terser": "^5.0.0" }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "peerDependencies": { + "rollup": "^2.0.0" } }, - "node_modules/wrap-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/rollup-plugin-terser/node_modules/jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", "dev": true, "dependencies": { - "color-name": "~1.1.4" + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" }, "engines": { - "node": ">=7.0.0" + "node": ">= 10.13.0" } }, - "node_modules/wrap-ansi/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "node_modules/rollup-pluginutils": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", + "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", "dev": true, "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" + "estree-walker": "^0.6.1" } }, - "node_modules/ws": { - "version": "7.5.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz", - "integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==", - "engines": { - "node": ">=8.3.0" + "node_modules/rollup-pluginutils/node_modules/estree-walker": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", + "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", + "dev": true + }, + "node_modules/rpc-websockets": { + "version": "7.4.17", + "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.4.17.tgz", + "integrity": "sha512-eolVi/qlXS13viIUH9aqrde902wzSLAai0IjmOZSRefp5I3CSG/vCnD0c0fDSYCWuEyUoRL1BHQA8K1baEUyow==", + "dependencies": { + "@babel/runtime": "^7.11.2", + "circular-json": "^0.5.9", + "eventemitter3": "^4.0.7", + "uuid": "^8.3.0", + "ws": "^7.4.5" }, - "peerDependencies": { + "funding": { + "type": "paypal", + "url": "https://paypal.me/kozjak" + }, + "optionalDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" }, - "utf-8-validate": { - "optional": true + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" } + ], + "dependencies": { + "queue-microtask": "^1.2.2" } }, - "node_modules/xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "dev": true + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "node_modules/saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", "dev": true, + "dependencies": { + "xmlchars": "^2.2.0" + }, "engines": { "node": ">=10" } }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, + "node_modules/secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", + "hasInstallScript": true, "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" + "elliptic": "^6.5.4", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" }, "engines": { - "node": ">=10" + "node": ">=10.0.0" } }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, "engines": { "node": ">=10" } - } - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz", - "integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==", - "dev": true, - "requires": { - "@babel/highlight": "^7.16.0" - } - }, - "@babel/compat-data": { - "version": "7.16.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.4.tgz", - "integrity": "sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q==", - "dev": true - }, - "@babel/core": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.5.tgz", - "integrity": "sha512-wUcenlLzuWMZ9Zt8S0KmFwGlH6QKRh3vsm/dhDA3CHkiTA45YuG1XkHRcNRl73EFPXDp/d5kVOU0/y7x2w6OaQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.16.0", - "@babel/generator": "^7.16.5", - "@babel/helper-compilation-targets": "^7.16.3", - "@babel/helper-module-transforms": "^7.16.5", - "@babel/helpers": "^7.16.5", - "@babel/parser": "^7.16.5", - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "semver": "^6.3.0", - "source-map": "^0.5.0" - } - }, - "@babel/generator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.5.tgz", - "integrity": "sha512-kIvCdjZqcdKqoDbVVdt5R99icaRtrtYhYK/xux5qiWCBmfdvEYMFZ68QCrpE5cbFM1JsuArUNs1ZkuKtTtUcZA==", - "dev": true, - "requires": { - "@babel/types": "^7.16.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.0.tgz", - "integrity": "sha512-ItmYF9vR4zA8cByDocY05o0LGUkp1zhbTQOH1NFyl5xXEqlTJQCEJjieriw+aFpxo16swMxUnUiKS7a/r4vtHg==", - "dev": true, - "requires": { - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.5.tgz", - "integrity": "sha512-3JEA9G5dmmnIWdzaT9d0NmFRgYnWUThLsDaL7982H0XqqWr56lRrsmwheXFMjR+TMl7QMBb6mzy9kvgr1lRLUA==", - "dev": true, - "requires": { - "@babel/helper-explode-assignable-expression": "^7.16.0", - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.16.3", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.3.tgz", - "integrity": "sha512-vKsoSQAyBmxS35JUOOt+07cLc6Nk/2ljLIHwmq2/NM6hdioUaqEXq/S+nXvbvXbZkNDlWOymPanJGOc4CBjSJA==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.16.0", - "@babel/helper-validator-option": "^7.14.5", - "browserslist": "^4.17.5", - "semver": "^6.3.0" - } }, - "@babel/helper-create-class-features-plugin": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.5.tgz", - "integrity": "sha512-NEohnYA7mkB8L5JhU7BLwcBdU3j83IziR9aseMueWGeAjblbul3zzb8UvJ3a1zuBiqCMObzCJHFqKIQE6hTVmg==", + "node_modules/serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-environment-visitor": "^7.16.5", - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-member-expression-to-functions": "^7.16.5", - "@babel/helper-optimise-call-expression": "^7.16.0", - "@babel/helper-replace-supers": "^7.16.5", - "@babel/helper-split-export-declaration": "^7.16.0" + "dependencies": { + "randombytes": "^2.1.0" } }, - "@babel/helper-create-regexp-features-plugin": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.0.tgz", - "integrity": "sha512-3DyG0zAFAZKcOp7aVr33ddwkxJ0Z0Jr5V99y3I690eYLpukJsJvAbzTy1ewoCqsML8SbIrjH14Jc/nSQ4TvNPA==", + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "regexpu-core": "^4.7.1" + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "@babel/helper-define-polyfill-provider": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz", - "integrity": "sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA==", + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, - "requires": { - "@babel/helper-compilation-targets": "^7.13.0", - "@babel/helper-module-imports": "^7.12.13", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/traverse": "^7.13.0", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2", - "semver": "^6.1.2" + "engines": { + "node": ">=8" } }, - "@babel/helper-environment-visitor": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.5.tgz", - "integrity": "sha512-ODQyc5AnxmZWm/R2W7fzhamOk1ey8gSguo5SGvF0zcB3uUzRpTRmM/jmLSm9bDMyPlvbyJ+PwPEK0BWIoZ9wjg==", - "dev": true, - "requires": { - "@babel/types": "^7.16.0" - } + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true }, - "@babel/helper-explode-assignable-expression": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.0.tgz", - "integrity": "sha512-Hk2SLxC9ZbcOhLpg/yMznzJ11W++lg5GMbxt1ev6TXUiJB0N42KPC+7w8a+eWGuqDnUYuwStJoZHM7RgmIOaGQ==", - "dev": true, - "requires": { - "@babel/types": "^7.16.0" - } + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true }, - "@babel/helper-function-name": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.0.tgz", - "integrity": "sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog==", + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.16.0", - "@babel/template": "^7.16.0", - "@babel/types": "^7.16.0" + "engines": { + "node": ">=8" } }, - "@babel/helper-get-function-arity": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.0.tgz", - "integrity": "sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ==", + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, - "requires": { - "@babel/types": "^7.16.0" + "engines": { + "node": ">=0.10.0" } }, - "@babel/helper-hoist-variables": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.0.tgz", - "integrity": "sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg==", + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, - "requires": { - "@babel/types": "^7.16.0" + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, - "@babel/helper-member-expression-to-functions": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.5.tgz", - "integrity": "sha512-7fecSXq7ZrLE+TWshbGT+HyCLkxloWNhTbU2QM1NTI/tDqyf0oZiMcEfYtDuUDCo528EOlt39G1rftea4bRZIw==", - "dev": true, - "requires": { - "@babel/types": "^7.16.0" - } + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "dev": true }, - "@babel/helper-module-imports": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", - "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/stack-utils": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", + "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", "dev": true, - "requires": { - "@babel/types": "^7.16.7" + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" } }, - "@babel/helper-module-transforms": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.5.tgz", - "integrity": "sha512-CkvMxgV4ZyyioElFwcuWnDCcNIeyqTkCm9BxXZi73RR1ozqlpboqsbGUNvRTflgZtFbbJ1v5Emvm+lkjMYY/LQ==", + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.16.5", - "@babel/helper-module-imports": "^7.16.0", - "@babel/helper-simple-access": "^7.16.0", - "@babel/helper-split-export-declaration": "^7.16.0", - "@babel/helper-validator-identifier": "^7.15.7", - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0" + "engines": { + "node": ">=8" } }, - "@babel/helper-optimise-call-expression": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.0.tgz", - "integrity": "sha512-SuI467Gi2V8fkofm2JPnZzB/SUuXoJA5zXe/xzyPP2M04686RzFKFHPK6HDVN6JvWBIEW8tt9hPR7fXdn2Lgpw==", + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, - "requires": { - "@babel/types": "^7.16.0" + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" } }, - "@babel/helper-plugin-utils": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", - "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", - "dev": true - }, - "@babel/helper-remap-async-to-generator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.5.tgz", - "integrity": "sha512-X+aAJldyxrOmN9v3FKp+Hu1NO69VWgYgDGq6YDykwRPzxs5f2N+X988CBXS7EQahDU+Vpet5QYMqLk+nsp+Qxw==", + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-wrap-function": "^7.16.5", - "@babel/types": "^7.16.0" + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" } }, - "@babel/helper-replace-supers": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.5.tgz", - "integrity": "sha512-ao3seGVa/FZCMCCNDuBcqnBFSbdr8N2EW35mzojx3TwfIbdPmNK+JV6+2d5bR0Z71W5ocLnQp9en/cTF7pBJiQ==", + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.16.5", - "@babel/helper-member-expression-to-functions": "^7.16.5", - "@babel/helper-optimise-call-expression": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0" + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "@babel/helper-simple-access": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.0.tgz", - "integrity": "sha512-o1rjBT/gppAqKsYfUdfHq5Rk03lMQrkPHG1OWzHWpLgVXRH4HnMM9Et9CVdIqwkCQlobnGHEJMsgWP/jE1zUiw==", + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true, - "requires": { - "@babel/types": "^7.16.0" + "engines": { + "node": ">=8" } }, - "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz", - "integrity": "sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw==", + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true, - "requires": { - "@babel/types": "^7.16.0" + "engines": { + "node": ">=6" } }, - "@babel/helper-split-export-declaration": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz", - "integrity": "sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw==", + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, - "requires": { - "@babel/types": "^7.16.0" + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", - "dev": true - }, - "@babel/helper-validator-option": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", - "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", - "dev": true + "node_modules/superstruct": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-0.14.2.tgz", + "integrity": "sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==" }, - "@babel/helper-wrap-function": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.16.5.tgz", - "integrity": "sha512-2J2pmLBqUqVdJw78U0KPNdeE2qeuIyKoG4mKV7wAq3mc4jJG282UgjZw4ZYDnqiWQuS3Y3IYdF/AQ6CpyBV3VA==", + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "requires": { - "@babel/helper-function-name": "^7.16.0", - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0" + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "@babel/helpers": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.5.tgz", - "integrity": "sha512-TLgi6Lh71vvMZGEkFuIxzaPsyeYCHQ5jJOOX1f0xXn0uciFuE8cEk0wyBquMcCxBXZ5BJhE2aUB7pnWTD150Tw==", + "node_modules/supports-hyperlinks": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", + "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", "dev": true, - "requires": { - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0" + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" } }, - "@babel/highlight": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.0.tgz", - "integrity": "sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==", + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.15.7", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "@babel/parser": { - "version": "7.16.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.6.tgz", - "integrity": "sha512-Gr86ujcNuPDnNOY8mi383Hvi8IYrJVJYuf3XcuBM/Dgd+bINn/7tHqsj+tKkoreMbmGsFLsltI/JJd8fOFWGDQ==", + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.16.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.2.tgz", - "integrity": "sha512-h37CvpLSf8gb2lIJ2CgC3t+EjFbi0t8qS7LCS1xcJIlEXE4czlofwaW7W1HA8zpgOCzI9C1nmoqNR1zWkk0pQg==", + "node_modules/terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "dependencies": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.0.tgz", - "integrity": "sha512-4tcFwwicpWTrpl9qjf7UsoosaArgImF85AxqCRZlgc3IQDvkUHjJpruXAL58Wmj+T6fypWTC/BakfEkwIL/pwA==", + "node_modules/terser": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.10.0.tgz", + "integrity": "sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", - "@babel/plugin-proposal-optional-chaining": "^7.16.0" + "dependencies": { + "commander": "^2.20.0", + "source-map": "~0.7.2", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "acorn": "^8.5.0" + }, + "peerDependenciesMeta": { + "acorn": { + "optional": true + } } }, - "@babel/plugin-proposal-async-generator-functions": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.5.tgz", - "integrity": "sha512-C/FX+3HNLV6sz7AqbTQqEo1L9/kfrKjxcVtgyBCmvIgOjvuBVUWooDoi7trsLxOzCEo5FccjRvKHkfDsJFZlfA==", + "node_modules/terser/node_modules/source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-remap-async-to-generator": "^7.16.5", - "@babel/plugin-syntax-async-generators": "^7.8.4" + "engines": { + "node": ">= 8" } }, - "@babel/plugin-proposal-class-properties": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.5.tgz", - "integrity": "sha512-pJD3HjgRv83s5dv1sTnDbZOaTjghKEz8KUn1Kbh2eAIRhGuyQ1XSeI4xVXU3UlIEVA3DAyIdxqT1eRn7Wcn55A==", + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5" + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" } }, - "@babel/plugin-proposal-class-static-block": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.16.5.tgz", - "integrity": "sha512-EEFzuLZcm/rNJ8Q5krK+FRKdVkd6FjfzT9tuSZql9sQn64K0hHA2KLJ0DqVot9/iV6+SsuadC5yI39zWnm+nmQ==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - } + "node_modules/text-encoding-utf-8": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz", + "integrity": "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==" }, - "@babel/plugin-proposal-dynamic-import": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.5.tgz", - "integrity": "sha512-P05/SJZTTvHz79LNYTF8ff5xXge0kk5sIIWAypcWgX4BTRUgyHc8wRxJ/Hk+mU0KXldgOOslKaeqnhthcDJCJQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - } + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "node_modules/throat": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", + "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true }, - "@babel/plugin-proposal-export-namespace-from": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.5.tgz", - "integrity": "sha512-i+sltzEShH1vsVydvNaTRsgvq2vZsfyrd7K7vPLUU/KgS0D5yZMe6uipM0+izminnkKrEfdUnz7CxMRb6oHZWw==", + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + "engines": { + "node": ">=4" } }, - "@babel/plugin-proposal-json-strings": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.5.tgz", - "integrity": "sha512-QQJueTFa0y9E4qHANqIvMsuxM/qcLQmKttBACtPCQzGUEizsXDACGonlPiSwynHfOa3vNw0FPMVvQzbuXwh4SQ==", + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-json-strings": "^7.8.3" + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" } }, - "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.5.tgz", - "integrity": "sha512-xqibl7ISO2vjuQM+MzR3rkd0zfNWltk7n9QhaD8ghMmMceVguYrNDt7MikRyj4J4v3QehpnrU8RYLnC7z/gZLA==", + "node_modules/tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + }, + "engines": { + "node": ">=6" } }, - "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.5.tgz", - "integrity": "sha512-YwMsTp/oOviSBhrjwi0vzCUycseCYwoXnLiXIL3YNjHSMBHicGTz7GjVU/IGgz4DtOEXBdCNG72pvCX22ehfqg==", + "node_modules/tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=8" } }, - "@babel/plugin-proposal-numeric-separator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.5.tgz", - "integrity": "sha512-DvB9l/TcsCRvsIV9v4jxR/jVP45cslTVC0PMVHvaJhhNuhn2Y1SOhCSFlPK777qLB5wb8rVDaNoqMTyOqtY5Iw==", + "node_modules/ts-jest": { + "version": "27.1.3", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.3.tgz", + "integrity": "sha512-6Nlura7s6uM9BVUAoqLH7JHyMXjz8gluryjpPXxr3IxZdAXnU6FhjvVLHFtfd1vsE1p8zD1OJfskkc0jhTSnkA==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" + "dependencies": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^27.0.0", + "json5": "2.x", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "7.x", + "yargs-parser": "20.x" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@types/jest": "^27.0.0", + "babel-jest": ">=27.0.0 <28", + "esbuild": "~0.14.0", + "jest": "^27.0.0", + "typescript": ">=3.8 <5.0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@types/jest": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + } } }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.16.5.tgz", - "integrity": "sha512-UEd6KpChoyPhCoE840KRHOlGhEZFutdPDMGj+0I56yuTTOaT51GzmnEl/0uT41fB/vD2nT+Pci2KjezyE3HmUw==", + "node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", "dev": true, - "requires": { - "@babel/compat-data": "^7.16.4", - "@babel/helper-compilation-targets": "^7.16.3", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.16.5" - } + "peer": true }, - "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.5.tgz", - "integrity": "sha512-ihCMxY1Iljmx4bWy/PIMJGXN4NS4oUj1MKynwO07kiKms23pNvIn1DMB92DNB2R0EA882sw0VXIelYGdtF7xEQ==", + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" } }, - "@babel/plugin-proposal-optional-chaining": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.5.tgz", - "integrity": "sha512-kzdHgnaXRonttiTfKYnSVafbWngPPr2qKw9BWYBESl91W54e+9R5pP70LtWxV56g0f05f/SQrwHYkfvbwcdQ/A==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - } + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true }, - "@babel/plugin-proposal-private-methods": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.5.tgz", - "integrity": "sha512-+yFMO4BGT3sgzXo+lrq7orX5mAZt57DwUK6seqII6AcJnJOIhBJ8pzKH47/ql/d426uQ7YhN8DpUFirQzqYSUA==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5" - } + "node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" }, - "@babel/plugin-proposal-private-property-in-object": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.5.tgz", - "integrity": "sha512-+YGh5Wbw0NH3y/E5YMu6ci5qTDmAEVNoZ3I54aB6nVEOZ5BQ7QJlwKq5pYVucQilMByGn/bvX0af+uNaPRCabA==", + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-create-class-features-plugin": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" } }, - "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.5.tgz", - "integrity": "sha512-s5sKtlKQyFSatt781HQwv1hoM5BQ9qRH30r+dK56OLDsHmV74mzwJNX7R1yMuE7VZKG5O6q/gmOGSAO6ikTudg==", + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5" + "engines": { + "node": ">=4" } }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "dependencies": { + "is-typedarray": "^1.0.0" } }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "node_modules/typescript": { + "version": "4.5.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz", + "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" } }, - "@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "engines": { + "node": ">= 4.0.0" } }, - "@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "dependencies": { + "punycode": "^2.1.0" } }, - "@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "node_modules/utf-8-validate": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.8.tgz", + "integrity": "sha512-k4dW/Qja1BYDl2qD4tOMB9PFVha/UJtxTc1cXYOe3WwA/2m0Yn4qB7wLMpJyLJ/7DR0XnTut3HsCSzDT4ZvKgA==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" } }, - "@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" } }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "node_modules/v8-to-istanbul": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", + "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "engines": { + "node": ">=10.12.0" } }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "node_modules/v8-to-istanbul/node_modules/source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "engines": { + "node": ">= 8" } }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "node_modules/w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "dependencies": { + "browser-process-hrtime": "^1.0.0" } }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "node_modules/w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "dependencies": { + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" } }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "dependencies": { + "makeerror": "1.0.12" } }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "node_modules/webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "engines": { + "node": ">=10.4" } }, - "@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "node_modules/whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "dependencies": { + "iconv-lite": "0.4.24" } }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "node_modules/whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "node_modules/whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "dependencies": { + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + }, + "engines": { + "node": ">=10" } }, - "@babel/plugin-syntax-typescript": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.5.tgz", - "integrity": "sha512-/d4//lZ1Vqb4mZ5xTep3dDK888j7BGM/iKqBmndBaoYAFPlPKrGU608VVBz5JeyAb6YQDjRu1UKqj86UhwWVgw==", + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, - "@babel/plugin-transform-arrow-functions": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.5.tgz", - "integrity": "sha512-8bTHiiZyMOyfZFULjsCnYOWG059FVMes0iljEHSfARhNgFfpsqE92OrCffv3veSw9rwMkYcFe9bj0ZoXU2IGtQ==", + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "engines": { + "node": ">=0.10.0" } }, - "@babel/plugin-transform-async-to-generator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.5.tgz", - "integrity": "sha512-TMXgfioJnkXU+XRoj7P2ED7rUm5jbnDWwlCuFVTpQboMfbSya5WrmubNBAMlk7KXvywpo8rd8WuYZkis1o2H8w==", + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-remap-async-to-generator": "^7.16.5" + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "@babel/plugin-transform-block-scoped-functions": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.5.tgz", - "integrity": "sha512-BxmIyKLjUGksJ99+hJyL/HIxLIGnLKtw772zYDER7UuycDZ+Xvzs98ZQw6NGgM2ss4/hlFAaGiZmMNKvValEjw==", + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" } }, - "@babel/plugin-transform-block-scoping": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.5.tgz", - "integrity": "sha512-JxjSPNZSiOtmxjX7PBRBeRJTUKTyJ607YUYeT0QJCNdsedOe+/rXITjP08eG8xUpsLfPirgzdCFN+h0w6RI+pQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "node_modules/ws": { + "version": "7.5.7", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", + "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, - "@babel/plugin-transform-classes": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.5.tgz", - "integrity": "sha512-DzJ1vYf/7TaCYy57J3SJ9rV+JEuvmlnvvyvYKFbk5u46oQbBvuB9/0w+YsVsxkOv8zVWKpDmUoj4T5ILHoXevA==", + "node_modules/xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-environment-visitor": "^7.16.5", - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-optimise-call-expression": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-replace-supers": "^7.16.5", - "@babel/helper-split-export-declaration": "^7.16.0", - "globals": "^11.1.0" + "engines": { + "node": ">=10" } }, - "@babel/plugin-transform-computed-properties": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.5.tgz", - "integrity": "sha512-n1+O7xtU5lSLraRzX88CNcpl7vtGdPakKzww74bVwpAIRgz9JVLJJpOLb0uYqcOaXVM0TL6X0RVeIJGD2CnCkg==", + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "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" + }, + "engines": { + "node": ">=10" } }, - "@babel/plugin-transform-destructuring": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.5.tgz", - "integrity": "sha512-GuRVAsjq+c9YPK6NeTkRLWyQskDC099XkBSVO+6QzbnOnH2d/4mBVXYStaPrZD3dFRfg00I6BFJ9Atsjfs8mlg==", + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "engines": { + "node": ">=10" } - }, - "@babel/plugin-transform-dotall-regex": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.5.tgz", - "integrity": "sha512-iQiEMt8Q4/5aRGHpGVK2Zc7a6mx7qEAO7qehgSug3SDImnuMzgmm/wtJALXaz25zUj1PmnNHtShjFgk4PDx4nw==", + } + }, + "dependencies": { + "@ampproject/remapping": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.0.tgz", + "integrity": "sha512-d5RysTlJ7hmw5Tw4UxgxcY3lkMe92n8sXCcuLPAyIAHK6j8DefDwtGnVVDgOnv+RnEosulDJ9NPKQL27bDId0g==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5" + "@jridgewell/trace-mapping": "^0.3.0" } }, - "@babel/plugin-transform-duplicate-keys": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.5.tgz", - "integrity": "sha512-81tijpDg2a6I1Yhj4aWY1l3O1J4Cg/Pd7LfvuaH2VVInAkXtzibz9+zSPdUM1WvuUi128ksstAP0hM5w48vQgg==", + "@babel/code-frame": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/highlight": "^7.16.7" + } + }, + "@babel/compat-data": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.0.tgz", + "integrity": "sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng==", + "dev": true + }, + "@babel/core": { + "version": "7.17.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.2.tgz", + "integrity": "sha512-R3VH5G42VSDolRHyUO4V2cfag8WHcZyxdq5Z/m8Xyb92lW/Erm/6kM+XtRFGf3Mulre3mveni2NHfEUws8wSvw==", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.0.0", + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.0", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helpers": "^7.17.2", + "@babel/parser": "^7.17.0", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.0", + "@babel/types": "^7.17.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, - "@babel/plugin-transform-exponentiation-operator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.5.tgz", - "integrity": "sha512-12rba2HwemQPa7BLIKCzm1pT2/RuQHtSFHdNl41cFiC6oi4tcrp7gjB07pxQvFpcADojQywSjblQth6gJyE6CA==", + "@babel/generator": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.0.tgz", + "integrity": "sha512-I3Omiv6FGOC29dtlZhkfXO6pgkmukJSlT26QjVvS1DGZe/NzSVCPG41X0tS21oZkJYlovfj9qDWgKP+Cn4bXxw==", "dev": true, "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/types": "^7.17.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } } }, - "@babel/plugin-transform-for-of": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.5.tgz", - "integrity": "sha512-+DpCAJFPAvViR17PIMi9x2AE34dll5wNlXO43wagAX2YcRGgEVHCNFC4azG85b4YyyFarvkc/iD5NPrz4Oneqw==", + "@babel/helper-compilation-targets": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", + "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/compat-data": "^7.16.4", + "@babel/helper-validator-option": "^7.16.7", + "browserslist": "^4.17.5", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, - "@babel/plugin-transform-function-name": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.5.tgz", - "integrity": "sha512-Fuec/KPSpVLbGo6z1RPw4EE1X+z9gZk1uQmnYy7v4xr4TO9p41v1AoUuXEtyqAI7H+xNJYSICzRqZBhDEkd3kQ==", + "@babel/helper-environment-visitor": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", + "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/types": "^7.16.7" } }, - "@babel/plugin-transform-literals": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.5.tgz", - "integrity": "sha512-B1j9C/IfvshnPcklsc93AVLTrNVa69iSqztylZH6qnmiAsDDOmmjEYqOm3Ts2lGSgTSywnBNiqC949VdD0/gfw==", + "@babel/helper-function-name": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", + "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-get-function-arity": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" } }, - "@babel/plugin-transform-member-expression-literals": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.5.tgz", - "integrity": "sha512-d57i3vPHWgIde/9Y8W/xSFUndhvhZN5Wu2TjRrN1MVz5KzdUihKnfDVlfP1U7mS5DNj/WHHhaE4/tTi4hIyHwQ==", + "@babel/helper-get-function-arity": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", + "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/types": "^7.16.7" } }, - "@babel/plugin-transform-modules-amd": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.5.tgz", - "integrity": "sha512-oHI15S/hdJuSCfnwIz+4lm6wu/wBn7oJ8+QrkzPPwSFGXk8kgdI/AIKcbR/XnD1nQVMg/i6eNaXpszbGuwYDRQ==", + "@babel/helper-hoist-variables": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", + "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5", - "babel-plugin-dynamic-import-node": "^2.3.3" + "@babel/types": "^7.16.7" } }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.5.tgz", - "integrity": "sha512-ABhUkxvoQyqhCWyb8xXtfwqNMJD7tx+irIRnUh6lmyFud7Jln1WzONXKlax1fg/ey178EXbs4bSGNd6PngO+SQ==", + "@babel/helper-module-imports": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", + "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-simple-access": "^7.16.0", - "babel-plugin-dynamic-import-node": "^2.3.3" + "@babel/types": "^7.16.7" } }, - "@babel/plugin-transform-modules-systemjs": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.5.tgz", - "integrity": "sha512-53gmLdScNN28XpjEVIm7LbWnD/b/TpbwKbLk6KV4KqC9WyU6rq1jnNmVG6UgAdQZVVGZVoik3DqHNxk4/EvrjA==", + "@babel/helper-module-transforms": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz", + "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==", "dev": true, "requires": { - "@babel/helper-hoist-variables": "^7.16.0", - "@babel/helper-module-transforms": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-validator-identifier": "^7.15.7", - "babel-plugin-dynamic-import-node": "^2.3.3" + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-simple-access": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" } }, - "@babel/plugin-transform-modules-umd": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.5.tgz", - "integrity": "sha512-qTFnpxHMoenNHkS3VoWRdwrcJ3FhX567GvDA3hRZKF0Dj8Fmg0UzySZp3AP2mShl/bzcywb/UWAMQIjA1bhXvw==", + "@babel/helper-plugin-utils": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", + "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", + "dev": true + }, + "@babel/helper-simple-access": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", + "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/types": "^7.16.7" } }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.5.tgz", - "integrity": "sha512-/wqGDgvFUeKELW6ex6QB7dLVRkd5ehjw34tpXu1nhKC0sFfmaLabIswnpf8JgDyV2NeDmZiwoOb0rAmxciNfjA==", + "@babel/helper-split-export-declaration": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", + "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.16.0" + "@babel/types": "^7.16.7" } }, - "@babel/plugin-transform-new-target": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.5.tgz", - "integrity": "sha512-ZaIrnXF08ZC8jnKR4/5g7YakGVL6go6V9ql6Jl3ecO8PQaQqFE74CuM384kezju7Z9nGCCA20BqZaR1tJ/WvHg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.5" - } + "@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", + "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", + "dev": true }, - "@babel/plugin-transform-object-super": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.5.tgz", - "integrity": "sha512-tded+yZEXuxt9Jdtkc1RraW1zMF/GalVxaVVxh41IYwirdRgyAxxxCKZ9XB7LxZqmsjfjALxupNE1MIz9KH+Zg==", + "@babel/helpers": { + "version": "7.17.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.2.tgz", + "integrity": "sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-replace-supers": "^7.16.5" + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.0", + "@babel/types": "^7.17.0" } }, - "@babel/plugin-transform-parameters": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.5.tgz", - "integrity": "sha512-B3O6AL5oPop1jAVg8CV+haeUte9oFuY85zu0jwnRNZZi3tVAbJriu5tag/oaO2kGaQM/7q7aGPBlTI5/sr9enA==", + "@babel/highlight": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, - "@babel/plugin-transform-property-literals": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.5.tgz", - "integrity": "sha512-+IRcVW71VdF9pEH/2R/Apab4a19LVvdVsr/gEeotH00vSDVlKD+XgfSIw+cgGWsjDB/ziqGv/pGoQZBIiQVXHg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.5" - } + "@babel/parser": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.0.tgz", + "integrity": "sha512-VKXSCQx5D8S04ej+Dqsr1CzYvvWgf20jIw2D+YhQCrIlr2UZGaDds23Y0xg75/skOxpLCRpUZvk/1EAVkGoDOw==", + "dev": true }, - "@babel/plugin-transform-regenerator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.5.tgz", - "integrity": "sha512-2z+it2eVWU8TtQQRauvGUqZwLy4+7rTfo6wO4npr+fvvN1SW30ZF3O/ZRCNmTuu4F5MIP8OJhXAhRV5QMJOuYg==", + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, "requires": { - "regenerator-transform": "^0.14.2" + "@babel/helper-plugin-utils": "^7.8.0" } }, - "@babel/plugin-transform-reserved-words": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.5.tgz", - "integrity": "sha512-aIB16u8lNcf7drkhXJRoggOxSTUAuihTSTfAcpynowGJOZiGf+Yvi7RuTwFzVYSYPmWyARsPqUGoZWWWxLiknw==", + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.8.0" } }, - "@babel/plugin-transform-shorthand-properties": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.5.tgz", - "integrity": "sha512-ZbuWVcY+MAXJuuW7qDoCwoxDUNClfZxoo7/4swVbOW1s/qYLOMHlm9YRWMsxMFuLs44eXsv4op1vAaBaBaDMVg==", + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.12.13" } }, - "@babel/plugin-transform-spread": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.5.tgz", - "integrity": "sha512-5d6l/cnG7Lw4tGHEoga4xSkYp1euP7LAtrah1h1PgJ3JY7yNsjybsxQAnVK4JbtReZ/8z6ASVmd3QhYYKLaKZw==", + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0" + "@babel/helper-plugin-utils": "^7.10.4" } }, - "@babel/plugin-transform-sticky-regex": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.5.tgz", - "integrity": "sha512-usYsuO1ID2LXxzuUxifgWtJemP7wL2uZtyrTVM4PKqsmJycdS4U4mGovL5xXkfUheds10Dd2PjoQLXw6zCsCbg==", + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.8.0" } }, - "@babel/plugin-transform-template-literals": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.5.tgz", - "integrity": "sha512-gnyKy9RyFhkovex4BjKWL3BVYzUDG6zC0gba7VMLbQoDuqMfJ1SDXs8k/XK41Mmt1Hyp4qNAvGFb9hKzdCqBRQ==", + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.10.4" } }, - "@babel/plugin-transform-typeof-symbol": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.5.tgz", - "integrity": "sha512-ldxCkW180qbrvyCVDzAUZqB0TAeF8W/vGJoRcaf75awm6By+PxfJKvuqVAnq8N9wz5Xa6mSpM19OfVKKVmGHSQ==", + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.8.0" } }, - "@babel/plugin-transform-typescript": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.1.tgz", - "integrity": "sha512-NO4XoryBng06jjw/qWEU2LhcLJr1tWkhpMam/H4eas/CDKMX/b2/Ylb6EI256Y7+FVPCawwSM1rrJNOpDiz+Lg==", + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.16.0", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-typescript": "^7.16.0" + "@babel/helper-plugin-utils": "^7.10.4" } }, - "@babel/plugin-transform-unicode-escapes": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.5.tgz", - "integrity": "sha512-shiCBHTIIChGLdyojsKQjoAyB8MBwat25lKM7MJjbe1hE0bgIppD+LX9afr41lLHOhqceqeWl4FkLp+Bgn9o1Q==", + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.8.0" } }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.5.tgz", - "integrity": "sha512-GTJ4IW012tiPEMMubd7sD07iU9O/LOo8Q/oU4xNhcaq0Xn8+6TcUQaHtC8YxySo1T+ErQ8RaWogIEeFhKGNPzw==", + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.8.0" } }, - "@babel/preset-env": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.16.5.tgz", - "integrity": "sha512-MiJJW5pwsktG61NDxpZ4oJ1CKxM1ncam9bzRtx9g40/WkLRkxFP6mhpkYV0/DxcciqoiHicx291+eUQrXb/SfQ==", + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, "requires": { - "@babel/compat-data": "^7.16.4", - "@babel/helper-compilation-targets": "^7.16.3", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-validator-option": "^7.14.5", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.16.2", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.16.0", - "@babel/plugin-proposal-async-generator-functions": "^7.16.5", - "@babel/plugin-proposal-class-properties": "^7.16.5", - "@babel/plugin-proposal-class-static-block": "^7.16.5", - "@babel/plugin-proposal-dynamic-import": "^7.16.5", - "@babel/plugin-proposal-export-namespace-from": "^7.16.5", - "@babel/plugin-proposal-json-strings": "^7.16.5", - "@babel/plugin-proposal-logical-assignment-operators": "^7.16.5", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.5", - "@babel/plugin-proposal-numeric-separator": "^7.16.5", - "@babel/plugin-proposal-object-rest-spread": "^7.16.5", - "@babel/plugin-proposal-optional-catch-binding": "^7.16.5", - "@babel/plugin-proposal-optional-chaining": "^7.16.5", - "@babel/plugin-proposal-private-methods": "^7.16.5", - "@babel/plugin-proposal-private-property-in-object": "^7.16.5", - "@babel/plugin-proposal-unicode-property-regex": "^7.16.5", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.16.5", - "@babel/plugin-transform-async-to-generator": "^7.16.5", - "@babel/plugin-transform-block-scoped-functions": "^7.16.5", - "@babel/plugin-transform-block-scoping": "^7.16.5", - "@babel/plugin-transform-classes": "^7.16.5", - "@babel/plugin-transform-computed-properties": "^7.16.5", - "@babel/plugin-transform-destructuring": "^7.16.5", - "@babel/plugin-transform-dotall-regex": "^7.16.5", - "@babel/plugin-transform-duplicate-keys": "^7.16.5", - "@babel/plugin-transform-exponentiation-operator": "^7.16.5", - "@babel/plugin-transform-for-of": "^7.16.5", - "@babel/plugin-transform-function-name": "^7.16.5", - "@babel/plugin-transform-literals": "^7.16.5", - "@babel/plugin-transform-member-expression-literals": "^7.16.5", - "@babel/plugin-transform-modules-amd": "^7.16.5", - "@babel/plugin-transform-modules-commonjs": "^7.16.5", - "@babel/plugin-transform-modules-systemjs": "^7.16.5", - "@babel/plugin-transform-modules-umd": "^7.16.5", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.16.5", - "@babel/plugin-transform-new-target": "^7.16.5", - "@babel/plugin-transform-object-super": "^7.16.5", - "@babel/plugin-transform-parameters": "^7.16.5", - "@babel/plugin-transform-property-literals": "^7.16.5", - "@babel/plugin-transform-regenerator": "^7.16.5", - "@babel/plugin-transform-reserved-words": "^7.16.5", - "@babel/plugin-transform-shorthand-properties": "^7.16.5", - "@babel/plugin-transform-spread": "^7.16.5", - "@babel/plugin-transform-sticky-regex": "^7.16.5", - "@babel/plugin-transform-template-literals": "^7.16.5", - "@babel/plugin-transform-typeof-symbol": "^7.16.5", - "@babel/plugin-transform-unicode-escapes": "^7.16.5", - "@babel/plugin-transform-unicode-regex": "^7.16.5", - "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.16.0", - "babel-plugin-polyfill-corejs2": "^0.3.0", - "babel-plugin-polyfill-corejs3": "^0.4.0", - "babel-plugin-polyfill-regenerator": "^0.3.0", - "core-js-compat": "^3.19.1", - "semver": "^6.3.0" + "@babel/helper-plugin-utils": "^7.8.0" } }, - "@babel/preset-modules": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", - "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", + "@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" + "@babel/helper-plugin-utils": "^7.14.5" } }, - "@babel/preset-typescript": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.16.5.tgz", - "integrity": "sha512-lmAWRoJ9iOSvs3DqOndQpj8XqXkzaiQs50VG/zESiI9D3eoZhGriU675xNCr0UwvsuXrhMAGvyk1w+EVWF3u8Q==", + "@babel/plugin-syntax-typescript": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz", + "integrity": "sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-validator-option": "^7.14.5", - "@babel/plugin-transform-typescript": "^7.16.1" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/runtime": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz", - "integrity": "sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==", + "version": "7.17.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz", + "integrity": "sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==", "requires": { "regenerator-runtime": "^0.13.4" } }, "@babel/template": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.0.tgz", - "integrity": "sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", + "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", "dev": true, "requires": { - "@babel/code-frame": "^7.16.0", - "@babel/parser": "^7.16.0", - "@babel/types": "^7.16.0" + "@babel/code-frame": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" } }, "@babel/traverse": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.5.tgz", - "integrity": "sha512-FOCODAzqUMROikDYLYxl4nmwiLlu85rNqBML/A5hKRVXG2LV8d0iMqgPzdYTcIpjZEBB7D6UDU9vxRZiriASdQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.16.0", - "@babel/generator": "^7.16.5", - "@babel/helper-environment-visitor": "^7.16.5", - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-hoist-variables": "^7.16.0", - "@babel/helper-split-export-declaration": "^7.16.0", - "@babel/parser": "^7.16.5", - "@babel/types": "^7.16.0", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.0.tgz", + "integrity": "sha512-fpFIXvqD6kC7c7PUNnZ0Z8cQXlarCLtCUpt2S1Dx7PjoRtCFffvOkHHSom+m5HIxMZn5bIBVb71lhabcmjEsqg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.0", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/parser": "^7.17.0", + "@babel/types": "^7.17.0", "debug": "^4.1.0", "globals": "^11.1.0" + }, + "dependencies": { + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + } } }, "@babel/types": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.8.tgz", - "integrity": "sha512-smN2DQc5s4M7fntyjGtyIPbRJv6wW4rU/94fmYJ7PKQuZkC0qGMHXJbg6sNGt12JmVr4k5YaptI/XtiLJBnmIg==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.16.7", @@ -10805,19 +6740,10 @@ "strip-json-comments": "^3.1.1" }, "dependencies": { - "globals": { - "version": "13.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", - "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true } } @@ -10846,9 +6772,9 @@ } }, "@humanwhocodes/config-array": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.2.tgz", - "integrity": "sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.3.tgz", + "integrity": "sha512-3xSMlXHh03hCcCmFc0rbKp3Ivt2PFEJnQUJDDMTJQ2wkECZWdq4GePs2ctc5H8zV+cHPaq8k2vU8mrQjA6iHdQ==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.1", @@ -10909,411 +6835,187 @@ "dev": true }, "@jest/console": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.4.6.tgz", - "integrity": "sha512-jauXyacQD33n47A44KrlOVeiXHEXDqapSdfb9kTekOchH/Pd18kBIO1+xxJQRLuG+LUuljFCwTG92ra4NW7SpA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", + "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", "dev": true, "requires": { - "@jest/types": "^27.4.2", + "@jest/types": "^27.5.1", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^27.4.6", - "jest-util": "^27.4.2", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", "slash": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } } }, "@jest/core": { - "version": "27.4.7", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.4.7.tgz", - "integrity": "sha512-n181PurSJkVMS+kClIFSX/LLvw9ExSb+4IMtD6YnfxZVerw9ANYtW0bPrm0MJu2pfe9SY9FJ9FtQ+MdZkrZwjg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", + "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", "dev": true, "requires": { - "@jest/console": "^27.4.6", - "@jest/reporters": "^27.4.6", - "@jest/test-result": "^27.4.6", - "@jest/transform": "^27.4.6", - "@jest/types": "^27.4.2", + "@jest/console": "^27.5.1", + "@jest/reporters": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "emittery": "^0.8.1", "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-changed-files": "^27.4.2", - "jest-config": "^27.4.7", - "jest-haste-map": "^27.4.6", - "jest-message-util": "^27.4.6", - "jest-regex-util": "^27.4.0", - "jest-resolve": "^27.4.6", - "jest-resolve-dependencies": "^27.4.6", - "jest-runner": "^27.4.6", - "jest-runtime": "^27.4.6", - "jest-snapshot": "^27.4.6", - "jest-util": "^27.4.2", - "jest-validate": "^27.4.6", - "jest-watcher": "^27.4.6", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^27.5.1", + "jest-config": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-resolve-dependencies": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "jest-watcher": "^27.5.1", "micromatch": "^4.0.4", "rimraf": "^3.0.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } } }, "@jest/environment": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.4.6.tgz", - "integrity": "sha512-E6t+RXPfATEEGVidr84WngLNWZ8ffCPky8RqqRK6u1Bn0LK92INe0MDttyPl/JOzaq92BmDzOeuqk09TvM22Sg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", + "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", "dev": true, "requires": { - "@jest/fake-timers": "^27.4.6", - "@jest/types": "^27.4.2", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", "@types/node": "*", - "jest-mock": "^27.4.6" + "jest-mock": "^27.5.1" } }, "@jest/fake-timers": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.4.6.tgz", - "integrity": "sha512-mfaethuYF8scV8ntPpiVGIHQgS0XIALbpY2jt2l7wb/bvq4Q5pDLk4EP4D7SAvYT1QrPOPVZAtbdGAOOyIgs7A==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", + "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", "dev": true, "requires": { - "@jest/types": "^27.4.2", + "@jest/types": "^27.5.1", "@sinonjs/fake-timers": "^8.0.1", - "@types/node": "*", - "jest-message-util": "^27.4.6", - "jest-mock": "^27.4.6", - "jest-util": "^27.4.2" - } - }, - "@jest/globals": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.4.6.tgz", - "integrity": "sha512-kAiwMGZ7UxrgPzu8Yv9uvWmXXxsy0GciNejlHvfPIfWkSxChzv6bgTS3YqBkGuHcis+ouMFI2696n2t+XYIeFw==", - "dev": true, - "requires": { - "@jest/environment": "^27.4.6", - "@jest/types": "^27.4.2", - "expect": "^27.4.6" - } - }, - "@jest/reporters": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.4.6.tgz", - "integrity": "sha512-+Zo9gV81R14+PSq4wzee4GC2mhAN9i9a7qgJWL90Gpx7fHYkWpTBvwWNZUXvJByYR9tAVBdc8VxDWqfJyIUrIQ==", - "dev": true, - "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.4.6", - "@jest/test-result": "^27.4.6", - "@jest/transform": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.4", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-haste-map": "^27.4.6", - "jest-resolve": "^27.4.6", - "jest-util": "^27.4.2", - "jest-worker": "^27.4.6", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^8.1.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "@types/node": "*", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" + } + }, + "@jest/globals": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", + "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", + "dev": true, + "requires": { + "@jest/environment": "^27.5.1", + "@jest/types": "^27.5.1", + "expect": "^27.5.1" + } + }, + "@jest/reporters": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", + "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-haste-map": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^8.1.0" } }, "@jest/source-map": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.4.0.tgz", - "integrity": "sha512-Ntjx9jzP26Bvhbm93z/AKcPRj/9wrkI88/gK60glXDx1q+IeI0rf7Lw2c89Ch6ofonB0On/iRDreQuQ6te9pgQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", + "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", "dev": true, "requires": { "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } } }, "@jest/test-result": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.4.6.tgz", - "integrity": "sha512-fi9IGj3fkOrlMmhQqa/t9xum8jaJOOAi/lZlm6JXSc55rJMXKHxNDN1oCP39B0/DhNOa2OMupF9BcKZnNtXMOQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", + "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", "dev": true, "requires": { - "@jest/console": "^27.4.6", - "@jest/types": "^27.4.2", + "@jest/console": "^27.5.1", + "@jest/types": "^27.5.1", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/test-sequencer": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.4.6.tgz", - "integrity": "sha512-3GL+nsf6E1PsyNsJuvPyIz+DwFuCtBdtvPpm/LMXVkBJbdFvQYCDpccYT56qq5BGniXWlE81n2qk1sdXfZebnw==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", + "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", "dev": true, "requires": { - "@jest/test-result": "^27.4.6", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.6", - "jest-runtime": "^27.4.6" + "@jest/test-result": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-runtime": "^27.5.1" } }, "@jest/transform": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.4.6.tgz", - "integrity": "sha512-9MsufmJC8t5JTpWEQJ0OcOOAXaH5ioaIX6uHVBLBMoCZPfKKQF+EqP8kACAvCZ0Y1h2Zr3uOccg8re+Dr5jxyw==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", + "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/types": "^27.4.2", + "@jest/types": "^27.5.1", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.6", - "jest-regex-util": "^27.4.0", - "jest-util": "^27.4.2", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-util": "^27.5.1", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", "source-map": "^0.6.1", "write-file-atomic": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } } }, "@jest/types": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.4.2.tgz", - "integrity": "sha512-j35yw0PMTPpZsUoOBiuHzr1zTYoad1cVIE0ajEjcrJONxxrko/IRGKkXx3os0Nsi4Hu3+5VmDbVfq5WhG/pWAg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -11321,57 +7023,28 @@ "@types/node": "*", "@types/yargs": "^16.0.0", "chalk": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + } + }, + "@jridgewell/resolve-uri": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.4.tgz", + "integrity": "sha512-cz8HFjOFfUBtvN+NXYSFMHYRdxZMaEl0XypVrhzxBgadKIXhIkRd8aMeHhmF56Sl7SuS8OnUpQ73/k9LE4VnLg==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.10.tgz", + "integrity": "sha512-Ht8wIW5v165atIX1p+JvKR5ONzUyF4Ac8DZIQ5kZs9zrb6M8SJNXpx1zn04rn65VjBMygRoMXcyYwNK0fT7bEg==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", + "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" } }, "@nodelib/fs.scandir": { @@ -11401,9 +7074,9 @@ } }, "@project-serum/borsh": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@project-serum/borsh/-/borsh-0.2.3.tgz", - "integrity": "sha512-lH9zEYADZE3cxrgiFym8+jbUE3NM/LH+WOKYcUjs65CT10Q64Hv45bcAAa/phwYk4Tpz0uQ1x+ergFaAoGt67Q==", + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@project-serum/borsh/-/borsh-0.2.4.tgz", + "integrity": "sha512-tQPc1ktAp1Jtn9D72DmObAfhAic9ivfYBOS5b+T4H7MvkQ84uML88LY1LfvGep30mCy+ua5rf+X9ocPfg6u9MA==", "requires": { "bn.js": "^5.1.2", "buffer-layout": "^1.2.0" @@ -11431,14 +7104,6 @@ "is-reference": "^1.2.1", "magic-string": "^0.25.7", "resolve": "^1.17.0" - }, - "dependencies": { - "estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true - } } }, "@rollup/plugin-json": { @@ -11500,6 +7165,14 @@ "@types/estree": "0.0.39", "estree-walker": "^1.0.1", "picomatch": "^2.2.2" + }, + "dependencies": { + "estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "dev": true + } } }, "@sinonjs/commons": { @@ -11542,9 +7215,9 @@ } }, "@solana/web3.js": { - "version": "1.31.0", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.31.0.tgz", - "integrity": "sha512-7nHHx1JNFnrt15e9y8m38I/EJCbaB+bFC3KZVM1+QhybCikFxGMtGA5r7PDC3GEL1R2RZA8yKoLkDKo3vzzqnw==", + "version": "1.34.0", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.34.0.tgz", + "integrity": "sha512-6QvqN2DqEELvuV+5yUQM8P9fRiSG+6SzQ58HjumJqODu14r7eu5HXVWEymvKAvMLGME+0TmAdJHjw9xD5NgUWA==", "requires": { "@babel/runtime": "^7.12.5", "@ethersproject/sha2": "^5.5.0", @@ -11599,9 +7272,9 @@ "dev": true }, "@types/babel__core": { - "version": "7.1.17", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.17.tgz", - "integrity": "sha512-6zzkezS9QEIL8yCBvXWxPTJPNuMeECJVxSOhxNY/jfq9LxOTHivaYTqr37n9LknWWRTIkzqH2UilS5QFvfa90A==", + "version": "7.1.18", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.18.tgz", + "integrity": "sha512-S7unDjm/C7z2A2R9NzfKCK1I+BAALDtxEmsJBwlB3EzNfb929ykjL++1CK9LO++EIp2fQrC8O+BwjKvz6UeDyQ==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -11663,9 +7336,9 @@ "dev": true }, "@types/express-serve-static-core": { - "version": "4.17.27", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.27.tgz", - "integrity": "sha512-e/sVallzUTPdyOTiqi8O8pMdBBphscvI6E4JYaKlja4Lm+zh7UFSSdW5VMkRbhDtmrONqOUHOXRguPsDckzxNA==", + "version": "4.17.28", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", + "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", "requires": { "@types/node": "*", "@types/qs": "*", @@ -11706,9 +7379,9 @@ } }, "@types/jest": { - "version": "27.0.3", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.0.3.tgz", - "integrity": "sha512-cmmwv9t7gBYt7hNKH5Spu7Kuu/DotGa+Ff+JGRKZ4db5eh8PnKS4LuebJ3YLUoyOyIHraTGyULn23YtEAm0VSg==", + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.0.tgz", + "integrity": "sha512-gHl8XuC1RZ8H2j5sHv/JqsaxXkDDM9iDOgu0Wp8sjs4u/snb2PVehyWXJPr+ORA0RPpgw231mnutWI1+0hgjIQ==", "dev": true, "requires": { "jest-diff": "^27.0.0", @@ -11727,14 +7400,14 @@ "integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==" }, "@types/node": { - "version": "17.0.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.5.tgz", - "integrity": "sha512-w3mrvNXLeDYV1GKTZorGJQivK6XLCoGwpnyJFbJVK/aTBQUxOCaa/GlFAAN3OTDFcb7h5tiFG+YXCO2By+riZw==" + "version": "17.0.17", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.17.tgz", + "integrity": "sha512-e8PUNQy1HgJGV3iU/Bp2+D/DXh3PYeyli8LgIwsQcs1Ar1LoaWHSIT6Rw+H2rNJmiq6SNWiDytfx8+gYj7wDHw==" }, "@types/prettier": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.3.tgz", - "integrity": "sha512-QzSuZMBuG5u8HqYz01qtMdg/Jfctlnvj1z/lYnIDXs/golxw0fxtRAHd9KrzjR7Yxz1qVeI00o0kiO3PmVdJ9w==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.4.tgz", + "integrity": "sha512-ReVR2rLTV1kvtlWFyuot+d1pkpG2Fw/XKE3PDAdj57rbM97ttSp9JZ2UsP+2EHTylra9cUf6JA7tGwW1INzUrA==", "dev": true }, "@types/qs": { @@ -11786,131 +7459,97 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.8.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.8.1.tgz", - "integrity": "sha512-wTZ5oEKrKj/8/366qTM366zqhIKAp6NCMweoRONtfuC07OAU9nVI2GZZdqQ1qD30WAAtcPdkH+npDwtRFdp4Rw==", + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.11.0.tgz", + "integrity": "sha512-HJh33bgzXe6jGRocOj4FmefD7hRY4itgjzOrSs3JPrTNXsX7j5+nQPciAUj/1nZtwo2kAc3C75jZO+T23gzSGw==", "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "5.8.1", - "@typescript-eslint/scope-manager": "5.8.1", + "@typescript-eslint/scope-manager": "5.11.0", + "@typescript-eslint/type-utils": "5.11.0", + "@typescript-eslint/utils": "5.11.0", "debug": "^4.3.2", "functional-red-black-tree": "^1.0.1", "ignore": "^5.1.8", "regexpp": "^3.2.0", "semver": "^7.3.5", "tsutils": "^3.21.0" - }, - "dependencies": { - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } } }, - "@typescript-eslint/experimental-utils": { - "version": "5.8.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.8.1.tgz", - "integrity": "sha512-fbodVnjIDU4JpeXWRDsG5IfIjYBxEvs8EBO8W1+YVdtrc2B9ppfof5sZhVEDOtgTfFHnYQJDI8+qdqLYO4ceww==", + "@typescript-eslint/parser": { + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.11.0.tgz", + "integrity": "sha512-x0DCjetHZYBRovJdr3U0zG9OOdNXUaFLJ82ehr1AlkArljJuwEsgnud+Q7umlGDFLFrs8tU8ybQDFocp/eX8mQ==", "dev": true, "requires": { - "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.8.1", - "@typescript-eslint/types": "5.8.1", - "@typescript-eslint/typescript-estree": "5.8.1", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - }, - "dependencies": { - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - } + "@typescript-eslint/scope-manager": "5.11.0", + "@typescript-eslint/types": "5.11.0", + "@typescript-eslint/typescript-estree": "5.11.0", + "debug": "^4.3.2" } }, - "@typescript-eslint/parser": { - "version": "5.8.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.8.1.tgz", - "integrity": "sha512-K1giKHAjHuyB421SoXMXFHHVI4NdNY603uKw92++D3qyxSeYvC10CBJ/GE5Thpo4WTUvu1mmJI2/FFkz38F2Gw==", + "@typescript-eslint/scope-manager": { + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.11.0.tgz", + "integrity": "sha512-z+K4LlahDFVMww20t/0zcA7gq/NgOawaLuxgqGRVKS0PiZlCTIUtX0EJbC0BK1JtR4CelmkPK67zuCgpdlF4EA==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.8.1", - "@typescript-eslint/types": "5.8.1", - "@typescript-eslint/typescript-estree": "5.8.1", - "debug": "^4.3.2" + "@typescript-eslint/types": "5.11.0", + "@typescript-eslint/visitor-keys": "5.11.0" } }, - "@typescript-eslint/scope-manager": { - "version": "5.8.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.8.1.tgz", - "integrity": "sha512-DGxJkNyYruFH3NIZc3PwrzwOQAg7vvgsHsHCILOLvUpupgkwDZdNq/cXU3BjF4LNrCsVg0qxEyWasys5AiJ85Q==", + "@typescript-eslint/type-utils": { + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.11.0.tgz", + "integrity": "sha512-wDqdsYO6ofLaD4DsGZ0jGwxp4HrzD2YKulpEZXmgN3xo4BHJwf7kq49JTRpV0Gx6bxkSUmc9s0EIK1xPbFFpIA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.8.1", - "@typescript-eslint/visitor-keys": "5.8.1" + "@typescript-eslint/utils": "5.11.0", + "debug": "^4.3.2", + "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.8.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.8.1.tgz", - "integrity": "sha512-L/FlWCCgnjKOLefdok90/pqInkomLnAcF9UAzNr+DSqMC3IffzumHTQTrINXhP1gVp9zlHiYYjvozVZDPleLcA==", + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.11.0.tgz", + "integrity": "sha512-cxgBFGSRCoBEhvSVLkKw39+kMzUKHlJGVwwMbPcTZX3qEhuXhrjwaZXWMxVfxDgyMm+b5Q5b29Llo2yow8Y7xQ==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.8.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.8.1.tgz", - "integrity": "sha512-26lQ8l8tTbG7ri7xEcCFT9ijU5Fk+sx/KRRyyzCv7MQ+rZZlqiDPtMKWLC8P7o+dtCnby4c+OlxuX1tp8WfafQ==", + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.11.0.tgz", + "integrity": "sha512-yVH9hKIv3ZN3lw8m/Jy5I4oXO4ZBMqijcXCdA4mY8ull6TPTAoQnKKrcZ0HDXg7Bsl0Unwwx7jcXMuNZc0m4lg==", "dev": true, "requires": { - "@typescript-eslint/types": "5.8.1", - "@typescript-eslint/visitor-keys": "5.8.1", + "@typescript-eslint/types": "5.11.0", + "@typescript-eslint/visitor-keys": "5.11.0", "debug": "^4.3.2", "globby": "^11.0.4", "is-glob": "^4.0.3", "semver": "^7.3.5", "tsutils": "^3.21.0" - }, - "dependencies": { - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } + } + }, + "@typescript-eslint/utils": { + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.11.0.tgz", + "integrity": "sha512-g2I480tFE1iYRDyMhxPAtLQ9HAn0jjBtipgTCZmd9I9s11OV8CTsG+YfFciuNDcHqm4csbAgC2aVZCHzLxMSUw==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.11.0", + "@typescript-eslint/types": "5.11.0", + "@typescript-eslint/typescript-estree": "5.11.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" } }, "@typescript-eslint/visitor-keys": { - "version": "5.8.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.8.1.tgz", - "integrity": "sha512-SWgiWIwocK6NralrJarPZlWdr0hZnj5GXHIgfdm8hNkyKvpeQuFyLP6YjSIe9kf3YBIfU6OHSZLYkQ+smZwtNg==", + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.11.0.tgz", + "integrity": "sha512-E8w/vJReMGuloGxJDkpPlGwhxocxOpSVgSvjiLO5IxZPmxZF30weOeJYyPSEACwM+X4NziYS9q+WkN/2DHYQwA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.8.1", + "@typescript-eslint/types": "5.11.0", "eslint-visitor-keys": "^3.0.0" } }, @@ -11978,12 +7617,6 @@ "uri-js": "^4.2.2" } }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, "ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -11991,6 +7624,14 @@ "dev": true, "requires": { "type-fest": "^0.21.3" + }, + "dependencies": { + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true + } } }, "ansi-regex": { @@ -12000,12 +7641,12 @@ "dev": true }, "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "color-convert": "^2.0.1" } }, "anymatch": { @@ -12024,36 +7665,12 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "array-includes": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", - "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.7" - } - }, "array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, - "array.prototype.flatmap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.5.tgz", - "integrity": "sha512-08u6rVyi1Lj7oqWbS9nUxliETrtIROT4XGTA4D/LWGten6E3ocm7cy9SIrmNHOL5XVbVuckUp3X6Xyg8/zpvHA==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0" - } - }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -12061,79 +7678,19 @@ "dev": true }, "babel-jest": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.4.6.tgz", - "integrity": "sha512-qZL0JT0HS1L+lOuH+xC2DVASR3nunZi/ozGhpgauJHgmI7f8rudxf6hUjEHympdQ/J64CdKmPkgfJ+A3U6QCrg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", + "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", "dev": true, "requires": { - "@jest/transform": "^27.4.6", - "@jest/types": "^27.4.2", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^27.4.0", + "babel-preset-jest": "^27.5.1", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "slash": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", - "dev": true, - "requires": { - "object.assign": "^4.1.0" } }, "babel-plugin-istanbul": { @@ -12150,9 +7707,9 @@ } }, "babel-plugin-jest-hoist": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.4.0.tgz", - "integrity": "sha512-Jcu7qS4OX5kTWBc45Hz7BMmgXuJqRnhatqpUhnzGC3OBYpOmf2tv6jFNwZpwM7wU7MUuv2r9IPS/ZlYOuburVw==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", + "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", "dev": true, "requires": { "@babel/template": "^7.3.3", @@ -12161,36 +7718,6 @@ "@types/babel__traverse": "^7.0.6" } }, - "babel-plugin-polyfill-corejs2": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.0.tgz", - "integrity": "sha512-wMDoBJ6uG4u4PNFh72Ty6t3EgfA91puCuAwKIazbQlci+ENb/UU9A3xG5lutjUIiXCIn1CY5L15r9LimiJyrSA==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.13.11", - "@babel/helper-define-polyfill-provider": "^0.3.0", - "semver": "^6.1.1" - } - }, - "babel-plugin-polyfill-corejs3": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.4.0.tgz", - "integrity": "sha512-YxFreYwUfglYKdLUGvIF2nJEsGwj+RhWSX/ije3D2vQPOXuyMLMtg/cCGMDpOA7Nd+MwlNdnGODbd2EwUZPlsw==", - "dev": true, - "requires": { - "@babel/helper-define-polyfill-provider": "^0.3.0", - "core-js-compat": "^3.18.0" - } - }, - "babel-plugin-polyfill-regenerator": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.0.tgz", - "integrity": "sha512-dhAPTDLGoMW5/84wkgwiLRwMnio2i1fUe53EuvtKMv0pn2p3S8OCoV1xAzfJPl0KOX7IB89s2ib85vbYiea3jg==", - "dev": true, - "requires": { - "@babel/helper-define-polyfill-provider": "^0.3.0" - } - }, "babel-preset-current-node-syntax": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", @@ -12212,12 +7739,12 @@ } }, "babel-preset-jest": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.4.0.tgz", - "integrity": "sha512-NK4jGYpnBvNxcGo7/ZpZJr51jCGT+3bwwpVIDY2oNfTxJJldRtB4VAcYdgp1loDE50ODuTu+yBjpMAswv5tlpg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", + "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", "dev": true, "requires": { - "babel-plugin-jest-hoist": "^27.4.0", + "babel-plugin-jest-hoist": "^27.5.1", "babel-preset-current-node-syntax": "^1.0.0" } }, @@ -12309,6 +7836,15 @@ "picocolors": "^1.0.0" } }, + "bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "requires": { + "fast-json-stable-stringify": "2.x" + } + }, "bs58": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", @@ -12347,9 +7883,9 @@ "integrity": "sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==" }, "bufferutil": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.5.tgz", - "integrity": "sha512-HTm14iMQKK2FjFLRTM5lAVcyaUzOnqbPtesFIvREgXpJHdQm8bWS+GkQgIkfaBYRHuCnea7w8UVNfwiAQhlr9A==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.6.tgz", + "integrity": "sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw==", "optional": true, "requires": { "node-gyp-build": "^4.3.0" @@ -12361,16 +7897,6 @@ "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", "dev": true }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -12384,20 +7910,19 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001294", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001294.tgz", - "integrity": "sha512-LiMlrs1nSKZ8qkNhpUf5KD0Al1KCBE3zaT7OLOwEkagXMEDij98SiOovn9wxVGQpklk9vVC/pUSqgYmkmKOS8g==", + "version": "1.0.30001311", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001311.tgz", + "integrity": "sha512-mleTFtFKfykEeW34EyfhGIFjGCqzhh38Y0LhdQ9aWF+HorZTtdgKV/1hEE0NlFkG2ubvisPV6l400tlbPys98A==", "dev": true }, "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, "char-regex": { @@ -12447,18 +7972,18 @@ "dev": true }, "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "color-name": "1.1.3" + "color-name": "~1.1.4" } }, "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "combined-stream": { @@ -12504,24 +8029,6 @@ } } }, - "core-js-compat": { - "version": "3.20.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.20.1.tgz", - "integrity": "sha512-AVhKZNpqMV3Jz8hU0YEXXE06qoxtQGsAqU0u1neUngz5IusDJRX/ZJ6t3i7mS7QxNyEONbCo14GprkBrxPlTZA==", - "dev": true, - "requires": { - "browserslist": "^4.19.1", - "semver": "7.0.0" - }, - "dependencies": { - "semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", - "dev": true - } - } - }, "cross-env": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", @@ -12532,11 +8039,11 @@ } }, "cross-fetch": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz", - "integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", + "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", "requires": { - "node-fetch": "2.6.1" + "node-fetch": "2.6.7" } }, "cross-spawn": { @@ -12617,15 +8124,6 @@ "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", "dev": true }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, "delay": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", @@ -12644,9 +8142,9 @@ "dev": true }, "diff-sequences": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.4.0.tgz", - "integrity": "sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", "dev": true }, "dir-glob": { @@ -12690,9 +8188,9 @@ "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" }, "electron-to-chromium": { - "version": "1.4.30", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.30.tgz", - "integrity": "sha512-609z9sIMxDHg+TcR/VB3MXwH+uwtrYyeAwWc/orhnr90ixs6WVGSrt85CDLGUdNnLqCA7liv426V20EecjvflQ==", + "version": "1.4.68", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.68.tgz", + "integrity": "sha512-cId+QwWrV8R1UawO6b9BR1hnkJ4EJPCPAr4h315vliHUtVUJDk39Sg1PMNnaWKfj5x+93ssjeJ9LKL6r8LaMiA==", "dev": true }, "elliptic": { @@ -12728,52 +8226,13 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1" - } - }, - "es-abstract": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", - "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", - "is-string": "^1.0.7", - "is-weakref": "^1.0.1", - "object-inspect": "^1.11.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "is-arrayish": "^0.2.1" } }, "es6-promise": { @@ -12796,9 +8255,9 @@ "dev": true }, "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, "escodegen": { @@ -12814,6 +8273,12 @@ "source-map": "~0.6.1" }, "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -12844,13 +8309,6 @@ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true - }, "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", @@ -12863,9 +8321,9 @@ } }, "eslint": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.5.0.tgz", - "integrity": "sha512-tVGSkgNbOfiHyVte8bCM8OmX+xG9PzVG/B4UCF60zx7j61WIVY/AqJECDgpLD4DbbESD0e174gOg3ZlrX15GDg==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.8.0.tgz", + "integrity": "sha512-H3KXAzQGBH1plhYS3okDix2ZthuYJlQQEGE5k0IKuEqUSiyu4AmxxlJ2MtTYeJ3xB4jDhcYCwGOg2TXYdnDXlQ==", "dev": true, "requires": { "@eslint/eslintrc": "^1.0.5", @@ -12875,12 +8333,11 @@ "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", - "enquirer": "^2.3.5", "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.1.0", "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.1.0", - "espree": "^9.2.0", + "eslint-visitor-keys": "^3.2.0", + "espree": "^9.3.0", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -12888,7 +8345,7 @@ "functional-red-black-tree": "^1.0.1", "glob-parent": "^6.0.1", "globals": "^13.6.0", - "ignore": "^4.0.6", + "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", @@ -12899,147 +8356,55 @@ "minimatch": "^3.0.4", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "progress": "^2.0.0", "regexpp": "^3.2.0", - "semver": "^7.2.1", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" }, "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "globals": { - "version": "13.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", - "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "eslint-scope": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.0.tgz", + "integrity": "sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==", "dev": true, "requires": { - "has-flag": "^4.0.0" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" } }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true } } }, - "eslint-plugin-react": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.28.0.tgz", - "integrity": "sha512-IOlFIRHzWfEQQKcAD4iyYDndHwTQiCMcJVJjxempf203jnNLUnW34AXLrV33+nEXoifJE2ZEGmcjKPL8957eSw==", + "eslint-config-prettier": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz", + "integrity": "sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==", + "dev": true, + "requires": {} + }, + "eslint-plugin-prettier": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.0.0.tgz", + "integrity": "sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ==", "dev": true, "requires": { - "array-includes": "^3.1.4", - "array.prototype.flatmap": "^1.2.5", - "doctrine": "^2.1.0", - "estraverse": "^5.3.0", - "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "minimatch": "^3.0.4", - "object.entries": "^1.1.5", - "object.fromentries": "^2.0.5", - "object.hasown": "^1.1.0", - "object.values": "^1.1.5", - "prop-types": "^15.7.2", - "resolve": "^2.0.0-next.3", - "semver": "^6.3.0", - "string.prototype.matchall": "^4.0.6" - }, - "dependencies": { - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "resolve": { - "version": "2.0.0-next.3", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz", - "integrity": "sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==", - "dev": true, - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - } + "prettier-linter-helpers": "^1.0.0" } }, "eslint-scope": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.0.tgz", - "integrity": "sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "requires": { "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" + "estraverse": "^4.1.1" } }, "eslint-utils": { @@ -13060,18 +8425,18 @@ } }, "eslint-visitor-keys": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz", - "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.2.0.tgz", + "integrity": "sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ==", "dev": true }, "espree": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.2.0.tgz", - "integrity": "sha512-oP3utRkynpZWF/F2x/HZJ+AGtnIclaR7z1pYPxy7NYM2fSO6LgK/Rkny8anRSPK/VwEA1eqm2squui0T7ZMOBg==", + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.0.tgz", + "integrity": "sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ==", "dev": true, "requires": { - "acorn": "^8.6.0", + "acorn": "^8.7.0", "acorn-jsx": "^5.3.1", "eslint-visitor-keys": "^3.1.0" } @@ -13089,6 +8454,14 @@ "dev": true, "requires": { "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } } }, "esrecurse": { @@ -13098,18 +8471,26 @@ "dev": true, "requires": { "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } } }, "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true }, "estree-walker": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", - "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true }, "esutils": { @@ -13147,15 +8528,15 @@ "dev": true }, "expect": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.4.6.tgz", - "integrity": "sha512-1M/0kAALIaj5LaG66sFJTbRsWTADnylly82cu4bspI0nl+pgP4E6Bh/aqdHlTUjul06K7xQnnrAoqfxVU0+/ag==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", + "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", "dev": true, "requires": { - "@jest/types": "^27.4.2", - "jest-get-type": "^27.4.0", - "jest-matcher-utils": "^27.4.6", - "jest-message-util": "^27.4.6" + "@jest/types": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1" } }, "eyes": { @@ -13169,10 +8550,16 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, "fast-glob": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", - "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -13262,9 +8649,9 @@ } }, "flatted": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz", - "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", + "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", "dev": true }, "form-data": { @@ -13315,17 +8702,6 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, "get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", @@ -13338,16 +8714,6 @@ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true }, - "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - } - }, "glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", @@ -13372,37 +8738,32 @@ } }, "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true + "version": "13.12.1", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz", + "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } }, "globby": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", - "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, "requires": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", "slash": "^3.0.0" - }, - "dependencies": { - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - } } }, "graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", + "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", "dev": true }, "has": { @@ -13414,33 +8775,12 @@ "function-bind": "^1.1.1" } }, - "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "dev": true - }, "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, "hash.js": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", @@ -13517,9 +8857,9 @@ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true }, "import-fresh": { @@ -13563,60 +8903,21 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, - "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - } - }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "requires": { - "has-bigints": "^1.0.1" - } - }, - "is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, "is-core-module": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", - "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", + "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", "dev": true, "requires": { "has": "^1.0.3" } }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -13650,27 +8951,12 @@ "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", "dev": true }, - "is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true - }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, - "is-number-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, "is-potential-custom-element-name": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", @@ -13686,45 +8972,11 @@ "@types/estree": "*" } }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", - "dev": true - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true - }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true }, "is-typedarray": { "version": "1.0.0", @@ -13732,15 +8984,6 @@ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, - "is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -13770,6 +9013,14 @@ "@istanbuljs/schema": "^0.1.2", "istanbul-lib-coverage": "^3.2.0", "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "istanbul-lib-report": { @@ -13781,23 +9032,6 @@ "istanbul-lib-coverage": "^3.0.0", "make-dir": "^3.0.0", "supports-color": "^7.1.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } } }, "istanbul-lib-source-maps": { @@ -13809,20 +9043,12 @@ "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } } }, "istanbul-reports": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.3.tgz", - "integrity": "sha512-x9LtDVtfm/t1GFiLl3NffC7hz+I1ragvgX1P/Lg1NlIagifZDKUkuuaAxH/qpwj2IuEfD8G2Bs/UKp+sZ/pKkg==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz", + "integrity": "sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==", "dev": true, "requires": { "html-escaper": "^2.0.0", @@ -13852,680 +9078,274 @@ }, "dependencies": { "@types/node": { - "version": "12.20.39", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.39.tgz", - "integrity": "sha512-U7PMwkDmc3bnL0e4U8oA0POpi1vfsYDc+DEUS2+rPxm9NlLcW1dBa5JcRhO633PoPUcCSWMNXrMsqhmAVEo+IQ==" + "version": "12.20.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.45.tgz", + "integrity": "sha512-1Jg2Qv5tuxBqgQV04+wO5u+wmSHbHgpORCJdeCLM+E+YdPElpdHhgywU+M1V1InL8rfOtpqtOjswk+uXTKwx7w==" } } }, "jest": { - "version": "27.4.7", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.4.7.tgz", - "integrity": "sha512-8heYvsx7nV/m8m24Vk26Y87g73Ba6ueUd0MWed/NXMhSZIm62U/llVbS0PJe1SHunbyXjJ/BqG1z9bFjGUIvTg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", + "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", "dev": true, "requires": { - "@jest/core": "^27.4.7", + "@jest/core": "^27.5.1", "import-local": "^3.0.2", - "jest-cli": "^27.4.7" + "jest-cli": "^27.5.1" } }, "jest-changed-files": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.4.2.tgz", - "integrity": "sha512-/9x8MjekuzUQoPjDHbBiXbNEBauhrPU2ct7m8TfCg69ywt1y/N+yYwGh3gCpnqUS3klYWDU/lSNgv+JhoD2k1A==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", + "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", "dev": true, "requires": { - "@jest/types": "^27.4.2", + "@jest/types": "^27.5.1", "execa": "^5.0.0", "throat": "^6.0.1" } }, "jest-circus": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.4.6.tgz", - "integrity": "sha512-UA7AI5HZrW4wRM72Ro80uRR2Fg+7nR0GESbSI/2M+ambbzVuA63mn5T1p3Z/wlhntzGpIG1xx78GP2YIkf6PhQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", + "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", "dev": true, "requires": { - "@jest/environment": "^27.4.6", - "@jest/test-result": "^27.4.6", - "@jest/types": "^27.4.2", + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", - "expect": "^27.4.6", + "expect": "^27.5.1", "is-generator-fn": "^2.0.0", - "jest-each": "^27.4.6", - "jest-matcher-utils": "^27.4.6", - "jest-message-util": "^27.4.6", - "jest-runtime": "^27.4.6", - "jest-snapshot": "^27.4.6", - "jest-util": "^27.4.2", - "pretty-format": "^27.4.6", + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", "slash": "^3.0.0", "stack-utils": "^2.0.3", "throat": "^6.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } } }, "jest-cli": { - "version": "27.4.7", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.4.7.tgz", - "integrity": "sha512-zREYhvjjqe1KsGV15mdnxjThKNDgza1fhDT+iUsXWLCq3sxe9w5xnvyctcYVT5PcdLSjv7Y5dCwTS3FCF1tiuw==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", + "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", "dev": true, "requires": { - "@jest/core": "^27.4.7", - "@jest/test-result": "^27.4.6", - "@jest/types": "^27.4.2", + "@jest/core": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", "chalk": "^4.0.0", "exit": "^0.1.2", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "import-local": "^3.0.2", - "jest-config": "^27.4.7", - "jest-util": "^27.4.2", - "jest-validate": "^27.4.6", + "jest-config": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", "prompts": "^2.0.1", "yargs": "^16.2.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } } }, "jest-config": { - "version": "27.4.7", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.4.7.tgz", - "integrity": "sha512-xz/o/KJJEedHMrIY9v2ParIoYSrSVY6IVeE4z5Z3i101GoA5XgfbJz+1C8EYPsv7u7f39dS8F9v46BHDhn0vlw==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", + "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", "dev": true, "requires": { "@babel/core": "^7.8.0", - "@jest/test-sequencer": "^27.4.6", - "@jest/types": "^27.4.2", - "babel-jest": "^27.4.6", + "@jest/test-sequencer": "^27.5.1", + "@jest/types": "^27.5.1", + "babel-jest": "^27.5.1", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-circus": "^27.4.6", - "jest-environment-jsdom": "^27.4.6", - "jest-environment-node": "^27.4.6", - "jest-get-type": "^27.4.0", - "jest-jasmine2": "^27.4.6", - "jest-regex-util": "^27.4.0", - "jest-resolve": "^27.4.6", - "jest-runner": "^27.4.6", - "jest-util": "^27.4.2", - "jest-validate": "^27.4.6", + "graceful-fs": "^4.2.9", + "jest-circus": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-jasmine2": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", "micromatch": "^4.0.4", - "pretty-format": "^27.4.6", - "slash": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "parse-json": "^5.2.0", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" } }, "jest-diff": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.4.6.tgz", - "integrity": "sha512-zjaB0sh0Lb13VyPsd92V7HkqF6yKRH9vm33rwBt7rPYrpQvS1nCvlIy2pICbKta+ZjWngYLNn4cCK4nyZkjS/w==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^27.4.0", - "jest-get-type": "^27.4.0", - "pretty-format": "^27.4.6" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" } }, "jest-docblock": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.4.0.tgz", - "integrity": "sha512-7TBazUdCKGV7svZ+gh7C8esAnweJoG+SvcF6Cjqj4l17zA2q1cMwx2JObSioubk317H+cjcHgP+7fTs60paulg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", + "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", "dev": true, "requires": { "detect-newline": "^3.0.0" } }, "jest-each": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.4.6.tgz", - "integrity": "sha512-n6QDq8y2Hsmn22tRkgAk+z6MCX7MeVlAzxmZDshfS2jLcaBlyhpF3tZSJLR+kXmh23GEvS0ojMR8i6ZeRvpQcA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", + "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", "dev": true, "requires": { - "@jest/types": "^27.4.2", + "@jest/types": "^27.5.1", "chalk": "^4.0.0", - "jest-get-type": "^27.4.0", - "jest-util": "^27.4.2", - "pretty-format": "^27.4.6" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "jest-get-type": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1" } }, "jest-environment-jsdom": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.4.6.tgz", - "integrity": "sha512-o3dx5p/kHPbUlRvSNjypEcEtgs6LmvESMzgRFQE6c+Prwl2JLA4RZ7qAnxc5VM8kutsGRTB15jXeeSbJsKN9iA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", + "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", "dev": true, "requires": { - "@jest/environment": "^27.4.6", - "@jest/fake-timers": "^27.4.6", - "@jest/types": "^27.4.2", + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", "@types/node": "*", - "jest-mock": "^27.4.6", - "jest-util": "^27.4.2", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1", "jsdom": "^16.6.0" } }, "jest-environment-node": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.4.6.tgz", - "integrity": "sha512-yfHlZ9m+kzTKZV0hVfhVu6GuDxKAYeFHrfulmy7Jxwsq4V7+ZK7f+c0XP/tbVDMQW7E4neG2u147hFkuVz0MlQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", + "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", "dev": true, "requires": { - "@jest/environment": "^27.4.6", - "@jest/fake-timers": "^27.4.6", - "@jest/types": "^27.4.2", + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", "@types/node": "*", - "jest-mock": "^27.4.6", - "jest-util": "^27.4.2" + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" } }, "jest-get-type": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.4.0.tgz", - "integrity": "sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", "dev": true }, "jest-haste-map": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.4.6.tgz", - "integrity": "sha512-0tNpgxg7BKurZeFkIOvGCkbmOHbLFf4LUQOxrQSMjvrQaQe3l6E8x6jYC1NuWkGo5WDdbr8FEzUxV2+LWNawKQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", + "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", "dev": true, "requires": { - "@jest/types": "^27.4.2", + "@jest/types": "^27.5.1", "@types/graceful-fs": "^4.1.2", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "fsevents": "^2.3.2", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^27.4.0", - "jest-serializer": "^27.4.0", - "jest-util": "^27.4.2", - "jest-worker": "^27.4.6", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^27.5.1", + "jest-serializer": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", "micromatch": "^4.0.4", "walker": "^1.0.7" } }, "jest-jasmine2": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.4.6.tgz", - "integrity": "sha512-uAGNXF644I/whzhsf7/qf74gqy9OuhvJ0XYp8SDecX2ooGeaPnmJMjXjKt0mqh1Rl5dtRGxJgNrHlBQIBfS5Nw==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", + "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", "dev": true, "requires": { - "@jest/environment": "^27.4.6", - "@jest/source-map": "^27.4.0", - "@jest/test-result": "^27.4.6", - "@jest/types": "^27.4.2", + "@jest/environment": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "expect": "^27.4.6", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.4.6", - "jest-matcher-utils": "^27.4.6", - "jest-message-util": "^27.4.6", - "jest-runtime": "^27.4.6", - "jest-snapshot": "^27.4.6", - "jest-util": "^27.4.2", - "pretty-format": "^27.4.6", - "throat": "^6.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-leak-detector": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.4.6.tgz", - "integrity": "sha512-kkaGixDf9R7CjHm2pOzfTxZTQQQ2gHTIWKY/JZSiYTc90bZp8kSZnUMS3uLAfwTZwc0tcMRoEX74e14LG1WapA==", - "dev": true, - "requires": { - "jest-get-type": "^27.4.0", - "pretty-format": "^27.4.6" - } - }, - "jest-matcher-utils": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.4.6.tgz", - "integrity": "sha512-XD4PKT3Wn1LQnRAq7ZsTI0VRuEc9OrCPFiO1XL7bftTGmfNF0DcEwMHRgqiu7NGf8ZoZDREpGrCniDkjt79WbA==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^27.4.6", - "jest-get-type": "^27.4.0", - "pretty-format": "^27.4.6" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "expect": "^27.5.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "throat": "^6.0.1" + } + }, + "jest-leak-detector": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", + "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", + "dev": true, + "requires": { + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + } + }, + "jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" } }, "jest-message-util": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.4.6.tgz", - "integrity": "sha512-0p5szriFU0U74czRSFjH6RyS7UYIAkn/ntwMuOwTGWrQIOh5NzXXrq72LOqIkJKKvFbPq+byZKuBz78fjBERBA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.4.2", + "@jest/types": "^27.5.1", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^27.4.6", + "pretty-format": "^27.5.1", "slash": "^3.0.0", "stack-utils": "^2.0.3" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } } }, "jest-mock": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.4.6.tgz", - "integrity": "sha512-kvojdYRkst8iVSZ1EJ+vc1RRD9llueBjKzXzeCytH3dMM7zvPV/ULcfI2nr0v0VUgm3Bjt3hBCQvOeaBz+ZTHw==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", + "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", "dev": true, "requires": { - "@jest/types": "^27.4.2", + "@jest/types": "^27.5.1", "@types/node": "*" } }, @@ -14537,267 +9357,113 @@ "requires": {} }, "jest-regex-util": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.4.0.tgz", - "integrity": "sha512-WeCpMpNnqJYMQoOjm1nTtsgbR4XHAk1u00qDoNBQoykM280+/TmgA5Qh5giC1ecy6a5d4hbSsHzpBtu5yvlbEg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", + "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", "dev": true }, "jest-resolve": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.4.6.tgz", - "integrity": "sha512-SFfITVApqtirbITKFAO7jOVN45UgFzcRdQanOFzjnbd+CACDoyeX7206JyU92l4cRr73+Qy/TlW51+4vHGt+zw==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", + "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", "dev": true, "requires": { - "@jest/types": "^27.4.2", + "@jest/types": "^27.5.1", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.6", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.4.2", - "jest-validate": "^27.4.6", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", "resolve": "^1.20.0", "resolve.exports": "^1.1.0", "slash": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } } }, "jest-resolve-dependencies": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.4.6.tgz", - "integrity": "sha512-W85uJZcFXEVZ7+MZqIPCscdjuctruNGXUZ3OHSXOfXR9ITgbUKeHj+uGcies+0SsvI5GtUfTw4dY7u9qjTvQOw==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", + "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", "dev": true, "requires": { - "@jest/types": "^27.4.2", - "jest-regex-util": "^27.4.0", - "jest-snapshot": "^27.4.6" + "@jest/types": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-snapshot": "^27.5.1" } }, "jest-runner": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.4.6.tgz", - "integrity": "sha512-IDeFt2SG4DzqalYBZRgbbPmpwV3X0DcntjezPBERvnhwKGWTW7C5pbbA5lVkmvgteeNfdd/23gwqv3aiilpYPg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", + "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", "dev": true, "requires": { - "@jest/console": "^27.4.6", - "@jest/environment": "^27.4.6", - "@jest/test-result": "^27.4.6", - "@jest/transform": "^27.4.6", - "@jest/types": "^27.4.2", + "@jest/console": "^27.5.1", + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", "@types/node": "*", "chalk": "^4.0.0", "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-docblock": "^27.4.0", - "jest-environment-jsdom": "^27.4.6", - "jest-environment-node": "^27.4.6", - "jest-haste-map": "^27.4.6", - "jest-leak-detector": "^27.4.6", - "jest-message-util": "^27.4.6", - "jest-resolve": "^27.4.6", - "jest-runtime": "^27.4.6", - "jest-util": "^27.4.2", - "jest-worker": "^27.4.6", + "graceful-fs": "^4.2.9", + "jest-docblock": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-leak-detector": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", "source-map-support": "^0.5.6", "throat": "^6.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } } }, "jest-runtime": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.4.6.tgz", - "integrity": "sha512-eXYeoR/MbIpVDrjqy5d6cGCFOYBFFDeKaNWqTp0h6E74dK0zLHzASQXJpl5a2/40euBmKnprNLJ0Kh0LCndnWQ==", - "dev": true, - "requires": { - "@jest/environment": "^27.4.6", - "@jest/fake-timers": "^27.4.6", - "@jest/globals": "^27.4.6", - "@jest/source-map": "^27.4.0", - "@jest/test-result": "^27.4.6", - "@jest/transform": "^27.4.6", - "@jest/types": "^27.4.2", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", + "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", + "dev": true, + "requires": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/globals": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", "execa": "^5.0.0", "glob": "^7.1.3", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.6", - "jest-message-util": "^27.4.6", - "jest-mock": "^27.4.6", - "jest-regex-util": "^27.4.0", - "jest-resolve": "^27.4.6", - "jest-snapshot": "^27.4.6", - "jest-util": "^27.4.2", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", "slash": "^3.0.0", "strip-bom": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } } }, "jest-serializer": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.4.0.tgz", - "integrity": "sha512-RDhpcn5f1JYTX2pvJAGDcnsNTnsV9bjYPU8xcV+xPwOXnUPOQwf4ZEuiU6G9H1UztH+OapMgu/ckEVwO87PwnQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", + "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", "dev": true, "requires": { "@types/node": "*", - "graceful-fs": "^4.2.4" + "graceful-fs": "^4.2.9" } }, "jest-snapshot": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.4.6.tgz", - "integrity": "sha512-fafUCDLQfzuNP9IRcEqaFAMzEe7u5BF7mude51wyWv7VRex60WznZIC7DfKTgSIlJa8aFzYmXclmN328aqSDmQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", + "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", "dev": true, "requires": { "@babel/core": "^7.7.2", @@ -14805,291 +9471,80 @@ "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.0.0", - "@jest/transform": "^27.4.6", - "@jest/types": "^27.4.2", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", "@types/babel__traverse": "^7.0.4", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^27.4.6", - "graceful-fs": "^4.2.4", - "jest-diff": "^27.4.6", - "jest-get-type": "^27.4.0", - "jest-haste-map": "^27.4.6", - "jest-matcher-utils": "^27.4.6", - "jest-message-util": "^27.4.6", - "jest-util": "^27.4.2", + "expect": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", "natural-compare": "^1.4.0", - "pretty-format": "^27.4.6", + "pretty-format": "^27.5.1", "semver": "^7.3.2" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } } }, "jest-util": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.4.2.tgz", - "integrity": "sha512-YuxxpXU6nlMan9qyLuxHaMMOzXAl5aGZWCSzben5DhLHemYQxCc4YK+4L3ZrCutT8GPQ+ui9k5D8rUJoDioMnA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", "dev": true, "requires": { - "@jest/types": "^27.4.2", + "@jest/types": "^27.5.1", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "picomatch": "^2.2.3" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } } }, "jest-validate": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.4.6.tgz", - "integrity": "sha512-872mEmCPVlBqbA5dToC57vA3yJaMRfIdpCoD3cyHWJOMx+SJwLNw0I71EkWs41oza/Er9Zno9XuTkRYCPDUJXQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", + "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", "dev": true, "requires": { - "@jest/types": "^27.4.2", + "@jest/types": "^27.5.1", "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-get-type": "^27.4.0", + "jest-get-type": "^27.5.1", "leven": "^3.1.0", - "pretty-format": "^27.4.6" + "pretty-format": "^27.5.1" }, "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, "camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } } } }, "jest-watcher": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.4.6.tgz", - "integrity": "sha512-yKQ20OMBiCDigbD0quhQKLkBO+ObGN79MO4nT7YaCuQ5SM+dkBNWE8cZX0FjU6czwMvWw6StWbe+Wv4jJPJ+fw==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", + "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", "dev": true, "requires": { - "@jest/test-result": "^27.4.6", - "@jest/types": "^27.4.2", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "jest-util": "^27.4.2", + "jest-util": "^27.5.1", "string-length": "^4.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } } }, "jest-worker": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.6.tgz", - "integrity": "sha512-gHWJF/6Xi5CTG5QCvROr6GcmpIqNYpDJyc8A1h/DyXqH1tD6SnRCM0d3U5msV31D2LB/U+E0M+W4oyvKV44oNw==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dev": true, "requires": { "@types/node": "*", @@ -15097,12 +9552,6 @@ "supports-color": "^8.0.0" }, "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, "supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -15175,6 +9624,12 @@ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -15215,16 +9670,6 @@ "through": ">=2.2.7 <3" } }, - "jsx-ast-utils": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.1.tgz", - "integrity": "sha512-uP5vu8xfy2F9A6LGC22KO7e2/vGTS1MhP+18f++ZNlf0Ohaxbc9nIEwHAsejlJKyzfZzU5UIhe5ItYkitcZnZA==", - "dev": true, - "requires": { - "array-includes": "^3.1.3", - "object.assign": "^4.1.2" - } - }, "kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -15247,6 +9692,12 @@ "type-check": "~0.4.0" } }, + "lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -15261,10 +9712,10 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", "dev": true }, "lodash.merge": { @@ -15273,15 +9724,6 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -15307,8 +9749,22 @@ "dev": true, "requires": { "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, "makeerror": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", @@ -15382,9 +9838,9 @@ "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" }, "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -15414,9 +9870,33 @@ "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" }, "node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "requires": { + "whatwg-url": "^5.0.0" + }, + "dependencies": { + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + } + } }, "node-gyp-build": { "version": "4.3.0", @@ -15430,9 +9910,9 @@ "dev": true }, "node-releases": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", - "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", + "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", "dev": true }, "normalize-path": { @@ -15456,79 +9936,6 @@ "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", "dev": true }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-inspect": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", - "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "object.entries": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz", - "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - } - }, - "object.fromentries": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.5.tgz", - "integrity": "sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - } - }, - "object.hasown": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.0.tgz", - "integrity": "sha512-MhjYRfj3GBlhSkDHo6QmvgjRLXQ2zndabdf3nX0yTyZK9rPfxb6uRpAac8HXNLy1GpqWtZ81Qh4v3uOls2sRAg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - } - }, - "object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - } - }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -15594,6 +10001,18 @@ "callsites": "^3.0.0" } }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, "parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", @@ -15637,15 +10056,15 @@ "dev": true }, "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, "pirates": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.4.tgz", - "integrity": "sha512-ZIrVPH+A52Dw84R0L3/VS9Op04PuQ2SEoJL6bkshmiTic/HldyW9Tf7oH5mhJZBK7NmDx27vSMrYEXPXclpDKw==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", + "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", "dev": true }, "pkg-dir": { @@ -15669,10 +10088,19 @@ "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==", "dev": true }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "requires": { + "fast-diff": "^1.1.2" + } + }, "pretty-format": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.6.tgz", - "integrity": "sha512-NblstegA1y/RJW2VyML+3LlpFjzx62cUrtBIKIWDXEDkjNeleA7Od7nrzcs/VLQvAeV4CgSYhrN39DRN88Qi/g==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, "requires": { "ansi-regex": "^5.0.1", @@ -15688,12 +10116,6 @@ } } }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, "prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -15704,25 +10126,6 @@ "sisteransi": "^1.0.5" } }, - "prop-types": { - "version": "15.8.0", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.0.tgz", - "integrity": "sha512-fDGekdaHh65eI3lMi5OnErU6a8Ighg2KjcjQxO7m8VHyWjcPyj5kiOgV1LQDOOOgVy3+5FgjXvdSSX7B8/5/4g==", - "dev": true, - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - }, - "dependencies": { - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true - } - } - }, "psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -15756,88 +10159,17 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, - "regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true - }, - "regenerate-unicode-properties": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz", - "integrity": "sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA==", - "dev": true, - "requires": { - "regenerate": "^1.4.2" - } - }, "regenerator-runtime": { "version": "0.13.9", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" }, - "regenerator-transform": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", - "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", - "dev": true, - "requires": { - "@babel/runtime": "^7.8.4" - } - }, - "regexp.prototype.flags": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", - "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, "regexpp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true }, - "regexpu-core": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.8.0.tgz", - "integrity": "sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg==", - "dev": true, - "requires": { - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^9.0.0", - "regjsgen": "^0.5.2", - "regjsparser": "^0.7.0", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.0.0" - } - }, - "regjsgen": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", - "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", - "dev": true - }, - "regjsparser": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.7.0.tgz", - "integrity": "sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ==", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true - } - } - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -15845,13 +10177,14 @@ "dev": true }, "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", "dev": true, "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" } }, "resolve-cwd": { @@ -15899,9 +10232,9 @@ } }, "rollup": { - "version": "2.66.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.66.1.tgz", - "integrity": "sha512-crSgLhSkLMnKr4s9iZ/1qJCplgAgrRY+igWv8KhG/AjKOJ0YX/WpmANyn8oxrw+zenF3BXWDLa7Xl/QZISH+7w==", + "version": "2.67.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.67.2.tgz", + "integrity": "sha512-hoEiBWwZtf1QdK3jZIq59L0FJj4Fiv4RplCO4pvCRC86qsoFurWB4hKQIjoRf3WvJmk5UZ9b0y5ton+62fC7Tw==", "dev": true, "requires": { "fsevents": "~2.3.2" @@ -15957,12 +10290,6 @@ "terser": "^5.0.0" }, "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, "jest-worker": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", @@ -15973,15 +10300,6 @@ "merge-stream": "^2.0.0", "supports-color": "^7.0.0" } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } } } }, @@ -16003,9 +10321,9 @@ } }, "rpc-websockets": { - "version": "7.4.16", - "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.4.16.tgz", - "integrity": "sha512-0b7OVhutzwRIaYAtJo5tqtaQTWKfwAsKnaThOSOy+VkhVdleNUgb8eZnWSdWITRZZEigV5uPEIDr5KZe4DBrdQ==", + "version": "7.4.17", + "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.4.17.tgz", + "integrity": "sha512-eolVi/qlXS13viIUH9aqrde902wzSLAai0IjmOZSRefp5I3CSG/vCnD0c0fDSYCWuEyUoRL1BHQA8K1baEUyow==", "requires": { "@babel/runtime": "^7.11.2", "bufferutil": "^4.0.1", @@ -16046,20 +10364,23 @@ } }, "secp256k1": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", - "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", "requires": { - "elliptic": "^6.5.2", + "elliptic": "^6.5.4", "node-addon-api": "^2.0.0", "node-gyp-build": "^4.2.0" } }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } }, "serialize-javascript": { "version": "4.0.0", @@ -16085,21 +10406,10 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, "signal-exit": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", - "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, "sisteransi": { @@ -16115,9 +10425,9 @@ "dev": true }, "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, "source-map-support": { @@ -16128,14 +10438,6 @@ "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } } }, "sourcemap-codec": { @@ -16188,42 +10490,6 @@ "strip-ansi": "^6.0.1" } }, - "string.prototype.matchall": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.6.tgz", - "integrity": "sha512-6WgDX8HmQqvEd7J+G6VtAahhsQIssiZ8zl7zKh1VDMFyL3hRTJP4FTNA3RbIp2TOQ9AYNDcc7e3fH0Qbup+DBg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", - "get-intrinsic": "^1.1.1", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "regexp.prototype.flags": "^1.3.1", - "side-channel": "^1.0.4" - } - }, - "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -16257,12 +10523,12 @@ "integrity": "sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==" }, "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" } }, "supports-hyperlinks": { @@ -16273,25 +10539,14 @@ "requires": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } } }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, "symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -16401,11 +10656,28 @@ "punycode": "^2.1.1" } }, + "ts-jest": { + "version": "27.1.3", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.3.tgz", + "integrity": "sha512-6Nlura7s6uM9BVUAoqLH7JHyMXjz8gluryjpPXxr3IxZdAXnU6FhjvVLHFtfd1vsE1p8zD1OJfskkc0jhTSnkA==", + "dev": true, + "requires": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^27.0.0", + "json5": "2.x", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "7.x", + "yargs-parser": "20.x" + } + }, "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true, + "peer": true }, "tsutils": { "version": "3.21.0", @@ -16414,6 +10686,14 @@ "dev": true, "requires": { "tslib": "^1.8.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } } }, "tweetnacl": { @@ -16437,9 +10717,9 @@ "dev": true }, "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, "typedarray-to-buffer": { @@ -16452,49 +10732,9 @@ } }, "typescript": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz", - "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==", - "dev": true - }, - "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - } - }, - "unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", - "dev": true - }, - "unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "dev": true, - "requires": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - } - }, - "unicode-match-property-value-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", - "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==", - "dev": true - }, - "unicode-property-aliases-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz", - "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==", + "version": "4.5.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz", + "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==", "dev": true }, "universalify": { @@ -16513,9 +10753,9 @@ } }, "utf-8-validate": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.7.tgz", - "integrity": "sha512-vLt1O5Pp+flcArHGIyKEQq883nBt8nN8tVBcoL0qUXj2XT1n7p70yGIq2VK98I5FdZ1YHc0wk/koOnHjnXWk1Q==", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.8.tgz", + "integrity": "sha512-k4dW/Qja1BYDl2qD4tOMB9PFVha/UJtxTc1cXYOe3WwA/2m0Yn4qB7wLMpJyLJ/7DR0XnTut3HsCSzDT4ZvKgA==", "optional": true, "requires": { "node-gyp-build": "^4.3.0" @@ -16619,19 +10859,6 @@ "isexe": "^2.0.0" } }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -16647,32 +10874,6 @@ "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - } } }, "wrappy": { @@ -16694,9 +10895,9 @@ } }, "ws": { - "version": "7.5.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz", - "integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==", + "version": "7.5.7", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", + "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==", "requires": {} }, "xml-name-validator": { diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 13839f1c..88deae7d 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -3,15 +3,13 @@ "version": "0.6.4", "description": "SPL Stake Pool Program JS API", "scripts": { - "build": "npm run clean; tsc; cross-env NODE_ENV=production rollup -c", - "lint": "npm run pretty && eslint .", - "lint:fix": "npm run pretty:fix && eslint . --fix", - "pretty": "prettier --check '{,src/**/,test/**/}*.ts'", - "pretty:fix": "prettier -w '{,src/**/,test/**/}*.ts'", + "build": "npm run clean && tsc && cross-env NODE_ENV=production rollup -c", + "lint": "eslint .", + "lint:fix": "eslint . --fix", "test": "jest", "test:watch": "jest --watch", "test:cov": "jest --coverage", - "clean": "rimraf ./dist ./dist.browser" + "clean": "rimraf ./dist" }, "keywords": [], "contributors": [ @@ -28,16 +26,21 @@ "publishConfig": { "access": "public" }, - "browser": "dist.browser/index.js", - "main": "dist/index.js", + "browser": { + "./dist/index.cjs.js": "./dist/index.browser.esm.js", + "./dist/index.esm.js": "./dist/index.browser.esm.js" + }, + "main": "dist/index.cjs.js", + "module": "dist/index.esm.js", "types": "dist/index.d.ts", "browserslist": [ "defaults", - "not IE 11" + "not IE 11", + "maintained node versions" ], "files": [ "/dist", - "/dist.browser" + "/src" ], "license": "ISC", "dependencies": { @@ -49,9 +52,6 @@ "buffer": "^6.0.3" }, "devDependencies": { - "@babel/core": "^7.16.5", - "@babel/preset-env": "^7.16.5", - "@babel/preset-typescript": "^7.16.5", "@rollup/plugin-alias": "^3.1.9", "@rollup/plugin-commonjs": "^21.0.1", "@rollup/plugin-json": "^4.1.0", @@ -59,24 +59,35 @@ "@rollup/plugin-node-resolve": "^13.1.3", "@rollup/plugin-typescript": "^8.3.0", "@types/bn.js": "^5.1.0", - "@types/jest": "^27.0.3", - "@typescript-eslint/eslint-plugin": "^5.8.1", - "@typescript-eslint/parser": "^5.8.1", - "babel-jest": "^27.4.6", + "@types/jest": "^27.4.0", + "@typescript-eslint/eslint-plugin": "^5.11.0", + "@typescript-eslint/parser": "^5.11.0", "cross-env": "^7.0.3", - "eslint": "^8.5.0", - "eslint-plugin-react": "^7.28.0", - "jest": "^27.4.7", - "prettier": "^2.2.1", + "eslint": "^8.8.0", + "eslint-config-prettier": "^8.3.0", + "eslint-plugin-prettier": "^4.0.0", + "jest": "^27.5.1", + "prettier": "^2.5.1", "rimraf": "^3.0.2", "rollup": "^2.66.1", "rollup-plugin-dts": "^4.1.0", "rollup-plugin-node-polyfills": "^0.2.1", "rollup-plugin-terser": "^7.0.2", + "ts-jest": "^27.1.3", "typescript": "^4.5.4" }, "jest": { + "moduleFileExtensions": [ + "js", + "json", + "ts" + ], + "rootDir": ".", + "transform": { + "^.+\\.(t|j)s$": "ts-jest" + }, "testRegex": ".*\\.test\\.ts$", "testEnvironment": "node" } } + diff --git a/clients/js-legacy/rollup.config.js b/clients/js-legacy/rollup.config.js index 680ba5d7..03c9c198 100644 --- a/clients/js-legacy/rollup.config.js +++ b/clients/js-legacy/rollup.config.js @@ -2,7 +2,7 @@ import typescript from '@rollup/plugin-typescript'; import commonjs from '@rollup/plugin-commonjs'; import json from '@rollup/plugin-json'; import nodeResolve from '@rollup/plugin-node-resolve'; -import {terser} from 'rollup-plugin-terser'; +import { terser } from 'rollup-plugin-terser'; const extensions = ['.js', '.ts']; @@ -39,7 +39,7 @@ function generateConfig(configType, format) { '@solana/spl-token', '@solana/web3.js', 'bn.js', - 'buffer' + 'buffer', ]; } @@ -49,7 +49,7 @@ function generateConfig(configType, format) { case 'esm': { config.output = [ { - file: 'dist.browser/index.browser.esm.js', + file: 'dist/index.browser.esm.js', format: 'es', sourcemap: true, }, @@ -62,7 +62,7 @@ function generateConfig(configType, format) { '@solana/spl-token', '@solana/web3.js', 'bn.js', - 'buffer' + 'buffer', ]; break; @@ -72,17 +72,17 @@ function generateConfig(configType, format) { config.output = [ { - file: 'dist.browser/index.iife.js', + file: 'dist/index.iife.js', format: 'iife', name: 'solanaStakePool', sourcemap: true, }, { - file: 'dist.browser/index.iife.min.js', + file: 'dist/index.iife.min.js', format: 'iife', name: 'solanaStakePool', sourcemap: true, - plugins: [terser({mangle: false, compress: false})], + plugins: [terser({ mangle: false, compress: false })], }, ]; @@ -100,12 +100,12 @@ function generateConfig(configType, format) { case 'node': config.output = [ { - file: 'dist.browser/index.cjs.js', + file: 'dist/index.cjs.js', format: 'cjs', sourcemap: true, }, { - file: 'dist.browser/index.esm.js', + file: 'dist/index.esm.js', format: 'es', sourcemap: true, }, diff --git a/clients/js-legacy/src/constants.ts b/clients/js-legacy/src/constants.ts index 4b1f5a1f..e1297fcf 100644 --- a/clients/js-legacy/src/constants.ts +++ b/clients/js-legacy/src/constants.ts @@ -1,11 +1,15 @@ -import {Buffer} from 'buffer'; -import {PublicKey} from '@solana/web3.js'; -import {solToLamports} from './utils'; +import { Buffer } from 'buffer'; +import { LAMPORTS_PER_SOL, PublicKey } from '@solana/web3.js'; -export const TRANSIENT_STAKE_SEED_PREFIX = Buffer.from('transient'); +// Public key that identifies the SPL Stake Pool program. +export const STAKE_POOL_PROGRAM_ID = new PublicKey('SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy'); + +// Maximum number of validators to update during UpdateValidatorListBalance. +export const MAX_VALIDATORS_TO_UPDATE = 5; -export const STAKE_POOL_PROGRAM_ID = new PublicKey( - 'SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy', -); +// Seed used to derive transient stake accounts. +export const TRANSIENT_STAKE_SEED_PREFIX = Buffer.from('transient'); -export const MIN_STAKE_BALANCE = solToLamports(0.001); +// Minimum amount of staked SOL required in a validator stake account to allow +// for merges without a mismatch on credits observed +export const MINIMUM_ACTIVE_STAKE = LAMPORTS_PER_SOL / 1_000; diff --git a/clients/js-legacy/src/index.ts b/clients/js-legacy/src/index.ts index f4c22eb4..d3202fe6 100644 --- a/clients/js-legacy/src/index.ts +++ b/clients/js-legacy/src/index.ts @@ -4,42 +4,39 @@ import { Keypair, PublicKey, Signer, + StakeAuthorizationLayout, StakeProgram, SystemProgram, TransactionInstruction, } from '@solana/web3.js'; +import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID, Token } from '@solana/spl-token'; import { - ASSOCIATED_TOKEN_PROGRAM_ID, - TOKEN_PROGRAM_ID, - Token, -} from '@solana/spl-token'; -import { + ValidatorAccount, addAssociatedTokenAccount, + arrayChunk, calcLamportsWithdrawAmount, findStakeProgramAddress, + findTransientStakeProgramAddress, findWithdrawAuthorityProgramAddress, getTokenAccount, + getValidatorListAccount, newStakeAccount, prepareWithdrawAccounts, lamportsToSol, solToLamports, } from './utils'; -import {StakePoolInstruction} from './instructions'; +import { StakePoolInstruction } from './instructions'; import { - StakePoolLayout, - ValidatorListLayout, - ValidatorList, - StakePool, -} from './layouts'; -import {MIN_STAKE_BALANCE, STAKE_POOL_PROGRAM_ID} from './constants'; - -export type { StakePool, - AccountType, + StakePoolLayout, ValidatorList, + ValidatorListLayout, ValidatorStakeInfo, } from './layouts'; -export {STAKE_POOL_PROGRAM_ID} from './constants'; +import { MAX_VALIDATORS_TO_UPDATE, MINIMUM_ACTIVE_STAKE, STAKE_POOL_PROGRAM_ID } from './constants'; + +export type { StakePool, AccountType, ValidatorList, ValidatorStakeInfo } from './layouts'; +export { STAKE_POOL_PROGRAM_ID } from './constants'; export * from './instructions'; export interface ValidatorListAccount { @@ -70,20 +67,20 @@ export interface StakePoolAccounts { /** * Retrieves and deserializes a StakePool account using a web3js connection and the stake pool address. * @param connection: An active web3js connection. - * @param stakePoolPubKey: The public key (address) of the stake pool account. + * @param stakePoolAddress: The public key (address) of the stake pool account. */ export async function getStakePoolAccount( connection: Connection, - stakePoolPubKey: PublicKey, + stakePoolAddress: PublicKey, ): Promise { - const account = await connection.getAccountInfo(stakePoolPubKey); + const account = await connection.getAccountInfo(stakePoolAddress); if (!account) { - throw new Error('Invalid account'); + throw new Error('Invalid stake pool account'); } return { - pubkey: stakePoolPubKey, + pubkey: stakePoolAddress, account: { data: StakePoolLayout.decode(account.data), executable: account.executable, @@ -104,7 +101,7 @@ export async function getStakePoolAccounts( ): Promise<(StakePoolAccount | ValidatorListAccount)[] | undefined> { const response = await connection.getProgramAccounts(stakePoolProgramAddress); - return response.map(a => { + return response.map((a) => { let decodedData; if (a.account.data.readUInt8() === 1) { @@ -140,6 +137,90 @@ export async function getStakePoolAccounts( }); } +/** + * Creates instructions required to deposit stake to stake pool. + */ +export async function depositStake( + connection: Connection, + stakePoolAddress: PublicKey, + authorizedPubkey: PublicKey, + validatorVote: PublicKey, + depositStake: PublicKey, + poolTokenReceiverAccount?: PublicKey, +) { + const stakePool = await getStakePoolAccount(connection, stakePoolAddress); + + const withdrawAuthority = await findWithdrawAuthorityProgramAddress( + STAKE_POOL_PROGRAM_ID, + stakePoolAddress, + ); + + const validatorStake = await findStakeProgramAddress( + STAKE_POOL_PROGRAM_ID, + validatorVote, + stakePoolAddress, + ); + + const instructions: TransactionInstruction[] = []; + const signers: Signer[] = []; + + const poolMint = stakePool.account.data.poolMint; + + let rentFee = 0; + + // Create token account if not specified + if (!poolTokenReceiverAccount) { + const { associatedAddress, rentFee: fee } = await addAssociatedTokenAccount( + connection, + authorizedPubkey, + poolMint, + instructions, + ); + poolTokenReceiverAccount = associatedAddress; + rentFee += fee; + } + + instructions.push( + ...StakeProgram.authorize({ + stakePubkey: depositStake, + authorizedPubkey, + newAuthorizedPubkey: stakePool.account.data.stakeDepositAuthority, + stakeAuthorizationType: StakeAuthorizationLayout.Staker, + }).instructions, + ); + + instructions.push( + ...StakeProgram.authorize({ + stakePubkey: depositStake, + authorizedPubkey, + newAuthorizedPubkey: stakePool.account.data.stakeDepositAuthority, + stakeAuthorizationType: StakeAuthorizationLayout.Withdrawer, + }).instructions, + ); + + instructions.push( + StakePoolInstruction.depositStake({ + stakePool: stakePoolAddress, + validatorList: stakePool.account.data.validatorList, + depositAuthority: stakePool.account.data.stakeDepositAuthority, + reserveStake: stakePool.account.data.reserveStake, + managerFeeAccount: stakePool.account.data.managerFeeAccount, + referralPoolAccount: poolTokenReceiverAccount, + destinationPoolAccount: poolTokenReceiverAccount, + withdrawAuthority, + depositStake, + validatorStake, + poolMint, + }), + ); + + return { + instructions, + signers, + rentFee, + }; +} + /** * Creates instructions required to deposit sol to stake pool. */ @@ -161,10 +242,7 @@ export async function depositSol( ); } - const stakePoolAccount = await getStakePoolAccount( - connection, - stakePoolAddress, - ); + const stakePoolAccount = await getStakePoolAccount(connection, stakePoolAddress); const stakePool = stakePoolAccount.account.data; // Ephemeral SOL account just to do the transfer @@ -172,6 +250,8 @@ export async function depositSol( const signers: Signer[] = [userSolTransfer]; const instructions: TransactionInstruction[] = []; + let rentFee = 0; + // Create the ephemeral SOL account instructions.push( SystemProgram.transfer({ @@ -183,12 +263,14 @@ export async function depositSol( // Create token account if not specified if (!destinationTokenAccount) { - destinationTokenAccount = await addAssociatedTokenAccount( + const { associatedAddress, rentFee: fee } = await addAssociatedTokenAccount( connection, from, stakePool.poolMint, instructions, ); + destinationTokenAccount = associatedAddress; + rentFee += fee; } const withdrawAuthority = await findWithdrawAuthorityProgramAddress( @@ -205,15 +287,16 @@ export async function depositSol( managerFeeAccount: stakePool.managerFeeAccount, referralPoolAccount: referrerTokenAccount ?? destinationTokenAccount, poolMint: stakePool.poolMint, - lamports: lamports, - withdrawAuthority: withdrawAuthority, - depositAuthority: depositAuthority, + lamports, + withdrawAuthority, + depositAuthority, }), ); return { instructions, signers, + rentFee, }; } @@ -229,6 +312,7 @@ export async function withdrawStake( voteAccountAddress?: PublicKey, stakeReceiver?: PublicKey, poolTokenAccount?: PublicKey, + validatorComparator?: (_a: ValidatorAccount, _b: ValidatorAccount) => number, ) { const stakePool = await getStakePoolAccount(connection, stakePoolAddress); const poolAmount = solToLamports(amount); @@ -254,15 +338,15 @@ export async function withdrawStake( // Check withdrawFrom balance if (tokenAccount.amount.toNumber() < poolAmount) { throw new Error( - `Not enough token balance to withdraw ${lamportsToSol( - poolAmount, - )} pool tokens. - Maximum withdraw amount is ${lamportsToSol( - tokenAccount.amount.toNumber(), - )} pool tokens.`, + `Not enough token balance to withdraw ${lamportsToSol(poolAmount)} pool tokens. + Maximum withdraw amount is ${lamportsToSol(tokenAccount.amount.toNumber())} pool tokens.`, ); } + const stakeAccountRentExemption = await connection.getMinimumBalanceForRentExemption( + StakeProgram.space, + ); + const withdrawAuthority = await findWithdrawAuthorityProgramAddress( STAKE_POOL_PROGRAM_ID, stakePoolAddress, @@ -289,7 +373,7 @@ export async function withdrawStake( const availableForWithdrawal = calcLamportsWithdrawAmount( stakePool.account.data, - stakeAccount.lamports - MIN_STAKE_BALANCE, + stakeAccount.lamports - MINIMUM_ACTIVE_STAKE - stakeAccountRentExemption, ); if (availableForWithdrawal < poolAmount) { @@ -312,6 +396,8 @@ export async function withdrawStake( stakePool.account.data, stakePoolAddress, poolAmount, + validatorComparator, + poolTokenAccount.equals(stakePool.account.data.managerFeeAccount), )), ); } @@ -346,10 +432,7 @@ export async function withdrawStake( } // Convert pool tokens amount to lamports const solWithdrawAmount = Math.ceil( - calcLamportsWithdrawAmount( - stakePool.account.data, - withdrawAccount.poolAmount, - ), + calcLamportsWithdrawAmount(stakePool.account.data, withdrawAccount.poolAmount), ); let infoMsg = `Withdrawing â—Ž${solWithdrawAmount}, @@ -365,15 +448,9 @@ export async function withdrawStake( // Use separate mutable variable because withdraw might create a new account if (!stakeReceiver) { - const stakeReceiverAccountBalance = - await connection.getMinimumBalanceForRentExemption(StakeProgram.space); - const stakeKeypair = newStakeAccount( - tokenOwner, - instructions, - stakeReceiverAccountBalance, - ); + const stakeKeypair = newStakeAccount(tokenOwner, instructions, stakeAccountRentExemption); signers.push(stakeKeypair); - totalRentFreeBalances += stakeReceiverAccountBalance; + totalRentFreeBalances += stakeAccountRentExemption; stakeToReceive = stakeKeypair.publicKey; } else { stakeToReceive = stakeReceiver; @@ -438,12 +515,8 @@ export async function withdrawSol( // Check withdrawFrom balance if (tokenAccount.amount.toNumber() < poolAmount) { throw new Error( - `Not enough token balance to withdraw ${lamportsToSol( - poolAmount, - )} pool tokens. - Maximum withdraw amount is ${lamportsToSol( - tokenAccount.amount.toNumber(), - )} pool tokens.`, + `Not enough token balance to withdraw ${lamportsToSol(poolAmount)} pool tokens. + Maximum withdraw amount is ${lamportsToSol(tokenAccount.amount.toNumber())} pool tokens.`, ); } @@ -469,16 +542,11 @@ export async function withdrawSol( ); if (solWithdrawAuthority) { - const expectedSolWithdrawAuthority = - stakePool.account.data.solWithdrawAuthority; + const expectedSolWithdrawAuthority = stakePool.account.data.solWithdrawAuthority; if (!expectedSolWithdrawAuthority) { - throw new Error( - 'SOL withdraw authority specified in arguments but stake pool has none', - ); + throw new Error('SOL withdraw authority specified in arguments but stake pool has none'); } - if ( - solWithdrawAuthority.toBase58() != expectedSolWithdrawAuthority.toBase58() - ) { + if (solWithdrawAuthority.toBase58() != expectedSolWithdrawAuthority.toBase58()) { throw new Error( `Invalid deposit withdraw specified, expected ${expectedSolWithdrawAuthority.toBase58()}, received ${solWithdrawAuthority.toBase58()}`, ); @@ -505,3 +573,330 @@ export async function withdrawSol( signers, }; } + +/** + * Creates instructions required to increase validator stake. + */ +export async function increaseValidatorStake( + connection: Connection, + stakePoolAddress: PublicKey, + validatorVote: PublicKey, + lamports: number, +) { + const stakePool = await getStakePoolAccount(connection, stakePoolAddress); + + const validatorList = await getValidatorListAccount( + connection, + stakePool.account.data.validatorList, + ); + + const validatorInfo = validatorList.account.data.validators.find( + (v) => v.voteAccountAddress.toBase58() == validatorVote.toBase58(), + ); + + if (!validatorInfo) { + throw new Error('Vote account not found in validator list'); + } + + const withdrawAuthority = await findWithdrawAuthorityProgramAddress( + STAKE_POOL_PROGRAM_ID, + stakePoolAddress, + ); + + const transientStakeSeed = validatorInfo.transientSeedSuffixStart.addn(1); // bump up by one to avoid reuse + + const transientStake = await findTransientStakeProgramAddress( + STAKE_POOL_PROGRAM_ID, + validatorInfo.voteAccountAddress, + stakePoolAddress, + transientStakeSeed, + ); + + const instructions: TransactionInstruction[] = []; + instructions.push( + StakePoolInstruction.increaseValidatorStake({ + stakePool: stakePoolAddress, + staker: stakePool.account.data.staker, + validatorList: stakePool.account.data.validatorList, + reserveStake: stakePool.account.data.reserveStake, + transientStakeSeed: transientStakeSeed.toNumber(), + withdrawAuthority, + transientStake, + validatorVote, + lamports, + }), + ); + + return { + instructions, + }; +} + +/** + * Creates instructions required to decrease validator stake. + */ +export async function decreaseValidatorStake( + connection: Connection, + stakePoolAddress: PublicKey, + validatorVote: PublicKey, + lamports: number, +) { + const stakePool = await getStakePoolAccount(connection, stakePoolAddress); + const validatorList = await getValidatorListAccount( + connection, + stakePool.account.data.validatorList, + ); + + const validatorInfo = validatorList.account.data.validators.find( + (v) => v.voteAccountAddress.toBase58() == validatorVote.toBase58(), + ); + + if (!validatorInfo) { + throw new Error('Vote account not found in validator list'); + } + + const withdrawAuthority = await findWithdrawAuthorityProgramAddress( + STAKE_POOL_PROGRAM_ID, + stakePoolAddress, + ); + + const validatorStake = await findStakeProgramAddress( + STAKE_POOL_PROGRAM_ID, + validatorInfo.voteAccountAddress, + stakePoolAddress, + ); + + const transientStakeSeed = validatorInfo.transientSeedSuffixStart.addn(1); // bump up by one to avoid reuse + + const transientStake = await findTransientStakeProgramAddress( + STAKE_POOL_PROGRAM_ID, + validatorInfo.voteAccountAddress, + stakePoolAddress, + transientStakeSeed, + ); + + const instructions: TransactionInstruction[] = []; + instructions.push( + StakePoolInstruction.decreaseValidatorStake({ + stakePool: stakePoolAddress, + staker: stakePool.account.data.staker, + validatorList: stakePool.account.data.validatorList, + transientStakeSeed: transientStakeSeed.toNumber(), + withdrawAuthority, + validatorStake, + transientStake, + lamports, + }), + ); + + return { + instructions, + }; +} + +/** + * Creates instructions required to completely update a stake pool after epoch change. + */ +export async function updateStakePool( + connection: Connection, + stakePool: StakePoolAccount, + noMerge = false, +) { + const stakePoolAddress = stakePool.pubkey; + + const validatorList = await getValidatorListAccount( + connection, + stakePool.account.data.validatorList, + ); + + const withdrawAuthority = await findWithdrawAuthorityProgramAddress( + STAKE_POOL_PROGRAM_ID, + stakePoolAddress, + ); + + const updateListInstructions: TransactionInstruction[] = []; + const instructions: TransactionInstruction[] = []; + + let startIndex = 0; + const validatorChunks: Array = arrayChunk( + validatorList.account.data.validators, + MAX_VALIDATORS_TO_UPDATE, + ); + + for (const validatorChunk of validatorChunks) { + const validatorAndTransientStakePairs: PublicKey[] = []; + + for (const validator of validatorChunk) { + const validatorStake = await findStakeProgramAddress( + STAKE_POOL_PROGRAM_ID, + validator.voteAccountAddress, + stakePoolAddress, + ); + validatorAndTransientStakePairs.push(validatorStake); + + const transientStake = await findTransientStakeProgramAddress( + STAKE_POOL_PROGRAM_ID, + validator.voteAccountAddress, + stakePoolAddress, + validator.transientSeedSuffixStart, + ); + validatorAndTransientStakePairs.push(transientStake); + } + + updateListInstructions.push( + StakePoolInstruction.updateValidatorListBalance({ + stakePool: stakePoolAddress, + validatorList: stakePool.account.data.validatorList, + reserveStake: stakePool.account.data.reserveStake, + validatorAndTransientStakePairs, + withdrawAuthority, + startIndex, + noMerge, + }), + ); + startIndex += MAX_VALIDATORS_TO_UPDATE; + } + + instructions.push( + StakePoolInstruction.updateStakePoolBalance({ + stakePool: stakePoolAddress, + validatorList: stakePool.account.data.validatorList, + reserveStake: stakePool.account.data.reserveStake, + managerFeeAccount: stakePool.account.data.managerFeeAccount, + poolMint: stakePool.account.data.poolMint, + withdrawAuthority, + }), + ); + + instructions.push( + StakePoolInstruction.cleanupRemovedValidatorEntries({ + stakePool: stakePoolAddress, + validatorList: stakePool.account.data.validatorList, + }), + ); + + return { + updateListInstructions, + finalInstructions: instructions, + }; +} + +/** + * Retrieves detailed information about the StakePool. + */ +export async function stakePoolInfo(connection: Connection, stakePoolAddress: PublicKey) { + const stakePool = await getStakePoolAccount(connection, stakePoolAddress); + const reserveAccountStakeAddress = stakePool.account.data.reserveStake; + const totalLamports = stakePool.account.data.totalLamports; + const lastUpdateEpoch = stakePool.account.data.lastUpdateEpoch; + + const validatorList = await getValidatorListAccount( + connection, + stakePool.account.data.validatorList, + ); + + const maxNumberOfValidators = validatorList.account.data.maxValidators; + const currentNumberOfValidators = validatorList.account.data.validators.length; + + const epochInfo = await connection.getEpochInfo(); + const reserveStake = await connection.getAccountInfo(reserveAccountStakeAddress); + const withdrawAuthority = await findWithdrawAuthorityProgramAddress( + STAKE_POOL_PROGRAM_ID, + stakePoolAddress, + ); + + const minimumReserveStakeBalance = + (await connection.getMinimumBalanceForRentExemption(StakeProgram.space)) + 1; + + const stakeAccounts = await Promise.all( + validatorList.account.data.validators.map(async (validator) => { + const stakeAccountAddress = await findStakeProgramAddress( + STAKE_POOL_PROGRAM_ID, + validator.voteAccountAddress, + stakePoolAddress, + ); + const transientStakeAccountAddress = await findTransientStakeProgramAddress( + STAKE_POOL_PROGRAM_ID, + validator.voteAccountAddress, + stakePoolAddress, + validator.transientSeedSuffixStart, + ); + const updateRequired = !validator.lastUpdateEpoch.eqn(epochInfo.epoch); + return { + voteAccountAddress: validator.voteAccountAddress.toBase58(), + stakeAccountAddress: stakeAccountAddress.toBase58(), + validatorActiveStakeLamports: validator.activeStakeLamports.toString(), + validatorLastUpdateEpoch: validator.lastUpdateEpoch.toString(), + validatorLamports: validator.activeStakeLamports + .add(validator.transientStakeLamports) + .toString(), + validatorTransientStakeAccountAddress: transientStakeAccountAddress.toBase58(), + validatorTransientStakeLamports: validator.transientStakeLamports.toString(), + updateRequired, + }; + }), + ); + + const totalPoolTokens = lamportsToSol(stakePool.account.data.poolTokenSupply); + const updateRequired = !lastUpdateEpoch.eqn(epochInfo.epoch); + + return { + address: stakePoolAddress.toBase58(), + poolWithdrawAuthority: withdrawAuthority.toBase58(), + manager: stakePool.account.data.manager.toBase58(), + staker: stakePool.account.data.staker.toBase58(), + stakeDepositAuthority: stakePool.account.data.stakeDepositAuthority.toBase58(), + stakeWithdrawBumpSeed: stakePool.account.data.stakeWithdrawBumpSeed, + maxValidators: maxNumberOfValidators, + validatorList: validatorList.account.data.validators.map((validator) => { + return { + activeStakeLamports: validator.activeStakeLamports.toString(), + transientStakeLamports: validator.transientStakeLamports.toString(), + lastUpdateEpoch: validator.lastUpdateEpoch.toString(), + transientSeedSuffixStart: validator.transientSeedSuffixStart.toString(), + transientSeedSuffixEnd: validator.transientSeedSuffixEnd.toString(), + status: validator.status.toString(), + voteAccountAddress: validator.voteAccountAddress.toString(), + }; + }), // CliStakePoolValidator + validatorListStorageAccount: stakePool.account.data.validatorList.toBase58(), + reserveStake: stakePool.account.data.reserveStake.toBase58(), + poolMint: stakePool.account.data.poolMint.toBase58(), + managerFeeAccount: stakePool.account.data.managerFeeAccount.toBase58(), + tokenProgramId: stakePool.account.data.tokenProgramId.toBase58(), + totalLamports: stakePool.account.data.totalLamports.toString(), + poolTokenSupply: stakePool.account.data.poolTokenSupply.toString(), + lastUpdateEpoch: stakePool.account.data.lastUpdateEpoch.toString(), + lockup: stakePool.account.data.lockup, // pub lockup: CliStakePoolLockup + epochFee: stakePool.account.data.epochFee, + nextEpochFee: stakePool.account.data.nextEpochFee, + preferredDepositValidatorVoteAddress: + stakePool.account.data.preferredDepositValidatorVoteAddress, + preferredWithdrawValidatorVoteAddress: + stakePool.account.data.preferredWithdrawValidatorVoteAddress, + stakeDepositFee: stakePool.account.data.stakeDepositFee, + stakeWithdrawalFee: stakePool.account.data.stakeWithdrawalFee, + // CliStakePool the same + nextStakeWithdrawalFee: stakePool.account.data.nextStakeWithdrawalFee, + stakeReferralFee: stakePool.account.data.stakeReferralFee, + solDepositAuthority: stakePool.account.data.solDepositAuthority?.toBase58(), + solDepositFee: stakePool.account.data.solDepositFee, + solReferralFee: stakePool.account.data.solReferralFee, + solWithdrawAuthority: stakePool.account.data.solWithdrawAuthority?.toBase58(), + solWithdrawalFee: stakePool.account.data.solWithdrawalFee, + nextSolWithdrawalFee: stakePool.account.data.nextSolWithdrawalFee, + lastEpochPoolTokenSupply: stakePool.account.data.lastEpochPoolTokenSupply.toString(), + lastEpochTotalLamports: stakePool.account.data.lastEpochTotalLamports.toString(), + details: { + reserveStakeLamports: reserveStake?.lamports, + reserveAccountStakeAddress: reserveAccountStakeAddress.toBase58(), + minimumReserveStakeBalance, + stakeAccounts, + totalLamports, + totalPoolTokens, + currentNumberOfValidators, + maxNumberOfValidators, + updateRequired, + }, // CliStakePoolDetails + }; +} diff --git a/clients/js-legacy/src/instructions.ts b/clients/js-legacy/src/instructions.ts index ccf1e438..74b817ce 100644 --- a/clients/js-legacy/src/instructions.ts +++ b/clients/js-legacy/src/instructions.ts @@ -1,32 +1,44 @@ -/** - * Based on https://github.com/solana-labs/solana-web3.js/blob/master/src/stake-program.ts - */ -import { - encodeData, - decodeData, - InstructionType, -} from './copied-from-solana-web3/instruction'; import { PublicKey, - TransactionInstruction, - StakeProgram, - SystemProgram, + STAKE_CONFIG_ID, SYSVAR_CLOCK_PUBKEY, + SYSVAR_RENT_PUBKEY, SYSVAR_STAKE_HISTORY_PUBKEY, + StakeProgram, + SystemProgram, + TransactionInstruction, } from '@solana/web3.js'; -import {struct, u8, nu64} from '@solana/buffer-layout'; -import {TOKEN_PROGRAM_ID} from '@solana/spl-token'; -import {STAKE_POOL_PROGRAM_ID} from './constants'; +import * as BufferLayout from '@solana/buffer-layout'; +import { TOKEN_PROGRAM_ID } from '@solana/spl-token'; +import { STAKE_POOL_PROGRAM_ID } from './constants'; +import { InstructionType, encodeData, decodeData } from './utils'; /** * An enumeration of valid StakePoolInstructionType's */ export type StakePoolInstructionType = + | 'IncreaseValidatorStake' + | 'DecreaseValidatorStake' + | 'UpdateValidatorListBalance' + | 'UpdateStakePoolBalance' + | 'CleanupRemovedValidatorEntries' | 'DepositStake' | 'DepositSol' | 'WithdrawStake' | 'WithdrawSol'; +const MOVE_STAKE_LAYOUT = BufferLayout.struct([ + BufferLayout.u8('instruction'), + BufferLayout.ns64('lamports'), + BufferLayout.ns64('transientStakeSeed'), +]); + +const UPDATE_VALIDATOR_LIST_BALANCE_LAYOUT = BufferLayout.struct([ + BufferLayout.u8('instruction'), + BufferLayout.u32('startIndex'), + BufferLayout.u8('noMerge'), +]); + /** * An enumeration of valid stake InstructionType's * @internal @@ -34,37 +46,126 @@ export type StakePoolInstructionType = export const STAKE_POOL_INSTRUCTION_LAYOUTS: { [type in StakePoolInstructionType]: InstructionType; } = Object.freeze({ + DecreaseValidatorStake: { + index: 3, + layout: MOVE_STAKE_LAYOUT, + }, + IncreaseValidatorStake: { + index: 4, + layout: MOVE_STAKE_LAYOUT, + }, + UpdateValidatorListBalance: { + index: 6, + layout: UPDATE_VALIDATOR_LIST_BALANCE_LAYOUT, + }, + UpdateStakePoolBalance: { + index: 7, + layout: BufferLayout.struct([BufferLayout.u8('instruction')]), + }, + CleanupRemovedValidatorEntries: { + index: 8, + layout: BufferLayout.struct([BufferLayout.u8('instruction')]), + }, DepositStake: { index: 9, - layout: struct([u8('instruction') as any]), // NOTE do this better + layout: BufferLayout.struct([BufferLayout.u8('instruction')]), }, /// Withdraw the token from the pool at the current ratio. WithdrawStake: { index: 10, - layout: struct([ - u8('instruction') as any, // NOTE do this better - nu64('poolTokens'), + layout: BufferLayout.struct([ + BufferLayout.u8('instruction'), + BufferLayout.ns64('poolTokens'), ]), }, /// Deposit SOL directly into the pool's reserve account. The output is a "pool" token /// representing ownership into the pool. Inputs are converted to the current ratio. DepositSol: { index: 14, - layout: struct([ - u8('instruction') as any, // NOTE do this better - nu64('lamports'), + layout: BufferLayout.struct([ + BufferLayout.u8('instruction'), + BufferLayout.ns64('lamports'), ]), }, /// Withdraw SOL directly from the pool's reserve account. Fails if the /// reserve does not have enough SOL. WithdrawSol: { index: 16, - layout: struct([u8('instruction') as any, nu64('poolTokens')]), + layout: BufferLayout.struct([ + BufferLayout.u8('instruction'), + BufferLayout.ns64('poolTokens'), + ]), }, }); /** - * Deposit stake pool instruction params + * Cleans up validator stake account entries marked as `ReadyForRemoval` + */ +export type CleanupRemovedValidatorEntriesParams = { + stakePool: PublicKey; + validatorList: PublicKey; +}; + +/** + * Updates balances of validator and transient stake accounts in the pool. + */ +export type UpdateValidatorListBalanceParams = { + stakePool: PublicKey; + withdrawAuthority: PublicKey; + validatorList: PublicKey; + reserveStake: PublicKey; + validatorAndTransientStakePairs: PublicKey[]; + startIndex: number; + noMerge: boolean; +}; + +/** + * Updates total pool balance based on balances in the reserve and validator list. + */ +export type UpdateStakePoolBalanceParams = { + stakePool: PublicKey; + withdrawAuthority: PublicKey; + validatorList: PublicKey; + reserveStake: PublicKey; + managerFeeAccount: PublicKey; + poolMint: PublicKey; +}; + +/** + * (Staker only) Decrease active stake on a validator, eventually moving it to the reserve + */ +export type DecreaseValidatorStakeParams = { + stakePool: PublicKey; + staker: PublicKey; + withdrawAuthority: PublicKey; + validatorList: PublicKey; + validatorStake: PublicKey; + transientStake: PublicKey; + // Amount of lamports to split into the transient stake account. + lamports: number; + // Seed to used to create the transient stake account. + transientStakeSeed: number; +}; + +/** + * (Staker only) Increase stake on a validator from the reserve account. + */ +export type IncreaseValidatorStakeParams = { + stakePool: PublicKey; + staker: PublicKey; + withdrawAuthority: PublicKey; + validatorList: PublicKey; + reserveStake: PublicKey; + transientStake: PublicKey; + validatorVote: PublicKey; + // Amount of lamports to split into the transient stake account. + lamports: number; + // Seed to used to create the transient stake account. + transientStakeSeed: number; +}; + +/** + * Deposits a stake account into the pool in exchange for pool tokens */ export type DepositStakeParams = { stakePool: PublicKey; @@ -81,7 +182,7 @@ export type DepositStakeParams = { }; /** - * Withdraw stake pool instruction params + * Withdraws a stake account from the pool in exchange for pool tokens */ export type WithdrawStakeParams = { stakePool: PublicKey; @@ -114,7 +215,8 @@ export type WithdrawSolParams = { }; /** - * Deposit sol instruction params + * Deposit SOL directly into the pool's reserve account. The output is a "pool" token + * representing ownership into the pool. Inputs are converted to the current ratio. */ export type DepositSolParams = { stakePool: PublicKey; @@ -133,6 +235,183 @@ export type DepositSolParams = { * Stake Pool Instruction class */ export class StakePoolInstruction { + /** + * Creates instruction to update a set of validators in the stake pool. + */ + static updateValidatorListBalance( + params: UpdateValidatorListBalanceParams, + ): TransactionInstruction { + const { + stakePool, + withdrawAuthority, + validatorList, + reserveStake, + startIndex, + noMerge, + validatorAndTransientStakePairs, + } = params; + + const type = STAKE_POOL_INSTRUCTION_LAYOUTS.UpdateValidatorListBalance; + const data = encodeData(type, { startIndex, noMerge: noMerge ? 1 : 0 }); + + const keys = [ + { pubkey: stakePool, isSigner: false, isWritable: false }, + { pubkey: withdrawAuthority, isSigner: false, isWritable: false }, + { pubkey: validatorList, isSigner: false, isWritable: true }, + { pubkey: reserveStake, isSigner: false, isWritable: true }, + { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false }, + { pubkey: SYSVAR_STAKE_HISTORY_PUBKEY, isSigner: false, isWritable: false }, + { pubkey: StakeProgram.programId, isSigner: false, isWritable: false }, + ...validatorAndTransientStakePairs.map((pubkey) => ({ + pubkey, + isSigner: false, + isWritable: true, + })), + ]; + + return new TransactionInstruction({ + programId: STAKE_POOL_PROGRAM_ID, + keys, + data, + }); + } + + /** + * Creates instruction to update the overall stake pool balance. + */ + static updateStakePoolBalance(params: UpdateStakePoolBalanceParams): TransactionInstruction { + const { + stakePool, + withdrawAuthority, + validatorList, + reserveStake, + managerFeeAccount, + poolMint, + } = params; + + const type = STAKE_POOL_INSTRUCTION_LAYOUTS.UpdateStakePoolBalance; + const data = encodeData(type); + + const keys = [ + { pubkey: stakePool, isSigner: false, isWritable: true }, + { pubkey: withdrawAuthority, isSigner: false, isWritable: false }, + { pubkey: validatorList, isSigner: false, isWritable: true }, + { pubkey: reserveStake, isSigner: false, isWritable: false }, + { pubkey: managerFeeAccount, isSigner: false, isWritable: true }, + { pubkey: poolMint, isSigner: false, isWritable: true }, + { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, + ]; + + return new TransactionInstruction({ + programId: STAKE_POOL_PROGRAM_ID, + keys, + data, + }); + } + + /** + * Creates instruction to cleanup removed validator entries. + */ + static cleanupRemovedValidatorEntries( + params: CleanupRemovedValidatorEntriesParams, + ): TransactionInstruction { + const { stakePool, validatorList } = params; + + const type = STAKE_POOL_INSTRUCTION_LAYOUTS.CleanupRemovedValidatorEntries; + const data = encodeData(type); + + const keys = [ + { pubkey: stakePool, isSigner: false, isWritable: false }, + { pubkey: validatorList, isSigner: false, isWritable: true }, + ]; + + return new TransactionInstruction({ + programId: STAKE_POOL_PROGRAM_ID, + keys, + data, + }); + } + + /** + * Creates instruction to increase the stake on a validator. + */ + static increaseValidatorStake(params: IncreaseValidatorStakeParams): TransactionInstruction { + const { + stakePool, + staker, + withdrawAuthority, + validatorList, + reserveStake, + transientStake, + validatorVote, + lamports, + transientStakeSeed, + } = params; + + const type = STAKE_POOL_INSTRUCTION_LAYOUTS.IncreaseValidatorStake; + const data = encodeData(type, { lamports, transientStakeSeed }); + + const keys = [ + { pubkey: stakePool, isSigner: false, isWritable: false }, + { pubkey: staker, isSigner: true, isWritable: false }, + { pubkey: withdrawAuthority, isSigner: false, isWritable: false }, + { pubkey: validatorList, isSigner: false, isWritable: true }, + { pubkey: reserveStake, isSigner: false, isWritable: true }, + { pubkey: transientStake, isSigner: false, isWritable: true }, + { pubkey: validatorVote, isSigner: false, isWritable: false }, + { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false }, + { pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false }, + { pubkey: SYSVAR_STAKE_HISTORY_PUBKEY, isSigner: false, isWritable: false }, + { pubkey: STAKE_CONFIG_ID, isSigner: false, isWritable: false }, + { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, + { pubkey: StakeProgram.programId, isSigner: false, isWritable: false }, + ]; + + return new TransactionInstruction({ + programId: STAKE_POOL_PROGRAM_ID, + keys, + data, + }); + } + + /** + * Creates instruction to decrease the stake on a validator. + */ + static decreaseValidatorStake(params: DecreaseValidatorStakeParams): TransactionInstruction { + const { + stakePool, + staker, + withdrawAuthority, + validatorList, + validatorStake, + transientStake, + lamports, + transientStakeSeed, + } = params; + + const type = STAKE_POOL_INSTRUCTION_LAYOUTS.DecreaseValidatorStake; + const data = encodeData(type, { lamports, transientStakeSeed }); + + const keys = [ + { pubkey: stakePool, isSigner: false, isWritable: false }, + { pubkey: staker, isSigner: true, isWritable: false }, + { pubkey: withdrawAuthority, isSigner: false, isWritable: false }, + { pubkey: validatorList, isSigner: false, isWritable: true }, + { pubkey: validatorStake, isSigner: false, isWritable: true }, + { pubkey: transientStake, isSigner: false, isWritable: true }, + { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false }, + { pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false }, + { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, + { pubkey: StakeProgram.programId, isSigner: false, isWritable: false }, + ]; + + return new TransactionInstruction({ + programId: STAKE_POOL_PROGRAM_ID, + keys, + data, + }); + } + /** * Creates a transaction instruction to deposit SOL into a stake pool. */ @@ -155,21 +434,21 @@ export class StakePoolInstruction { const data = encodeData(type); const keys = [ - {pubkey: stakePool, isSigner: false, isWritable: true}, - {pubkey: validatorList, isSigner: false, isWritable: true}, - {pubkey: depositAuthority, isSigner: false, isWritable: false}, - {pubkey: withdrawAuthority, isSigner: false, isWritable: false}, - {pubkey: depositStake, isSigner: false, isWritable: true}, - {pubkey: validatorStake, isSigner: false, isWritable: true}, - {pubkey: reserveStake, isSigner: false, isWritable: true}, - {pubkey: destinationPoolAccount, isSigner: false, isWritable: true}, - {pubkey: managerFeeAccount, isSigner: false, isWritable: true}, - {pubkey: referralPoolAccount, isSigner: false, isWritable: true}, - {pubkey: poolMint, isSigner: false, isWritable: true}, - {pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false}, - {pubkey: SYSVAR_STAKE_HISTORY_PUBKEY, isSigner: false, isWritable: false}, - {pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false}, - {pubkey: StakeProgram.programId, isSigner: false, isWritable: false}, + { pubkey: stakePool, isSigner: false, isWritable: true }, + { pubkey: validatorList, isSigner: false, isWritable: true }, + { pubkey: depositAuthority, isSigner: false, isWritable: false }, + { pubkey: withdrawAuthority, isSigner: false, isWritable: false }, + { pubkey: depositStake, isSigner: false, isWritable: true }, + { pubkey: validatorStake, isSigner: false, isWritable: true }, + { pubkey: reserveStake, isSigner: false, isWritable: true }, + { pubkey: destinationPoolAccount, isSigner: false, isWritable: true }, + { pubkey: managerFeeAccount, isSigner: false, isWritable: true }, + { pubkey: referralPoolAccount, isSigner: false, isWritable: true }, + { pubkey: poolMint, isSigner: false, isWritable: true }, + { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false }, + { pubkey: SYSVAR_STAKE_HISTORY_PUBKEY, isSigner: false, isWritable: false }, + { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, + { pubkey: StakeProgram.programId, isSigner: false, isWritable: false }, ]; return new TransactionInstruction({ @@ -197,19 +476,19 @@ export class StakePoolInstruction { } = params; const type = STAKE_POOL_INSTRUCTION_LAYOUTS.DepositSol; - const data = encodeData(type, {lamports}); + const data = encodeData(type, { lamports }); const keys = [ - {pubkey: stakePool, isSigner: false, isWritable: true}, - {pubkey: withdrawAuthority, isSigner: false, isWritable: false}, - {pubkey: reserveStake, isSigner: false, isWritable: true}, - {pubkey: fundingAccount, isSigner: true, isWritable: true}, - {pubkey: destinationPoolAccount, isSigner: false, isWritable: true}, - {pubkey: managerFeeAccount, isSigner: false, isWritable: true}, - {pubkey: referralPoolAccount, isSigner: false, isWritable: true}, - {pubkey: poolMint, isSigner: false, isWritable: true}, - {pubkey: SystemProgram.programId, isSigner: false, isWritable: false}, - {pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false}, + { pubkey: stakePool, isSigner: false, isWritable: true }, + { pubkey: withdrawAuthority, isSigner: false, isWritable: false }, + { pubkey: reserveStake, isSigner: false, isWritable: true }, + { pubkey: fundingAccount, isSigner: true, isWritable: true }, + { pubkey: destinationPoolAccount, isSigner: false, isWritable: true }, + { pubkey: managerFeeAccount, isSigner: false, isWritable: true }, + { pubkey: referralPoolAccount, isSigner: false, isWritable: true }, + { pubkey: poolMint, isSigner: false, isWritable: true }, + { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, + { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, ]; if (depositAuthority) { @@ -246,22 +525,22 @@ export class StakePoolInstruction { } = params; const type = STAKE_POOL_INSTRUCTION_LAYOUTS.WithdrawStake; - const data = encodeData(type, {poolTokens}); + const data = encodeData(type, { poolTokens }); const keys = [ - {pubkey: stakePool, isSigner: false, isWritable: true}, - {pubkey: validatorList, isSigner: false, isWritable: true}, - {pubkey: withdrawAuthority, isSigner: false, isWritable: false}, - {pubkey: validatorStake, isSigner: false, isWritable: true}, - {pubkey: destinationStake, isSigner: false, isWritable: true}, - {pubkey: destinationStakeAuthority, isSigner: false, isWritable: false}, - {pubkey: sourceTransferAuthority, isSigner: true, isWritable: false}, - {pubkey: sourcePoolAccount, isSigner: false, isWritable: true}, - {pubkey: managerFeeAccount, isSigner: false, isWritable: true}, - {pubkey: poolMint, isSigner: false, isWritable: true}, - {pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false}, - {pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false}, - {pubkey: StakeProgram.programId, isSigner: false, isWritable: false}, + { pubkey: stakePool, isSigner: false, isWritable: true }, + { pubkey: validatorList, isSigner: false, isWritable: true }, + { pubkey: withdrawAuthority, isSigner: false, isWritable: false }, + { pubkey: validatorStake, isSigner: false, isWritable: true }, + { pubkey: destinationStake, isSigner: false, isWritable: true }, + { pubkey: destinationStakeAuthority, isSigner: false, isWritable: false }, + { pubkey: sourceTransferAuthority, isSigner: true, isWritable: false }, + { pubkey: sourcePoolAccount, isSigner: false, isWritable: true }, + { pubkey: managerFeeAccount, isSigner: false, isWritable: true }, + { pubkey: poolMint, isSigner: false, isWritable: true }, + { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false }, + { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, + { pubkey: StakeProgram.programId, isSigner: false, isWritable: false }, ]; return new TransactionInstruction({ @@ -289,21 +568,21 @@ export class StakePoolInstruction { } = params; const type = STAKE_POOL_INSTRUCTION_LAYOUTS.WithdrawSol; - const data = encodeData(type, {poolTokens}); + const data = encodeData(type, { poolTokens }); const keys = [ - {pubkey: stakePool, isSigner: false, isWritable: true}, - {pubkey: withdrawAuthority, isSigner: false, isWritable: false}, - {pubkey: sourceTransferAuthority, isSigner: true, isWritable: false}, - {pubkey: sourcePoolAccount, isSigner: false, isWritable: true}, - {pubkey: reserveStake, isSigner: false, isWritable: true}, - {pubkey: destinationSystemAccount, isSigner: false, isWritable: true}, - {pubkey: managerFeeAccount, isSigner: false, isWritable: true}, - {pubkey: poolMint, isSigner: false, isWritable: true}, - {pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false}, - {pubkey: SYSVAR_STAKE_HISTORY_PUBKEY, isSigner: false, isWritable: false}, - {pubkey: StakeProgram.programId, isSigner: false, isWritable: false}, - {pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false}, + { pubkey: stakePool, isSigner: false, isWritable: true }, + { pubkey: withdrawAuthority, isSigner: false, isWritable: false }, + { pubkey: sourceTransferAuthority, isSigner: true, isWritable: false }, + { pubkey: sourcePoolAccount, isSigner: false, isWritable: true }, + { pubkey: reserveStake, isSigner: false, isWritable: true }, + { pubkey: destinationSystemAccount, isSigner: false, isWritable: true }, + { pubkey: managerFeeAccount, isSigner: false, isWritable: true }, + { pubkey: poolMint, isSigner: false, isWritable: true }, + { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false }, + { pubkey: SYSVAR_STAKE_HISTORY_PUBKEY, isSigner: false, isWritable: false }, + { pubkey: StakeProgram.programId, isSigner: false, isWritable: false }, + { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, ]; if (solWithdrawAuthority) { @@ -324,9 +603,7 @@ export class StakePoolInstruction { /** * Decode a deposit stake pool instruction and retrieve the instruction params. */ - static decodeDepositStake( - instruction: TransactionInstruction, - ): DepositStakeParams { + static decodeDepositStake(instruction: TransactionInstruction): DepositStakeParams { this.checkProgramId(instruction.programId); this.checkKeyLength(instruction.keys, 11); @@ -350,16 +627,11 @@ export class StakePoolInstruction { /** * Decode a deposit sol instruction and retrieve the instruction params. */ - static decodeDepositSol( - instruction: TransactionInstruction, - ): DepositSolParams { + static decodeDepositSol(instruction: TransactionInstruction): DepositSolParams { this.checkProgramId(instruction.programId); this.checkKeyLength(instruction.keys, 9); - const {amount} = decodeData( - STAKE_POOL_INSTRUCTION_LAYOUTS.DepositSol, - instruction.data, - ); + const { amount } = decodeData(STAKE_POOL_INSTRUCTION_LAYOUTS.DepositSol, instruction.data); return { stakePool: instruction.keys[0].pubkey, diff --git a/clients/js-legacy/src/layouts.ts b/clients/js-legacy/src/layouts.ts index fafdde3e..ba5d9489 100644 --- a/clients/js-legacy/src/layouts.ts +++ b/clients/js-legacy/src/layouts.ts @@ -1,14 +1,6 @@ -import { - publicKey, - struct, - u32, - u64, - u8, - option, - vec, -} from '@project-serum/borsh'; -import {Lockup, PublicKey} from '@solana/web3.js'; -import {AccountInfo} from '@solana/spl-token'; +import { publicKey, struct, u32, u64, u8, option, vec } from '@project-serum/borsh'; +import { Lockup, PublicKey } from '@solana/web3.js'; +import { AccountInfo } from '@solana/spl-token'; import BN from 'bn.js'; export interface Fee { @@ -62,7 +54,7 @@ export interface StakePool { preferredWithdrawValidatorVoteAddress?: PublicKey | undefined; stakeDepositFee: Fee; stakeWithdrawalFee: Fee; - nextWithdrawalFee?: Fee | undefined; + nextStakeWithdrawalFee?: Fee | undefined; stakeReferralFee: number; solDepositAuthority?: PublicKey | undefined; solDepositFee: Fee; @@ -88,17 +80,14 @@ export const StakePoolLayout = struct([ u64('totalLamports'), u64('poolTokenSupply'), u64('lastUpdateEpoch'), - struct( - [u64('unixTimestamp'), u64('epoch'), publicKey('custodian')], - 'lockup', - ), + struct([u64('unixTimestamp'), u64('epoch'), publicKey('custodian')], 'lockup'), struct(feeFields, 'epochFee'), option(struct(feeFields), 'nextEpochFee'), option(publicKey(), 'preferredDepositValidatorVoteAddress'), option(publicKey(), 'preferredWithdrawValidatorVoteAddress'), struct(feeFields, 'stakeDepositFee'), struct(feeFields, 'stakeWithdrawalFee'), - option(struct(feeFields), 'nextWithdrawalFee'), + option(struct(feeFields), 'nextStakeWithdrawalFee'), u8('stakeReferralFee'), option(publicKey(), 'solDepositAuthority'), struct(feeFields, 'solDepositFee'), diff --git a/clients/js-legacy/src/buffer-layout.d.ts b/clients/js-legacy/src/types/buffer-layout.d.ts similarity index 79% rename from clients/js-legacy/src/buffer-layout.d.ts rename to clients/js-legacy/src/types/buffer-layout.d.ts index 0e506a0f..54773bba 100644 --- a/clients/js-legacy/src/buffer-layout.d.ts +++ b/clients/js-legacy/src/types/buffer-layout.d.ts @@ -2,11 +2,7 @@ declare module 'buffer-layout' { export class Layout {} export class UInt {} /* eslint-disable @typescript-eslint/no-unused-vars */ - export function struct( - fields: any, - property?: string, - decodePrefixes?: boolean, - ): any; + export function struct(fields: any, property?: string, decodePrefixes?: boolean): any; export function s32(property?: string): UInt; export function u32(property?: string): UInt; export function s16(property?: string): UInt; diff --git a/clients/js-legacy/src/utils/index.ts b/clients/js-legacy/src/utils/index.ts index 49665079..1091d0ec 100644 --- a/clients/js-legacy/src/utils/index.ts +++ b/clients/js-legacy/src/utils/index.ts @@ -2,3 +2,12 @@ export * from './math'; export * from './program-address'; export * from './stake'; export * from './token'; +export * from './instruction'; + +export function arrayChunk(array: any[], size: number): any[] { + const result = []; + for (let i = 0; i < array.length; i += size) { + result.push(array.slice(i, i + size)); + } + return result; +} diff --git a/clients/js-legacy/src/copied-from-solana-web3/instruction.ts b/clients/js-legacy/src/utils/instruction.ts similarity index 82% rename from clients/js-legacy/src/copied-from-solana-web3/instruction.ts rename to clients/js-legacy/src/utils/instruction.ts index ec1a6353..24ccad8a 100644 --- a/clients/js-legacy/src/copied-from-solana-web3/instruction.ts +++ b/clients/js-legacy/src/utils/instruction.ts @@ -1,5 +1,5 @@ -import {Buffer} from 'buffer'; -import {Layout} from '@solana/buffer-layout'; +import * as BufferLayout from '@solana/buffer-layout'; +import { Buffer } from 'buffer'; /** * @internal @@ -8,7 +8,7 @@ export type InstructionType = { /** The Instruction index (from solana upstream program) */ index: number; /** The BufferLayout to use to build data */ - layout: Layout; // NOTE do this better + layout: BufferLayout.Layout; }; /** @@ -18,7 +18,7 @@ export type InstructionType = { export function encodeData(type: InstructionType, fields?: any): Buffer { const allocLength = type.layout.span; const data = Buffer.alloc(allocLength); - const layoutFields = Object.assign({instruction: type.index}, fields); + const layoutFields = Object.assign({ instruction: type.index }, fields); type.layout.encode(layoutFields, data); return data; diff --git a/clients/js-legacy/src/utils/math.ts b/clients/js-legacy/src/utils/math.ts index b0ba6250..ab64724e 100644 --- a/clients/js-legacy/src/utils/math.ts +++ b/clients/js-legacy/src/utils/math.ts @@ -1,5 +1,5 @@ import BN from 'bn.js'; -import {LAMPORTS_PER_SOL} from '@solana/web3.js'; +import { LAMPORTS_PER_SOL } from '@solana/web3.js'; export function solToLamports(amount: number): number { if (isNaN(amount)) return Number(0); @@ -19,9 +19,6 @@ export function lamportsToSol(lamports: number | BN): number { const absLamports = lamports.abs(); const lamportsString = absLamports.toString(10).padStart(10, '0'); const splitIndex = lamportsString.length - 9; - const solString = - lamportsString.slice(0, splitIndex) + - '.' + - lamportsString.slice(splitIndex); + const solString = lamportsString.slice(0, splitIndex) + '.' + lamportsString.slice(splitIndex); return signMultiplier * parseFloat(solString); } diff --git a/clients/js-legacy/src/utils/program-address.ts b/clients/js-legacy/src/utils/program-address.ts index 87383817..2eb364c1 100644 --- a/clients/js-legacy/src/utils/program-address.ts +++ b/clients/js-legacy/src/utils/program-address.ts @@ -1,6 +1,7 @@ -import {PublicKey} from '@solana/web3.js'; +import { PublicKey } from '@solana/web3.js'; import BN from 'bn.js'; -import {TRANSIENT_STAKE_SEED_PREFIX} from '../constants'; +import { Buffer } from 'buffer'; +import { TRANSIENT_STAKE_SEED_PREFIX } from '../constants'; /** * Generates the withdraw authority program address for the stake pool diff --git a/clients/js-legacy/src/utils/stake.ts b/clients/js-legacy/src/utils/stake.ts index c4f54811..9eef2c6c 100644 --- a/clients/js-legacy/src/utils/stake.ts +++ b/clients/js-legacy/src/utils/stake.ts @@ -6,39 +6,63 @@ import { SystemProgram, TransactionInstruction, } from '@solana/web3.js'; -import { - findStakeProgramAddress, - findTransientStakeProgramAddress, -} from './program-address'; +import { findStakeProgramAddress, findTransientStakeProgramAddress } from './program-address'; import BN from 'bn.js'; -import {lamportsToSol} from './math'; -import {WithdrawAccount} from '../index'; +import { lamportsToSol } from './math'; +import { WithdrawAccount } from '../index'; import { + Fee, StakePool, ValidatorList, ValidatorListLayout, ValidatorStakeInfoStatus, } from '../layouts'; -import {STAKE_POOL_PROGRAM_ID} from '../constants'; +import { MINIMUM_ACTIVE_STAKE, STAKE_POOL_PROGRAM_ID } from '../constants'; + +export async function getValidatorListAccount(connection: Connection, pubkey: PublicKey) { + const account = await connection.getAccountInfo(pubkey); + if (!account) { + throw new Error('Invalid validator list account'); + } + return { + pubkey, + account: { + data: ValidatorListLayout.decode(account?.data) as ValidatorList, + executable: account.executable, + lamports: account.lamports, + owner: account.owner, + }, + }; +} + +export interface ValidatorAccount { + type: 'preferred' | 'active' | 'transient' | 'reserve'; + voteAddress?: PublicKey | undefined; + stakeAddress: PublicKey; + lamports: number; +} export async function prepareWithdrawAccounts( connection: Connection, stakePool: StakePool, stakePoolAddress: PublicKey, amount: number, + compareFn?: (a: ValidatorAccount, b: ValidatorAccount) => number, + skipFee?: boolean, ): Promise { - const validatorListAcc = await connection.getAccountInfo( - stakePool.validatorList, - ); - const validatorList = ValidatorListLayout.decode( - validatorListAcc?.data, - ) as ValidatorList; + const validatorListAcc = await connection.getAccountInfo(stakePool.validatorList); + const validatorList = ValidatorListLayout.decode(validatorListAcc?.data) as ValidatorList; if (!validatorList?.validators || validatorList?.validators.length == 0) { throw new Error('No accounts found'); } + const minBalanceForRentExemption = await connection.getMinimumBalanceForRentExemption( + StakeProgram.space, + ); + const minBalance = minBalanceForRentExemption + MINIMUM_ACTIVE_STAKE; + let accounts = [] as Array<{ type: 'preferred' | 'active' | 'transient' | 'reserve'; voteAddress?: PublicKey | undefined; @@ -59,10 +83,9 @@ export async function prepareWithdrawAccounts( ); if (!validator.activeStakeLamports.isZero()) { - const isPreferred = - stakePool.preferredWithdrawValidatorVoteAddress && - stakePool.preferredWithdrawValidatorVoteAddress.toBase58() == - validator.voteAccountAddress.toBase58(); + const isPreferred = stakePool?.preferredWithdrawValidatorVoteAddress?.equals( + validator.voteAccountAddress, + ); accounts.push({ type: isPreferred ? 'preferred' : 'active', voteAddress: validator.voteAccountAddress, @@ -71,33 +94,33 @@ export async function prepareWithdrawAccounts( }); } - const transientStakeAccountAddress = await findTransientStakeProgramAddress( - STAKE_POOL_PROGRAM_ID, - validator.voteAccountAddress, - stakePoolAddress, - validator.transientSeedSuffixStart, - ); - - if (!validator.transientStakeLamports?.isZero()) { + const transientStakeLamports = validator.transientStakeLamports.toNumber() - minBalance; + if (transientStakeLamports > 0) { + const transientStakeAccountAddress = await findTransientStakeProgramAddress( + STAKE_POOL_PROGRAM_ID, + validator.voteAccountAddress, + stakePoolAddress, + validator.transientSeedSuffixStart, + ); accounts.push({ type: 'transient', voteAddress: validator.voteAccountAddress, stakeAddress: transientStakeAccountAddress, - lamports: validator.transientStakeLamports.toNumber(), + lamports: transientStakeLamports, }); } } // Sort from highest to lowest balance - accounts = accounts.sort((a, b) => b.lamports - a.lamports); + accounts = accounts.sort(compareFn ? compareFn : (a, b) => b.lamports - a.lamports); const reserveStake = await connection.getAccountInfo(stakePool.reserveStake); - if (reserveStake && reserveStake.lamports > 0) { - console.log('Reserve Stake: ', reserveStake.lamports); + const reserveStakeBalance = (reserveStake?.lamports ?? 0) - minBalanceForRentExemption - 1; + if (reserveStakeBalance > 0) { accounts.push({ type: 'reserve', stakeAddress: stakePool.reserveStake, - lamports: reserveStake?.lamports, + lamports: reserveStakeBalance, }); } @@ -105,21 +128,26 @@ export async function prepareWithdrawAccounts( const withdrawFrom: WithdrawAccount[] = []; let remainingAmount = amount; + const fee = stakePool.stakeWithdrawalFee; + const inverseFee: Fee = { + numerator: fee.denominator.sub(fee.numerator), + denominator: fee.denominator, + }; + for (const type of ['preferred', 'active', 'transient', 'reserve']) { - const filteredAccounts = accounts.filter(a => a.type == type); + const filteredAccounts = accounts.filter((a) => a.type == type); - for (const {stakeAddress, voteAddress, lamports} of filteredAccounts) { - let availableForWithdrawal = Math.floor( - calcPoolTokensForDeposit(stakePool, lamports), - ); - if (!stakePool.stakeWithdrawalFee.denominator.isZero()) { + for (const { stakeAddress, voteAddress, lamports } of filteredAccounts) { + if (lamports <= minBalance && type == 'transient') { + continue; + } + + let availableForWithdrawal = calcPoolTokensForDeposit(stakePool, lamports); + + if (!skipFee && !inverseFee.numerator.isZero()) { availableForWithdrawal = divideBnToNumber( - new BN(availableForWithdrawal).mul( - stakePool.stakeWithdrawalFee.denominator, - ), - stakePool.stakeWithdrawalFee.denominator.sub( - stakePool.stakeWithdrawalFee.numerator, - ), + new BN(availableForWithdrawal).mul(inverseFee.denominator), + inverseFee.numerator, ); } @@ -129,12 +157,14 @@ export async function prepareWithdrawAccounts( } // Those accounts will be withdrawn completely with `claim` instruction - withdrawFrom.push({stakeAddress, voteAddress, poolAmount}); + withdrawFrom.push({ stakeAddress, voteAddress, poolAmount }); remainingAmount -= poolAmount; + if (remainingAmount == 0) { break; } } + if (remainingAmount == 0) { break; } @@ -155,26 +185,19 @@ export async function prepareWithdrawAccounts( /** * Calculate the pool tokens that should be minted for a deposit of `stakeLamports` */ -export function calcPoolTokensForDeposit( - stakePool: StakePool, - stakeLamports: number, -): number { +export function calcPoolTokensForDeposit(stakePool: StakePool, stakeLamports: number): number { if (stakePool.poolTokenSupply.isZero() || stakePool.totalLamports.isZero()) { return stakeLamports; } - return divideBnToNumber( - new BN(stakeLamports).mul(stakePool.poolTokenSupply), - stakePool.totalLamports, + return Math.floor( + divideBnToNumber(new BN(stakeLamports).mul(stakePool.poolTokenSupply), stakePool.totalLamports), ); } /** * Calculate lamports amount on withdrawal */ -export function calcLamportsWithdrawAmount( - stakePool: StakePool, - poolTokens: number, -): number { +export function calcLamportsWithdrawAmount(stakePool: StakePool, poolTokens: number): number { const numerator = new BN(poolTokens).mul(stakePool.totalLamports); const denominator = stakePool.poolTokenSupply; if (numerator.lt(denominator)) { @@ -200,9 +223,7 @@ export function newStakeAccount( ): Keypair { // Account for tokens not specified, creating one const stakeReceiverKeypair = Keypair.generate(); - console.log( - `Creating account to receive stake ${stakeReceiverKeypair.publicKey}`, - ); + console.log(`Creating account to receive stake ${stakeReceiverKeypair.publicKey}`); instructions.push( // Creating new account diff --git a/clients/js-legacy/src/utils/token.ts b/clients/js-legacy/src/utils/token.ts index f05859e0..ee20463f 100644 --- a/clients/js-legacy/src/utils/token.ts +++ b/clients/js-legacy/src/utils/token.ts @@ -1,15 +1,25 @@ -import {Connection, PublicKey, TransactionInstruction} from '@solana/web3.js'; +import { Connection, PublicKey, TransactionInstruction } from '@solana/web3.js'; import { AccountInfo, ASSOCIATED_TOKEN_PROGRAM_ID, + MintInfo, Token, TOKEN_PROGRAM_ID, } from '@solana/spl-token'; -import {AccountLayout} from '../layouts'; +import { AccountLayout } from '../layouts'; const FAILED_TO_FIND_ACCOUNT = 'Failed to find account'; const INVALID_ACCOUNT_OWNER = 'Invalid account owner'; +export async function getTokenMint( + connection: Connection, + tokenMintPubkey: PublicKey, +): Promise { + // @ts-ignore + const token = new Token(connection, tokenMintPubkey, TOKEN_PROGRAM_ID, null); + return token.getMintInfo(); +} + /** * Retrieve the associated account or create one if not found. * This account may then be used as a `transfer()` or `approve()` destination @@ -27,6 +37,8 @@ export async function addAssociatedTokenAccount( owner, ); + let rentFee = 0; + // This is the optimum logic, considering TX fee, client-side computation, // RPC roundtrips and guaranteed idempotent. // Sadly we can't do this atomically; @@ -41,10 +53,7 @@ export async function addAssociatedTokenAccount( // already been received some lamports (= became system accounts). // Assuming program derived addressing is safe, this is the only case // for the INVALID_ACCOUNT_OWNER in this code-path - if ( - err.message === FAILED_TO_FIND_ACCOUNT || - err.message === INVALID_ACCOUNT_OWNER - ) { + if (err.message === FAILED_TO_FIND_ACCOUNT || err.message === INVALID_ACCOUNT_OWNER) { instructions.push( Token.createAssociatedTokenAccountInstruction( ASSOCIATED_TOKEN_PROGRAM_ID, @@ -55,13 +64,17 @@ export async function addAssociatedTokenAccount( owner, ), ); + rentFee = await connection.getMinimumBalanceForRentExemption(AccountLayout.span); } else { throw err; } console.warn(err); } - return associatedAddress; + return { + associatedAddress, + rentFee, + }; } export async function getTokenAccount( diff --git a/clients/js-legacy/test/equal.ts b/clients/js-legacy/test/equal.ts index 49e84993..b86e417b 100644 --- a/clients/js-legacy/test/equal.ts +++ b/clients/js-legacy/test/equal.ts @@ -1,14 +1,4 @@ import BN from 'bn.js'; -import {StakePoolAccount} from '../src'; - -export function isStakePoolAccount(account: any): account is StakePoolAccount { - return ( - account !== undefined && - account.account !== undefined && - account.account.data !== undefined && - 'manager' in account.account.data - ); -} /** * Helper function to do deep equality check because BNs are not equal. @@ -23,9 +13,7 @@ export function deepStrictEqualBN(a: any, b: any) { for (const subkey in a[key]) { if (a[key][subkey] instanceof Object) { if (a[key][subkey] instanceof BN) { - expect(b[key][subkey].toString()).toEqual( - a[key][subkey].toString(), - ); + expect(b[key][subkey].toString()).toEqual(a[key][subkey].toString()); } else { for (const subsubkey in a[key][subkey]) { if (a[key][subkey][subsubkey] instanceof BN) { @@ -33,9 +21,7 @@ export function deepStrictEqualBN(a: any, b: any) { a[key][subkey][subsubkey].toString(), ); } else { - expect(b[key][subkey][subsubkey]).toStrictEqual( - a[key][subkey][subsubkey], - ); + expect(b[key][subkey][subsubkey]).toStrictEqual(a[key][subkey][subsubkey]); } } } diff --git a/clients/js-legacy/test/instructions.test.ts b/clients/js-legacy/test/instructions.test.ts index b21d6f71..8a9681b1 100644 --- a/clients/js-legacy/test/instructions.test.ts +++ b/clients/js-legacy/test/instructions.test.ts @@ -6,11 +6,10 @@ import { AccountInfo, LAMPORTS_PER_SOL, } from '@solana/web3.js'; -import {StakePoolLayout} from '../src/layouts'; -import {STAKE_POOL_PROGRAM_ID} from '../src/constants'; -import {decodeData} from '../src/copied-from-solana-web3/instruction'; +import { StakePoolLayout } from '../src/layouts'; import { STAKE_POOL_INSTRUCTION_LAYOUTS, + STAKE_POOL_PROGRAM_ID, DepositSolParams, StakePoolInstruction, depositSol, @@ -18,30 +17,30 @@ import { withdrawStake, } from '../src'; -import {mockTokenAccount, mockValidatorList, stakePoolMock} from './mocks'; +import { decodeData } from '../src/utils'; + +import { mockTokenAccount, mockValidatorList, stakePoolMock } from './mocks'; describe('StakePoolProgram', () => { const connection = new Connection('http://127.0.0.1:8899'); connection.getMinimumBalanceForRentExemption = jest.fn(async () => 10000); - const stakePoolPubkey = new PublicKey( - 'SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy', - ); + const stakePoolAddress = new PublicKey('SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy'); const data = Buffer.alloc(1024); StakePoolLayout.encode(stakePoolMock, data); const stakePoolAccount = >{ executable: true, - owner: stakePoolPubkey, + owner: stakePoolAddress, lamports: 99999, data, }; it('StakePoolInstruction.depositSol', () => { const payload: DepositSolParams = { - stakePool: stakePoolPubkey, + stakePool: stakePoolAddress, withdrawAuthority: Keypair.generate().publicKey, reserveStake: Keypair.generate().publicKey, fundingAccount: Keypair.generate().publicKey, @@ -55,39 +54,20 @@ describe('StakePoolProgram', () => { const instruction = StakePoolInstruction.depositSol(payload); expect(instruction.keys).toHaveLength(10); - expect(instruction.keys[0].pubkey.toBase58()).toEqual( - payload.stakePool.toBase58(), - ); - expect(instruction.keys[1].pubkey.toBase58()).toEqual( - payload.withdrawAuthority.toBase58(), - ); - expect(instruction.keys[3].pubkey.toBase58()).toEqual( - payload.fundingAccount.toBase58(), - ); + expect(instruction.keys[0].pubkey.toBase58()).toEqual(payload.stakePool.toBase58()); + expect(instruction.keys[1].pubkey.toBase58()).toEqual(payload.withdrawAuthority.toBase58()); + expect(instruction.keys[3].pubkey.toBase58()).toEqual(payload.fundingAccount.toBase58()); expect(instruction.keys[4].pubkey.toBase58()).toEqual( payload.destinationPoolAccount.toBase58(), ); - expect(instruction.keys[5].pubkey.toBase58()).toEqual( - payload.managerFeeAccount.toBase58(), - ); - expect(instruction.keys[6].pubkey.toBase58()).toEqual( - payload.referralPoolAccount.toBase58(), - ); - expect(instruction.keys[8].pubkey.toBase58()).toEqual( - SystemProgram.programId.toBase58(), - ); - expect(instruction.keys[9].pubkey.toBase58()).toEqual( - STAKE_POOL_PROGRAM_ID.toBase58(), - ); + expect(instruction.keys[5].pubkey.toBase58()).toEqual(payload.managerFeeAccount.toBase58()); + expect(instruction.keys[6].pubkey.toBase58()).toEqual(payload.referralPoolAccount.toBase58()); + expect(instruction.keys[8].pubkey.toBase58()).toEqual(SystemProgram.programId.toBase58()); + expect(instruction.keys[9].pubkey.toBase58()).toEqual(STAKE_POOL_PROGRAM_ID.toBase58()); - const decodedData = decodeData( - STAKE_POOL_INSTRUCTION_LAYOUTS.DepositSol, - instruction.data, - ); + const decodedData = decodeData(STAKE_POOL_INSTRUCTION_LAYOUTS.DepositSol, instruction.data); - expect(decodedData.instruction).toEqual( - STAKE_POOL_INSTRUCTION_LAYOUTS.DepositSol.index, - ); + expect(decodedData.instruction).toEqual(STAKE_POOL_INSTRUCTION_LAYOUTS.DepositSol.index); expect(decodedData.lamports).toEqual(payload.lamports); payload.depositAuthority = Keypair.generate().publicKey; @@ -95,9 +75,7 @@ describe('StakePoolProgram', () => { const instruction2 = StakePoolInstruction.depositSol(payload); expect(instruction2.keys).toHaveLength(11); - expect(instruction2.keys[10].pubkey.toBase58()).toEqual( - payload.depositAuthority.toBase58(), - ); + expect(instruction2.keys[10].pubkey.toBase58()).toEqual(payload.depositAuthority.toBase58()); }); describe('depositSol', () => { @@ -106,8 +84,8 @@ describe('StakePoolProgram', () => { connection.getBalance = jest.fn(async () => balance); - connection.getAccountInfo = jest.fn(async pubKey => { - if (pubKey == stakePoolPubkey) { + connection.getAccountInfo = jest.fn(async (pubKey) => { + if (pubKey == stakePoolAddress) { return stakePoolAccount; } return >{ @@ -119,25 +97,21 @@ describe('StakePoolProgram', () => { }); it.only('should throw an error with invalid balance', async () => { - await expect( - depositSol(connection, stakePoolPubkey, from, balance + 1), - ).rejects.toThrow( - Error( - 'Not enough SOL to deposit into pool. Maximum deposit amount is 0.00001 SOL.', - ), + await expect(depositSol(connection, stakePoolAddress, from, balance + 1)).rejects.toThrow( + Error('Not enough SOL to deposit into pool. Maximum deposit amount is 0.00001 SOL.'), ); }); it.only('should throw an error with invalid account', async () => { connection.getAccountInfo = jest.fn(async () => null); - await expect( - depositSol(connection, stakePoolPubkey, from, balance), - ).rejects.toThrow(Error('Invalid account')); + await expect(depositSol(connection, stakePoolAddress, from, balance)).rejects.toThrow( + Error('Invalid stake pool account'), + ); }); it.only('should call successfully', async () => { - connection.getAccountInfo = jest.fn(async pubKey => { - if (pubKey == stakePoolPubkey) { + connection.getAccountInfo = jest.fn(async (pubKey) => { + if (pubKey == stakePoolAddress) { return stakePoolAccount; } return >{ @@ -148,11 +122,9 @@ describe('StakePoolProgram', () => { }; }); - const res = await depositSol(connection, stakePoolPubkey, from, balance); + const res = await depositSol(connection, stakePoolAddress, from, balance); - expect((connection.getAccountInfo as jest.Mock).mock.calls.length).toBe( - 2, - ); + expect((connection.getAccountInfo as jest.Mock).mock.calls.length).toBe(2); expect(res.instructions).toHaveLength(2); expect(res.signers).toHaveLength(1); }); @@ -165,43 +137,39 @@ describe('StakePoolProgram', () => { it.only('should throw an error with invalid stake pool account', async () => { connection.getAccountInfo = jest.fn(async () => null); await expect( - withdrawSol(connection, stakePoolPubkey, tokenOwner, solReceiver, 1), - ).rejects.toThrowError('Invalid account'); + withdrawSol(connection, stakePoolAddress, tokenOwner, solReceiver, 1), + ).rejects.toThrowError('Invalid stake pool account'); }); it.only('should throw an error with invalid token account', async () => { connection.getAccountInfo = jest.fn(async (pubKey: PublicKey) => { - if (pubKey == stakePoolPubkey) { + if (pubKey == stakePoolAddress) { return stakePoolAccount; } - if ( - pubKey.toBase58() == '9q2rZU5RujvyD9dmYKhzJAZfG4aGBbvQ8rWY52jCNBai' - ) { + if (pubKey.toBase58() == '9q2rZU5RujvyD9dmYKhzJAZfG4aGBbvQ8rWY52jCNBai') { return null; } return null; }); await expect( - withdrawSol(connection, stakePoolPubkey, tokenOwner, solReceiver, 1), + withdrawSol(connection, stakePoolAddress, tokenOwner, solReceiver, 1), ).rejects.toThrow(Error('Invalid token account')); }); it.only('should throw an error with invalid token account balance', async () => { connection.getAccountInfo = jest.fn(async (pubKey: PublicKey) => { - if (pubKey == stakePoolPubkey) { + if (pubKey == stakePoolAddress) { return stakePoolAccount; } - if ( - pubKey.toBase58() == 'GQkqTamwqjaNDfsbNm7r3aXPJ4oTSqKC3d5t2PF9Smqd' - ) { + if (pubKey.toBase58() == 'GQkqTamwqjaNDfsbNm7r3aXPJ4oTSqKC3d5t2PF9Smqd') { return mockTokenAccount(0); } return null; }); await expect( - withdrawSol(connection, stakePoolPubkey, tokenOwner, solReceiver, 1), + withdrawSol(connection, stakePoolAddress, tokenOwner, solReceiver, 1), ).rejects.toThrow( Error( 'Not enough token balance to withdraw 1 pool tokens.\n Maximum withdraw amount is 0 pool tokens.', @@ -211,27 +179,17 @@ describe('StakePoolProgram', () => { it.only('should call successfully', async () => { connection.getAccountInfo = jest.fn(async (pubKey: PublicKey) => { - if (pubKey == stakePoolPubkey) { + if (pubKey == stakePoolAddress) { return stakePoolAccount; } - if ( - pubKey.toBase58() == 'GQkqTamwqjaNDfsbNm7r3aXPJ4oTSqKC3d5t2PF9Smqd' - ) { + if (pubKey.toBase58() == 'GQkqTamwqjaNDfsbNm7r3aXPJ4oTSqKC3d5t2PF9Smqd') { return mockTokenAccount(LAMPORTS_PER_SOL); } return null; }); - const res = await withdrawSol( - connection, - stakePoolPubkey, - tokenOwner, - solReceiver, - 1, - ); + const res = await withdrawSol(connection, stakePoolAddress, tokenOwner, solReceiver, 1); - expect((connection.getAccountInfo as jest.Mock).mock.calls.length).toBe( - 2, - ); + expect((connection.getAccountInfo as jest.Mock).mock.calls.length).toBe(2); expect(res.instructions).toHaveLength(2); expect(res.signers).toHaveLength(1); }); @@ -242,33 +200,29 @@ describe('StakePoolProgram', () => { it.only('should throw an error with invalid token account', async () => { connection.getAccountInfo = jest.fn(async (pubKey: PublicKey) => { - if (pubKey == stakePoolPubkey) { + if (pubKey == stakePoolAddress) { return stakePoolAccount; } return null; }); - await expect( - withdrawStake(connection, stakePoolPubkey, tokenOwner, 1), - ).rejects.toThrow(Error('Invalid token account')); + await expect(withdrawStake(connection, stakePoolAddress, tokenOwner, 1)).rejects.toThrow( + Error('Invalid token account'), + ); }); it.only('should throw an error with invalid token account balance', async () => { connection.getAccountInfo = jest.fn(async (pubKey: PublicKey) => { - if (pubKey == stakePoolPubkey) { + if (pubKey == stakePoolAddress) { return stakePoolAccount; } - if ( - pubKey.toBase58() == 'GQkqTamwqjaNDfsbNm7r3aXPJ4oTSqKC3d5t2PF9Smqd' - ) { + if (pubKey.toBase58() == 'GQkqTamwqjaNDfsbNm7r3aXPJ4oTSqKC3d5t2PF9Smqd') { return mockTokenAccount(0); } return null; }); - await expect( - withdrawStake(connection, stakePoolPubkey, tokenOwner, 1), - ).rejects.toThrow( + await expect(withdrawStake(connection, stakePoolAddress, tokenOwner, 1)).rejects.toThrow( Error( 'Not enough token balance to withdraw 1 pool tokens.\n' + ' Maximum withdraw amount is 0 pool tokens.', @@ -278,12 +232,10 @@ describe('StakePoolProgram', () => { it.only('should call successfully', async () => { connection.getAccountInfo = jest.fn(async (pubKey: PublicKey) => { - if (pubKey == stakePoolPubkey) { + if (pubKey == stakePoolAddress) { return stakePoolAccount; } - if ( - pubKey.toBase58() == 'GQkqTamwqjaNDfsbNm7r3aXPJ4oTSqKC3d5t2PF9Smqd' - ) { + if (pubKey.toBase58() == 'GQkqTamwqjaNDfsbNm7r3aXPJ4oTSqKC3d5t2PF9Smqd') { return mockTokenAccount(LAMPORTS_PER_SOL * 2); } if (pubKey.toBase58() == stakePoolMock.validatorList.toBase58()) { @@ -292,16 +244,9 @@ describe('StakePoolProgram', () => { return null; }); - const res = await withdrawStake( - connection, - stakePoolPubkey, - tokenOwner, - 1, - ); + const res = await withdrawStake(connection, stakePoolAddress, tokenOwner, 1); - expect((connection.getAccountInfo as jest.Mock).mock.calls.length).toBe( - 4, - ); + expect((connection.getAccountInfo as jest.Mock).mock.calls.length).toBe(4); expect(res.instructions).toHaveLength(3); expect(res.signers).toHaveLength(2); expect(res.stakeReceiver).toEqual(undefined); diff --git a/clients/js-legacy/test/layouts.test.ts b/clients/js-legacy/test/layouts.test.ts index 292a95f6..053f43e1 100644 --- a/clients/js-legacy/test/layouts.test.ts +++ b/clients/js-legacy/test/layouts.test.ts @@ -1,10 +1,6 @@ -import { - StakePoolLayout, - ValidatorListLayout, - ValidatorList, -} from '../src/layouts'; -import {deepStrictEqualBN} from './equal'; -import {stakePoolMock, validatorListMock} from './mocks'; +import { StakePoolLayout, ValidatorListLayout, ValidatorList } from '../src/layouts'; +import { deepStrictEqualBN } from './equal'; +import { stakePoolMock, validatorListMock } from './mocks'; describe('layouts', () => { describe('StakePoolAccount', () => { diff --git a/clients/js-legacy/test/mocks.ts b/clients/js-legacy/test/mocks.ts index 52716773..df2c0c04 100644 --- a/clients/js-legacy/test/mocks.ts +++ b/clients/js-legacy/test/mocks.ts @@ -1,11 +1,7 @@ -import {AccountInfo, LAMPORTS_PER_SOL, PublicKey} from '@solana/web3.js'; +import { AccountInfo, LAMPORTS_PER_SOL, PublicKey } from '@solana/web3.js'; import BN from 'bn.js'; -import {ValidatorStakeInfo} from '../src'; -import { - ValidatorStakeInfoStatus, - AccountLayout, - ValidatorListLayout, -} from '../src/layouts'; +import { ValidatorStakeInfo } from '../src'; +import { ValidatorStakeInfoStatus, AccountLayout, ValidatorListLayout } from '../src/layouts'; export const stakePoolMock = { accountType: 1, @@ -44,7 +40,7 @@ export const stakePoolMock = { denominator: new BN(0), numerator: new BN(0), }, - nextWithdrawalFee: { + nextStakeWithdrawalFee: { denominator: new BN(0), numerator: new BN(0), }, @@ -75,10 +71,7 @@ export const validatorListMock = { { status: ValidatorStakeInfoStatus.ReadyForRemoval, voteAccountAddress: new PublicKey( - new BN( - 'a9946a889af14fd3c9b33d5df309489d9699271a6b09ff3190fcb41cf21a2f8c', - 'hex', - ), + new BN('a9946a889af14fd3c9b33d5df309489d9699271a6b09ff3190fcb41cf21a2f8c', 'hex'), ), lastUpdateEpoch: new BN('c3', 'hex'), activeStakeLamports: new BN(123), @@ -89,10 +82,7 @@ export const validatorListMock = { { status: ValidatorStakeInfoStatus.Active, voteAccountAddress: new PublicKey( - new BN( - '3796d40645ee07e3c64117e3f73430471d4c40465f696ebc9b034c1fc06a9f7d', - 'hex', - ), + new BN('3796d40645ee07e3c64117e3f73430471d4c40465f696ebc9b034c1fc06a9f7d', 'hex'), ), lastUpdateEpoch: new BN('c3', 'hex'), activeStakeLamports: new BN(LAMPORTS_PER_SOL * 100), @@ -103,10 +93,7 @@ export const validatorListMock = { { status: ValidatorStakeInfoStatus.Active, voteAccountAddress: new PublicKey( - new BN( - 'e4e37d6f2e80c0bb0f3da8a06304e57be5cda6efa2825b86780aa320d9784cf8', - 'hex', - ), + new BN('e4e37d6f2e80c0bb0f3da8a06304e57be5cda6efa2825b86780aa320d9784cf8', 'hex'), ), lastUpdateEpoch: new BN('c3', 'hex'), activeStakeLamports: new BN(0), diff --git a/clients/js-legacy/tsconfig.json b/clients/js-legacy/tsconfig.json index eb622f76..d8b2a264 100644 --- a/clients/js-legacy/tsconfig.json +++ b/clients/js-legacy/tsconfig.json @@ -1,23 +1,22 @@ { "compilerOptions": { + "module": "esnext", "target": "es2019", - "allowJs": true, + "baseUrl": "./src", + "outDir": "dist", "declaration": true, "declarationDir": "dist", - "outDir": "dist", "esModuleInterop": true, "allowSyntheticDefaultImports": true, "strict": true, "forceConsistentCasingInFileNames": true, - "module": "esnext", "moduleResolution": "node", "resolveJsonModule": true, "isolatedModules": true, - "baseUrl": "src", "noFallthroughCasesInSwitch": true, "noImplicitReturns": true }, "include": [ - "src/**/*" + "src/**/*.ts" ] } From 5df6d83daac89616387f56c7bcc60aeb3b266217 Mon Sep 17 00:00:00 2001 From: Tyera Eulberg Date: Wed, 23 Feb 2022 16:20:55 -0700 Subject: [PATCH 0234/1076] Bump solana to v1.9.9 (#2902) --- clients/cli/Cargo.toml | 18 +++++++++--------- program/Cargo.toml | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 02407bf3..7f550ebf 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -14,15 +14,15 @@ clap = "2.33.3" serde = "1.0.130" serde_derive = "1.0.130" serde_json = "1.0.68" -solana-account-decoder = "=1.9.5" -solana-clap-utils = "=1.9.5" -solana-cli-config = "=1.9.5" -solana-cli-output = "=1.9.5" -solana-client = "=1.9.5" -solana-logger = "=1.9.5" -solana-program = "=1.9.5" -solana-remote-wallet = "=1.9.5" -solana-sdk = "=1.9.5" +solana-account-decoder = "=1.9.9" +solana-clap-utils = "=1.9.9" +solana-cli-config = "=1.9.9" +solana-cli-output = "=1.9.9" +solana-client = "=1.9.9" +solana-logger = "=1.9.9" +solana-program = "=1.9.9" +solana-remote-wallet = "=1.9.9" +solana-sdk = "=1.9.9" spl-associated-token-account = { version = "=1.0.5", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "=0.6.4", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "=3.3.0", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/program/Cargo.toml b/program/Cargo.toml index 04518402..9acbf51d 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -19,7 +19,7 @@ num-traits = "0.2" num_enum = "0.5.4" serde = "1.0.130" serde_derive = "1.0.103" -solana-program = "1.9.5" +solana-program = "1.9.9" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-token = { version = "3.3", path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" @@ -27,9 +27,9 @@ bincode = "1.3.1" [dev-dependencies] proptest = "1.0" -solana-program-test = "1.9.5" -solana-sdk = "1.9.5" -solana-vote-program = "1.9.5" +solana-program-test = "1.9.9" +solana-sdk = "1.9.9" +solana-vote-program = "1.9.9" [lib] crate-type = ["cdylib", "lib"] From eafbfdce05cf2f7047953d002c1f2579be68292c Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Mon, 11 Apr 2022 22:25:27 +0200 Subject: [PATCH 0235/1076] Upgrade crates to 1.10.8 (#3076) --- clients/cli/Cargo.toml | 18 +++++++++--------- program/Cargo.toml | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 7f550ebf..8e9bd852 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -14,15 +14,15 @@ clap = "2.33.3" serde = "1.0.130" serde_derive = "1.0.130" serde_json = "1.0.68" -solana-account-decoder = "=1.9.9" -solana-clap-utils = "=1.9.9" -solana-cli-config = "=1.9.9" -solana-cli-output = "=1.9.9" -solana-client = "=1.9.9" -solana-logger = "=1.9.9" -solana-program = "=1.9.9" -solana-remote-wallet = "=1.9.9" -solana-sdk = "=1.9.9" +solana-account-decoder = "=1.10.8" +solana-clap-utils = "=1.10.8" +solana-cli-config = "=1.10.8" +solana-cli-output = "=1.10.8" +solana-client = "=1.10.8" +solana-logger = "=1.10.8" +solana-program = "=1.10.8" +solana-remote-wallet = "=1.10.8" +solana-sdk = "=1.10.8" spl-associated-token-account = { version = "=1.0.5", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "=0.6.4", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "=3.3.0", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/program/Cargo.toml b/program/Cargo.toml index 9acbf51d..2125654f 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -19,7 +19,7 @@ num-traits = "0.2" num_enum = "0.5.4" serde = "1.0.130" serde_derive = "1.0.103" -solana-program = "1.9.9" +solana-program = "1.10.8" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-token = { version = "3.3", path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" @@ -27,9 +27,9 @@ bincode = "1.3.1" [dev-dependencies] proptest = "1.0" -solana-program-test = "1.9.9" -solana-sdk = "1.9.9" -solana-vote-program = "1.9.9" +solana-program-test = "1.10.8" +solana-sdk = "1.10.8" +solana-vote-program = "1.10.8" [lib] crate-type = ["cdylib", "lib"] From f9f609fb4436318a8fb2e39d80b8041e19a334a8 Mon Sep 17 00:00:00 2001 From: Bogdan Shumygora <102970929+bshumygora@users.noreply.github.com> Date: Tue, 19 Apr 2022 00:26:08 +0300 Subject: [PATCH 0236/1076] Remove duplciate output of 'Stake Accounts' header (#3089) --- clients/cli/src/output.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/clients/cli/src/output.rs b/clients/cli/src/output.rs index 2a9f0577..7ca8feab 100644 --- a/clients/cli/src/output.rs +++ b/clients/cli/src/output.rs @@ -167,8 +167,7 @@ impl VerboseDisplay for CliStakePool { &self.sol_referral_fee )?; writeln!(w)?; - writeln!(w, "Stake Accounts")?; - writeln!(w, "--------------")?; + match &self.details { None => {} Some(details) => { @@ -294,7 +293,6 @@ impl Display for CliStakePoolDetails { impl QuietDisplay for CliStakePoolDetails {} impl VerboseDisplay for CliStakePoolDetails { fn write_str(&self, w: &mut dyn Write) -> Result { - writeln!(w)?; writeln!(w, "Stake Accounts")?; writeln!(w, "--------------")?; writeln!( From 1b23ab4ffeaeee4d9a0acc089f2fc7c810c28902 Mon Sep 17 00:00:00 2001 From: Tyera Eulberg Date: Tue, 26 Apr 2022 14:15:26 -0400 Subject: [PATCH 0237/1076] Bump token-2022 (#3113) * Bump token-2022 * Bump solana dependencies --- clients/cli/Cargo.toml | 18 +++++++++--------- program/Cargo.toml | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 8e9bd852..4d9c4dc7 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -14,15 +14,15 @@ clap = "2.33.3" serde = "1.0.130" serde_derive = "1.0.130" serde_json = "1.0.68" -solana-account-decoder = "=1.10.8" -solana-clap-utils = "=1.10.8" -solana-cli-config = "=1.10.8" -solana-cli-output = "=1.10.8" -solana-client = "=1.10.8" -solana-logger = "=1.10.8" -solana-program = "=1.10.8" -solana-remote-wallet = "=1.10.8" -solana-sdk = "=1.10.8" +solana-account-decoder = "=1.10.10" +solana-clap-utils = "=1.10.10" +solana-cli-config = "=1.10.10" +solana-cli-output = "=1.10.10" +solana-client = "=1.10.10" +solana-logger = "=1.10.10" +solana-program = "=1.10.10" +solana-remote-wallet = "=1.10.10" +solana-sdk = "=1.10.10" spl-associated-token-account = { version = "=1.0.5", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "=0.6.4", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "=3.3.0", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/program/Cargo.toml b/program/Cargo.toml index 2125654f..93e9a11c 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -19,7 +19,7 @@ num-traits = "0.2" num_enum = "0.5.4" serde = "1.0.130" serde_derive = "1.0.103" -solana-program = "1.10.8" +solana-program = "1.10.10" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-token = { version = "3.3", path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" @@ -27,9 +27,9 @@ bincode = "1.3.1" [dev-dependencies] proptest = "1.0" -solana-program-test = "1.10.8" -solana-sdk = "1.10.8" -solana-vote-program = "1.10.8" +solana-program-test = "1.10.10" +solana-sdk = "1.10.10" +solana-vote-program = "1.10.10" [lib] crate-type = ["cdylib", "lib"] From 961a8d4975cb566492410eccbc77c5d940bbb37d Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Mon, 2 May 2022 22:45:25 +0200 Subject: [PATCH 0238/1076] stake-pool: Update program to work with minimum delegation (#3127) * stake-pool: Update program to work with minimum delegation * Update minimum reserve lamports in the CLI * Cargo fmt * Add another test for hijacked account * Fix python and JS constants --- clients/cli/src/main.rs | 8 +- clients/js-legacy/src/constants.ts | 2 +- clients/py/bot/rebalance.py | 11 +- clients/py/stake/constants.py | 6 + clients/py/stake_pool/actions.py | 3 +- clients/py/stake_pool/constants.py | 7 + clients/py/tests/conftest.py | 2 +- clients/py/tests/test_a_time_sensitive.py | 5 +- clients/py/tests/test_bot_rebalance.py | 17 +- clients/py/tests/test_create.py | 7 +- .../py/tests/test_deposit_withdraw_stake.py | 3 +- clients/py/tests/test_stake.py | 7 +- program/src/entrypoint.rs | 10 +- program/src/error.rs | 8 +- program/src/lib.rs | 8 +- program/src/processor.rs | 37 +++-- program/src/state.rs | 8 +- program/tests/decrease.rs | 20 ++- program/tests/deposit.rs | 17 +- program/tests/deposit_authority.rs | 23 ++- program/tests/deposit_sol.rs | 21 ++- program/tests/helpers/mod.rs | 4 +- program/tests/increase.rs | 8 +- program/tests/initialize.rs | 77 +++++++-- program/tests/set_deposit_fee.rs | 6 +- program/tests/set_epoch_fee.rs | 5 +- program/tests/set_funding_authority.rs | 15 +- program/tests/set_manager.rs | 22 ++- program/tests/set_preferred.rs | 8 +- program/tests/set_referral_fee.rs | 3 +- program/tests/set_staker.rs | 15 +- program/tests/set_withdrawal_fee.rs | 5 +- program/tests/update_stake_pool_balance.rs | 25 ++- .../tests/update_validator_list_balance.rs | 56 +++++-- program/tests/vsa_add.rs | 19 ++- program/tests/vsa_remove.rs | 12 +- program/tests/withdraw.rs | 146 ++++++++++++++---- program/tests/withdraw_sol.rs | 7 +- 38 files changed, 475 insertions(+), 188 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index aca6d19c..299d0aac 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -45,7 +45,7 @@ use { find_withdraw_authority_program_address, instruction::{FundingType, PreferredValidatorType}, state::{Fee, FeeType, StakePool, ValidatorList}, - MINIMUM_ACTIVE_STAKE, + MINIMUM_ACTIVE_STAKE, MINIMUM_RESERVE_LAMPORTS, }, std::cmp::Ordering, std::{process::exit, sync::Arc}, @@ -250,7 +250,7 @@ fn command_create_pool( let reserve_stake_balance = config .rpc_client .get_minimum_balance_for_rent_exemption(STAKE_STATE_LEN)? - + 1; + + MINIMUM_RESERVE_LAMPORTS; let mint_account_balance = config .rpc_client .get_minimum_balance_for_rent_exemption(spl_token::state::Mint::LEN)?; @@ -1058,7 +1058,7 @@ fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { let minimum_reserve_stake_balance = config .rpc_client .get_minimum_balance_for_rent_exemption(STAKE_STATE_LEN)? - + 1; + + MINIMUM_RESERVE_LAMPORTS; let cli_stake_pool_stake_account_infos = validator_list .validators .iter() @@ -1271,7 +1271,7 @@ fn prepare_withdraw_accounts( stake_pool.reserve_stake, reserve_stake.lamports - rpc_client.get_minimum_balance_for_rent_exemption(STAKE_STATE_LEN)? - - 1, + - MINIMUM_RESERVE_LAMPORTS, None, )); diff --git a/clients/js-legacy/src/constants.ts b/clients/js-legacy/src/constants.ts index e1297fcf..447835fa 100644 --- a/clients/js-legacy/src/constants.ts +++ b/clients/js-legacy/src/constants.ts @@ -12,4 +12,4 @@ export const TRANSIENT_STAKE_SEED_PREFIX = Buffer.from('transient'); // Minimum amount of staked SOL required in a validator stake account to allow // for merges without a mismatch on credits observed -export const MINIMUM_ACTIVE_STAKE = LAMPORTS_PER_SOL / 1_000; +export const MINIMUM_ACTIVE_STAKE = LAMPORTS_PER_SOL; diff --git a/clients/py/bot/rebalance.py b/clients/py/bot/rebalance.py index 37e25261..bc656a87 100644 --- a/clients/py/bot/rebalance.py +++ b/clients/py/bot/rebalance.py @@ -7,15 +7,12 @@ from solana.rpc.async_api import AsyncClient from solana.rpc.commitment import Confirmed -from stake.constants import STAKE_LEN +from stake.constants import STAKE_LEN, LAMPORTS_PER_SOL from stake_pool.actions import decrease_validator_stake, increase_validator_stake, update_stake_pool +from stake_pool.constants import MINIMUM_ACTIVE_STAKE from stake_pool.state import StakePool, ValidatorList -LAMPORTS_PER_SOL: int = 1_000_000_000 -MINIMUM_INCREASE_LAMPORTS: int = LAMPORTS_PER_SOL // 100 - - async def get_client(endpoint: str) -> AsyncClient: print(f'Connecting to network at {endpoint}') async_client = AsyncClient(endpoint=endpoint, commitment=Confirmed) @@ -87,10 +84,10 @@ async def rebalance(endpoint: str, stake_pool_address: PublicKey, staker: Keypai )) elif validator.active_stake_lamports < lamports_per_validator: lamports_to_increase = lamports_per_validator - validator.active_stake_lamports - if lamports_to_increase < MINIMUM_INCREASE_LAMPORTS: + if lamports_to_increase < MINIMUM_ACTIVE_STAKE: print(f'Skipping increase on {validator.vote_account_address}, \ currently at {validator.active_stake_lamports} lamports, \ -increase of {lamports_to_increase} less than the minimum of {MINIMUM_INCREASE_LAMPORTS}') +increase of {lamports_to_increase} less than the minimum of {MINIMUM_ACTIVE_STAKE}') else: futures.append(increase_validator_stake( async_client, staker, staker, stake_pool_address, diff --git a/clients/py/stake/constants.py b/clients/py/stake/constants.py index 39e6c4a6..344a8a5e 100644 --- a/clients/py/stake/constants.py +++ b/clients/py/stake/constants.py @@ -10,3 +10,9 @@ STAKE_LEN: int = 200 """Size of stake account.""" + +LAMPORTS_PER_SOL: int = 1_000_000_000 +"""Number of lamports per SOL""" + +MINIMUM_DELEGATION: int = LAMPORTS_PER_SOL +"""Minimum delegation allowed by the stake program""" diff --git a/clients/py/stake_pool/actions.py b/clients/py/stake_pool/actions.py index acfce4f8..289aca16 100644 --- a/clients/py/stake_pool/actions.py +++ b/clients/py/stake_pool/actions.py @@ -16,6 +16,7 @@ from stake.state import StakeAuthorize from stake_pool.constants import \ MAX_VALIDATORS_TO_UPDATE, \ + MINIMUM_RESERVE_LAMPORTS, \ STAKE_POOL_PROGRAM_ID, \ find_stake_program_address, \ find_transient_stake_program_address, \ @@ -98,7 +99,7 @@ async def create_all(client: AsyncClient, manager: Keypair, fee: Fee, referral_f STAKE_POOL_PROGRAM_ID, stake_pool.public_key) reserve_stake = Keypair() - await create_stake(client, manager, reserve_stake, pool_withdraw_authority, 1) + await create_stake(client, manager, reserve_stake, pool_withdraw_authority, MINIMUM_RESERVE_LAMPORTS) pool_mint = Keypair() await create_mint(client, manager, pool_mint, pool_withdraw_authority) diff --git a/clients/py/stake_pool/constants.py b/clients/py/stake_pool/constants.py index 6e9f6a35..3af4dce4 100644 --- a/clients/py/stake_pool/constants.py +++ b/clients/py/stake_pool/constants.py @@ -3,6 +3,7 @@ from typing import Tuple from solana.publickey import PublicKey +from stake.constants import MINIMUM_DELEGATION STAKE_POOL_PROGRAM_ID: PublicKey = PublicKey("SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy") """Public key that identifies the SPL Stake Pool program.""" @@ -10,6 +11,12 @@ MAX_VALIDATORS_TO_UPDATE: int = 5 """Maximum number of validators to update during UpdateValidatorListBalance.""" +MINIMUM_RESERVE_LAMPORTS: int = MINIMUM_DELEGATION +"""Minimum balance required in the stake pool reserve""" + +MINIMUM_ACTIVE_STAKE: int = MINIMUM_DELEGATION +"""Minimum active delegated staked required in a stake account""" + def find_deposit_authority_program_address( program_id: PublicKey, diff --git a/clients/py/tests/conftest.py b/clients/py/tests/conftest.py index b55be25b..a5a4f178 100644 --- a/clients/py/tests/conftest.py +++ b/clients/py/tests/conftest.py @@ -92,7 +92,7 @@ def async_client(event_loop, solana_test_validator) -> Iterator[AsyncClient]: @pytest.fixture def payer(event_loop, async_client) -> Keypair: payer = Keypair() - airdrop_lamports = 10_000_000_000 + airdrop_lamports = 20_000_000_000 event_loop.run_until_complete(airdrop(async_client, payer.public_key, airdrop_lamports)) return payer diff --git a/clients/py/tests/test_a_time_sensitive.py b/clients/py/tests/test_a_time_sensitive.py index 78f707c7..82e82764 100644 --- a/clients/py/tests/test_a_time_sensitive.py +++ b/clients/py/tests/test_a_time_sensitive.py @@ -5,8 +5,9 @@ from spl.token.instructions import get_associated_token_address from stake.constants import STAKE_LEN -from stake_pool.state import StakePool, ValidatorList from stake_pool.actions import deposit_sol, decrease_validator_stake, increase_validator_stake, update_stake_pool +from stake_pool.constants import MINIMUM_ACTIVE_STAKE +from stake_pool.state import StakePool, ValidatorList @pytest.mark.asyncio @@ -14,7 +15,7 @@ async def test_increase_decrease_this_is_very_slow(async_client, validators, pay (stake_pool_address, validator_list_address) = stake_pool_addresses resp = await async_client.get_minimum_balance_for_rent_exemption(STAKE_LEN) stake_rent_exemption = resp['result'] - increase_amount = 100_000_000 + increase_amount = MINIMUM_ACTIVE_STAKE * 2 decrease_amount = increase_amount // 2 deposit_amount = (increase_amount + stake_rent_exemption) * len(validators) diff --git a/clients/py/tests/test_bot_rebalance.py b/clients/py/tests/test_bot_rebalance.py index 1b28251b..69876e11 100644 --- a/clients/py/tests/test_bot_rebalance.py +++ b/clients/py/tests/test_bot_rebalance.py @@ -3,9 +3,10 @@ from solana.rpc.commitment import Confirmed from spl.token.instructions import get_associated_token_address -from stake.constants import STAKE_LEN -from stake_pool.state import StakePool, ValidatorList +from stake.constants import STAKE_LEN, LAMPORTS_PER_SOL from stake_pool.actions import deposit_sol +from stake_pool.constants import MINIMUM_ACTIVE_STAKE, MINIMUM_RESERVE_LAMPORTS +from stake_pool.state import StakePool, ValidatorList from bot.rebalance import rebalance @@ -18,7 +19,7 @@ async def test_rebalance_this_is_very_slow(async_client, validators, payer, stak (stake_pool_address, validator_list_address) = stake_pool_addresses resp = await async_client.get_minimum_balance_for_rent_exemption(STAKE_LEN) stake_rent_exemption = resp['result'] - increase_amount = 100_000_000 + increase_amount = MINIMUM_ACTIVE_STAKE deposit_amount = (increase_amount + stake_rent_exemption) * len(validators) resp = await async_client.get_account_info(stake_pool_address, commitment=Confirmed) @@ -32,7 +33,7 @@ async def test_rebalance_this_is_very_slow(async_client, validators, payer, stak # should only have minimum left resp = await async_client.get_account_info(stake_pool.reserve_stake, commitment=Confirmed) - assert resp['result']['value']['lamports'] == stake_rent_exemption + 1 + assert resp['result']['value']['lamports'] == stake_rent_exemption + MINIMUM_RESERVE_LAMPORTS # should all be the same resp = await async_client.get_account_info(validator_list_address, commitment=Confirmed) @@ -45,12 +46,12 @@ async def test_rebalance_this_is_very_slow(async_client, validators, payer, stak # Test case 2: Decrease print('Waiting for next epoch') await waiter.wait_for_next_epoch(async_client) - await rebalance(ENDPOINT, stake_pool_address, payer, deposit_amount / 1_000_000_000) + await rebalance(ENDPOINT, stake_pool_address, payer, deposit_amount / LAMPORTS_PER_SOL) # should still only have minimum left + rent exemptions from increase resp = await async_client.get_account_info(stake_pool.reserve_stake, commitment=Confirmed) reserve_lamports = resp['result']['value']['lamports'] - assert reserve_lamports == stake_rent_exemption * (1 + len(validator_list.validators)) + 1 + assert reserve_lamports == stake_rent_exemption * (1 + len(validator_list.validators)) + MINIMUM_RESERVE_LAMPORTS # should all be decreasing now resp = await async_client.get_account_info(validator_list_address, commitment=Confirmed) @@ -63,12 +64,12 @@ async def test_rebalance_this_is_very_slow(async_client, validators, payer, stak # Test case 3: Do nothing print('Waiting for next epoch') await waiter.wait_for_next_epoch(async_client) - await rebalance(ENDPOINT, stake_pool_address, payer, deposit_amount / 1_000_000_000) + await rebalance(ENDPOINT, stake_pool_address, payer, deposit_amount / LAMPORTS_PER_SOL) # should still only have minimum left + rent exemptions from increase resp = await async_client.get_account_info(stake_pool.reserve_stake, commitment=Confirmed) reserve_lamports = resp['result']['value']['lamports'] - assert reserve_lamports == stake_rent_exemption + deposit_amount + 1 + assert reserve_lamports == stake_rent_exemption + deposit_amount + MINIMUM_RESERVE_LAMPORTS # should all be decreasing now resp = await async_client.get_account_info(validator_list_address, commitment=Confirmed) diff --git a/clients/py/tests/test_create.py b/clients/py/tests/test_create.py index ee37be58..97600ae3 100644 --- a/clients/py/tests/test_create.py +++ b/clients/py/tests/test_create.py @@ -3,7 +3,10 @@ from solana.rpc.commitment import Confirmed from spl.token.constants import TOKEN_PROGRAM_ID -from stake_pool.constants import find_withdraw_authority_program_address, STAKE_POOL_PROGRAM_ID +from stake_pool.constants import \ + find_withdraw_authority_program_address, \ + MINIMUM_RESERVE_LAMPORTS, \ + STAKE_POOL_PROGRAM_ID from stake_pool.state import StakePool, Fee from stake.actions import create_stake @@ -19,7 +22,7 @@ async def test_create_stake_pool(async_client, payer): STAKE_POOL_PROGRAM_ID, stake_pool.public_key) reserve_stake = Keypair() - await create_stake(async_client, payer, reserve_stake, pool_withdraw_authority, 1) + await create_stake(async_client, payer, reserve_stake, pool_withdraw_authority, MINIMUM_RESERVE_LAMPORTS) pool_mint = Keypair() await create_mint(async_client, payer, pool_mint, pool_withdraw_authority) diff --git a/clients/py/tests/test_deposit_withdraw_stake.py b/clients/py/tests/test_deposit_withdraw_stake.py index 7a0ebf51..896960dc 100644 --- a/clients/py/tests/test_deposit_withdraw_stake.py +++ b/clients/py/tests/test_deposit_withdraw_stake.py @@ -7,6 +7,7 @@ from stake.constants import STAKE_LEN from stake.state import StakeState from stake_pool.actions import deposit_stake, withdraw_stake, update_stake_pool +from stake_pool.constants import MINIMUM_ACTIVE_STAKE from stake_pool.state import StakePool @@ -17,7 +18,7 @@ async def test_deposit_withdraw_stake(async_client, validators, payer, stake_poo data = resp['result']['value']['data'] stake_pool = StakePool.decode(data[0], data[1]) validator = next(iter(validators)) - stake_amount = 1_000_000 + stake_amount = MINIMUM_ACTIVE_STAKE stake = Keypair() await create_stake(async_client, payer, stake, payer.public_key, stake_amount) stake = stake.public_key diff --git a/clients/py/tests/test_stake.py b/clients/py/tests/test_stake.py index 152a487c..53b23e1b 100644 --- a/clients/py/tests/test_stake.py +++ b/clients/py/tests/test_stake.py @@ -2,14 +2,15 @@ import pytest from solana.keypair import Keypair -from stake.state import StakeAuthorize from stake.actions import authorize, create_stake, delegate_stake +from stake.constants import MINIMUM_DELEGATION +from stake.state import StakeAuthorize @pytest.mark.asyncio async def test_create_stake(async_client, payer): stake = Keypair() - await create_stake(async_client, payer, stake, payer.public_key, 100_000) + await create_stake(async_client, payer, stake, payer.public_key, MINIMUM_DELEGATION) @pytest.mark.asyncio @@ -24,7 +25,7 @@ async def test_delegate_stake(async_client, validators, payer): async def test_authorize_stake(async_client, payer): stake = Keypair() new_authority = Keypair() - await create_stake(async_client, payer, stake, payer.public_key, 1_000) + await create_stake(async_client, payer, stake, payer.public_key, MINIMUM_DELEGATION) await asyncio.gather( authorize(async_client, payer, payer, stake.public_key, new_authority.public_key, StakeAuthorize.STAKER), authorize(async_client, payer, payer, stake.public_key, new_authority.public_key, StakeAuthorize.WITHDRAWER) diff --git a/program/src/entrypoint.rs b/program/src/entrypoint.rs index e2d4de2a..a44df1e5 100644 --- a/program/src/entrypoint.rs +++ b/program/src/entrypoint.rs @@ -2,10 +2,12 @@ #![cfg(all(target_arch = "bpf", not(feature = "no-entrypoint")))] -use crate::{error::StakePoolError, processor::Processor}; -use solana_program::{ - account_info::AccountInfo, entrypoint, entrypoint::ProgramResult, - program_error::PrintProgramError, pubkey::Pubkey, +use { + crate::{error::StakePoolError, processor::Processor}, + solana_program::{ + account_info::AccountInfo, entrypoint, entrypoint::ProgramResult, + program_error::PrintProgramError, pubkey::Pubkey, + }, }; entrypoint!(process_instruction); diff --git a/program/src/error.rs b/program/src/error.rs index 48bf1bc3..8ffa32e1 100644 --- a/program/src/error.rs +++ b/program/src/error.rs @@ -1,8 +1,10 @@ //! Error types -use num_derive::FromPrimitive; -use solana_program::{decode_error::DecodeError, program_error::ProgramError}; -use thiserror::Error; +use { + num_derive::FromPrimitive, + solana_program::{decode_error::DecodeError, program_error::ProgramError}, + thiserror::Error, +}; /// Errors that may be returned by the StakePool program. #[derive(Clone, Debug, Eq, Error, FromPrimitive, PartialEq)] diff --git a/program/src/lib.rs b/program/src/lib.rs index 3c726fa3..aa6931dd 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -29,7 +29,10 @@ const TRANSIENT_STAKE_SEED_PREFIX: &[u8] = b"transient"; /// Minimum amount of staked SOL required in a validator stake account to allow /// for merges without a mismatch on credits observed -pub const MINIMUM_ACTIVE_STAKE: u64 = LAMPORTS_PER_SOL / 1_000; +pub const MINIMUM_ACTIVE_STAKE: u64 = LAMPORTS_PER_SOL; + +/// Minimum amount of SOL in the reserve +pub const MINIMUM_RESERVE_LAMPORTS: u64 = LAMPORTS_PER_SOL; /// Maximum amount of validator stake accounts to update per /// `UpdateValidatorListBalance` instruction, based on compute limits @@ -64,7 +67,8 @@ pub fn minimum_stake_lamports(meta: &Meta) -> u64 { /// conversions #[inline] pub fn minimum_reserve_lamports(meta: &Meta) -> u64 { - meta.rent_exempt_reserve.saturating_add(1) + meta.rent_exempt_reserve + .saturating_add(MINIMUM_RESERVE_LAMPORTS) } /// Generates the deposit authority program address for the stake pool diff --git a/program/src/processor.rs b/program/src/processor.rs index dea314a4..e22ed222 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -15,16 +15,14 @@ use { borsh::{BorshDeserialize, BorshSerialize}, num_traits::FromPrimitive, solana_program::{ - account_info::next_account_info, - account_info::AccountInfo, + account_info::{next_account_info, AccountInfo}, borsh::try_from_slice_unchecked, clock::{Clock, Epoch}, decode_error::DecodeError, entrypoint::ProgramResult, msg, program::{invoke, invoke_signed}, - program_error::PrintProgramError, - program_error::ProgramError, + program_error::{PrintProgramError, ProgramError}, program_pack::Pack, pubkey::Pubkey, rent::Rent, @@ -136,6 +134,17 @@ fn check_account_owner( } } +/// Checks if a stake acount can be managed by the pool +fn stake_is_usable_by_pool( + meta: &stake::state::Meta, + expected_authority: &Pubkey, + expected_lockup: &stake::state::Lockup, +) -> bool { + meta.authorized.staker == *expected_authority + && meta.authorized.withdrawer == *expected_authority + && meta.lockup == *expected_lockup +} + /// Create a transient stake account without transferring lamports fn create_transient_stake_account<'a>( transient_stake_account_info: AccountInfo<'a>, @@ -747,7 +756,7 @@ impl Processor { stake_pool.manager_fee_account = *manager_fee_info.key; stake_pool.token_program_id = *token_program_info.key; stake_pool.total_lamports = total_lamports; - stake_pool.pool_token_supply = 0; + stake_pool.pool_token_supply = total_lamports; stake_pool.last_update_epoch = Clock::get()?.epoch; stake_pool.lockup = stake::state::Lockup::default(); stake_pool.epoch_fee = epoch_fee; @@ -1543,10 +1552,11 @@ impl Processor { // * not a stake -> ignore match transient_stake_state { Some(stake::state::StakeState::Initialized(meta)) => { - // if transient account was hijacked, ignore it - if meta.authorized.staker == *withdraw_authority_info.key - && meta.authorized.withdrawer == *withdraw_authority_info.key - { + if stake_is_usable_by_pool( + &meta, + withdraw_authority_info.key, + &stake_pool.lockup, + ) { if no_merge { transient_stake_lamports = transient_stake_info.lamports(); } else { @@ -1571,10 +1581,11 @@ impl Processor { } } Some(stake::state::StakeState::Stake(meta, stake)) => { - // if transient account was hijacked, ignore it - if meta.authorized.staker == *withdraw_authority_info.key - && meta.authorized.withdrawer == *withdraw_authority_info.key - { + if stake_is_usable_by_pool( + &meta, + withdraw_authority_info.key, + &stake_pool.lockup, + ) { let account_stake = meta .rent_exempt_reserve .saturating_add(stake.delegation.stake); diff --git a/program/src/state.rs b/program/src/state.rs index bcbf6f8c..88901dc6 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -1,6 +1,5 @@ //! State transition types -use spl_token::state::{Account, AccountState}; use { crate::{ big_vec::BigVec, error::StakePoolError, MAX_WITHDRAWAL_FEE_INCREASE, @@ -20,6 +19,7 @@ use { stake::state::Lockup, }, spl_math::checked_ceil_div::CheckedCeilDiv, + spl_token::state::{Account, AccountState}, std::{convert::TryFrom, fmt, matches}, }; @@ -535,7 +535,7 @@ impl Default for StakeStatus { pub struct ValidatorStakeInfo { /// Amount of active stake delegated to this validator, minus the minimum /// required stake amount of rent-exemption + `crate::MINIMUM_ACTIVE_STAKE` - /// (currently 0.001 SOL). + /// (currently 1 SOL). /// /// Note that if `last_update_epoch` does not match the current epoch then /// this field may not be accurate @@ -823,10 +823,8 @@ mod test { use { super::*, proptest::prelude::*, - solana_program::borsh::{ - get_instance_packed_len, get_packed_len, try_from_slice_unchecked, - }, solana_program::{ + borsh::{get_instance_packed_len, get_packed_len, try_from_slice_unchecked}, clock::{DEFAULT_SLOTS_PER_EPOCH, DEFAULT_S_PER_SLOT, SECONDS_PER_DAY}, native_token::LAMPORTS_PER_SOL, }, diff --git a/program/tests/decrease.rs b/program/tests/decrease.rs index 72ebc5d7..1089fba9 100644 --- a/program/tests/decrease.rs +++ b/program/tests/decrease.rs @@ -15,6 +15,7 @@ use { }, spl_stake_pool::{ error::StakePoolError, find_transient_stake_program_address, id, instruction, + MINIMUM_ACTIVE_STAKE, MINIMUM_RESERVE_LAMPORTS, }, }; @@ -28,9 +29,16 @@ async fn setup() -> ( u64, ) { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let rent = banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .initialize_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) .await .unwrap(); @@ -48,12 +56,12 @@ async fn setup() -> ( &recent_blockhash, &stake_pool_accounts, &validator_stake_account, - 100_000_000, + MINIMUM_ACTIVE_STAKE * 2 + stake_rent, ) .await .unwrap(); - let lamports = deposit_info.stake_lamports / 2; + let decrease_lamports = MINIMUM_ACTIVE_STAKE + stake_rent; ( banks_client, @@ -62,7 +70,7 @@ async fn setup() -> ( stake_pool_accounts, validator_stake_account, deposit_info, - lamports, + decrease_lamports, ) } @@ -297,7 +305,7 @@ async fn fail_decrease_twice() { &recent_blockhash, &validator_stake.stake_account, &validator_stake.transient_stake_account, - decrease_lamports / 3, + decrease_lamports, validator_stake.transient_stake_seed, ) .await; @@ -318,7 +326,7 @@ async fn fail_decrease_twice() { &recent_blockhash, &validator_stake.stake_account, &transient_stake_address, - decrease_lamports / 2, + decrease_lamports, transient_stake_seed, ) .await diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 2d37bca1..d38bb63a 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -15,11 +15,13 @@ use { solana_program_test::*, solana_sdk::{ signature::{Keypair, Signer}, - transaction::Transaction, - transaction::TransactionError, + transaction::{Transaction, TransactionError}, transport::TransportError, }, - spl_stake_pool::{error::StakePoolError, id, instruction, minimum_stake_lamports, state}, + spl_stake_pool::{ + error::StakePoolError, id, instruction, minimum_stake_lamports, state, + MINIMUM_RESERVE_LAMPORTS, + }, spl_token::error as token_error, }; @@ -40,7 +42,7 @@ async fn setup() -> ( &mut context.banks_client, &context.payer, &context.last_blockhash, - 1, + MINIMUM_RESERVE_LAMPORTS, ) .await .unwrap(); @@ -616,7 +618,12 @@ async fn fail_with_unknown_validator() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .initialize_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) .await .unwrap(); diff --git a/program/tests/deposit_authority.rs b/program/tests/deposit_authority.rs index ace4b5d1..afae4c08 100644 --- a/program/tests/deposit_authority.rs +++ b/program/tests/deposit_authority.rs @@ -11,7 +11,7 @@ use { signature::{Keypair, Signer}, transaction::TransactionError, }, - spl_stake_pool::{error::StakePoolError, state::StakePool}, + spl_stake_pool::{error::StakePoolError, state::StakePool, MINIMUM_RESERVE_LAMPORTS}, }; #[tokio::test] @@ -21,7 +21,12 @@ async fn success_initialize() { let stake_pool_accounts = StakePoolAccounts::new_with_deposit_authority(deposit_authority); let deposit_authority = stake_pool_accounts.stake_deposit_authority; stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .initialize_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) .await .unwrap(); @@ -41,7 +46,12 @@ async fn success_deposit() { let stake_pool_accounts = StakePoolAccounts::new_with_deposit_authority(stake_deposit_authority); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .initialize_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) .await .unwrap(); @@ -116,7 +126,12 @@ async fn fail_deposit_without_authority_signature() { let mut stake_pool_accounts = StakePoolAccounts::new_with_deposit_authority(stake_deposit_authority); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .initialize_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) .await .unwrap(); diff --git a/program/tests/deposit_sol.rs b/program/tests/deposit_sol.rs index 3639847a..72121a0e 100644 --- a/program/tests/deposit_sol.rs +++ b/program/tests/deposit_sol.rs @@ -10,14 +10,13 @@ use { solana_program_test::*, solana_sdk::{ signature::{Keypair, Signer}, - transaction::Transaction, - transaction::TransactionError, + transaction::{Transaction, TransactionError}, transport::TransportError, }, spl_stake_pool::{ error, id, instruction::{self, FundingType}, - state, + state, MINIMUM_RESERVE_LAMPORTS, }, spl_token::error as token_error, }; @@ -31,7 +30,7 @@ async fn setup() -> (ProgramTestContext, StakePoolAccounts, Keypair, Pubkey) { &mut context.banks_client, &context.payer, &context.last_blockhash, - 1, + MINIMUM_RESERVE_LAMPORTS, ) .await .unwrap(); @@ -258,7 +257,12 @@ async fn success_with_sol_deposit_authority() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .initialize_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) .await .unwrap(); @@ -323,7 +327,12 @@ async fn fail_without_sol_deposit_authority_signature() { let sol_deposit_authority = Keypair::new(); let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .initialize_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) .await .unwrap(); diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 6b81275c..19690bfd 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -24,7 +24,7 @@ use { find_transient_stake_program_address, find_withdraw_authority_program_address, id, instruction, processor, state::{self, FeeType, ValidatorList}, - MINIMUM_ACTIVE_STAKE, + MINIMUM_ACTIVE_STAKE, MINIMUM_RESERVE_LAMPORTS, }, }; @@ -1575,5 +1575,5 @@ pub async fn get_validator_list_sum( .sum(); let rent = banks_client.get_rent().await.unwrap(); let rent = rent.minimum_balance(std::mem::size_of::()); - validator_sum + reserve_stake.lamports - rent - 1 + validator_sum + reserve_stake.lamports - rent - MINIMUM_RESERVE_LAMPORTS } diff --git a/program/tests/increase.rs b/program/tests/increase.rs index 105eda3c..6ab04762 100644 --- a/program/tests/increase.rs +++ b/program/tests/increase.rs @@ -15,7 +15,7 @@ use { }, spl_stake_pool::{ error::StakePoolError, find_transient_stake_program_address, id, instruction, - MINIMUM_ACTIVE_STAKE, + MINIMUM_ACTIVE_STAKE, MINIMUM_RESERVE_LAMPORTS, }, }; @@ -29,7 +29,7 @@ async fn setup() -> ( ) { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); - let reserve_lamports = 100_000_000_000; + let reserve_lamports = 100_000_000_000 + MINIMUM_RESERVE_LAMPORTS; stake_pool_accounts .initialize_stake_pool( &mut banks_client, @@ -54,7 +54,7 @@ async fn setup() -> ( &recent_blockhash, &stake_pool_accounts, &validator_stake_account, - 5_000_000, + MINIMUM_ACTIVE_STAKE, ) .await .unwrap(); @@ -96,7 +96,7 @@ async fn success() { let rent = banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); - let increase_amount = reserve_lamports - stake_rent - 1; + let increase_amount = reserve_lamports - stake_rent - MINIMUM_RESERVE_LAMPORTS; let error = stake_pool_accounts .increase_validator_stake( &mut banks_client, diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index 85f2142a..220f621e 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -15,10 +15,12 @@ use { }, solana_program_test::*, solana_sdk::{ - instruction::InstructionError, signature::Keypair, signature::Signer, - transaction::Transaction, transaction::TransactionError, transport::TransportError, + instruction::InstructionError, + signature::{Keypair, Signer}, + transaction::{Transaction, TransactionError}, + transport::TransportError, }, - spl_stake_pool::{error, id, instruction, state}, + spl_stake_pool::{error, id, instruction, state, MINIMUM_RESERVE_LAMPORTS}, }; async fn create_required_accounts( @@ -58,7 +60,7 @@ async fn create_required_accounts( withdrawer: stake_pool_accounts.withdraw_authority, }, &stake::state::Lockup::default(), - 1, + MINIMUM_RESERVE_LAMPORTS, ) .await; } @@ -68,7 +70,12 @@ async fn success() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .initialize_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) .await .unwrap(); @@ -93,7 +100,12 @@ async fn fail_double_initialize() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .initialize_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) .await .unwrap(); @@ -103,7 +115,12 @@ async fn fail_double_initialize() { second_stake_pool_accounts.stake_pool = stake_pool_accounts.stake_pool; let transaction_error = second_stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &latest_blockhash, 1) + .initialize_stake_pool( + &mut banks_client, + &payer, + &latest_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) .await .err() .unwrap(); @@ -124,7 +141,12 @@ async fn fail_with_already_initialized_validator_list() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .initialize_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) .await .unwrap(); @@ -134,7 +156,12 @@ async fn fail_with_already_initialized_validator_list() { second_stake_pool_accounts.validator_list = stake_pool_accounts.validator_list; let transaction_error = second_stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &latest_blockhash, 1) + .initialize_stake_pool( + &mut banks_client, + &payer, + &latest_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) .await .err() .unwrap(); @@ -160,7 +187,12 @@ async fn fail_with_high_fee() { }; let transaction_error = stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .initialize_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) .await .err() .unwrap(); @@ -186,7 +218,12 @@ async fn fail_with_high_withdrawal_fee() { }; let transaction_error = stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .initialize_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) .await .err() .unwrap(); @@ -720,7 +757,12 @@ async fn fail_with_wrong_withdraw_authority() { stake_pool_accounts.withdraw_authority = Keypair::new().pubkey(); let transaction_error = stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .initialize_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) .await .err() .unwrap(); @@ -1096,7 +1138,7 @@ async fn fail_with_bad_reserve() { withdrawer: stake_pool_accounts.withdraw_authority, }, &stake::state::Lockup::default(), - 1, + MINIMUM_RESERVE_LAMPORTS, ) .await; @@ -1147,7 +1189,7 @@ async fn fail_with_bad_reserve() { withdrawer: wrong_authority, }, &stake::state::Lockup::default(), - 1, + MINIMUM_RESERVE_LAMPORTS, ) .await; @@ -1201,7 +1243,7 @@ async fn fail_with_bad_reserve() { custodian: wrong_authority, ..stake::state::Lockup::default() }, - 1, + MINIMUM_RESERVE_LAMPORTS, ) .await; @@ -1243,7 +1285,8 @@ async fn fail_with_bad_reserve() { { let bad_stake = Keypair::new(); let rent = banks_client.get_rent().await.unwrap(); - let lamports = rent.minimum_balance(std::mem::size_of::()); + let lamports = rent.minimum_balance(std::mem::size_of::()) + + MINIMUM_RESERVE_LAMPORTS; let transaction = Transaction::new_signed_with_payer( &[system_instruction::create_account( @@ -1305,7 +1348,7 @@ async fn success_with_extra_reserve_lamports() { &mut banks_client, &payer, &recent_blockhash, - 1 + init_lamports, + MINIMUM_RESERVE_LAMPORTS + init_lamports, ) .await .unwrap(); diff --git a/program/tests/set_deposit_fee.rs b/program/tests/set_deposit_fee.rs index 761440f5..ba7ead80 100644 --- a/program/tests/set_deposit_fee.rs +++ b/program/tests/set_deposit_fee.rs @@ -13,8 +13,8 @@ use { }, spl_stake_pool::{ error, id, instruction, - state::StakePool, - state::{Fee, FeeType}, + state::{Fee, FeeType, StakePool}, + MINIMUM_RESERVE_LAMPORTS, }, }; @@ -29,7 +29,7 @@ async fn setup(fee: Option) -> (ProgramTestContext, StakePoolAccounts, Fee) &mut context.banks_client, &context.payer, &context.last_blockhash, - 1, + MINIMUM_RESERVE_LAMPORTS, ) .await .unwrap(); diff --git a/program/tests/set_epoch_fee.rs b/program/tests/set_epoch_fee.rs index 95d3a46c..d63a23a6 100644 --- a/program/tests/set_epoch_fee.rs +++ b/program/tests/set_epoch_fee.rs @@ -14,6 +14,7 @@ use { spl_stake_pool::{ error, id, instruction, state::{Fee, FeeType, StakePool}, + MINIMUM_RESERVE_LAMPORTS, }, }; @@ -25,7 +26,7 @@ async fn setup() -> (ProgramTestContext, StakePoolAccounts, Fee) { &mut context.banks_client, &context.payer, &context.last_blockhash, - 1, + MINIMUM_RESERVE_LAMPORTS, ) .await .unwrap(); @@ -180,7 +181,7 @@ async fn fail_not_updated() { &mut context.banks_client, &context.payer, &context.last_blockhash, - 1, + MINIMUM_RESERVE_LAMPORTS, ) .await .unwrap(); diff --git a/program/tests/set_funding_authority.rs b/program/tests/set_funding_authority.rs index d0394bee..fb4607da 100644 --- a/program/tests/set_funding_authority.rs +++ b/program/tests/set_funding_authority.rs @@ -12,13 +12,15 @@ use { }, solana_program_test::*, solana_sdk::{ - instruction::InstructionError, signature::Keypair, signature::Signer, - transaction::Transaction, transaction::TransactionError, transport::TransportError, + instruction::InstructionError, + signature::{Keypair, Signer}, + transaction::{Transaction, TransactionError}, + transport::TransportError, }, spl_stake_pool::{ error, find_deposit_authority_program_address, id, instruction::{self, FundingType}, - state, + state, MINIMUM_RESERVE_LAMPORTS, }, }; @@ -26,7 +28,12 @@ async fn setup() -> (BanksClient, Keypair, Hash, StakePoolAccounts, Keypair) { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .initialize_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) .await .unwrap(); diff --git a/program/tests/set_manager.rs b/program/tests/set_manager.rs index 89b3b651..64fcdb06 100644 --- a/program/tests/set_manager.rs +++ b/program/tests/set_manager.rs @@ -12,10 +12,12 @@ use { }, solana_program_test::*, solana_sdk::{ - instruction::InstructionError, signature::Keypair, signature::Signer, - transaction::Transaction, transaction::TransactionError, transport::TransportError, + instruction::InstructionError, + signature::{Keypair, Signer}, + transaction::{Transaction, TransactionError}, + transport::TransportError, }, - spl_stake_pool::{error, id, instruction, state}, + spl_stake_pool::{error, id, instruction, state, MINIMUM_RESERVE_LAMPORTS}, }; async fn setup() -> ( @@ -29,7 +31,12 @@ async fn setup() -> ( let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .initialize_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) .await .unwrap(); @@ -213,7 +220,12 @@ async fn test_set_manager_with_wrong_mint_for_pool_fee_acc() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .initialize_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) .await .unwrap(); diff --git a/program/tests/set_preferred.rs b/program/tests/set_preferred.rs index fb5fbf81..10b11a81 100644 --- a/program/tests/set_preferred.rs +++ b/program/tests/set_preferred.rs @@ -17,6 +17,7 @@ use { error, find_transient_stake_program_address, id, instruction::{self, PreferredValidatorType}, state::StakePool, + MINIMUM_RESERVE_LAMPORTS, }, }; @@ -30,7 +31,12 @@ async fn setup() -> ( let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .initialize_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) .await .unwrap(); diff --git a/program/tests/set_referral_fee.rs b/program/tests/set_referral_fee.rs index 5a19c2f0..cdc93fb9 100644 --- a/program/tests/set_referral_fee.rs +++ b/program/tests/set_referral_fee.rs @@ -14,6 +14,7 @@ use { spl_stake_pool::{ error, id, instruction, state::{FeeType, StakePool}, + MINIMUM_RESERVE_LAMPORTS, }, }; @@ -28,7 +29,7 @@ async fn setup(fee: Option) -> (ProgramTestContext, StakePoolAccounts, u8) { &mut context.banks_client, &context.payer, &context.last_blockhash, - 1, + MINIMUM_RESERVE_LAMPORTS, ) .await .unwrap(); diff --git a/program/tests/set_staker.rs b/program/tests/set_staker.rs index 314030be..49efad60 100644 --- a/program/tests/set_staker.rs +++ b/program/tests/set_staker.rs @@ -12,17 +12,24 @@ use { }, solana_program_test::*, solana_sdk::{ - instruction::InstructionError, signature::Keypair, signature::Signer, - transaction::Transaction, transaction::TransactionError, transport::TransportError, + instruction::InstructionError, + signature::{Keypair, Signer}, + transaction::{Transaction, TransactionError}, + transport::TransportError, }, - spl_stake_pool::{error, id, instruction, state}, + spl_stake_pool::{error, id, instruction, state, MINIMUM_RESERVE_LAMPORTS}, }; async fn setup() -> (BanksClient, Keypair, Hash, StakePoolAccounts, Keypair) { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .initialize_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) .await .unwrap(); diff --git a/program/tests/set_withdrawal_fee.rs b/program/tests/set_withdrawal_fee.rs index 10438662..1b2d48ae 100644 --- a/program/tests/set_withdrawal_fee.rs +++ b/program/tests/set_withdrawal_fee.rs @@ -14,6 +14,7 @@ use { spl_stake_pool::{ error, id, instruction, state::{Fee, FeeType, StakePool}, + MINIMUM_RESERVE_LAMPORTS, }, }; @@ -28,7 +29,7 @@ async fn setup(fee: Option) -> (ProgramTestContext, StakePoolAccounts, Fee) &mut context.banks_client, &context.payer, &context.last_blockhash, - 1, + MINIMUM_RESERVE_LAMPORTS, ) .await .unwrap(); @@ -623,7 +624,7 @@ async fn fail_not_updated() { &mut context.banks_client, &context.payer, &context.last_blockhash, - 1, + MINIMUM_RESERVE_LAMPORTS, ) .await .unwrap(); diff --git a/program/tests/update_stake_pool_balance.rs b/program/tests/update_stake_pool_balance.rs index aa031690..3b415c0a 100644 --- a/program/tests/update_stake_pool_balance.rs +++ b/program/tests/update_stake_pool_balance.rs @@ -12,7 +12,7 @@ use { signature::{Keypair, Signer}, transaction::TransactionError, }, - spl_stake_pool::{error::StakePoolError, state::StakePool}, + spl_stake_pool::{error::StakePoolError, state::StakePool, MINIMUM_RESERVE_LAMPORTS}, }; async fn setup() -> ( @@ -27,7 +27,7 @@ async fn setup() -> ( &mut context.banks_client, &context.payer, &context.last_blockhash, - 1, + MINIMUM_RESERVE_LAMPORTS, ) .await .unwrap(); @@ -260,7 +260,12 @@ async fn fail_with_wrong_validator_list() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let mut stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .initialize_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) .await .unwrap(); @@ -289,7 +294,12 @@ async fn fail_with_wrong_pool_fee_account() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let mut stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .initialize_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) .await .unwrap(); @@ -318,7 +328,12 @@ async fn fail_with_wrong_reserve() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let mut stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .initialize_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) .await .unwrap(); diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index 44cb093e..1268ab7f 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -8,13 +8,15 @@ use { solana_program_test::*, solana_sdk::{ signature::{Keypair, Signer}, + stake::state::{Authorized, Lockup, StakeState}, system_instruction, transaction::Transaction, }, spl_stake_pool::{ - find_transient_stake_program_address, id, instruction, + find_transient_stake_program_address, find_withdraw_authority_program_address, id, + instruction, state::{StakePool, StakeStatus, ValidatorList}, - MAX_VALIDATORS_TO_UPDATE, MINIMUM_ACTIVE_STAKE, + MAX_VALIDATORS_TO_UPDATE, MINIMUM_ACTIVE_STAKE, MINIMUM_RESERVE_LAMPORTS, }, spl_token::state::Mint, }; @@ -43,7 +45,7 @@ async fn setup( &mut context.banks_client, &context.payer, &context.last_blockhash, - reserve_stake_amount + 1, + reserve_stake_amount + MINIMUM_RESERVE_LAMPORTS, ) .await .unwrap(); @@ -163,7 +165,7 @@ async fn success() { // Check current balance in the list let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); // initially, have all of the deposits plus their rent, and the reserve stake let initial_lamports = (validator_lamports + stake_rent) * num_validators as u64 + reserve_lamports; @@ -436,7 +438,7 @@ async fn merge_into_validator_stake() { // Check validator stake accounts have the expected balance now: // validator stake account minimum + deposited lamports + rents + increased lamports - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let expected_lamports = MINIMUM_ACTIVE_STAKE + lamports + reserve_lamports / stake_accounts.len() as u64 @@ -456,7 +458,7 @@ async fn merge_into_validator_stake() { .await; assert_eq!( reserve_stake.lamports, - 1 + stake_rent * (1 + stake_accounts.len() as u64) + MINIMUM_RESERVE_LAMPORTS + stake_rent * (1 + stake_accounts.len() as u64) ); } @@ -466,7 +468,7 @@ async fn merge_transient_stake_after_remove() { setup(1).await; let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let deactivated_lamports = lamports; let new_authority = Pubkey::new_unique(); let destination_stake = Keypair::new(); @@ -575,7 +577,7 @@ async fn merge_transient_stake_after_remove() { .unwrap(); assert_eq!( reserve_stake.lamports, - reserve_lamports + deactivated_lamports + 2 * stake_rent + 1 + reserve_lamports + deactivated_lamports + 2 * stake_rent + MINIMUM_RESERVE_LAMPORTS ); // Update stake pool balance and cleanup, should be gone @@ -677,17 +679,43 @@ async fn success_with_burned_tokens() { } #[tokio::test] -async fn success_ignoring_hijacked_transient_stake() { +async fn success_ignoring_hijacked_transient_stake_with_authorized() { + let hijacker = Pubkey::new_unique(); + check_ignored_hijacked_transient_stake(Some(&Authorized::auto(&hijacker)), None).await; +} + +#[tokio::test] +async fn success_ignoring_hijacked_transient_stake_with_lockup() { + let hijacker = Pubkey::new_unique(); + check_ignored_hijacked_transient_stake( + None, + Some(&Lockup { + custodian: hijacker, + ..Lockup::default() + }), + ) + .await; +} + +async fn check_ignored_hijacked_transient_stake( + hijack_authorized: Option<&Authorized>, + hijack_lockup: Option<&Lockup>, +) { let num_validators = 1; let (mut context, stake_pool_accounts, stake_accounts, _, lamports, _, mut slot) = setup(num_validators).await; + let rent = context.banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let pre_lamports = get_validator_list_sum( &mut context.banks_client, &stake_pool_accounts.reserve_stake.pubkey(), &stake_pool_accounts.validator_list.pubkey(), ) .await; + let (withdraw_authority, _) = + find_withdraw_authority_program_address(&id(), &stake_pool_accounts.stake_pool.pubkey()); println!("Decrease from all validators"); let stake_account = &stake_accounts[0]; @@ -713,7 +741,6 @@ async fn success_ignoring_hijacked_transient_stake() { let validator_list = stake_pool_accounts .get_validator_list(&mut context.banks_client) .await; - let hijacker = Pubkey::new_unique(); let transient_stake_address = find_transient_stake_program_address( &id(), &stake_account.vote.pubkey(), @@ -737,15 +764,12 @@ async fn success_ignoring_hijacked_transient_stake() { system_instruction::transfer( &context.payer.pubkey(), &transient_stake_address, - 1_000_000_000, + stake_rent + MINIMUM_RESERVE_LAMPORTS, ), stake::instruction::initialize( &transient_stake_address, - &stake::state::Authorized { - staker: hijacker, - withdrawer: hijacker, - }, - &stake::state::Lockup::default(), + &hijack_authorized.unwrap_or(&Authorized::auto(&withdraw_authority)), + &hijack_lockup.unwrap_or(&Lockup::default()), ), instruction::update_stake_pool_balance( &id(), diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index e6070676..de0c6665 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -19,7 +19,10 @@ use { transaction::{Transaction, TransactionError}, transport::TransportError, }, - spl_stake_pool::{error::StakePoolError, find_stake_program_address, id, instruction, state}, + spl_stake_pool::{ + error::StakePoolError, find_stake_program_address, id, instruction, state, + MINIMUM_RESERVE_LAMPORTS, + }, }; async fn setup() -> ( @@ -32,7 +35,12 @@ async fn setup() -> ( let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .initialize_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) .await .unwrap(); @@ -391,7 +399,12 @@ async fn fail_add_too_many_validator_stake_accounts() { let mut stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts.max_validators = 1; stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .initialize_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) .await .unwrap(); diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index a0dde372..0f1f41d7 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -20,6 +20,7 @@ use { }, spl_stake_pool::{ error::StakePoolError, find_transient_stake_program_address, id, instruction, state, + MINIMUM_ACTIVE_STAKE, MINIMUM_RESERVE_LAMPORTS, }, }; @@ -37,7 +38,7 @@ async fn setup() -> ( &mut context.banks_client, &context.payer, &context.last_blockhash, - 10_000_000_000, + 10_000_000_000 + MINIMUM_RESERVE_LAMPORTS, ) .await .unwrap(); @@ -688,6 +689,9 @@ async fn success_resets_preferred_validator() { async fn success_with_hijacked_transient_account() { let (mut context, stake_pool_accounts, validator_stake, new_authority, destination_stake) = setup().await; + let rent = context.banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let increase_amount = MINIMUM_ACTIVE_STAKE + stake_rent; // increase stake on validator let error = stake_pool_accounts @@ -697,7 +701,7 @@ async fn success_with_hijacked_transient_account() { &context.last_blockhash, &validator_stake.transient_stake_account, &validator_stake.vote.pubkey(), - 1_000_000_000, + increase_amount, validator_stake.transient_stake_seed, ) .await; @@ -726,7 +730,7 @@ async fn success_with_hijacked_transient_account() { &context.last_blockhash, &validator_stake.stake_account, &validator_stake.transient_stake_account, - 1_000_000_000, + increase_amount, validator_stake.transient_stake_seed, ) .await; @@ -764,7 +768,7 @@ async fn success_with_hijacked_transient_account() { system_instruction::transfer( &context.payer.pubkey(), &transient_stake_address, - 1_000_000_000, + MINIMUM_RESERVE_LAMPORTS + stake_rent, ), stake::instruction::initialize( &transient_stake_address, diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 1b120599..e3fbc2ba 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -19,7 +19,10 @@ use { transaction::{Transaction, TransactionError}, transport::TransportError, }, - spl_stake_pool::{error::StakePoolError, id, instruction, minimum_stake_lamports, state}, + spl_stake_pool::{ + error::StakePoolError, id, instruction, minimum_stake_lamports, state, + MINIMUM_ACTIVE_STAKE, MINIMUM_RESERVE_LAMPORTS, + }, spl_token::error::TokenError, }; @@ -37,7 +40,12 @@ async fn setup() -> ( let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .initialize_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) .await .unwrap(); @@ -55,12 +63,12 @@ async fn setup() -> ( &recent_blockhash, &stake_pool_accounts, &validator_stake_account, - TEST_STAKE_AMOUNT, + MINIMUM_ACTIVE_STAKE * 3, ) .await .unwrap(); - let tokens_to_withdraw = deposit_info.pool_tokens / 4; + let tokens_to_withdraw = deposit_info.pool_tokens; // Delegate tokens for withdrawing let user_transfer_authority = Keypair::new(); @@ -590,7 +598,7 @@ async fn fail_double_withdraw_to_the_same_account() { &deposit_info.pool_account.pubkey(), &validator_stake_account.stake_account, &new_authority, - tokens_to_burn, + tokens_to_burn / 2, ) .await; assert!(error.is_none()); @@ -605,7 +613,7 @@ async fn fail_double_withdraw_to_the_same_account() { &deposit_info.pool_account.pubkey(), &deposit_info.authority, &user_transfer_authority.pubkey(), - tokens_to_burn, + tokens_to_burn / 2, ) .await; @@ -619,7 +627,7 @@ async fn fail_double_withdraw_to_the_same_account() { &deposit_info.pool_account.pubkey(), &validator_stake_account.stake_account, &new_authority, - tokens_to_burn, + tokens_to_burn / 2, ) .await .unwrap(); @@ -637,7 +645,12 @@ async fn fail_without_token_approval() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .initialize_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) .await .unwrap(); @@ -708,7 +721,12 @@ async fn fail_with_low_delegation() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let stake_pool_accounts = StakePoolAccounts::new(); stake_pool_accounts - .initialize_stake_pool(&mut banks_client, &payer, &recent_blockhash, 1) + .initialize_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) .await .unwrap(); @@ -837,7 +855,7 @@ async fn fail_overdraw_validator() { async fn success_with_reserve() { let mut context = program_test().start_with_context().await; let stake_pool_accounts = StakePoolAccounts::new(); - let initial_reserve_lamports = 1; + let initial_reserve_lamports = MINIMUM_RESERVE_LAMPORTS; stake_pool_accounts .initialize_stake_pool( &mut context.banks_client, @@ -856,9 +874,9 @@ async fn success_with_reserve() { ) .await; - let deposit_lamports = TEST_STAKE_AMOUNT; let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let deposit_lamports = (MINIMUM_ACTIVE_STAKE + stake_rent) * 2; let deposit_info = simple_deposit_stake( &mut context.banks_client, @@ -879,7 +897,7 @@ async fn success_with_reserve() { &context.last_blockhash, &validator_stake.stake_account, &validator_stake.transient_stake_account, - deposit_lamports - 1, + deposit_lamports / 2, validator_stake.transient_stake_seed, ) .await; @@ -957,7 +975,7 @@ async fn success_with_reserve() { &context.last_blockhash, &validator_stake.stake_account, &validator_stake.transient_stake_account, - stake_rent + 1, + deposit_lamports / 2 + stake_rent, validator_stake.transient_stake_seed, ) .await; @@ -1191,10 +1209,10 @@ async fn fail_with_wrong_preferred_withdraw() { } #[tokio::test] -async fn success_withdraw_from_transient() { +async fn fail_withdraw_from_transient() { let mut context = program_test().start_with_context().await; let stake_pool_accounts = StakePoolAccounts::new(); - let initial_reserve_lamports = 1; + let initial_reserve_lamports = MINIMUM_RESERVE_LAMPORTS; stake_pool_accounts .initialize_stake_pool( &mut context.banks_client, @@ -1232,9 +1250,9 @@ async fn success_withdraw_from_transient() { ) .await; - let deposit_lamports = TEST_STAKE_AMOUNT; let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let deposit_lamports = (MINIMUM_ACTIVE_STAKE + stake_rent) * 2; let deposit_info = simple_deposit_stake( &mut context.banks_client, @@ -1260,7 +1278,7 @@ async fn success_withdraw_from_transient() { ) .await; - // decrease minimum stake + // decrease to minimum stake + 1 lamport let error = stake_pool_accounts .decrease_validator_stake( &mut context.banks_client, @@ -1268,7 +1286,7 @@ async fn success_withdraw_from_transient() { &context.last_blockhash, &validator_stake.stake_account, &validator_stake.transient_stake_account, - stake_rent + 1, + deposit_lamports + stake_rent - 1, validator_stake.transient_stake_seed, ) .await; @@ -1307,29 +1325,91 @@ async fn success_withdraw_from_transient() { InstructionError::Custom(StakePoolError::InvalidStakeAccountAddress as u32) ) ); +} - // warp forward to deactivation - let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; - let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; - context - .warp_to_slot(first_normal_slot + slots_per_epoch) +#[tokio::test] +async fn success_withdraw_from_transient() { + let mut context = program_test().start_with_context().await; + let stake_pool_accounts = StakePoolAccounts::new(); + let initial_reserve_lamports = MINIMUM_RESERVE_LAMPORTS; + stake_pool_accounts + .initialize_stake_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + initial_reserve_lamports, + ) + .await .unwrap(); - // update to merge deactivated stake into reserve + // add a preferred withdraw validator, keep it empty, to be sure that this works + let preferred_validator = simple_add_validator_to_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + ) + .await; + stake_pool_accounts - .update_all( + .set_preferred_validator( &mut context.banks_client, &context.payer, &context.last_blockhash, - &[ - preferred_validator.vote.pubkey(), - validator_stake.vote.pubkey(), - ], - false, + instruction::PreferredValidatorType::Withdraw, + Some(preferred_validator.vote.pubkey()), ) .await; - // decrease rest of stake + let validator_stake = simple_add_validator_to_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + ) + .await; + + let rent = context.banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + + // compensate for the fee and the minimum balance in the transient stake account + let deposit_lamports = (MINIMUM_ACTIVE_STAKE + stake_rent) * 3; + + let deposit_info = simple_deposit_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + &validator_stake, + deposit_lamports, + ) + .await + .unwrap(); + + // Delegate tokens for burning during withdraw + let user_transfer_authority = Keypair::new(); + delegate_tokens( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &deposit_info.pool_account.pubkey(), + &deposit_info.authority, + &user_transfer_authority.pubkey(), + deposit_info.pool_tokens, + ) + .await; + + let withdraw_destination = Keypair::new(); + let withdraw_destination_authority = Pubkey::new_unique(); + let _initial_stake_lamports = create_blank_stake_account( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &withdraw_destination, + ) + .await; + + // decrease all of stake let error = stake_pool_accounts .decrease_validator_stake( &mut context.banks_client, @@ -1337,7 +1417,7 @@ async fn success_withdraw_from_transient() { &context.last_blockhash, &validator_stake.stake_account, &validator_stake.transient_stake_account, - deposit_lamports - 1, + deposit_lamports + stake_rent, validator_stake.transient_stake_seed, ) .await; @@ -1355,7 +1435,7 @@ async fn success_withdraw_from_transient() { &deposit_info.pool_account.pubkey(), &validator_stake.transient_stake_account, &withdraw_destination_authority, - deposit_info.pool_tokens / 4, + deposit_info.pool_tokens / 2, ) .await; assert!(error.is_none()); diff --git a/program/tests/withdraw_sol.rs b/program/tests/withdraw_sol.rs index 4dd35b3d..4d42d0ba 100644 --- a/program/tests/withdraw_sol.rs +++ b/program/tests/withdraw_sol.rs @@ -10,14 +10,13 @@ use { solana_program_test::*, solana_sdk::{ signature::{Keypair, Signer}, - transaction::Transaction, - transaction::TransactionError, + transaction::{Transaction, TransactionError}, }, spl_stake_pool::{ error::StakePoolError, id, instruction::{self, FundingType}, - state, + state, MINIMUM_RESERVE_LAMPORTS, }, }; @@ -30,7 +29,7 @@ async fn setup() -> (ProgramTestContext, StakePoolAccounts, Keypair, Pubkey, u64 &mut context.banks_client, &context.payer, &context.last_blockhash, - 1, + MINIMUM_RESERVE_LAMPORTS, ) .await .unwrap(); From 86dcd6247493b7c93eac72a60ea4674a7cde1b6e Mon Sep 17 00:00:00 2001 From: Dmitri Makarov Date: Tue, 17 May 2022 11:27:30 -0700 Subject: [PATCH 0239/1076] Bump solana to v1.10.15 (#3176) --- clients/cli/Cargo.toml | 18 +++++++++--------- program/Cargo.toml | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 4d9c4dc7..5db39645 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -14,15 +14,15 @@ clap = "2.33.3" serde = "1.0.130" serde_derive = "1.0.130" serde_json = "1.0.68" -solana-account-decoder = "=1.10.10" -solana-clap-utils = "=1.10.10" -solana-cli-config = "=1.10.10" -solana-cli-output = "=1.10.10" -solana-client = "=1.10.10" -solana-logger = "=1.10.10" -solana-program = "=1.10.10" -solana-remote-wallet = "=1.10.10" -solana-sdk = "=1.10.10" +solana-account-decoder = "=1.10.15" +solana-clap-utils = "=1.10.15" +solana-cli-config = "=1.10.15" +solana-cli-output = "=1.10.15" +solana-client = "=1.10.15" +solana-logger = "=1.10.15" +solana-program = "=1.10.15" +solana-remote-wallet = "=1.10.15" +solana-sdk = "=1.10.15" spl-associated-token-account = { version = "=1.0.5", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "=0.6.4", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "=3.3.0", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/program/Cargo.toml b/program/Cargo.toml index 93e9a11c..968a074e 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -19,7 +19,7 @@ num-traits = "0.2" num_enum = "0.5.4" serde = "1.0.130" serde_derive = "1.0.103" -solana-program = "1.10.10" +solana-program = "1.10.15" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-token = { version = "3.3", path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" @@ -27,9 +27,9 @@ bincode = "1.3.1" [dev-dependencies] proptest = "1.0" -solana-program-test = "1.10.10" -solana-sdk = "1.10.10" -solana-vote-program = "1.10.10" +solana-program-test = "1.10.15" +solana-sdk = "1.10.15" +solana-vote-program = "1.10.15" [lib] crate-type = ["cdylib", "lib"] From dc3f6b59713f9e4e264775852bfc6eeb92d83789 Mon Sep 17 00:00:00 2001 From: Dmitri Makarov Date: Tue, 17 May 2022 12:25:24 -0700 Subject: [PATCH 0240/1076] Use target_os instead of target_arch for Solana conditional compilation (#3148) --- program/src/entrypoint.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/src/entrypoint.rs b/program/src/entrypoint.rs index a44df1e5..a809d7f2 100644 --- a/program/src/entrypoint.rs +++ b/program/src/entrypoint.rs @@ -1,6 +1,6 @@ //! Program entrypoint -#![cfg(all(target_arch = "bpf", not(feature = "no-entrypoint")))] +#![cfg(all(target_os = "solana", not(feature = "no-entrypoint")))] use { crate::{error::StakePoolError, processor::Processor}, From d74ab7c250c95fe15b86b75a37f5e7496c95b28f Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 19 May 2022 19:08:50 +0200 Subject: [PATCH 0241/1076] stake-pool: Handle force destaked accounts (#3152) --- clients/js-legacy/src/index.ts | 7 + clients/js-legacy/src/instructions.ts | 3 + clients/py/stake_pool/actions.py | 6 + clients/py/stake_pool/instructions.py | 3 + program/src/instruction.rs | 20 +- program/src/processor.rs | 51 ++++ program/tests/force_destake.rs | 193 +++++++++++++ program/tests/helpers/mod.rs | 270 +++++++++++++++++- program/tests/huge_pool.rs | 245 +++------------- program/tests/increase.rs | 15 +- .../tests/update_validator_list_balance.rs | 7 +- program/tests/vsa_remove.rs | 2 + program/tests/withdraw_sol.rs | 1 + 13 files changed, 595 insertions(+), 228 deletions(-) create mode 100644 program/tests/force_destake.rs diff --git a/clients/js-legacy/src/index.ts b/clients/js-legacy/src/index.ts index d3202fe6..7eac0b4d 100644 --- a/clients/js-legacy/src/index.ts +++ b/clients/js-legacy/src/index.ts @@ -612,6 +612,12 @@ export async function increaseValidatorStake( transientStakeSeed, ); + const validatorStake = await findStakeProgramAddress( + STAKE_POOL_PROGRAM_ID, + validatorInfo.voteAccountAddress, + stakePoolAddress, + ); + const instructions: TransactionInstruction[] = []; instructions.push( StakePoolInstruction.increaseValidatorStake({ @@ -622,6 +628,7 @@ export async function increaseValidatorStake( transientStakeSeed: transientStakeSeed.toNumber(), withdrawAuthority, transientStake, + validatorStake, validatorVote, lamports, }), diff --git a/clients/js-legacy/src/instructions.ts b/clients/js-legacy/src/instructions.ts index 74b817ce..422bdc67 100644 --- a/clients/js-legacy/src/instructions.ts +++ b/clients/js-legacy/src/instructions.ts @@ -157,6 +157,7 @@ export type IncreaseValidatorStakeParams = { validatorList: PublicKey; reserveStake: PublicKey; transientStake: PublicKey; + validatorStake: PublicKey; validatorVote: PublicKey; // Amount of lamports to split into the transient stake account. lamports: number; @@ -343,6 +344,7 @@ export class StakePoolInstruction { validatorList, reserveStake, transientStake, + validatorStake, validatorVote, lamports, transientStakeSeed, @@ -358,6 +360,7 @@ export class StakePoolInstruction { { pubkey: validatorList, isSigner: false, isWritable: true }, { pubkey: reserveStake, isSigner: false, isWritable: true }, { pubkey: transientStake, isSigner: false, isWritable: true }, + { pubkey: validatorStake, isSigner: false, isWritable: false }, { pubkey: validatorVote, isSigner: false, isWritable: false }, { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false }, { pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false }, diff --git a/clients/py/stake_pool/actions.py b/clients/py/stake_pool/actions.py index 289aca16..970205a3 100644 --- a/clients/py/stake_pool/actions.py +++ b/clients/py/stake_pool/actions.py @@ -493,6 +493,11 @@ async def increase_validator_stake( stake_pool_address, transient_stake_seed, ) + (validator_stake, _) = find_stake_program_address( + STAKE_POOL_PROGRAM_ID, + validator_info.vote_account_address, + stake_pool_address, + ) txn = Transaction() txn.add( @@ -505,6 +510,7 @@ async def increase_validator_stake( validator_list=stake_pool.validator_list, reserve_stake=stake_pool.reserve_stake, transient_stake=transient_stake, + validator_stake=validator_stake, validator_vote=validator_vote, clock_sysvar=SYSVAR_CLOCK_PUBKEY, rent_sysvar=SYSVAR_RENT_PUBKEY, diff --git a/clients/py/stake_pool/instructions.py b/clients/py/stake_pool/instructions.py index 5a227575..dfc3c8a3 100644 --- a/clients/py/stake_pool/instructions.py +++ b/clients/py/stake_pool/instructions.py @@ -191,6 +191,8 @@ class IncreaseValidatorStakeParams(NamedTuple): """`[w]` Stake pool's reserve.""" transient_stake: PublicKey """`[w]` Transient stake account to receive split.""" + validator_stake: PublicKey + """`[]` Canonical stake account to check.""" validator_vote: PublicKey """`[]` Validator vote account to delegate to.""" clock_sysvar: PublicKey @@ -866,6 +868,7 @@ def increase_validator_stake(params: IncreaseValidatorStakeParams) -> Transactio AccountMeta(pubkey=params.validator_list, is_signer=False, is_writable=True), AccountMeta(pubkey=params.reserve_stake, is_signer=False, is_writable=True), AccountMeta(pubkey=params.transient_stake, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.validator_stake, is_signer=False, is_writable=False), AccountMeta(pubkey=params.validator_vote, is_signer=False, is_writable=False), AccountMeta(pubkey=params.clock_sysvar, is_signer=False, is_writable=False), AccountMeta(pubkey=params.rent_sysvar, is_signer=False, is_writable=False), diff --git a/program/src/instruction.rs b/program/src/instruction.rs index d511a051..85c81a47 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -166,13 +166,14 @@ pub enum StakePoolInstruction { /// 3. `[w]` Validator list /// 4. `[w]` Stake pool reserve stake /// 5. `[w]` Transient stake account - /// 6. `[]` Validator vote account to delegate to - /// 7. '[]' Clock sysvar - /// 8. '[]' Rent sysvar - /// 9. `[]` Stake History sysvar - /// 10. `[]` Stake Config sysvar - /// 11. `[]` System program - /// 12. `[]` Stake program + /// 6. `[]` Validator stake account + /// 7. `[]` Validator vote account to delegate to + /// 8. '[]' Clock sysvar + /// 9. '[]' Rent sysvar + /// 10. `[]` Stake History sysvar + /// 11. `[]` Stake Config sysvar + /// 12. `[]` System program + /// 13. `[]` Stake program /// userdata: amount of lamports to increase on the given validator. /// The actual amount split into the transient stake account is: /// `lamports + stake_rent_exemption` @@ -538,6 +539,7 @@ pub fn increase_validator_stake( validator_list: &Pubkey, reserve_stake: &Pubkey, transient_stake: &Pubkey, + validator_stake: &Pubkey, validator: &Pubkey, lamports: u64, transient_stake_seed: u64, @@ -549,6 +551,7 @@ pub fn increase_validator_stake( AccountMeta::new(*validator_list, false), AccountMeta::new(*reserve_stake, false), AccountMeta::new(*transient_stake, false), + AccountMeta::new_readonly(*validator_stake, false), AccountMeta::new_readonly(*validator, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::rent::id(), false), @@ -671,6 +674,8 @@ pub fn increase_validator_stake_with_vote( stake_pool_address, transient_stake_seed, ); + let (validator_stake_address, _) = + find_stake_program_address(program_id, vote_account_address, stake_pool_address); increase_validator_stake( program_id, @@ -680,6 +685,7 @@ pub fn increase_validator_stake_with_vote( &stake_pool.validator_list, &stake_pool.reserve_stake, &transient_stake_address, + &validator_stake_address, vote_account_address, lamports, transient_stake_seed, diff --git a/program/src/processor.rs b/program/src/processor.rs index e22ed222..2b194e2b 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1240,6 +1240,7 @@ impl Processor { let validator_list_info = next_account_info(account_info_iter)?; let reserve_stake_account_info = next_account_info(account_info_iter)?; let transient_stake_account_info = next_account_info(account_info_iter)?; + let validator_stake_account_info = next_account_info(account_info_iter)?; let validator_vote_account_info = next_account_info(account_info_iter)?; let clock_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(clock_info)?; @@ -1300,6 +1301,32 @@ impl Processor { return Err(StakePoolError::TransientAccountInUse.into()); } + // Check that the validator stake account is actually delegated to the right + // validator. This can happen if a validator was force destaked during a + // cluster restart. + { + check_account_owner(validator_stake_account_info, stake_program_info.key)?; + check_validator_stake_address( + program_id, + stake_pool_info.key, + validator_stake_account_info.key, + vote_account_address, + )?; + let (meta, stake) = get_stake_state(validator_stake_account_info)?; + if !stake_is_usable_by_pool(&meta, withdraw_authority_info.key, &stake_pool.lockup) { + msg!("Validator stake for {} not usable by pool, must be owned by withdraw authority", vote_account_address); + return Err(StakePoolError::WrongStakeState.into()); + } + if stake.delegation.voter_pubkey != *vote_account_address { + msg!( + "Validator stake {} not delegated to {}", + validator_stake_account_info.key, + vote_account_address + ); + return Err(StakePoolError::WrongStakeState.into()); + } + } + let transient_stake_bump_seed = check_transient_stake_address( program_id, stake_pool_info.key, @@ -1683,6 +1710,30 @@ impl Processor { msg!("Validator stake account no longer part of the pool, ignoring"); } } + Some(stake::state::StakeState::Initialized(meta)) + if stake_is_usable_by_pool( + &meta, + withdraw_authority_info.key, + &stake_pool.lockup, + ) => + { + // If a validator stake is `Initialized`, the validator could + // have been destaked during a cluster restart. Either way, + // absorb those lamports into the reserve. The transient + // stake was likely absorbed into the reserve earlier. + Self::stake_merge( + stake_pool_info.key, + validator_stake_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + reserve_stake_info.clone(), + clock_info.clone(), + stake_history_info.clone(), + stake_program_info.clone(), + )?; + validator_stake_record.status = StakeStatus::ReadyForRemoval; + } Some(stake::state::StakeState::Initialized(_)) | Some(stake::state::StakeState::Uninitialized) | Some(stake::state::StakeState::RewardsPool) diff --git a/program/tests/force_destake.rs b/program/tests/force_destake.rs new file mode 100644 index 00000000..afc33fb6 --- /dev/null +++ b/program/tests/force_destake.rs @@ -0,0 +1,193 @@ +#![cfg(feature = "test-bpf")] + +mod helpers; + +use { + helpers::*, + solana_program::{instruction::InstructionError, pubkey::Pubkey, stake}, + solana_program_test::*, + solana_sdk::{ + account::{Account, WritableAccount}, + clock::Epoch, + signature::Signer, + transaction::TransactionError, + }, + spl_stake_pool::{ + error::StakePoolError, + find_stake_program_address, find_transient_stake_program_address, id, + state::{StakeStatus, ValidatorStakeInfo}, + MINIMUM_ACTIVE_STAKE, + }, +}; + +async fn setup() -> (ProgramTestContext, StakePoolAccounts, Pubkey) { + let mut program_test = program_test(); + let stake_pool_accounts = StakePoolAccounts::new(); + + let stake_pool_pubkey = stake_pool_accounts.stake_pool.pubkey(); + let (mut stake_pool, mut validator_list) = stake_pool_accounts.state(); + + let voter_pubkey = add_vote_account(&mut program_test); + let meta = stake::state::Meta { + rent_exempt_reserve: STAKE_ACCOUNT_RENT_EXEMPTION, + authorized: stake::state::Authorized { + staker: stake_pool_accounts.withdraw_authority, + withdrawer: stake_pool_accounts.withdraw_authority, + }, + lockup: stake_pool.lockup, + }; + + let stake_account = Account::create( + TEST_STAKE_AMOUNT + STAKE_ACCOUNT_RENT_EXEMPTION, + bincode::serialize::(&stake::state::StakeState::Initialized( + meta, + )) + .unwrap(), + stake::program::id(), + false, + Epoch::default(), + ); + + let (stake_address, _) = find_stake_program_address(&id(), &voter_pubkey, &stake_pool_pubkey); + program_test.add_account(stake_address, stake_account); + let active_stake_lamports = TEST_STAKE_AMOUNT - MINIMUM_ACTIVE_STAKE; + // add to validator list + validator_list.validators.push(ValidatorStakeInfo { + status: StakeStatus::Active, + vote_account_address: voter_pubkey, + active_stake_lamports, + transient_stake_lamports: 0, + last_update_epoch: 0, + transient_seed_suffix_start: 0, + transient_seed_suffix_end: 0, + }); + + stake_pool.total_lamports += active_stake_lamports; + stake_pool.pool_token_supply += active_stake_lamports; + + add_reserve_stake_account( + &mut program_test, + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.withdraw_authority, + TEST_STAKE_AMOUNT, + ); + add_stake_pool_account( + &mut program_test, + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool, + ); + add_validator_list_account( + &mut program_test, + &stake_pool_accounts.validator_list.pubkey(), + &validator_list, + stake_pool_accounts.max_validators, + ); + + add_mint_account( + &mut program_test, + &stake_pool_accounts.pool_mint.pubkey(), + &stake_pool_accounts.withdraw_authority, + stake_pool.pool_token_supply, + ); + add_token_account( + &mut program_test, + &stake_pool_accounts.pool_fee_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &stake_pool_accounts.manager.pubkey(), + ); + + let context = program_test.start_with_context().await; + (context, stake_pool_accounts, voter_pubkey) +} + +#[tokio::test] +async fn success_update() { + let (mut context, stake_pool_accounts, voter_pubkey) = setup().await; + let pre_reserve_lamports = context + .banks_client + .get_account(stake_pool_accounts.reserve_stake.pubkey()) + .await + .unwrap() + .unwrap() + .lamports; + let (stake_address, _) = find_stake_program_address( + &id(), + &voter_pubkey, + &stake_pool_accounts.stake_pool.pubkey(), + ); + let validator_stake_lamports = context + .banks_client + .get_account(stake_address) + .await + .unwrap() + .unwrap() + .lamports; + // update should merge the destaked validator stake account into the reserve + let error = stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &[voter_pubkey], + false, + ) + .await; + assert!(error.is_none()); + let post_reserve_lamports = context + .banks_client + .get_account(stake_pool_accounts.reserve_stake.pubkey()) + .await + .unwrap() + .unwrap() + .lamports; + assert_eq!( + post_reserve_lamports, + pre_reserve_lamports + validator_stake_lamports + ); + // test no more validator stake account + assert!(context + .banks_client + .get_account(stake_address) + .await + .unwrap() + .is_none()); +} + +#[tokio::test] +async fn fail_increase() { + let (mut context, stake_pool_accounts, voter_pubkey) = setup().await; + let (stake_address, _) = find_stake_program_address( + &id(), + &voter_pubkey, + &stake_pool_accounts.stake_pool.pubkey(), + ); + let transient_stake_seed = 0; + let transient_stake_address = find_transient_stake_program_address( + &id(), + &voter_pubkey, + &stake_pool_accounts.stake_pool.pubkey(), + transient_stake_seed, + ) + .0; + let error = stake_pool_accounts + .increase_validator_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &transient_stake_address, + &stake_address, + &voter_pubkey, + MINIMUM_ACTIVE_STAKE, + transient_stake_seed, + ) + .await + .unwrap() + .unwrap(); + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::WrongStakeState as u32) + ) + ); +} diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 19690bfd..d211afd9 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -1,28 +1,32 @@ #![allow(dead_code)] use { + borsh::BorshSerialize, solana_program::{ borsh::{get_instance_packed_len, get_packed_len, try_from_slice_unchecked}, hash::Hash, + program_option::COption, program_pack::Pack, pubkey::Pubkey, stake, system_instruction, system_program, }, - solana_program_test::*, + solana_program_test::{processor, BanksClient, ProgramTest}, solana_sdk::{ - account::Account, + account::{Account, WritableAccount}, + clock::{Clock, Epoch}, signature::{Keypair, Signer}, transaction::Transaction, transport::TransportError, }, solana_vote_program::{ self, vote_instruction, - vote_state::{VoteInit, VoteState}, + vote_state::{VoteInit, VoteState, VoteStateVersions}, }, spl_stake_pool::{ find_deposit_authority_program_address, find_stake_program_address, find_transient_stake_program_address, find_withdraw_authority_program_address, id, - instruction, processor, + instruction, + processor::Processor, state::{self, FeeType, ValidatorList}, MINIMUM_ACTIVE_STAKE, MINIMUM_RESERVE_LAMPORTS, }, @@ -31,13 +35,11 @@ use { pub const TEST_STAKE_AMOUNT: u64 = 1_500_000_000; pub const MAX_TEST_VALIDATORS: u32 = 10_000; pub const DEFAULT_TRANSIENT_STAKE_SEED: u64 = 42; +pub const STAKE_ACCOUNT_RENT_EXEMPTION: u64 = 2_282_880; +const ACCOUNT_RENT_EXEMPTION: u64 = 1_000_000_000; // go with something big to be safe pub fn program_test() -> ProgramTest { - ProgramTest::new( - "spl_stake_pool", - id(), - processor!(processor::Processor::process), - ) + ProgramTest::new("spl_stake_pool", id(), processor!(Processor::process)) } pub async fn get_account(banks_client: &mut BanksClient, pubkey: &Pubkey) -> Account { @@ -1280,6 +1282,7 @@ impl StakePoolAccounts { payer: &Keypair, recent_blockhash: &Hash, transient_stake: &Pubkey, + validator_stake: &Pubkey, validator: &Pubkey, lamports: u64, transient_stake_seed: u64, @@ -1293,6 +1296,7 @@ impl StakePoolAccounts { &self.validator_list.pubkey(), &self.reserve_stake.pubkey(), transient_stake, + validator_stake, validator, lamports, transient_stake_seed, @@ -1337,6 +1341,46 @@ impl StakePoolAccounts { .map_err(|e| e.into()) .err() } + + pub fn state(&self) -> (state::StakePool, state::ValidatorList) { + let (_, stake_withdraw_bump_seed) = + find_withdraw_authority_program_address(&id(), &self.stake_pool.pubkey()); + let stake_pool = state::StakePool { + account_type: state::AccountType::StakePool, + manager: self.manager.pubkey(), + staker: self.staker.pubkey(), + stake_deposit_authority: self.stake_deposit_authority, + stake_withdraw_bump_seed, + validator_list: self.validator_list.pubkey(), + reserve_stake: self.reserve_stake.pubkey(), + pool_mint: self.pool_mint.pubkey(), + manager_fee_account: self.pool_fee_account.pubkey(), + token_program_id: spl_token::id(), + total_lamports: 0, + pool_token_supply: 0, + last_update_epoch: 0, + lockup: stake::state::Lockup::default(), + epoch_fee: self.epoch_fee, + next_epoch_fee: None, + preferred_deposit_validator_vote_address: None, + preferred_withdraw_validator_vote_address: None, + stake_deposit_fee: state::Fee::default(), + sol_deposit_fee: state::Fee::default(), + stake_withdrawal_fee: state::Fee::default(), + next_stake_withdrawal_fee: None, + stake_referral_fee: 0, + sol_referral_fee: 0, + sol_deposit_authority: None, + sol_withdraw_authority: None, + sol_withdrawal_fee: state::Fee::default(), + next_sol_withdrawal_fee: None, + last_epoch_pool_token_supply: 0, + last_epoch_total_lamports: 0, + }; + let mut validator_list = ValidatorList::new(self.max_validators); + validator_list.validators = vec![]; + (stake_pool, validator_list) + } } pub async fn simple_add_validator_to_pool( @@ -1577,3 +1621,211 @@ pub async fn get_validator_list_sum( let rent = rent.minimum_balance(std::mem::size_of::()); validator_sum + reserve_stake.lamports - rent - MINIMUM_RESERVE_LAMPORTS } + +pub fn add_vote_account(program_test: &mut ProgramTest) -> Pubkey { + let authorized_voter = Pubkey::new_unique(); + let authorized_withdrawer = Pubkey::new_unique(); + let commission = 1; + + // create vote account + let vote_pubkey = Pubkey::new_unique(); + let node_pubkey = Pubkey::new_unique(); + let vote_state = VoteStateVersions::new_current(VoteState::new( + &VoteInit { + node_pubkey, + authorized_voter, + authorized_withdrawer, + commission, + }, + &Clock::default(), + )); + let vote_account = Account::create( + ACCOUNT_RENT_EXEMPTION, + bincode::serialize::(&vote_state).unwrap(), + solana_vote_program::id(), + false, + Epoch::default(), + ); + program_test.add_account(vote_pubkey, vote_account); + vote_pubkey +} + +pub fn add_validator_stake_account( + program_test: &mut ProgramTest, + stake_pool: &mut state::StakePool, + validator_list: &mut state::ValidatorList, + stake_pool_pubkey: &Pubkey, + withdraw_authority: &Pubkey, + voter_pubkey: &Pubkey, + stake_amount: u64, +) { + let meta = stake::state::Meta { + rent_exempt_reserve: STAKE_ACCOUNT_RENT_EXEMPTION, + authorized: stake::state::Authorized { + staker: *withdraw_authority, + withdrawer: *withdraw_authority, + }, + lockup: stake_pool.lockup, + }; + + // create validator stake account + let stake = stake::state::Stake { + delegation: stake::state::Delegation { + voter_pubkey: *voter_pubkey, + stake: stake_amount, + activation_epoch: 0, + deactivation_epoch: u64::MAX, + warmup_cooldown_rate: 0.25, // default + }, + credits_observed: 0, + }; + + let stake_account = Account::create( + stake_amount + STAKE_ACCOUNT_RENT_EXEMPTION, + bincode::serialize::(&stake::state::StakeState::Stake( + meta, stake, + )) + .unwrap(), + stake::program::id(), + false, + Epoch::default(), + ); + + let (stake_address, _) = find_stake_program_address(&id(), voter_pubkey, stake_pool_pubkey); + program_test.add_account(stake_address, stake_account); + let active_stake_lamports = stake_amount - MINIMUM_ACTIVE_STAKE; + // add to validator list + validator_list.validators.push(state::ValidatorStakeInfo { + status: state::StakeStatus::Active, + vote_account_address: *voter_pubkey, + active_stake_lamports, + transient_stake_lamports: 0, + last_update_epoch: 0, + transient_seed_suffix_start: 0, + transient_seed_suffix_end: 0, + }); + + stake_pool.total_lamports += active_stake_lamports; + stake_pool.pool_token_supply += active_stake_lamports; +} + +pub fn add_reserve_stake_account( + program_test: &mut ProgramTest, + reserve_stake: &Pubkey, + withdraw_authority: &Pubkey, + stake_amount: u64, +) { + let meta = stake::state::Meta { + rent_exempt_reserve: STAKE_ACCOUNT_RENT_EXEMPTION, + authorized: stake::state::Authorized { + staker: *withdraw_authority, + withdrawer: *withdraw_authority, + }, + lockup: stake::state::Lockup::default(), + }; + let reserve_stake_account = Account::create( + stake_amount + STAKE_ACCOUNT_RENT_EXEMPTION, + bincode::serialize::(&stake::state::StakeState::Initialized( + meta, + )) + .unwrap(), + stake::program::id(), + false, + Epoch::default(), + ); + program_test.add_account(*reserve_stake, reserve_stake_account); +} + +pub fn add_stake_pool_account( + program_test: &mut ProgramTest, + stake_pool_pubkey: &Pubkey, + stake_pool: &state::StakePool, +) { + let mut stake_pool_bytes = stake_pool.try_to_vec().unwrap(); + // more room for optionals + stake_pool_bytes.extend_from_slice(&Pubkey::default().to_bytes()); + stake_pool_bytes.extend_from_slice(&Pubkey::default().to_bytes()); + let stake_pool_account = Account::create( + ACCOUNT_RENT_EXEMPTION, + stake_pool_bytes, + id(), + false, + Epoch::default(), + ); + program_test.add_account(*stake_pool_pubkey, stake_pool_account); +} + +pub fn add_validator_list_account( + program_test: &mut ProgramTest, + validator_list_pubkey: &Pubkey, + validator_list: &state::ValidatorList, + max_validators: u32, +) { + let mut validator_list_bytes = validator_list.try_to_vec().unwrap(); + // add extra room if needed + for _ in validator_list.validators.len()..max_validators as usize { + validator_list_bytes + .append(&mut state::ValidatorStakeInfo::default().try_to_vec().unwrap()); + } + let validator_list_account = Account::create( + ACCOUNT_RENT_EXEMPTION, + validator_list_bytes, + id(), + false, + Epoch::default(), + ); + program_test.add_account(*validator_list_pubkey, validator_list_account); +} + +pub fn add_mint_account( + program_test: &mut ProgramTest, + mint_key: &Pubkey, + mint_authority: &Pubkey, + supply: u64, +) { + let mut mint_vec = vec![0u8; spl_token::state::Mint::LEN]; + let mint = spl_token::state::Mint { + mint_authority: COption::Some(*mint_authority), + supply, + decimals: 9, + is_initialized: true, + freeze_authority: COption::None, + }; + Pack::pack(mint, &mut mint_vec).unwrap(); + let stake_pool_mint = Account::create( + ACCOUNT_RENT_EXEMPTION, + mint_vec, + spl_token::id(), + false, + Epoch::default(), + ); + program_test.add_account(*mint_key, stake_pool_mint); +} + +pub fn add_token_account( + program_test: &mut ProgramTest, + account_key: &Pubkey, + mint_key: &Pubkey, + owner: &Pubkey, +) { + let mut fee_account_vec = vec![0u8; spl_token::state::Account::LEN]; + let fee_account_data = spl_token::state::Account { + mint: *mint_key, + owner: *owner, + amount: 0, + delegate: COption::None, + state: spl_token::state::AccountState::Initialized, + is_native: COption::None, + delegated_amount: 0, + close_authority: COption::None, + }; + Pack::pack(fee_account_data, &mut fee_account_vec).unwrap(); + let fee_account = Account::create( + ACCOUNT_RENT_EXEMPTION, + fee_account_vec, + spl_token::id(), + false, + Epoch::default(), + ); + program_test.add_account(*account_key, fee_account); +} diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index 67f8366a..d5d7a20d 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -3,37 +3,23 @@ mod helpers; use { - borsh::BorshSerialize, helpers::*, - solana_program::{ - borsh::try_from_slice_unchecked, program_option::COption, program_pack::Pack, - pubkey::Pubkey, stake, - }, + solana_program::{borsh::try_from_slice_unchecked, pubkey::Pubkey, stake}, solana_program_test::*, solana_sdk::{ - account::{Account, WritableAccount}, - clock::{Clock, Epoch}, signature::{Keypair, Signer}, transaction::Transaction, }, - solana_vote_program::{ - self, - vote_state::{VoteInit, VoteState, VoteStateVersions}, - }, spl_stake_pool::{ - find_stake_program_address, find_transient_stake_program_address, - find_withdraw_authority_program_address, id, + find_stake_program_address, find_transient_stake_program_address, id, instruction::{self, PreferredValidatorType}, - state::{AccountType, Fee, StakePool, StakeStatus, ValidatorList, ValidatorStakeInfo}, + state::{StakePool, StakeStatus, ValidatorList}, MAX_VALIDATORS_TO_UPDATE, MINIMUM_ACTIVE_STAKE, }, - spl_token::state::{Account as SplAccount, AccountState as SplAccountState, Mint}, }; const HUGE_POOL_SIZE: u32 = 2_950; -const ACCOUNT_RENT_EXEMPTION: u64 = 1_000_000_000; // go with something big to be safe const STAKE_AMOUNT: u64 = 200_000_000_000; -const STAKE_ACCOUNT_RENT_EXEMPTION: u64 = 2_282_880; async fn setup( max_validators: u32, @@ -54,210 +40,54 @@ async fn setup( stake_pool_accounts.max_validators = max_validators; let stake_pool_pubkey = stake_pool_accounts.stake_pool.pubkey(); - let (_, stake_withdraw_bump_seed) = - find_withdraw_authority_program_address(&id(), &stake_pool_pubkey); - - let mut stake_pool = StakePool { - account_type: AccountType::StakePool, - manager: stake_pool_accounts.manager.pubkey(), - staker: stake_pool_accounts.staker.pubkey(), - stake_deposit_authority: stake_pool_accounts.stake_deposit_authority, - stake_withdraw_bump_seed, - validator_list: stake_pool_accounts.validator_list.pubkey(), - reserve_stake: stake_pool_accounts.reserve_stake.pubkey(), - pool_mint: stake_pool_accounts.pool_mint.pubkey(), - manager_fee_account: stake_pool_accounts.pool_fee_account.pubkey(), - token_program_id: spl_token::id(), - total_lamports: 0, - pool_token_supply: 0, - last_update_epoch: 0, - lockup: stake::state::Lockup::default(), - epoch_fee: stake_pool_accounts.epoch_fee, - next_epoch_fee: None, - preferred_deposit_validator_vote_address: None, - preferred_withdraw_validator_vote_address: None, - stake_deposit_fee: Fee::default(), - sol_deposit_fee: Fee::default(), - stake_withdrawal_fee: Fee::default(), - next_stake_withdrawal_fee: None, - stake_referral_fee: 0, - sol_referral_fee: 0, - sol_deposit_authority: None, - sol_withdraw_authority: None, - sol_withdrawal_fee: Fee::default(), - next_sol_withdrawal_fee: None, - last_epoch_pool_token_supply: 0, - last_epoch_total_lamports: 0, - }; - - let mut validator_list = ValidatorList::new(max_validators); - validator_list.validators = vec![]; - - let authorized_voter = Pubkey::new_unique(); - let authorized_withdrawer = Pubkey::new_unique(); - let commission = 1; - - let meta = stake::state::Meta { - rent_exempt_reserve: STAKE_ACCOUNT_RENT_EXEMPTION, - authorized: stake::state::Authorized { - staker: stake_pool_accounts.withdraw_authority, - withdrawer: stake_pool_accounts.withdraw_authority, - }, - lockup: stake::state::Lockup::default(), - }; + let (mut stake_pool, mut validator_list) = stake_pool_accounts.state(); for _ in 0..max_validators { - // create vote account - let vote_pubkey = Pubkey::new_unique(); - vote_account_pubkeys.push(vote_pubkey); - let node_pubkey = Pubkey::new_unique(); - let vote_state = VoteStateVersions::new_current(VoteState::new( - &VoteInit { - node_pubkey, - authorized_voter, - authorized_withdrawer, - commission, - }, - &Clock::default(), - )); - let vote_account = Account::create( - ACCOUNT_RENT_EXEMPTION, - bincode::serialize::(&vote_state).unwrap(), - solana_vote_program::id(), - false, - Epoch::default(), - ); - program_test.add_account(vote_pubkey, vote_account); + vote_account_pubkeys.push(add_vote_account(&mut program_test)); } for vote_account_address in vote_account_pubkeys.iter().take(num_validators as usize) { - // create validator stake account - let stake = stake::state::Stake { - delegation: stake::state::Delegation { - voter_pubkey: *vote_account_address, - stake: stake_amount, - activation_epoch: 0, - deactivation_epoch: u64::MAX, - warmup_cooldown_rate: 0.25, // default - }, - credits_observed: 0, - }; - - let stake_account = Account::create( - stake_amount + STAKE_ACCOUNT_RENT_EXEMPTION, - bincode::serialize::(&stake::state::StakeState::Stake( - meta, stake, - )) - .unwrap(), - stake::program::id(), - false, - Epoch::default(), + add_validator_stake_account( + &mut program_test, + &mut stake_pool, + &mut validator_list, + &stake_pool_pubkey, + &stake_pool_accounts.withdraw_authority, + vote_account_address, + stake_amount, ); - - let (stake_address, _) = - find_stake_program_address(&id(), vote_account_address, &stake_pool_pubkey); - program_test.add_account(stake_address, stake_account); - let active_stake_lamports = stake_amount - MINIMUM_ACTIVE_STAKE; - // add to validator list - validator_list.validators.push(ValidatorStakeInfo { - status: StakeStatus::Active, - vote_account_address: *vote_account_address, - active_stake_lamports, - transient_stake_lamports: 0, - last_update_epoch: 0, - transient_seed_suffix_start: 0, - transient_seed_suffix_end: 0, - }); - - stake_pool.total_lamports += active_stake_lamports; - stake_pool.pool_token_supply += active_stake_lamports; - } - - let mut validator_list_bytes = validator_list.try_to_vec().unwrap(); - - // add extra room if needed - for _ in num_validators..max_validators { - validator_list_bytes.append(&mut ValidatorStakeInfo::default().try_to_vec().unwrap()); } - let reserve_stake_account = Account::create( - stake_amount + STAKE_ACCOUNT_RENT_EXEMPTION, - bincode::serialize::(&stake::state::StakeState::Initialized( - meta, - )) - .unwrap(), - stake::program::id(), - false, - Epoch::default(), - ); - program_test.add_account( - stake_pool_accounts.reserve_stake.pubkey(), - reserve_stake_account, - ); - - let mut stake_pool_bytes = stake_pool.try_to_vec().unwrap(); - // more room for optionals - stake_pool_bytes.extend_from_slice(&Pubkey::default().to_bytes()); - stake_pool_bytes.extend_from_slice(&Pubkey::default().to_bytes()); - let stake_pool_account = Account::create( - ACCOUNT_RENT_EXEMPTION, - stake_pool_bytes, - id(), - false, - Epoch::default(), + add_reserve_stake_account( + &mut program_test, + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.withdraw_authority, + stake_amount, ); - program_test.add_account(stake_pool_pubkey, stake_pool_account); - - let validator_list_account = Account::create( - ACCOUNT_RENT_EXEMPTION, - validator_list_bytes, - id(), - false, - Epoch::default(), + add_stake_pool_account( + &mut program_test, + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool, ); - program_test.add_account( - stake_pool_accounts.validator_list.pubkey(), - validator_list_account, + add_validator_list_account( + &mut program_test, + &stake_pool_accounts.validator_list.pubkey(), + &validator_list, + max_validators, ); - let mut mint_vec = vec![0u8; Mint::LEN]; - let mint = Mint { - mint_authority: COption::Some(stake_pool_accounts.withdraw_authority), - supply: stake_pool.pool_token_supply, - decimals: 9, - is_initialized: true, - freeze_authority: COption::None, - }; - Pack::pack(mint, &mut mint_vec).unwrap(); - let stake_pool_mint = Account::create( - ACCOUNT_RENT_EXEMPTION, - mint_vec, - spl_token::id(), - false, - Epoch::default(), + add_mint_account( + &mut program_test, + &stake_pool_accounts.pool_mint.pubkey(), + &stake_pool_accounts.withdraw_authority, + stake_pool.pool_token_supply, ); - program_test.add_account(stake_pool_accounts.pool_mint.pubkey(), stake_pool_mint); - - let mut fee_account_vec = vec![0u8; SplAccount::LEN]; - let fee_account_data = SplAccount { - mint: stake_pool_accounts.pool_mint.pubkey(), - owner: stake_pool_accounts.manager.pubkey(), - amount: 0, - delegate: COption::None, - state: SplAccountState::Initialized, - is_native: COption::None, - delegated_amount: 0, - close_authority: COption::None, - }; - Pack::pack(fee_account_data, &mut fee_account_vec).unwrap(); - let fee_account = Account::create( - ACCOUNT_RENT_EXEMPTION, - fee_account_vec, - spl_token::id(), - false, - Epoch::default(), + add_token_account( + &mut program_test, + &stake_pool_accounts.pool_fee_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &stake_pool_accounts.manager.pubkey(), ); - program_test.add_account(stake_pool_accounts.pool_fee_account.pubkey(), fee_account); let mut context = program_test.start_with_context().await; @@ -604,6 +434,7 @@ async fn add_validator_to_pool() { &context.payer, &context.last_blockhash, &transient_stake_address, + &stake_address, &test_vote_address, increase_amount, transient_stake_seed, diff --git a/program/tests/increase.rs b/program/tests/increase.rs index 6ab04762..13f55564 100644 --- a/program/tests/increase.rs +++ b/program/tests/increase.rs @@ -103,6 +103,7 @@ async fn success() { &payer, &recent_blockhash, &validator_stake.transient_stake_account, + &validator_stake.stake_account, &validator_stake.vote.pubkey(), increase_amount, validator_stake.transient_stake_seed, @@ -161,6 +162,7 @@ async fn fail_with_wrong_withdraw_authority() { &stake_pool_accounts.validator_list.pubkey(), &stake_pool_accounts.reserve_stake.pubkey(), &validator_stake.transient_stake_account, + &validator_stake.stake_account, &validator_stake.vote.pubkey(), reserve_lamports / 2, validator_stake.transient_stake_seed, @@ -207,6 +209,7 @@ async fn fail_with_wrong_validator_list() { &wrong_validator_list, &stake_pool_accounts.reserve_stake.pubkey(), &validator_stake.transient_stake_account, + &validator_stake.stake_account, &validator_stake.vote.pubkey(), reserve_lamports / 2, validator_stake.transient_stake_seed, @@ -259,6 +262,7 @@ async fn fail_with_unknown_validator() { &stake_pool_accounts.validator_list.pubkey(), &stake_pool_accounts.reserve_stake.pubkey(), &unknown_stake.transient_stake_account, + &unknown_stake.stake_account, &unknown_stake.vote.pubkey(), reserve_lamports / 2, unknown_stake.transient_stake_seed, @@ -300,6 +304,7 @@ async fn fail_increase_twice() { &payer, &recent_blockhash, &validator_stake.transient_stake_account, + &validator_stake.stake_account, &validator_stake.vote.pubkey(), reserve_lamports / 3, validator_stake.transient_stake_seed, @@ -320,8 +325,9 @@ async fn fail_increase_twice() { &mut banks_client, &payer, &recent_blockhash, - &validator_stake.stake_account, &transient_stake_address, + &validator_stake.stake_account, + &validator_stake.vote.pubkey(), reserve_lamports / 4, transient_stake_seed, ) @@ -330,7 +336,7 @@ async fn fail_increase_twice() { .unwrap(); match error { TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { - let program_error = StakePoolError::ValidatorNotFound as u32; + let program_error = StakePoolError::TransientAccountInUse as u32; assert_eq!(error_index, program_error); } _ => panic!("Wrong error"), @@ -354,6 +360,7 @@ async fn fail_with_small_lamport_amount() { &payer, &recent_blockhash, &validator_stake.transient_stake_account, + &validator_stake.stake_account, &validator_stake.vote.pubkey(), MINIMUM_ACTIVE_STAKE - 1, validator_stake.transient_stake_seed, @@ -385,6 +392,7 @@ async fn fail_overdraw_reserve() { &payer, &recent_blockhash, &validator_stake.transient_stake_account, + &validator_stake.stake_account, &validator_stake.vote.pubkey(), reserve_lamports, validator_stake.transient_stake_seed, @@ -398,3 +406,6 @@ async fn fail_overdraw_reserve() { _ => panic!("Wrong error occurs while overdrawing reserve stake"), } } + +#[tokio::test] +async fn fail_with_force_destaked_validator() {} diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index 1268ab7f..21ba0f3d 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -351,6 +351,7 @@ async fn merge_into_validator_stake() { &context.payer, &context.last_blockhash, &stake_account.transient_stake_account, + &stake_account.stake_account, &stake_account.vote.pubkey(), reserve_lamports / stake_accounts.len() as u64, stake_account.transient_stake_seed, @@ -768,8 +769,8 @@ async fn check_ignored_hijacked_transient_stake( ), stake::instruction::initialize( &transient_stake_address, - &hijack_authorized.unwrap_or(&Authorized::auto(&withdraw_authority)), - &hijack_lockup.unwrap_or(&Lockup::default()), + hijack_authorized.unwrap_or(&Authorized::auto(&withdraw_authority)), + hijack_lockup.unwrap_or(&Lockup::default()), ), instruction::update_stake_pool_balance( &id(), @@ -834,4 +835,4 @@ async fn check_ignored_hijacked_transient_stake( async fn fail_with_uninitialized_validator_list() {} // TODO #[tokio::test] -async fn fail_with_wrong_stake_state() {} // TODO +async fn success_with_force_destaked_validator() {} diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 0f1f41d7..aec2b983 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -435,6 +435,7 @@ async fn fail_with_activating_transient_stake() { &context.payer, &context.last_blockhash, &validator_stake.transient_stake_account, + &validator_stake.stake_account, &validator_stake.vote.pubkey(), 2_000_000_000, validator_stake.transient_stake_seed, @@ -700,6 +701,7 @@ async fn success_with_hijacked_transient_account() { &context.payer, &context.last_blockhash, &validator_stake.transient_stake_account, + &validator_stake.stake_account, &validator_stake.vote.pubkey(), increase_amount, validator_stake.transient_stake_seed, diff --git a/program/tests/withdraw_sol.rs b/program/tests/withdraw_sol.rs index 4d42d0ba..82686de9 100644 --- a/program/tests/withdraw_sol.rs +++ b/program/tests/withdraw_sol.rs @@ -195,6 +195,7 @@ async fn fail_overdraw_reserve() { &context.payer, &context.last_blockhash, &validator_stake.transient_stake_account, + &validator_stake.stake_account, &validator_stake.vote.pubkey(), TEST_STAKE_AMOUNT - stake_rent, validator_stake.transient_stake_seed, From 7bd8aa739cd7015750ef177ee8730c4f63f54289 Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Wed, 25 May 2022 08:40:30 +0900 Subject: [PATCH 0242/1076] bump solana to v1.10.19 (#3195) * bump solana to v1.10.19 * update solana-version.sh --- clients/cli/Cargo.toml | 18 +++++++++--------- program/Cargo.toml | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 5db39645..261a32ab 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -14,15 +14,15 @@ clap = "2.33.3" serde = "1.0.130" serde_derive = "1.0.130" serde_json = "1.0.68" -solana-account-decoder = "=1.10.15" -solana-clap-utils = "=1.10.15" -solana-cli-config = "=1.10.15" -solana-cli-output = "=1.10.15" -solana-client = "=1.10.15" -solana-logger = "=1.10.15" -solana-program = "=1.10.15" -solana-remote-wallet = "=1.10.15" -solana-sdk = "=1.10.15" +solana-account-decoder = "=1.10.19" +solana-clap-utils = "=1.10.19" +solana-cli-config = "=1.10.19" +solana-cli-output = "=1.10.19" +solana-client = "=1.10.19" +solana-logger = "=1.10.19" +solana-program = "=1.10.19" +solana-remote-wallet = "=1.10.19" +solana-sdk = "=1.10.19" spl-associated-token-account = { version = "=1.0.5", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "=0.6.4", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "=3.3.0", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/program/Cargo.toml b/program/Cargo.toml index 968a074e..706735c7 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -19,7 +19,7 @@ num-traits = "0.2" num_enum = "0.5.4" serde = "1.0.130" serde_derive = "1.0.103" -solana-program = "1.10.15" +solana-program = "1.10.19" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-token = { version = "3.3", path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" @@ -27,9 +27,9 @@ bincode = "1.3.1" [dev-dependencies] proptest = "1.0" -solana-program-test = "1.10.15" -solana-sdk = "1.10.15" -solana-vote-program = "1.10.15" +solana-program-test = "1.10.19" +solana-sdk = "1.10.19" +solana-vote-program = "1.10.19" [lib] crate-type = ["cdylib", "lib"] From de0b6437751f327a6f66435e2a17b3f4d1f4986e Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 16 Jun 2022 15:39:55 +0200 Subject: [PATCH 0243/1076] CI: Add `--max-warnings 0` to eslint to abort on errors (#3254) * CI: Add `--max-warnings 0` to eslint to abort on errors * Fix lint issue --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 88deae7d..e2bc8021 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -4,7 +4,7 @@ "description": "SPL Stake Pool Program JS API", "scripts": { "build": "npm run clean && tsc && cross-env NODE_ENV=production rollup -c", - "lint": "eslint .", + "lint": "eslint --max-warnings 0 .", "lint:fix": "eslint . --fix", "test": "jest", "test:watch": "jest --watch", From 416ddf1a7a0a0268943030fa179ef82ff535123a Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Mon, 20 Jun 2022 09:55:49 +0900 Subject: [PATCH 0244/1076] bump solana to v1.10.26 (#3274) --- clients/cli/Cargo.toml | 18 +++++++++--------- program/Cargo.toml | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 261a32ab..6ba20cff 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -14,15 +14,15 @@ clap = "2.33.3" serde = "1.0.130" serde_derive = "1.0.130" serde_json = "1.0.68" -solana-account-decoder = "=1.10.19" -solana-clap-utils = "=1.10.19" -solana-cli-config = "=1.10.19" -solana-cli-output = "=1.10.19" -solana-client = "=1.10.19" -solana-logger = "=1.10.19" -solana-program = "=1.10.19" -solana-remote-wallet = "=1.10.19" -solana-sdk = "=1.10.19" +solana-account-decoder = "=1.10.26" +solana-clap-utils = "=1.10.26" +solana-cli-config = "=1.10.26" +solana-cli-output = "=1.10.26" +solana-client = "=1.10.26" +solana-logger = "=1.10.26" +solana-program = "=1.10.26" +solana-remote-wallet = "=1.10.26" +solana-sdk = "=1.10.26" spl-associated-token-account = { version = "=1.0.5", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "=0.6.4", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "=3.3.0", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/program/Cargo.toml b/program/Cargo.toml index 706735c7..9220479c 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -19,7 +19,7 @@ num-traits = "0.2" num_enum = "0.5.4" serde = "1.0.130" serde_derive = "1.0.103" -solana-program = "1.10.19" +solana-program = "1.10.26" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-token = { version = "3.3", path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" @@ -27,9 +27,9 @@ bincode = "1.3.1" [dev-dependencies] proptest = "1.0" -solana-program-test = "1.10.19" -solana-sdk = "1.10.19" -solana-vote-program = "1.10.19" +solana-program-test = "1.10.26" +solana-sdk = "1.10.26" +solana-vote-program = "1.10.26" [lib] crate-type = ["cdylib", "lib"] From a1bcca9381aac3203d1763815ee996564f111b22 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 1 Jul 2022 22:51:01 +0200 Subject: [PATCH 0245/1076] Update Solana crates to 1.10.29 (#3303) --- clients/cli/Cargo.toml | 18 +++++++++--------- program/Cargo.toml | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 6ba20cff..a182d84a 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -14,15 +14,15 @@ clap = "2.33.3" serde = "1.0.130" serde_derive = "1.0.130" serde_json = "1.0.68" -solana-account-decoder = "=1.10.26" -solana-clap-utils = "=1.10.26" -solana-cli-config = "=1.10.26" -solana-cli-output = "=1.10.26" -solana-client = "=1.10.26" -solana-logger = "=1.10.26" -solana-program = "=1.10.26" -solana-remote-wallet = "=1.10.26" -solana-sdk = "=1.10.26" +solana-account-decoder = "=1.10.29" +solana-clap-utils = "=1.10.29" +solana-cli-config = "=1.10.29" +solana-cli-output = "=1.10.29" +solana-client = "=1.10.29" +solana-logger = "=1.10.29" +solana-program = "=1.10.29" +solana-remote-wallet = "=1.10.29" +solana-sdk = "=1.10.29" spl-associated-token-account = { version = "=1.0.5", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "=0.6.4", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "=3.3.0", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/program/Cargo.toml b/program/Cargo.toml index 9220479c..9ba05079 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -19,7 +19,7 @@ num-traits = "0.2" num_enum = "0.5.4" serde = "1.0.130" serde_derive = "1.0.103" -solana-program = "1.10.26" +solana-program = "1.10.29" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-token = { version = "3.3", path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" @@ -27,9 +27,9 @@ bincode = "1.3.1" [dev-dependencies] proptest = "1.0" -solana-program-test = "1.10.26" -solana-sdk = "1.10.26" -solana-vote-program = "1.10.26" +solana-program-test = "1.10.29" +solana-sdk = "1.10.29" +solana-vote-program = "1.10.29" [lib] crate-type = ["cdylib", "lib"] From 7d5c54d09f3ee00b8a57c26088a6b3275394c255 Mon Sep 17 00:00:00 2001 From: Pranjal Paliwal Date: Sat, 23 Jul 2022 00:25:17 +0400 Subject: [PATCH 0246/1076] [stake-pool] instruction to add metadata for pool token (#3335) * instruction to add metadata for pool token * add documentation for instruction accounts * address pull request comments * added more tests for update pool token instruction * add check for payer signature --- program/Cargo.toml | 1 + program/src/error.rs | 3 + program/src/instruction.rs | 113 ++++++++ program/src/processor.rs | 224 +++++++++++++++ program/tests/create_pool_token_metadata.rs | 276 +++++++++++++++++++ program/tests/fixtures/mpl_token_metadata.so | Bin 0 -> 383568 bytes program/tests/helpers/mod.rs | 18 ++ program/tests/update_pool_token_metadata.rs | 198 +++++++++++++ 8 files changed, 833 insertions(+) create mode 100644 program/tests/create_pool_token_metadata.rs create mode 100755 program/tests/fixtures/mpl_token_metadata.so create mode 100644 program/tests/update_pool_token_metadata.rs diff --git a/program/Cargo.toml b/program/Cargo.toml index 9ba05079..46a69c93 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -14,6 +14,7 @@ test-bpf = [] [dependencies] arrayref = "0.3.6" borsh = "0.9" +mpl-token-metadata = { version = "1.3.1", features = [ "no-entrypoint" ] } num-derive = "0.3" num-traits = "0.2" num_enum = "0.5.4" diff --git a/program/src/error.rs b/program/src/error.rs index 8ffa32e1..908b947d 100644 --- a/program/src/error.rs +++ b/program/src/error.rs @@ -132,6 +132,9 @@ pub enum StakePoolError { /// Too much SOL withdrawn from the stake pool's reserve account #[error("SolWithdrawalTooLarge")] SolWithdrawalTooLarge, + /// Provided metadata account does not match metadata account derived for pool mint + #[error("InvalidMetadataAccount")] + InvalidMetadataAccount, } impl From for ProgramError { fn from(e: StakePoolError) -> Self { diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 85c81a47..04353fbb 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -1,6 +1,7 @@ //! Instruction types #![allow(clippy::too_many_arguments)] + use { crate::{ find_deposit_authority_program_address, find_stake_program_address, @@ -9,6 +10,7 @@ use { MAX_VALIDATORS_TO_UPDATE, }, borsh::{BorshDeserialize, BorshSchema, BorshSerialize}, + mpl_token_metadata::pda::find_metadata_account, solana_program::{ instruction::{AccountMeta, Instruction}, pubkey::Pubkey, @@ -374,6 +376,48 @@ pub enum StakePoolInstruction { /// 11. `[]` Token program id /// 12. `[s]` (Optional) Stake pool sol withdraw authority WithdrawSol(u64), + + /// Create token metadata for the stake-pool token in the + /// metaplex-token program + /// 0. `[]` Stake pool + /// 1. `[s]` Manager + /// 2. `[]` Stake pool withdraw authority + /// 3. `[]` Pool token mint account + /// 4. `[s, w]` Payer for creation of token metadata account + /// 5. `[w]` Token metadata account + /// 6. `[]` Metadata program id + /// 7. `[]` System program id + /// 8. `[]` Rent sysvar + CreateTokenMetadata { + #[allow(dead_code)] + /// Token name + name: String, + #[allow(dead_code)] + /// Token symbol e.g. stkSOL + symbol: String, + /// URI of the uploaded metadata of the spl-token + #[allow(dead_code)] + uri: String, + }, + /// Update token metadata for the stake-pool token in the + /// metaplex-token program + /// + /// 0. `[]` Stake pool + /// 1. `[s]` Manager + /// 2. `[]` Stake pool withdraw authority + /// 3. `[w]` Token metadata account + /// 4. `[]` Metadata program id + UpdateTokenMetadata { + #[allow(dead_code)] + /// Token name + name: String, + #[allow(dead_code)] + /// Token symbol e.g. stkSOL + symbol: String, + /// URI of the uploaded metadata of the spl-token + #[allow(dead_code)] + uri: String, + }, } /// Creates an 'initialize' instruction. @@ -1276,3 +1320,72 @@ pub fn set_funding_authority( .unwrap(), } } + +/// Creates an instruction to update metadata in the mpl token metadata program account for +/// the pool token +pub fn update_token_metadata( + program_id: &Pubkey, + stake_pool: &Pubkey, + manager: &Pubkey, + pool_mint: &Pubkey, + name: String, + symbol: String, + uri: String, +) -> Instruction { + let (stake_pool_withdraw_authority, _) = + find_withdraw_authority_program_address(program_id, stake_pool); + let (token_metadata, _) = find_metadata_account(pool_mint); + + let accounts = vec![ + AccountMeta::new_readonly(*stake_pool, false), + AccountMeta::new_readonly(*manager, true), + AccountMeta::new_readonly(stake_pool_withdraw_authority, false), + AccountMeta::new(token_metadata, false), + AccountMeta::new_readonly(mpl_token_metadata::id(), false), + ]; + + Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::UpdateTokenMetadata { name, symbol, uri } + .try_to_vec() + .unwrap(), + } +} + +/// Creates an instruction to create metadata using the mpl token metadata program for +/// the pool token +pub fn create_token_metadata( + program_id: &Pubkey, + stake_pool: &Pubkey, + manager: &Pubkey, + pool_mint: &Pubkey, + payer: &Pubkey, + name: String, + symbol: String, + uri: String, +) -> Instruction { + let (stake_pool_withdraw_authority, _) = + find_withdraw_authority_program_address(program_id, stake_pool); + let (token_metadata, _) = find_metadata_account(pool_mint); + + let accounts = vec![ + AccountMeta::new_readonly(*stake_pool, false), + AccountMeta::new_readonly(*manager, true), + AccountMeta::new_readonly(stake_pool_withdraw_authority, false), + AccountMeta::new_readonly(*pool_mint, false), + AccountMeta::new(*payer, true), + AccountMeta::new(token_metadata, false), + AccountMeta::new_readonly(mpl_token_metadata::id(), false), + AccountMeta::new_readonly(system_program::id(), false), + AccountMeta::new_readonly(sysvar::rent::id(), false), + ]; + + Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::CreateTokenMetadata { name, symbol, uri } + .try_to_vec() + .unwrap(), + } +} diff --git a/program/src/processor.rs b/program/src/processor.rs index 2b194e2b..d26c4efb 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -13,6 +13,11 @@ use { AUTHORITY_DEPOSIT, AUTHORITY_WITHDRAW, MINIMUM_ACTIVE_STAKE, TRANSIENT_STAKE_SEED_PREFIX, }, borsh::{BorshDeserialize, BorshSerialize}, + mpl_token_metadata::{ + instruction::{create_metadata_accounts_v3, update_metadata_accounts_v2}, + pda::find_metadata_account, + state::DataV2, + }, num_traits::FromPrimitive, solana_program::{ account_info::{next_account_info, AccountInfo}, @@ -89,6 +94,19 @@ fn check_transient_stake_address( } } +/// Check mpl metadata account address for the pool mint +fn check_mpl_metadata_account_address( + metadata_address: &Pubkey, + pool_mint: &Pubkey, +) -> Result<(), ProgramError> { + let (metadata_account_pubkey, _) = find_metadata_account(pool_mint); + if metadata_account_pubkey != *metadata_address { + Err(StakePoolError::InvalidMetadataAccount.into()) + } else { + Ok(()) + } +} + /// Check system program address fn check_system_program(program_id: &Pubkey) -> Result<(), ProgramError> { if *program_id != system_program::id() { @@ -117,6 +135,34 @@ fn check_stake_program(program_id: &Pubkey) -> Result<(), ProgramError> { } } +/// Check mpl metadata program +fn check_mpl_metadata_program(program_id: &Pubkey) -> Result<(), ProgramError> { + if *program_id != mpl_token_metadata::id() { + msg!( + "Expected mpl metadata program {}, received {}", + mpl_token_metadata::id(), + program_id + ); + Err(ProgramError::IncorrectProgramId) + } else { + Ok(()) + } +} + +/// Check rent sysvar correctness +fn check_rent_sysvar(sysvar_key: &Pubkey) -> Result<(), ProgramError> { + if *sysvar_key != solana_program::sysvar::rent::id() { + msg!( + "Expected rent sysvar {}, received {}", + solana_program::sysvar::rent::id(), + sysvar_key + ); + Err(ProgramError::InvalidArgument) + } else { + Ok(()) + } +} + /// Check account owner is the given program fn check_account_owner( account_info: &AccountInfo, @@ -2676,6 +2722,175 @@ impl Processor { Ok(()) } + #[inline(never)] + fn process_create_pool_token_metadata( + program_id: &Pubkey, + accounts: &[AccountInfo], + name: String, + symbol: String, + uri: String, + ) -> ProgramResult { + let account_info_iter = &mut accounts.iter(); + let stake_pool_info = next_account_info(account_info_iter)?; + let manager_info = next_account_info(account_info_iter)?; + let withdraw_authority_info = next_account_info(account_info_iter)?; + let pool_mint_info = next_account_info(account_info_iter)?; + let payer_info = next_account_info(account_info_iter)?; + let metadata_info = next_account_info(account_info_iter)?; + let mpl_token_metadata_program_info = next_account_info(account_info_iter)?; + let system_program_info = next_account_info(account_info_iter)?; + let rent_sysvar_info = next_account_info(account_info_iter)?; + + if !payer_info.is_signer { + msg!("Payer did not sign metadata creation"); + return Err(StakePoolError::SignatureMissing.into()); + } + + check_system_program(system_program_info.key)?; + check_rent_sysvar(rent_sysvar_info.key)?; + check_account_owner(payer_info, &system_program::id())?; + check_account_owner(stake_pool_info, program_id)?; + check_mpl_metadata_program(mpl_token_metadata_program_info.key)?; + + let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; + if !stake_pool.is_valid() { + return Err(StakePoolError::InvalidState.into()); + } + + stake_pool.check_manager(manager_info)?; + stake_pool.check_authority_withdraw( + withdraw_authority_info.key, + program_id, + stake_pool_info.key, + )?; + stake_pool.check_mint(pool_mint_info)?; + check_mpl_metadata_account_address(metadata_info.key, &stake_pool.pool_mint)?; + + // Token mint authority for stake-pool token is stake-pool withdraw authority + let token_mint_authority = withdraw_authority_info; + + let new_metadata_instruction = create_metadata_accounts_v3( + *mpl_token_metadata_program_info.key, + *metadata_info.key, + *pool_mint_info.key, + *token_mint_authority.key, + *payer_info.key, + *token_mint_authority.key, + name, + symbol, + uri, + None, + 0, + true, + true, + None, + None, + None, + ); + + let (_, stake_withdraw_bump_seed) = + crate::find_withdraw_authority_program_address(program_id, stake_pool_info.key); + + let token_mint_authority_signer_seeds: &[&[_]] = &[ + &stake_pool_info.key.to_bytes()[..32], + AUTHORITY_WITHDRAW, + &[stake_withdraw_bump_seed], + ]; + + invoke_signed( + &new_metadata_instruction, + &[ + metadata_info.clone(), + pool_mint_info.clone(), + withdraw_authority_info.clone(), + payer_info.clone(), + withdraw_authority_info.clone(), + system_program_info.clone(), + rent_sysvar_info.clone(), + mpl_token_metadata_program_info.clone(), + ], + &[token_mint_authority_signer_seeds], + )?; + + Ok(()) + } + + #[inline(never)] + fn process_update_pool_token_metadata( + program_id: &Pubkey, + accounts: &[AccountInfo], + name: String, + symbol: String, + uri: String, + ) -> ProgramResult { + let account_info_iter = &mut accounts.iter(); + + let stake_pool_info = next_account_info(account_info_iter)?; + let manager_info = next_account_info(account_info_iter)?; + let withdraw_authority_info = next_account_info(account_info_iter)?; + let metadata_info = next_account_info(account_info_iter)?; + let mpl_token_metadata_program_info = next_account_info(account_info_iter)?; + + check_account_owner(stake_pool_info, program_id)?; + + check_mpl_metadata_program(mpl_token_metadata_program_info.key)?; + + let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; + if !stake_pool.is_valid() { + return Err(StakePoolError::InvalidState.into()); + } + + stake_pool.check_manager(manager_info)?; + stake_pool.check_authority_withdraw( + withdraw_authority_info.key, + program_id, + stake_pool_info.key, + )?; + check_mpl_metadata_account_address(metadata_info.key, &stake_pool.pool_mint)?; + + // Token mint authority for stake-pool token is withdraw authority only + let token_mint_authority = withdraw_authority_info; + + let update_metadata_accounts_instruction = update_metadata_accounts_v2( + *mpl_token_metadata_program_info.key, + *metadata_info.key, + *token_mint_authority.key, + None, + Some(DataV2 { + name, + symbol, + uri, + seller_fee_basis_points: 0, + creators: None, + collection: None, + uses: None, + }), + None, + Some(true), + ); + + let (_, stake_withdraw_bump_seed) = + crate::find_withdraw_authority_program_address(program_id, stake_pool_info.key); + + let token_mint_authority_signer_seeds: &[&[_]] = &[ + &stake_pool_info.key.to_bytes()[..32], + AUTHORITY_WITHDRAW, + &[stake_withdraw_bump_seed], + ]; + + invoke_signed( + &update_metadata_accounts_instruction, + &[ + metadata_info.clone(), + withdraw_authority_info.clone(), + mpl_token_metadata_program_info.clone(), + ], + &[token_mint_authority_signer_seeds], + )?; + + Ok(()) + } + /// Processes [SetManager](enum.Instruction.html). #[inline(never)] // needed to avoid stack size violation fn process_set_manager(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { @@ -2916,6 +3131,14 @@ impl Processor { msg!("Instruction: WithdrawSol"); Self::process_withdraw_sol(program_id, accounts, pool_tokens) } + StakePoolInstruction::CreateTokenMetadata { name, symbol, uri } => { + msg!("Instruction: CreateTokenMetadata"); + Self::process_create_pool_token_metadata(program_id, accounts, name, symbol, uri) + } + StakePoolInstruction::UpdateTokenMetadata { name, symbol, uri } => { + msg!("Instruction: UpdateTokenMetadata"); + Self::process_update_pool_token_metadata(program_id, accounts, name, symbol, uri) + } } } } @@ -2964,6 +3187,7 @@ impl PrintProgramError for StakePoolError { StakePoolError::TransientAccountInUse => msg!("Error: Provided validator stake account already has a transient stake account in use"), StakePoolError::InvalidSolWithdrawAuthority => msg!("Error: Provided sol withdraw authority does not match the program's"), StakePoolError::SolWithdrawalTooLarge => msg!("Error: Too much SOL withdrawn from the stake pool's reserve account"), + StakePoolError::InvalidMetadataAccount => msg!("Error: Metadata account derived from pool mint account does not match the one passed to program") } } } diff --git a/program/tests/create_pool_token_metadata.rs b/program/tests/create_pool_token_metadata.rs new file mode 100644 index 00000000..3068df62 --- /dev/null +++ b/program/tests/create_pool_token_metadata.rs @@ -0,0 +1,276 @@ +#![cfg(feature = "test-bpf")] +mod helpers; + +use { + helpers::*, + mpl_token_metadata::{ + state::{MAX_NAME_LENGTH, MAX_SYMBOL_LENGTH, MAX_URI_LENGTH}, + utils::puffed_out_string, + }, + solana_program::{instruction::InstructionError, pubkey::Pubkey}, + solana_program_test::*, + solana_sdk::{ + signature::{Keypair, Signer}, + transaction::{Transaction, TransactionError}, + }, + spl_stake_pool::{ + error::StakePoolError::{AlreadyInUse, SignatureMissing, WrongManager}, + instruction, MINIMUM_RESERVE_LAMPORTS, + }, +}; + +async fn setup() -> (ProgramTestContext, StakePoolAccounts) { + let mut context = program_test_with_metadata_program() + .start_with_context() + .await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) + .await + .unwrap(); + + (context, stake_pool_accounts) +} + +#[tokio::test] +async fn success_create_pool_token_metadata() { + let (mut context, stake_pool_accounts) = setup().await; + + let name = "test_name"; + let symbol = "SYM"; + let uri = "test_uri"; + + let puffed_name = puffed_out_string(&name, MAX_NAME_LENGTH); + let puffed_symbol = puffed_out_string(&symbol, MAX_SYMBOL_LENGTH); + let puffed_uri = puffed_out_string(&uri, MAX_URI_LENGTH); + + let ix = instruction::create_token_metadata( + &spl_stake_pool::id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &context.payer.pubkey(), + name.to_string(), + symbol.to_string(), + uri.to_string(), + ); + + let transaction = Transaction::new_signed_with_payer( + &[ix], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + + context + .banks_client + .process_transaction(transaction) + .await + .unwrap(); + + let metadata = get_metadata_account( + &mut context.banks_client, + &stake_pool_accounts.pool_mint.pubkey(), + ) + .await; + + assert_eq!(metadata.data.name.to_string(), puffed_name); + assert_eq!(metadata.data.symbol.to_string(), puffed_symbol); + assert_eq!(metadata.data.uri.to_string(), puffed_uri); +} + +#[tokio::test] +async fn fail_manager_did_not_sign() { + let (mut context, stake_pool_accounts) = setup().await; + + let name = "test_name"; + let symbol = "SYM"; + let uri = "test_uri"; + + let mut ix = instruction::create_token_metadata( + &spl_stake_pool::id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &context.payer.pubkey(), + name.to_string(), + symbol.to_string(), + uri.to_string(), + ); + ix.accounts[1].is_signer = false; + + let transaction = Transaction::new_signed_with_payer( + &[ix], + Some(&context.payer.pubkey()), + &[&context.payer], + context.last_blockhash, + ); + + let error = context + .banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = SignatureMissing as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while manager signature missing"), + } +} + +#[tokio::test] +async fn fail_wrong_manager_signed() { + let (mut context, stake_pool_accounts) = setup().await; + + let name = "test_name"; + let symbol = "SYM"; + let uri = "test_uri"; + + let random_keypair = Keypair::new(); + let ix = instruction::create_token_metadata( + &spl_stake_pool::id(), + &stake_pool_accounts.stake_pool.pubkey(), + &random_keypair.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &context.payer.pubkey(), + name.to_string(), + symbol.to_string(), + uri.to_string(), + ); + + let transaction = Transaction::new_signed_with_payer( + &[ix], + Some(&context.payer.pubkey()), + &[&context.payer, &random_keypair], + context.last_blockhash, + ); + + let error = context + .banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = WrongManager as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while signing with the wrong manager"), + } +} + +#[tokio::test] +async fn fail_wrong_mpl_metadata_program() { + let (mut context, stake_pool_accounts) = setup().await; + + let name = "test_name"; + let symbol = "SYM"; + let uri = "test_uri"; + + let random_keypair = Keypair::new(); + let mut ix = instruction::create_token_metadata( + &spl_stake_pool::id(), + &stake_pool_accounts.stake_pool.pubkey(), + &random_keypair.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &context.payer.pubkey(), + name.to_string(), + symbol.to_string(), + uri.to_string(), + ); + ix.accounts[7].pubkey = Pubkey::new_unique(); + + let transaction = Transaction::new_signed_with_payer( + &[ix], + Some(&context.payer.pubkey()), + &[&context.payer, &random_keypair], + context.last_blockhash, + ); + + let error = context + .banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, error) => { + assert_eq!(error, InstructionError::IncorrectProgramId); + } + _ => panic!( + "Wrong error occurs while try to create metadata with wrong mpl token metadata program ID" + ), + } +} + +#[tokio::test] +async fn fail_create_metadata_twice() { + let (mut context, stake_pool_accounts) = setup().await; + + let name = "test_name"; + let symbol = "SYM"; + let uri = "test_uri"; + + let ix = instruction::create_token_metadata( + &spl_stake_pool::id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &context.payer.pubkey(), + name.to_string(), + symbol.to_string(), + uri.to_string(), + ); + + let transaction = Transaction::new_signed_with_payer( + &[ix.clone()], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + + let latest_blockhash = context.banks_client.get_latest_blockhash().await.unwrap(); + let transaction_2 = Transaction::new_signed_with_payer( + &[ix], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + latest_blockhash, + ); + + context + .banks_client + .process_transaction(transaction) + .await + .unwrap(); + + let error = context + .banks_client + .process_transaction(transaction_2) + .await + .err() + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = AlreadyInUse as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while trying to create pool token metadata twice"), + } +} diff --git a/program/tests/fixtures/mpl_token_metadata.so b/program/tests/fixtures/mpl_token_metadata.so new file mode 100755 index 0000000000000000000000000000000000000000..f7b3c9f1793e7d33ae892d4036d669974ac774c2 GIT binary patch literal 383568 zcmd?S37l1DeK&pv=E@KoAtaZO8Oi7m+(?X-^47||GlaqBt!Sgcx7NXGEBdxOYD{%e(5`#QB&QKP)y?{7Khxf={i zmij**nCJeU_4oX?=l3kv5-d>)47+L5&B4lP$7cHOS!JoIwx z4cps)yOygDcWAN5!w!Q-rs$7&x`rjA)q5>HK3j9<$Nlyoqh_O_vk~UU{YKzN$45e= zH>2MZk|@eW2PEFhk4)8y;$98w>o50e{iU|w9z<19yj%$wmo+|i{K{JXoe0?1xZlz* zaQs*r@s=-szScv$e!dp*y$U~y!qbqCc(WwaN0FY3{$22Pe9KQEzTZ0xzK=D*xA!T; zclTlN{Y-#wJjMA%DF z$$h|0+WU~?pQq_*{;rn!w=;k5B1@PhLMcrQnB{>qQb z>T&tq6x8GL8>e)#`cgV+eTTy9T|$RqO+Vs8&}~D|ey{0keq3AhEY#rqi>H90c-)S} zCmA2x8tup%QJ>q9c*=Y$=X5dtv>m=5uMhAVOFiUtGy2|9Q;(n%EgLsk`j;PGSbO3-URt7jlfs0jBXqj= zPT3^&lJ2C~1Sprw&3g|XJeZ4qEq3p4@|WS+D1QqA`lRw_cHQmw1QbJa2NNQPr!;PY zgx+qJu5wXAKlspI7a0cjx*P4eJwG1x ~bxl+H%+3~2q9{;nY{`qJX{V;vW`Y+K( zM4x*6r#{L2=y-zp@pw#rKXLpRmHOuk;hzY8{6Okoaop-JqNY$E_DcP$j$8fp^7IAN z@Al-$(C<%5e`w8~82$K&)c?fE(?e4K{3i_m%~JmpCr|H^`ky#?S}*nMxO6=9tq4ko z`f!)jzvT&||81y0)rZ;AOyqh|zD(h3FwSzM%(tB^Vfp;}_(>8!0fREKMiVf;F&we- zBNu3X_N$1W^oJkW5=G1LoABKh<|7?P^Bmam z1?hd3p7!fnDH`CM2z5j+cG5+@UPk%8f>`vpKxoX*m8UN2;dBasnVVA^@R2ZZF$~^cDBUOVz)Lno{ zkN3S9_F>yR$sa#7zoFb5mU}?UG5`I{zkQD8AMR?%KMncgs`i)p-;Vr`8hw(&u;gdI zA3B>Jo<2!oi^M1QZPIY_Mh$PMf9nK3z%sz#5owcQruKDOjDM&f==X(6e?8_@8x;*@0!RJtP zSbh)XrJfEtFN!PHZTc<_MIr8+8MSl>=7|Ax0kQQ7*P zGyMqp_#)zEcE|N3PU-#utN(KnCY_rM{*=MSm+Hq2-XLMW=|@~qIGL*Siz}KxnX2>N zxT5tXQR}E-9DI{s`=QTaGdk}VgExp zZdFgJ|4X#qkxMMJewL^2l!y}6C&22Oad;76*AuTNwsDs8zmFq*WV#fOeB284@sSTS z>SHPTPoeWjSZa_*d`j)gC8{bPDo~ibtlp81M@l3TF`P>Nt`#9nG z9z|WmeC{H}KQ3ziKgy{=n5NNeGI|OAC)4F;>M!^;>@n?u$fe~=*JCcydVL-H zjCS@qieB|H_4nd)6z?-G)O@dcnWm?59pG^t%H^W}EA$BQd#S`L|9zeRj2pb2UrPR5 zr0GfL0)dmlBCQ9_*7$$-seDX>I@kCioA+pbpk3pKtlh2gSl+7fLvB<19NMoXl*cN2 z4}TE-a{q7fy`Ue^CFR|2QGO28_*FZk9p)pYl7iY9=BxF;HcGzCe;GD-iG-P-r*fBU z9@Y4@`!&2x^&!N2MIGK72@kOs=m(H?|A}%yJ^QZ>lEmT*h5VTuZIOB@AEPyLr1VbQzhA3#PHt0vWq!NzE0ecXX??ZwwnF<+ znJ-~d*kSNIgNG#y@fEuq=mF)6{G^2)K_B?A{|}2Cjaof>tls?w?>2a!!MhCJYw%79 z%i9iE{2UFZX#F8RJFWeqwY%>x8|5kU!@H!OvHRhg|FC|zjk_b~D1MVJ)X?R4?&T_% zg!wE+$e*P)N;Bld)~QF#Pgo8+#q_z?XaSeonGj6ck4KTtFyChD^0xrMt#nHY zM*mKwyN`E{M^e!Eke+)$&(J=IA82yy^^?EfM|-i&6X<6U)3~bqER9pVnD6#?s63$B zgFb#IcMS%GQ^NH&LH^ zfp)?PI~c1^lL2i?Kn#MhUJc)zNQzg>`oK={&7Qqa%O9;hdsM4Q>7Viq z#O*@WpbFr-lrF>L&Vm#9ytd~{0oy$+Gvv0?GzD2#Sl>Ew1 zpU>6z!^cx!$MJrR3`n(6@(k?<`_0GK9g@3%5FTHDaD9kpSii?BUMyEYKDQ(6$F;y~ z#OPO=@LZ{-hf%guQ2)s5@qG!>jU-BZ9_RB?M6S5eoC~Jgz69q5TmDmJiwz|O zwToeU+oV197sB{q#5bGAUIls)uW6`{^d?0}@6$o=Ql#UBpC@6y*Td%Dekyb8`qGNx z>t4g(#g(sJm7J>lC7#P}E#ATSWv^X+XL732nenC9F2f2;6s=m;hj{*K-u^SCeeG*A z{ALAwW;*31nXK(6leN8Ml~iBj&kcYM>?bvA1aiP<8k*VPm(iR3|F5^vjtq#r#MKQF zrt8{MwSKmXf03^<<|3V_`1-EnssdfIrd*jH=uve=fC9{l0EA0ez)M~^Q2VY zuF>=nHFL5q!Scy9idTNT&M!*iPe|M4k7SyrV|_^CXSQFY>sclTA^v|~gTFSIi+&{d zJc{9o{7Y`zsrXf-IytAr`H#oS@aWIp^-6|)hA8|$JBS{lEl==M_^kk#R;R>lY zuCCJh=V*n_r(}hogK_U;@`HZQZ_uCKbMXU@+Xt?%Q4153)8xK6QeS@JUr0Xoo5o}0 z&jgI--mm4!N5;>5hVExMUq`H6pGS?X({iDFyiw?Ol_WGv|MNhu+5VGd|85t&bO3uQ z?C&e2{nqyPt~$Dm)&6pQZ7lZfDv_%tCRaU83Yo+9iV$F|0L!6rkpAHC&2s?5AXK~H?Qz;epWhL|K91^@4muM zrCey5?qVatN?Qd-RNPfN~-nK={ZQrD!?GummXnU`k_IZg9`7CyPy{5AtTYro3 zaf`}HJgjn)i#{#oD93!BRp00Q$-hYIQJHvw0ML|1+fDr8ZTB6o12)FeR^j8$GMt|i%gFGMU{Nm%_3+YCQAivmC(&ydaYbly39epasw>L@qt;e^` zfjqgqxgX_z{ISe0R&Jnt3H^0aU^_YLBQ;q^z&Hcb^v@Je@{V8hnlY+eCy%$DU;h53tpUu z{F39vg^I85_i=q_BKdKFWW)J2wZr5qb2{H$4sy|Dl9BL}H9zSm6R)xQ=c~rZ?@tN8SDBq!BcY$uI+FIry590P(%zx%BHP8kbiK2| z&W*v}c^Guf{GE$axvKYf{xP8M(fd2P;$E`#XO92=kh8vSn~QoSI7Vyt#|(HQKm z>xG~5&qX?~JeF}`ta|&0W6;~a)Spp%)?4|E*b|OBeEQ5E@0+UWN2Ay0*XZ>nQm^wP z^k4os;MdXXwa;UCI#T79q3d(Tj}As-{CK5=&Gh>h%Q&w7{_FQSE%f`>t2xd-b^85d zX}|S2n+xQ{<;mv<$77!IwYMDJuX1^E`AXL-o`m_zF2V26dNhBh>FN!ydU`^hD23vVBPyA3P<@Pxv&$>-{zOUn=?jJI_x( z2s*Q$_2cz`=#w%$7wLM^v5Z4w9Vc%egC6;QT`u|~p+Dy*zk{DuZZbdN(B$)z{;PGM z5;;bhjPE+}W&D#hFL}Ap_o=g&S4#V>?d8pZ{<$8E#a@neUh-VwbM3sOe*J{);$OON z>~`r$@ENQB^Xw+}vHrf9v7Em+t;RlNa#cSsd453OqxWCN3w=s$&lEi%UHIf8IZ{xw zPvG;ADfe=J;P>B8nbg9r{R_?rJ(YgS*QNc|dN&F=^l|S<z)s_fxX-8hSwC zSnU5;_3*C*zeD>enf=%GCZC7&P0fk?_g3_Mx4x-r@6&xcdq22r=dk-bcj&svpsx4F zLwf{HuGVv6$;DjVg8i8_UBYDQX%dQ_LDzizaJ!WHL1S3Ico1@s`9ZDyjlT}$;ppvz zt;@FQIXJ-|q;dQYwQkXc0|@_ruorIwok^E^Kj`MC*j`+B7<+MBARkYJy}0zK?8TF} zZZY$S?1kFhve^e;x9FcGY7IX_2hdcXXKQ?_*Q<3MpfpbHg3~*kx13g^*O#UCqG9|G z_!jH5Bl7zv`V0DAEzkMDtv#6VU=ALxw-duemql<6-1R!xKdRB|6;iH#y&^m>@W`)2 z{non_%fo6v4^?jBJkM)oZ;2-tzaQk3? zDfn&B@xQA6Mm>J+XSh9BS@{Rae|up_!qm^O`$fu?&q{p1`5BqtF)Hzy-*G_Tcu@U~ zcu4(^dOsssxLxuk-Fi=hpNEaBJ0!k$Xp4j^w<Hbxkxv%IX{0Ke2LGMPr`a$QPcnHq`_RI=c4@lnZM^hVs@T-w-Pi6?F--2^!FCRd@p@B z^=PN?rPMY{=-~TB>3uZzzFg9|Lh>d4-mBeflia6znAp7>ejeBP?&o*?{v5`W-hPgE zWSi1)0{9_#Rt<)pZ6V%9?`dG$qFZyCh`;P-AI?99{iOW}$DiMVzNP3@QYJm8VdrmL z-u+yETv2)V_sEH7y}x!Y_))U+7QU~Z+@<5AzgLmGMH%n?&qaT1?W-R8I)|_4`}(l+ zq1id$CFmFBB9EF5wf{bec4u3U@F^Z%qM_Nx^!`(`o6YV&orL~5{@$Nlbb;W{{ybUh zSC8YIVM(kk_43KzSO1B$Ppi?~Z=cXaZ=J8s&t~V678oB7H-3EM9_r-+$Pvq#_^FkT5oE< z*QuP(#Cr?0sFaU-KlIa}V`jhg9Bs3F--X<|zmVGV_1a$V3=RDpJN;I2CNX^S<6kcs zlG{}7S$_#JBf4!L%{?Cxcz7P2@kzJZtA=yxDaP+JC#3I2|9Rs69{Z z@sy&}liKSkDtLT-kL^1CK29x1Bum_FVLYt(##NO&e_uWqJzwf=cJ6vN`t9R2V zum^U&&(ACSIGt~Mw%`$0l}_<=8;|ULwRk!zz~kduY<`!I%kgwcM*6VO)$d_S&r_eK z_vnOt;d)!@cbJ|L&j(>}M*6hAc#HBg-md)3MS3oq@<@HEKfmSoJo&uM?OJ+Hp{n|w ztY>MpH>e8!nSj`b(SF8Nm9ISRXXfMgOy%3uuj6^_F2v`@*?JX>m+SZQpjSCLb;fdv zckJz^a-sDnsoZEk-A`oy_&8o}m*YjzDC6^Xk58#x&;8K8&_hg&4u%04tOWzl`NQy^1zsUxZr3{A4MRbeo)x zS3V})%GVhA`6S&-EdP9imEQ4qML6j;xf;)2G5-e3KgZw!gNp{QG1&B?dzHb9EPdGE zB?j*>xX0j~0HTm?_cVc%Zsk{U zoAN7JsPYkx-$m-#5KAlH=?9K%RhaUz`EttZ-%5KUx?LQNoUG~b^_jd8j}p$$@=4`w zhJXU|S1#(4h@^AiH~ay*YFOAPVSGOt#FO1;uKPkEzV2^q3GU5ddn`$RV{hPJ(BGJ| z1b^&de|p}M`2q0_MxV|#+Wrkjr_NOZyB{(EdcgYG4#MN? z%yBPk13$qOkq@25LjU&umhs8jJraiVqFtEahV|}YJ2o$3{T--?^?wlchxqKo`nu1D z!hBna$Nfg1s`8uZMYPX)euVVp_)Yk33-k7#KzKfpB8PMHDko-#a}kUvo)8bgceO-E z{(d~$x$RA@>49}VrAJ}c<186hjXs^b6&~ED>D_x29@?+)!o3P_HN39UekK>8K|G1w z@0R2Rlyv~|f%3!9@6jd92jhqIZ?UEOz4U%>G4K25!~Xo$e`faD-+PSztV_~Eetv>{ zG5(F*BFSPOidN5~pg+eEnCb>Tl%f|&0Ut-p4=fQlKkg4D9El}J`xRGBf2V7Fa-Z_s z-#^ZGoT=q1nohZ-K2RQ3Ad3CE8TgbdD}}E4w(BG#+s8ln4W^d`)z{QdTWj_#sCRdr zeu&-$_D$r~?3?=$Z2v3R>h7)V7XFsnuGICnhYVlnKNo;TdKG5=wcvxp-v6*aSD`<6 zPgeL^p04HcZ8{#s({&#%InDHA`bm-@ISm!#iKnaMnw;kONd?eBi@{G*d*%13E=Dp9 zbiVC!87~%tt}Nkt!}pN*_@EBt!4fbB>%j+{9P^cw=;ibk)=N%<5gT;V&!!_&)$>Mdu&7e z9{&^4=j~E1q|Xb0ztb_JllpnR)gOqw^mUp&82nD1z4)5h3$rI%zo76^vo~ARe)JWe zjaI;iF3#E!&R4%NS)}yuQ?aPAca&?=^<2oI>q9R3qTug((_dI2{T~VBSmeJ~ni0NS zd3CKF9fsY&dbh|e*TXgi@4K_Tcj9P9ynTnH$AiNXhIV)p?T*P1q+I92{C_^5c63H%az>{_7_%Z`nH`KZr>r{q43yRgGaC8v3Ze{ zOV%!tFvI6P20K0*1JF1_A@J*@q2`<&cYoNRXgUj5d% z5=nZw@<9plUa-nXMeE1?L;{C$GL7>;>p$tX>{o!dDgK<-cQL(=PR#c++WkO&WgZ#S z^FmDA!t^zD?R*vO#FaUw7bbs|qQOS*$~1$u-(h{bpf6Zo(*D>yfO0qos1v`FAEdmf z{l`53%D?nG0;2}6u=)=etn>J!p!&=DD8anHaU4TTEh%{;+wlhv*X#BJkMgkUz1#m% zn@+%-uI|t0BArObRmGnE%kZ z+hFr6I`;_N`+)iz@LLof)c%);J|*?^Zq;!nS-L~$nJnC?VfQWxp zzxp4PC#9>W`}!@@KQ8HOq&?n8NPYDC<9mk(B;NP)Lpk&D{ktfii}W4|`ing^-|N^d z_|gvWfu1RU3M$vkza#LgAh((y?mmko_o=)$Yxm4`z;kG_(qroq4Yw@Pu)0OUWY#8W z7k-z)8wKvWOXm~4Rr4PP*J%2Ur%QVB43)>ei&cL5W=*nsR#-hV1TI%s3EV&HJb`(PA|KS$#GW<5{Ss{>a56#|#58?636wse)h{#m;W zR=Mn(^$CO3uJzCQTZ7fE_0RfW2JaQQ=%4j*gVjFv&)RA5eo0Se?J#(b;WKP-m%&>M zE*iYS-~|Q`7~Em-8iVH>yvpEt2Cp!9)Y|Vcc$%dz5jeSek;SXNC9}R|unjFt z61h!gea_&G27k(6)!)8Z`wiY<=|3@8^)H$AbAfwpU%qdaOe46SPVtQT-XdZu>j#8= zob&TCeotgBDoXvK9MkSo|E?ANdA6p{W-YLzwoVo1-^+300!?Q*E*AN@lziJMs<+$K z-o(TEq`vr`4k?fyPiu|*&>23y-okqBd{6DXXD8dSaU)zm>beExt4bHYpSach#pfy6 z`;Y2x_;&^TUXILus@;nR4euedn}_|*2p1%Pm)$es>k#bMAN(oe@0a9k{mcUxG(cMdpChV;J@ z^iS-b)8uVhj_r**HCP`5+zy!ba(=L`n~N@&0=~}5dWkXne`&LNk&b^g>u$uSzTS}; zQf+h%`;B(vt;&zmxC;gU`hG3L_ZZl&+xdJ>`9hfSes5+T-+f^FjAzy1{ilpiHfuZm zg@Yo$+_z-;k>&VQ;4boj3aurIkuVLy-K>qTdoe8BIJ z_IzK-_bo|J;e)Lk5hfo(`Dah5=cJ?WXEo6C9Buz@WTJ#|Jt5@da=;Xw>n^l>=qB?m zMtiJ(vKE_`+Lt)m(a?36Mb(d*;?0$&Z3-4Dd_t$7X-*58!2xA);Q~7s#qg_5D zD>XdpQVspPE%oxh9C#OzZqJJnK(#zl5^zUoA{<*%h{uQVn^AEMJz1Ge; z#e?!hl=9vVU^LahZ?{jWKDIqq^07Rh*xm!mbHg4_9sIu3Z@`rL-BhM($mKFn_rt*A>w#)iNo-O}%7ifIyzg?zqGF|cZaV1&1SNI%P z)E@hN&0LpfP9Hz!a=^kvI!k<2K>6NKE4n_8vD)dHmOn^hr}23 zryQjC0&Xe?htLlcX<|1&D|px2MfVd@c>sNChA!^ukTyN$p89n@U(3E`jHx#Mk@ z%1!JNP)PmZ&@O!+^c%BXs_Q5AHKc=wvP)k_{VnYhkRo2GT>?NpwDRjxyEN_^wM*u= zQeN>dO6L&-@VI|_DErdNpZy<{E7VbAUjQG8T=}^t+5y@Zx1Xi9vjl(o14Na2TSVAQ zZzX;m67huo_FIpK+@sFsa(|rth55w(5PrLjyQw|_sTzF(Tw`BBG_kL!v#EV$r|_iq z)$(6=zQ(71`{fF^@)z7r#aFBSeboE~-k*vpGyhhTvw4&I5zDpyvo5iAFVk?u=EsxF zzc0_!_2kMuw{H-XHjw^OQ zyVt{hvB}h52TT(3d{f8=pU+*x&coh%`@YUx8h>i7TpOKQ>8Ib1>+7WPp!zSw_dMcj z^TkQ$O7}ASt^et{7Nh@JZuhKzi-Y#5$0c1(lJQOath)aBx>92NPRHAYJ7hsB=^oaw zbBl!jou~MEKQE%|ZhlS;_cP17TDZO>=ijQ@AL{=++rM44g!Jsvaoz6Ejcq?7-}Zcw zx3Hci+^-AkfgvLwccW_3Z#-y}+@|Za$$h$B7*`a(eA_z(0rG_|kjo3p{Rnd*Kfhag zhAL9Cd~I*ic4$AD-g_(Gk46P}XuofX?_9>;{l(SG{9G*KU;4T`i;VBRA_Ux`6eG&5|K(Z%*C$AfBfqpTKVE=a)8e-(J^?`wB%_m+h^5 zTf)A=3<+^=TSDv$8LaE7IHzQ=u16<@$pV+{oLPTin!vpkTfZ(GkbbPJJR4ng_g3B`a9`ou25&T2&!vmO-6J&wNLofymRd&c$Tb9`f&n_)R&X{3V;`h~6Z(6(tPmFZ+jq zo{%3Q{r?j5$N6xQh{qta4l!ko=Gvf%^-pPqc%4a1KuMbq=WhRoe~jF<9Ipe2;sLz~$-z#iMhB z!3E2|!r;>kUL|n0pYj@scfR{LAD(0UgSFXrV3u`UC|`nF*0Dj(|K~eCEpHxBuD&^| zR<0JKA31xEaaqTu(V2jk;bU~qMwsu|CEsObx%Zw^TW${0UGE*QL&^UnINtuf-(?;1 z@SF92Qv8&p^T_Rnw|^?+llV=VQ;XjV1N@lo4|f**yF{TLP_Nma5B^{3={JPl%R0`L zn=JDke09l^bx5)-|-<`uj%-RoF``ecg(Kk!vfTwi}XV- z`Hn}$zo1;v^=AHkb@ z{{F*Q9S%0*YC{d=^IzqH#&!iR5*owziu@40n)OFHGEg7lE|{JT2-%s9gK z4i;J8d1-qusgq-#M?Vt$&xh}h`F2|0^)qVi4w^fn`qtyf3*HAz>w8|EoL_bX^@aY| zc{pN-?=q(K9xI+pVA$}z=d`{r)$xsZ=AwVbU$p~|)TJNkcyc4=WVz_)zw`QXb#mw9 zF#Z3r*p)ZHvB*U~PU}0?@#r2HkX)qx9p&`j1N=h05Ai$}y`KoZ&*mu`gbzMn=r8EK zC)vE^ZIYhNTi#*$ecrOsV4t^aGT7%WI<95&mSL;!fcS@fg%1k6vZC|H+Y5hf91)pcBzuQ-Mx$qU|fvmjG%XVA) zJ`dX?u+PKdiu${5FXM{(!%0EkXAJ$caGn;%AML!1pRCG7n^Ji^DX?=-g#3K!UB7?w z(>M;QJUtQP;3^oRTy#rQe$mgW(eqv3_E_B}Q`P|vq|{vHp# zd!6v{+?0>!AH(<^j<*-UG08<|ruBZg&d+!e+I2sJS#QkjSA4zek-pEF$(g>-n#q~IKTUq2`GfvF z^SI1aA>g~ZC}Gl>u2+k_4#&Iwb^Cq0ZU5;L=n(c{C4W3Ts$u#bir#-0)+6^8RHZpN z2SkKuCk`NrbbbTm%IQbDME*Fw_&%-J;p9GDUk~5&-BEX+!!GW7^=dn;-|ur+h5AE$ z`2MfIzZ>Seop?NCeC<^_`F;`e6%F5qk&oN#gzvU6Z~NilILobetP`u;*tsv?$B(zE z9Oa^yAXhDZ(vS5L9fj-ObJ18UI$>Wz=~UPu^NqM_bnD!y@SyHLB;C6d9@71dWTDPi z;;n|~;qG~Wy(fPhf42wujt9lw<|2D9ePx$)ARH$iCf(OrzaG#qr0Y7+mGwlKj1OxlwQs>+ zz8}3r_*829ONkHVit9&-$y0Wpf%32AeFo0A>H(ooc8}qx!m{cL`a{l%2lZ0EmsFiB zcx3rI6mF7#bQ$|Mr!If7W&R&Ce`UUG)PrnD$KU)R4j8v)G@l3cDQ&&sn_^3(eR+7d%UCFK)P}W0ZOn;FZHT6`sqGepovD zzXDCM|6fM`Lpljw4;fxqg(h;?vsbXV-4C3@z_ATZqatb_m=+T-K8T3{}$vA z`85x8A^leW7<|!gG_hl=q<(zQS;Ek6yny|#8;^1kgbhz`^$Q|zeVw|#7!Q6%;G}!6 zj_*UCPV;J`PTI9&=rS6+N+5J5d`MM^MuS`x_%hhE^C|56NAy=~lxynV| zB0v4zYA^kqXlO6Rj+q{jfA9OFT6q=w>3SQSqyHZK$KKRmoFsOm*Ul64b*i5d59&FE zq+9)%cu3dflZEQ%#9MzNa+xf(a~MY`e^@t>{?U)1-EzHXcJB)9Z7%v#Y0vNf^Yv1n zSLWOG{Wq=)P%caD5Kug0w_hlN!Gc`<>n%yd*K|JaEAxqUiPCC`jC7tRYCnwlBniJGNCcQ|v^!}=f z#$(?>{HM5T)@hjkZ_i5lg3WH5Q zD@GqXC*}07r&EXr=QV8a^M3;U5U$c+I7d1f@}KvcW%HTF{_s2{`YrurKZdOze}jI6 z_f+hlpJeBD<7#96|H=G;Ty`*jFfZ|Xhim8)DSu;=Bhz2M7d4bqn7Lz`_sbD(#7pm*fYu3v!ug9n7)K5n@_($7PaX#ZrQ zQ$s)UjpdiT9`a;#X|OYP{~Yeo75^cw+Pu{CE*`XbX}9WEJhV^ewF~#Czj3wNljLHh zzkj#H&-Lb__lXS+`?(i*;XP{Ai=e+GT+*G%#R2q(_}@l;x5Qub`@J%m-sm_L${*#l zUanmp$xmOOcx9a&irfZr==l~CFI&F}{pzCO{pU!ppEu`IJ$oi{fnOAAJoN8{|LYWH zzpsEDj>~H#qFMd#Y+C=Bl0WpfxbETnh^vwCE%Re+{@G;yIOkThU!7K$-{zl9@}DjF zyXx}KQMgI|XET3gfu-LdauQb;S$SOt&*qyiRsR5dqP&wnr=UE}wMu-syhQr#>wWR+ zE`dY2E5e?T&qXW0tSS94@xl|*?>xY{=$qO;8s~aQcHhF+74OP?u|xT`B2sJhFrpm` zqTWvPwgDu`QYPzrSmOp_kgwYtbe7S)TaC#JfQ9MYI)-Ep*w*` zi~4hsuDAL9)0rQ7X#dmwi}E^`U+c%ZX^M9suala{NnTDt*2*jO9s6Z1&@{TFE2|}PdOf@6dL%HyKjKBL|92a$6Al~kN zm-phg8F#x+xH+hyx)xF>&MYj^b4V1Y9CMgT?0KuZq`dPLbnNG zAM54gxso9}$8Yv9JumO`Uz4vPJKuj;`^ZtERxf7*_Ho$nX$kG*oFEoj3YA zD)IUEe(Ir+ExY%~#+zKUTj?-Q)1Qd(;3d$LdcAl$j|XpB`^1h1ryr;B;3L9UFc?px zeYN?~QQqJFM2rXj_%_O6D}0aNc<^zw6Y6QJ@!%2Sa~#KmQPg)N;{o~BKZfz(Dy)0> zI!fj*{Qiswt8PL6j$k~vP4bU@Jh&D4k7Yb~CCVSmc<{$d*uN)lJh<;ihaL~k8_Rfb z38fQy#KE4SolncRKVRT{`vo#y=G)JgeU*HBm#q8d+n*=%oP7IpK{L?3eXhR$)czcq zkLKIYll}MXyvZDyzhv*Bcjep40&Z6XFyiJS}n4fsE zp7rNae;ps6?-nF~Jf!W#m+3qsT_3s}1@R=E=I333g%`qp&+L@~Mt=WnE?OuN^fOOj zKI50q+p_OcnV&e*>R)R0�^aoZ9-+b?6(d+{KpvYR#96ex`oJc7^E=hxCPh3tj1F zK^?@;Y6smydeyIAdA@@iYV&O(AJ%I-r0>=Amu(#d?;S`xI43V5{4EK?b~d0q%e@HY zNH2Q8xIaVWg?{b_g7?z!p1H*1{%8sD-mBHG>)b3)O5py=wEW)S`#V_2uyPx%ocWWL z4F)&*l|r{6?H|u+io9EY{k}rKUzz=Q*+o2`p!-?b_;8|BfN{gl_k2nG=WN~d9~B-{ z{wLj^RCvhF115>cB6PXWV+r_uI#gQ!^V8HT>jp2yt)TaEuS8)YyW?v zeb>8s`j(;db<;5+BlI05pL<|B4AA9oE#@jS>1)#uuFX zH+>wHa&cwA;QbBttT6lWD9VTR-z@t}x=!rp2J5=E+pYe>&06m`o$s=KO0?U{q*K>NVq4e4{o7jq zItZ-f+hTBs!J7;g5cOoiRXub(eLXfOUQVrk5<~w!PACstCuY4% zekl9eGCuk|4eP|pcmIyz9BL8dae9#f=%RAr^a|@;638*u6{Q~L%X59O(j$DI*_M-W zP56twY(J01d?zEHe;?bw;~m~F$ozNz!Yho?_~Jj?nm%oE4+xielQ z8S-s&C5+dTODz9~3a?Z7&9`+6?CU={`8qG?IB4=`-?jAmlNnmi-G*O(VW037_Zuod z3wsTAz1|~m$iF>YX9m6n)IolnfwfBKhttLNaVCZ*_S?^;x}9UW6QNhk&&S8FvrsRe zx$E@@`^5*}J5>G+YFM)Si~ZhMzu#(Zhqx;kw_Lxi+{s!G$6+=(bNsmy5)abd!?Mw} z)HX>pB~I7xwLTx8d_C%&sEe4!{g!@#@x{J};`!p|E8W@72Yb+8ThAgLsX6Q?OEUc- zrmq8lhv`LzL3*_Z?V0}h_gSfz>__%p(KTYna4(M9v+97tohuX`+@NsxDh)4I{q^sa z_&rjw*+I7_Zih2_5{rD4?>rY+!f#qVM?&v6*2hJzyj*g=B&X{rZa?FbG~VsY%yhr~ zf2%wWsy+5|#(uuo<=*u&mNR$yZ*rM)Q{!NeDk%=~OOC1@OlWHog@02%Id@ z`s3I4X!+|EZlv3g&@KH=A#$?-?IIu7yYlL_T2KE94ewkfVShpIsd0Vwb1PmB_g!iI z3ny#Xt>;3MrMCZhpUy`xZ&bW(9^(E&e?i|5$9{mM_ZR-v<{3)w{`5O8N{8&ckI|vv z^BI#1JLi$gnayY5Z&~{~k4gJeM~D7`-qXYJ_cy`45|ocKK`*xtF>D>5@H~Occh+e< z<WKzi(C8?Wx?? ziYVg$cX%Pw&n>%s=6vfEq~m+i!grkKl6g;lobJ#2eQ0@mZz$V;Fg-!LEXevN_0TTq zd@Vcop!4-+=X@t3Kk0p1Cn=;4=}ilASb7Kj-pKPN>$E(}-3HtGbfWva4oUZU$4vKq zHy;_@A4C37jwm;z+s1zZ9V<#l+7po{lXs?9p$OT%UpimU&dd4vIn_)59u@ow(d%?w zD3~X+ea}J39Zidk)icaZ`1Cb-Bz%7fSt^p6L2S*bnN7+YjdBX*hIlaF`e|OmFX7u#; zmu&sV^}zKx-=VtVcFw{S?(g}Ph8$D z`Q1*$4gQmlYu^<5mskI*;UR4&qaPT9$Nikv^xJCmQ@_N^XY|tXID>V3ZKR*Z zXY|`Ccs0^T<6HYj+FtznC93B)NH;_e7%>y$FvDE*E~Q()`A6k7n*UDoj}{IXor+RH zvT%dJ<{vHGC~z`Ul0k3tk1ki3dRN=tfV7vKqv`2+qA3bHecZ0p`%O-l^qyOjyYiZ~ zf_EB^@sUrw#{8>Q=3jMQEB*lPW05d9VZMg<&C}4|Utc;$V65k8{|ZHem9Fl$z+Ota z`)#m~2CJWjdmpU4`fG8;=v7d^&HXa?9ag`|pRFrnUE0d)db0afnIE^$+H*f{kHNlP zyv54vcz}CQ4IZl>x5M(QAJ^Z#Q1A@xnD|3gr8oI4b~o@7Xm{xkktMWq@4@47QDY!gSU=>{(bdke%+UlzZw1R1^w{e)p6-hv-&@H zjQn}Drk|%8p6ypUcC}{HTZkF?*RKDbi;Xg@$>MWg2J8V z4-M{Cx(?a<7>7LvwnFO}*8H)R5Aj>Tb;rOyaNa;XPh3p;Es%cuy1-&saT=KHoYQq; zSp0i)KHv8DD9dHuGR6GoNxraM+7F!XmipP=xHCe!EPk8?Tg@lKeMj!}u>9-aT&rJV z_ts0Zx=v*IRw1ABudi^c(C1KiO|IeBJQ*+JL(p?x9X*K$@w@8fr02ZD&{H?)ThTMb z^MKX+)_(>aZ9al~piNHo9t@njHrVcssVF_tdCXRYeLrsGL4}EL-|S}lY&vk0ey1R7 zw%&ER(6P7r9g)xMy}hrg{HE{ieL>;$y}i#UZ13&$&3d*VkX+2#;n!XL2O9D+K0H}_ zC#qZzE>e2-O0vko37A*5q949ztmTfop4qy<;QR)B4saiPo#I!oAItzAihW9S2e_Ml=u}IzXkvvzNfMaVYn|nO874P!7~A!EP@~-s|-d! zPdVw{&`|#X;};HS{GFB`MBBmgHb3M%Y@d|hC;5_vdo^6D<4JPDZiR2#rQznC8s4`< z!gx^e$9EeH)_&q#wZTe{qvK{d<@HP@kn=!8*~WVcKfOS@NZ#{Af7eG2P~Gh55pt*!HKA z?s*EIL+z#fb}4+efSBLU5jZ{H;qS%S_e7FenlBgqtKCuC%qeq zHGFy`I;0!luL|q^z!>Z02%3u?mU{CYjqP3~=}PbX#K!ciC0+MPvUN(6!*tv|IV1nTXD__F?kiMZG{4dnQ26=El*!W)jrTzfUfy(%fbD$jGc@Feh2$Q8tgg!h6I!WR?<-9<=dQ>Ey z^n?khu_GHnZ+;(lSMXhU+KIQn0{vgTOUhw=Mg2qjE=s(8qrlDT8?gHJ*44KT^(C7Z zNxAp|wVU~I&$jwESpD-gy<+)J000lg z$4mC8Z0owLhZ+34r86<?Jl@2Y^aqqS2-;~p& zeA21<98Xa~C!LBA2uLa&;C*G!4q;nBXhw{9l4&Qu$Z|KJlfH!IXP5JE}`GA8doX?cUk&& zgXbx{dJ8nQw*6J0GuwNJbX~oV&ES2ORc4>osNE@aNf_eYW92>|a-`|Fr(E0HyhuXw zh1SLIbEQ9WU$C!_bB&5uWrek~!r&f*dlbI25pU8hr0;yd^k48#?9i1Q*W3;jHdwu? zKS^Q0VAUV2=Nhc^P71384*OfIYj2gcSG4xxdz$%SAS|BH54#dD?$x&Tc1V~M^j@eq z^*a`8`k>+4eVxMYe=NL4%b9&m&kJ4LA?+n}s_@`@rIN2~`#AYFdTXFd`GE2{Ho86_ z(Xwt;#81k@%}x6w#Za&I3;UB2;c^@LkBbjkUh#~}n+y-mJ|UM)@OWv{der|3>B{*L z&fQ6WDR&b9XX`f?NqoppvFAM9xasBwx7JXXUh4SG^)6I^RPhu+kC7dfEVRQ18DdaQ#4(UKU72;8B zf=6CX$2IT&Y^gs=>CSdZ7d{;KM(g~e3$fNg`9iZb=NzcdEH?|~a?vkD|H(%_VSOES z_Pz5k_0bQ`MS5RXy}b|l!SN=f!@>2<^trVh%#n8fN$q4H2VIEAJ=YEKJrX~sA%3I8 z7aQVtN&Ga857x6r5g)EU6+yF+V10?}H1+E_J};tQOU?6hko2?m5ROqP9=?Y`gPLqU zApFI-Jq9u=P7mT{q1&`-~^#zRX4k4G^WQKTq;cV9@k_=v_Mk{UyK9jKG9@2w8x zHC?Z|LK;Xq2Y$mJN%tBFpN#vMe;(jN{h%KCeZ{^$b}aWyY{b2m@%H^fmw0%ehBgn+ zw>93c-0U6)>d^tvg>+uDp5qOE;K}Bx3gdk!SszdC)BU}0eW>ZZ4eO+un*Eh4QGaO9 z_OqEcrwH zr;4epVF~=kHSOy6<)Yk;8yQpJKoLab$$=Q z9hlgK_{)6-kU>7;CvaV5o4%JC58J%~6-_600~V zT!+Lb_l=4iV!b)lS9%bBo{Z&c-)Grta_jGd>-dEEz3Qu-rwIGS`@=#!d7lR5ffhfu z`;^(=U)`>Fqekq~|(#5~~NdAWFQ236g z&?h^W8Y%4O!$EJBC!IdFlJlseet~C? z^ZTFwhrqbEQ~Nu(QRFCGM|&IOqSZRuk@Wk0N7(QCkFeiwuj%(dUBBO0*Y7t7Og(VE z+=KGDNY@ib76>__bbat#gMFOrc%DS$@%>|#&v(ofe>C6m99= zX6H${a(RQ6Z_|o>d}}sO_}sc?_L{8{U$xtDd9T3D%75yRpEc3hx&@fONk{D6?Z+r3D>qe8o97wZjjf0z66Q0U4L#_t1LNZyHtjK>@M9 zWcKc`^V%OOzJcA@#rljNVL$fsTy0^e>T5t(_Y3|IbPeCbw0y>RKywRf~#l$aDI@$Q$gifcj|JyA;#BLwXgZRA%aaGGv zUY%YiHKA9{_{wqTJz8Hpr1~;)t-)IrKhpK>-{*bJI{s76IG*6Vxny+t{qLc@Nc*MtV8q+ZPqF(?!}7c9#%ana>)DMXQE_#*%J+1we=(4t zf{IJRlmpC*J*ZO(7xNr!Z~rg$azlIj z^c-(Zjsrc@am4IVlX2vwplhg?I^JsjaQwKoE}xFK8UH^I`egRg_c@;||3ekGalEyD z2YNgj9i3ltF8kkdylwPPW;CH!>+#m`OvhUtf2mjRud(Ak-eM5|PwVlPtF}l#hVk}U zLA#~4nKB+_(sy6{ER-u5*Q2|0(lJ@@?OK%E#GUi*a_GjI+A06^^ru zz>@lL_VDA{bA*w3%ojN><}qIc>k*!7^T;{k=VbH8b0zQE7P;Bw{ZMgqj)x%FaGq9_51j>SIRfT??+9`KY8QV)TjCQwGos%n)%{gplfJn zTFn>Bb@}S&i$8;@dFsY52p^ts{OSRm(jyqZc1iq^&lj&}|67hGA8PEQk6#y}7r@8nU*UX_JIT%Fi=&7?lKJArLA!^aFY0+`jt6|kGGF{6?Zt7J zFOI`iS5Jre;^cr{Plx&9bG}>aKlps{T*N;e=Zk;40(=bgl%nM8?oY@0VjlXv95@#7 z|85JjbNZ(vhW%+ho}GBe@~y_(%-?&om-V-vFSZ@BejjhSx&=ED%xj8(>G%EWjm`S^ z=Qqxybl<1hcuP&n$yW}5?=j357X2%on;9};2d|-|);kgzJSm@ab~X6F|MsV~?QMY^;r-o)d_P3K-pYXOJNSD7I{t-pEdl>rG(+e_KeO36 z{_H+yJ6AFj0~sEC*HY@w?q%Ge@Hvuq|-8vP6%zeD=G5cz!_B5ZHJ?W_Fw z+mzSGL|(J+73n%ydEEw-hFrCsFQI=InD1|PAtvnSF2d_2o7jgU``zhskbcKm`hjyW zqs$rNLpkt!$ijHi#lL&${z%fT^oWNtIeiVLKDb}Qm9V!Rypqr4tGo_vE{F2=l?e{Bn+I`W3df!0Ot@lO8LpufE zWZ_@e%2~_z?LI4fqMVb{*}nE?Bp%<}mHPV9@BDp6>+d!>ANqu~XL7#v5rvnkoR4)M zDi`T@!pfBoYkAZ6kd7O{Pv;lu_UJ93`+7A%tBphLp!yiz1^SkHjT>4&5|xySMY zR{p@R72aU*sK86lg>!`5tjSx?B4f;rkVT$D4k~K|EX+qaACwf7s+Jy?^+Am9N(K51X7^0K($&`Wx>bo~H7d>Z$H? zf%LjOivHOfS}@KY(=Czt;B;>v>tfS23>IIoi%WV*j9b z65>8T4KG&xP2VR<-_KNfXZH{5_>hgWcK_hL=K@Qd<6A#RLcSBl$G>wM8{ho?;CP+V zHM3`$KjV+@>)QMDgJy5k-Hk>r)BL0x`H1smBCi>&^4oY{p2qvRRv-WTJH3thwZG+c zozh@qy0#m?Z70!);`d6n*7pzJ`z^^=UcXoKuj4HswD-H!9<3`91iZ&!<4a+$>Z86M z8pQ*L;o683jb)bVnLWKaDC z*FVyaPk(2J%8{M>OP1<6pX3BRFOzJxb2Jt0C;SHSFWf)qFFaErXT*{rkSa%5QqlRb`*jv7mmj+woGn(L)2w_fL@iaNIoPeZ=dv|Ka+} z7TA+ie<7c4C;tNnjo2Rd9h%)otn$`Ew(Fl@~$=(24Szv$i4UUGxxADM6AMH+IvA_7jQQcloG{T6?(vn08YPt`Ii4?HFr z(|FXwCmt~W=56NREWK3P@3;F^lFeO;&k1uh?DY3irwNR8GVNbsvcXDM_ZP6v)7CPqJ z&S~J!4&l%AUDa5(4elT<2@VE@58^R@LgFi9Z@$z?g3Z?OX}ab3-MfH>&SP0o9q8eq(6(1 zmxj00Hed03Py*mTS<>Bqi7V3-ws9z~%u)Cx&F^+RS*rUYZs(Jw(?*$N8ti;e_?^wA zzMrD^iiUVn?tQ<6^!zLOV@A(XTbJOQ?Ng}!W^`5kh8+5Ir!tHI`H2KJ5ikACWn zm)l?jd^vve&Bkd^+XJ^|@$AQ@#TiWeetBEAE){RrcH?2=<2}0W7q2H3n(Oz=Ktt~z z=X2yoE_#XNkB4;sG5cPu&d1{Pd$H>G##d-N>3yPCN^$y4YR?Y)o?clBlq)w0UwxgR zZq)uj-70StjpsTB#|zvKB<1S&S!tISAuH*0<=Wc*cSt$)cX8jdlxM#6*VpFb z{4m{rtg2ix-=Egy)A@?(sr&uRx27)NeC&((ek9ZHWcqgN&qSMt->)#<2UdEZA6?du z^XmG+dleji_Sf^xs>?T7+Ex6*eADal@qWj+YV>@M;=%EkBM9-W-oo)$$FpGmFB$9g zi1{ypeGlWwFUGIf%W>s3YWD_B&dx^yp7;U@qS)@QOS)|w?Nt5odzkz_kYuf<`+je~ z-P6Q*A|wQ#RJ9$hcZ(l#kHW<7%4>i}b%Dy&bd9IIBEsx9>5+?Yco`4d zIR#<1&Z+UeReg`GuXCS{H-q*bo2{e9L-roqLR)9us`t+%OLt5DvF;~^^!0JOqXpeB z6}rz7J&FexY5#hq8^Yg@_MzV7%k7AtAt2@A z(B~<7q`vGP-6aaA_vkKC_-w5`>0BUidY+=?J-YgRZ2!)y?;nt#Mf}G-aLRwsl220T zYM__U-RMO+J@`tF6PE7*El2tk@ssJ_1AVZyBkV znVqM=I4^kBzpoL>OBd=3`?rzsYHf{ry$e5ajz;Q9I(^)qrf`#U6y(3JpN4WF^w_HP zy1$jZm#p$e{Qn3D^``RZ=P2@0u%SM~ljWwqiu7G1dY_HM&z5r7=ahKdkEilbU8QiR z$;aRlf#abbjX&&tAL?&XKFOiXZhcYgac}hwsi&{gOk{bBDUi16=U-4FzNAmq9tech__-^kf zR*cVu*BIYT4mw}0@SxGF`$mQB{;Fi*O9f8tM9cFq|19{Ihp!j@`F#t`{CCPf@jVg$ z|je)w@;e z@3;G5Q~&Tr-u?@|UCmLM`ls^UH&qQ>Z$;bfo61od`E36(7kyg!r{+36f5rQ7={NX( z`-qzPi1B|Pq%Kg-GJK>C@yD>{JH9%b_#v(F}Hl-rv5 zOYpr(;?rz@C$v}O+X)bCw=bo(sSz=aQ~BC2bja+?K7(B!_ZqDH@_XCD{i8kb>yBg| zv!iYv^Xip4j-VQ;hyCJn6aMF-cS`%AUU586$E~Vlm34ah1GEQ=5XFA~1D0sRaynm7 zzQ7L`{bs)LC=ljjf6{TXs{CQT-{BsGFy9XPA64Zi(|^tMVZ#SPBz#z>u-{We{JIRk z57*&0AoVF;VZMj!^8vrOs&>TB*@f$5b9<==146e_+ePA^hIqR^#~5$Jc+!>q`1v;w zUsk*cfAJOQ7nK4}m|yxAjAN(0GLy4>+cc9im8018{cNp={o|8dpke(wb28oHO<#z| zCy0l-715-(YC6X;{EOzU;$QX087{W?QkyDLJ>DVT#?|2M^I%0Z(~ILZ{$4123CE-7 z1K(WKCGox0zmTx6)7BFP9~9WnI!FvEJh@r^!;BB-h};}cZUjQ zzGH&OLB8V|I`6>uHz{KIj&_-MEJOS=1Re)kGrmpW^!qVrznQbgmfWYu|F*IAYI2p|MC4pf#a&iv;RfZ$Mlz= z|I6{4@X^de*4R4b^F-d&KlOc@^8GteE93y*9pvNlN%p6U@BbAR56#Iz0Sb%7M$9&qJn3dOdv|Z zc3b;HHXm7N?Qeat=v}f@<#p`ylTWDJRuq5oS@m?6$zP+MJ_?}=={pbeN$ej<{!mXp zf_%M|X{tX3O)s@g5PL;EJ+Ik%Fyv@=o!|6Z2s`;k`-%Co)HnCk8GSlPSbiT63DqS$|vqcll;W%1){Gm zhwl`-7gyYm+#>nhFU5Vm3ZG>5ysaP=$M^3BR**}R_fX%z3_3RI`{`0Hw0An+<7iWB z2lYIP&JR<&qS>GaN*_ND8n(NuX}egAudDwSz`ov*6N^;aKHTy&J+2x(lwIjLy~Oaz zMXzJ^HS(qORyz<6D&6BD!+WdR8}i{DSobRj_J9QS?|o$cjm;~o=J$8nywcVel5U+> z#zQ(^OBP-&@|BZOo8KY0R`sl4c-Ve*e6sS>{enY@u0Rla=w6(>nHsw=A3)J=6C;UvBmrMkiGs;FI4_NB=}>Tl`!N_v2LB5 z^P+fgli*Fh-3;4~dChN#k)M-wI%MnQ|0oEDwhaX2;n6hn5~f zZqoH6wfk|^*H3I*uyqH&_xo`Bogp3rwqDu!b^67>6uFPL)vjlR`6t)Wk>djK|N2#= zpYAKQrk^^zt={9u_bY^srM7nno&6jM>CYz@y-mV=$0cI7N45zV@%wy2PqXvxPZ6)_ zxc?#Cmm=Stf9`iO-?N!-*y@9DbA0smkhr=hm6KDMuVVRt)*2Zn)c;{UCnKHXJu$|3 zBlHaO??8SZr)Y<}kdNg)cULywgB~`N8)dom+HP3x?@=zSpX&m?Zp?Z=T;%w?Mf4%x z)+-jSx2pa?pMM8v@DbIU?u`=0L;8I)eD7T0t#+<@>43nwNC_Pe>V9K*FYsG>AP2?= z`WZrpQx)%Av_s0z27TG@Ny<*xOVyt zBEb*eiIH;IxhD1R`q%1xQJK7~N$ckdU{Y8i@L1&hGuY}503dE;>m%M*M5%>8}*|WIX53x#;_XA7MT|pZE2oY(Kvw<-+mkCgjgW-<9(5 z;2a%SdZilC_vt-Me@xP!taXxHG+*#c@2{St_@wI(cprdWEw#fi;c+^+-}hdLg?_a^ zeh@=4!rvTZ&V2i?50anx_FrKPVR+!6tWUK6Qq~*X9{E02C|A?WZ~E&KA#YU_#>0F? z+SST5p%2bK30|RmPo{k~`KCSe^@U=cJYdPA#@>3q(~&Q|e`US48~VksLVBY=u7Z%0 z(Fgbj`?BnZ<3l~000F@JQ&J$b_eC_t^y{0}Pid_6t2tsi{X@DfvT^tMU*ov_1>tM9 z{-N`yY(G}#J8`-ntMj$^Y-tYjq{(7u(tVbe`?0!?klj-brr{} zq*|H32!B^AO#WRC{+3hu^z{X$2hMMZ+$M$Rs@<=4Dcm_r;lViycb}>7P*LH9Q)~Iq za$Vt*f?v6Env~18{Xh2J1-#CqIv3uOvtz|vd`WiVY*Mmq$FU+}kP}E01BsH5L=l%L z35peSiDUtG(hJ^J5_|lWVmUw@|K%Jz0b<+(Xm81}+(W5bpfMCGw?7xtQtF-pbve+- z<7rQM|Yx!C<8e>m&v%-B{NUnD})(RzB8`$Erv0y;Y;T z-|!qUxKH4if2|xxs#0CiN3N%y2m3CJwW{3h>1Zq`#&=&QB_HzWYxVMi7YNV1ygVu8 z#B#n0Px86@mHx847CGm>N9;!uzPNl174`dTvA*l7;g9gk^fBuzc1Fa%TbMq2KMwmL z467e6{r=Ig@+0wmo#}bjUCQrarPIGxiFvj>hrdPWg+IpN9R_PXNYAhLfhN?Af$+-) zVtZTVi*m#yUjIUF3zI{S_e)ODrFc)_96IHOe1E#<(7*on%rEBlH2f<`D~XSt3<2k!B#zgQkE4A#KW7rmBelKk zp7yXrlH>fyHs#-Cis(e=&X-2zdAs<$|4E}`#^=t5wS1?S_65j|&Yizf5)}Nq8(YB` zghF$N#D4y!&~%l+9LJjQD=%Mx1^-4(E>3#x{GiIGea9Z>DzqJoIxmX#&wkPeIys`U zovynlXdd_^Sz91fkUYu8F@Ois`zifF68Wh3L zfqTF3_5JMp(aWTKmP@{RT(|j)AZ-cH<@1PH@VjNL}L3m z!>G=aeO=S{Wz?T5S3TqN2KZ&A{oS64+n@TC^qu<`(3=$yi@^R*JAM-==b3pI)Dr%WXnm{d?56c_66;J5U z`2J3bhl=IYj^Ts!{Fc1sJ#4yvDCu4&>5|=Qzxa2-lkMuqhW}gX_V0O{9W_+ELGr=B zChv!e*Bh+-9xA%srF_WjF5`pQUAS+_@~PZnU#7t-XV_mZuIo9M>?I2_8o~|WYpRl<%#{j zM`72elz-|g_Q#{xcj5cBTu)~H26bp-f4kWC+4(JyIkl$BJ&p91_pLL4-{`u=L&QzpX()l9! z^{M|cRe#scBVP_d#`>xB3(5-#$M=4e{)(RO!n(T76DyZVI`lJxR~T&b`*hy9Ox~9( z+CPWRSGurYPo5{|3wp?p;z`a|L%`Qr6WebXDvHPb0{Praq(5c-M)gKqZ}uD4A56y( z&(qjnTyIc5r=E9LKJfX}^X^CL`tczt=WyL~(GyiEcFMf%hXat?apT)Q<7ZX*7SBt7 z_NfB)+b|T)(SGLd(|!+qz^bu*C(!O;NRnfIy+eM4u|o~%O4|BF|1#ey_M`GHN$>ii z-mY?a_`0-ndBbNUz583RKC1fu-dq4>pEW4kK6jZT>h-kSN~qibGtB|XPNzx*_qA{{f=#UgV{Z0vwQAWK43qO@Fm>8 zU-{A9W$?JcJqnMFOyyrd!ytrczYE(ryB}aw`x~8d2pNCY37!nrakQRa`aI)TzvQdu zhd!U)4$|_%17-)^q4aQGBlN;-XN>)(DmO!B2bIkZy1&HNu;W^l5BHY{0&X|h?4a%r zfs>{3Iv4IYJLm?5>&tt$^5+tLpWbJ>Kw;;P>yKLd!1>bKBIJp^&Ya~c~_iH)3`wXwinSB@A?-#-Pk-gtyc->ChX0Y37+J7=Tt;@>ku>3s+ zw;MceaI3-l4K5knXYfLShgMc4uGQnQ|4a00WEXH8i}&dscvHRo)95@q^HKlJ!nk-k z%4BD@^yoi zuct%zk6#JPkGCO zdM*8qyxS?-&yzN@Uq-DTk7@rt*?y0F?qAhj+-v&4^2hWYpnov3n`p<8&VTNtydDsJ z;q&-as5d(V?Nv&!?>lzCgU^rs`wZk0SGMxG?N*tg6pdXX==SZ~f&vA)4 zc#i!@%{lhgKD8Bzi1m2!pvJT#S?@;su=$+tlM9s&|9)(Ev_v#mkJEW8_7RKTiQDN2 z*BPUBItDx}_sQ>|zm6W${!=~b{Yc^h&P|}mDSG56_i4B3xDeyxJ`;&p?AT#t?DKRnGk?pl-=*IVTCQF6!pcc>8QT0^?* zI~TEiUP3y)AH(~TuH&j%nB#s3;qNd@(fn`dCH^A|#)O~yv+xH((L z-HZ;G&;5Q~dy_w`$BWoMOm6G>e^}>r>37tRD4c#r{iwn#5C4qxgt21^cOMZrx!LSJ zU-!Kfj6lfe#)Y12y|*OKPjqgzA1TuLjG~>=j-QLxAt+zO$ojprAs@Ng%X&+c`my7D z>l)M+OU7O${K)5~yLbDG!l$^sp$3rt59``f z|0W}?XMNK{+_J-rov;|@00GYY5Sh^ zz6$e`R{qM$M}r{5_2>iaauDu6$k$WaQ|dD+kL5nKxS#s>E?Cb=*c14ka9U3t4=z`H zWzElY7lI#tuWsCKwS0R!`(=vH&u7)>zr~7|?agrV^I577Nkt^M1ye`7zd@DKf0<=~{} zqc@2B4OI1h2Hf9Za`R7`f2Hb)F!p_gyRDo(-&T0F(lPUM25+nD2UntI`CPv|hg~gr zgO5+vKFL<8e%<|S$s&DzB01=qA_sr@6q_XMwQ?%Pulb6H<2VE5VF6;c2gl**><+ds z<=Az7k=6sh@5r4m z+5G@7k^Gt7)dJG<;*ZK}sYeMvS&uKH4^2PLy+|^gXg?Cy(5BC?j+nR|#7?m9&$Ik{ z-w3|jIEiy2sr}&eee#6(P0yD**nH{vqgYS>_lEgteNWX_9B1>=OVQ52Hl6*&60>&w znYL?%*mRvu_S;5!`diQiu^n?9c9Qqk%x`OYd#8=3b}w*tPyTW3e~+nR!F`Gfe?ZGk zx@}xOsowrur58M5pgk~&IQ^bsRF7k{^NMD_M{+|K3)^iaaK!D(eLHUNlmDLX6*cL| zA8%*k`8`zWKaU?p;X_;xt+&lH8r1tmHT5|PJIw17*ZX{=bH8rf{eL|=5y~s(}xBgwI-ll6suLc`eeLtnc zalNGcM43s zf`2prK2|OL*566@>%}foyDp1=zn8g0=nH#g znvVS`YDdI;mHj}G{IK7Xp8s|o@Yuec>F4{4g^-z#o1-Fc1J&nCJlK{~J784rmBM!^ zR1c2*%~oVgwHK`AG;W8VRa^SPb!9QPMXjQO>eTb-wHo0V()3S-K@ zllxa5R=oDT?f5*z+pzy}IzHudTO?n49{f3EPkerTBRxi`Cm&C4Pkj1>`KPld4vXDD zIlSji^6iL}hx0de_Qbvu;y<}PQE8a}*|R4OgT#0|d2ZSh%J*1r=(u`F+9TfA?sh^u z_!_5IdqUI4wg1P#pG=?mJn7l8ucosnrmy$>n);|cQD5)pBi*Uk6R$)1 zwde&U{NHGCL9E(SvnO8qwZ`_uOYrR7xnK&tz6HmwM)znthGZTJnZlBzV|nLJ8P$m zkC<2>)X%Tg-}vm=3A=Utwe|e^dmzsfItyo=EA~|3tOd5NFyGb{=IOe^&V!Q9zv~d6 z*P93bg6~fyU*B^F_1ZzPJKTPY?e(wWXncKtuRj-aElNDuJlD$!kB$g^v0f%!q~{xO zY{vfhh4hD1)E;7cam3H(Oz$r8d2OHCZ%cpxAz9g@aC*L|OJOw=v7XT>u2O0m5Zc4y-m*({!Bcc(c6!oZtul><#{&$&PUwdJ7!q^n}FBvdBgcwk)QHT zbW(&u(=8HD*t~+@w`|7~-{;T$Gdl=J{Z{1C=EV~x|4H|L!At)BIobsG??`)O{r1&b zPK4(O`My;iOS>ePha|gq2_C zbg(@>Hs#zaQMD znSA}-Ujg6uY5iwo`ZPj3=7(~9%yg4CA>Cd}H`~sgTlI8dtcR!jFw&v_YrjePe!yVkdxVF4cX^<^ z;2-2grH=J-(GzF&9Cad16nRwf7bbSW>+1P zdWF>gV(TQS|K*6jPyH{41)gbtZba`*)6jbm^v3Dg&smR8)jVf^=kwpe^L*}mLXVGI z&xYOh`r9cV+P`D@DVdx-4*6M&--I_>T#!|rsq?gJ@$O96Z6AFhehdQe)T9&Zb@S zu|Iik+HEhKhTca&Z`?j^x4o<8x!Y}<@jSKLZiNwq;Pc>#Wd_?hwZb{CmIsA%UL|&Q z;ha~h-|d{0>UTTm8r?s0P6uqMsd6Irb~IlYg)b!5FUP^}Y+d0>_1{Etrt2FEe?kIq zFOI~VC;0ltd9`vW_larxINe;NE1WY+{1;{WuKcPdeE%JIdz-E!`kc=L=$~mPY;(XEpLd*y9s?k1>ZD>F8^FRKW z{YLLODi71ENq-+_5mV*kAYgo7`^WOU!oMmv?ZD&hM0~Tw|EzM9-oH?3H#wS={5Z#C z@Uc34C8O)-m=9%kp879Xuc`hy^J`5KOwIcpg6D|g zQN6)*pQ=gMFX>Fqs!9*j{dP?{@*Ddw44=|RebNt-nEoBVq;f`n=SpZttskzrW`F)|&UqXKh!fhxOh8x>>Jl zrtoV^9lv%=!>=nE@+*^{U%a3Zzid5nSlA}zuf7fKG)MUr^I!U7G@d_!blLdr>r)pA zqBFm*=LLcn-@lW7J=k{qXM7Mwf2RF*<)p%6dcF$dj>3EXN#CzND)7_sn^AwUUG5b9 z|0-z@+|#CURrQD8-^X@jIQjneOnxp0A17dEFu=boay55>!qhX;-^|`vULvIZknt*e z-`j*m8id;Risf|ul=k`)-Jd;8J#e3_&~fs5WP17B6Ua@dX6f#kLdR!MNXOIRXY(21 zr`~&WB7WXHr5=?N)?=pptS!&&P|Dw%rzc9uiq;S{FJ;xi^_G3SH`mlukO3a+Vd>TVe0(}_4{{PK_B@(^p!?_ zgR_P3!3QzTuS1aA=ea7cJPaYJ`nUf<63g?_7?d<1h;`Y3!L3=h@zoGn|bp2)n8V14dlPh4K z2t&MXdmR0q{o?7KGv0}X1=lldU+R(cK1koEW9NIr;*ymAbj}rDj_(Ief3Dc|x2`Y7 za^>e%zW@`#&%Zf8GPyE7RSv7YbjHuG>b=Ome~9I_gA;yVXiTr3haQ)CVchSKr~!PQ8lT_Tf#>1=ejy;ncLejXSWXrHE}={GJnT_F$JvYfGP%w?P}whbZlOu_ zRIKkoMq2)~-$=3N&G{n@!WG_aKS&!UH7I>f(V{zZKMS<)rj4+!0i7}qYw{!B-*^SSL*V?#=u-Vlyzx4Gj5mk&CO>~47g^-gaJ zKR3EZZtzCRxqbgLO|RdPY?S^jlD?w`f4j*C3>pN=DO-y5U&Zv59(%t^_zVk5G6%8SAs>{d9Iy3W`$pr# zZ$Oai?Hk1x%bAW3|El%y`=rwQCeHjgaCmitalr3ouycr~bFaiN;kz)?>;IPsUt|5+ zPrlmy(XqUrs(xJteouej!AbP$K5bC$N1|Sh_4#!7OYKdN}bzIy$7F6p!P zalYF71>V?DZd4J)azjhemF09g=Q3J~2H5`Sq2>F~9WQoPmm-`yVX+lIY($JXOuld1>u9csuOGjQ{?f z6}1b=_mho--}*Ag!8d5VQ-8uyu?w?%FKqvCdhdnGdr0rSIHY#uNzYFolyaWwdlB-v z-_`bLRlfPWB(LeBdH+IWiPLevA=AC8CS7|?I=>I-YNYe_zIUq*jN#!P zA*3+-Mv0TQF6H;ueu3li`Z=Fy>y!76hxfffY;v((wgU4ezkfVb)=BzaoEu>9d)oJ+ zv-63sQ>+3&*zY}Ly?$v`HjX9tbt+x^`X%Q4jUnAvx>Z1t#6bse2R3NB+7+A zEeH5PRFLugY*o;EgWivytofnTFM0IuG~TM;IT^Y`lI4b)pOWXCxBNBmvs}`_@0~I3 zon`jh6UMKqwdbhPnYaCig{Gehp7H}FLHs2C0%fi@e@vbeX7G76_ERW5>3w+GU$Xo1 z4%qwk5@R2|!P^WzV(<=wj~cwoU@aH-d>TAy@5c>3Zt#ACwFPy}?=! z+^cV}@;g+Nj^zB3B*6X9_P*6%r6W1N-C(67IlseTr6W1N)8IbK-!E`-exJry^+^1S zmv%|)cBS|G!YsvKRxuGj`hOs$f7iQr)_l2_g!*y;p8IzU{rik@|2ztLm}1ueWYLdvqActwQ~ovUe7x4sr8*xnG_9 zp=E~ecpKl3NF2){>l@4A5y0f%8?L5(q4Jl>-6Fw{b#=jmalHNhrUnm!&W@meb}xi)b9`~ipS;IT&?XsWb!QAF`Q@K8a^VG-jJ&g3;r*S*aklwTPLgA<1%fR+n2>!-$OFtj&oa1;-{;XPues26o z+t27tY&=iir*h-^#Pv+x&S%HvF{RsgKCfXpCCItUjpv`PTyN*J-DaSV*dI?tA9dE~ zqc1dSw>o|Fden}3kzB>R?iBP9J!NiR*6X99;OlL^FjqvIQ6Dk(@zB3h6YC?^H*QzB z*F+z6t>n09<6%|x8Samh{+H>eB~o6DZ`|_#BlbJt{Dz4Cdw{Yx-RWr>YpAwqCVcW7W!qg(YIae z6YqaN$n}vZzwoK7_=u<9@cdWcsnh=(>eFpUy6N=2%emL{ROJ5$s~U{+t)>TtHEv|T z9s)m3WxQBlBmX~-%1z~ep_RL}Bn&7t>plm+hs))EDeO;l8L>ZqgqZ!Canj~`?|{fn z+@7R2ZjS?i*^X;O-yf0mxIai^o7ZM?UoRiqEdTNo%DL*bP|^N`?@3uXruW+V6&|(z zy0TB7xX#a%Ru=~t~YwlE6Iz(S$9et&NKVzH3H_66`HPa z)&)7RIJFZO&er$*dma84@ZDz4Ueoe7Q<$t0t#rZ-%416UDGo$(mX}tT%EwwfPWR_)@U-8Z`8(44 zSRT~*%uL3ck%$iR<$_4w!;*_gF63AF9hRs)fv`(m%qIV!!rX>j0zu@DG09<0413->d13 z{M*3_bqftAD4|U)z@a$84%za1kc+T$1*ySy(IU@B7gGV)fo8k#?S9-%bBt{7LDj$*^7H^TqxunO&nNBOe zUGXF(#mjQZUzRH|=tFZn)!StFoo<_dWbJSLb%n}P+V5AWJf-Ja*_a=+Aj;!=4Hzw5Zd0}6AzWeei|9_7!yUGl>3ZG82uFBX{l z3K{Sn6N$ZjmmxnX2y0Xhe4lmd&s?DO#6C{JpYG#wzAR`FeCc?t=yS=2k~~lByPsU| zMp3!sLrUNBU4%%Ft)El`6o2ng@Sk$p0{=r8=#&?4x$y6`e&!eReV|PDP8eFj>YdMh zU(zjq#PKU%eSIgbZ`Jsz)N#2QT>&B?IpL5xNGKs9d^zGidWZd{5vTy4XME)Jviw!UN(1bV3ujgOz z0kFiN=SuuoW$$}u>AIG$lQ?~i=sE_v!d|U+p+(o@_+1V(&r{1E(GKQv=Jn^eI3A5> ztlv#{W#g>tffKd&UbOczltcc^eORiI>c>Xyeqlqo%G#G2DpalAt-t2&-sN=OaDnnW zxu7Hk=5xojy|1?NmsqT9NYBfXA8hGxMW-Z4zbCpv+duxEDC<*bMuQ-*eUMe!fBahH zH+`G<{LK5?LZ;$-iE_z8jVZURm;1M!ufhD(?!PX~s<)?)qy0{0UU{&lJ+F+~ll7oH zxPN@W_>{ES_)}Cp`u16Q*-!HJSuG-`-tP*tQ~~+;?(1Q1pEX-nObfGK2%V|pKU4#L z&ld(1@SdD3%zA!mkF&-7e!K$8ql6Y_%@IBmKSz4^`w?b-O{Msm-q)-7p5?lKg)piL z7(WmQvt@>gDktH=5+A4Q@4aVRI&D6zKWoFqb~f9=$0a|1%>EM4@16v%X0WEJnOUdOfexJt4+LHW89yk0dUb$6>$*)55`NDVh%g*R~NfX*VavKqo#Dz#7zh4WO z5`5bwfx(VJa;mUf79hS*{pVp zuba{?C&?VwONb}d;Sa*{wHcpFfE)4iwuql;dZcZ{&#+g^JsDqno4@gt(1UuCg0#H> zGfb@2_~NTIp4g@FTrvm2>lGHY3S4MKTKkeyr);FKCa~_NIxsUg8xvUS%eJ#rMd+1MEF6br6J|3iUYwgB) zek@O(8nRSAD7brLUSf1}IaX-%T1sPxYzD}?83Hsaw#&U+3zu$RVrr+EjNPS8?%NL!5-)jV2 z&hNudmX+i|%4hH+mNS>DTK?C`8S2U4dNVwse8~9SFT7g@IbzS5NbSXf3;3y`k8d;H}bx=Ji*hq@BW}twQfJQLkSEDYxyol z9)`4^-BJ=bxq4dp`T1E)pVmtW!o3$#-?U!ZU2+pL0HNKT4)j;4cU6kX#*+?(eZOMd zKdz1HwLBPqkev0o*zASr#@V^+6t9o-wf!NIA6d7X&c0%Q)cKIw<%8*b$kqerY5S&j z*rKU$n5TTo-cN;nd%w2g77(Ae)bDR-wf@{`bpD^W zF8mGj`7^OD{8iv_Khtc;kM!pa(yY?%{rE|J^kt-bCf0=)NAmlBgP(o?HZl7l{yi-} z{YPLclHcsdr{bsowO66HuXg<$mKgqL$ZwzC`@2l(b^T9%kzVRWvXcD27478T z@$7Bk=&SNln{F^_C;#4TcvSfk9#cMr4`{u@2TOt{>`;CVwXjv-m+31>oOD_JJB+`r z#$SDm@4s|Py3}u1?ohZ%>7zfF^u>NVug?n9$K^e_piA;47j$a;u;Sr+N>HtzE@{*G z1@3`Tdjn~RH>{BCSl>`PBw49`H23QjX50F~gPM->5z^;+Eavx%Kwq!S9vZ*DD&li8 zN9_UkGq_(kT|XFAdM2*Wa(&%|_B6vUEGbCru&>k6Z^M>J_rYJH^$tt5-l1gmYt{0D z$x*mW%Nu&EBzT90v|W>jtUYI0d){g7d7~tg^J(M<%WY>2`p8%6ch0YRo2E_IH0*a=}zN!1q?Az1{9g?N3`*Dm1J9qTG@GLh~&A1^;Y63GETq znEmN*P=4CaZNGgO#0!Ko;rE@avA6EOGtN6t5d(P-PitqtH0OxyABmi->)kP zzv+LXob~c@00duu4EL(M#{QAN1K-l|X-JYwdwzBe@}c>~@9TH~bAB*4Xu69xX`H;T zBtMc58U8!;x%)4s_4~r+U^r#JFX*7)*7<#{-0A(k+RrGj_rDHuJfQN){zy(G=PR7b zvF#6I|D^_|{w%TFhw%qt`7m=Se@loP@o{IwN6(+;dz$?0ZT_bC8JwZD)9rZT@`Sly9M|!@eT$1O>fVQ{GiR*oSAC!U5 zDKEADu3CSP`^9SgVBra^-$W!&tZ5&ftqt6E1t z9NZ8`ot0HqCGC;Psnp?R)X#n&0V49xTZN-;e#Y>s{Ag?kC=s$}0;>{luV;H4P(& zwLM#O9INvaw=NR;LUV`2>Hg2{ns0Es-mgGDvfUc-QJzP9{MTvtSUi(_M1Oo*e&C3Y zG;N$enSbT2!Y`UBi}`+B<;mAAxgN~tr`qmb4u%o2>*M}MI#NIIDeCXqexJ|XB=i?@ zR|6~b?;LGM_S+KRwEZ?@{Xm|(+;2r9gjoK+H;~DHs&C7d|7rGv+WPl4AC>+~zZ^05 zasWXf%;5XuIc}5)JH3zbt?JXS4PS3PWVhl7-kq?Z|q(6{D{7n3TOJ9U^ z;0t4XM@{(d=OE*KOssEg7w!T~`gg)s@O?L7e80B0onOlK%L6$=jIWFMw#wu5z7FEM z>9r^F2X-0$extKR;cB14Z8?SQ96P=bt^VaP&6jlRJX!@p(aVGZZ2M+XMg7 z^S{&i(;A%<>8s(>LBMQ>PT*tx?i>K#%{@x*cBL!cFJF7lpYW-S%m~EOgP3@_fyebW z<(rhp`%^vLO-MH#{j4X$O!n>8o^u|F=HqF{*B>lwwMbn+j z$j+HeDqi0Yo1Qy4X!IVl_pV2d8mx5To*97$i@MGi_nTj>;qw^bsNYz~?h z#NOM0mk4ZkPxsgT=r_a2fWZF6uHyUMyx(}eef;p}lnVyhGqwHZnn->pUask`1`)^c zbD6~#->A=N|FYbPc7<0V68XeX!si8?Ms}D*?)CTPM=Io=FX?=~FY_>@$;;{dT<&EL z0zi0Kuf}T;mGIyFo*SW51m1#&2pjQV=wU*Hr7g{}&+KJySJ>|j@%*chpXupmV_azY zk+k2$U7lY3TN}YA{L9U~LZ6pyzbn7x&aetEnbG;$JB!!=gFg)BZp#f_ug|?bPRd{8 zWsZqg5DUryUxlB>_d@=H6c+y4`$FFMYV{%=e4p~QpV+|H*J!*J`AYaX!3IRwh(bz; z{a(e5crSF&ct%(X!;t)Vnbj}ltL0yX{7nBO{xdGjHokTOK*;A#%vay%Hgts+K)#CK zcai2#`FFL#seWIi{b6a-*|`#4xnE#uQ-ZuTOuOq<=!vh1MR43oQo}UeYh|(peut zUhr?$#{>?y&zs~Aw|~Oz{=F2_Pj}?xy|0%q1AU8;KHXUy_xF6yNH@5>M#xlyiI7_i4KSVD1t@ zkMAz49(KJp@rXS)e`r2u=ci0R|H6fK-f^d<^ZPfbFH3ktz4~kYkVm77`-{kzwfJAc z|BV*+HfSff{m}-hsQp|_K9|u4HU3m>z5E`Ki*3F%myL~ZHRxfvUjFiP&F{HS+asU* zf%0islBfI5e7}2n!6JF#`x;iEKFr|nosLy#H$G?muSEQo1xSeC`>fuw;BJAFl}Dw# zP|^Ct_E`xj$hTGf$fwzJYZ3GLMvEywd`0_!A(bZ^*E4>Rih6#tJ(#ms{$}mt`^)cH zB-yaup>mYryIfu*t9K~<`}Rv*I7jzmCfm2^b2}IAenr36%KdANgD9$48NA+^8{ai@b#SX&Yw%V^5T-v>-8u!Q|qAL?NR#uo}_&4B7Ht?c!ve7mxK8w zO=o;@JcT9*HUj3S`rhytpbr^heMQxo&*{Y8>GE?Kg{H4-{p|j$+e~lxy%NjMeXqQC zKaKBG^?i~qk7cJbr9=4^(}C$3=ukxzKfgqtLy!^T=Su-kHy?0&$H(Krt91Ox=YC@K zQN8B%S!MFuo7eLF+-PqTI!;Zwmjd>FU)%pE|8JA`nvZfV%0-pf=j30=HD?hgE7y;#FR zyWcFHH;f>EcAm9Q`MqSGUW}84?IqobFOMmD3#pKO1sNIb%DrKCJhO>!-@8)T5&PrjeZPp!^M6djijX!*c=T zA(m6#U+nT0%c-ZIkM!Qo`x(4Fe4kFb z|HIC^rR%mut5@nb(t5@BTO36>9B1#kLC17b#`)t*5OY27cyw-SA(CvXY1iu`J>&Oc zWpa_vEg?SOzl8W87b7+KJ7c-ndq~>b+pBEzA73XZK+ec_;sYw|Yns~rZqJ;I-(|D! zxo*Oc eNUVw@t^fv#C&{3YxQUEvUe4OPn`2BnNoIZDaz0G!yUy4WVnDPR{)2!`5 zIpFva?7Vj>_Y2VB5Rx|IgY_?8_jJDa`SVyF$%$BRyZn6ZM&%btce=eE`P^SgJx?Tm zbDm@Jcc4aoeuOR7)Kd^+++%W3;pf{C)O%jz7;G{kQNbp$lc%R{?(+rRqROL?~Csrt6f4j&?=jN)Cf)iSv&8a| zpKJ$we_8N39LBWXy{0EzPFO#tcmEDy2KWKx-uv?HZ36qf>aOqc-Cd=(O}|?jx{MzW zN%DvvPOp7$_y(*0^;Z9zH9hvDNqOO}k~~Q6vwQgO(s?A#bISW+5`(IX@0)`I`?aU#@q)5F7Am_35uQI`>N)T2987&#HaUY`Z|)Y z1Eu`1@~4%LwoO{@>VApKO*Q;r=SIMKp{CouO=5i4Smoxv9R_Rv3l;5u>HheontwLB zqR@|frj`B=D8F_ZzjhhFKA`Et*(Ldr%;{77aw{+Bn6qB#;NXoAK4|@`M`2c1%E4bP z=V9fOse&i%ecDenTdurQ>y7*Rv^@Vl&WB5qVrb6aYd`e-zQ57(56wBI{Mda|wuN<-G+8$WXFj(bv zsJPwW15%%%;v)vDTn`nu8N5sRS=?f<$zgGm!P>q_alOGuE&V!!4;kEVaEru4#nlE+ zTKRVye9YiJgAZH&9)ph<+-2}_gF6k*Nt_frB&Hr?JBR8zNten!A0iAD|3ULr=V`vS z9SV;fRJ`5o3RhY+R<|$Y{fNj-JpbZ+E-C8zk(Z0_oKCWwq+7>@Ot0EHQiX3Zu7I8` z$Um`1;V`~X%A0tP!W>_kuR%TR9^UXoN#1AkyAhRRJBQ(ZR(u~?o~QTwrt`aPmj3kT zcU?7h#Cvg`&&R`feZHObt7?6)yqViZxU4YsG`lGC{qW6dU-U1wPKoD9QTdhePx%@1 ze;)CT8h+qwr+>!ynXbD)Ur}YTobpZFe=$$^(A#vW*cqYPA#i%WrqZtP49?el@fDOa z^}`m@@11p7ejRXqJYxA=bEX}#s>TkX#!vZIBOjrva>)0$p?(7<5A=@%74*L9%k-Y0 zqLv@3yMzw+1Bdi}QLS%C?-$kjrhb!YzlZvOFnXYRx!@gaYmqpNUZUl!%qcu}k;2`_ zwg2onPvO;*0?+jO)~C}hk4|Zqw+h{%;_U)qLx|hu*O5M-)AhT7%6o*~jK4Mx)#w9! z2S)ToFnc>x`W2op=pnzRFUAz+crE&(+t-^j{lIoi^@hoPEa$PFi1ov-!8UOH(A#u@ z>b>-y+2h(C{{50?K`->z=!ND;FHr7x)W|(e8GHv;81!`X#=2)oZ~Vh+V!g5OwDrcd zQ{W|XAS=rA)o6F>dEr}yMHT|AL>P>d)x0n_0$Jh7{dPv{rJKu zeA0FNj8ESa`OfFwCvkc|h;Cb$vhS4RPGa{glMl`R20zfa>c_BmhxL*YD^e}=G6^ZEHlzh`U}33}|EHPOwxs0PW;zvLTWBY!W<4;Tu{k}K$Uk~j}e_@M&wduoFP33kH<%}93 zY}NGXdCP~iTu(=Sd=d)P`*&O(x)Iu?Q|n=V&$L`0zigjq*xRG^9yfi|tl!7Qcqh*b zP5&q{_ZzVug=W78)Z`28PD)8n1@!p-o3OKlr)bXyCCbgE^98}@q3OM6tSrJR#AI1- zvrh1R9}ewEbQ4+Ul6EvdJ;!r~Rfr|uEcJILmzCtX`+a>}c7I`de`xwWjYCuFAKud= z`Qv^naylxH#UFAA^f=#K-q>!`>;si;g0Hu!MaPZztZ$6Z^hy}*m-Myy3z&yfzYkP( zAMBvrClspxP12|9RaKow`~I&`{dIe<^6qjlXma4|bjbqSKV$dJBnwy?`@^K>UvQDY z1GYbGaKR-4*UC{oH&>p=^2eP@UT$*A@~3lxOy0DiT^`x)E^l{2-cH_senaY$&pj@2 z810bQ_xJgIPpMp5dPeT>1^Z@Ujl{nK^an*Azy(SlR` z(3C4LFXgxC71x8c`zs2wv|>z833q!bZ{v~g|Li?WZ_*5X#`hNW!!KWm0TE$B)j#x` z4zLb$pPTcAaeA)Tua=L3MiL2q-N zijVcKU$+3G5rVC&7VP`Nv0s7hLb_)9oxX!L{2ajfCblQgJjMRWII(@zVL?gCUy6Gb zE<_n@mm>bNU5?b?xhHNHUl-nr#0XA5`NAiTKcB0L{17iCfp|C7;9VNg=j$ncUwO8k zqTh9Qy%aVy@W)`DfpwRkksj9f7Li}|vlTG@k*-itKUcQ?KTq^`Oy777eVuW=Z65CX zq(fExb?JWUQNur`{<8EO%e3Zg7{ulLmJhe8k`mgAW_r zZtwwvTMa&FaLM392AkioZJzKiY*0Tz7*hR{tjx)C*Jq)s_4D=qFkj^W`^6RCBGy9v zj3RH=Z(=)U9{pt-G#%UPllVS2{9`}olLGu>#F%Vu(Q@}{I^OFu0)(+&?>you>wAvJ zv&YE5wyrgq2@Q|M%3G-=Pf1sRvY>J<{ zQ~C@1uYxxz+PXnS%S~+knRqy2!_Oz_iRZ{7wQX53tRpxcqqD={T?VUM#dOy8L-rf; z`7Gd@xSv>+-)Fyu{5T-;hxv}--EZ(AgU1a%=yVu-z+lzuKK{mZ9I$drR^BTcv~PC* zna$@aq)zqIwn#6K?;Y2XUhV&0UZ`xF+MauN2prR~$=a9lg-Bk z59Gz#Z&Ki_y^aZ7-(E*8-xi6nZZ7!X4>C9>a7>@*+p5(Ya(5K;dV7U2m1EZb@Qtj$ z>$48SYkH&DZm{W%VynR_Kae+p%X?K`LM5kkHqiei+b>!INi6rQhVAw|A(-{|KugQ* zC_jfa_#mZD`OetwYM%G#0_=Vqmh;^wGe2Y)v+;FQ$5prE_?;>i*~pFqd!q7nzXa@F zYd;+?F<&vbv7O@UM4_s3O}aKijlwdw1^8{H||zK5B5Mw&%{>26q{(f|C?`3?8@lcNt9V)FX!s?lD-`Q^U?a zgOBL@$~K9yUTE+ZgO3@!$>5^~?=bkd!MhC3xxO&CMc{#*N3A^5zmHD}94bmLzRO~G z-eCC-7<{wA`wdq6D)ZB*eU*7+m$wHmDY&c~6=E>OMVc0sazMD$$jhpg?V zhq#}6Sjd-kBX7q(w4=+#FBbcZ55H;j`+E298ob8df7amp3|2n)dOG{d0TdPMjZKhC zAFrq{7U4bRs0-yMoA(QzWb?SaN*QMOKu<|S5ay$7-O21xThI3O*O(6K z`C7Zl`;psq@%q$vF}%S}kn-7YIN#38F3YL)TUVq1H(lF6|L0346{{*uKYgvh`$qPeS+-k6)~DHh#TC-Vap2ZglKYK8}9X z=-8p~*cXfr_2-5?pEEkP$orGg;o~8`b13QEUzgthV&6vzyGp`u^65)xr&yl5qJHA% ze3|Z##J=kh`C8hf9x3VHOCh(gGZ>ieAn~yiAf)FE%`Tu{>Nwhi`(-HK`JCPl8>(G` zH!P8C*gvRtO0auMdvOku{A^U-??&ahzHxiO*QLtl2U%a(gs)$PM>W0UP3(T~jYijyt*0g1*Qq>I zln+UY+a<+KLeKKqdSQa&4f8caFn@HmueDXmXSwW;9+!<@y-jmG$j=j^ z2f`k;v&(P1OkR}lXq7nhXu4#M*(sozA>65aa6fJRe#k#nI_}i;el9#&t@=HKRStX4 zQUUS%F_Lb5?)yNKZncYg{rg@fPdG;+_EM-C{fkxK*Qe8RaX+M{UuNxW^UV7FsGnB8 zj%)hz7URo%jW1iZUbug1O8McklDtTEo87qB{K;)O8chyv0s(J^AEMH({W&TzsB49 zH16)vcypJ;p{n)7ek_BPpF?dc4c7J=YP-f@ZI_|84uh2+Nn5+Y#*emEfg!gVn|}f8 zox)f5E4cnm>#x~!W)*hw&v#D8+awqLk9j|>qLuQv= zCmiv660-e(BO*ufck&hkU!(iB|KE1VQ}v*xPxk{Ju>7P#^&1N!J)cK<^8Lb^eLd_U zGv@m!v0@Aa-#f_Ks z!K*3hJ7AB|&pKJ-XYIh&gHY*EyUEtOsh1{^Kc9QI)^l&CzE^dl_7mO@84Ulf<;O#W zn9f$4@BGE9C~xhOuF(9lrV`SzzcD6Vr8j5&nf1EuwoI;EANaoM7(e?}QdB*|bPTZ{ zlad_!F?%9^xa%9r^}?U(SgHBdZjQ^@B;{CttT2`O14k&wRfAEOx67~Ig!UMh>SgzpkC_W$kVDQP^wa;s&K7jHz7}(@#2aubSvt;`#3N zz?06;RG-(|TRuMhx$5yTEvH<2erAv6Pt;t+c_9>lkgT+E_)4WKv*R4^mkh6_t3N-a zecZ$Pn$)xYypTS3ze{<(*$+*W5|u~B>AHgRd7jx1kW+^Gdi<8v zL))c}Kad56Wc4PsANE*#tt#pB&0F+&uXdU+O$&F3l3 z7w2Oy=w=`+F+e`)b$d%+<9;8jPp`?DzgKaCelY$#pzR(umIU8W@xwyT(8^s(*XA7> zuimEd?kyU3Z;}}P8?A48&PDm}_L9r{P*LqeoWGFtLq)X*u}{+St6dl>#y|5DCfm(E zoMZN3MdcWN94mjn;WPWt?75+$*@w1XF=Xdnun*kIGyAZz&0w_;v5&-HwG%@+e_d$h z?XdUr1RiSJEpe>xI4;C`S@iU%uvhvo^)&4*HX-%lE3c~`?|Yjr7e8Q(*Y*4RKFxLC zakHOvKZl=dn2G)M7{}ez{_=Xd{qlk&6kGdfSq&ewFv z`+C*?G@sM^wBcVcdrkFD(yEHj?Z>2bzBG`p*C(y# zD6Efh&!{T6r@xLhPs_J;G+$Sv-2B^5XwOb}JR%iJ_ZK{}OW^R{evO9@*!yjke!s!}3U3*=blS0eKSLN^Z|OQU-9zgv zU8g$nvjZnt!3U<6;ka{nOC&1$~)$ZNR|R?^+KOP(k9jYv#8pan0;7siR5 zJB3}X>2~XQmTcZ6aN(R63Bp)U?clg$i14oFBCkK%kNDGd7YVJ@qdfT>0K0j}euH)N0Fx?+yeiT1v z;rvMbI4jqQ{F5*E2fo<3vDLayEUy1LnMY|q#Xhk~QWn2o&vAPXpW?amX-MJ3&byKy zAH4$aqkhf#8SECJqtJA>(BXXX`$M^2xrKNiR($jab>S!X!7k+Uiakdq77CrpZ;rz~ zc*SymyLW23L*f@|RsL7&)9*uizdtLzw>6!2?NGg8eh~l8rTeMfP*wRz+LTW?4=QvgZ8~2J)jorDo}1}6)n7QLZ0}9KRo5H5 zU(2z5TIqh;B$QLE|wGDx0Ze<8A9%M zUCXs-FXJ!U@3v3TZaXY=WPY@(kD*i>3PPT8m@;SY)u2tdmzPggaizPYshb~lj zkK#=VhUXP356Mj?H%m1=&fzM3*x$>r7S&-5({+)GwiD~eoaE<9@}ttP^>aOeeCR&d zH%u%%7lV$5;PyniZna3u@3rr;Q7@K|F2?^-;kWWF7`}A<#LDZndrw2v(<$C8ot0zl z>w1CZwbqnZlKON$WA!;t@OPat{I&GA2!8F?z8@{)H!6#8I_>eZ% zf8815PYLyn<>~vx|AgwTFhFjoKSJcy?6BS@FcBdPsNAG-Wb10ZcF%~9tBvI7FHufD zryVO)4@iBobNBldZZK~;jC^KZ3k|f)T`wdi?@H~9Yq59Nh9GCNY+C9(Cn zbX|0FpQJD3bbc1wC+lK6a;=s(@ga+^(Kwl-``@Uie*^0Tem}Q=Z))OROaGw8VXu}4 z|FM)ialJmz>_+XEIG-%Nxd>6>1-ckwLbj-(r5Ob+S!>s*stUJ zu;NRKeG1$C(KEI;Q+rYU1tGO34=TQ$ARHmJHwU!5utw$Hzmpoqx~yHhG~bx^kEFZD zV3n_=+w9M=4oh$L=a}|8|GrBY({}OsbFllv65n4nru{kTHv4nT? z*{QGjB<<93DJQd2M--lcojRNPxO&j?oBmDrH$nj+P%a^YQhpQCW4+n%Z!-JzT{ZUU zJb9nlr|%Lx*?r0_%IDNR%_*GPr^h9KSS;CKpH3>gNAaHAK3%W$O>3WOJH_MP-{OEt z>Q8cggzC$9zewpg9ee0og1@BoI0N`wK~hZr*93p-8N*+y!T(2szx|BiuciO@1i$w4 zGhr{*(*K)+zw;TR|D%Fm_1ZH*|D%Gx=Opx-ztQ|MnLV%ix3^grg53_y&NJ^2yqVp( zP2mQ1=P>Aq?asGBPJ-V%W^x^DzVF}FuALvI_HZ;md=Pk3yH2+^)}0%V_2&_e>o=fq zgo!&XR`n%%YU``npC?ss7fsLmJpg|0*Uo=q-?Qo;JD2SKl=8Uh{jkCCS2X5$d;sOM z|CR8FdihDvK=X?5MvMJBF+=Y|1_au142{lz&;wX|?%VItPWfW<4*yB6~&XXW@$_#~XG zc#@SP25Ub^R_;>R@+HL`0>|U9QDSwyXIq6%3_KfM@ zkM)tb-96n!YLO;&EXnR(^V6e4!<#PsGdsjYX zu(mhlpIs9Dy^il}f9Es#`_HdHJ@y{g_A0BK#r!P+57S-MpdJOBOkjxh<~4w^ej?9t zp2zgmSH=SLME>-pji@Wb?C*tI6m~FTtDB$@{VIn!+cle$H&RN z{X%~jUsqR;9^>1OkS~+deknJu?>lk69rHPPo^0>bcyouu8UNY^uIFE?Jcpl7%Evi8 zgL@3_GFa<3RD7qwrjJd3#`>ZK^u+!8>vz>gg|A?0s6kKS*v^=Ci#y;F)szZlW?`*d85&!heq=&SgA)Cvsb ze!e2?RXtG1{hA;Ok3&EaeEq5ZywvmLeY`LEDD)%S@9CbG`l}mMUvhrM{(^s4S2j8} zX}g6`l5*L9t^@tC+;_5nZI#zkzKi}!q{DrBBEKg(H*^j0aj-)0@0ahnd7+ku=Y{;95z_w>miL&J=jFN_r00i>o*ADXGC6R%-QH*an~kEDFX1Qy zd9-oU&jS^jVH_g3|EAFNa)FtT?U2u{5ZKQfIo@QMw$DZ+qC^hax%*`Mp`SAY_FYOG zx6?t$3FjMo@t=ISnf?nE=k%P=Qrt7ma{YWu*r)m>mglP=&*T?_w|jbi$nJ~r^H=_z zdf%6a`_Y812cZoT*JIxg8d2R`IE8aV z-^A8Gw>QWy_5ijASw%Yj2j5$J^L?r2{nzl``!D+w=}-HU_4l;@r~ByEtNy6&kQnQ` z3Xkqmc;yz2uh#zP?Vntr4LJC)+7Z}Srgp^zAPOO$Q@>vM17^QH+A7b(;}Yc(6|Y=) z%=n15WvD+dWcT62reb&!|Ji_kPN)~>=^5N#?dO8h`>~Zg_>+~s@}po9Li%1H$n6}R zcObunHyGZll{F>t1S&|3X4`Q(KwM)~5 zON<{kD9nDx8fNEz^nR6O^LojjT%zeH4@{Syg8|Hdb3jU$p9Avqm>(|5`=Pd5#r{e2 z*X%nTYSVV~dq0!S9cnLiw`;t;RbuQHPmRD4J%=Ktme-#Vpr*0{aHE=~?ndW;#(6GwRLkW)Zn10kDD3(#J_j^;jqD%z z8B?U=dwM?oSA-*2UzGVm<|o$s2xhVm^#S4>T9V=80DcrzbdKJ=>?Vebd_j#wt?-wF{Jnm9n$geN_Hs)_N_8sYD$ma${ zQ&0}4j2AY)4I4_54(BOFj{Sas+Hzw1pW{8tz3Fo(cU}cqi8AbK>p)JMf`$Q1q4G`{ezdd}r`|aJYBF z^jiHoru6@)U+kd$>-xa^k&ROxF%Oj_Ol?pXztWCmF%?kHWMF#ie{Hrw%B{sx0#)-dKUM<89ueo;Wsqc#`%iMq3d1jceVGb zZ-?483w^PEsvVz2UyW+JxZN9{zxsbVGCQ{yn-M5dF+SJBfB6ZHYfs?M zC^R1zJ)YUU|1PliXX@AQAYVTBFY+AgN>YD}>oR^|o+$HaoI^2K=iRUm4Ayz~!1%`n zJ{|hM8quHnH&0-%e+lUu@$px|$9(R`XQV!j@K>XDO6M)OhnxX?lX7P=Kl#Lz`hHLH zW$pAg0>|w%F75Q!XQW=I(@u|1q5IEVFIc_xzLb3KkL&u4*s*T+JtXWBJK@1=z&G31 z<$BfaWXPS>SM3?MOOiH~&oHXa=Qxhl%qxHMx3YO=Z11l_7WV50ZlgRNkp4VWyj}ZeMb{CN;+W8Z z^OUx3@^OPl4E~hC;|70D>Au(K!8pGIKWqDk)4_99BbTeK$Q-2SMf)4s_b(QN!Rik` zlhT>))7xgS@*Da|VBg=#b1$rKEgjfjCiNyA2O>KBToLK{2KsUReB=2-PmGWE+IhX$ z9~W7DZWaFSl5*CfeM@-0(c(hWLa~q7?hIJ>5W3xOKTv(X^pC+dlhe_&1kU96XKGJ$ zo1E|YSA|zwKNvY8qTuf_N*<&nN$LAv;TJLZ*P?=gAr_?fOBO9ZepOn!A-5BoX zYwZu}56UI^AKy289CnAd-%#-m;cK~aNaCU5of2cek?_sW$I^cb)=lB>Jn)D8sHf(f ziJizy5j1aV9!bA~la z_)O@$|7p>=4W*!*wVNb95uJySf^@!+>DO$L^pqp!oC$sXF@5$OhLn$X{s-sYm5;V> z?}Jhb_;R!U@b8o3zBo-++$HhF59)ir=P%j4U*GROAhGKqzwftjHV8-X^*#Cv1V%r{ zKiTg^_$}LB&j|8;i^RU(THwHskje}4GavbLJ?iP}wY`4tkm(ioOEBG=UZv?pzJ~=J z$1kDR_pvkG>)rtUz4@@#XY(PAw;z-kc7~>}Xnyuf?(=m1`1(2VEC&yR?bqbGEa^@8 zoqj*|sN%Qtu2a@ifS2RXbl*o<`1Y*-F2v7uHTwDwug&Tkp3rizPfE%woHJW05X;}e zs6WT`_$dAJ<5vH@%9pt+zUg|f`;+5*OTfpuzMg9Q3{{n%#O?{j{737bp3~NHk_FyA zDp#R0qIBE&%0_y;8FG-yZ`3~Hs2AJg80%5d_6z$|PJLg(T$`s1ZMAlVxUszwljm38 z`w1yO*u7V8x$L;W`P~0j`d8cd-L2zY(q?wY1y+w0s#n~u2`l>LMY?ZvMUTOUbbMaX zWw6;XD>@DC)Nx`(hru=;r~6mcF3R?=>UfgvN40Tg#X`$}*vbQg5O6Nn@V6MO<9xQy zRqd8=RiC^M_ewNnT|(wJ!}^?j|5iKtr_Xnczts07B;or@ASY|_oA5@9dvn+07y8RS z<448nU9tLBl;7ANC-f%w9ngB1{fBh`8&8cNHm;`gJhy|){}U?OZf=*s52koG9~8Xt zysWl0hc+tbCs3ia{LIRk zPqqS&wX@*~Pnf)}k=Il9y-uDGpXw3cALe=>Zr@`K^Q%6me)Dh*eqg>Y{PzCu`;Ovt zP;2S^9^T)>hrnRwAJDkaRKFi=J?v)UdAjz|1(81G_y)D|RN~|6fc7W1Ba^mWKPNqy zze*hIS&^SA-$EvuF|P()l#fqh!~XQ^k-pBQ19gn=a5P_y@29>MzI^9LYCk%?mBTV0 zzRJ3_IqhZk1D+Ku)ZHVrf~NWh4)!I-D-N|8s&R(ndyxSwSIn2PfRbrzY)*B zYS&TU40)N3?qs{sxm)Rv`^!Q4OCr7sUxt+q%A>EN_5goO&jHQ{x7Me7E$Q(7wm|C_ z=VLpv-TwWbryWAn@1gE!9_X|GyZh^5O*oJyjhK%8Od1fI`z-BzC^VbR30z z#CoZ>VR>pF#pS(5%3G~??H8Lou`QL?~2-k>90n5 z>Njfkllnonx2XMdUru7?qa^zJ3i;UB|1qNDYjL6E%lwk_6nkP!Vej=kG1iqV zU%Nby>ml+zCTz`dADrk}<3q6dHTU7sYGyre`7!qqXurz(>0&_uJ6-i%@e|UIL)G+Q zo83D;YI-f>C^5HDO}r6r#biF=V%MfbFEyhU!my*Q(($1SSfVxS;{)-`04HB z=biF7ooB`Ji>yfBEcoK*B|P!(F~oe#nLq5?ze)eZxx(l2zOM*B+}uu~~ z5!m^JeQg4h4^#bm$E|)^KF)I(tn{H@3Y^Kews*aJo1U(0vHDFKo=pa;Tn+7hO6fwg zka5Jz829~Zy0((mW7x-wE|sfcFi_IjInngKh7Nl#uYspsVLQ)3zK^^Nd}AR9gm3K7 zatVWfQf?ua5JdZ^|24S1V0P6^_T8^HJL~E0yZ?t*DSfoB>g<-a%8#(FBy_SKJ*Y=4 z59=a%iS41+A)TM!InloRZsMczL&%F467T|rSE0Qc@4H_o{0lbzX8Z1^|4zrNqjJ3c z-QM+m;xpc7Usn2@PTG~^AN2;SQn%0E=HKZ)`?A^()9$lhqjKkX6Z<~HM#vL$4i)=F z-V(oue|L|-al74>ANAn?c@6V9oAm=?H4#%rsaiZ2oORjNhG>K z$_EvU^SO%h4|FkjzfAWfS^2)tul!!y&$UI%OZOe!r~8B4kDQ)+uzpFHVW_)H%iG?m zvF#Va_cj#veL}YWn56snm9N?UeQnQd|Gu_cwtrvw;`{gE$5Xzvnf+?}_}y+zcI*7j z^>SK&GKqB0bl<-Dr+hy_eDB{5=)<%hNAsZTpch##S>0&gKJ8rCC(=J-{W{Zq`y8LA z_?Zdsk!q!SmF+_jpuYL>mE6y?UdnU(g!VGm=kmG3!V&m&<$byiT-l-U4DNS%?In=M z>VC_wf&o9R_wApI@1t5@E&E>{=7UwE2Vx}m68N}@c1JZtzF&x`c!pABJgLxhoxnI(DRH@?`=SbVA7wmm1S{(Nv>D#3YVf|?@Lno$t$f7(I`Tc{*DJuU z`u#fH!r0V)Grt_iQLuQ5T=roez1&fK_#!|G5_r18VZn!(&pp12T+b6q+GYCZHnPmZLdB_~JT_ zp!VQ8J~*Cs9kdkfAzCTfitEe)aLJ= z$8g7+q@F?d-E0=WGJ7A8?VFFuHsgUGfp*NK>mLz@fsDr_XX7i$uYPy?DO_Cq*unh^ zd5``b%A@tK+`hs4CFDJgSMvAj_t@;@?+(Ai-UCz+yjZ{NGVO<4s{N45xmh>|Q_5BR z#fuC4A-Snr-k-1ikc-!G+}#7Tln6ynta3jXf8)9SgyyjDr1+D5Pa5y%atGs2-lzE6 zAn9y<7LZDhI}b_y#p?KzdfoatTNg~eIvzVuekS#Ag#Nk?U;BNf7R8^=Q^as4=&^k< z@h0uZT~Lts%U5Oaw_5Pm!JmUz$6w;>B|doH_g)@9Ocu*`yC2%dhfMF-`Wm;cQ^Y3S z&tv=7i4XD6IhG7Z>3r$;x&7^m&v>(Zk1yB$V0(e{b+zg~ln2&Gzi#pT$M zH!6CnN9>y2j~DCtpQQiw`#RAljV&A&dv4XZ(Dj+LpZ!VKej)@tL-k)@L+!6bhZ#hN zFnE*V@0qoyQu!A>LponkM(5iVPV1-N%5l@npko`;xy0{_z0$AiXcaodebTQ>=64Hy zHc7wE&Q*>#OTW&}o3?rHTK%ik5B!v@S8#sdCpaDkpO$)`MZS4n89x6(^pKOAPjNh? zQyjrh155FjLh`*hoFrkqQ1mSDUZ7XN`<)jJo=0!j^WBo0R&}q8aeMT zzC-tQZ~aD5akhR7H{9$K@C6%KiBp1 zrYbxS7m$qB>5dK1)qx)Z{oJAFmH6Xte+B&ZA~pFDl&%eN?H}R1nI#l=>qj0Idi(MX z`hfn(0(ipHh)*)*Q9qygs6980_35DcGxZrhi{wk=DZWy|c&3EOaUPi^f&NDV7q(6EJJLU+yCP&Gg%Y<*5v>kTuT$93Y_mVV8yQse`a=B%R$YGD<1N<8@c6pW3VLc@Q z9X`8+?3Ui2MC%GUKkau?y`%m|qw2#R^-FX-$?%`WlTY_G+8_H2xng#%Oc=~&0Dby* zQ@YshQ+izCr@`f2SXWY%IQXYu;r<}O?eAA>LAr+|o!@V>^p7LGhnH?|J(^!`52Yh~ zF#i4Wv-;)j#J@x7mmg9&D+!ze{cr0<)AfyALa!dxZ>m>(_%;xHzP|ish4ScL4TdwS zu%6<4sy7T?!}XvXJn+B3akP(0>sS3$q5d_Q`k$&$znyRE>p`p#34?32{OtmttrO`L zzJ~rdh0^)$&DQt#73(90=JNkj+C@?Li|M)&@xy(13Y`A0IK9pDSihL=WfD4zcn1Es zEYsT?C%6Lien|D&EmSByK7BS;fVVxkm($UFKGzek6nV9MrCB?0DD?lg=2g)DlNF9z z3JhQU^uMeRN^VlVzD4on$z9eCpo`|~0oaw)4xC(@9ngKchujVr-kg75qyC>Fct~0V z@5!<;jQ5TukVfKPq7j}jIFG})i395QtNj{I@Art_PZ~v@eYqM=|BoWRje8^?ov)^P ze}s0x+b7NTQt{-&VRisl`J{HBnH%cUpY4G2ceOn=*n^*6NPOgtTeCe-`K@FR{tf9p zzGQpg$#p+L2K)FUO6TE6^o3VXR!@AL+83K%xApH{xdkn^v4Xycc(z974H+@?2mWUw z?Bn*04A$o#5`FuyPhafovUTD3{sP!3-Om-}PT~S> zKULhnN9d{NX-1=j?sncL>cN9@`ap*si37fMs7LwOU$1s8_3>yNN$}7l>6cP^yh!Jp zBK~0e>0NuLN_yK@f_8t`+ZPXbUP?)<-9G+1>Am&0+`V7!o`RjyPTQY3=-z@I`d#p0 z_Y}~13j$}~dTCFOzz29~+XK%lyzq2tulkwUb`*QGAFTYilHe~;5qD^aedX|1Y@Ms| zUl_>zOR@KxTyIC~Hi55C_$$5N_9=ev?&sP3q{NqRkbKQ2GQi1P)I#`Ktn)fosGZUN zxb;s5s`6`r^AE+Zgbq3vRruBC6XwS=I6Kqr2docwGknj4A1|$uAD>faemplLhesMe zK0W7u5kHmOd3_bdUlEYH1>1o zk2myFJelvU+Hslb)jDqdj-D?7Qz3K9BNhznuLa&FSF}5o<6$ZkY!A zqjq2SE4S0S5IoV?(>UEw@EjNto^cs?Y=4O9|6{lwAD$HqkHIbc+@2G-qp>zmDfY|9 zBU+H+@pvxR|9&%nmvU{t7me?;ywLeJA~${C=a9~~k@zODzwUm!&1!#_i+<>67QRX5 zs-0b|cJ>OfvmJU~0qiC)YU2`SZ_S>jaQ}(x_2EXo^!tAPp0(3HeatV}cPjW!+7abW z6n(f=_=e`KqV`%hg=>w6h~ykEBc)m?bsxbe>)xBJHNe%^a7y9@7cKI*eywR;rt z{+QLBAHn+{fBp3r7+!pS$&Lr?QM$hz{f7Px(*NJOkwZVua^2R}DZU9^AL z!CSsxX&t|(b3Y|~U=@eR2TId;h09mI|4#Ug&ckOoXgr$J#XT|(P2&_UUpd~y&JM<# z(0?%Agg*x3Z9A9mx1af-7nqg#56H{FCXJJNf*gYG^ppAHd$bRP_8o9JbU&BC-#cF7 ztpX42_mlX1;mDp><<|KV|6na?TzMv`GjZ#QH?bA3$U1!TbG$$7HO+NAo0jSE=5Ym%%5Fb{PCS z*Nb&u`>32)=k4rXFwA=b6N#9OAQ>}{ViaE@03moJcLP2aZhYm3dfF8To@^IFFBG)f+hkCQ{o#pX|(J>hhDiGduy9Htls_qx9&$qG^l|!V?CHEO3gv^0iWpG#WdP^#;=K$fQRPAq>vd^k)UosL|N@0aym5Sk~6%=XYeQZ7Dos9pI3l)b+RyLfzHa$GewB=sR70iOc;^oelGYizr=Z!*bS`QA3bBPxA4IAnJ!E4FlQd5B(+a8?^qj zgHF!BjBmD$8vYbq%lZEttl%)m@5A7JSAUV-)4ChYKQDMb#XB3WU{5Y;*w6EaQNw=) zWR|)8@bJQ5t;;X*D>Q#Q^KaDfJF!y@zZZQ^aD#Kg;7*rM;+JT?%Xz*oYWQ{V60YYr z!8uyrOF3Vc%O~+An(vjta!&UjJiZb&?BkIb;0f=;;MFdl#20G5%lLfMsNoku6X*YB z0KJ2JGdN$T%O~;qn(xv8_C0F&8T$!Q!_V16Lq4(lf=AFr;xE*EZNXo0zMljabNJH$ z78LpLp6s=&PvXzhe3$S^P*KB=132wb!@sd-fqbhtUz^J(aoL~ONr&-~dq?T_1TWz5 zY3Zj?KD-Zui(Ed5pRDy=OFlgE{UAVB3H2aO>q}gEi9>UPPp%RB-0)r2i%36#)1Twg zOI#-SI~%U%lTV|DZv~4f9nxRO>CbZMC4Q`ye^t=I>AoIZr|A)=eVi`6#AV}sXTy~| zKN2;3HK1W8F8_I){xp|f;_Sw;oE^>SzQ}$a;6dE>If9N7|8IJW_P#1uKw;GIIrdPH z9&y^A>&ln-Z|N=4FAJ`sFlzY6;7Sg291nx3E8a}}*Cy-wJi|4rX68~3C-yYC0ja2@}1I$ApJ>ntn5r$S5E2F!&>X2R7z}_}^-} zck#$H(sgpWZ@F|5f4`>Nz$;*p?)jWf@Cdw0e6yx|hx98b-LahR%lsbcB)(D8JAyPer;$ zPWOaMC-FCHx_kMgIi!Q%5C$K0=_G!irn@J&nSLSNt2y0=Tsn#0t?9ahGd10dI9 zC-J{_aY7Z*`j>j$z|0Lv*PLZ2SIewe_4!uz2A zIF6%LQvP`yhZIWue2%YlaoG8gxktXQ;5f9S#9KICbn#O;j$HD6G{>)Y@dl1x>EbWp z_^VtT_SyQG;HzaEZ+G93GGwny%5UO0uq5&69KXcHPvAJTl6;Ri{xTQ8nB$Nd`HnB{ z9Br!q2995V&)iP~W^7#~;Clhb7veL2pTqHUUHo#6qgC>KJjY+`;)^+cwu@iKad3g8 zKaJzyB8iXXIJBL_QIp;440wRqkfDE%yDq7#HVq5s*7L2aX=~GCvqHAllT&j zLmNu`dX7(UakSJQCp?DZ&vD-uavX0ZKRDCQ(*V5CGi0~$ndu40Li*3*;4GW3M*5pM zPCw{D9D1Ou@qGs@j?nslKqqp-qzNI(l(?=zYCm)amWo`Jy=iD?Zr{=iNu0we_Hy< zw4agN?cVFT?{54fFZ+|z^$5rPh3h4z0zQy$HL(Vb1Mqvm_fTdWLiE>Y`3`2(2S06J zIp7bv8}a?qcw^^W%@(&by?y(!0D3zKEfBCYnvp* ze9sv9$#OD#A^;(LYC8M|Ja$g=0F(he?~uTS1H$e+&ZD0=pRKo<0;Sq5U$}kZHo0}4 zwmx;*LP_(41nyq;*+prPotKC6s_?Xvox@}6obE&6^jr%gMGxpv*1qD=?mhpYKis~e z#AYwj@=lSs!8HIQMvu_}bU%L)#aHlahX*GgJ@OvlVcx@^m%|que@W$PFY{s2xRXP` zy~CS_qw|~H`|j^*Be@(IzwqS=@@Mnh{(G#)^5qoc`Dn*Eb1=>&24*W_UVqud>N=+Ao8yYV`|-knC-cM+~B^jT}{T+`(MY$w@E!X?T{E9l&+kLfP z@B6jh)iSP?`-qHdM}6bV zQvvZGW~a<*7trHU(9_ne*@R|R381NdbDqR8U4=I`nJlrWbQM0^v9yy zSMp?r>r!8Lnf#rm_5G8KXXd_?NB^!K?OITV$CI_5ugN%QZfBlci@Ma)UB(|1w4SfZ z_-XF*`Negrr%)!>M`=A@k#X1DQ~B%aRL_bse)t1BbDg;_%XlsE!)bM@XIB{?{9Nn# z5|86XxgB}*%j>}h`^xC^1Fh$a!2&8j%6&S2Zk_5`Uq+u@TF*`yS0?>%Wu5BTRYsrB zYCT`z@#l#2!zp#DXF-{s{d=wF^D>T|+n&dWLOtj+zKlLwwVuz(_;>E_^B7O5M?Krh z^ufEeo~LBooa_b0Y3fnWKCfRy=L=~)pOx`;vKMF6sh$;O@^d%W6Xia_H=?@j7vqNcQ77Rk9zi$$d}ru8J}IE<$pOpu}Re|9>uzan*XjzpV`af7Ee| zr}E8pD!))BU;m-ye>RVC-+I8mudMtZYx$qaV;s32<*zT3-|uMo|CqV<@#Av!J+&N`>@~FC%TPQ2{zjF1Gw_Rm? z_N%&;yQ8e!AJ?ti@nw2)ciqYj%F6v}-OBAQn3lbISB&ciqY@l$Cp1-OAlq=11LBw{q8)m3wX7%55v7 z+vRmDcYPWE%6i{=`0I1Z^yEwH2Jh-Jevoz3^?-Lz8Qogy25(Si-%hGqxf{#yE9<7~ zf`>Bv$^w#ll-pLO*Z%~yUYGu6p^Sh3vu@??D3iCJ)UDj048Py2Te+*t_;**`%3V>$ zzn`mHxou_TezI=m24#5o+q#vzuT0)H)verZWpeS(x|O@JtlYQOt=u_fa&b@H%3WP1 z$7||V?)Wmgy{2yEww1~8b#*IuM;ZSvty{T!%JBPFbt|{K48IHOR_=~6{K|sGdf1^k zWpaVpzundSy0mTzg>+hc^#?S$Ex?#+PzHf9wsafpa=H`;fd%z0X*%rixlwq>q=Lly|?gZ zhI8p?T2I<9=Lp1GWgjk`=gaj*xkosE+#~Bv>7F}&@6PpTT&D3|9MXDNUN>#$x6!>X z`d#-kH;&i1tXrjX4>T_8yXjs!jc?$P=%wYY*Z6*ouhY2P&lC4_YkaqU7dYvjJ$`TJ zdC@(593KiFZ|cK+kgGUddj8j)j4<1$9QO*o?7r)nu#Ue3n%en4J8kGGPXqW&rL z333im!~5$A5AEDav~L_|L^?jdW-?NXJ}*1JM$ZceoMq?NOcnvg`?B+Eu(*VtO7&mP z^-EhTeSe*&U+^9JXVCdEtGW0xJyD=`qn%hkIMn$uFQtX3aes^O>DB^=h6g*x$m+B6 zPwdOd=ZtkU$~j-f zo*OxTN8>&zFV!m?zp+R7@@6}KuSfNO-urC&q0;@(S-pEtMLmPng^+vU?}ODdcFtOC zay|BGhCkAC7>3e2$3m_(pDQP;hc=5IibAo|@n+RWq2QbD;}bpHE9rbagpKFJl|K?a z^m}5^te%W=pOyCJKf__Fhjwt>hv!$6KMdrar;^g2?vv$oNpqXfqgU)m(!7M@MLnmh zqge!}*em?g(JTf$?%l)fPnz%2{ChQihsMQDCe5ofE_NbmUZL^vT0d4NQ~P?yXncXj zMPDb)^EAFo%b%lh!F$r&qH&=|(p=E^ZcQ)xDJw6rovYM*AE&>ucMsQpbMu27@0#=w zhmb2gVeoeTo;}AnzFYWVC_m{*!hh-~y^G5;J>~mT-zGVSz9qGAAeL^P=O@kL`kkND zBK0~yNzmlZHNw6mXv`=l{&stA^&mf~h3fIozx@@NnRu(}nO@N|c7G79uNM8%I)(9S z@@x0R#!gQNoz1_ZdyF*w3ZZY~9E~s2`2IfwA#qQe##{8e@~68;Px-Sk(C^)veu>6K zZ;?O5abM5ketO^Dt%u$vzX6;Ce81<#sQ)P~Pxvdh1KTQ=H&4qG{u_z@#gV{S_@W$E55f;@=P=d3;ureu zdnx4)c~_VCH*BZ1pW)L_{6gV-(>rz#7~ zwsBYwzi>s3_5VB9ze?+0!C~?U5saRsS?mMa&HOe=+L`)=&ttvN(fB85$Iusqo9Tqx#KA#Ub4Qte$)q-BG#XdZ_!5rWes0YAt)e%+p8|gYd^LyO zLl3W;kN%v>tNO1Uw{MVg`vksZ?h1`Bk$UDX)3~%hnY%#a!jH*ZaUA15@xzk2sEznv z?Qb$y9}Yj@kcY?ihaG(Y#H>m` z9A?|;kDq?)-S8vVbGp=zd>-S+#vS7=ZCdUs4Xs^PpTV&~zV{0Ll2Zwx^w_z^&R!}0 z-TwYDs&ChF^1wew5%vvqnZWY8OyF#g^f*TykG03w)5jovufZvBN4%Q`{U&%@8s*3c(-ZM(dOCNPvQ6jsDg55g|L2MD1Dp7La=*w&w!MkoD;x$Va=KE_ zLyE6;944o>@%y;9TjNVO-Zgc#yf?c%b(O{i|H;%98W;GJsj3%xr2Wa%1^Qj^kW5v* zp!fGCQ|IV+p>r~|MdO0+WNJaUZPf8#OL)(ftD&-z|Da$GgnWNyphmPpAFbotj?p=f>?7U)tZJ``5L6 z(MRdL!amOL%h`U?@4mjrxi#PyP!#<9rL)WR5Aa}ojPKX6Tnaq~%jGVCcZK2;v-DVOghzNho7xgI)qllf#Qx!i#Cy#}YiJ(OHN%;jr4dZk@9?h)l_ zaG0J{E`@J>xqN`-awezq`4n<*d}@3g1_e%6+Hxt=nfyed_tZ9i@BHSepd!&vhLQLb zzg39$@@pP<2mO6|znSRW6>sANHoln3t+X$dTft8%w}PisZiRnSxfMQ07==i{Ce zm0RJTRBi?De!GT~+gDbS+v@~RklTNM7wlk94k@*a5Szrq?F7aek-Q zCaYd6@#~uO+JBNOk*wUIbFp7k)}6FVnc-DVe-LtQ}o>Ag2qMu6P?F2e)IVe3F%%;ew@Fe<0-M;<2*B0{hpL3 z3E%1XKTZ*n@ifd+mW}_DE`@#|Gk*a6L7Xoa&*0=ie5QoSM3EDW`{P$~hQ8N(wje)v z=v;gb5kFk>wC|&Kw(}^kv~LPQ;Exx6(rX{!s&$@rAK{^v@wofRgp*u|UGCj4_Mn*% zN>8=*3xnu6L-5;9_uk+!IDINN;nxMcnE7pr=*`}O=#?t`M(1BLT{?49^_;mg_}-UtaJ^7Um`o5n|7L>XLp^Rv+{a5Pn(Lz%yt<3meWPakMCjdagIm1 zYvjCsD!+l=pnPZyn$PF&mGJbuGXCgybVI(BKelpy%ws`MN4ceP?lYASy&MLjR{)R1 z`!xOKdLG_&a;`k3Co!b-AK>qm;CV|KAIW+n}(Q;P?P4p|ub;z9a zk8~1$gQmNiPvAwmlR4d6_&w4|{4S1HYX5D29*S?A|T=)GlhZgg~>PUWR^1~*mCKekLiOmz7n-&y!Wwvv_0c}p1_V_i8X zpd4oxWj$9V{&-_qe#6fK%1!xu)L+v3KEoh?0Pn$fCs8<1M2zkOBK#F7^v8MNN5OB} zLGQsgmk|Aud%?XF-VQ2K=&j@9xZ>aWr#+mE%ZERlG!~?Os*ls_x?`UI_xAbNdSkrb zy&IZRo=WRQ&m}l*T>#b(q3Gn!7Op3`Q`+z2ExV4?{F4jVFWM{l+E~3@WWlQon0XMZYV#UD_E2-{E@v@~io^+b9dlf3C_`6UDRD{f0l1qDcFJ=P-cgm-_vSi0}tEsM!Zb-f!5#aCPPySYLPM zjukn8Fwp~lLPFzjSYhI0`VM-Bd}=8C#$(j)csad8z8uHxeleu?^>dWFnC)?tdl}nd zq!)XE+)}>8ML%P_Ui_Jh*q=duLUEbDD|{||13cle{S7I9DxclCliNL*|980e!}0$X zmMiH$`ux&Q?|pgRL2=M$?^}97y=K89IL6&4K=si-ii2C^ zJG7X)Pk=s(Um&{8=s^7^mmYj&{A2ZXGz)%AztXr7!)thOdWAz!|APG@OQV~6wXbi-aX2P|M6b3^HuL97JHiBODuBY!;f-oycm4( z|4?49j-&L6eA&8o$hGJRc*i77!p2hEicT#z7yiNI}Zx7Q2_eB8ykZ)C^@=jHHYrB$D zrF^^RIPUG|d~wf4$v?zA{0W4Qk1S+i~7(?kzF96T1xAlH!*q5?> zE>lDy;COVHk-1qV-A~xB1cJ)Mec8HMkamvsJAqRY3`Et9q`w4CL zN3}gmv^{Ooo*MM~8Y(Z<@1ht@zI{9JFzIab+sr;EtqZuG>iT`2z*B>M&+^F|HbB2C zpXmOWxNkR?m+JS$((YmPyW&IV6^Fv_GS(Bd)8jIx$Gu9AH!3~4IXs;D`&@!!DE++dzfcW!-{*r#gi>*C(p=`wSKbeYCeI$;4F6Da|7%|Nqc7FX6 zsibK19L38E6fd$)sn{d;Gj}w8gYi)8`7VbYjk|=d>TlWoOE>oH=l3`3JxwOBNn?wq z7kgp*M*Q|><$W^ybAmTok0AL6$vb8PhWF?EdJL~$86jT3LwFhqUcb(Gt=-T2GNm^^ zFYfE-_L@H&_X!^+^EW6Slt0yfkNfuV`{E{{Q^!SJjF;jjp;O02t2rKTn#bvGzNk&( zqOX&SmT0_9>b+=z#+PV(p2nAHT=*s4v`XXRpvRk5XuP25S8H74!Pc#rJ&reRWbAT@zv?;(FA~4&#!Wk=oXtBV-_(ur z{nQPb{yq+GzUV=TpWV+P^dX+qKa%}-c8{8^vuLM&5+2i^zI}X<=$VeM$-c)*>9&%d zG&>5rNn)SQ%b&-^)BSQ|_y?9N0yLYKH#ocI%QzeA#}kdZK*NQcJ{q-%`%%6e9O>g( zZza5-ec&9l3m5>Nt|z><^KBsL&r#zDDGO7OkTqbI&YLk+U4B93MK z+3p(c>Pwr@FX|S)?p-H*of)@5z4R}z@uiTlD0swse>@5-W9e)h%H}l=$2im}+@AH? z9?@^v{hu}tW%_X>a(Hr?9LoHX(Z!e7c^=(tom1&WgdBS8p2@8I4Pfw*9=wO#CW}N) zyOxVQM&a}M`~M`ln?`u3#Mi&0E?7Hr75HZnx9f25$DRWCeQ5qj=U2oY%%t;KFb-RZ z&flkYq9uU zOcx>=JKgUoy9?kC@iXlFj*wTsr1Y<)zFPI~Te-g4 z^sk*uJ|&l7>AJg75ZHdtu*xLj$8l?dL``??s;iJO65C{@AK~y|#?6Pv?RS z-@cxEmq!m9->~u7kZAJ9(7 z(I9zLIjm*AJSyW?=_echeEE8Thu?#rFCWeDqFg*t?jj9sJXG~9eMh^(Km;?&Eo47G z$}Qq~@Bc}D$9TdU@R{}Ze?qFEJ($hye>Uvfx4Hi6_U%6l2WQ`EwKqGaL7r-}H|EEO zyc&Y=N&Ep8^8I~sWjw!y(HfZFZ+7Z%_;s7PT|@hI=J$tz&Oe_e@FuMy=f&w7Z`{jr z-$~~gfKr|LF(N+@4tgTKEl}Dm@)Gg;PP%0m>qa8F9gR#E<3-ky$U2mWz5{;|m1lTE z`KHhC9eyUh!%~5NF(TmB3s79}k5uv<<+$|%^c`P9E?vH(97iwu4!F7+|G@2w*N8pD z{qFRM=3nub@&Rai;#fj|eF*$nw-2jBzQfO0e}>ct)I?Se6?YWH$K5FDrmd1Nxlig% z9@X+EO1P97C-^&o@jiv(3$6#m@(f@RI6Zezqfx>XLZ1J9CB^5_`%BJ4DoRKBk!~r$ zfd*T@3+eFw676rfam9u7k{*yl65S7z^0n|yJVD#jxS#O~y5Y^hy__wW zy_R0k1HAJ4UU?6{1pZAWeBR*U6LN=qv+ve&C^$I0+PWn<@2M)?b$k@?!4s+k-(>`! z(RE<0v}amTLfg-0^nHTxUB(v_2mHVj{S3?xTuP*7`iEcSb2SFh-{@-er~GB~r#RE! z_(btGuu$L%gHJPk+56#shp~{0RI+ zKY9G?s4{pdLXYn^L*7dj{ATDS^P9VlK)?BC)D?d=&u{uJ*AMO%yl4H8-%d;EZ*-}r z-~3rxxPLhP=8toI2kAGT#b^qOGbFTix=E|r;ZbUbM`i5rC{iNy0Ds`;kas_jy{7Zj zSdWaVVu$HFi2#jjSFywNo$WAvhu%f`hsF*cV10Bjc9_JnqTP5OsT{ytrf(^JaQ5Qp zy4vB8dtU?}5eM`d z#^o1##qW0WQZlU=l+NVO?i>L0bHN{WK6;n#|FwPv>c{hJ>;pb|7`=YBhX=z`EqcAy z@rf}b(6iQmGk?|2u}E~?WO2IS@!)F`OgSuPbNFLUDM4W=O-=q4Ln&tbo1DekIGgbRNi=<^5vQ zuh?f$pe(MRa-ZUlh{^9O=-+R6?VfGvDO)A`QhU3tU-AtGAnuiUJHUAg!FMole)^EY z`Dupp31L6>r_q%J-{C{NN#Kt!SVl4Fr@~%yg#N@^gdVdm5CM#PH2s7noFvh6)sp2h zAKS59_!#B0UA$LH^81zizE|D@Z`JtrT^?T04?w=*`jyq_n6+n9GJI=%xRUBYzwAN^ z;j!5~=TfR1dL!N}?Tn5xK6p3d*YV{WIT{RHL5b0oo`luhvB6+uD#y)BdOq;{F`rk z?FL^{!)yFonz)VQw%-?W3rx4?@mKT?LhHx0kJk6-?9fw{p4zVl9ZtK7q^5 zC78BW;tqaYXO-L{?@fPa+n?1-5#b&D?$)Du{g98+dw>2L>uch^jqK9{&)<9x#dV#H zUoH})<@Pc_hOgqpk8#{D7vlhaxxbW`S<$CaLr#F7NSa0E%`!a@iC&OR8 z-1URX-IFPId#2nE(f$RS@2y_05YX@tAJ6O(6esTI`h2+iQNFJ02A=0o`JgB06mRMm z_%GmW0p^eJ!t`uJhZ=J_UGF}yNYdRwb^$DB=i9HO^5#+e66FN^S?{U7uP z@jhvle%3gZ>uI7sDV^|fVtU)`qRLOarJM2GK;{3C=;6~9_8j9qz_YzK{ATe5_!-Y< zP-1$r-@`!8e^2g|`l5#AT(9f@uabPTK`?rtX9^UW{F6q@5Oz)IGwFyi2HVM+~7BUv+;Vmr%=8tT=kzxl z5#sNVT<`}_>aXvp&$#D)!RtY+@2IvO;d0QCr>5t35Z5dG6SV~ z`=->MABy!ItsXwX2dLSN=N&X&O@4KK2bDub58uCfJ6cVCmElY0;o>GzIP^rhqq!W@ zvrj0#1}@^y>~Fu2+LNpl{0(0B(aH(YzY@7`;dtCMg+sb;QRMX@DG%iXZom9lRKC^k z>LDG1hxw91*KY&A(*c(*G#Z^vH!MgkH3dI!XKp+jrS2@&!22 z;(=B4haT5YqL=)>SKdQUvRvIGap>`%(-K5m7vtz}{WZnYxceo&*(cZTN9Fy&wh#D1 z)BJTeAV3s8!uD+7JSpGZ3ph*SL#;FalcSmzgqIzRYhq!7~i#fU2cKC<(W zU!x<|fH!hK4ix*-c|_nfHb3Q5fz#F>0q>wgV(|CK_Xa8-{=0wQz~$J#sq&tl1JlA8 z2G3^}_&wk}T>CN}Bs>kZ|N8wNehh#0oOg_gAl47D{j;^Mi_YTD?y*cJsr>8xIvw|d zT4EOwhQaSeFBttM;VtotN5|bnNASf>%zwK%eMINb5@~{3`0x4}`R{K${1*FVA2ayq zVEGSl`}}tl^Pj#~ji_Hesw-?!btFR-&2|YHYy&Z-&Z^TiG4{Lbsn@w@R>Aj5dO;WlTVk~#G<7hqs!M0fUnYh>~c?S zx{rN_z~}a{Z{v7L_px_1ZrASyPq)Smo^>40^0yDqbIag)vK*dCFJt^UcqT33xXB;g z@1B82{OVZoVfRlJa!EF1dmRW9W%D3tp2e3K|!@y8Sd6`R-UO z>p?o^3V)aS6fc_uUrF;)E+?6EiG+*K<*;imEHw0xv?G~xEyqiGu20vbl^h5E;i+Z4 zr|FM>{T=L=(OJ&vs};hO*Zm^XOu9tHoY#t5ILxGZk{8a@A{c1u768NZ&$4l4g$5J|8PM?#<+*V-mb|*d5W=9g{@C8UNdO zh}~0|s2`Qg75}PhQi1b#EuJo6a}$RqCtd1Sg*3W{4|spL$G=7Tf zFZReeydBPO5PqloZ1{Ug?RJ-*D`e-}*}9N;i`bK);Q07@^m_~rJ8w<+EYb7UoV{&a zBY5dy_Th6Wv+bJm4k}N_>tZ`E#g%VzDtbNf?sWl2o4!tT|E=viv-)G*|5?p$S$@-F z)?cynpp%P5za;bbaXajO`xA6;i{#vsDW`1GPynw%V=y~47UgcBs-<+SQcKmj=<8#%HH>(}* z75+_{)sCxu>S|UyzIX-KlT2F1q3y>{CJDgq{9v>Q?4$`09l$ai0Ppl*ULpj6s%WkI%W1atq zd)F%;fx95j!f&V-Br^H5{)~<1Mfv+VUzA(N;Vh~bl#TND3O$Kmtv#!$sbO%Byr)88 zfd{o`HNB+AZ_kDr+jAASX9Jh-=EbUEE~gfMY6aPt z)Src~tdt9?mCxruyS0+z{gvU+-Px@ln>l3WE;L7u$Ktx_>afP4E(5 zD&atzgiu$2EK$8RupoWUdaps@rr81{sRYmLGPq^jknZDQd_#Y--fNR`k_#ooc@jh# zcg}>JXI9)S{g7lX8D)G|J=Jl=F&ytuJ7wp)Ce73MeW`aR*VolNi{pu&dzVaV;W*&N zV|-%k3h@4L=_gz*{A})n+fTAPR6po=kFSi*waD|v8s+(4iKKQOuF13Qw;oA-wf4Kd z$@Oh#zKGSXW&0mh`(45|70+|Ae%Duj3D_c`!4khO)uE}9r4yG{kXeDE}$nnsUK&4TBPTM$L?I&L5k#o1stDA>$Z^6_OB$5 z1(MG0Em?)sbT1~Ux#<+zerz9K_puz#47zOSNVG z7W7ZtEBp(-dL^Yx^-mMm7xxNYicQ1>^tf|jn>b4GT?}X3JBPz!leDv=@eA@^)7g2k z#U6Rz(J1Y+el6XnE9tlFm2mSO344UT11qGytEb30>^@yLP&-VI+Wr%?=bzt1?>i-5 zyixce?ic=W_v$F$K%VFy>o4SpHy5~m+pioOTsrP$b}GsXVr`vV#JdCh`)`F&FrSO^ z0oSqgJAQmTm+$Uh((#}$C`!9~rQKGprH{9ak?&gr2^G$Gqv)ezpV*0x`8V_TVqZ6h z9rIU7`o7g1Ci9nZSn6BDVV9nR-f_Diq}ZqVH%Y$a3hggGk{S1%EBsyRTOs9dl5!L6 zmnM@I0G&aycm{`EbG83?ZyU$so+$#4_8ZMV13mDB!2IkL$TVMaYo&0k= zfGca~b`gnFJ6GL5|2c`a>2I^c>9~CdmtW04FIDi*fuc(OIf=u8ME&!2Ud>Y(?oX7# zJ=i~|W9bf*+Jq3ke-4hebKuQJuk}HWu525I4a5q zywfOj>%DBf7PX(>>-sgnowLzS%8Yhe{@Ip~-t+p&VcLs)sNY|&g?9gMKCfcmfBNgm z^xRUnp6pn@mlk-*+RLBQyVPEaUr{L?@SfUBk>6Oy!NcH8!Y<9XdFNF;4ZAm47(FiW z=fL<2Al|DmMm7kUdN*b zpF=AC4%&6N?9>3&HPkrHzmQ%vd>X!Mu@mSgpr1B(+W8`h$0C+o9{34wDY$F)nPWMDfA8yl`hfe>9$H9) z()vISfETQP+wPrv2)_I^eK7unzM-sv?W?qN31O!|(Lr>`z!%Xz1U!}C+1OML4^Rkr zc4y$(`cAg4sFgc+c(Bag2d2k`D5=o$9mwCfG;RmVvLG zRKM*HGkal z?X>kK)6{P`rzp6$b`3nN`8y;;J&)c`<0>w{ydP(N$K8X|pF}Fa&dW+3m3p)Co0U(i zKRf<2lg^2{i>ipPQ}}fs_0a6jqi2MD7axJ2y0<|wrXG2sl)!2J@gB=wG>qp{*=y8hQ9`JP<7 zpJ75f-hg~k4c~)}6t)k~@|jg>=~3RDR43{IC)@f*Td$DZEBS_k zZviFo;k%OJmEg;!yKNZwkRI^epzxuk!@+0kx(6Po#Pl?f@b7|sEJ_^hoi&v<-^|~M0qCjp{el@OeGM-t7yI6f?ub9~ZwC(e@egO>AIii}BtEzF;6FSar%Sk$ z_zeoEqedp?r{IxM%( zs&tDWrmGbL-Q^47wujYz<-HyuL@uaOFFL8<<*Dr0KdJ|Bu789C$Q6~$=7Gl zd!YMRLIm*fJo=vcA%Z9KV{AQXymdF*!*d>z_J+YVl#B8eIS8EJ@-~U1{Ew1MkJ}(| zvuB}le3ZL}B{IqtS#p6t!0GSvhKFKuYxo`tf8ZC}mx1!Y7e0Ofxy@Tw!YA-&=|i54 zP3h*-349Xoh_o3hdznQ;KOFO_X1_#<9cvy()h>r>!+Iro%M4c*nY?Pi5AoI=Tu^ zW`FE_Sm)P!e2=p2d`^?AFwpxpRgQgrf@N~&I8^u!iS*kGIkEPdU8o0NfTDgq)%apt z6~4G@NWR!6`0U><_*^T#l;P9#mHEZcA3r38p7I$1N6$FrGuQ9GN8Tg-DbP3fN!;f3 z?YxvIpJ)9I{ulX0>%?w|+?U4ME(J)lS2{1ptx4zQSLcxSF-)CO5*^( zL_4dD1DIdXb-I+B?RSO28T`J(rB7@h#f?&*^=}OC@aNI~ zt|s{oUPs*U9j`TgB>g8h4yp5hwrc-~E7F+#Po=hMi+&>tg)$y=176kD9~&GU~T=kj6KAL=W2Y3vxK(9)SbrI^c2rsUD8pFgK_?t!fKyO>eXXBi{e*riF7t*2pn`V++DIFcYdWF9aCw{&O{Paruu09o1F6VFH z1@Nu_K6(WoSv(m3KNEZ`A$$NopipG^{VT>D;UBCcR^NrHx*p-9I{odyrCbpjvkG5xDxj~8%#W(O+SS%wi zAbe!)ZZultc_r!AGW$bz0-R|4elY&fk_z>~uCe_Yt@g*pVGg7H*~a|Z&Ga3K{h42Z z9;y8iy`J*V{tW-@)40gD>rXbZ`XPURk9_Z0!=c;XPvcix=ReJK00nCcyDf6n59;vOkCxpTbW>!vA!zk4(N#EOf9=%_8@*(>8Aa{_+kD`-$ifPI78eg`IGs(rJO#=pUmH- z@g*E4^LJ`o@+b3maJ-}SNe=B?DQ6edAMy1>wf^nbX=9tMPs2D19< z^ud|FJ)OsJW&5{gCkOX)NrBJ$ezh>y`EnWna62pE}ytn+P9=)4pC+p}r%* zzCOj{o!w0Dk=WN)RG>#{U&m+oXMaZS_G$dtwy#qdj*-~c8IYqY{X4U#^%#!@zYMmg zbO~{e7AiE=Ws?vDu zKGIFlPw1x)ZwLS9jK|Jrd0)bK8;O0|HOjY7lE0q%c>DCh`q=tihtqyfVtXX*8)`iE z!@$QO9FKj3@ZtKyN6>ieUr1!q@oMqge1FyY!w&#Ib+p&FR^X3AIUajMh5C+!@z}2c z|Ju(SiM?J{fgY*77Qa1}vm@1BOTT6$_IfttsEWOYet({)=j&;|ucvwk+wWGfU&GC( zR+&fj<;=!scW1_D8|q}AKR4s>+UFnB{n#V1&wrw+*Z+<7c`?iP$nEp@^Qm4q6!WD| z(b!kEzw~U_=jmnk2cr??<0WQ)J_&prLi^lH_&5^n^U-DascxSi0e( zw^XR_NU+cULPL}XW1p|DK#%_m_W5kcQI5s9;(X~mPtVuWKCh;F4~Knj@zz_xUL6lR zcZ;+a^QYvNm5ukdQGe6cbJ)0IrTNpZPd~i&`9J<^WcGQCN4Nh?{pZVAzDI7K_Y#kr zUN{u?c~{}cu+Q^>pBmOPeIEEYg!cKvgpVW9K2IvcPj&m;3;fj4KEJsFe;i8t{5KWq zI}+^kPiPF#way?SGSfzJ}#{B(`U>>; zzhIv)g&YlGpWA5twzJQ6J_OCZ;<5W?P5;kcBn4S{ODT#s?KwHe&Gvr{=sx%-G!IX1zm}f2nDu+?dp4h2 zFGpkNcv}@H@37kaW7f`6N${JlQ;~b8OC=gOrKdgjb1vWTSGomI)BF5S z`F%&Dtj`_j=huAB{@WqHy&9)to8TFUETu+w|yJiM(Yd;m}D2?T3T7<`@c z+4;n!lB`#=bF-q{3z)yc;O{tHsq_M_Af@l0^!*%u-=6z#DUaHNr*wt5LaX8Uux?A-iE1Rs9A^E35sr*csqEFI`_9F=EsVfV-zzT0#E#O*7U z49~`2ir<{@7w`yGlAZ&ypYx^XfQTJR&jH!1-zgJ4wok&BBetI&AMGKy&94F6i>VC* zU6McLtIr6$6JE_9o}j;A31?3wxjXNul78GoX;9u~3Vr?9ozai4k5c`ZwtH8m-8(fd z^6K^%Dt}el-`;|DdhG_i(B2kmZ(N$kElBLX4W*0Qr&wyy@2ZbW1&wcKIDGuFo~lsK zb5YNl1)Q%`TEbzf_h%2I_f3!8NPVbBUNDf->U!?GX%CN7d_b=x7V7>n` zd7st$J^Y&W*Q+!5hu-()ub*6vQmp(%)e^db+3q}|0vA*&y@tamH(mKJukT;0?}bjr zw^{ve_s*0`(!Tbb=*v>c+GTR7?NPn&>-E2)no_;qFMR0q`bLc_U)HeyH!F|pl`p?V zO|y1{!MC_v+c#tPXW6;fVIcBQDhVFib7sF@$9QSa{ebhAN~<;gJt>cn3<}4$ir|&O5E}F+c_Qv zlCD&`TkAn9z^8H!WvO%z$J=wFAAv_arCZ*>VU$0S!<4V39OLUW|6Z=IRFZt{xu0+x zdijl1LaLt*jb2XX@A(S=wSIlFd^g9Tw;m$?h&M~z{OGt((i`7c`sCtWoX^UuWUs+@ zzJ6rCtb)CMA<3z42iF6>TL2~TEAffh>E}~Ax9_ZRFV`RI{v;Z2(D*#YC!Ketaq%Y- z-M3`tR=E9Wdj3b!IG*#_IU;ucN4mefz~6m1+Xz0teb7ffyi+pmf&}~N_tJSHNWXyI z1OF4beS-gF(mHyJ_9~tyb!%Mc(J^Ta$GaYp4o`CL5{?^RhQTEaFZTD%fAjCaTEX8O z2)5dJ<#>PM$KLo$yubF!vmQ!x{}kST_sdT&#`~}Rd;CE=2OIB4|KRseNB@G^Gw2W%dZK)e z z6uX_mKZgsb1pgO3_)~b~9OD$8KQbLc+I5S9(sUYkaQ|M@{YKIee()H6;tAj$8W)7_|6N^VtJtN(PP8;+k0`b71T8coluXDN6;@h zUEqk1M`;At91iH5ba|h`t?3RS+}kp6pXI?Fk1sG_hZCNi8F*&;@JtYR%-=P;hd3Sw z=XAx}3<*Im-0y@mOz-o^V9*nvQs5AD#bfdn9R(^$9AVe#61Q^&u}%pk8@-Sp9Axrt zeu16amBOWbsBpF0x%Zx&p!-zZQ_#_-%5A!nIJsLj~8fg&#Mrs_p;3FfVW+(YKay>lRv1YkF-Y~n;FL@am9C=@0ms7hWe7n#6LdRacmpM1-zs-Yoh0`sP2QI zr=RcH9MAsrZ)+RR{s&GcdcT(O?7!pmLRjmE9jftclZT{rhxjkkiFow*;~2Zh9@sp9 zorel}!BdG}UsuMjySdz|{7Ps6KboHge)xdT7yY|9e{xedhtU{P0`%B8vB?key_xV9 z_enbpiW>@db`2UE;?j_YeZ; zvHJt<9tU^dt+?Ysu}A#cj^j_`^ras0O}dU3xL{Agc}c721H(tG_e;Va<2$BffCp=* z-Jd#pp;R<*Iu{?Kn_66zOy<6sYinuVp;(NSR+Sfh`v6PR;P39<#0|}qH@n5xD z={dz48IJf4rE`yrqg*}lef-|nGkf57-nmZRFO~9>o7PKwvBZJ*21++@y~N|k_4{oa z-y->Ay|3K(Eesywa*|eQ&%h&+e%xFMOGObtn^!9pMQ{^6Z=(_m9|6qFUu!!pYZJyR4ai> z^Z)ou@bF)1$I)8O#gcBILq5RYN4t{w!asJdW1{E0+4*mFevav>ajJJP@3sv2rx@P} zzLF^gu3(%Tqs4mcTB>L%=`&ikc_6DFOm7*!?LOhFCyG5E#J|f0U*Lz2QpYdeEOCR+ z_%W;hjb8@{k9bUfbX_j;WqQ2p1kn$s=etzz#XZ`-6AGN)=$o7%?N8nybV_a&#z<6t zvihFRZ)Z92`Dq7bF?|QSj~bHGwVWodF75x$(E3hSyla2c`jK}3pyiLJOa4Lq#5$E@ z7s zqWm%Jao`?Sa7Y-)yeZ;@I{pq4hk?wSB0aGly_az;$RFw(cpLqp2Xe50LK{Cry{B;e zIQlDceHF(=F!5c=7e5K*LFM~?J?1U^@|RIORy{b5)+FFDc}0Fa(P%1|9@9(KzXxAj zP5LGZu?)mWj4H#Rhu@4Va5C0^c+nwZ!1o3KPf6>3uE*{-oYo}i<41(Q!SDDr zTm2)u54SV_LZ$all-^@XC}n}hp!*@Qv2*X%0>OaUk-X=qu|5tm-698{Z--a z+sE)vn?Z@_F}P=+E(*@{m7T+!6eS(x9_5lo0^aVxkO<|mB1xpt`BB{yaGN%0+TXyJ@FzrIp?>>O9)H?-^1s9)=Kbky>awE~B; zi&g7gzzO3==Zv`i57(jobJnWf=uvocx<2$eiTmRQ8;7XR`gwl(9}|m@yI0Dw@f5c& zUh!e)n`iOY^^n3t;1NiH(arqxfmpsrV}2bJ=%Y|MQXZh5p zE9wDV@A2Ac^Nz-!rXNPar!mT_qCYxT2)vN@q4k~cr}5wH<8!RZ9NwCwoUHz+u0M_6 zk=8vXY|U*(5!MQLYA z{cuO$Ch1RAY6r?eJC=Cu2!mg-UN*Q7hORFig0AMLJN-k-4sc}YeDHXATix(7v(9*V z?l5?P#yM!btQGnLkHDw#SIRG|E8|7|$&v6&zRq~rPZOop^Z@t;cIVLH<>ht5%a70w zXU|oRVC?BJc^Zj+{FaZG3U(ZRkKrYGYzND&(=)_OtT&xK5eM1nsUm|#_l!$ue3G>% z?X(HMKuL^0rfI&oSL%yr!3(GF)0c2KGuK<$PY^X7_;v-Tf&SS}?X-2V<~M|a7%J;0 z+x=~W^jq=&al5nn&95h?^?U&MR6K^k4@J+hwHTRy)$7wm>FxWyz`M~UtJmVbom_9M z{m@v)593YRZ?Jx`jt3;xFYc56U#$Jp%MBjWx98|ShA{X5 z!yEVOIK*0x2Il|Sx@WZW3bO6vZkO*?{2Kk#xr{U~l zH0FW>1>np4aHYp!J5|{auVkmb?X@SQTXKQPLG3zd{&@|GqkYH2^UraIn14Qja|RV( z29MD(%Ri2O#H5wzXMA(;bUe21bbL=Obkz1|`7!HnowGK_bPI!Xg?<@*QfZvw+te4V zG|mA0nLappeEsAv1uCbWe1As;d}Z~J^+)}2$koV~8Ak|%rGEyZ2Icq0-)=-c=db@) z#q@Shy2+`pUyGFA`K_wAjeo=7Wh}SZ`iClS>5%2!U%5QBZ~pkwE6^_I=YCT16@d*I z9|b4DKD?U-G!fG9?txhSyJVplfLQ0V6J4(s>wI>y5Za&g$8-*8U7duW3(Dq-4}r^#}?_XC5r^d!sWUXX#!5=XlMufdmGEcP&&zn$@A^QVd4 zH);1N#h2;*BCXw=F1}3aNm|!%Jj%VCD~Nly$@f`OALiMCGLzGB6Xm__SGW5*Z9d-J zpRD(YVqS1J<{9*!(lB^27tlTit-yHrSsca>w{YmsV-)BO+WQ#k1B?@5T@38t9D2W! z{>S$_G;9xk$8eX5P4ou)qm&=izExijY;au6`D}g`^CMKXn-5K9@aMqpSBYoftE>+O zAL2I!cg;T2%DWJ+0)IWQl((MKqJISlfggl+-(=Fdj=zV2`kxv2ZQi&&-;Cme0i_4Z zFMRw7t^Lvh}Eg;B3|YUZeI0RiB?USr~Re{Wk2=0N=#@ z`?)>lABKVYZ#~LqI^XT)Yc~l$#+!vtP0rhSRDkpV;R~3Fd;7WE4sCzPwbA@T|1V45^Vp`wEVd~q!-);R= znoszpI-J5U*Xnws3yE(rPm-L$O>ugnsCdG>Df+3MG!Od!*?SZCx{B+5{Ju?_ZDboB zHU^_BjImi{%lpD+V{B{!wpoM-2}sYEvH7m@^Ka{K^F|iU>YFh92o^H~e%`V(EusNMm1g!$Jw5L z`}pLOJ>T)uDNlA@-cKjL>^>7eoubP73)qg?<;r^`Yz2JN$05-w#w<{O?YxJbPcgf`2Y4Y6yD&(Mw=KaRgd(03ieBLTInj&MtN_9=za~Lv&9Z)f6Q+*y@~ur=P&wxznl+o-}_^G4ECNjVJ6wVEB3xN=h4I7 z`AvI2T;|t1bWF4!^$Yy=o`l|-pJ;v{{Uh?te;@D=@F-97P#x)z{^_s;1J18#!S~6@ zsq$k_%e-p$HmhA2|P(dO*%| z{8^Iu-$s7K=XFR#Fn(9~_@ep)j=v*wUU0Db55!|aX^y@Z?ceuAKiJj-)ez$6JbP#F z_uKhq)4LYYD*8v(?jhxi`9X6WpB^?koPXx-kFs^ez{5&U-rXm|agD8CoS$Fm=S#7E zG9CXzZnPbiukqfmGx_r6g8k)tm9srO_Uk$rNb8?H*Rgw6>>TCDIXZ5(t{FMUjkELT z?0xRisUfJUtgCFi=>Lu)-Q-|#BeAsIK1{(TSH8db37CX28gB%XW72s8(`ghCY+uOo zZGV7x`+?U5oDlz>adD4ZFOBU*0)mwzU%(#W@zJB--@x*nY==xnuzBtoz#-tL@Q?UK z*j)y@k0+AXRgxS;>wTwJ_Pr{O-&sKM?f+XL@4kPY%zq5J5slM6XQ!rXT;8YSGcsM{ z@;)7(k?C%n_9;Chnl1WH(r=p{N=8M_`kkEZa&fzhZBWJ^Gp7?+^6+N>)Qw1c)Ux;NzNye@7qH` z99ieav03p(LK`<%Pc&|n2IxsNuIdj}#(k;FH@Q%MU&d9&`7+5r(QzKRV^qe8_-T|Z z&2i&4$Bmn_Pru4>dpI#}uky$3m(Zui#JDB(=^}sJena|1{&K`4{yM&o{2KLRD8c75 zJw8)-O?YdZW;rleMA3DL_Ez*aQQD zP=JkR=-7mc5e7~nwHS|0p~U4Gvm_ol)#=qrr=M;hmg1pRjJJ#b#$75439 zC1H1Ozr8=f^kQeYo9V^gt|5Dmg6S>2#l1}LFLofEzm$KZfczr`=-=6Rro&c^rr?7o=^AkqgJ!EVb{|6;E z|0U(5P|$XZDZLk=2!E3!Q*`&77g zO4ciW`EOqyFR$x^|KZBdck9V5vYzzIwIN)6*e=gAVUOsi1TZe8Ex%B%zGeJM)3HO9J`Zv1u=oVRz`sHr$=>`21 zom{Y4${nkp|KOKHKj}KMpBdLr%9TC$I#xfQ_4>*39jM6oN%#<8+i&;je%WsybZdW? zDBa$;b|?6v@^Ha8yhkUjZ^1ac-$~S`{5oqK-rEy+D!+K?6~XVv^NDuz$j`~@EROf7 z1RmuoC%X!9yh{`9(oWfancwa?2|OH=1|D}Y;`P00!ge{jalG9Lywj1-@p~LqnjNB@ zW3YQ_?0yQnFCsa=Q7;cC=nPSw_4Z=Glk0^&DV>ivf8wX?Pa%rlBQrYe`G&o>W&3#s zv;I$bbdR0GT3~M2tl7e&%OAa_&k@)&tObQH_X-1k$&wL>tQG% zonfS1e;7UX+{x%FtGbN$XXa`7iN@nO*cGcU8b5dMj6ZH~@Wzev6)9;2&2+H&Jb-q+ zn4T??Uc`PnCApYhA@ag`x4*G6U**$(f?TZOk^b(@m2}ptcI4xdUrbla&9}vLD4JVL zHwSs-qU^XY8??F#V^C+b&wb6a7x5|9R{!(>WZ+i@HpToOG^nmW7s>-?6ygVo`n7+34!>3B`SeX;=XJyxFpKIJ5j&N zxvuxwul-)X%}-(aoJ74aOQ?5QRPXdeKFk~P7f1Q`Cg@hW&X4leqa>qWParu=6~ z$@SpTZ^!4+Wd0nKv3az#U+2q_QJqh1ofth20WL&$-1nSpKCj%b*PwonJ7+O469p0c z_2ww%ZMJ&`Vy=H@zaGqR!R|Hi@%8z}L!3Ti^*qG+f84(LVZkFm*s`6giS3(rRpv9> zH!nYYuavWUc+2j4*>;bDzkZPC2n8jW{V0HC<}c^dGi6?|dkV{qidQ~M`C6VAN`m=c zZwExa=EO@tT{Dyy9dq>FP(DAT-DH0xh9ALxvE4tD@ud};IREb)9@uoWa=)LWgUX6v z_ZYCg{{;gP?Z3B6b|imnzqE6BcZb_==D78SrD0-qbQDXrzrggq{^B6h3q##~w*NeG z$3f-q9S1b7)A3}z=u$LJwNsD$Kk8o>2scA$;Fvqwehq3i1s_5{({t3epvgTPw9QMoEOlvjO$x4t~orN zVt?PwKM2S2H~$C5&G0ymv{Q^Z?(EO+`*se@UgYxGOXA`4WulM7CrrLtd5it}4ewZS zh2FTlvA&%Ndg)Om+cCQ~b~Z8*{{L{l+#2-rMDCY+E%1zA(YdPImCts6w2hbL6W=cv z@pm4%i+v#{f7C0=VblKyzdOVE`9%2J47^{4zka#sd6T+B(etMNjPI8OupcM#{gR{q zLOk_XPUOC~p9nssgY#9D#J{fl-e|Xep0Hb-vbevw*|YN;r&qzI*?2ML?C!(g0^L4* zv$Jz%zxq7b{F!KfLe&cA92QD{%LR$>T`J8m`_u(vN_(2m!nh$kC4XVJ^ZKJ2M6pEq zMuqELy-Wwma(^iI;m1Zbza{JLW69`5oyWN^2AjwET`C5)!x5q0GH@S-^)=na)gs!z zOQN9uER7>PfKtxsebYj%fb$STt4p`%*)198XCTjSFJGhmwf8#MKJ&@%C%|`0x91iH z`*@%A_|J5Pkp=7p;#tb55f#&5($5e>Fpj&I+}rNa%lEB z`P~WIU$gTEd(d8p`sd@k+?|NaJCrYWe&XhtAPm9Z_q!Z)R`4V{nDm|j_goA2DG8$S zzXLDLF+pGqLDNiKH%&&LmP-MTqfZ@F`D?}aTnhLK#G{Bycf2h1+WG4};0Yz`3dDz* z@7iU*Dec!9U+6}@(2aOh@U-9T7yCOIo$MDx3HR{D$GKr25)m#QP}#HbHvRVH z_XXb56P4F;_CB@mui|ySqkg%qU_t#}#UFX2wr_IE=Y(88Qhw+7`=C0^ft_E*KH_kh})hWoVK#RbQ2N7vZ>n(nWgK1_Z`pfD?IX` zwrlf+@!Q`|9zp*n%eV7`V~=Tle7@(ePklQ$6YUoiVAe&wBQCWbN~+&q$|y zjjVk^;H3Q~T|8o*q>JZi8LU5?S11W4k2bHcd~c#(ESFEcr0wH3Ysv+B-#&Hb?AI>; z2%_NX|21o?)n9H5nS}SM93R~KSe%z`^7z2<XI`GDS^8KICkrsEZ-_n!wWMv*|WwSbep=XtO zsY}v1kDqys>NXSby^bS{$%jA0KYXtvf)7c)nESxak6Qa2ue$A(dN^L^0iXWBEnYh5 ze+TR)>&O4mcLZC4djM7B>7`0DHgrQ#CeqCH&HrBiPF0u*CAlehm1+T z1@>aw0)_ncs0S0(i!M!=9(w7IgIL-Nw$p-uEQ#&>&K{?)ZS$BD1Px0xrhYF&AjH_{ zXpjAXA1^szM>au%IsUKXQn;*vZzPhy{ zSH65MMxHO9p}>>N=WSP4>Y;qn;!r;S*h{B;uANXmn}u-PL!kC_!1V)d9zNOtyLa&D z;m6XEovcRsGq_+XDZkW9@}+5}_S^KQ75FbpJ->7G%%|h^+_GfidT7s@X8u-;9=6+X z%Eb5$u-8p99~g)K&D_NJ-vqmwX1;wK{>Q%a^9lR)vG3La|4o8VdBFeC_vpI7?+`HM zoUwiPXntnj(eLBzQuLiqj0aUOCMT#UpSxM=we#0@j;+J_UFPq+8)X^BIN>0a&j~eN z;O3Vh%`m@_`uIDEd4hha%@gL&wFLV7&CZ?XQ+%pQ`Flv{qMW{jURbd6?!KR)`=z@7 z>8BrnJ{@cS9wefj7ov6+?(*Al^F91Wkbv(3yd-$Z`QG|#@8MF;PsUiZxb;p>W;O8Z z&DsMyZ)@L6Gk=qOAwBHxk3aFucZhxFhkp3_o2TN7^;b-AlBr8b;33^>}n&wX>fr$N9nDr)IhKlsA6ox#t0MUb$Rg_#hWL z-oAXi;QNE_yND+u51$8ZwhkHFul+K8qMeNSrB|x|NqfyOa^;JvpI170M7qeMyQkeh zzs~)g=)H4yzn{s!uNQ}aXYZp>Ugx46#z;Ooatyw4p0ejzv_lN`9uZ-5Gtwt}&P93N z9Mh{ORgWH);_{xgucySH{WEX;qj69^`29F2^eDgl^e2(-_YYNi{j+gB66t+Sj6Q9L zbi~HRy$|HKLw=BN|A2|R!avnhyC-|(N+*Zz{_bS?UxuH%V)QCMNpJJZt9Yb2)3@wSLt)@vb(q3-uH^WuP_4@Aw+ujmKS7v z?ETgH2PHdbaO-WWx21}s>#bWJ*73FP8MLJCm3;ao47Sdqyt2in#%4`-en<3PDvc5X zzwtV5Gv($D z*h?_I;d?9$W8E6((;E~{jEmVt+xM>DsQ3ddu3YXMSua|B_MHx^ckX5My6Fe&z2k-# zY`wN)>t>Ui zh!5K}-{^7d!v3;;LD2d?cfI=8IXsPJiF&Iy**|6b_~&)*{tT1*R***uTim|J#VawG z2oXPb2pBXh)!6vkA)dIYw^^eajKiSyz5 zS4i)bM<=4!_&wHHq4)U&y>IjAwf$3jj?DF)$OR9>AaEa>a7*eYfd>k;5|^F*DBQ0G zs}j= zerWkV9nbRpQf*LvK;@wPE(kh8`Q1w2z_HjkGStE z*g9k)zghh!=WpI6&EPv(I*!z{!`P>95pMx{`LO15o@BYn#)0L&f^vEBMk@R)oul$x za?csY+O@uSYgCc9guJkwPbJ2i<7DG)<7MO0;=T`^3;tZk$DLEN@1pw8a}J>&CMP!j zEx|v#a&F#t-&wJHd`QnT33`0_tH_PxtJ`-NDCoH6ExkH8B`c(mLHs_eEo01eIN`YYgO(^-~aLG%V$ZQ+Jl(hyY{K?q+@KepapsN{&!>t z213aw4^3(~LU2WDUN zX~cbp?nL#te7CkYUY=EdjnDR;i`~aiex>rPYKwC~I^UGuqy42FAgk>?#-u*mJU5Vd z{%+4vTHM}7D;Pk9h3Nr*h@6LCWcL*31+&akg zC7*KZHJ4v*3YN5@S2vZ-zfexM6_wS8lYp9Bj+pk$*G^&3VJU^eODl6y`}Tq zIRxkb?m;^DKbe16@|C_lpqHL=D`F{+c$E2T-8lrn_#gf(cWEl;0oYISIXa&(PqHVi zhwZZ+wton*ohx8HNJ2d-7vuZk&L?>NnCa>{;?-mOE!NKXdffR0v`0Q1tG^hU*u64* zF2Z^8$M{Zw$@eRHE`8~=_1_%WL1#$v=kwCvS1N zH97e2EN_oZFy603?v6mveLwJca!0)|xuZRzXqDFM{K$P`3n6}ttZx=@WQorEBaKYO zJV0eesJwTo@VI)fbpCO&-YbuY9kqKzqx0~bco9bKcwY1GI3#g-H57*F?w-?@8okG> zyi)1PSKTK0b}v(Tb|^6IJVO_Z5=r1aqWC{3t2vFnt6F}5SeWOc`!Q+7famT@istA0 zwLj)}+Wgbv-it5qbNP2m@tA#~Ut5{~cL@T|XVAWqF7}Z3n@Wu4xxbgM+AerG9ERnO z@*4Fo^0ik>y7iCcn~|~r7$1?GZeVs=3q`R-d8E_({U`{qkehb`HN<+2w=zgeHwqyA_Y0FI~a zhuZfW%Nsem@T>9f#Wz=k?&ch&9CGXGDX$k0=TJ2^eH&Tp6Uz6zAbihfE9F^& zu+l?qs?@8yVS4Y9yJrfH`Zh8ev^N{9r7*jz9VmPQjYFncJfB2NAUFhGxOJt|MVN4MLy|c zdoAw$%3QFL#b7s8P9pp4?5y3hozE(tEx-Jz>hGAc1^rdN)elN_vdh4BxW5Z=INFj` zU#5PC=G%EWtEc?9wx0{WCGz2pAqHJ&mh$zCi;ezb%@1WCPsfM+cJ{akBe+Oo=HI+YNlJC@D+xKqR#a!fTcjX)_^GDwDtm=Deh2-Z` zON7t%oMaF1g&!b>@g5gjxtzR}gm#?W^~dc#wik_?%2~M(A{F{%=Lk(7-1oT4A5gnW zy%l?+#e!B>k3Aspx6x;Gl?Ie=l(P|(vwa(T-^9vO zuU{EobzJRUoP6ry6XdIw%ennWvnOV+ZCp(5Ie(HaqqoA3m(*U(UWi=epBhSR{bo7J zcfQum`*&-;ox8Amf-3e?-)qa^X&o!Fddlv3K|b{tNS_hWQGP_nqjJx+_KSSpit;VN zrxrbdniT;*9r1EX&LFSerz-;F@{k3@_@A^xa z{Icf-*8ir{elJD`?pIKlgMtw4cfMKS|Ge?ib5@g&*SkR{#_N~nzn-%)dt&lePV)a@ z9rwBSLEsRM%XcTw5#ODh+Hb*F5yT$R@8ebV75a~b>My-k5)vIju=_NwjKC`Fz_DrbFG}E zcOj3iNh^_XGsZTpCPs()H=Oup$oov}Z-X1?`Zur~=qr6y0>(m24nLj8~({O`Qg7O$DUREDYXL^Kcx3H zn7o-h4&*5vI=@IP^i$qvsy}nRWTPE7?l&l$lq>qpY`0kTJ@vN~4drxyvz!klr94CB z+t#~d*C?XtpUExdgY_l%mmA)!_^qImBQf$`^=tE4UH|2?^;+&h#oGhD5q>y3Xa1Fy zv-dg8pDsV9dRl&5$0?t?P%3J=K^G#jzls#I8*_`RBtIuwrh3AJ=)3fe4x8T!vvmN= zGnEhaJ<{@Nq140gVG6yVTl@tUM6h|kd~ztT&9DA*Rq~@HP(Q%VVOV|kye6OGd-e1i zRQ{rIp!0|j$!EeZYzh8K^osQf-s8%5o1f=)shmai9*53q*U!8=zd~5%`-0YQbT`fV z(^$K?;1dFy{jR^(;XAn^qE$%y1TKU-is_d@yRl;F%2{6nV)vqHr?D3R>bJWo3JDNMO+ z#!vcjcVcV8_-*GWY~98D_j&t#h3PD%_7qw29UHR9+V}HAm+#Xz=K5*#lC3w&`{Md* z^Q-Nf+k0}R&!sB14t;o|MA3Sk_L!W`+jAcsj-Ygo+HHHjWb}@sV^t^>mTlkAz87P1 zH{jYsy=UR4omV4W)Dv4@v;?bUz|HT^*PJ7;`Q;;TIVj_6?*-azGS=P*Vsl)=h0!#leX`$&GZlH zN08pMVwNCA_45!pg3YJf)(9Akn=iL$I>mu zy`<+yy}J+>gB0AnQLNJa$npnt-1AlXyvx30)!@dxd_dc&SN1?Y72lql&z=5FX(t!x z{#d2HlT{Azv0c(xOzRg=Oy2To@(Fr{_u$z-rgMaC-z5)xHpzVQnfVwx{Nvw>Uf8}A z^NAnrhXH0en81Uom!b%NM&7t?Ogj`z$|$Hd-$Yg%!Yl$(2GD!qW*M2e?p{~zpw{%5H3O=NvYlU zY4aWX_gdoX^a1~`UdE64?1G&?qdu`C#mscg*XdXM^w-78S4%rqPcGPmT#QH5{^bHk z^Sawdu=Z`fv2(CyKU>`WXt_Y;G@m&|FoRgM5kf`k>BZ^ry&g+J{l* zJ9}sMH#Ie0fK>ALY>ADJ!&=~ZDA@UPd+@kk=t$$-16pwoKDbG(feJVGGf)MS8 z&QmygZVWmW0K?vwH#=zik}bgvQoeAPM6u`P^c%!qKnL0W3cP?ZeqM3&(ql(t{0awO z)Hs@7)IZSkyzqmtEF`~dU0#9JanEOT{PeP| z|12Fgx#4q|5GgjkA3vT^AqN62HFAkH=p{Fv^U;fxclwgyhXm~{G`tTj2}$r{A6||7w|cN z!pIVSvfS~;&E|>Z^Bo&U8<)w()5fndPw4ZnT<}q)=a(M8e@=|w<5FKf^Y@e3d-Xpi zxA(v5@%v(o-xYiR`B=ZlkCX17B+rBU>x;v%6ZZU3<^hc3iM*HikY|_8KlST9DD|pc zc_r^99*}ZwpXXr^gTVeiiF8}H(w=<}_RRd1Uq}C*{tfrg`l<5v%H>q$`}lJDTYf*?c_Z@=DAzxLT-*Mxy}#A81Q`hS zJf;Qrw=mfIbooqC;rS8;)o@=hHOqbqnmgLy(oLWF9wgsGBsOE(QHES_vBY-Xq2A3K z1MQL=28ezDcL18Ylur8&v-$P*{xHjvjmdRBiJVJBx7fn%|drER-my->)&tQGVPqTfRFd?IMk_ zwNu1B`D17|7koep8ogZW9rp0@@c$10&IOO+uhPYy9=~7jkM)c5=K+*!s?~EOx!}Ek zD)qG@pD(2veJ!=`3AnR#{C4ge*Ull7YpVUS%nvy^QI2{-BqG$0N)!yBJqCNPz6-y7 zKJ}y;B|o2=EA@|U7cgiT)tG$ZP_(%B1ux#L6(-v$SE<02wOFvNU4OLoYaG273pAMa zpy?iczx3kO`ur$a-(=(3gYR20*mKFIyI+$2+w*~uC9EC&b^Bo>^OP>rlU$$#Rmy+G z@lWZQjk5pvDkz%^CT~Vh9$$~hA}^2kL1>3eo}%%D*D3ze1aeJzA|6B21Expn-$(u5 zulZK5wVNC_Yp;k?7%JaaNI{lk7#o#H#?Ei|;^xhgF}Xd+%YJLV_VnP#z%)9jmmDd| zFBxX-&#%2i`g?r&T{DUNs)KFc!9E`SO_`l;ycSD8BKiPvWGSycebmQhq&3y5+}Qhf zR_^$8pB1Bfeh>!lM12#{DdXTG4>`WyFR|%U`2(tdrITj~fw!HUm$;*2 zhQuZJL70)dD|*OwMx1`y`g*{fqs(XYfb+n~I$ou>@0CHBvo(hs%g+4Q#=?71spCfV~1@Dj!`RSrp$LJSXI8nb2oKU|GM|_C)>qXZu?VnGN_RHyq*WcC0 z?60o-C$cZi((gX$cb*@?Lugt`Yk}ud?)%))cfcSQ47SfYshx(LQjdDvJuVfwX_tQG z-M!G2b{0v!c0ahSC+vLKz~z!H&q+lOz;wpNY*yz12p5_=%I7!?xj^5iFgc$)?<`4= z_J3VJ>^suQec)nR=TG|%Nh{cKDQYl%iJmWSl4?ai(dA&4Bq6GAhAMI^x-IqDz8(0(pQKaH zUtK1}qIz4>tB^25?jP4j5lY-1mQd zc|D%~u=R=b=kN*X&k><#yj^%n(nlt^|48+xqIWfK5hk%)pkutg(JuJ*=b_K~_^MZa ze|HQ1iQAoa!GBWd_3If$x;-c3IDEhx2jhRot!_LpZlj>TX@@(Pgu$Vti64NescDCM z{(^K$jHF`(n|3@CjVF7RbLXPR)SU^+*XVtwc8<7wgL~g2a~`m%ohrH(Vl!^=?S*-f5#NI(L1a)<->K1p}KE z=D9*raPw^KZ!3NiHoqjI`%#s*vU`qE=?AgN_kYxJz;CA5dE9zAsmTvDKkxt^v z`UW+ay|edz#&nq$G;9G9LKpm+5b-lE?s-6;4?m7H)-(5uSmpaGBaeVQlVv|D!~o#$dGCj$ko zf7>Yl5V+67akckeqUT@NO19ji)tspRRy^loJ5Z~mcFxk?iy}Qqd|XEw;TvBET>I2N z&XhU1&n;xZJ)iT{@OfQ+Rom9ZnPuqZxm4W#mKNRJ-!j_L4WaoFdz3ObKUCi z$BhDh3Yq&5H=QyCe^rl15tIHJZ$FX!#I>do{bTEZgh2UZz1+WRM%{N)jvYya= zAv@nRALrUSkWV{Bm!Ec-^Fh-oH{&nnEf_oeFZS+7p1rGg`$yeN1TDC2&Ie__WIgkd zlnZW>jLGevu9GIuSNdP6zM7u4LQf~2k8;PEj~a#U9Cnx)Cbxg?yaU=%dH5IU|F53j z|M>iQ!3oLte~tMwC(;VOJO5-A$P70o?`KL zoIcSXpoWzkJ(Kwj<}Yx*S>VwZ`5PZ}?KEoa`w_AIJ@l7>enis=>ACK^wSq4p%2o7y z8LJV!COvjv0rh)25}Hm4nH~Ar5x+q{^X>l91(0un*9m&iuw7$Yr-+_G@>cTIV;a-n75=VNnCH&XWWfFIn0=uWhtNH&@ohKElOIgxjXzz8r5wt~$^mBR zZqfL*8|KRo`m0cbqw}-hJbLu-PjZCO&7hdtruGkfq222_g|*UtwMiWLxsM7c?_V8D zK61ehK{UH&?-^G75bjD;_&z>gpC|mXc4QCwkFEss@xJ}B{q9Dg!~A~p+b6eoy8rqV z>Q{TG`>+3TI*(`HxQhgS!MPqqJkk1K|IfVj!S%$39IlgSf^~vBM~r?@mh8T-|7`y$ z=kBvJy=%pwQLZCZZO7Cs!HJ*%)Ux(d%83?hYJGrW7ClQ`-G4-Byns!I#t&JhG-M$~{+bE#ujXzJZ zjKH>Ugn5TytX(3}ebG07olLLR^aY3sH{7o9*y9>=|4jI|K;bS#AU)u9BQgEpCJ#dQ zs6@eS)$`;B_sK%xTez!&_N9n>o3;HkfR?f{^jvw=JKT-$s$rqWoHnLXA zqwXiNob1nhP?BZ;OX$~XWgZj1W~1iY{e8yIR@5u}K`i`n^FF&T{K;xLvs+vzPuQ<@ zibs0HUOehx;0rxxD;)J3=?pd>;k_=kM@X0YK~Ictj{f7;Z~lOrAD%*e>`Q}d-@a?b zeL|m4BRA9v?3>-$f((Ztnrw_}P19Z0FLSRQ#iezQjF` zK3$*o=(6*kcK)n9kdW_zPzWUdQ`g1y6_1i5eWg4LzvVCZPXNKbmt^M%Ms9U-{kY~+ z-uYgjzn@6Cw*Io+xScde@3V<| zccI>a1FF9jy-=gWo0W+9*z{GeTHNuk3C$FhshdCv`K7r_G9Mpc+& zmHS+x9EZT{Bjuh8gUQAz`TnT+>1;nlIrFEvZXy4fMrYhZk zvwLplwi`W~o}_<%dZWBgV)sjRp}#^G>-Fg3`s2@#kxyq8|2iNb*nJj-wLBcF+WQC#$e~u?YyO(TWy87kkXcF-RI=Egn*ltYC&5+Svu!~{R#O!iWholC)i#W z@}(cF$LojPBTzU8l_Q89J=ze|Z&$dWk?>Xe!AcMwN6dO{A0nUC{hrkVJGK>L8E zf~HRW?o@p{Q^(H>{`m!tFZ;1K!PhT%eD(1|)JOdG1pende3>6Wh|NQ^9}KqNL%Np( zZbf_)GC)1#i=R#NRDTFF^qj2rhUGa9^KmcTC6G0?Pnb9uo#?yAOs|CL!8YedvA$&} z*ECP%mHPvKg?(aaAGP!~YAL%9#q_#W+QFF}S5MN8%tkSzgEi2;8jSc(d+(*q=?(S1 z5{}&2)WI6Sm$Nms?Rt%q^)_{?qqvPsLoj~k-E&>jyEf-f7V%y<=}6Yo)5uk`mZzM| zZ3OcX>|E72{F%xxwx{^~OMH!u4zp9wATPu}8~0>=|BpX${!mZIN#mFK_jZrW6K*`| zCwO7BZJt7Qzh9iM_0e}D+nl|y`OV~Oj01+S2g5IVh?sh4_ay9rlOgGdCH)PG&;2mU z)%@K2;1|HR_X+HKf0g`3$)}wXe@4YcE5W0iZK~EX4_YF2vVv`$3i<1TBWTa;f!S5^ z?YB^O{hJiuzPDL^#Q9&2KW!bFZ|4gu&qL=*2I(Vdrl)(L@0SAJwp7d6a{yVlVB@uX zK%a{jt5d?7q<1aK6YlrXjl1o~O3Cfv28S0_;NW6ah^R z+8)r{rsy1aUJ~N%)&$#hdW!b7ZCywD(=q!0`6%fpUrBmTNhug-SB($Ar95m~pmf-C z`M6x7{YK3p5Me+KB(Ka`KKQXSK`hHhKN!zC%5aK7t zlkxn_EE!kwf#X2GgX3&^vCY}vz9A$cn7y}inRhxq*g7LxR}3n?-D4V`e}d7bC2H{P zeXz=TT__TQ`9F3~y4h9EPvnr5Gy5<%8h?88m~Z5-{Q=){|1L5%j&I7&;E96bR>nu) zCos9r=YA;V^BG+q+xKxz&*SnoJ!rZHgd#K*R!E!+_DOlp3+wPNpFLmFZ69?Hx-I?M zAj!eD>ohjMmHDi3qIAwg6Qy%KG*LQLaH90kOMe{lL3yD4Y(YSl#OAN>0Ze+^wlfFM z2Y}B&{ACFI&Dih_k8;O;*t~D&Wyf53=CePRPPwT^V110+n)yrpoD>3oGhXb{N!M!p zhxk$#Oa%}ITn*I8B5_4;1+>y~K!_I*^_x3%?Ty&E6<&T;AbN`0)S=VYCy^|mk2 zQP6x_#~GdP*5v4(n-k~DtV#GXO=>hcThT8vp5q%EM@N6eKck~de;B_;sAvcgpYU7w zlvO+Yx+SWZNj{a%mSR#)`SCLue_MaZx&$c4|EuC zg7UsJ<%H{dhNhKHUK||Bp_7mDUd6NT)!yvBiDUawoL5;NpSMZ>H~yRShx;j{>vhXj zF>JgI?{&*n5UsuXP1=r)PxAZJ13NW;?hPu34L3Oac8zVn#`@K9rQYl4@4xZ+xyf1K zfaY^pL;QQj#U^)ge+Yit*+4*Ob9{~bI5!UVUJTd~*)2ZjW|^Z$zkg>_^Sk&nI*(*{ zP0jad`aFrCXXGOAoIQ!)M$P9sl6H|0*T1G0ZJnBL^E=g$V9MvVQsu9hcZ80tNDI9L}5aFnI9&=m-%6W^w6v4aWqCgjGMm~X!~5> zkdtjrPa6g`o#zW<^Y?sBZyR>yP%rz@=J1pIFXSKlW9js_V)KKmkLfYH;?l_{nZJ=Q z^SA3K?JPy974fBr`>w|ygh& zf2IrLN4po_?->oYIXttAHvcv_KG=A*RO@pqTMyg$l3dUv?bol9Naij5C4W=)9&g(z znwrnvB0p>&pMDMHg6hE7)~UAM$OShFetaE+_2>#cUt#yN=7QHN9xI6g)_<;D^Y?SX znGrpby{dvW+dubXdJP5Rh4Eb!2#4Ja7CV=I9WY3#UX_kEJ zKlL1_k^i>M`J1NC%ojbJAYJruf^^Zt3DQLmCrA&`zO@_q(`YxQhb)XheIdPV+X=yc zC4ev+|6=yi@u|)6g>of&=4V6oIkKagGPY19td_c+WSpg%)- zXhke??D*2RQHqP7#gcZfnE59Sjhf$zOqRRTjl;Hen*J1-is0+7*cI0v^JMN zUu!w?Y<{-=Eb2YFkF%;XWjt(t&ZBo6pXj@~pojF@`?%KMq+OW1f>xgrjGbNJs zvHs%Um+p+03r5X9nY)y|VR?J)hV$-wj8O>eucEy5Yw-pxv3S15^(!0TF%bNTYL5GF5T77`HsFEQWzrIBmY zkXyMVy(a%7DXqu&)Y})9hWZ8zUB$4}U+5?ndxyG*%3*KcP`I;ixVQ7%aL=w{Z&=#h z-O=6K6}ETu_4XD!hPwND!@**yI8@j@SS)mw!ySEtgME97oxA!y%0tCc*n^^-1^h$l-F+Rmg$UR6^%RFo#li5Ri^CnmgS}h( zdW&0nZ!hfb?nM24yU}7l8|@t`kbt$JWp3+t1jVx#h1c&YhC90lK@wXHdxrU|7&eD} zgW(ckME_u4*I=P%acQt)aVM+qC=3-l+mPH*ES35O7Y&xcqK>}ZyIrq4L3sD>l5(f6 z*xAjdEBS4O;h|l9gW#cGvtQko-qO(Eu&{7#cwKQQyuR-?aQM2RLT_hbuyaGDsjV1< zO&o*}+`if|Y$NzQxHeqh(Se+y^~(M&y&wa8x}(@Ru6nP+>wpl;Z|S|gIM}_j99EF- zpLM~f25&yJ{@?!gZP#4eo;@dc-~&_ArLX<_(EYQ1{;o&XZQ0$uW3Vt-Ufj_)SQM^N zG>VIRiai~>$Sob_zTu&;Zzo0#)R)$VLl}qM=wx>(yt=TryJxs3bet=N{e#`TV0q{y zX|27~b`}3VXuKi@S?mlrSSThO%j}SiGZn9HeWD zw?kmO5ewIw$i*sK-w&xHVHJUz7|~VOQYs#&rpYmov$$obn*ylf9HV3$UvF5Z?83+u zN<&cijjBemQZ4z)R&Zv6K+h@ec|PitqBVys>+f@OBOX>5ccmb7BCPngW+Uc zI=2pOp8x~BCWN@{R5TiKp`dg@sFF*|tgXlTew@<6H>v12^<3B8RWV+ZwczylS{V1i z+eLN4tGY`=$En&QkqZ6_OFQ|3`RRc@3rmIF#qf3r!w}8!WQ4x5Q9g0{&5*^^VSMpP z#O7Sggx;hwndY2WX(PqWH)g0xw^K<}l_^9ePB#9;*gaJ2@#nk}X6Ygfwx2c(8$ly} zJ=}uQPAGo3yU^3$H#k(HMsb$tg}N4OZi8b$6CjQWCfq^6u-sCKlEpGE#j5Dr(@O$f zyO0bK`W_mCXmYmHooaET^iAEp-KAaVSjiPjB3yS{cYi;tPiDZc=qONahjw9>lh$@Y zvwPvgL{s)q_wB_S`i6>b^4_q!uVk5+7F}xTa=1mDsWG*LPh{VfXHM zM?HjihNna<9nV}p*frckZmR#)(tBGk1kJ6o)Tj3U!aYBB*gCmaxhULF=%okV-PGQSlaSz%Ha3`3%A;U1)efZMyFJBv23I$6%Z zaW4)+FJUiq1~iX5gs)y)B=y6$qmN477bf5;vM0bpkGgkugHP~*cfh7$GN)B4^`lFY zUKySVN}oU>NW%iGTj+ci!UGE5}QTxzY6#o9UCtIIkW*`#$p2J&!k z5?S1Wu!Ghu+$jd)7(Oc|k}g;@vK`{Cs&4B#xRrxWMnbrOf{g(2e04Tof&DI{UD4CU#F@sAHE%*|=#4!$;}k1SBFok^2u<37m%GM}lO1 zt%3=DSC#;iAsws2%Sj-IWaD1AZ(8ZG@ZIuN(M!NDf^Xyas7^Rn046#by0eU$xhVP z-@}O1%$w1-VC!LcNVrAS?d#o*O)Ic!H~cxZ9Xm1oV0%P3NLQ-^i-I!rx<^vD@nmb0 zUb;$@22=oRPy2@oQ5goMqklNu-Q9yu!%&p^dP}eF8xDsCIX|F4cQ0z8Bx6rZ*StuD zR26z5Q@ud&CNwNdZVRyp-Uj6ByL(io)w87A2l|bzG=$o?ELcm}dWaT#;)xy~-%PH! zmj?9pWB-mD8SDeNMnNp~bH7K-u@Fl|r#yQ6X{17Vu;`~_ICKRr3OB1je_?mu5bWk< z#d048*Fi9+ohV#Vwn7%Xni}bs$$Skyl*9@etty|+@wnC-tWtj;mKPPFEQyC^0XSZmuvQi{h<|uJrV%c*%Yii$f`(O+ptc7e8bN zYIKIX$L)i;p;3`>u0xM51D%9K9S5^MP8VPL#wUr7zlB1Z#*M?&%)d<)dS^ny7p<%}Yg-G-7j@Hr9CEE>4>| ztYQ{)oR>5=t6^|nOJQ)ZP?lCJ9tdr!iK*H&*zHa!=GMh`h!GIe5JtqA4^nUwGZ^h0 z^DZoNX@DyGDw9}T?1Q6}+VyVJpUXUl&5RE0tPG_LAo|qYEPY5Qqs$`|EO~Mv7?IN( zk-e(`kIOv1EjuxFQdi+ZD~GV8Ad4;t%P@InUumwLq(x{PX-q*@%22@#PFHH;yD>Ku zhawyi4x0PjeZ5^m-cC54SnAS#bPQva+dBlS*x6m;G}TFW$aXAr1ay=lKFb0K=sU5K z!bP8$1r>6t%CK&rMtd7FqN+o(>FUf2aq;o zrDI{Vvafh_<;Gp>cFXe6&6-d|IvZBPab{wq^_8`Gr2kT>Q>Sj&$lLI^Nch!Rq#L1I zzvBj8be7{j*xj`Y-lVK;I2ZVG48tmmn*KtG=1UaPY*d8naNHuvTre?M${isPf~pMK zs6HC@^XSbB8O6PY4r(boA?&>x)Pzz)(l)xzMh_>Pm+yuUOA#{~-1@>Yj5>^_MZn$e z>jKy#9TlL{Qo={Y6I)#}i%Ej%7~*a!sDh)`a_tsWp%&)4a?cJtG&OK*0WPEgLUg5O z+b&7=fTUEgyrm_b0Ha>$B@-%`q|}JCMVm*Y8m9G8$9#X<6$2lf{W2vVw?>+X=Wf8j zHY$)O10}fZwBfH=VD&A)!xr6A47)oo2z$Yv3&I6XBo^H4Hc?RO>dIKW(n=`-m6~ih z>1~BxrQ6@wrPy8I=E064wlW~ey+ch!*|vo=z`vmN)vZu{@2+z0=F47Kcx6(Jn zl!piY>g`q@{1?K@yRkMXz-;y4Ar^NnRhtKknBuVNlhpz@PjNiJDA`?J+=2yBY4PAN zjui|p-qSaD+u|MlJDVVs~K;#pNa|pl_j0mix-n_4N8HFE?2U9VvYx zRQ0z%{l=Gz4?pmgzxc+c&wac6duRN?8@}82npO9$ecMmo@cN^{hluOufVS@5oqZTv zCPAVG%d(N@68eXCKp_FN^vb#(^12fu%}vs7NihAk73GfMo_=^_#m@CGmg67A;Hk%Y zb#KN!gYh4}jC<xh@*QoMZ@;v1fOWI~yk%xqLW{>53R zUGUm#8sGNWt1iCs2Y251H{YxI?T3GH`QLx_D{o;r>`Fsuy6Bd`gkTG}Z%|jG`csdY zU=O`-uv{@Ka^48WekUGIVSC!1kwx1XFnn0$4i5Lj7#19nx^%PoktI1JL=z@6WS3@l zckgYbj={cCsi_k?RIu4h;dUIXHcG&3ces5fRsyS8D#L=qucmniAgR(0nl2J@yG#Sa zSd?S&s89VMrl_?S#*)88oQbOjnLgMMJU2{fc%U%tD{O%?)7yz%)k^cb`}+FX4QLRa!|AgC-IZ8aT-3D)dtp7&Q{tV=IiN|lbi5i+ z*v^uHwC>>^tq4P-`?=hHg}YL~l7$T*or^UOtPGIbF5$^As1#46nE>f}cgLXkvi;b{ zw_bH(`D2PM_1f;JC1SCUg)Ot(A+}yd{}sm;#zQB+rBmoN9r!9L*7XEy6|-i>lR*cu2BVtT@R7*kXP?;4+v}Ci`D&- z=B3TcnwK}PXkOX8s(E$unkCIkmMmGiWZ9DCOI9pdxn$Ln)l1eaZC<)$>C&akmM&kq zV(H4ItCp@_x@KAPvL(xw;$ZdiWh<7gT()Z2>Sb$|H!okZeChIK%a<=-v3%w7Rm)c| zU$dfl#gY|ES1enxe8q|tD_5*qv3kXtmCY-ctX#Ts*~;ZBSFBvQa@ES!E7z=QUbSS^ z(pAe=Enl@_)yh??R;^yOW_9!GC99XNUbcGq>J_V3u3oiz_3AZiK;jxSzXnyWL9sPR zny{1VVCktyXeIW7l~X1an!}A`IafzPfhEFIcn2%Cl!PV?DZ_ERQUGUVw4^Jx@Z6+R z?=Q9DsC)oN=M663@X*et)p}~Ogyl(*&Z!)qas%sZj-o{vpjOJ@cqETnDegEvz++o1 zPn|?Bcpii&)PIwKGtGZ2q>mXgiI8RR8hp*7MT>5hBdSgspg6H3l$3+^9mOu#FdUBM zaoUCYFhm|yWA9IoTH+wng?!$E;#eQ>Y3aFAa@-JLr?;c8vxo=vm^9aRM*a^J7daeQ|C;Ze$ur1?DWjcnJ3qtnwpiJojNTur~35N8R>>o!_4`arYVb3 z&6y?XrK!i$A4-2X`@1#&p8i?x7wMNXM{ED*-tt@D{z!A{jc4rKnp zAN}!X{`_;#ed`~B?6i|4ckP86H*LA{md@fm_x<+!KKr@nrp-7PNn2W9^V(b5I*V_= z??Wi^>Cb-sTmNum+Ki1`I*X(C{Qf8YbnJ^?KJtUR-|*H)AN$j>Pe1dy=l==KmNq2v(9YTbj8+fH{SHxTV8+X$3FdqFMjRF4}LOOdgsvad(K(3`0*#6 z8hhrsFMs{L>mGcl`JD}a{e{mR-Ma0j*HqWkPhYV3d*AQvTXpfJmu=jC-*sKX&wlp# z&%f}Mf5NrXVcS`EeLZ{E@W z{mkl?>P+^Gy4p-lraF^`G)>LsGE=HjC*^Znt52_Ptxi{+I&FJ)Lk9O*WM@>>PhFdx zJHIXL$=*7D^x529PiE#+-SvyitE*3~on3p%)KjM3T2)syr|Q+!=jS%nU67rcO=Xr$ zxga~IYD#AG_mH)C$<>+BM{6$1)MqZLUR`s3?yjRVX4fp9(UfVdZ>%4ETlTI8Pn(jz z_g%TgxeKe)C(W)M{nN9CrjCAT&eYuK(cI|Qr~dGLnN_v>UVF;u(>0@ik*k}1VWzHX zbE2a-)w;-}jU1 zRCrz$a^IdE{nO0pnfhr#RVszfrE}HQ>6)6_bX{&r`lRgi)Qt4Z+{rUeN#)bC(x**3 zBR99^?9{E<+tN>DK9PPd{rU74rhc*ZOX)AC|0Z=f_l@*FWnWBxFFcZcDGfnQO^ZoDtosqXb@SaD0|Bv4I(W>g&l^0)f!;hZ-eD;*tD_7mndgq5f^2DF4I6U)B zZ+^%7BT1wnZr#>deC;1Tb^00AHFZ-?nYD7w+Jhf@;VZSP_TP7~y6(bDc6Pt>{=T-c z?|uKK9Y6m0(f9uLqQwgqw!H7a!ykC`@q_>Kk3R9Kswq?RbJt$F@tVgT|I5ERP<`5* zv*urN=|6qv`$s?hnQS<3{y7VmtzNtN%B!|t*Kz}euDzqU^S097*WLM+M?d_;lZT%F z$P>MN58QIrNG_AbH={GD#fwJonwwcte@6D~+B0+K=Pu8lbl&KPtIp1zon2V7e9G1h z`&QMST30js!i{S(9W}Mhr{)?nr{_}ZR%c(8Tb!+{uB~1dF33);U71;%n^T>gTD^VC zs%6ubRWGWk+jq{jTNl=xcj}yT&NyXO?N&5!`Lxrj>#8=_ET|oxa_Rc>sxHjcRb5k+ z%1zJYM&G*Q%*{1*qmSKk*2XDyRntyhTUEF6g6yo(k6+Yz-PFysb(=PxzPaYQXpP{xnj$z%tCbN(eeWq#TWe1nebc@xGH@czq{5oTvmaj5e8xAf_|ch-R~@+Tidv zu512Aq2(jreE5dvU;M@mVbI%pBz3eEA0@BG$Kg_`H2zC%p3#;qQO$X?Q{gHU$kxE>RM(~Frq;4}wgxD5={c!%dJVKZn}(H3 zote(0rV!2nA$3anRM-Guqwbnib*3(TX6izeor;nRQ9Wt}$5Ywr^c1O;B%#qX;WN@} zK%ccTH?=vHO`-BsP3oFdx_WBOj#RpKO4XI=(@|e4wd$l4TFgyJon4#SnN3xJsPt*+ zY-W0P8h%!#>Qmr*W^VdS{I@Qhs;)_;r_`okdsD;dvr@Nbvgz7XRpzT;0;sKKjp>@I zx^$|!VM(?ba4xm5c4|6ACsUc#$V9=++M0Cwp-gI8s+tXE(w|uur2eci$h}xQ{POz8!w5Wm)V7xZ0dukKS=-9lqK1b)XMsE(aXBb64Y3o zx;S%oE>&|$YHE6UEz}~_mLVgnQU_9*n!Io|l{z(bQgtTxXEp4|EOHd%M66W$+n}oo z@#*Q78m8PzULd!a!GPj2*Hro^7C7T98y7kN``S}M2x_^b z3JrkYkTf=xLO(D81*uE3*YNkE^ens_p2_BFYSPtbX5W>;XA73rq)tkmnoHHArWsNT zuVzbKoDHgbs)P2?Bc2;}mfc>iX>$QLc-a>v;C8_CT>fsv?rM_YZls^#mHQ*WeBYCS z?{A%>KLbDg5YqWRCWD{Oy9C`Uy0P?UCQ1KGr0bha@p}FW>C3eGSUsOZy1tPa$A4~; z^dBL8B6>RE&gzYm@p?WqN&452zF-1+HsO6Z+spL%@H#L3Bj?(!ph580s3Y&{@zWvc zQGfmPE0I1C{u?Jre+20lOi=%`NDn7Tcdxt#HK4iO;TX>d9{L&zBh>t@#?3B1azx?j zKXCb9*Lb^&gKsIk%V38Wy7)<#e+Zk^+ogrdSP|UyV=e!ri(hc@^H~fkg2jh^>e~NT zjckRPPJ;iVN$`I@ z3H~pTJ_G+4{Q7xq^+fd8JvvGJt-v=u^Xs_<>88hi`U^-m8TQk^iu8&4`;SPUB~-@g ztikwPHbHtV(kJ5cKBQkb0sdV`cds7D`0ysAPn`gN6Z|9_bD#cyM7r5+KmF%OUpqlP zuZP_-IeJ}FPVTI5Xu(G+=Ckgnwfc^f@S(=Mv ziv^ki^Id)moq(@20P#lv`{ln1*ye1a{Q%<`@`nqlWw}Tum~;tXpZ;3`>un!e;2ywc zpPBLnz?(Ho{+_Ws-u@QAHdhj%AMmvv{wD#i_u$NmxO}Vz?DK0E;AtNIFkrJOOnxI^ zUmiY|fWHOUY&h}jSH|V35wPh2^H&1Cnm=5)8?fmHlO6`_xBvTquQ6oAnN@Zxs3y(< z?DJ~}V84I&1NQahdBA3)Si`pg`{Vr#^ww+-^H;2nmoEYK`}=;t>xk&W-vRdJGqWZR zF9ht%!}WkySz*L)1?=n7#{rv7BH9lD`|>w?Z7w*=E58=7uWz>i_T}Ms68V1y*zfOG z0MGO4`#E6VBVeK9!kpZ1WAGmV_WAJ-fHzqt;`1-c$=w^4bSq$=-+uu3BFjX41hDx` zOwL@K3$}RqR{{3r<8LuuzF&Sb@_l~22e3aLe+<~Suipaf>;LRa;`($e;8VQzKR++7 z@2^L`&+kV7pXcHKCEyMZUVLfXo?ZyJ-pjudu&K`Tuk9&u{N9k?-^W>wx|7ty>@G_ql)@z51^N?Ay0az&2icfVafq?#G;J z>mc(bnDzW1CRK#V@?UcKhWBiT&ZkfR6)I#o7az3P;amPN=<)r#$=Z4Td982n=QUpa zWsMJ`{HvrT+~Wf$!u+GXDVK=I`xzYhh4yE%{MBzgcK%+M-;ZvFt_h!C3wKw_PoE%v ze@gko_N|=7L_gsAwfP0@-!2zFyP+bdoNr7f{Pfp*=|2X(;arCF)9{bMPp8}&j-Sr? z%hI3SsPwWdL-pkq`Pq&>nC+gAbdx3G%?508{0G1bnTXJTUiO%BHd%gB&YE{BT`zVk zzYn?i1s5N5a%TCv(5~^>V$!pEK+8{-zst)fJ_EWF1(TOxQ=Csp__577xf|RHeiX1@ z&tbr(2UTg_5u{<=mdgG_3(^f|JDpt@{CZ5jnQ#5HnCMU5tL1Kdv&MT}%u(eaRr@BOgS z^~YCM>M5fk^Tqu1QKXxXaG%$Y*PvaKn=hfBh<2pE2>2|-77jJ$qCEhnCG+cE7576z zz^2c{ZvyQ5k(UAX=OunG%9ocO7#&sdjAaYJT`=ICMvQy>)Thw_2{R7 zjTglI--&joUY(2P1m^!3{Z>vB3WCuDACl#h?ae`bzQ6Z8%KP%L4*6ADwfs%iw+Z?4 zU49*6(`P@Od@5)fcGo1Etsy0U(HE7FVye)_dYk9_S(BOA~pJO%?(%t?qYJrZp4s%{+db6`^vz-FapPi_lb(5suJW2Y{Bi zj|xhCyW4j6b+yS4oM6K1Ep0*NU}n%ECmGx1Sdig#^zV`bOpZ%Wc7S*E!RJhZ67+=X_ZHY^V4JuXajc@VyCm^+I$U!Sc5! z;Dc@fVfmY#p)vSHXP6AO1)sssy9J=Z3*7?S;DZVHAr7cV&yxwb#wo9rKaha?-NOXS zzc&Hj=oUu4Z6{QizOd~X7NC;`84 zYaBnIVL`C=n-g$*IiCM?00Z)G*p1&>uA4tHn-xbI2Prwf);3Elm^Sk5a zA4pmFIzcB&tO2GGiG>(5D0Y905SAQ&yzdZrBC*WP5h~tkY z;Qa}B?CG#Nn5g#o_78o;| zouiIcI;T#w{x~om54b4g6k>yb4NA3!N_W5a^Z9=7>-lf@obTEDxUcu;Ju`dvd+*(Q zXWpy%j->muQ7Igqm;pR52cW+nw zcc?qq`LO05TzyP)=T3F^DYf%ywFmc~)!ePs133AD<~6*6J2<#U*U#Y+uHmrJ^)Z~n zqc3ZH2G8LF9^H@i@Ek7S;RCuphZk@O59~Qad;iyOoo56u;L*dny_Gpv$bP--VdoL8 zUv5t5*zxtHgM&vkpTfbnki+F;nlIt`L(P|P`i$l|oS5G{+x^MlYU|Xw4!HwFifAe5}@I z@C+Uvr}e|*)xnAC2u|Q7T)q_Rcd1i2hYQ#_Mb~%mrysVjK+E1Jjf_}4Vg;PlrupTP?__${rkU!~4Af4JN6_#T|C&fqy*?biCi zrRvp{>cLg&>DB7u?dlqC;P9PVzucV2x8r!i>(nvq-KhB-?lv!OyrbXn1L_u@-=cX5 z*KoYh`V5}I)g4;jz%AT=MC*qiRo8c_-MiHOU#rJ(0K1>i`s|bH;_uY6&!`J{`8my7 zxQCbbq8{$y>OQS6?^jPAfWM}m!ZBRH*@L=%4i|6-C;zVN3poFV=1aJT{YSOFfrpQ2 zp27vZg5Ae;{TPnnIXrwq*9UM6=Wqcp;SP4ct=k*I0UX1VAL#lST)-7P`k}5*&EM>r{10yu|DxQ7Qn zqWz|D2G?*04}Vnqh42in;5F?3nD&d{9A3gbJbJeF3*i}D!aeMH=m#fo2{*9!9PKxP z6LpFpa07Sn@CDj`0%!0XUco&)GB0pwzdri&oD3@+dfc8=116L<>G z;S%m)_b0S}07viwuHZH79j*OCIED+jhMgB_zX3dj6S#zzu=`@|@52$C!WG=W-Z9#L z2*+>+*YFA+_}YI2CvXlg;THCf)&65Rg=cUBcku8y?LUDtcn+`N9v&U9{R23M7jO%& z;qgnfe+bXu0`6ev1noD0r|=vu;U0E>Qu_yR1TWwUUc=r`Y5x$8;R3EW?pSjlPJdqWHSC_Ld3u)GpQ^{Oe=c%( zcAnZetJL1x z)Far-ki+9Y(!7A@*J@tD?K?Gh{#fn(iQ4@$^$;$v*Sv;jf3EogUcF264z6aJFJb3B zntN~y_wf9Ey1szh8#G_T`TI4W!;24SUc=4Jn)mdrntKa%c$+$cN4IM}f%7{wcMJ9S zPIXkO7avzApHNRetuEo{Gn%*mtPby1PnPNko_$X95_Z3+d3uk!huwQM&)_*cZcq=; z;Q~&-qU+0*x_wx^cueg*uJ*s9PQIre9k6}ngnhnL!i}qWc$hlz)IHq12>Eep=Opz2 z9>Nvez%3k{to{dtc_yWyScmc28sP)mC)C+h8dzWZ^0MFnR>|Uzt zCvXba@EZ0n(|!S*z;n2UJJ?IK{}_(o9B$$83hfue1>C}eJ-R-CQ@DUvu={51H-e{d z4p(po4}M?!2XGAMZ~-sj4tCz6+wvOn;>l?Jbhokpvp2FUZnh)VA zyu3;4=eMYbA5^d4_%Afi;K{9;PZsJWJo-z`YdE@1^AsN6u6Ym7KBW2L4)q$Inroo# zp_K(tHGm_i5g()b0c79A3cQSG7KZ zD>(R?*3V$~LCwc-0=KaDkgkv5{Og+gtvZBrxPm+SVeRL9Lmk00IDACw*Kqw!&Ex-2 zk2`e>myc>b{g%3eXOC+>enLHiC*RgQ_)m2PCr@hbe@C6cEu4N=>l=9Tl;%C`{I}*~ z*!v&N6L_%Jyo3GkX}*T1|EqZq*H3G{hMVteKKg-r3A9(f@Yr0l zZ@*qv2OKQ@M+d3{IENRoe~_-9!oz22Uc=GBn&)s2SBGeQ2ghe?p29gihfBDIS8xxz zuh#AR@E8u^7|!51T*6DZh1ak*)%_j96L<;7zkPTNhj0WZa1Jlv3U1&IcFxuP z9l#?vfFn4CXK(@6@Cxo>_dMNSA0ERY9K#trhYPrd8@Ppg*m;fazX$v92%f+p9Ki{k z!83RPmv9X?a0~aa^Sd~H*oQ~(1PEhhgd;eC zGk69s;1aIk25#XVb|M@rm!zEn74ZMPTcny0O z>is!@NAMU9;VB%!F`U73xP+H*3-_>VW|i8<*8sM&Ol=+@58)V2;1tf_9G<~*cmWr1 z4KLvq?qKI4{rtP|03O0)IDjKKg=g>_F5wEU;U&C+J9rJdvECm(JcP$^08il5#wX_{`z(AYqo4$ z`RX1X9H)5*H^*!4zC^t^LA`?0%^=dPH@kn4nU87RpQ!orWOchsot&z!PgAF-tL=-z z*zHAUXrBL~dOT6bzpNhos(NnbN80}DKy%N`gS5GSrsfkf|Iy~_Q1kRv>c!dWshQts z*H6yXynxr|XHnt6Y=e|CrFOEYiH=Bb&dW?lTf)>r?iF3r3$Tih0dSvD^S+DQb_0hkmb2E?0);nL+ zJTmi^Y`%hLX1ay1S7ZB4%)A=w#LTO)PT~AS?Z4Qio|<_vc75@3 z&3iaFL-P*KU!nQP%zLr@D>HA!I`~bk58;uSpJMA9Ge5<;GxJTXvum_p4zF&}yt-9g znE4^L-`dOvv5w6A4(sl3bbSxIpV!=N)R~!gVf)qegIe!Aq;?-sSKm~xI(1{_C)n*( z=K34!!71D4J6pG>sz>H}nSJ>yHLrg|U7o2Pou%&1Q3vMw7~9{EGY=&5#rCh>ta~SEF5%i-UtsgmeY(8@4(`{ygTt?Co;{+D&GiU& zd)^b8cTcL_r_^)Uds_3gvwi-F?Oz_Kp1bPsaP`zUUZ8efs2;=7QJT-;!O@zB zaQ7n3-Q(4hlhkWCKUwp^&!|JVdzt3`scPpmbqp^~*Sv#!cy@-?m%pu!UaPJyP)8T4 z*RNNXv3h#3dSsxdFt<7t5zOD7boL_65e@WLD=KNKgmtWU>{BP=kIp5RPr*Hws=KN1vzcS~4 zT8EwXUz+nfZC;r3H?8w0wLU#~`}bcqZw^sAhpOG{_dcE2`+REilUZWs{cqOq{YmZJ znlE72%qy5icH;)hZ zW$OHA)$2>uQKC+-P)~L|U)=OxzI5-SaNpz88L1;PAJgvN%FM^K_Fk>^v6(k%^VZCp z+~@1G-Z%3QZ9X^i5Uu^sYJFqo5!!rd<`G&?%{)Tu%*>y&?shyM+H`gg*#Gm>#_f*p zPa9Wf?Z5vvmGQOe`s3;jo<4v7*MrUaen6Mr4z1@Au8!m8m zT@i0p@7aC+R?TIbC7VwFueZ&;u=%$+hRvJ5eYfnpo%q}Py`Ao#cWgb`dS|obx#k1W zvD@|b_Mp>DU~cT+TkS`mz4gv!{q|>b>+@vJ1Gcx>k+yRCmg_gaM&InaUEi6%8`#^@ zEVsvJ*L&vUCv4pwvGs5J(Yp0{Gp~bnBhvSGHFKJ3qMfKDYmWuR)ya literal 0 HcmV?d00001 diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index d211afd9..34648313 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -2,6 +2,7 @@ use { borsh::BorshSerialize, + mpl_token_metadata::{pda::find_metadata_account, state::Metadata}, solana_program::{ borsh::{get_instance_packed_len, get_packed_len, try_from_slice_unchecked}, hash::Hash, @@ -42,6 +43,13 @@ pub fn program_test() -> ProgramTest { ProgramTest::new("spl_stake_pool", id(), processor!(Processor::process)) } +pub fn program_test_with_metadata_program() -> ProgramTest { + let mut program_test = ProgramTest::default(); + program_test.add_program("spl_stake_pool", id(), processor!(Processor::process)); + program_test.add_program("mpl_token_metadata", mpl_token_metadata::id(), None); + program_test +} + pub async fn get_account(banks_client: &mut BanksClient, pubkey: &Pubkey) -> Account { banks_client .get_account(*pubkey) @@ -293,6 +301,16 @@ pub async fn get_token_balance(banks_client: &mut BanksClient, token: &Pubkey) - account_info.amount } +pub async fn get_metadata_account(banks_client: &mut BanksClient, token_mint: &Pubkey) -> Metadata { + let (token_metadata, _) = find_metadata_account(token_mint); + let token_metadata_account = banks_client + .get_account(token_metadata) + .await + .unwrap() + .unwrap(); + try_from_slice_unchecked(token_metadata_account.data.as_slice()).unwrap() +} + pub async fn get_token_supply(banks_client: &mut BanksClient, mint: &Pubkey) -> u64 { let mint_account = banks_client.get_account(*mint).await.unwrap().unwrap(); let account_info = diff --git a/program/tests/update_pool_token_metadata.rs b/program/tests/update_pool_token_metadata.rs new file mode 100644 index 00000000..fd27f806 --- /dev/null +++ b/program/tests/update_pool_token_metadata.rs @@ -0,0 +1,198 @@ +#![cfg(feature = "test-bpf")] +mod helpers; + +use { + helpers::*, + mpl_token_metadata::{ + state::{MAX_NAME_LENGTH, MAX_SYMBOL_LENGTH, MAX_URI_LENGTH}, + utils::puffed_out_string, + }, + solana_program::instruction::InstructionError, + solana_program_test::*, + solana_sdk::{ + signature::{Keypair, Signer}, + transaction::{Transaction, TransactionError}, + }, + spl_stake_pool::{ + error::StakePoolError::{SignatureMissing, WrongManager}, + instruction, MINIMUM_RESERVE_LAMPORTS, + }, +}; + +async fn setup() -> (ProgramTestContext, StakePoolAccounts) { + let mut context = program_test_with_metadata_program() + .start_with_context() + .await; + let stake_pool_accounts = StakePoolAccounts::new(); + stake_pool_accounts + .initialize_stake_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) + .await + .unwrap(); + + let name = "test_name"; + let symbol = "SYM"; + let uri = "test_uri"; + + let ix = instruction::create_token_metadata( + &spl_stake_pool::id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &context.payer.pubkey(), + name.to_string(), + symbol.to_string(), + uri.to_string(), + ); + + let transaction = Transaction::new_signed_with_payer( + &[ix], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + + context + .banks_client + .process_transaction(transaction) + .await + .unwrap(); + + (context, stake_pool_accounts) +} + +#[tokio::test] +async fn success_update_pool_token_metadata() { + let (mut context, stake_pool_accounts) = setup().await; + + let updated_name = "updated_name"; + let updated_symbol = "USYM"; + let updated_uri = "updated_uri"; + + let puffed_name = puffed_out_string(&updated_name, MAX_NAME_LENGTH); + let puffed_symbol = puffed_out_string(&updated_symbol, MAX_SYMBOL_LENGTH); + let puffed_uri = puffed_out_string(&updated_uri, MAX_URI_LENGTH); + + let ix = instruction::update_token_metadata( + &spl_stake_pool::id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + updated_name.to_string(), + updated_symbol.to_string(), + updated_uri.to_string(), + ); + + let transaction = Transaction::new_signed_with_payer( + &[ix], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + + context + .banks_client + .process_transaction(transaction) + .await + .unwrap(); + + let metadata = get_metadata_account( + &mut context.banks_client, + &stake_pool_accounts.pool_mint.pubkey(), + ) + .await; + + assert_eq!(metadata.data.name.to_string(), puffed_name); + assert_eq!(metadata.data.symbol.to_string(), puffed_symbol); + assert_eq!(metadata.data.uri.to_string(), puffed_uri); +} + +#[tokio::test] +async fn fail_manager_did_not_sign() { + let (mut context, stake_pool_accounts) = setup().await; + + let updated_name = "updated_name"; + let updated_symbol = "USYM"; + let updated_uri = "updated_uri"; + + let mut ix = instruction::update_token_metadata( + &spl_stake_pool::id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + updated_name.to_string(), + updated_symbol.to_string(), + updated_uri.to_string(), + ); + ix.accounts[1].is_signer = false; + + let transaction = Transaction::new_signed_with_payer( + &[ix], + Some(&context.payer.pubkey()), + &[&context.payer], + context.last_blockhash, + ); + + let error = context + .banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = SignatureMissing as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while manager signature missing"), + } +} + +#[tokio::test] +async fn fail_wrong_manager_signed() { + let (mut context, stake_pool_accounts) = setup().await; + + let updated_name = "updated_name"; + let updated_symbol = "USYM"; + let updated_uri = "updated_uri"; + + let random_keypair = Keypair::new(); + let ix = instruction::update_token_metadata( + &spl_stake_pool::id(), + &stake_pool_accounts.stake_pool.pubkey(), + &random_keypair.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + updated_name.to_string(), + updated_symbol.to_string(), + updated_uri.to_string(), + ); + + let transaction = Transaction::new_signed_with_payer( + &[ix], + Some(&context.payer.pubkey()), + &[&context.payer, &random_keypair], + context.last_blockhash, + ); + + let error = context + .banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = WrongManager as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while signing with the wrong manager"), + } +} From ab0d7b2b14e6d9cc33511628864abcc14603aad4 Mon Sep 17 00:00:00 2001 From: c3pko Date: Mon, 25 Jul 2022 16:55:17 -0700 Subject: [PATCH 0247/1076] Rename stake-pool/LICENSE to stake-pool/py/LICENSE --- clients/py/LICENSE | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 clients/py/LICENSE diff --git a/clients/py/LICENSE b/clients/py/LICENSE new file mode 100644 index 00000000..7e71f6e9 --- /dev/null +++ b/clients/py/LICENSE @@ -0,0 +1,13 @@ +Copyright 2022 Solana Foundation. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. From 4335deadda2cdf16745559492f9400e8fce3593f Mon Sep 17 00:00:00 2001 From: Tyera Eulberg Date: Wed, 27 Jul 2022 10:28:14 -0700 Subject: [PATCH 0248/1076] Bump solana crates to v1.10.33 (#3385) --- clients/cli/Cargo.toml | 18 +++++++++--------- program/Cargo.toml | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index a182d84a..95a60e04 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -14,15 +14,15 @@ clap = "2.33.3" serde = "1.0.130" serde_derive = "1.0.130" serde_json = "1.0.68" -solana-account-decoder = "=1.10.29" -solana-clap-utils = "=1.10.29" -solana-cli-config = "=1.10.29" -solana-cli-output = "=1.10.29" -solana-client = "=1.10.29" -solana-logger = "=1.10.29" -solana-program = "=1.10.29" -solana-remote-wallet = "=1.10.29" -solana-sdk = "=1.10.29" +solana-account-decoder = "=1.10.33" +solana-clap-utils = "=1.10.33" +solana-cli-config = "=1.10.33" +solana-cli-output = "=1.10.33" +solana-client = "=1.10.33" +solana-logger = "=1.10.33" +solana-program = "=1.10.33" +solana-remote-wallet = "=1.10.33" +solana-sdk = "=1.10.33" spl-associated-token-account = { version = "=1.0.5", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "=0.6.4", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "=3.3.0", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/program/Cargo.toml b/program/Cargo.toml index 46a69c93..77658747 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -20,7 +20,7 @@ num-traits = "0.2" num_enum = "0.5.4" serde = "1.0.130" serde_derive = "1.0.103" -solana-program = "1.10.29" +solana-program = "1.10.33" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-token = { version = "3.3", path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" @@ -28,9 +28,9 @@ bincode = "1.3.1" [dev-dependencies] proptest = "1.0" -solana-program-test = "1.10.29" -solana-sdk = "1.10.29" -solana-vote-program = "1.10.29" +solana-program-test = "1.10.33" +solana-sdk = "1.10.33" +solana-vote-program = "1.10.33" [lib] crate-type = ["cdylib", "lib"] From fe39fcc8790bee35bbdc2f772ef04b3c6aa73635 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 29 Jul 2022 22:59:50 +0200 Subject: [PATCH 0249/1076] stake-pool-py: Fix tests for Solana 1.10.33 (#3395) --- clients/py/requirements.txt | 2 +- clients/py/tests/conftest.py | 47 +++++++++-------------- clients/py/tests/test_a_time_sensitive.py | 3 +- 3 files changed, 21 insertions(+), 31 deletions(-) diff --git a/clients/py/requirements.txt b/clients/py/requirements.txt index 32b09a63..2a39c606 100644 --- a/clients/py/requirements.txt +++ b/clients/py/requirements.txt @@ -24,7 +24,7 @@ pyflakes==2.4.0 PyNaCl==1.4.0 pyparsing==2.4.7 pytest==6.2.5 -pytest-asyncio==0.16.0 +pytest-asyncio==0.19.0 requests==2.26.0 rfc3986==1.5.0 six==1.16.0 diff --git a/clients/py/tests/conftest.py b/clients/py/tests/conftest.py index a5a4f178..660bbe97 100644 --- a/clients/py/tests/conftest.py +++ b/clients/py/tests/conftest.py @@ -1,10 +1,11 @@ import asyncio import pytest +import pytest_asyncio import os import shutil import tempfile import time -from typing import Iterator, List, Tuple +from typing import AsyncIterator, List, Tuple from subprocess import Popen from solana.keypair import Keypair @@ -38,62 +39,50 @@ def solana_test_validator(): shutil.rmtree(newpath) -@pytest.fixture -def validators(event_loop, async_client, payer) -> List[PublicKey]: +@pytest_asyncio.fixture +async def validators(async_client, payer) -> List[PublicKey]: num_validators = 3 validators = [] for i in range(num_validators): vote = Keypair() node = Keypair() - event_loop.run_until_complete( - create_vote(async_client, payer, vote, node, payer.public_key, payer.public_key, 10) - ) + await create_vote(async_client, payer, vote, node, payer.public_key, payer.public_key, 10) validators.append(vote.public_key) return validators -@pytest.fixture -def stake_pool_addresses(event_loop, async_client, payer, validators, waiter) -> Tuple[PublicKey, PublicKey]: +@pytest_asyncio.fixture +async def stake_pool_addresses(async_client, payer, validators, waiter) -> Tuple[PublicKey, PublicKey]: fee = Fee(numerator=1, denominator=1000) referral_fee = 20 - event_loop.run_until_complete(waiter.wait_for_next_epoch_if_soon(async_client)) - stake_pool_addresses = event_loop.run_until_complete( - create_all(async_client, payer, fee, referral_fee) - ) + # Change back to `wait_for_next_epoch_if_soon` once https://github.com/solana-labs/solana/pull/26851 is available + await waiter.wait_for_next_epoch(async_client) + stake_pool_addresses = await create_all(async_client, payer, fee, referral_fee) for validator in validators: - event_loop.run_until_complete( - add_validator_to_pool(async_client, payer, stake_pool_addresses[0], validator) - ) + await add_validator_to_pool(async_client, payer, stake_pool_addresses[0], validator) return stake_pool_addresses -@pytest.fixture -def event_loop(): - loop = asyncio.get_event_loop() - yield loop - loop.close() - - -@pytest.fixture -def async_client(event_loop, solana_test_validator) -> Iterator[AsyncClient]: +@pytest_asyncio.fixture +async def async_client(solana_test_validator) -> AsyncIterator[AsyncClient]: async_client = AsyncClient(commitment=Confirmed) total_attempts = 10 current_attempt = 0 - while not event_loop.run_until_complete(async_client.is_connected()): + while not await async_client.is_connected(): if current_attempt == total_attempts: raise Exception("Could not connect to test validator") else: current_attempt += 1 time.sleep(1) yield async_client - event_loop.run_until_complete(async_client.close()) + await async_client.close() -@pytest.fixture -def payer(event_loop, async_client) -> Keypair: +@pytest_asyncio.fixture +async def payer(async_client) -> Keypair: payer = Keypair() airdrop_lamports = 20_000_000_000 - event_loop.run_until_complete(airdrop(async_client, payer.public_key, airdrop_lamports)) + await airdrop(async_client, payer.public_key, airdrop_lamports) return payer diff --git a/clients/py/tests/test_a_time_sensitive.py b/clients/py/tests/test_a_time_sensitive.py index 82e82764..abac2005 100644 --- a/clients/py/tests/test_a_time_sensitive.py +++ b/clients/py/tests/test_a_time_sensitive.py @@ -13,9 +13,10 @@ @pytest.mark.asyncio async def test_increase_decrease_this_is_very_slow(async_client, validators, payer, stake_pool_addresses, waiter): (stake_pool_address, validator_list_address) = stake_pool_addresses + resp = await async_client.get_minimum_balance_for_rent_exemption(STAKE_LEN) stake_rent_exemption = resp['result'] - increase_amount = MINIMUM_ACTIVE_STAKE * 2 + increase_amount = MINIMUM_ACTIVE_STAKE * 4 decrease_amount = increase_amount // 2 deposit_amount = (increase_amount + stake_rent_exemption) * len(validators) From ab1432b3cd8a88e56c017981d9502b606ab3e1ab Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 3 Aug 2022 01:19:33 +0200 Subject: [PATCH 0250/1076] stake-pool-py: Clean up dependencies (#3412) --- clients/py/README.md | 3 +- clients/py/optional-requirements.txt | 15 ++++++++++ clients/py/requirements.txt | 42 +++++++++------------------- clients/py/stake/instructions.py | 5 ++-- clients/py/stake/state.py | 5 ++-- clients/py/stake_pool/state.py | 7 +++-- clients/py/tests/conftest.py | 5 ++-- clients/py/tests/test_stake.py | 2 +- clients/py/vote/instructions.py | 5 ++-- 9 files changed, 46 insertions(+), 43 deletions(-) create mode 100644 clients/py/optional-requirements.txt diff --git a/clients/py/README.md b/clients/py/README.md index 49866fb6..cda7beea 100644 --- a/clients/py/README.md +++ b/clients/py/README.md @@ -22,10 +22,11 @@ $ python3 -m venv venv $ source venv/bin/activate ``` -3. Install requirements +3. Install build and dev requirements ``` $ pip install -r requirements.txt +$ pip install -r optional-requirements.txt ``` 4. Install the Solana tool suite: https://docs.solana.com/cli/install-solana-cli-tools diff --git a/clients/py/optional-requirements.txt b/clients/py/optional-requirements.txt new file mode 100644 index 00000000..5aa59319 --- /dev/null +++ b/clients/py/optional-requirements.txt @@ -0,0 +1,15 @@ +attrs==22.1.0 +flake8==5.0.3 +iniconfig==1.1.1 +mccabe==0.7.0 +mypy==0.971 +mypy-extensions==0.4.3 +packaging==21.3 +pluggy==1.0.0 +py==1.11.0 +pycodestyle==2.9.0 +pyflakes==2.5.0 +pyparsing==3.0.9 +pytest==7.1.2 +pytest-asyncio==0.19.0 +tomli==2.0.1 diff --git a/clients/py/requirements.txt b/clients/py/requirements.txt index 2a39c606..1b72ffc6 100644 --- a/clients/py/requirements.txt +++ b/clients/py/requirements.txt @@ -1,35 +1,19 @@ -anyio==3.3.4 -attrs==21.2.0 -base58==2.1.0 +anyio==3.6.1 +base58==2.1.1 cachetools==4.2.4 -certifi==2021.10.8 -cffi==1.15.0 -charset-normalizer==2.0.7 -construct==2.10.67 -flake8==4.0.1 +certifi==2022.6.15 +cffi==1.15.1 +charset-normalizer==2.1.0 +construct==2.10.68 h11==0.12.0 -httpcore==0.13.7 -httpx==0.20.0 +httpcore==0.15.0 +httpx==0.23.0 idna==3.3 -iniconfig==1.1.1 -mccabe==0.6.1 -mypy==0.910 -mypy-extensions==0.4.3 -packaging==21.2 -pluggy==1.0.0 -py==1.10.0 -pycodestyle==2.8.0 -pycparser==2.20 -pyflakes==2.4.0 -PyNaCl==1.4.0 -pyparsing==2.4.7 -pytest==6.2.5 -pytest-asyncio==0.19.0 -requests==2.26.0 +pycparser==2.21 +PyNaCl==1.5.0 +requests==2.28.1 rfc3986==1.5.0 -six==1.16.0 sniffio==1.2.0 solana==0.18.1 -toml==0.10.2 -typing-extensions==3.10.0.2 -urllib3==1.26.7 +typing_extensions==4.3.0 +urllib3==1.26.11 diff --git a/clients/py/stake/instructions.py b/clients/py/stake/instructions.py index 29378e52..f4b116ba 100644 --- a/clients/py/stake/instructions.py +++ b/clients/py/stake/instructions.py @@ -5,9 +5,8 @@ from construct import Switch # type: ignore from construct import Int32ul, Pass # type: ignore -from construct import Struct +from construct import Bytes, Struct -from solana._layouts.shared import PUBLIC_KEY_LAYOUT from solana.publickey import PublicKey from solana.sysvar import SYSVAR_RENT_PUBKEY from solana.transaction import AccountMeta, TransactionInstruction @@ -15,6 +14,8 @@ from stake.constants import STAKE_PROGRAM_ID from stake.state import AUTHORIZED_LAYOUT, LOCKUP_LAYOUT, Authorized, Lockup, StakeAuthorize +PUBLIC_KEY_LAYOUT = Bytes(32) + class InitializeParams(NamedTuple): """Initialize stake transaction params.""" diff --git a/clients/py/stake/state.py b/clients/py/stake/state.py index 4911de76..9ff48d34 100644 --- a/clients/py/stake/state.py +++ b/clients/py/stake/state.py @@ -2,11 +2,12 @@ from enum import IntEnum from typing import NamedTuple, Dict -from construct import Container, Struct, Float64l, Int32ul, Int64ul # type: ignore +from construct import Bytes, Container, Struct, Float64l, Int32ul, Int64ul # type: ignore from solana.publickey import PublicKey from solana.utils.helpers import decode_byte_string -from solana._layouts.shared import PUBLIC_KEY_LAYOUT + +PUBLIC_KEY_LAYOUT = Bytes(32) class Lockup(NamedTuple): diff --git a/clients/py/stake_pool/state.py b/clients/py/stake_pool/state.py index 93acc103..8791c3e2 100644 --- a/clients/py/stake_pool/state.py +++ b/clients/py/stake_pool/state.py @@ -2,17 +2,18 @@ from enum import IntEnum from typing import List, NamedTuple, Optional -from construct import Container, Struct, Switch, Int8ul, Int32ul, Int64ul, Pass # type: ignore +from construct import Bytes, Container, Struct, Switch, Int8ul, Int32ul, Int64ul, Pass # type: ignore from solana.publickey import PublicKey from solana.utils.helpers import decode_byte_string -from solana._layouts.shared import PUBLIC_KEY_LAYOUT from stake.state import Lockup, LOCKUP_LAYOUT +PUBLIC_KEY_LAYOUT = Bytes(32) + def decode_optional_publickey(container: Container) -> Optional[PublicKey]: if container: - return PublicKey(container) + return PublicKey(container.popitem()[1]) else: return None diff --git a/clients/py/tests/conftest.py b/clients/py/tests/conftest.py index 660bbe97..9e39dda8 100644 --- a/clients/py/tests/conftest.py +++ b/clients/py/tests/conftest.py @@ -4,7 +4,6 @@ import os import shutil import tempfile -import time from typing import AsyncIterator, List, Tuple from subprocess import Popen @@ -66,14 +65,14 @@ async def stake_pool_addresses(async_client, payer, validators, waiter) -> Tuple @pytest_asyncio.fixture async def async_client(solana_test_validator) -> AsyncIterator[AsyncClient]: async_client = AsyncClient(commitment=Confirmed) - total_attempts = 10 + total_attempts = 20 current_attempt = 0 while not await async_client.is_connected(): if current_attempt == total_attempts: raise Exception("Could not connect to test validator") else: current_attempt += 1 - time.sleep(1) + await asyncio.sleep(1.0) yield async_client await async_client.close() diff --git a/clients/py/tests/test_stake.py b/clients/py/tests/test_stake.py index 53b23e1b..fdf016bc 100644 --- a/clients/py/tests/test_stake.py +++ b/clients/py/tests/test_stake.py @@ -10,7 +10,7 @@ @pytest.mark.asyncio async def test_create_stake(async_client, payer): stake = Keypair() - await create_stake(async_client, payer, stake, payer.public_key, MINIMUM_DELEGATION) + await create_stake(async_client, payer, stake, payer.public_key, 1) @pytest.mark.asyncio diff --git a/clients/py/vote/instructions.py b/clients/py/vote/instructions.py index 38106535..267aeb4a 100644 --- a/clients/py/vote/instructions.py +++ b/clients/py/vote/instructions.py @@ -3,15 +3,16 @@ from enum import IntEnum from typing import NamedTuple -from construct import Struct, Switch, Int8ul, Int32ul, Pass # type: ignore +from construct import Bytes, Struct, Switch, Int8ul, Int32ul, Pass # type: ignore from solana.publickey import PublicKey from solana.sysvar import SYSVAR_CLOCK_PUBKEY, SYSVAR_RENT_PUBKEY from solana.transaction import AccountMeta, TransactionInstruction -from solana._layouts.shared import PUBLIC_KEY_LAYOUT from vote.constants import VOTE_PROGRAM_ID +PUBLIC_KEY_LAYOUT = Bytes(32) + class InitializeParams(NamedTuple): """Initialize vote account params.""" From 5d03926f47314cf8cc8fcff7505f99a2c7396de2 Mon Sep 17 00:00:00 2001 From: Tyera Eulberg Date: Wed, 3 Aug 2022 00:24:38 -0700 Subject: [PATCH 0251/1076] Bump spl-token (#3418) --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 95a60e04..b1c3943a 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -25,7 +25,7 @@ solana-remote-wallet = "=1.10.33" solana-sdk = "=1.10.33" spl-associated-token-account = { version = "=1.0.5", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "=0.6.4", path="../program", features = [ "no-entrypoint" ] } -spl-token = { version = "=3.3.0", path="../../token/program", features = [ "no-entrypoint" ] } +spl-token = { version = "=3.3.1", path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" bincode = "1.3.1" From fa0ec72deff0331a807c78491c316203fc64c128 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 4 Aug 2022 01:03:04 +0200 Subject: [PATCH 0252/1076] token/ata: Bump versions to 3.4.0 and 1.1.0, respectively (#3427) --- clients/cli/Cargo.toml | 4 ++-- program/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index b1c3943a..8c4e8bf8 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -23,9 +23,9 @@ solana-logger = "=1.10.33" solana-program = "=1.10.33" solana-remote-wallet = "=1.10.33" solana-sdk = "=1.10.33" -spl-associated-token-account = { version = "=1.0.5", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } +spl-associated-token-account = { version = "=1.1.0", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "=0.6.4", path="../program", features = [ "no-entrypoint" ] } -spl-token = { version = "=3.3.1", path="../../token/program", features = [ "no-entrypoint" ] } +spl-token = { version = "=3.4.0", path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" bincode = "1.3.1" diff --git a/program/Cargo.toml b/program/Cargo.toml index 77658747..e01c839e 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -22,7 +22,7 @@ serde = "1.0.130" serde_derive = "1.0.103" solana-program = "1.10.33" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } -spl-token = { version = "3.3", path = "../../token/program", features = [ "no-entrypoint" ] } +spl-token = { version = "3.4", path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" bincode = "1.3.1" From 24834a635a01dcf10f96c0b08bdf95bfa5e7c1c5 Mon Sep 17 00:00:00 2001 From: Tyera Eulberg Date: Thu, 4 Aug 2022 00:09:38 -0700 Subject: [PATCH 0253/1076] Bump token to v3.5.0 and ata to v1.1.1 (#3430) --- clients/cli/Cargo.toml | 4 ++-- program/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 8c4e8bf8..74237901 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -23,9 +23,9 @@ solana-logger = "=1.10.33" solana-program = "=1.10.33" solana-remote-wallet = "=1.10.33" solana-sdk = "=1.10.33" -spl-associated-token-account = { version = "=1.1.0", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } +spl-associated-token-account = { version = "=1.1.1", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "=0.6.4", path="../program", features = [ "no-entrypoint" ] } -spl-token = { version = "=3.4.0", path="../../token/program", features = [ "no-entrypoint" ] } +spl-token = { version = "=3.5.0", path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" bincode = "1.3.1" diff --git a/program/Cargo.toml b/program/Cargo.toml index e01c839e..5a3abca2 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -22,7 +22,7 @@ serde = "1.0.130" serde_derive = "1.0.103" solana-program = "1.10.33" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } -spl-token = { version = "3.4", path = "../../token/program", features = [ "no-entrypoint" ] } +spl-token = { version = "3.5", path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" bincode = "1.3.1" From 51254ea87cf7889284920e9ca4ba6f69a41805e5 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 11 Aug 2022 19:52:23 +0200 Subject: [PATCH 0254/1076] stake-pool: Bump versions to 0.7.0 (#3456) --- clients/cli/Cargo.toml | 4 ++-- program/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 74237901..53c17882 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -6,7 +6,7 @@ homepage = "https://spl.solana.com/stake-pool" license = "Apache-2.0" name = "spl-stake-pool-cli" repository = "https://github.com/solana-labs/solana-program-library" -version = "0.6.4" +version = "0.7.0" [dependencies] borsh = "0.9" @@ -24,7 +24,7 @@ solana-program = "=1.10.33" solana-remote-wallet = "=1.10.33" solana-sdk = "=1.10.33" spl-associated-token-account = { version = "=1.1.1", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } -spl-stake-pool = { version = "=0.6.4", path="../program", features = [ "no-entrypoint" ] } +spl-stake-pool = { version = "=0.7.0", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "=3.5.0", path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" bincode = "1.3.1" diff --git a/program/Cargo.toml b/program/Cargo.toml index 5a3abca2..261e0bc1 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "spl-stake-pool" -version = "0.6.4" +version = "0.7.0" description = "Solana Program Library Stake Pool" authors = ["Solana Maintainers "] repository = "https://github.com/solana-labs/solana-program-library" From bdfd17285ffa60d99526bcf33983d007d1711922 Mon Sep 17 00:00:00 2001 From: Tyera Eulberg Date: Tue, 16 Aug 2022 11:33:24 -0700 Subject: [PATCH 0255/1076] Bump solana to v1.10.35 (#3485) --- clients/cli/Cargo.toml | 18 +++++++++--------- program/Cargo.toml | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 53c17882..c6150bcf 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -14,15 +14,15 @@ clap = "2.33.3" serde = "1.0.130" serde_derive = "1.0.130" serde_json = "1.0.68" -solana-account-decoder = "=1.10.33" -solana-clap-utils = "=1.10.33" -solana-cli-config = "=1.10.33" -solana-cli-output = "=1.10.33" -solana-client = "=1.10.33" -solana-logger = "=1.10.33" -solana-program = "=1.10.33" -solana-remote-wallet = "=1.10.33" -solana-sdk = "=1.10.33" +solana-account-decoder = "=1.10.35" +solana-clap-utils = "=1.10.35" +solana-cli-config = "=1.10.35" +solana-cli-output = "=1.10.35" +solana-client = "=1.10.35" +solana-logger = "=1.10.35" +solana-program = "=1.10.35" +solana-remote-wallet = "=1.10.35" +solana-sdk = "=1.10.35" spl-associated-token-account = { version = "=1.1.1", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "=0.7.0", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "=3.5.0", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/program/Cargo.toml b/program/Cargo.toml index 261e0bc1..8a997302 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -20,7 +20,7 @@ num-traits = "0.2" num_enum = "0.5.4" serde = "1.0.130" serde_derive = "1.0.103" -solana-program = "1.10.33" +solana-program = "1.10.35" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-token = { version = "3.5", path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" @@ -28,9 +28,9 @@ bincode = "1.3.1" [dev-dependencies] proptest = "1.0" -solana-program-test = "1.10.33" -solana-sdk = "1.10.33" -solana-vote-program = "1.10.33" +solana-program-test = "1.10.35" +solana-sdk = "1.10.35" +solana-vote-program = "1.10.35" [lib] crate-type = ["cdylib", "lib"] From d3fbb3661b9bae1173bf74a3b7123eadc52d240a Mon Sep 17 00:00:00 2001 From: hana <81144685+2501babe@users.noreply.github.com> Date: Thu, 18 Aug 2022 12:16:02 -0700 Subject: [PATCH 0256/1076] Update rust to 1.60, solana to 1.11.6 (#3492) also change bpf to sbf throughout the codebase Co-authored-by: Jon Cinque --- clients/cli/Cargo.toml | 18 +++++++++--------- clients/cli/src/client.rs | 18 +++++++----------- clients/py/tests/test_bot_rebalance.py | 9 ++++++--- clients/py/tests/test_stake.py | 2 +- program/Cargo.toml | 10 +++++----- program/tests/create_pool_token_metadata.rs | 2 +- program/tests/decrease.rs | 2 +- program/tests/deposit.rs | 2 +- program/tests/deposit_authority.rs | 2 +- program/tests/deposit_sol.rs | 2 +- program/tests/force_destake.rs | 2 +- program/tests/huge_pool.rs | 2 +- program/tests/increase.rs | 2 +- program/tests/initialize.rs | 2 +- program/tests/set_deposit_fee.rs | 2 +- program/tests/set_epoch_fee.rs | 2 +- program/tests/set_funding_authority.rs | 2 +- program/tests/set_manager.rs | 2 +- program/tests/set_preferred.rs | 2 +- program/tests/set_referral_fee.rs | 2 +- program/tests/set_staker.rs | 2 +- program/tests/set_withdrawal_fee.rs | 2 +- program/tests/update_pool_token_metadata.rs | 2 +- program/tests/update_stake_pool_balance.rs | 2 +- program/tests/update_validator_list_balance.rs | 2 +- program/tests/vsa_add.rs | 2 +- program/tests/vsa_remove.rs | 2 +- program/tests/withdraw.rs | 2 +- program/tests/withdraw_sol.rs | 2 +- 29 files changed, 52 insertions(+), 53 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index c6150bcf..1984f073 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -14,15 +14,15 @@ clap = "2.33.3" serde = "1.0.130" serde_derive = "1.0.130" serde_json = "1.0.68" -solana-account-decoder = "=1.10.35" -solana-clap-utils = "=1.10.35" -solana-cli-config = "=1.10.35" -solana-cli-output = "=1.10.35" -solana-client = "=1.10.35" -solana-logger = "=1.10.35" -solana-program = "=1.10.35" -solana-remote-wallet = "=1.10.35" -solana-sdk = "=1.10.35" +solana-account-decoder = "=1.11.6" +solana-clap-utils = "=1.11.6" +solana-cli-config = "=1.11.6" +solana-cli-output = "=1.11.6" +solana-client = "=1.11.6" +solana-logger = "=1.11.6" +solana-program = "=1.11.6" +solana-remote-wallet = "=1.11.6" +solana-sdk = "=1.11.6" spl-associated-token-account = { version = "=1.1.1", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "=0.7.0", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "=3.5.0", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/clients/cli/src/client.rs b/clients/cli/src/client.rs index 005d8908..039d057c 100644 --- a/clients/cli/src/client.rs +++ b/clients/cli/src/client.rs @@ -5,7 +5,7 @@ use { client_error::ClientError, rpc_client::RpcClient, rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig}, - rpc_filter::{Memcmp, MemcmpEncodedBytes, MemcmpEncoding, RpcFilterType}, + rpc_filter::{Memcmp, RpcFilterType}, }, solana_program::{borsh::try_from_slice_unchecked, program_pack::Pack, pubkey::Pubkey, stake}, spl_stake_pool::{ @@ -85,11 +85,11 @@ pub(crate) fn get_stake_pools( .get_program_accounts_with_config( &spl_stake_pool::id(), RpcProgramAccountsConfig { - filters: Some(vec![RpcFilterType::Memcmp(Memcmp { - offset: 0, // 0 is the account type - bytes: MemcmpEncodedBytes::Base58("2".to_string()), - encoding: None, - })]), + // 0 is the account type + filters: Some(vec![RpcFilterType::Memcmp(Memcmp::new_raw_bytes( + 0, + vec![1], + ))]), account_config: RpcAccountInfoConfig { encoding: Some(UiAccountEncoding::Base64), ..RpcAccountInfoConfig::default() @@ -130,11 +130,7 @@ pub(crate) fn get_all_stake( RpcProgramAccountsConfig { filters: Some(vec![ // Filter by `Meta::authorized::staker`, which begins at byte offset 12 - RpcFilterType::Memcmp(Memcmp { - offset: 12, - bytes: MemcmpEncodedBytes::Base58(authorized_staker.to_string()), - encoding: Some(MemcmpEncoding::Binary), - }), + RpcFilterType::Memcmp(Memcmp::new_base58_encoded(12, authorized_staker.as_ref())), ]), account_config: RpcAccountInfoConfig { encoding: Some(solana_account_decoder::UiAccountEncoding::Base64), diff --git a/clients/py/tests/test_bot_rebalance.py b/clients/py/tests/test_bot_rebalance.py index 69876e11..e9c32e02 100644 --- a/clients/py/tests/test_bot_rebalance.py +++ b/clients/py/tests/test_bot_rebalance.py @@ -19,7 +19,10 @@ async def test_rebalance_this_is_very_slow(async_client, validators, payer, stak (stake_pool_address, validator_list_address) = stake_pool_addresses resp = await async_client.get_minimum_balance_for_rent_exemption(STAKE_LEN) stake_rent_exemption = resp['result'] - increase_amount = MINIMUM_ACTIVE_STAKE + # With minimum delegation at MINIMUM_DELEGATION + rent-exemption, when + # decreasing, we'll need rent exemption + minimum delegation delegated to + # cover all movements + increase_amount = MINIMUM_ACTIVE_STAKE + stake_rent_exemption deposit_amount = (increase_amount + stake_rent_exemption) * len(validators) resp = await async_client.get_account_info(stake_pool_address, commitment=Confirmed) @@ -28,7 +31,7 @@ async def test_rebalance_this_is_very_slow(async_client, validators, payer, stak token_account = get_associated_token_address(payer.public_key, stake_pool.pool_mint) await deposit_sol(async_client, payer, stake_pool_address, token_account, deposit_amount) - # Test case 1: Increase + # Test case 1: Increase everywhere await rebalance(ENDPOINT, stake_pool_address, payer, 0.0) # should only have minimum left @@ -43,7 +46,7 @@ async def test_rebalance_this_is_very_slow(async_client, validators, payer, stak assert validator.active_stake_lamports == 0 assert validator.transient_stake_lamports == increase_amount + stake_rent_exemption - # Test case 2: Decrease + # Test case 2: Decrease everything back to reserve print('Waiting for next epoch') await waiter.wait_for_next_epoch(async_client) await rebalance(ENDPOINT, stake_pool_address, payer, deposit_amount / LAMPORTS_PER_SOL) diff --git a/clients/py/tests/test_stake.py b/clients/py/tests/test_stake.py index fdf016bc..ab7cc3a4 100644 --- a/clients/py/tests/test_stake.py +++ b/clients/py/tests/test_stake.py @@ -17,7 +17,7 @@ async def test_create_stake(async_client, payer): async def test_delegate_stake(async_client, validators, payer): validator = validators[0] stake = Keypair() - await create_stake(async_client, payer, stake, payer.public_key, 1) + await create_stake(async_client, payer, stake, payer.public_key, MINIMUM_DELEGATION) await delegate_stake(async_client, payer, payer, stake.public_key, validator) diff --git a/program/Cargo.toml b/program/Cargo.toml index 8a997302..bf7ce2e9 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -9,7 +9,7 @@ edition = "2018" [features] no-entrypoint = [] -test-bpf = [] +test-sbf = [] [dependencies] arrayref = "0.3.6" @@ -20,7 +20,7 @@ num-traits = "0.2" num_enum = "0.5.4" serde = "1.0.130" serde_derive = "1.0.103" -solana-program = "1.10.35" +solana-program = "1.11.6" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-token = { version = "3.5", path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" @@ -28,9 +28,9 @@ bincode = "1.3.1" [dev-dependencies] proptest = "1.0" -solana-program-test = "1.10.35" -solana-sdk = "1.10.35" -solana-vote-program = "1.10.35" +solana-program-test = "1.11.6" +solana-sdk = "1.11.6" +solana-vote-program = "1.11.6" [lib] crate-type = ["cdylib", "lib"] diff --git a/program/tests/create_pool_token_metadata.rs b/program/tests/create_pool_token_metadata.rs index 3068df62..7d648969 100644 --- a/program/tests/create_pool_token_metadata.rs +++ b/program/tests/create_pool_token_metadata.rs @@ -1,4 +1,4 @@ -#![cfg(feature = "test-bpf")] +#![cfg(feature = "test-sbf")] mod helpers; use { diff --git a/program/tests/decrease.rs b/program/tests/decrease.rs index 1089fba9..a050b407 100644 --- a/program/tests/decrease.rs +++ b/program/tests/decrease.rs @@ -1,4 +1,4 @@ -#![cfg(feature = "test-bpf")] +#![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index d38bb63a..4a586550 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -1,4 +1,4 @@ -#![cfg(feature = "test-bpf")] +#![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/deposit_authority.rs b/program/tests/deposit_authority.rs index afae4c08..b78bdc42 100644 --- a/program/tests/deposit_authority.rs +++ b/program/tests/deposit_authority.rs @@ -1,4 +1,4 @@ -#![cfg(feature = "test-bpf")] +#![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/deposit_sol.rs b/program/tests/deposit_sol.rs index 72121a0e..c38aebed 100644 --- a/program/tests/deposit_sol.rs +++ b/program/tests/deposit_sol.rs @@ -1,4 +1,4 @@ -#![cfg(feature = "test-bpf")] +#![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/force_destake.rs b/program/tests/force_destake.rs index afc33fb6..a6820529 100644 --- a/program/tests/force_destake.rs +++ b/program/tests/force_destake.rs @@ -1,4 +1,4 @@ -#![cfg(feature = "test-bpf")] +#![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index d5d7a20d..b74186b2 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -1,4 +1,4 @@ -#![cfg(feature = "test-bpf")] +#![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/increase.rs b/program/tests/increase.rs index 13f55564..5f73615b 100644 --- a/program/tests/increase.rs +++ b/program/tests/increase.rs @@ -1,4 +1,4 @@ -#![cfg(feature = "test-bpf")] +#![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index 220f621e..fb4cfd0c 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -1,4 +1,4 @@ -#![cfg(feature = "test-bpf")] +#![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/set_deposit_fee.rs b/program/tests/set_deposit_fee.rs index ba7ead80..7f7c268b 100644 --- a/program/tests/set_deposit_fee.rs +++ b/program/tests/set_deposit_fee.rs @@ -1,4 +1,4 @@ -#![cfg(feature = "test-bpf")] +#![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/set_epoch_fee.rs b/program/tests/set_epoch_fee.rs index d63a23a6..2df679cb 100644 --- a/program/tests/set_epoch_fee.rs +++ b/program/tests/set_epoch_fee.rs @@ -1,4 +1,4 @@ -#![cfg(feature = "test-bpf")] +#![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/set_funding_authority.rs b/program/tests/set_funding_authority.rs index fb4607da..08e0668e 100644 --- a/program/tests/set_funding_authority.rs +++ b/program/tests/set_funding_authority.rs @@ -1,4 +1,4 @@ -#![cfg(feature = "test-bpf")] +#![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/set_manager.rs b/program/tests/set_manager.rs index 64fcdb06..987211ce 100644 --- a/program/tests/set_manager.rs +++ b/program/tests/set_manager.rs @@ -1,4 +1,4 @@ -#![cfg(feature = "test-bpf")] +#![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/set_preferred.rs b/program/tests/set_preferred.rs index 10b11a81..83586d60 100644 --- a/program/tests/set_preferred.rs +++ b/program/tests/set_preferred.rs @@ -1,4 +1,4 @@ -#![cfg(feature = "test-bpf")] +#![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/set_referral_fee.rs b/program/tests/set_referral_fee.rs index cdc93fb9..a2f6166b 100644 --- a/program/tests/set_referral_fee.rs +++ b/program/tests/set_referral_fee.rs @@ -1,4 +1,4 @@ -#![cfg(feature = "test-bpf")] +#![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/set_staker.rs b/program/tests/set_staker.rs index 49efad60..dca486a6 100644 --- a/program/tests/set_staker.rs +++ b/program/tests/set_staker.rs @@ -1,4 +1,4 @@ -#![cfg(feature = "test-bpf")] +#![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/set_withdrawal_fee.rs b/program/tests/set_withdrawal_fee.rs index 1b2d48ae..00ae0bf5 100644 --- a/program/tests/set_withdrawal_fee.rs +++ b/program/tests/set_withdrawal_fee.rs @@ -1,4 +1,4 @@ -#![cfg(feature = "test-bpf")] +#![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/update_pool_token_metadata.rs b/program/tests/update_pool_token_metadata.rs index fd27f806..1e2d01d3 100644 --- a/program/tests/update_pool_token_metadata.rs +++ b/program/tests/update_pool_token_metadata.rs @@ -1,4 +1,4 @@ -#![cfg(feature = "test-bpf")] +#![cfg(feature = "test-sbf")] mod helpers; use { diff --git a/program/tests/update_stake_pool_balance.rs b/program/tests/update_stake_pool_balance.rs index 3b415c0a..099797f9 100644 --- a/program/tests/update_stake_pool_balance.rs +++ b/program/tests/update_stake_pool_balance.rs @@ -1,4 +1,4 @@ -#![cfg(feature = "test-bpf")] +#![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index 21ba0f3d..75277c0e 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -1,4 +1,4 @@ -#![cfg(feature = "test-bpf")] +#![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index de0c6665..0e640de7 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -1,4 +1,4 @@ -#![cfg(feature = "test-bpf")] +#![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index aec2b983..209d5193 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -1,4 +1,4 @@ -#![cfg(feature = "test-bpf")] +#![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index e3fbc2ba..96a899e5 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -1,4 +1,4 @@ -#![cfg(feature = "test-bpf")] +#![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/withdraw_sol.rs b/program/tests/withdraw_sol.rs index 82686de9..2abcfc89 100644 --- a/program/tests/withdraw_sol.rs +++ b/program/tests/withdraw_sol.rs @@ -1,4 +1,4 @@ -#![cfg(feature = "test-bpf")] +#![cfg(feature = "test-sbf")] mod helpers; From 33f043aa4d17a204a795c8f6a96c5f272b45d8db Mon Sep 17 00:00:00 2001 From: Edgar Date: Fri, 19 Aug 2022 12:57:32 -0400 Subject: [PATCH 0257/1076] stake-pool: fix docstring typos (#3495) fix typos --- clients/js-legacy/src/instructions.ts | 6 +++--- clients/py/stake_pool/instructions.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/clients/js-legacy/src/instructions.ts b/clients/js-legacy/src/instructions.ts index 422bdc67..babcc2cd 100644 --- a/clients/js-legacy/src/instructions.ts +++ b/clients/js-legacy/src/instructions.ts @@ -416,7 +416,7 @@ export class StakePoolInstruction { } /** - * Creates a transaction instruction to deposit SOL into a stake pool. + * Creates a transaction instruction to deposit a stake account into a stake pool. */ static depositStake(params: DepositStakeParams): TransactionInstruction { const { @@ -462,7 +462,7 @@ export class StakePoolInstruction { } /** - * Creates a transaction instruction to withdraw SOL from a stake pool. + * Creates a transaction instruction to deposit SOL into a stake pool. */ static depositSol(params: DepositSolParams): TransactionInstruction { const { @@ -510,7 +510,7 @@ export class StakePoolInstruction { } /** - * Creates a transaction instruction to withdraw SOL from a stake pool. + * Creates a transaction instruction to withdraw active stake from a stake pool. */ static withdrawStake(params: WithdrawStakeParams): TransactionInstruction { const { diff --git a/clients/py/stake_pool/instructions.py b/clients/py/stake_pool/instructions.py index dfc3c8a3..282037bd 100644 --- a/clients/py/stake_pool/instructions.py +++ b/clients/py/stake_pool/instructions.py @@ -674,7 +674,7 @@ def remove_validator_from_pool_with_vote( def deposit_stake(params: DepositStakeParams) -> TransactionInstruction: - """Creates a transaction instruction to deposit SOL into a stake pool.""" + """Creates a transaction instruction to deposit a stake account into a stake pool.""" keys = [ AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=True), AccountMeta(pubkey=params.validator_list, is_signer=False, is_writable=True), @@ -705,7 +705,7 @@ def deposit_stake(params: DepositStakeParams) -> TransactionInstruction: def withdraw_stake(params: WithdrawStakeParams) -> TransactionInstruction: - """Creates a transaction instruction to withdraw SOL from a stake pool.""" + """Creates a transaction instruction to withdraw active stake from a stake pool.""" return TransactionInstruction( keys=[ AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=True), From f4087332f6a5e0c71298a285796ae814d338c891 Mon Sep 17 00:00:00 2001 From: Athar Mohammad <56029409+atharmohammad@users.noreply.github.com> Date: Tue, 23 Aug 2022 03:06:13 +0530 Subject: [PATCH 0258/1076] Extends withdraw functionality in stake pool (#3445) * extends withdraw to merge if stake account is provided * check if account is stake account and delegated to same validator * fixing tests and defining withdraw accounts for delegated stake reciever * implementation improvements in cli * fix js tests * added test for uninitialized stake account --- clients/cli/scripts/withdraw.sh | 37 ++++++- clients/cli/src/main.rs | 106 +++++++++++++++++--- clients/js-legacy/src/index.ts | 92 ++++++++++++++++- clients/js-legacy/src/layouts.ts | 62 ++++++++++++ clients/js-legacy/test/instructions.test.ts | 80 +++++++++++++-- clients/js-legacy/test/mocks.ts | 78 +++++++++++++- 6 files changed, 426 insertions(+), 29 deletions(-) diff --git a/clients/cli/scripts/withdraw.sh b/clients/cli/scripts/withdraw.sh index deeee7a0..733acec6 100755 --- a/clients/cli/scripts/withdraw.sh +++ b/clients/cli/scripts/withdraw.sh @@ -15,6 +15,16 @@ create_keypair () { fi } +create_stake_account () { + authority=$1 + while read -r validator + do + solana-keygen new --no-passphrase -o "$keys_dir/stake_account_$validator.json" + solana create-stake-account "$keys_dir/stake_account_$validator.json" 2 + solana delegate-stake --force "$keys_dir/stake_account_$validator.json" "$validator" + done < "$validator_list" +} + withdraw_stakes () { stake_pool_pubkey=$1 validator_list=$2 @@ -25,20 +35,41 @@ withdraw_stakes () { done < "$validator_list" } -stake_pool_pubkey=$(solana-keygen pubkey "$stake_pool_keyfile") -keys_dir=keys +withdraw_stakes_to_stake_receiver () { + stake_pool_pubkey=$1 + validator_list=$2 + pool_amount=$3 + while read -r validator + do + stake_receiver=$(solana-keygen pubkey "$keys_dir/stake_account_$validator.json") + $spl_stake_pool withdraw-stake "$stake_pool_pubkey" "$pool_amount" --vote-account "$validator" --stake-receiver "$stake_receiver" + done < "$validator_list" +} spl_stake_pool=spl-stake-pool # Uncomment to use a locally build CLI -#spl_stake_pool=../../../target/debug/spl-stake-pool +# spl_stake_pool=../../../target/debug/spl-stake-pool + +stake_pool_pubkey=$(solana-keygen pubkey "$stake_pool_keyfile") +keys_dir=keys echo "Setting up keys directory $keys_dir" mkdir -p $keys_dir authority=$keys_dir/authority.json + +create_stake_account $authority +echo "Waiting for stakes to activate, this may take awhile depending on the network!" +echo "If you are running on localnet with 32 slots per epoch, wait 12 seconds..." +sleep 12 + echo "Setting up authority for withdrawn stake accounts at $authority" create_keypair $authority echo "Withdrawing stakes from stake pool" withdraw_stakes "$stake_pool_pubkey" "$validator_list" "$withdraw_sol_amount" + +echo "Withdrawing stakes from stake pool to recieve it in stake receiver account" +withdraw_stakes_to_stake_receiver "$stake_pool_pubkey" "$validator_list" "$withdraw_sol_amount" + echo "Withdrawing SOL from stake pool to authority" $spl_stake_pool withdraw-sol "$stake_pool_pubkey" $authority "$withdraw_sol_amount" diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 299d0aac..07315aac 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -6,6 +6,7 @@ use { client::*, output::{CliStakePool, CliStakePoolDetails, CliStakePoolStakeAccountInfo, CliStakePools}, }, + bincode::deserialize, clap::{ crate_description, crate_name, crate_version, value_t, value_t_or_exit, App, AppSettings, Arg, ArgGroup, ArgMatches, SubCommand, @@ -1370,12 +1371,77 @@ fn command_withdraw_stake( .into()); } + // Check for the delegated stake receiver + let maybe_stake_receiver_state = stake_receiver_param + .map(|stake_receiver_pubkey| { + let stake_account = config.rpc_client.get_account(&stake_receiver_pubkey).ok()?; + let stake_state: stake::state::StakeState = deserialize(stake_account.data.as_slice()) + .map_err(|err| format!("Invalid stake account {}: {}", stake_receiver_pubkey, err)) + .ok()?; + if stake_state.delegation().is_some() && stake_account.owner == stake::program::id() { + Some(stake_state) + } else { + None + } + }) + .flatten(); + let withdraw_accounts = if use_reserve { vec![WithdrawAccount { stake_address: stake_pool.reserve_stake, vote_address: None, pool_amount, }] + } else if maybe_stake_receiver_state.is_some() { + let vote_account = maybe_stake_receiver_state + .unwrap() + .delegation() + .unwrap() + .voter_pubkey; + if let Some(vote_account_address) = vote_account_address { + if *vote_account_address != vote_account { + return Err(format!("Provided withdrawal vote account {} does not match delegation on stake receiver account {}, + remove this flag or provide a different stake account delegated to {}", vote_account_address, vote_account, vote_account_address).into()); + } + } + // Check if the vote account exists in the stake pool + let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?; + if validator_list + .validators + .into_iter() + .any(|x| x.vote_account_address == vote_account) + { + let (stake_account_address, _) = find_stake_program_address( + &spl_stake_pool::id(), + &vote_account, + stake_pool_address, + ); + let stake_account = config.rpc_client.get_account(&stake_account_address)?; + + let available_for_withdrawal = stake_pool + .calc_lamports_withdraw_amount( + stake_account + .lamports + .saturating_sub(MINIMUM_ACTIVE_STAKE) + .saturating_sub(stake_account_rent_exemption), + ) + .unwrap(); + + if available_for_withdrawal < pool_amount { + return Err(format!( + "Not enough lamports available for withdrawal from {}, {} asked, {} available", + stake_account_address, pool_amount, available_for_withdrawal + ) + .into()); + } + vec![WithdrawAccount { + stake_address: stake_account_address, + vote_address: Some(vote_account), + pool_amount, + }] + } else { + return Err(format!("Provided stake account is delegated to a vote account {} which does not exist in the stake pool", vote_account).into()); + } } else if let Some(vote_account_address) = vote_account_address { let (stake_account_address, _) = find_stake_program_address( &spl_stake_pool::id(), @@ -1439,7 +1505,6 @@ fn command_withdraw_stake( ); let mut total_rent_free_balances = 0; - // Go through prepared accounts and withdraw/claim them for withdraw_account in withdraw_accounts { // Convert pool tokens amount to lamports @@ -1463,19 +1528,21 @@ fn command_withdraw_stake( withdraw_account.stake_address, ); } - - // Use separate mutable variable because withdraw might create a new account - let stake_receiver = stake_receiver_param.unwrap_or_else(|| { - let stake_keypair = new_stake_account( - &config.fee_payer.pubkey(), - &mut instructions, - stake_account_rent_exemption, - ); - let stake_pubkey = stake_keypair.pubkey(); - total_rent_free_balances += stake_account_rent_exemption; - new_stake_keypairs.push(stake_keypair); - stake_pubkey - }); + let stake_receiver = + if (stake_receiver_param.is_none()) || (maybe_stake_receiver_state.is_some()) { + // Creating new account to split the stake into new account + let stake_keypair = new_stake_account( + &config.fee_payer.pubkey(), + &mut instructions, + stake_account_rent_exemption, + ); + let stake_pubkey = stake_keypair.pubkey(); + total_rent_free_balances += stake_account_rent_exemption; + new_stake_keypairs.push(stake_keypair); + stake_pubkey + } else { + stake_receiver_param.unwrap() + }; instructions.push(spl_stake_pool::instruction::withdraw_stake( &spl_stake_pool::id(), @@ -1494,6 +1561,17 @@ fn command_withdraw_stake( )); } + // Merging the stake with account provided by user + if maybe_stake_receiver_state.is_some() { + for new_stake_keypair in &new_stake_keypairs { + instructions.extend(stake::instruction::merge( + &stake_receiver_param.unwrap(), + &new_stake_keypair.pubkey(), + &config.fee_payer.pubkey(), + )); + } + } + let recent_blockhash = get_latest_blockhash(&config.rpc_client)?; let message = Message::new_with_blockhash( &instructions, diff --git a/clients/js-legacy/src/index.ts b/clients/js-legacy/src/index.ts index 7eac0b4d..6cd146b3 100644 --- a/clients/js-legacy/src/index.ts +++ b/clients/js-legacy/src/index.ts @@ -27,6 +27,7 @@ import { } from './utils'; import { StakePoolInstruction } from './instructions'; import { + StakeAccount, StakePool, StakePoolLayout, ValidatorList, @@ -34,6 +35,7 @@ import { ValidatorStakeInfo, } from './layouts'; import { MAX_VALIDATORS_TO_UPDATE, MINIMUM_ACTIVE_STAKE, STAKE_POOL_PROGRAM_ID } from './constants'; +import { create } from 'superstruct'; export type { StakePool, AccountType, ValidatorList, ValidatorStakeInfo } from './layouts'; export { STAKE_POOL_PROGRAM_ID } from './constants'; @@ -90,6 +92,28 @@ export async function getStakePoolAccount( }; } +/** + * Retrieves and deserializes a Stake account using a web3js connection and the stake address. + * @param connection: An active web3js connection. + * @param stakeAccount: The public key (address) of the stake account. + */ +export async function getStakeAccount( + connection: Connection, + stakeAccount: PublicKey, +): Promise { + const result = (await connection.getParsedAccountInfo(stakeAccount)).value; + if (!result || !('parsed' in result.data)) { + throw new Error('Invalid stake account'); + } + const program = result.data.program; + if (program != 'stake') { + throw new Error('Not a stake account'); + } + const parsed = create(result.data.parsed, StakeAccount); + + return parsed; +} + /** * Retrieves all StakePool and ValidatorList accounts that are running a particular StakePool program. * @param connection: An active web3js connection. @@ -331,6 +355,7 @@ export async function withdrawStake( poolTokenAccount, stakePool.account.data.poolMint, ); + if (!tokenAccount) { throw new Error('Invalid token account'); } @@ -352,6 +377,11 @@ export async function withdrawStake( stakePoolAddress, ); + let stakeReceiverAccount = null; + if (stakeReceiver) { + stakeReceiverAccount = await getStakeAccount(connection, stakeReceiver); + } + const withdrawAccounts: WithdrawAccount[] = []; if (useReserve) { @@ -360,6 +390,53 @@ export async function withdrawStake( voteAddress: undefined, poolAmount, }); + } else if (stakeReceiverAccount && stakeReceiverAccount?.type == 'delegated') { + const voteAccount = stakeReceiverAccount.info?.stake?.delegation.voter; + if (!voteAccount) throw new Error(`Invalid stake reciever ${stakeReceiver} delegation`); + const validatorListAccount = await connection.getAccountInfo( + stakePool.account.data.validatorList, + ); + const validatorList = ValidatorListLayout.decode(validatorListAccount?.data) as ValidatorList; + const isValidVoter = validatorList.validators.find((val) => + val.voteAccountAddress.equals(voteAccount), + ); + if (voteAccountAddress && voteAccountAddress !== voteAccount) { + throw new Error(`Provided withdrawal vote account ${voteAccountAddress} does not match delegation on stake receiver account ${voteAccount}, + remove this flag or provide a different stake account delegated to ${voteAccountAddress}`); + } + if (isValidVoter) { + const stakeAccountAddress = await findStakeProgramAddress( + STAKE_POOL_PROGRAM_ID, + voteAccount, + stakePoolAddress, + ); + + const stakeAccount = await connection.getAccountInfo(stakeAccountAddress); + if (!stakeAccount) { + throw new Error(`Preferred withdraw valdator's stake account is invalid`); + } + + const availableForWithdrawal = calcLamportsWithdrawAmount( + stakePool.account.data, + stakeAccount.lamports - MINIMUM_ACTIVE_STAKE - stakeAccountRentExemption, + ); + + if (availableForWithdrawal < poolAmount) { + throw new Error( + `Not enough lamports available for withdrawal from ${stakeAccountAddress}, + ${poolAmount} asked, ${availableForWithdrawal} available.`, + ); + } + withdrawAccounts.push({ + stakeAddress: stakeAccountAddress, + voteAddress: voteAccount, + poolAmount, + }); + } else { + throw new Error( + `Provided stake account is delegated to a vote account ${voteAccount} which does not exist in the stake pool`, + ); + } } else if (voteAccountAddress) { const stakeAccountAddress = await findStakeProgramAddress( STAKE_POOL_PROGRAM_ID, @@ -443,11 +520,9 @@ export async function withdrawStake( } console.info(infoMsg); - let stakeToReceive; - // Use separate mutable variable because withdraw might create a new account - if (!stakeReceiver) { + if (!stakeReceiver || (stakeReceiverAccount && stakeReceiverAccount.type === 'delegated')) { const stakeKeypair = newStakeAccount(tokenOwner, instructions, stakeAccountRentExemption); signers.push(stakeKeypair); totalRentFreeBalances += stakeAccountRentExemption; @@ -473,6 +548,17 @@ export async function withdrawStake( ); i++; } + if (stakeReceiver && stakeReceiverAccount && stakeReceiverAccount.type === 'delegated') { + signers.forEach((newStakeKeypair) => { + instructions.concat( + StakeProgram.merge({ + stakePubkey: stakeReceiver, + sourceStakePubKey: newStakeKeypair.publicKey, + authorizedPubkey: tokenOwner, + }).instructions, + ); + }); + } return { instructions, diff --git a/clients/js-legacy/src/layouts.ts b/clients/js-legacy/src/layouts.ts index ba5d9489..e7cd77b6 100644 --- a/clients/js-legacy/src/layouts.ts +++ b/clients/js-legacy/src/layouts.ts @@ -2,6 +2,17 @@ import { publicKey, struct, u32, u64, u8, option, vec } from '@project-serum/bor import { Lockup, PublicKey } from '@solana/web3.js'; import { AccountInfo } from '@solana/spl-token'; import BN from 'bn.js'; +import { + Infer, + number, + nullable, + enums, + type, + coerce, + instance, + string, + optional, +} from 'superstruct'; export interface Fee { denominator: BN; @@ -33,6 +44,57 @@ export enum AccountType { ValidatorList, } +export const BigNumFromString = coerce(instance(BN), string(), (value) => { + if (typeof value === 'string') return new BN(value, 10); + throw new Error('invalid big num'); +}); + +export const PublicKeyFromString = coerce( + instance(PublicKey), + string(), + (value) => new PublicKey(value), +); + +export type StakeAccountType = Infer; +export const StakeAccountType = enums(['uninitialized', 'initialized', 'delegated', 'rewardsPool']); + +export type StakeMeta = Infer; +export const StakeMeta = type({ + rentExemptReserve: BigNumFromString, + authorized: type({ + staker: PublicKeyFromString, + withdrawer: PublicKeyFromString, + }), + lockup: type({ + unixTimestamp: number(), + epoch: number(), + custodian: PublicKeyFromString, + }), +}); + +export type StakeAccountInfo = Infer; +export const StakeAccountInfo = type({ + meta: StakeMeta, + stake: nullable( + type({ + delegation: type({ + voter: PublicKeyFromString, + stake: BigNumFromString, + activationEpoch: BigNumFromString, + deactivationEpoch: BigNumFromString, + warmupCooldownRate: number(), + }), + creditsObserved: number(), + }), + ), +}); + +export type StakeAccount = Infer; +export const StakeAccount = type({ + type: StakeAccountType, + info: optional(StakeAccountInfo), +}); + export interface StakePool { accountType: AccountType; manager: PublicKey; diff --git a/clients/js-legacy/test/instructions.test.ts b/clients/js-legacy/test/instructions.test.ts index 8a9681b1..458eb0cb 100644 --- a/clients/js-legacy/test/instructions.test.ts +++ b/clients/js-legacy/test/instructions.test.ts @@ -15,11 +15,21 @@ import { depositSol, withdrawSol, withdrawStake, + getStakeAccount, } from '../src'; import { decodeData } from '../src/utils'; -import { mockTokenAccount, mockValidatorList, stakePoolMock } from './mocks'; +import { + mockRpc, + mockTokenAccount, + mockValidatorList, + mockValidatorsStakeAccount, + stakePoolMock, + CONSTANTS, + stakeAccountData, + uninitializedStakeAccount, +} from './mocks'; describe('StakePoolProgram', () => { const connection = new Connection('http://127.0.0.1:8899'); @@ -146,7 +156,7 @@ describe('StakePoolProgram', () => { if (pubKey == stakePoolAddress) { return stakePoolAccount; } - if (pubKey.toBase58() == '9q2rZU5RujvyD9dmYKhzJAZfG4aGBbvQ8rWY52jCNBai') { + if (pubKey.equals(CONSTANTS.poolTokenAccount)) { return null; } return null; @@ -162,7 +172,7 @@ describe('StakePoolProgram', () => { if (pubKey == stakePoolAddress) { return stakePoolAccount; } - if (pubKey.toBase58() == 'GQkqTamwqjaNDfsbNm7r3aXPJ4oTSqKC3d5t2PF9Smqd') { + if (pubKey.equals(CONSTANTS.poolTokenAccount)) { return mockTokenAccount(0); } return null; @@ -182,7 +192,7 @@ describe('StakePoolProgram', () => { if (pubKey == stakePoolAddress) { return stakePoolAccount; } - if (pubKey.toBase58() == 'GQkqTamwqjaNDfsbNm7r3aXPJ4oTSqKC3d5t2PF9Smqd') { + if (pubKey.equals(CONSTANTS.poolTokenAccount)) { return mockTokenAccount(LAMPORTS_PER_SOL); } return null; @@ -216,7 +226,7 @@ describe('StakePoolProgram', () => { if (pubKey == stakePoolAddress) { return stakePoolAccount; } - if (pubKey.toBase58() == 'GQkqTamwqjaNDfsbNm7r3aXPJ4oTSqKC3d5t2PF9Smqd') { + if (pubKey.equals(CONSTANTS.poolTokenAccount)) { return mockTokenAccount(0); } return null; @@ -235,15 +245,14 @@ describe('StakePoolProgram', () => { if (pubKey == stakePoolAddress) { return stakePoolAccount; } - if (pubKey.toBase58() == 'GQkqTamwqjaNDfsbNm7r3aXPJ4oTSqKC3d5t2PF9Smqd') { + if (pubKey.equals(CONSTANTS.poolTokenAccount)) { return mockTokenAccount(LAMPORTS_PER_SOL * 2); } - if (pubKey.toBase58() == stakePoolMock.validatorList.toBase58()) { + if (pubKey.equals(stakePoolMock.validatorList)) { return mockValidatorList(); } return null; }); - const res = await withdrawStake(connection, stakePoolAddress, tokenOwner, 1); expect((connection.getAccountInfo as jest.Mock).mock.calls.length).toBe(4); @@ -252,5 +261,60 @@ describe('StakePoolProgram', () => { expect(res.stakeReceiver).toEqual(undefined); expect(res.totalRentFreeBalances).toEqual(10000); }); + + it.only('withdraw to a stake account provided', async () => { + const stakeReceiver = new PublicKey(20); + connection.getAccountInfo = jest.fn(async (pubKey: PublicKey) => { + if (pubKey == stakePoolAddress) { + return stakePoolAccount; + } + if (pubKey.equals(CONSTANTS.poolTokenAccount)) { + return mockTokenAccount(LAMPORTS_PER_SOL * 2); + } + if (pubKey.equals(stakePoolMock.validatorList)) { + return mockValidatorList(); + } + if (pubKey.equals(CONSTANTS.validatorStakeAccountAddress)) + return mockValidatorsStakeAccount(); + return null; + }); + connection.getParsedAccountInfo = jest.fn(async (pubKey: PublicKey) => { + if (pubKey.equals(stakeReceiver)) { + return mockRpc(stakeAccountData); + } + return null; + }); + + const res = await withdrawStake( + connection, + stakePoolAddress, + tokenOwner, + 1, + undefined, + undefined, + stakeReceiver, + ); + + expect((connection.getAccountInfo as jest.Mock).mock.calls.length).toBe(4); + expect((connection.getParsedAccountInfo as jest.Mock).mock.calls.length).toBe(1); + expect(res.instructions).toHaveLength(3); + expect(res.signers).toHaveLength(2); + expect(res.stakeReceiver).toEqual(stakeReceiver); + expect(res.totalRentFreeBalances).toEqual(10000); + }); + }); + describe('getStakeAccount', () => { + it.only('returns an uninitialized parsed stake account', async () => { + const stakeAccount = new PublicKey(20); + connection.getParsedAccountInfo = jest.fn(async (pubKey: PublicKey) => { + if (pubKey.equals(stakeAccount)) { + return mockRpc(uninitializedStakeAccount); + } + return null; + }); + const parsedStakeAccount = await getStakeAccount(connection, stakeAccount); + expect((connection.getParsedAccountInfo as jest.Mock).mock.calls.length).toBe(1); + expect(parsedStakeAccount).toEqual(uninitializedStakeAccount.parsed); + }); }); }); diff --git a/clients/js-legacy/test/mocks.ts b/clients/js-legacy/test/mocks.ts index df2c0c04..db93fa5a 100644 --- a/clients/js-legacy/test/mocks.ts +++ b/clients/js-legacy/test/mocks.ts @@ -1,8 +1,17 @@ -import { AccountInfo, LAMPORTS_PER_SOL, PublicKey } from '@solana/web3.js'; +import { AccountInfo, LAMPORTS_PER_SOL, PublicKey, StakeProgram } from '@solana/web3.js'; import BN from 'bn.js'; import { ValidatorStakeInfo } from '../src'; import { ValidatorStakeInfoStatus, AccountLayout, ValidatorListLayout } from '../src/layouts'; +export const CONSTANTS = { + poolTokenAccount: new PublicKey( + new BN('e4f53a3a11521b9171c942ff91183ec8db4e6f347bb9aa7d4a814b7874bfd15c', 'hex'), + ), + validatorStakeAccountAddress: new PublicKey( + new BN('69184b7f1bc836271c4ac0e29e53eb38a38ea0e7bcde693c45b30d1592a5a678', 'hex'), + ), +}; + export const stakePoolMock = { accountType: 1, manager: new PublicKey(11), @@ -132,6 +141,73 @@ export function mockTokenAccount(amount = 0) { }; } +export const mockRpc = (data: any): any => { + const value = { + owner: StakeProgram.programId, + lamports: LAMPORTS_PER_SOL, + data: data, + executable: false, + rentEpoch: 0, + }; + const result = { + context: { + slot: 11, + }, + value: value, + }; + return result; +}; + +export const stakeAccountData = { + program: 'stake', + parsed: { + type: 'delegated', + info: { + meta: { + rentExemptReserve: new BN(1), + lockup: { + epoch: 32, + unixTimestamp: 2, + custodian: new PublicKey(12), + }, + authorized: { + staker: new PublicKey(12), + withdrawer: new PublicKey(12), + }, + }, + stake: { + delegation: { + voter: new PublicKey( + new BN('e4e37d6f2e80c0bb0f3da8a06304e57be5cda6efa2825b86780aa320d9784cf8', 'hex'), + ), + stake: new BN(0), + activationEpoch: new BN(1), + deactivationEpoch: new BN(1), + warmupCooldownRate: 1.2, + }, + creditsObserved: 1, + }, + }, + }, +}; + +export const uninitializedStakeAccount = { + program: 'stake', + parsed: { + type: 'uninitialized', + }, +}; + +export function mockValidatorsStakeAccount() { + const data = Buffer.alloc(1024); + return >{ + executable: false, + owner: StakeProgram.programId, + lamports: 3000000000, + data, + }; +} + export function mockValidatorList() { const data = Buffer.alloc(1024); ValidatorListLayout.encode(validatorListMock, data); From ee0fe46c34e80457fa376c42b45f00357eca9f23 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Sat, 27 Aug 2022 18:20:12 +0200 Subject: [PATCH 0259/1076] ci: Update rust-nightly to 2022-04-01 (#3539) * ci: Update rust-nightly to 2022-04-01 * Use rust_nightly parameter in fuzz script --- program/src/state.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/program/src/state.rs b/program/src/state.rs index 88901dc6..fc54676b 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -20,7 +20,7 @@ use { }, spl_math::checked_ceil_div::CheckedCeilDiv, spl_token::state::{Account, AccountState}, - std::{convert::TryFrom, fmt, matches}, + std::{borrow::Borrow, convert::TryFrom, fmt, matches}, }; /// Enum representing the account type managed by the program @@ -289,7 +289,7 @@ impl StakePool { &self, manager_fee_info: &AccountInfo, ) -> Result<(), ProgramError> { - let token_account = Account::unpack(&manager_fee_info.data.borrow())?; + let token_account = Account::unpack(&manager_fee_info.try_borrow_data()?)?; if manager_fee_info.owner != &self.token_program_id || token_account.state != AccountState::Initialized || token_account.mint != self.pool_mint @@ -684,7 +684,7 @@ impl ValidatorListHeader { /// Extracts the validator list into its header and internal BigVec pub fn deserialize_vec(data: &mut [u8]) -> Result<(Self, BigVec), ProgramError> { - let mut data_mut = &data[..]; + let mut data_mut = data.borrow(); let header = ValidatorListHeader::deserialize(&mut data_mut)?; let length = get_instance_packed_len(&header)?; From 780fe32cec5af4eb5878aa8db3c73cd68ef3543f Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 30 Aug 2022 21:45:18 +0200 Subject: [PATCH 0260/1076] stake-pool: Use stake program minimum delegation (#3547) * stake-pool: Support dynamic minimum delegation amount * Use minimum_delegation in CLI * Address feedback * Update minimum delegation in python test * Address feedback * Improve error message --- clients/cli/src/main.rs | 16 ++++-- clients/py/stake_pool/constants.py | 2 +- program/src/instruction.rs | 14 ++--- program/src/lib.rs | 18 +++++-- program/src/processor.rs | 45 ++++++++++------ program/src/state.rs | 4 +- program/tests/decrease.rs | 9 ++-- program/tests/deposit.rs | 16 +++++- program/tests/helpers/mod.rs | 52 +++++++++++++++++-- program/tests/huge_pool.rs | 7 +-- program/tests/increase.rs | 18 +++++-- .../tests/update_validator_list_balance.rs | 10 +++- program/tests/vsa_remove.rs | 12 +++-- program/tests/withdraw.rs | 42 ++++++++++++--- 14 files changed, 200 insertions(+), 65 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 07315aac..1ed08872 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -45,8 +45,9 @@ use { self, find_stake_program_address, find_transient_stake_program_address, find_withdraw_authority_program_address, instruction::{FundingType, PreferredValidatorType}, + minimum_delegation, state::{Fee, FeeType, StakePool, ValidatorList}, - MINIMUM_ACTIVE_STAKE, MINIMUM_RESERVE_LAMPORTS, + MINIMUM_RESERVE_LAMPORTS, }, std::cmp::Ordering, std::{process::exit, sync::Arc}, @@ -1219,9 +1220,11 @@ fn prepare_withdraw_accounts( stake_pool_address: &Pubkey, skip_fee: bool, ) -> Result, Error> { + let stake_minimum_delegation = rpc_client.get_stake_minimum_delegation()?; + let stake_pool_minimum_delegation = minimum_delegation(stake_minimum_delegation); let min_balance = rpc_client .get_minimum_balance_for_rent_exemption(STAKE_STATE_LEN)? - .saturating_add(MINIMUM_ACTIVE_STAKE); + .saturating_add(stake_pool_minimum_delegation); let pool_mint = get_token_mint(rpc_client, &stake_pool.pool_mint)?; let validator_list: ValidatorList = get_validator_list(rpc_client, &stake_pool.validator_list)?; @@ -1386,6 +1389,9 @@ fn command_withdraw_stake( }) .flatten(); + let stake_minimum_delegation = config.rpc_client.get_stake_minimum_delegation()?; + let stake_pool_minimum_delegation = minimum_delegation(stake_minimum_delegation); + let withdraw_accounts = if use_reserve { vec![WithdrawAccount { stake_address: stake_pool.reserve_stake, @@ -1400,7 +1406,7 @@ fn command_withdraw_stake( .voter_pubkey; if let Some(vote_account_address) = vote_account_address { if *vote_account_address != vote_account { - return Err(format!("Provided withdrawal vote account {} does not match delegation on stake receiver account {}, + return Err(format!("Provided withdrawal vote account {} does not match delegation on stake receiver account {}, remove this flag or provide a different stake account delegated to {}", vote_account_address, vote_account, vote_account_address).into()); } } @@ -1422,7 +1428,7 @@ fn command_withdraw_stake( .calc_lamports_withdraw_amount( stake_account .lamports - .saturating_sub(MINIMUM_ACTIVE_STAKE) + .saturating_sub(stake_pool_minimum_delegation) .saturating_sub(stake_account_rent_exemption), ) .unwrap(); @@ -1454,7 +1460,7 @@ fn command_withdraw_stake( .calc_lamports_withdraw_amount( stake_account .lamports - .saturating_sub(MINIMUM_ACTIVE_STAKE) + .saturating_sub(stake_pool_minimum_delegation) .saturating_sub(stake_account_rent_exemption), ) .unwrap(); diff --git a/clients/py/stake_pool/constants.py b/clients/py/stake_pool/constants.py index 3af4dce4..d58a99fe 100644 --- a/clients/py/stake_pool/constants.py +++ b/clients/py/stake_pool/constants.py @@ -11,7 +11,7 @@ MAX_VALIDATORS_TO_UPDATE: int = 5 """Maximum number of validators to update during UpdateValidatorListBalance.""" -MINIMUM_RESERVE_LAMPORTS: int = MINIMUM_DELEGATION +MINIMUM_RESERVE_LAMPORTS: int = 1 """Minimum balance required in the stake pool reserve""" MINIMUM_ACTIVE_STAKE: int = MINIMUM_DELEGATION diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 04353fbb..4a11e759 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -83,7 +83,7 @@ pub enum StakePoolInstruction { /// list of managed validators. /// /// The stake account will have the rent-exempt amount plus - /// `crate::MINIMUM_ACTIVE_STAKE` (currently 0.001 SOL). + /// `max(crate::MINIMUM_ACTIVE_STAKE, solana_program::stake::tools::get_minimum_delegation())`. /// /// 0. `[w]` Stake pool /// 1. `[s]` Staker @@ -103,8 +103,8 @@ pub enum StakePoolInstruction { /// (Staker only) Removes validator from the pool /// /// Only succeeds if the validator stake account has the minimum of - /// `crate::MINIMUM_ACTIVE_STAKE` (currently 0.001 SOL) plus the rent-exempt - /// amount. + /// `max(crate::MINIMUM_ACTIVE_STAKE, solana_program::stake::tools::get_minimum_delegation())`. + /// plus the rent-exempt amount. /// /// 0. `[w]` Stake pool /// 1. `[s]` Staker @@ -158,9 +158,8 @@ pub enum StakePoolInstruction { /// will do the work of merging once it's ready. /// /// This instruction only succeeds if the transient stake account does not exist. - /// The minimum amount to move is rent-exemption plus `crate::MINIMUM_ACTIVE_STAKE` - /// (currently 0.001 SOL) in order to avoid issues on credits observed when - /// merging active stakes later. + /// The minimum amount to move is rent-exemption plus + /// `max(crate::MINIMUM_ACTIVE_STAKE, solana_program::stake::tools::get_minimum_delegation())`. /// /// 0. `[]` Stake pool /// 1. `[s]` Stake pool staker @@ -281,7 +280,8 @@ pub enum StakePoolInstruction { /// /// Succeeds if the stake account has enough SOL to cover the desired amount /// of pool tokens, and if the withdrawal keeps the total staked amount - /// above the minimum of rent-exempt amount + 0.001 SOL. + /// above the minimum of rent-exempt amount + + /// `max(crate::MINIMUM_ACTIVE_STAKE, solana_program::stake::tools::get_minimum_delegation())`. /// /// When allowing withdrawals, the order of priority goes: /// diff --git a/program/src/lib.rs b/program/src/lib.rs index aa6931dd..321654ab 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -15,7 +15,7 @@ pub mod entrypoint; pub use solana_program; use { crate::state::Fee, - solana_program::{native_token::LAMPORTS_PER_SOL, pubkey::Pubkey, stake::state::Meta}, + solana_program::{pubkey::Pubkey, stake::state::Meta}, }; /// Seed for deposit authority seed @@ -29,10 +29,12 @@ const TRANSIENT_STAKE_SEED_PREFIX: &[u8] = b"transient"; /// Minimum amount of staked SOL required in a validator stake account to allow /// for merges without a mismatch on credits observed -pub const MINIMUM_ACTIVE_STAKE: u64 = LAMPORTS_PER_SOL; +pub const MINIMUM_ACTIVE_STAKE: u64 = 1_000_000; /// Minimum amount of SOL in the reserve -pub const MINIMUM_RESERVE_LAMPORTS: u64 = LAMPORTS_PER_SOL; +/// NOTE: This can be changed to 0 once the `stake_allow_zero_undelegated_amount` +/// feature is enabled on all clusters +pub const MINIMUM_RESERVE_LAMPORTS: u64 = 1; /// Maximum amount of validator stake accounts to update per /// `UpdateValidatorListBalance` instruction, based on compute limits @@ -58,9 +60,15 @@ pub const MAX_TRANSIENT_STAKE_ACCOUNTS: usize = 10; /// Get the stake amount under consideration when calculating pool token /// conversions #[inline] -pub fn minimum_stake_lamports(meta: &Meta) -> u64 { +pub fn minimum_stake_lamports(meta: &Meta, stake_program_minimum_delegation: u64) -> u64 { meta.rent_exempt_reserve - .saturating_add(MINIMUM_ACTIVE_STAKE) + .saturating_add(minimum_delegation(stake_program_minimum_delegation)) +} + +/// Get the minimum delegation required by a stake account in a stake pool +#[inline] +pub fn minimum_delegation(stake_program_minimum_delegation: u64) -> u64 { + std::cmp::max(stake_program_minimum_delegation, MINIMUM_ACTIVE_STAKE) } /// Get the stake amount under consideration when calculating pool token diff --git a/program/src/processor.rs b/program/src/processor.rs index d26c4efb..77fdb2b4 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -5,12 +5,12 @@ use { error::StakePoolError, find_deposit_authority_program_address, instruction::{FundingType, PreferredValidatorType, StakePoolInstruction}, - minimum_reserve_lamports, minimum_stake_lamports, + minimum_delegation, minimum_reserve_lamports, minimum_stake_lamports, state::{ AccountType, Fee, FeeType, StakePool, StakeStatus, ValidatorList, ValidatorListHeader, ValidatorStakeInfo, }, - AUTHORITY_DEPOSIT, AUTHORITY_WITHDRAW, MINIMUM_ACTIVE_STAKE, TRANSIENT_STAKE_SEED_PREFIX, + AUTHORITY_DEPOSIT, AUTHORITY_WITHDRAW, TRANSIENT_STAKE_SEED_PREFIX, }, borsh::{BorshDeserialize, BorshSerialize}, mpl_token_metadata::{ @@ -907,7 +907,9 @@ impl Processor { // Fund the stake account with the minimum + rent-exempt balance let space = std::mem::size_of::(); - let required_lamports = MINIMUM_ACTIVE_STAKE + rent.minimum_balance(space); + let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; + let required_lamports = minimum_delegation(stake_minimum_delegation) + .saturating_add(rent.minimum_balance(space)); // Create new stake account create_pda_account( @@ -1031,7 +1033,8 @@ impl Processor { let mut validator_stake_info = maybe_validator_stake_info.unwrap(); let stake_lamports = **stake_account_info.lamports.borrow(); - let required_lamports = minimum_stake_lamports(&meta); + let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; + let required_lamports = minimum_stake_lamports(&meta, stake_minimum_delegation); if stake_lamports != required_lamports { msg!( "Attempting to remove validator account with {} lamports, must have {} lamports", @@ -1041,11 +1044,12 @@ impl Processor { return Err(StakePoolError::StakeLamportsNotEqualToMinimum.into()); } - if stake.delegation.stake != MINIMUM_ACTIVE_STAKE { + let current_minimum_delegation = minimum_delegation(stake_minimum_delegation); + if stake.delegation.stake != current_minimum_delegation { msg!( "Error: attempting to remove stake with delegation of {} lamports, must have {} lamports", stake.delegation.stake, - MINIMUM_ACTIVE_STAKE + current_minimum_delegation ); return Err(StakePoolError::StakeLamportsNotEqualToMinimum.into()); } @@ -1224,7 +1228,8 @@ impl Processor { .lamports() .checked_sub(lamports) .ok_or(ProgramError::InsufficientFunds)?; - let required_lamports = minimum_stake_lamports(&meta); + let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; + let required_lamports = minimum_stake_lamports(&meta, stake_minimum_delegation); if remaining_lamports < required_lamports { msg!("Need at least {} lamports in the stake account after decrease, {} requested, {} is the current possible maximum", required_lamports, @@ -1394,13 +1399,17 @@ impl Processor { } let stake_rent = rent.minimum_balance(std::mem::size_of::()); - if lamports < MINIMUM_ACTIVE_STAKE { + let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; + let current_minimum_delegation = minimum_delegation(stake_minimum_delegation); + if lamports < current_minimum_delegation { msg!( - "Need more than {} lamports for transient stake to be rent-exempt and mergeable, {} provided", - MINIMUM_ACTIVE_STAKE, + "Need more than {} lamports for transient stake to meet minimum delegation requirement, {} provided", + current_minimum_delegation, lamports ); - return Err(ProgramError::AccountNotRentExempt); + return Err(ProgramError::Custom( + stake::instruction::StakeError::InsufficientDelegation as u32, + )); } // the stake account rent exemption is withdrawn after the merge, so @@ -1577,6 +1586,8 @@ impl Processor { return Err(StakePoolError::InvalidState.into()); } + let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; + let current_minimum_delegation = minimum_delegation(stake_minimum_delegation); let validator_iter = &mut validator_slice .iter_mut() .zip(validator_stake_accounts.chunks_exact(2)); @@ -1750,7 +1761,7 @@ impl Processor { active_stake_lamports = stake .delegation .stake - .checked_sub(MINIMUM_ACTIVE_STAKE) + .checked_sub(current_minimum_delegation) .ok_or(StakePoolError::CalculationFailure)?; } else { msg!("Validator stake account no longer part of the pool, ignoring"); @@ -2195,10 +2206,12 @@ impl Processor { .ok_or(StakePoolError::CalculationFailure)?; stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; + let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; + let current_minimum_delegation = minimum_delegation(stake_minimum_delegation); validator_stake_info.active_stake_lamports = post_validator_stake .delegation .stake - .checked_sub(MINIMUM_ACTIVE_STAKE) + .checked_sub(current_minimum_delegation) .ok_or(StakePoolError::CalculationFailure)?; Ok(()) @@ -2508,8 +2521,10 @@ impl Processor { } let remaining_lamports = stake.delegation.stake.saturating_sub(withdraw_lamports); - if remaining_lamports < MINIMUM_ACTIVE_STAKE { - msg!("Attempting to withdraw {} lamports from validator account with {} stake lamports, {} must remain", withdraw_lamports, stake.delegation.stake, MINIMUM_ACTIVE_STAKE); + let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; + let current_minimum_delegation = minimum_delegation(stake_minimum_delegation); + if remaining_lamports < current_minimum_delegation { + msg!("Attempting to withdraw {} lamports from validator account with {} stake lamports, {} must remain", withdraw_lamports, stake.delegation.stake, current_minimum_delegation); return Err(StakePoolError::StakeLamportsNotEqualToMinimum.into()); } Some((validator_stake_info, withdrawing_from_transient_stake)) diff --git a/program/src/state.rs b/program/src/state.rs index fc54676b..fcb0ab57 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -534,8 +534,8 @@ impl Default for StakeStatus { #[derive(Clone, Copy, Debug, Default, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)] pub struct ValidatorStakeInfo { /// Amount of active stake delegated to this validator, minus the minimum - /// required stake amount of rent-exemption + `crate::MINIMUM_ACTIVE_STAKE` - /// (currently 1 SOL). + /// required stake amount of rent-exemption + + /// `max(crate::MINIMUM_ACTIVE_STAKE, solana_program::stake::tools::get_minimum_delegation())`. /// /// Note that if `last_update_epoch` does not match the current epoch then /// this field may not be accurate diff --git a/program/tests/decrease.rs b/program/tests/decrease.rs index a050b407..11be6e7c 100644 --- a/program/tests/decrease.rs +++ b/program/tests/decrease.rs @@ -15,7 +15,7 @@ use { }, spl_stake_pool::{ error::StakePoolError, find_transient_stake_program_address, id, instruction, - MINIMUM_ACTIVE_STAKE, MINIMUM_RESERVE_LAMPORTS, + MINIMUM_RESERVE_LAMPORTS, }, }; @@ -50,18 +50,21 @@ async fn setup() -> ( ) .await; + let current_minimum_delegation = + stake_pool_get_minimum_delegation(&mut banks_client, &payer, &recent_blockhash).await; + let deposit_info = simple_deposit_stake( &mut banks_client, &payer, &recent_blockhash, &stake_pool_accounts, &validator_stake_account, - MINIMUM_ACTIVE_STAKE * 2 + stake_rent, + current_minimum_delegation * 2 + stake_rent, ) .await .unwrap(); - let decrease_lamports = MINIMUM_ACTIVE_STAKE + stake_rent; + let decrease_lamports = current_minimum_delegation + stake_rent; ( banks_client, diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 4a586550..7f3ad276 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -248,8 +248,14 @@ async fn success() { let stake_state = deserialize::(&validator_stake_account.data).unwrap(); let meta = stake_state.meta().unwrap(); + let stake_minimum_delegation = stake_get_minimum_delegation( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; assert_eq!( - validator_stake_account.lamports - minimum_stake_lamports(&meta), + validator_stake_account.lamports - minimum_stake_lamports(&meta, stake_minimum_delegation), post_validator_stake_item.stake_lamports() ); assert_eq!(post_validator_stake_item.transient_stake_lamports, 0); @@ -443,8 +449,14 @@ async fn success_with_extra_stake_lamports() { let stake_state = deserialize::(&validator_stake_account.data).unwrap(); let meta = stake_state.meta().unwrap(); + let stake_minimum_delegation = stake_get_minimum_delegation( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; assert_eq!( - validator_stake_account.lamports - minimum_stake_lamports(&meta), + validator_stake_account.lamports - minimum_stake_lamports(&meta, stake_minimum_delegation), post_validator_stake_item.stake_lamports() ); assert_eq!(post_validator_stake_item.transient_stake_lamports, 0); diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 34648313..4b9f9579 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -15,6 +15,7 @@ use { solana_sdk::{ account::{Account, WritableAccount}, clock::{Clock, Epoch}, + native_token::LAMPORTS_PER_SOL, signature::{Keypair, Signer}, transaction::Transaction, transport::TransportError, @@ -26,11 +27,12 @@ use { spl_stake_pool::{ find_deposit_authority_program_address, find_stake_program_address, find_transient_stake_program_address, find_withdraw_authority_program_address, id, - instruction, + instruction, minimum_delegation, processor::Processor, state::{self, FeeType, ValidatorList}, - MINIMUM_ACTIVE_STAKE, MINIMUM_RESERVE_LAMPORTS, + MINIMUM_RESERVE_LAMPORTS, }, + std::convert::TryInto, }; pub const TEST_STAKE_AMOUNT: u64 = 1_500_000_000; @@ -546,6 +548,39 @@ pub async fn delegate_stake_account( banks_client.process_transaction(transaction).await.unwrap(); } +pub async fn stake_get_minimum_delegation( + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, +) -> u64 { + let transaction = Transaction::new_signed_with_payer( + &[stake::instruction::get_minimum_delegation()], + Some(&payer.pubkey()), + &[payer], + *recent_blockhash, + ); + let mut data = banks_client + .simulate_transaction(transaction) + .await + .unwrap() + .simulation_details + .unwrap() + .return_data + .unwrap() + .data; + data.resize(8, 0); + data.try_into().map(u64::from_le_bytes).unwrap() +} + +pub async fn stake_pool_get_minimum_delegation( + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, +) -> u64 { + let stake_minimum = stake_get_minimum_delegation(banks_client, payer, recent_blockhash).await; + minimum_delegation(stake_minimum) +} + pub async fn authorize_stake_account( banks_client: &mut BanksClient, payer: &Keypair, @@ -586,6 +621,9 @@ pub async fn create_unknown_validator_stake( .await; let user = Keypair::new(); let fake_validator_stake = Keypair::new(); + let stake_minimum_delegation = + stake_get_minimum_delegation(banks_client, payer, recent_blockhash).await; + let current_minimum_delegation = minimum_delegation(stake_minimum_delegation); create_independent_stake_account( banks_client, payer, @@ -596,7 +634,7 @@ pub async fn create_unknown_validator_stake( withdrawer: user.pubkey(), }, &stake::state::Lockup::default(), - MINIMUM_ACTIVE_STAKE, + current_minimum_delegation, ) .await; delegate_stake_account( @@ -1711,8 +1749,12 @@ pub fn add_validator_stake_account( let (stake_address, _) = find_stake_program_address(&id(), voter_pubkey, stake_pool_pubkey); program_test.add_account(stake_address, stake_account); - let active_stake_lamports = stake_amount - MINIMUM_ACTIVE_STAKE; - // add to validator list + + // Hack the active stake lamports to the current amount given by the runtime. + // Since program_test hasn't been started, there's no usable banks_client for + // fetching the minimum stake delegation. + let active_stake_lamports = stake_amount - LAMPORTS_PER_SOL; + validator_list.validators.push(state::ValidatorStakeInfo { status: state::StakeStatus::Active, vote_account_address: *voter_pubkey, diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index b74186b2..194a971d 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -7,6 +7,7 @@ use { solana_program::{borsh::try_from_slice_unchecked, pubkey::Pubkey, stake}, solana_program_test::*, solana_sdk::{ + native_token::LAMPORTS_PER_SOL, signature::{Keypair, Signer}, transaction::Transaction, }, @@ -14,7 +15,7 @@ use { find_stake_program_address, find_transient_stake_program_address, id, instruction::{self, PreferredValidatorType}, state::{StakePool, StakeStatus, ValidatorList}, - MAX_VALIDATORS_TO_UPDATE, MINIMUM_ACTIVE_STAKE, + MAX_VALIDATORS_TO_UPDATE, }, }; @@ -221,7 +222,7 @@ async fn update() { #[tokio::test] async fn remove_validator_from_pool() { let (mut context, stake_pool_accounts, vote_account_pubkeys, _, _, _, _) = - setup(HUGE_POOL_SIZE, HUGE_POOL_SIZE, MINIMUM_ACTIVE_STAKE).await; + setup(HUGE_POOL_SIZE, HUGE_POOL_SIZE, LAMPORTS_PER_SOL).await; let first_vote = vote_account_pubkeys[0]; let (stake_address, _) = @@ -427,7 +428,7 @@ async fn add_validator_to_pool() { &stake_pool_pubkey, transient_stake_seed, ); - let increase_amount = MINIMUM_ACTIVE_STAKE; + let increase_amount = LAMPORTS_PER_SOL; let error = stake_pool_accounts .increase_validator_stake( &mut context.banks_client, diff --git a/program/tests/increase.rs b/program/tests/increase.rs index 5f73615b..ac9c9191 100644 --- a/program/tests/increase.rs +++ b/program/tests/increase.rs @@ -11,11 +11,12 @@ use { solana_program_test::*, solana_sdk::{ signature::{Keypair, Signer}, + stake::instruction::StakeError, transaction::{Transaction, TransactionError}, }, spl_stake_pool::{ error::StakePoolError, find_transient_stake_program_address, id, instruction, - MINIMUM_ACTIVE_STAKE, MINIMUM_RESERVE_LAMPORTS, + MINIMUM_RESERVE_LAMPORTS, }, }; @@ -48,13 +49,16 @@ async fn setup() -> ( ) .await; + let current_minimum_delegation = + stake_pool_get_minimum_delegation(&mut banks_client, &payer, &recent_blockhash).await; + let _deposit_info = simple_deposit_stake( &mut banks_client, &payer, &recent_blockhash, &stake_pool_accounts, &validator_stake_account, - MINIMUM_ACTIVE_STAKE, + current_minimum_delegation, ) .await .unwrap(); @@ -354,6 +358,9 @@ async fn fail_with_small_lamport_amount() { _reserve_lamports, ) = setup().await; + let current_minimum_delegation = + stake_pool_get_minimum_delegation(&mut banks_client, &payer, &recent_blockhash).await; + let error = stake_pool_accounts .increase_validator_stake( &mut banks_client, @@ -362,7 +369,7 @@ async fn fail_with_small_lamport_amount() { &validator_stake.transient_stake_account, &validator_stake.stake_account, &validator_stake.vote.pubkey(), - MINIMUM_ACTIVE_STAKE - 1, + current_minimum_delegation - 1, validator_stake.transient_stake_seed, ) .await @@ -370,7 +377,10 @@ async fn fail_with_small_lamport_amount() { .unwrap(); match error { - TransactionError::InstructionError(_, InstructionError::AccountNotRentExempt) => {} + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = StakeError::InsufficientDelegation as u32; + assert_eq!(error_index, program_error); + } _ => panic!("Wrong error"), } } diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index 75277c0e..7ceb6483 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -16,7 +16,7 @@ use { find_transient_stake_program_address, find_withdraw_authority_program_address, id, instruction, state::{StakePool, StakeStatus, ValidatorList}, - MAX_VALIDATORS_TO_UPDATE, MINIMUM_ACTIVE_STAKE, MINIMUM_RESERVE_LAMPORTS, + MAX_VALIDATORS_TO_UPDATE, MINIMUM_RESERVE_LAMPORTS, }, spl_token::state::Mint, }; @@ -440,7 +440,13 @@ async fn merge_into_validator_stake() { // Check validator stake accounts have the expected balance now: // validator stake account minimum + deposited lamports + rents + increased lamports let stake_rent = rent.minimum_balance(std::mem::size_of::()); - let expected_lamports = MINIMUM_ACTIVE_STAKE + let current_minimum_delegation = stake_pool_get_minimum_delegation( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; + let expected_lamports = current_minimum_delegation + lamports + reserve_lamports / stake_accounts.len() as u64 + stake_rent; diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 209d5193..f80c5333 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -20,7 +20,7 @@ use { }, spl_stake_pool::{ error::StakePoolError, find_transient_stake_program_address, id, instruction, state, - MINIMUM_ACTIVE_STAKE, MINIMUM_RESERVE_LAMPORTS, + MINIMUM_RESERVE_LAMPORTS, }, }; @@ -692,7 +692,13 @@ async fn success_with_hijacked_transient_account() { setup().await; let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); - let increase_amount = MINIMUM_ACTIVE_STAKE + stake_rent; + let current_minimum_delegation = stake_pool_get_minimum_delegation( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; + let increase_amount = current_minimum_delegation + stake_rent; // increase stake on validator let error = stake_pool_accounts @@ -770,7 +776,7 @@ async fn success_with_hijacked_transient_account() { system_instruction::transfer( &context.payer.pubkey(), &transient_stake_address, - MINIMUM_RESERVE_LAMPORTS + stake_rent, + current_minimum_delegation + stake_rent, ), stake::instruction::initialize( &transient_stake_address, diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 96a899e5..31cf72d5 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -21,7 +21,7 @@ use { }, spl_stake_pool::{ error::StakePoolError, id, instruction, minimum_stake_lamports, state, - MINIMUM_ACTIVE_STAKE, MINIMUM_RESERVE_LAMPORTS, + MINIMUM_RESERVE_LAMPORTS, }, spl_token::error::TokenError, }; @@ -57,13 +57,16 @@ async fn setup() -> ( ) .await; + let current_minimum_delegation = + stake_pool_get_minimum_delegation(&mut banks_client, &payer, &recent_blockhash).await; + let deposit_info = simple_deposit_stake( &mut banks_client, &payer, &recent_blockhash, &stake_pool_accounts, &validator_stake_account, - MINIMUM_ACTIVE_STAKE * 3, + current_minimum_delegation * 3, ) .await .unwrap(); @@ -306,8 +309,10 @@ async fn _success(test_type: SuccessTestType) { let stake_state = deserialize::(&validator_stake_account.data).unwrap(); let meta = stake_state.meta().unwrap(); + let stake_minimum_delegation = + stake_get_minimum_delegation(&mut banks_client, &payer, &recent_blockhash).await; assert_eq!( - validator_stake_account.lamports - minimum_stake_lamports(&meta), + validator_stake_account.lamports - minimum_stake_lamports(&meta, stake_minimum_delegation), validator_stake_item.active_stake_lamports ); @@ -876,7 +881,13 @@ async fn success_with_reserve() { let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); - let deposit_lamports = (MINIMUM_ACTIVE_STAKE + stake_rent) * 2; + let current_minimum_delegation = stake_pool_get_minimum_delegation( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; + let deposit_lamports = (current_minimum_delegation + stake_rent) * 2; let deposit_info = simple_deposit_stake( &mut context.banks_client, @@ -1252,7 +1263,13 @@ async fn fail_withdraw_from_transient() { let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); - let deposit_lamports = (MINIMUM_ACTIVE_STAKE + stake_rent) * 2; + let current_minimum_delegation = stake_pool_get_minimum_delegation( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; + let deposit_lamports = (current_minimum_delegation + stake_rent) * 2; let deposit_info = simple_deposit_stake( &mut context.banks_client, @@ -1373,7 +1390,13 @@ async fn success_withdraw_from_transient() { let stake_rent = rent.minimum_balance(std::mem::size_of::()); // compensate for the fee and the minimum balance in the transient stake account - let deposit_lamports = (MINIMUM_ACTIVE_STAKE + stake_rent) * 3; + let current_minimum_delegation = stake_pool_get_minimum_delegation( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; + let deposit_lamports = (current_minimum_delegation + stake_rent) * 3; let deposit_info = simple_deposit_stake( &mut context.banks_client, @@ -1581,7 +1604,10 @@ async fn success_empty_out_stake_with_fee() { let stake_state = deserialize::(&validator_stake_account.data).unwrap(); let meta = stake_state.meta().unwrap(); - let lamports_to_withdraw = validator_stake_account.lamports - minimum_stake_lamports(&meta); + let stake_minimum_delegation = + stake_get_minimum_delegation(&mut banks_client, &payer, &recent_blockhash).await; + let lamports_to_withdraw = + validator_stake_account.lamports - minimum_stake_lamports(&meta, stake_minimum_delegation); let stake_pool_account = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; let stake_pool = @@ -1621,6 +1647,6 @@ async fn success_empty_out_stake_with_fee() { let meta = stake_state.meta().unwrap(); assert_eq!( validator_stake_account.lamports, - minimum_stake_lamports(&meta) + minimum_stake_lamports(&meta, stake_minimum_delegation) ); } From 5ecedf768b3f60317a8f33dd723284b63517b5db Mon Sep 17 00:00:00 2001 From: Edgar Date: Tue, 13 Sep 2022 14:31:27 -0400 Subject: [PATCH 0261/1076] add stake pool support support for hardware wallets in set-manager (#3583) * add support for hardware wallets in set-manager * clippy * wrap new_manager in &Option type * trigger CI --- clients/cli/src/main.rs | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 1ed08872..00d9f2bd 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -1718,7 +1718,7 @@ fn command_withdraw_sol( fn command_set_manager( config: &Config, stake_pool_address: &Pubkey, - new_manager: &Option, + new_manager: &Option>, new_fee_receiver: &Option, ) -> CommandResult { if !config.no_update { @@ -1729,8 +1729,9 @@ fn command_set_manager( // If new accounts are missing in the arguments use the old ones let (new_manager_pubkey, mut signers): (Pubkey, Vec<&dyn Signer>) = match new_manager { None => (stake_pool.manager, vec![]), - Some(value) => (value.pubkey(), vec![value]), + Some(value) => (value.pubkey(), vec![value.as_ref()]), }; + let new_fee_receiver = match new_fee_receiver { None => stake_pool.manager_fee_account, Some(value) => { @@ -2937,7 +2938,24 @@ fn main() { } ("set-manager", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); - let new_manager: Option = keypair_of(arg_matches, "new_manager"); + + let new_manager = if arg_matches.value_of("new_manager").is_some() { + let signer = get_signer( + arg_matches, + "new-manager", + arg_matches + .value_of("new_manager") + .expect("new manager argument not found!"), + &mut wallet_manager, + SignerFromPathConfig { + allow_null_signer: true, + }, + ); + Some(signer) + } else { + None + }; + let new_fee_receiver: Option = pubkey_of(arg_matches, "new_fee_receiver"); command_set_manager( &config, From 33d19c3d4dde3893c8612a16cc6674600a6afd17 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 15 Sep 2022 13:16:53 +0200 Subject: [PATCH 0262/1076] clippy: Deny integer arithmetic, add allows where needed (#3606) --- clients/cli/src/main.rs | 1 + program/src/lib.rs | 1 + program/tests/create_pool_token_metadata.rs | 13 +++++++------ program/tests/decrease.rs | 1 + program/tests/deposit.rs | 1 + program/tests/deposit_authority.rs | 1 + program/tests/deposit_sol.rs | 1 + program/tests/force_destake.rs | 1 + program/tests/huge_pool.rs | 1 + program/tests/increase.rs | 1 + program/tests/initialize.rs | 1 + program/tests/set_deposit_fee.rs | 1 + program/tests/set_epoch_fee.rs | 1 + program/tests/set_funding_authority.rs | 1 + program/tests/set_manager.rs | 1 + program/tests/set_preferred.rs | 1 + program/tests/set_referral_fee.rs | 1 + program/tests/set_staker.rs | 1 + program/tests/set_withdrawal_fee.rs | 1 + program/tests/update_pool_token_metadata.rs | 13 +++++++------ program/tests/update_stake_pool_balance.rs | 1 + program/tests/update_validator_list_balance.rs | 1 + program/tests/vsa_add.rs | 1 + program/tests/vsa_remove.rs | 1 + program/tests/withdraw.rs | 1 + program/tests/withdraw_sol.rs | 1 + 26 files changed, 38 insertions(+), 12 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 00d9f2bd..a960e23b 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -1,3 +1,4 @@ +#![allow(clippy::integer_arithmetic)] mod client; mod output; diff --git a/program/src/lib.rs b/program/src/lib.rs index 321654ab..0cca0342 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -1,3 +1,4 @@ +#![allow(clippy::integer_arithmetic)] #![deny(missing_docs)] //! A program for creating and managing pools of stake diff --git a/program/tests/create_pool_token_metadata.rs b/program/tests/create_pool_token_metadata.rs index 7d648969..e24a4978 100644 --- a/program/tests/create_pool_token_metadata.rs +++ b/program/tests/create_pool_token_metadata.rs @@ -1,3 +1,4 @@ +#![allow(clippy::integer_arithmetic)] #![cfg(feature = "test-sbf")] mod helpers; @@ -45,9 +46,9 @@ async fn success_create_pool_token_metadata() { let symbol = "SYM"; let uri = "test_uri"; - let puffed_name = puffed_out_string(&name, MAX_NAME_LENGTH); - let puffed_symbol = puffed_out_string(&symbol, MAX_SYMBOL_LENGTH); - let puffed_uri = puffed_out_string(&uri, MAX_URI_LENGTH); + let puffed_name = puffed_out_string(name, MAX_NAME_LENGTH); + let puffed_symbol = puffed_out_string(symbol, MAX_SYMBOL_LENGTH); + let puffed_uri = puffed_out_string(uri, MAX_URI_LENGTH); let ix = instruction::create_token_metadata( &spl_stake_pool::id(), @@ -79,9 +80,9 @@ async fn success_create_pool_token_metadata() { ) .await; - assert_eq!(metadata.data.name.to_string(), puffed_name); - assert_eq!(metadata.data.symbol.to_string(), puffed_symbol); - assert_eq!(metadata.data.uri.to_string(), puffed_uri); + assert_eq!(metadata.data.name, puffed_name); + assert_eq!(metadata.data.symbol, puffed_symbol); + assert_eq!(metadata.data.uri, puffed_uri); } #[tokio::test] diff --git a/program/tests/decrease.rs b/program/tests/decrease.rs index 11be6e7c..008089e1 100644 --- a/program/tests/decrease.rs +++ b/program/tests/decrease.rs @@ -1,3 +1,4 @@ +#![allow(clippy::integer_arithmetic)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 7f3ad276..f3ebe513 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -1,3 +1,4 @@ +#![allow(clippy::integer_arithmetic)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/deposit_authority.rs b/program/tests/deposit_authority.rs index b78bdc42..ba8de843 100644 --- a/program/tests/deposit_authority.rs +++ b/program/tests/deposit_authority.rs @@ -1,3 +1,4 @@ +#![allow(clippy::integer_arithmetic)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/deposit_sol.rs b/program/tests/deposit_sol.rs index c38aebed..0e88e4f3 100644 --- a/program/tests/deposit_sol.rs +++ b/program/tests/deposit_sol.rs @@ -1,3 +1,4 @@ +#![allow(clippy::integer_arithmetic)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/force_destake.rs b/program/tests/force_destake.rs index a6820529..a9520806 100644 --- a/program/tests/force_destake.rs +++ b/program/tests/force_destake.rs @@ -1,3 +1,4 @@ +#![allow(clippy::integer_arithmetic)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index 194a971d..603d5d36 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -1,3 +1,4 @@ +#![allow(clippy::integer_arithmetic)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/increase.rs b/program/tests/increase.rs index ac9c9191..70d7cbf7 100644 --- a/program/tests/increase.rs +++ b/program/tests/increase.rs @@ -1,3 +1,4 @@ +#![allow(clippy::integer_arithmetic)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index fb4cfd0c..00d04ff6 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -1,3 +1,4 @@ +#![allow(clippy::integer_arithmetic)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/set_deposit_fee.rs b/program/tests/set_deposit_fee.rs index 7f7c268b..19025d37 100644 --- a/program/tests/set_deposit_fee.rs +++ b/program/tests/set_deposit_fee.rs @@ -1,3 +1,4 @@ +#![allow(clippy::integer_arithmetic)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/set_epoch_fee.rs b/program/tests/set_epoch_fee.rs index 2df679cb..0f33acbd 100644 --- a/program/tests/set_epoch_fee.rs +++ b/program/tests/set_epoch_fee.rs @@ -1,3 +1,4 @@ +#![allow(clippy::integer_arithmetic)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/set_funding_authority.rs b/program/tests/set_funding_authority.rs index 08e0668e..c719a780 100644 --- a/program/tests/set_funding_authority.rs +++ b/program/tests/set_funding_authority.rs @@ -1,3 +1,4 @@ +#![allow(clippy::integer_arithmetic)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/set_manager.rs b/program/tests/set_manager.rs index 987211ce..f813d429 100644 --- a/program/tests/set_manager.rs +++ b/program/tests/set_manager.rs @@ -1,3 +1,4 @@ +#![allow(clippy::integer_arithmetic)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/set_preferred.rs b/program/tests/set_preferred.rs index 83586d60..43e3251f 100644 --- a/program/tests/set_preferred.rs +++ b/program/tests/set_preferred.rs @@ -1,3 +1,4 @@ +#![allow(clippy::integer_arithmetic)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/set_referral_fee.rs b/program/tests/set_referral_fee.rs index a2f6166b..f4a1afbb 100644 --- a/program/tests/set_referral_fee.rs +++ b/program/tests/set_referral_fee.rs @@ -1,3 +1,4 @@ +#![allow(clippy::integer_arithmetic)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/set_staker.rs b/program/tests/set_staker.rs index dca486a6..0121493b 100644 --- a/program/tests/set_staker.rs +++ b/program/tests/set_staker.rs @@ -1,3 +1,4 @@ +#![allow(clippy::integer_arithmetic)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/set_withdrawal_fee.rs b/program/tests/set_withdrawal_fee.rs index 00ae0bf5..81b7152d 100644 --- a/program/tests/set_withdrawal_fee.rs +++ b/program/tests/set_withdrawal_fee.rs @@ -1,3 +1,4 @@ +#![allow(clippy::integer_arithmetic)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/update_pool_token_metadata.rs b/program/tests/update_pool_token_metadata.rs index 1e2d01d3..393ee9ed 100644 --- a/program/tests/update_pool_token_metadata.rs +++ b/program/tests/update_pool_token_metadata.rs @@ -1,3 +1,4 @@ +#![allow(clippy::integer_arithmetic)] #![cfg(feature = "test-sbf")] mod helpers; @@ -73,9 +74,9 @@ async fn success_update_pool_token_metadata() { let updated_symbol = "USYM"; let updated_uri = "updated_uri"; - let puffed_name = puffed_out_string(&updated_name, MAX_NAME_LENGTH); - let puffed_symbol = puffed_out_string(&updated_symbol, MAX_SYMBOL_LENGTH); - let puffed_uri = puffed_out_string(&updated_uri, MAX_URI_LENGTH); + let puffed_name = puffed_out_string(updated_name, MAX_NAME_LENGTH); + let puffed_symbol = puffed_out_string(updated_symbol, MAX_SYMBOL_LENGTH); + let puffed_uri = puffed_out_string(updated_uri, MAX_URI_LENGTH); let ix = instruction::update_token_metadata( &spl_stake_pool::id(), @@ -106,9 +107,9 @@ async fn success_update_pool_token_metadata() { ) .await; - assert_eq!(metadata.data.name.to_string(), puffed_name); - assert_eq!(metadata.data.symbol.to_string(), puffed_symbol); - assert_eq!(metadata.data.uri.to_string(), puffed_uri); + assert_eq!(metadata.data.name, puffed_name); + assert_eq!(metadata.data.symbol, puffed_symbol); + assert_eq!(metadata.data.uri, puffed_uri); } #[tokio::test] diff --git a/program/tests/update_stake_pool_balance.rs b/program/tests/update_stake_pool_balance.rs index 099797f9..0801d1af 100644 --- a/program/tests/update_stake_pool_balance.rs +++ b/program/tests/update_stake_pool_balance.rs @@ -1,3 +1,4 @@ +#![allow(clippy::integer_arithmetic)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index 7ceb6483..fa1e38da 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -1,3 +1,4 @@ +#![allow(clippy::integer_arithmetic)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index 0e640de7..79878732 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -1,3 +1,4 @@ +#![allow(clippy::integer_arithmetic)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index f80c5333..142d9da9 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -1,3 +1,4 @@ +#![allow(clippy::integer_arithmetic)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 31cf72d5..74b3ede1 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -1,3 +1,4 @@ +#![allow(clippy::integer_arithmetic)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/withdraw_sol.rs b/program/tests/withdraw_sol.rs index 2abcfc89..1dcdaf8f 100644 --- a/program/tests/withdraw_sol.rs +++ b/program/tests/withdraw_sol.rs @@ -1,3 +1,4 @@ +#![allow(clippy::integer_arithmetic)] #![cfg(feature = "test-sbf")] mod helpers; From 73baf9779364a6126f12ff4695a45674f9deef16 Mon Sep 17 00:00:00 2001 From: hanako mumei <81144685+2501babe@users.noreply.github.com> Date: Tue, 11 Oct 2022 12:04:28 -0700 Subject: [PATCH 0263/1076] update solana to 1.14.4 --- clients/cli/Cargo.toml | 18 +++++++++--------- program/Cargo.toml | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 1984f073..a750f046 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -14,15 +14,15 @@ clap = "2.33.3" serde = "1.0.130" serde_derive = "1.0.130" serde_json = "1.0.68" -solana-account-decoder = "=1.11.6" -solana-clap-utils = "=1.11.6" -solana-cli-config = "=1.11.6" -solana-cli-output = "=1.11.6" -solana-client = "=1.11.6" -solana-logger = "=1.11.6" -solana-program = "=1.11.6" -solana-remote-wallet = "=1.11.6" -solana-sdk = "=1.11.6" +solana-account-decoder = "=1.14.4" +solana-clap-utils = "=1.14.4" +solana-cli-config = "=1.14.4" +solana-cli-output = "=1.14.4" +solana-client = "=1.14.4" +solana-logger = "=1.14.4" +solana-program = "=1.14.4" +solana-remote-wallet = "=1.14.4" +solana-sdk = "=1.14.4" spl-associated-token-account = { version = "=1.1.1", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "=0.7.0", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "=3.5.0", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/program/Cargo.toml b/program/Cargo.toml index bf7ce2e9..7cda0129 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -20,7 +20,7 @@ num-traits = "0.2" num_enum = "0.5.4" serde = "1.0.130" serde_derive = "1.0.103" -solana-program = "1.11.6" +solana-program = "1.14.4" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-token = { version = "3.5", path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" @@ -28,9 +28,9 @@ bincode = "1.3.1" [dev-dependencies] proptest = "1.0" -solana-program-test = "1.11.6" -solana-sdk = "1.11.6" -solana-vote-program = "1.11.6" +solana-program-test = "1.14.4" +solana-sdk = "1.14.4" +solana-vote-program = "1.14.4" [lib] crate-type = ["cdylib", "lib"] From 49df691fbf16fdfee72f71bb2c22456ac1a16b1f Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Thu, 27 Oct 2022 07:59:25 +0900 Subject: [PATCH 0264/1076] upgrade solana-program to 1.14.6 (#3765) --- clients/cli/Cargo.toml | 18 +++++++++--------- program/Cargo.toml | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index a750f046..3e3e02f0 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -14,15 +14,15 @@ clap = "2.33.3" serde = "1.0.130" serde_derive = "1.0.130" serde_json = "1.0.68" -solana-account-decoder = "=1.14.4" -solana-clap-utils = "=1.14.4" -solana-cli-config = "=1.14.4" -solana-cli-output = "=1.14.4" -solana-client = "=1.14.4" -solana-logger = "=1.14.4" -solana-program = "=1.14.4" -solana-remote-wallet = "=1.14.4" -solana-sdk = "=1.14.4" +solana-account-decoder = "=1.14.6" +solana-clap-utils = "=1.14.6" +solana-cli-config = "=1.14.6" +solana-cli-output = "=1.14.6" +solana-client = "=1.14.6" +solana-logger = "=1.14.6" +solana-program = "=1.14.6" +solana-remote-wallet = "=1.14.6" +solana-sdk = "=1.14.6" spl-associated-token-account = { version = "=1.1.1", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "=0.7.0", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "=3.5.0", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/program/Cargo.toml b/program/Cargo.toml index 7cda0129..1ab55f01 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -20,7 +20,7 @@ num-traits = "0.2" num_enum = "0.5.4" serde = "1.0.130" serde_derive = "1.0.103" -solana-program = "1.14.4" +solana-program = "1.14.6" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-token = { version = "3.5", path = "../../token/program", features = [ "no-entrypoint" ] } thiserror = "1.0" @@ -28,9 +28,9 @@ bincode = "1.3.1" [dev-dependencies] proptest = "1.0" -solana-program-test = "1.14.4" -solana-sdk = "1.14.4" -solana-vote-program = "1.14.4" +solana-program-test = "1.14.6" +solana-sdk = "1.14.6" +solana-vote-program = "1.14.6" [lib] crate-type = ["cdylib", "lib"] From ddd72a8722f17d87c15995865be38cdff0bc74cd Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Sat, 19 Nov 2022 01:42:57 +0100 Subject: [PATCH 0265/1076] stake-pool: Truncate on withdrawal calculation (#3804) --- program/src/state.rs | 82 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 77 insertions(+), 5 deletions(-) diff --git a/program/src/state.rs b/program/src/state.rs index fcb0ab57..ca7507f6 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -18,7 +18,6 @@ use { pubkey::{Pubkey, PUBKEY_BYTES}, stake::state::Lockup, }, - spl_math::checked_ceil_div::CheckedCeilDiv, spl_token::state::{Account, AccountState}, std::{borrow::Borrow, convert::TryFrom, fmt, matches}, }; @@ -172,7 +171,7 @@ impl StakePool { /// calculate lamports amount on withdrawal #[inline] pub fn calc_lamports_withdraw_amount(&self, pool_tokens: u64) -> Option { - // `checked_ceil_div` returns `None` for a 0 quotient result, but in this + // `checked_div` returns `None` for a 0 quotient result, but in this // case, a return of 0 is valid for small amounts of pool tokens. So // we check for that separately let numerator = (pool_tokens as u128).checked_mul(self.total_lamports as u128)?; @@ -180,8 +179,7 @@ impl StakePool { if numerator < denominator || denominator == 0 { Some(0) } else { - let (quotient, _) = numerator.checked_ceil_div(denominator)?; - u64::try_from(quotient).ok() + u64::try_from(numerator.checked_div(denominator)?).ok() } } @@ -1033,7 +1031,7 @@ mod test { let fee_lamports = stake_pool .calc_lamports_withdraw_amount(pool_token_fee) .unwrap(); - assert_eq!(fee_lamports, LAMPORTS_PER_SOL); + assert_eq!(fee_lamports, LAMPORTS_PER_SOL - 1); // off-by-one due to truncation } #[test] @@ -1148,6 +1146,80 @@ mod test { stake_pool.pool_token_supply += deposit_result; let withdraw_result = stake_pool.calc_lamports_withdraw_amount(deposit_result).unwrap(); assert!(withdraw_result <= deposit_stake); + + // also test splitting the withdrawal in two operations + if deposit_result >= 2 { + let first_half_deposit = deposit_result / 2; + let first_withdraw_result = stake_pool.calc_lamports_withdraw_amount(first_half_deposit).unwrap(); + stake_pool.total_lamports -= first_withdraw_result; + stake_pool.pool_token_supply -= first_half_deposit; + let second_half_deposit = deposit_result - first_half_deposit; // do the whole thing + let second_withdraw_result = stake_pool.calc_lamports_withdraw_amount(second_half_deposit).unwrap(); + assert!(first_withdraw_result + second_withdraw_result <= deposit_stake); + } } } + + #[test] + fn specific_split_withdrawal() { + let total_lamports = 1_100_000_000_000; + let pool_token_supply = 1_000_000_000_000; + let deposit_stake = 3; + let mut stake_pool = StakePool { + total_lamports, + pool_token_supply, + ..StakePool::default() + }; + let deposit_result = stake_pool + .calc_pool_tokens_for_deposit(deposit_stake) + .unwrap(); + assert!(deposit_result > 0); + stake_pool.total_lamports += deposit_stake; + stake_pool.pool_token_supply += deposit_result; + let withdraw_result = stake_pool + .calc_lamports_withdraw_amount(deposit_result / 2) + .unwrap(); + assert!(withdraw_result * 2 <= deposit_stake); + } + + #[test] + fn withdraw_all() { + let total_lamports = 1_100_000_000_000; + let pool_token_supply = 1_000_000_000_000; + let mut stake_pool = StakePool { + total_lamports, + pool_token_supply, + ..StakePool::default() + }; + // take everything out at once + let withdraw_result = stake_pool + .calc_lamports_withdraw_amount(pool_token_supply) + .unwrap(); + assert_eq!(stake_pool.total_lamports, withdraw_result); + + // take out 1, then the rest + let withdraw_result = stake_pool.calc_lamports_withdraw_amount(1).unwrap(); + stake_pool.total_lamports -= withdraw_result; + stake_pool.pool_token_supply -= 1; + let withdraw_result = stake_pool + .calc_lamports_withdraw_amount(stake_pool.pool_token_supply) + .unwrap(); + assert_eq!(stake_pool.total_lamports, withdraw_result); + + // take out all except 1, then the rest + let mut stake_pool = StakePool { + total_lamports, + pool_token_supply, + ..StakePool::default() + }; + let withdraw_result = stake_pool + .calc_lamports_withdraw_amount(pool_token_supply - 1) + .unwrap(); + stake_pool.total_lamports -= withdraw_result; + stake_pool.pool_token_supply = 1; + assert_ne!(stake_pool.total_lamports, 0); + + let withdraw_result = stake_pool.calc_lamports_withdraw_amount(1).unwrap(); + assert_eq!(stake_pool.total_lamports, withdraw_result); + } } From 02970c52b482a8d0b12b888ca2456bf4a1643871 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Sat, 19 Nov 2022 01:43:22 +0100 Subject: [PATCH 0266/1076] stake-pool: Add lamports check for transient stake account on decrease (#3805) --- program/src/processor.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/program/src/processor.rs b/program/src/processor.rs index 77fdb2b4..15d011b6 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1214,11 +1214,14 @@ impl Processor { &[transient_stake_bump_seed], ]; + let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; let stake_rent = rent.minimum_balance(std::mem::size_of::()); - if lamports <= stake_rent { + let current_minimum_lamports = + stake_rent.saturating_add(minimum_delegation(stake_minimum_delegation)); + if lamports < current_minimum_lamports { msg!( - "Need more than {} lamports for transient stake to be rent-exempt, {} provided", - stake_rent, + "Need at least {} lamports for transient stake meet minimum delegation and rent-exempt requirements, {} provided", + current_minimum_lamports, lamports ); return Err(ProgramError::AccountNotRentExempt); @@ -1228,7 +1231,6 @@ impl Processor { .lamports() .checked_sub(lamports) .ok_or(ProgramError::InsufficientFunds)?; - let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; let required_lamports = minimum_stake_lamports(&meta, stake_minimum_delegation); if remaining_lamports < required_lamports { msg!("Need at least {} lamports in the stake account after decrease, {} requested, {} is the current possible maximum", From 8a4ea7abee840282064ccd66658cb280b0d8d382 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Sat, 19 Nov 2022 01:47:02 +0100 Subject: [PATCH 0267/1076] stake-pool: Add test for removing all validators from huge pool (#3806) --- program/tests/helpers/mod.rs | 4 ++- program/tests/huge_pool.rs | 60 ++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 4b9f9579..202f77b7 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -1706,6 +1706,7 @@ pub fn add_vote_account(program_test: &mut ProgramTest) -> Pubkey { vote_pubkey } +#[allow(clippy::too_many_arguments)] pub fn add_validator_stake_account( program_test: &mut ProgramTest, stake_pool: &mut state::StakePool, @@ -1714,6 +1715,7 @@ pub fn add_validator_stake_account( withdraw_authority: &Pubkey, voter_pubkey: &Pubkey, stake_amount: u64, + status: state::StakeStatus, ) { let meta = stake::state::Meta { rent_exempt_reserve: STAKE_ACCOUNT_RENT_EXEMPTION, @@ -1756,7 +1758,7 @@ pub fn add_validator_stake_account( let active_stake_lamports = stake_amount - LAMPORTS_PER_SOL; validator_list.validators.push(state::ValidatorStakeInfo { - status: state::StakeStatus::Active, + status, vote_account_address: *voter_pubkey, active_stake_lamports, transient_stake_lamports: 0, diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index 603d5d36..71b97e5e 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -57,6 +57,7 @@ async fn setup( &stake_pool_accounts.withdraw_authority, vote_account_address, stake_amount, + StakeStatus::Active, ); } @@ -578,3 +579,62 @@ async fn withdraw() { .await; assert!(error.is_none(), "{:?}", error); } + +#[tokio::test] +async fn cleanup_all() { + let mut program_test = program_test(); + let mut vote_account_pubkeys = vec![]; + let mut stake_pool_accounts = StakePoolAccounts::new(); + let max_validators = HUGE_POOL_SIZE; + stake_pool_accounts.max_validators = max_validators; + + let stake_pool_pubkey = stake_pool_accounts.stake_pool.pubkey(); + let (mut stake_pool, mut validator_list) = stake_pool_accounts.state(); + + for _ in 0..max_validators { + vote_account_pubkeys.push(add_vote_account(&mut program_test)); + } + + for vote_account_address in vote_account_pubkeys.iter() { + add_validator_stake_account( + &mut program_test, + &mut stake_pool, + &mut validator_list, + &stake_pool_pubkey, + &stake_pool_accounts.withdraw_authority, + vote_account_address, + STAKE_AMOUNT, + StakeStatus::ReadyForRemoval, + ); + } + + add_stake_pool_account( + &mut program_test, + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool, + ); + add_validator_list_account( + &mut program_test, + &stake_pool_accounts.validator_list.pubkey(), + &validator_list, + max_validators, + ); + let mut context = program_test.start_with_context().await; + + let transaction = Transaction::new_signed_with_payer( + &[instruction::cleanup_removed_validator_entries( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + )], + Some(&context.payer.pubkey()), + &[&context.payer], + context.last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err(); + assert!(error.is_none()); +} From 8ad921158cd8a5035350ae770b2288454c426c0c Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Mon, 21 Nov 2022 20:13:27 +0100 Subject: [PATCH 0268/1076] stake-pool: Add / remove validators from the reserve (#3714) * stake-pool: Create validator stake accounts from reserve * Update accounting to take minimum into account * Refactor withdraw tests * Add ability to remove validators during withdraw stake * Add seed to validator stake account address derivation * Update CLI with new instruction formats * Update documentation and helper scripts for new funding * Update Python bindings * Try to fix flakey test * Support token-2022 * Condense tests for CI * Reduce huge pool limit post-rebase * Avoid draining the whole reserve * Restrict account extensions on allow-list * Update comments to say "lamports" * Fixup code comments and variable names * Fix clippy in tests --- clients/cli/scripts/deposit.sh | 2 - clients/cli/scripts/setup-stake-pool.sh | 21 +- clients/cli/scripts/setup-test-validator.sh | 2 + clients/cli/src/main.rs | 237 ++-- clients/cli/src/output.rs | 16 +- clients/py/stake_pool/actions.py | 57 +- clients/py/stake_pool/constants.py | 4 +- clients/py/stake_pool/instructions.py | 43 +- clients/py/stake_pool/state.py | 25 +- clients/py/tests/conftest.py | 18 +- clients/py/tests/test_a_time_sensitive.py | 11 +- clients/py/tests/test_add_remove.py | 12 +- clients/py/tests/test_bot_rebalance.py | 23 +- clients/py/tests/test_deposit_withdraw_sol.py | 7 +- .../py/tests/test_deposit_withdraw_stake.py | 10 +- program/Cargo.toml | 4 +- program/src/error.rs | 6 + program/src/instruction.rs | 93 +- program/src/lib.rs | 35 +- program/src/processor.rs | 630 ++++----- program/src/state.rs | 134 +- program/tests/create_pool_token_metadata.rs | 19 +- program/tests/decrease.rs | 11 +- program/tests/deposit.rs | 90 +- program/tests/deposit_authority.rs | 10 +- program/tests/deposit_sol.rs | 56 +- program/tests/force_destake.rs | 30 +- program/tests/helpers/mod.rs | 567 +++++--- program/tests/huge_pool.rs | 154 ++- program/tests/increase.rs | 3 +- program/tests/initialize.rs | 320 ++++- program/tests/set_deposit_fee.rs | 2 +- program/tests/set_epoch_fee.rs | 4 +- program/tests/set_funding_authority.rs | 2 +- program/tests/set_manager.rs | 17 +- program/tests/set_preferred.rs | 7 +- program/tests/set_referral_fee.rs | 2 +- program/tests/set_staker.rs | 2 +- program/tests/set_withdrawal_fee.rs | 4 +- program/tests/update_pool_token_metadata.rs | 2 +- program/tests/update_stake_pool_balance.rs | 124 +- .../tests/update_validator_list_balance.rs | 322 ++++- program/tests/vsa_add.rs | 237 +++- program/tests/vsa_remove.rs | 183 ++- program/tests/withdraw.rs | 1175 +++++++++-------- program/tests/withdraw_sol.rs | 30 +- 46 files changed, 3033 insertions(+), 1730 deletions(-) diff --git a/clients/cli/scripts/deposit.sh b/clients/cli/scripts/deposit.sh index 9f316f35..56cea561 100755 --- a/clients/cli/scripts/deposit.sh +++ b/clients/cli/scripts/deposit.sh @@ -69,5 +69,3 @@ echo "If you are running on localnet with 32 slots per epoch, wait 12 seconds... sleep 12 echo "Depositing stakes into stake pool" deposit_stakes "$stake_pool_pubkey" "$validator_list" $authority -echo "Depositing SOL into stake pool" -$spl_stake_pool deposit-sol "$stake_pool_pubkey" "$sol_amount" diff --git a/clients/cli/scripts/setup-stake-pool.sh b/clients/cli/scripts/setup-stake-pool.sh index 0aacb09d..d196a93f 100755 --- a/clients/cli/scripts/setup-stake-pool.sh +++ b/clients/cli/scripts/setup-stake-pool.sh @@ -5,6 +5,7 @@ cd "$(dirname "$0")" || exit command_args=() +sol_amount=$1 ################################################### ### MODIFY PARAMETERS BELOW THIS LINE FOR YOUR POOL @@ -12,20 +13,20 @@ command_args=() # Epoch fee, assessed as a percentage of rewards earned by the pool every epoch, # represented as `numerator / denominator` -command_args+=( --epoch-fee-numerator 0 ) -command_args+=( --epoch-fee-denominator 0 ) +command_args+=( --epoch-fee-numerator 1 ) +command_args+=( --epoch-fee-denominator 100 ) # Withdrawal fee for SOL and stake accounts, represented as `numerator / denominator` -command_args+=( --withdrawal-fee-numerator 0 ) -command_args+=( --withdrawal-fee-denominator 0 ) +command_args+=( --withdrawal-fee-numerator 2 ) +command_args+=( --withdrawal-fee-denominator 100 ) # Deposit fee for SOL and stake accounts, represented as `numerator / denominator` -command_args+=( --deposit-fee-numerator 0 ) -command_args+=( --deposit-fee-denominator 0 ) +command_args+=( --deposit-fee-numerator 3 ) +command_args+=( --deposit-fee-denominator 100 ) command_args+=( --referral-fee 0 ) # Percentage of deposit fee that goes towards the referrer (a number between 0 and 100, inclusive) -command_args+=( --max-validators 2950 ) # Maximum number of validators in the stake pool, 2950 is the current maximum possible +command_args+=( --max-validators 2350 ) # Maximum number of validators in the stake pool, 2350 is the current maximum possible # (Optional) Deposit authority, required to sign all deposits into the pool. # Setting this variable makes the pool "private" or "restricted". @@ -68,3 +69,9 @@ $spl_stake_pool \ --validator-list-keypair "$validator_list_keyfile" \ --mint-keypair "$mint_keyfile" \ --reserve-keypair "$reserve_keyfile" + +set +ex +echo "Depositing SOL into stake pool" +stake_pool_pubkey=$(solana-keygen pubkey "$stake_pool_keyfile") +set -ex +$spl_stake_pool deposit-sol "$stake_pool_pubkey" "$sol_amount" diff --git a/clients/cli/scripts/setup-test-validator.sh b/clients/cli/scripts/setup-test-validator.sh index 5fd803dd..c0414c6e 100755 --- a/clients/cli/scripts/setup-test-validator.sh +++ b/clients/cli/scripts/setup-test-validator.sh @@ -17,6 +17,8 @@ create_keypair () { setup_test_validator() { solana-test-validator -c SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy -c EmiU8AQkB2sswTxVB6aCmsAJftoowZGGDXuytm6X65R3 --url devnet --slots-per-epoch 32 --quiet --reset & + # Uncomment to use a locally built stake program + #solana-test-validator --bpf-program SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy ../../../target/deploy/spl_stake_pool.so --slots-per-epoch 32 --quiet --reset & pid=$! solana config set --url http://127.0.0.1:8899 solana config set --commitment confirmed diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index a960e23b..cba12254 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -51,7 +51,7 @@ use { MINIMUM_RESERVE_LAMPORTS, }, std::cmp::Ordering, - std::{process::exit, sync::Arc}, + std::{num::NonZeroU32, process::exit, sync::Arc}, }; // use instruction::create_associated_token_account once ATA 1.0.5 is released #[allow(deprecated)] @@ -421,12 +421,6 @@ fn command_vsa_add( stake_pool_address: &Pubkey, vote_account: &Pubkey, ) -> CommandResult { - let (stake_account_address, _) = - find_stake_program_address(&spl_stake_pool::id(), vote_account, stake_pool_address); - println!( - "Adding stake account {}, delegated to {}", - stake_account_address, vote_account - ); let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?; if validator_list.contains(vote_account) { @@ -441,6 +435,35 @@ fn command_vsa_add( command_update(config, stake_pool_address, false, false)?; } + // iterate until a free account is found + let (stake_account_address, validator_seed) = { + let mut i = 0; + loop { + let seed = NonZeroU32::new(i); + let (address, _) = find_stake_program_address( + &spl_stake_pool::id(), + vote_account, + stake_pool_address, + seed, + ); + let maybe_account = config + .rpc_client + .get_account_with_commitment( + &stake_pool.reserve_stake, + config.rpc_client.commitment(), + )? + .value; + if maybe_account.is_some() { + break (address, seed); + } + i += 1; + } + }; + println!( + "Adding stake account {}, delegated to {}", + stake_account_address, vote_account + ); + let mut signers = vec![config.fee_payer.as_ref(), config.staker.as_ref()]; unique_signers!(signers); let transaction = checked_transaction_with_signers( @@ -450,8 +473,8 @@ fn command_vsa_add( &spl_stake_pool::id(), &stake_pool, stake_pool_address, - &config.fee_payer.pubkey(), vote_account, + validator_seed, ), ], &signers, @@ -465,60 +488,41 @@ fn command_vsa_remove( config: &Config, stake_pool_address: &Pubkey, vote_account: &Pubkey, - new_authority: &Option, - stake_receiver: &Option, ) -> CommandResult { if !config.no_update { command_update(config, stake_pool_address, false, false)?; } - let (stake_account_address, _) = - find_stake_program_address(&spl_stake_pool::id(), vote_account, stake_pool_address); - println!( - "Removing stake account {}, delegated to {}", - stake_account_address, vote_account - ); - let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; - - let mut instructions = vec![]; - let mut stake_keypair = None; - - let stake_receiver = stake_receiver.unwrap_or_else(|| { - let new_stake_keypair = new_stake_account( - &config.fee_payer.pubkey(), - &mut instructions, - /* stake_receiver_account_balance = */ 0, - ); - let stake_pubkey = new_stake_keypair.pubkey(); - stake_keypair = Some(new_stake_keypair); - stake_pubkey - }); - - let staker_pubkey = config.staker.pubkey(); - let new_authority = new_authority.as_ref().unwrap_or(&staker_pubkey); - let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?; let validator_stake_info = validator_list .find(vote_account) .ok_or("Vote account not found in validator list")?; + let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix); + let (stake_account_address, _) = find_stake_program_address( + &spl_stake_pool::id(), + vote_account, + stake_pool_address, + validator_seed, + ); + println!( + "Removing stake account {}, delegated to {}", + stake_account_address, vote_account + ); + let mut signers = vec![config.fee_payer.as_ref(), config.staker.as_ref()]; - if let Some(stake_keypair) = stake_keypair.as_ref() { - signers.push(stake_keypair); - } - instructions.push( + let instructions = vec![ // Create new validator stake account address spl_stake_pool::instruction::remove_validator_from_pool_with_vote( &spl_stake_pool::id(), &stake_pool, stake_pool_address, vote_account, - new_authority, - validator_stake_info.transient_seed_suffix_start, - &stake_receiver, + validator_seed, + validator_stake_info.transient_seed_suffix, ), - ); + ]; unique_signers!(signers); let transaction = checked_transaction_with_signers(config, &instructions, &signers)?; send_transaction(config, transaction)?; @@ -541,6 +545,7 @@ fn command_increase_validator_stake( let validator_stake_info = validator_list .find(vote_account) .ok_or("Vote account not found in validator list")?; + let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix); let mut signers = vec![config.fee_payer.as_ref(), config.staker.as_ref()]; unique_signers!(signers); @@ -553,7 +558,8 @@ fn command_increase_validator_stake( stake_pool_address, vote_account, lamports, - validator_stake_info.transient_seed_suffix_start, + validator_seed, + validator_stake_info.transient_seed_suffix, ), ], &signers, @@ -578,6 +584,7 @@ fn command_decrease_validator_stake( let validator_stake_info = validator_list .find(vote_account) .ok_or("Vote account not found in validator list")?; + let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix); let mut signers = vec![config.fee_payer.as_ref(), config.staker.as_ref()]; unique_signers!(signers); @@ -590,7 +597,8 @@ fn command_decrease_validator_stake( stake_pool_address, vote_account, lamports, - validator_stake_info.transient_seed_suffix_start, + validator_seed, + validator_stake_info.transient_seed_suffix, ), ], &signers, @@ -681,13 +689,18 @@ fn command_deposit_stake( // Check if this vote account has staking account in the pool let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?; - if !validator_list.contains(&vote_account) { - return Err("Stake account for this validator does not exist in the pool.".into()); - } + let validator_stake_info = validator_list + .find(&vote_account) + .ok_or("Vote account not found in the stake pool")?; + let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix); // Calculate validator stake account address linked to the pool - let (validator_stake_account, _) = - find_stake_program_address(&spl_stake_pool::id(), &vote_account, stake_pool_address); + let (validator_stake_account, _) = find_stake_program_address( + &spl_stake_pool::id(), + &vote_account, + stake_pool_address, + validator_seed, + ); let validator_stake_state = get_stake_state(&config.rpc_client, &validator_stake_account)?; println!( @@ -856,13 +869,18 @@ fn command_deposit_all_stake( _ => Err("Wrong stake account state, must be delegated to validator"), }?; - if !validator_list.contains(&vote_account) { - return Err("Stake account for this validator does not exist in the pool.".into()); - } + let validator_stake_info = validator_list + .find(&vote_account) + .ok_or("Vote account not found in the stake pool")?; + let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix); // Calculate validator stake account address linked to the pool - let (validator_stake_account, _) = - find_stake_program_address(&spl_stake_pool::id(), &vote_account, stake_pool_address); + let (validator_stake_account, _) = find_stake_program_address( + &spl_stake_pool::id(), + &vote_account, + stake_pool_address, + validator_seed, + ); let validator_stake_state = get_stake_state(&config.rpc_client, &validator_stake_account)?; println!("Depositing user stake {}: {:?}", stake_address, stake_state); @@ -1066,16 +1084,18 @@ fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { .validators .iter() .map(|validator| { + let validator_seed = NonZeroU32::new(validator.validator_seed_suffix); let (stake_account_address, _) = find_stake_program_address( &spl_stake_pool::id(), &validator.vote_account_address, stake_pool_address, + validator_seed, ); let (transient_stake_account_address, _) = find_transient_stake_program_address( &spl_stake_pool::id(), &validator.vote_account_address, stake_pool_address, - validator.transient_seed_suffix_start, + validator.transient_seed_suffix, ); let update_required = validator.last_update_epoch != epoch_info.epoch; CliStakePoolStakeAccountInfo { @@ -1235,10 +1255,12 @@ fn prepare_withdraw_accounts( &validator_list, stake_pool, |validator| { + let validator_seed = NonZeroU32::new(validator.validator_seed_suffix); let (stake_account_address, _) = find_stake_program_address( &spl_stake_pool::id(), &validator.vote_account_address, stake_pool_address, + validator_seed, ); ( @@ -1257,7 +1279,7 @@ fn prepare_withdraw_accounts( &spl_stake_pool::id(), &validator.vote_account_address, stake_pool_address, - validator.transient_seed_suffix_start, + validator.transient_seed_suffix, ); ( @@ -1413,47 +1435,51 @@ fn command_withdraw_stake( } // Check if the vote account exists in the stake pool let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?; - if validator_list - .validators - .into_iter() - .any(|x| x.vote_account_address == vote_account) - { - let (stake_account_address, _) = find_stake_program_address( - &spl_stake_pool::id(), - &vote_account, - stake_pool_address, - ); - let stake_account = config.rpc_client.get_account(&stake_account_address)?; - - let available_for_withdrawal = stake_pool - .calc_lamports_withdraw_amount( - stake_account - .lamports - .saturating_sub(stake_pool_minimum_delegation) - .saturating_sub(stake_account_rent_exemption), - ) - .unwrap(); - - if available_for_withdrawal < pool_amount { - return Err(format!( - "Not enough lamports available for withdrawal from {}, {} asked, {} available", - stake_account_address, pool_amount, available_for_withdrawal - ) - .into()); - } - vec![WithdrawAccount { - stake_address: stake_account_address, - vote_address: Some(vote_account), - pool_amount, - }] - } else { - return Err(format!("Provided stake account is delegated to a vote account {} which does not exist in the stake pool", vote_account).into()); + let validator_stake_info = validator_list + .find(&vote_account) + .ok_or(format!("Provided stake account is delegated to a vote account {} which does not exist in the stake pool", vote_account))?; + let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix); + let (stake_account_address, _) = find_stake_program_address( + &spl_stake_pool::id(), + &vote_account, + stake_pool_address, + validator_seed, + ); + let stake_account = config.rpc_client.get_account(&stake_account_address)?; + + let available_for_withdrawal = stake_pool + .calc_lamports_withdraw_amount( + stake_account + .lamports + .saturating_sub(stake_pool_minimum_delegation) + .saturating_sub(stake_account_rent_exemption), + ) + .unwrap(); + + if available_for_withdrawal < pool_amount { + return Err(format!( + "Not enough lamports available for withdrawal from {}, {} asked, {} available", + stake_account_address, pool_amount, available_for_withdrawal + ) + .into()); } + vec![WithdrawAccount { + stake_address: stake_account_address, + vote_address: Some(vote_account), + pool_amount, + }] } else if let Some(vote_account_address) = vote_account_address { + let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?; + let validator_stake_info = validator_list.find(vote_account_address).ok_or(format!( + "Provided vote account address {} does not exist in the stake pool", + vote_account_address + ))?; + let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix); let (stake_account_address, _) = find_stake_program_address( &spl_stake_pool::id(), vote_account_address, stake_pool_address, + validator_seed, ); let stake_account = config.rpc_client.get_account(&stake_account_address)?; @@ -2120,23 +2146,6 @@ fn main() { .required(true) .help("Vote account for the validator to remove from the pool"), ) - .arg( - Arg::with_name("new_authority") - .long("new-authority") - .validator(is_pubkey) - .value_name("ADDRESS") - .takes_value(true) - .help("New authority to set as Staker and Withdrawer in the stake account removed from the pool. - Defaults to the client keypair."), - ) - .arg( - Arg::with_name("stake_receiver") - .long("stake-receiver") - .validator(is_pubkey) - .value_name("ADDRESS") - .takes_value(true) - .help("Stake account to receive SOL from the stake pool. Defaults to a new stake account."), - ) ) .subcommand(SubCommand::with_name("increase-validator-stake") .about("Increase stake to a validator, drawing from the stake pool reserve. Must be signed by the pool staker.") @@ -2810,15 +2819,7 @@ fn main() { ("remove-validator", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); let vote_account = pubkey_of(arg_matches, "vote_account").unwrap(); - let new_authority = pubkey_of(arg_matches, "new_authority"); - let stake_receiver = pubkey_of(arg_matches, "stake_receiver"); - command_vsa_remove( - &config, - &stake_pool_address, - &vote_account, - &new_authority, - &stake_receiver, - ) + command_vsa_remove(&config, &stake_pool_address, &vote_account) } ("increase-validator-stake", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); diff --git a/clients/cli/src/output.rs b/clients/cli/src/output.rs index 7ca8feab..f9b0cd27 100644 --- a/clients/cli/src/output.rs +++ b/clients/cli/src/output.rs @@ -362,8 +362,9 @@ pub(crate) struct CliStakePoolValidator { pub active_stake_lamports: u64, pub transient_stake_lamports: u64, pub last_update_epoch: u64, - pub transient_seed_suffix_start: u64, - pub transient_seed_suffix_end: u64, + pub transient_seed_suffix: u64, + pub unused: u32, + pub validator_seed_suffix: u32, pub status: CliStakePoolValidatorStakeStatus, pub vote_account_address: String, } @@ -374,8 +375,9 @@ impl From for CliStakePoolValidator { active_stake_lamports: v.active_stake_lamports, transient_stake_lamports: v.transient_stake_lamports, last_update_epoch: v.last_update_epoch, - transient_seed_suffix_start: v.transient_seed_suffix_start, - transient_seed_suffix_end: v.transient_seed_suffix_end, + transient_seed_suffix: v.transient_seed_suffix, + unused: v.unused, + validator_seed_suffix: v.validator_seed_suffix, status: CliStakePoolValidatorStakeStatus::from(v.status), vote_account_address: v.vote_account_address.to_string(), } @@ -390,6 +392,10 @@ impl From for CliStakePoolValidatorStakeStatus { CliStakePoolValidatorStakeStatus::DeactivatingTransient } StakeStatus::ReadyForRemoval => CliStakePoolValidatorStakeStatus::ReadyForRemoval, + StakeStatus::DeactivatingValidator => { + CliStakePoolValidatorStakeStatus::DeactivatingValidator + } + StakeStatus::DeactivatingAll => CliStakePoolValidatorStakeStatus::DeactivatingAll, } } } @@ -399,6 +405,8 @@ pub(crate) enum CliStakePoolValidatorStakeStatus { Active, DeactivatingTransient, ReadyForRemoval, + DeactivatingValidator, + DeactivatingAll, } #[derive(Serialize, Deserialize)] diff --git a/clients/py/stake_pool/actions.py b/clients/py/stake_pool/actions.py index 970205a3..18176f45 100644 --- a/clients/py/stake_pool/actions.py +++ b/clients/py/stake_pool/actions.py @@ -92,7 +92,9 @@ async def create(client: AsyncClient, manager: Keypair, txn, manager, validator_list, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) -async def create_all(client: AsyncClient, manager: Keypair, fee: Fee, referral_fee: int) -> Tuple[PublicKey, PublicKey]: +async def create_all( + client: AsyncClient, manager: Keypair, fee: Fee, referral_fee: int +) -> Tuple[PublicKey, PublicKey, PublicKey]: stake_pool = Keypair() validator_list = Keypair() (pool_withdraw_authority, seed) = find_withdraw_authority_program_address( @@ -116,11 +118,11 @@ async def create_all(client: AsyncClient, manager: Keypair, fee: Fee, referral_f await create( client, manager, stake_pool, validator_list, pool_mint.public_key, reserve_stake.public_key, manager_fee_account, fee, referral_fee) - return (stake_pool.public_key, validator_list.public_key) + return (stake_pool.public_key, validator_list.public_key, pool_mint.public_key) async def add_validator_to_pool( - client: AsyncClient, funder: Keypair, + client: AsyncClient, staker: Keypair, stake_pool_address: PublicKey, validator: PublicKey ): resp = await client.get_account_info(stake_pool_address, commitment=Confirmed) @@ -133,12 +135,13 @@ async def add_validator_to_pool( stake_pool_address, stake_pool.staker, stake_pool.validator_list, - funder.public_key, + stake_pool.reserve_stake, validator, + None, ) ) await client.send_transaction( - txn, funder, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + txn, staker, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) async def remove_validator_from_pool( @@ -152,33 +155,20 @@ async def remove_validator_from_pool( data = resp['result']['value']['data'] validator_list = ValidatorList.decode(data[0], data[1]) validator_info = next(x for x in validator_list.validators if x.vote_account_address == validator) - destination_stake = Keypair() txn = Transaction() - txn.add( - sys.create_account( - sys.CreateAccountParams( - from_pubkey=staker.public_key, - new_account_pubkey=destination_stake.public_key, - lamports=0, # will get filled by split - space=STAKE_LEN, - program_id=STAKE_PROGRAM_ID, - ) - ) - ) txn.add( sp.remove_validator_from_pool_with_vote( STAKE_POOL_PROGRAM_ID, stake_pool_address, stake_pool.staker, stake_pool.validator_list, - staker.public_key, validator, - validator_info.transient_seed_suffix_start, - destination_stake.public_key + validator_info.validator_seed_suffix or None, + validator_info.transient_seed_suffix, ) ) await client.send_transaction( - txn, staker, destination_stake, + txn, staker, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) @@ -264,11 +254,18 @@ async def deposit_stake( data = resp['result']['value']['data'] stake_pool = StakePool.decode(data[0], data[1]) + resp = await client.get_account_info(stake_pool.validator_list, commitment=Confirmed) + data = resp['result']['value']['data'] + validator_list = ValidatorList.decode(data[0], data[1]) + + validator_info = next(x for x in validator_list.validators if x.vote_account_address == validator_vote) + (withdraw_authority, _) = find_withdraw_authority_program_address(STAKE_POOL_PROGRAM_ID, stake_pool_address) (validator_stake, _) = find_stake_program_address( STAKE_POOL_PROGRAM_ID, validator_vote, stake_pool_address, + validator_info.validator_seed_suffix or None, ) txn = Transaction() @@ -335,11 +332,18 @@ async def withdraw_stake( data = resp['result']['value']['data'] stake_pool = StakePool.decode(data[0], data[1]) + resp = await client.get_account_info(stake_pool.validator_list, commitment=Confirmed) + data = resp['result']['value']['data'] + validator_list = ValidatorList.decode(data[0], data[1]) + + validator_info = next(x for x in validator_list.validators if x.vote_account_address == validator_vote) + (withdraw_authority, _) = find_withdraw_authority_program_address(STAKE_POOL_PROGRAM_ID, stake_pool_address) (validator_stake, _) = find_stake_program_address( STAKE_POOL_PROGRAM_ID, validator_vote, stake_pool_address, + validator_info.validator_seed_suffix or None, ) resp = await client.get_minimum_balance_for_rent_exemption(STAKE_LEN) @@ -406,13 +410,14 @@ async def update_stake_pool(client: AsyncClient, payer: Keypair, stake_pool_addr STAKE_POOL_PROGRAM_ID, validator.vote_account_address, stake_pool_address, + validator.validator_seed_suffix or None, ) validator_and_transient_stake_pairs.append(validator_stake_address) (transient_stake_address, _) = find_transient_stake_program_address( STAKE_POOL_PROGRAM_ID, validator.vote_account_address, stake_pool_address, - validator.transient_seed_suffix_start, + validator.transient_seed_suffix, ) validator_and_transient_stake_pairs.append(transient_stake_address) update_list_instructions.append( @@ -486,7 +491,8 @@ async def increase_validator_stake( (withdraw_authority, seed) = find_withdraw_authority_program_address(STAKE_POOL_PROGRAM_ID, stake_pool_address) validator_info = next(x for x in validator_list.validators if x.vote_account_address == validator_vote) - transient_stake_seed = validator_info.transient_seed_suffix_start + 1 # bump up by one to avoid reuse + transient_stake_seed = validator_info.transient_seed_suffix + 1 # bump up by one to avoid reuse + validator_stake_seed = validator_info.validator_seed_suffix or None (transient_stake, _) = find_transient_stake_program_address( STAKE_POOL_PROGRAM_ID, validator_info.vote_account_address, @@ -497,6 +503,7 @@ async def increase_validator_stake( STAKE_POOL_PROGRAM_ID, validator_info.vote_account_address, stake_pool_address, + validator_stake_seed ) txn = Transaction() @@ -543,12 +550,14 @@ async def decrease_validator_stake( (withdraw_authority, seed) = find_withdraw_authority_program_address(STAKE_POOL_PROGRAM_ID, stake_pool_address) validator_info = next(x for x in validator_list.validators if x.vote_account_address == validator_vote) + validator_stake_seed = validator_info.validator_seed_suffix or None (validator_stake, _) = find_stake_program_address( STAKE_POOL_PROGRAM_ID, validator_info.vote_account_address, stake_pool_address, + validator_stake_seed, ) - transient_stake_seed = validator_info.transient_seed_suffix_start + 1 # bump up by one to avoid reuse + transient_stake_seed = validator_info.transient_seed_suffix + 1 # bump up by one to avoid reuse (transient_stake, _) = find_transient_stake_program_address( STAKE_POOL_PROGRAM_ID, validator_info.vote_account_address, diff --git a/clients/py/stake_pool/constants.py b/clients/py/stake_pool/constants.py index d58a99fe..7e0be876 100644 --- a/clients/py/stake_pool/constants.py +++ b/clients/py/stake_pool/constants.py @@ -1,6 +1,6 @@ """SPL Stake Pool Constants.""" -from typing import Tuple +from typing import Optional, Tuple from solana.publickey import PublicKey from stake.constants import MINIMUM_DELEGATION @@ -44,12 +44,14 @@ def find_stake_program_address( program_id: PublicKey, vote_account_address: PublicKey, stake_pool_address: PublicKey, + seed: Optional[int] ) -> Tuple[PublicKey, int]: """Generates the stake program address for a validator's vote account""" return PublicKey.find_program_address( [ bytes(vote_account_address), bytes(stake_pool_address), + seed.to_bytes(4, 'little') if seed else bytes(), ], program_id, ) diff --git a/clients/py/stake_pool/instructions.py b/clients/py/stake_pool/instructions.py index 282037bd..0ecfea60 100644 --- a/clients/py/stake_pool/instructions.py +++ b/clients/py/stake_pool/instructions.py @@ -88,8 +88,8 @@ class AddValidatorToPoolParams(NamedTuple): """`[w]` Stake pool.""" staker: PublicKey """`[s]` Staker.""" - funding_account: PublicKey - """`[ws]` Funding account (must be a system account).""" + reserve_stake: PublicKey + """`[w]` Reserve stake account.""" withdraw_authority: PublicKey """`[]` Stake pool withdraw authority.""" validator_list: PublicKey @@ -111,6 +111,10 @@ class AddValidatorToPoolParams(NamedTuple): stake_program_id: PublicKey """`[]` Stake program.""" + # Params + seed: Optional[int] + """Seed to used to create the validator stake account.""" + class RemoveValidatorFromPoolParams(NamedTuple): """(Staker only) Removes validator from the pool.""" @@ -123,16 +127,12 @@ class RemoveValidatorFromPoolParams(NamedTuple): """`[s]` Staker.""" withdraw_authority: PublicKey """`[]` Stake pool withdraw authority.""" - new_stake_authority: PublicKey - """`[]` New stake / withdraw authority on the split stake account.""" validator_list: PublicKey """`[w]` Validator stake list storage account.""" validator_stake: PublicKey """`[w]` Stake account to remove from the pool.""" transient_stake: PublicKey """`[]` Transient stake account, to check that there's no activation ongoing.""" - destination_stake: PublicKey - """`[w]` Destination stake account, to receive the minimum SOL from the validator stake account.""" clock_sysvar: PublicKey """'[]' Stake config sysvar.""" stake_program_id: PublicKey @@ -492,6 +492,10 @@ class InstructionType(IntEnum): "amount" / Int64ul ) +SEED_LAYOUT = Struct( + "seed" / Int32ul +) + INSTRUCTIONS_LAYOUT = Struct( "instruction_type" / Int8ul, "args" @@ -499,7 +503,7 @@ class InstructionType(IntEnum): lambda this: this.instruction_type, { InstructionType.INITIALIZE: INITIALIZE_LAYOUT, - InstructionType.ADD_VALIDATOR_TO_POOL: Pass, + InstructionType.ADD_VALIDATOR_TO_POOL: SEED_LAYOUT, InstructionType.REMOVE_VALIDATOR_FROM_POOL: Pass, InstructionType.DECREASE_VALIDATOR_STAKE: MOVE_STAKE_LAYOUT, InstructionType.INCREASE_VALIDATOR_STAKE: MOVE_STAKE_LAYOUT, @@ -563,7 +567,7 @@ def add_validator_to_pool(params: AddValidatorToPoolParams) -> TransactionInstru keys=[ AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=False), AccountMeta(pubkey=params.staker, is_signer=True, is_writable=False), - AccountMeta(pubkey=params.funding_account, is_signer=True, is_writable=True), + AccountMeta(pubkey=params.reserve_stake, is_signer=False, is_writable=True), AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), AccountMeta(pubkey=params.validator_list, is_signer=False, is_writable=True), AccountMeta(pubkey=params.validator_stake, is_signer=False, is_writable=True), @@ -579,7 +583,7 @@ def add_validator_to_pool(params: AddValidatorToPoolParams) -> TransactionInstru data=INSTRUCTIONS_LAYOUT.build( dict( instruction_type=InstructionType.ADD_VALIDATOR_TO_POOL, - args=None + args={'seed': params.seed or 0} ) ) ) @@ -590,18 +594,19 @@ def add_validator_to_pool_with_vote( stake_pool: PublicKey, staker: PublicKey, validator_list: PublicKey, - funder: PublicKey, - validator: PublicKey + reserve_stake: PublicKey, + validator: PublicKey, + validator_stake_seed: Optional[int], ) -> TransactionInstruction: """Creates instruction to add a validator based on their vote account address.""" - (withdraw_authority, seed) = find_withdraw_authority_program_address(program_id, stake_pool) - (validator_stake, seed) = find_stake_program_address(program_id, validator, stake_pool) + (withdraw_authority, _seed) = find_withdraw_authority_program_address(program_id, stake_pool) + (validator_stake, _seed) = find_stake_program_address(program_id, validator, stake_pool, validator_stake_seed) return add_validator_to_pool( AddValidatorToPoolParams( program_id=STAKE_POOL_PROGRAM_ID, stake_pool=stake_pool, staker=staker, - funding_account=funder, + reserve_stake=reserve_stake, withdraw_authority=withdraw_authority, validator_list=validator_list, validator_stake=validator_stake, @@ -612,6 +617,7 @@ def add_validator_to_pool_with_vote( stake_config_sysvar=SYSVAR_STAKE_CONFIG_ID, system_program_id=SYS_PROGRAM_ID, stake_program_id=STAKE_PROGRAM_ID, + seed=validator_stake_seed, ) ) @@ -623,11 +629,9 @@ def remove_validator_from_pool(params: RemoveValidatorFromPoolParams) -> Transac AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=False), AccountMeta(pubkey=params.staker, is_signer=True, is_writable=False), AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), - AccountMeta(pubkey=params.new_stake_authority, is_signer=False, is_writable=True), AccountMeta(pubkey=params.validator_list, is_signer=False, is_writable=True), AccountMeta(pubkey=params.validator_stake, is_signer=False, is_writable=True), AccountMeta(pubkey=params.transient_stake, is_signer=False, is_writable=False), - AccountMeta(pubkey=params.destination_stake, is_signer=False, is_writable=True), AccountMeta(pubkey=params.clock_sysvar, is_signer=False, is_writable=False), AccountMeta(pubkey=params.stake_program_id, is_signer=False, is_writable=False), ], @@ -646,14 +650,13 @@ def remove_validator_from_pool_with_vote( stake_pool: PublicKey, staker: PublicKey, validator_list: PublicKey, - new_stake_authority: PublicKey, validator: PublicKey, + validator_stake_seed: Optional[int], transient_stake_seed: int, - destination_stake: PublicKey, ) -> TransactionInstruction: """Creates instruction to remove a validator based on their vote account address.""" (withdraw_authority, seed) = find_withdraw_authority_program_address(program_id, stake_pool) - (validator_stake, seed) = find_stake_program_address(program_id, validator, stake_pool) + (validator_stake, seed) = find_stake_program_address(program_id, validator, stake_pool, validator_stake_seed) (transient_stake, seed) = find_transient_stake_program_address( program_id, validator, stake_pool, transient_stake_seed) return remove_validator_from_pool( @@ -662,11 +665,9 @@ def remove_validator_from_pool_with_vote( stake_pool=stake_pool, staker=staker, withdraw_authority=withdraw_authority, - new_stake_authority=new_stake_authority, validator_list=validator_list, validator_stake=validator_stake, transient_stake=transient_stake, - destination_stake=destination_stake, clock_sysvar=SYSVAR_CLOCK_PUBKEY, stake_program_id=STAKE_PROGRAM_ID, ) diff --git a/clients/py/stake_pool/state.py b/clients/py/stake_pool/state.py index 8791c3e2..b963e7a2 100644 --- a/clients/py/stake_pool/state.py +++ b/clients/py/stake_pool/state.py @@ -116,6 +116,10 @@ class StakeStatus(IntEnum): """Stake has been removed, but a deactivating transient stake still exists.""" READY_FOR_REMOVAL = 2 """No more validator stake accounts exist, entry ready for removal.""" + DEACTIVATING_VALIDATOR = 3 + """Validator stake account is deactivating to be merged into the reserve next epoch.""" + DEACTIVATING_ALL = 3 + """All alidator stake accounts are deactivating to be merged into the reserve next epoch.""" class ValidatorStakeInfo(NamedTuple): @@ -128,11 +132,14 @@ class ValidatorStakeInfo(NamedTuple): last_update_epoch: int """Last epoch the active and transient stake lamports fields were updated.""" - transient_seed_suffix_start: int - """Start of the validator transient account seed suffixes.""" + transient_seed_suffix: int + """Transient account seed suffix.""" - transient_seed_suffix_end: int - """End of the validator transient account seed suffixes.""" + unused: int + """Unused space, initially meant to specify the range of transient stake account suffixes.""" + + validator_seed_suffix: int + """Validator account seed suffix.""" status: StakeStatus """Status of the validator stake account.""" @@ -146,8 +153,9 @@ def decode_container(cls, container: Container): active_stake_lamports=container['active_stake_lamports'], transient_stake_lamports=container['transient_stake_lamports'], last_update_epoch=container['last_update_epoch'], - transient_seed_suffix_start=container['transient_seed_suffix_start'], - transient_seed_suffix_end=container['transient_seed_suffix_end'], + transient_seed_suffix=container['transient_seed_suffix'], + unused=container['unused'], + validator_seed_suffix=container['validator_seed_suffix'], status=container['status'], vote_account_address=PublicKey(container['vote_account_address']), ) @@ -302,8 +310,9 @@ def decode(cls, data: str, encoding: str): "active_stake_lamports" / Int64ul, "transient_stake_lamports" / Int64ul, "last_update_epoch" / Int64ul, - "transient_seed_suffix_start" / Int64ul, - "transient_seed_suffix_end" / Int64ul, + "transient_seed_suffix" / Int64ul, + "unused" / Int32ul, + "validator_seed_suffix" / Int32ul, "status" / Int8ul, "vote_account_address" / PUBLIC_KEY_LAYOUT, ) diff --git a/clients/py/tests/conftest.py b/clients/py/tests/conftest.py index 9e39dda8..df80f807 100644 --- a/clients/py/tests/conftest.py +++ b/clients/py/tests/conftest.py @@ -12,12 +12,15 @@ from solana.rpc.async_api import AsyncClient from solana.rpc.commitment import Confirmed +from spl.token.instructions import get_associated_token_address + from vote.actions import create_vote from system.actions import airdrop -from stake_pool.actions import create_all, add_validator_to_pool +from stake_pool.actions import deposit_sol, create_all, add_validator_to_pool from stake_pool.state import Fee NUM_SLOTS_PER_EPOCH: int = 32 +AIRDROP_LAMPORTS: int = 30_000_000_000 @pytest.fixture(scope="session") @@ -51,14 +54,20 @@ async def validators(async_client, payer) -> List[PublicKey]: @pytest_asyncio.fixture -async def stake_pool_addresses(async_client, payer, validators, waiter) -> Tuple[PublicKey, PublicKey]: +async def stake_pool_addresses( + async_client, payer, validators, waiter +) -> Tuple[PublicKey, PublicKey, PublicKey]: fee = Fee(numerator=1, denominator=1000) referral_fee = 20 # Change back to `wait_for_next_epoch_if_soon` once https://github.com/solana-labs/solana/pull/26851 is available await waiter.wait_for_next_epoch(async_client) stake_pool_addresses = await create_all(async_client, payer, fee, referral_fee) + stake_pool = stake_pool_addresses[0] + pool_mint = stake_pool_addresses[2] + token_account = get_associated_token_address(payer.public_key, pool_mint) + await deposit_sol(async_client, payer, stake_pool, token_account, AIRDROP_LAMPORTS // 2) for validator in validators: - await add_validator_to_pool(async_client, payer, stake_pool_addresses[0], validator) + await add_validator_to_pool(async_client, payer, stake_pool, validator) return stake_pool_addresses @@ -80,8 +89,7 @@ async def async_client(solana_test_validator) -> AsyncIterator[AsyncClient]: @pytest_asyncio.fixture async def payer(async_client) -> Keypair: payer = Keypair() - airdrop_lamports = 20_000_000_000 - await airdrop(async_client, payer.public_key, airdrop_lamports) + await airdrop(async_client, payer.public_key, AIRDROP_LAMPORTS) return payer diff --git a/clients/py/tests/test_a_time_sensitive.py b/clients/py/tests/test_a_time_sensitive.py index abac2005..4b9164cf 100644 --- a/clients/py/tests/test_a_time_sensitive.py +++ b/clients/py/tests/test_a_time_sensitive.py @@ -12,10 +12,11 @@ @pytest.mark.asyncio async def test_increase_decrease_this_is_very_slow(async_client, validators, payer, stake_pool_addresses, waiter): - (stake_pool_address, validator_list_address) = stake_pool_addresses + (stake_pool_address, validator_list_address, _) = stake_pool_addresses resp = await async_client.get_minimum_balance_for_rent_exemption(STAKE_LEN) stake_rent_exemption = resp['result'] + minimum_amount = MINIMUM_ACTIVE_STAKE + stake_rent_exemption increase_amount = MINIMUM_ACTIVE_STAKE * 4 decrease_amount = increase_amount // 2 deposit_amount = (increase_amount + stake_rent_exemption) * len(validators) @@ -38,7 +39,7 @@ async def test_increase_decrease_this_is_very_slow(async_client, validators, pay validator_list = ValidatorList.decode(data[0], data[1]) for validator in validator_list.validators: assert validator.transient_stake_lamports == increase_amount + stake_rent_exemption - assert validator.active_stake_lamports == 0 + assert validator.active_stake_lamports == minimum_amount print("Waiting for epoch to roll over") await waiter.wait_for_next_epoch(async_client) @@ -50,7 +51,7 @@ async def test_increase_decrease_this_is_very_slow(async_client, validators, pay for validator in validator_list.validators: assert validator.last_update_epoch != 0 assert validator.transient_stake_lamports == 0 - assert validator.active_stake_lamports == increase_amount # rent exemption brought back to reserve + assert validator.active_stake_lamports == increase_amount + minimum_amount # decrease from all futures = [ @@ -64,7 +65,7 @@ async def test_increase_decrease_this_is_very_slow(async_client, validators, pay validator_list = ValidatorList.decode(data[0], data[1]) for validator in validator_list.validators: assert validator.transient_stake_lamports == decrease_amount - assert validator.active_stake_lamports == increase_amount - decrease_amount + assert validator.active_stake_lamports == increase_amount - decrease_amount + minimum_amount print("Waiting for epoch to roll over") await waiter.wait_for_next_epoch(async_client) @@ -75,4 +76,4 @@ async def test_increase_decrease_this_is_very_slow(async_client, validators, pay validator_list = ValidatorList.decode(data[0], data[1]) for validator in validator_list.validators: assert validator.transient_stake_lamports == 0 - assert validator.active_stake_lamports == increase_amount - decrease_amount + assert validator.active_stake_lamports == increase_amount - decrease_amount + minimum_amount diff --git a/clients/py/tests/test_add_remove.py b/clients/py/tests/test_add_remove.py index 5937a229..b2d96af3 100644 --- a/clients/py/tests/test_add_remove.py +++ b/clients/py/tests/test_add_remove.py @@ -2,21 +2,25 @@ import pytest from solana.rpc.commitment import Confirmed -from stake_pool.state import ValidatorList, StakeStatus +from stake.constants import STAKE_LEN from stake_pool.actions import remove_validator_from_pool +from stake_pool.constants import MINIMUM_ACTIVE_STAKE +from stake_pool.state import ValidatorList, StakeStatus @pytest.mark.asyncio async def test_add_remove_validators(async_client, validators, payer, stake_pool_addresses): - (stake_pool_address, validator_list_address) = stake_pool_addresses + (stake_pool_address, validator_list_address, _) = stake_pool_addresses resp = await async_client.get_account_info(validator_list_address, commitment=Confirmed) data = resp['result']['value']['data'] validator_list = ValidatorList.decode(data[0], data[1]) assert len(validator_list.validators) == len(validators) + resp = await async_client.get_minimum_balance_for_rent_exemption(STAKE_LEN) + stake_rent_exemption = resp['result'] futures = [] for validator_info in validator_list.validators: assert validator_info.vote_account_address in validators - assert validator_info.active_stake_lamports == 0 + assert validator_info.active_stake_lamports == stake_rent_exemption + MINIMUM_ACTIVE_STAKE assert validator_info.transient_stake_lamports == 0 assert validator_info.status == StakeStatus.ACTIVE futures.append( @@ -28,4 +32,4 @@ async def test_add_remove_validators(async_client, validators, payer, stake_pool data = resp['result']['value']['data'] validator_list = ValidatorList.decode(data[0], data[1]) for validator_info in validator_list.validators: - assert validator_info.status == StakeStatus.READY_FOR_REMOVAL + assert validator_info.status == StakeStatus.DEACTIVATING_VALIDATOR diff --git a/clients/py/tests/test_bot_rebalance.py b/clients/py/tests/test_bot_rebalance.py index e9c32e02..548a2ac7 100644 --- a/clients/py/tests/test_bot_rebalance.py +++ b/clients/py/tests/test_bot_rebalance.py @@ -16,18 +16,20 @@ @pytest.mark.asyncio async def test_rebalance_this_is_very_slow(async_client, validators, payer, stake_pool_addresses, waiter): - (stake_pool_address, validator_list_address) = stake_pool_addresses + (stake_pool_address, validator_list_address, _) = stake_pool_addresses resp = await async_client.get_minimum_balance_for_rent_exemption(STAKE_LEN) stake_rent_exemption = resp['result'] # With minimum delegation at MINIMUM_DELEGATION + rent-exemption, when # decreasing, we'll need rent exemption + minimum delegation delegated to # cover all movements + minimum_amount = MINIMUM_ACTIVE_STAKE + stake_rent_exemption increase_amount = MINIMUM_ACTIVE_STAKE + stake_rent_exemption deposit_amount = (increase_amount + stake_rent_exemption) * len(validators) resp = await async_client.get_account_info(stake_pool_address, commitment=Confirmed) data = resp['result']['value']['data'] stake_pool = StakePool.decode(data[0], data[1]) + total_lamports = stake_pool.total_lamports + deposit_amount token_account = get_associated_token_address(payer.public_key, stake_pool.pool_mint) await deposit_sol(async_client, payer, stake_pool_address, token_account, deposit_amount) @@ -43,13 +45,14 @@ async def test_rebalance_this_is_very_slow(async_client, validators, payer, stak data = resp['result']['value']['data'] validator_list = ValidatorList.decode(data[0], data[1]) for validator in validator_list.validators: - assert validator.active_stake_lamports == 0 - assert validator.transient_stake_lamports == increase_amount + stake_rent_exemption + assert validator.active_stake_lamports == minimum_amount + assert validator.transient_stake_lamports == total_lamports / len(validators) - minimum_amount # Test case 2: Decrease everything back to reserve print('Waiting for next epoch') await waiter.wait_for_next_epoch(async_client) - await rebalance(ENDPOINT, stake_pool_address, payer, deposit_amount / LAMPORTS_PER_SOL) + max_in_reserve = total_lamports - minimum_amount * len(validators) + await rebalance(ENDPOINT, stake_pool_address, payer, max_in_reserve / LAMPORTS_PER_SOL) # should still only have minimum left + rent exemptions from increase resp = await async_client.get_account_info(stake_pool.reserve_stake, commitment=Confirmed) @@ -61,23 +64,23 @@ async def test_rebalance_this_is_very_slow(async_client, validators, payer, stak data = resp['result']['value']['data'] validator_list = ValidatorList.decode(data[0], data[1]) for validator in validator_list.validators: - assert validator.active_stake_lamports == 0 - assert validator.transient_stake_lamports == increase_amount + assert validator.active_stake_lamports == minimum_amount + assert validator.transient_stake_lamports == max_in_reserve / len(validators) - stake_rent_exemption # Test case 3: Do nothing print('Waiting for next epoch') await waiter.wait_for_next_epoch(async_client) - await rebalance(ENDPOINT, stake_pool_address, payer, deposit_amount / LAMPORTS_PER_SOL) + await rebalance(ENDPOINT, stake_pool_address, payer, max_in_reserve / LAMPORTS_PER_SOL) # should still only have minimum left + rent exemptions from increase resp = await async_client.get_account_info(stake_pool.reserve_stake, commitment=Confirmed) reserve_lamports = resp['result']['value']['lamports'] - assert reserve_lamports == stake_rent_exemption + deposit_amount + MINIMUM_RESERVE_LAMPORTS + assert reserve_lamports == stake_rent_exemption + max_in_reserve + MINIMUM_RESERVE_LAMPORTS - # should all be decreasing now + # should all be decreased now resp = await async_client.get_account_info(validator_list_address, commitment=Confirmed) data = resp['result']['value']['data'] validator_list = ValidatorList.decode(data[0], data[1]) for validator in validator_list.validators: - assert validator.active_stake_lamports == 0 + assert validator.active_stake_lamports == minimum_amount assert validator.transient_stake_lamports == 0 diff --git a/clients/py/tests/test_deposit_withdraw_sol.py b/clients/py/tests/test_deposit_withdraw_sol.py index c61a353f..8057101e 100644 --- a/clients/py/tests/test_deposit_withdraw_sol.py +++ b/clients/py/tests/test_deposit_withdraw_sol.py @@ -1,5 +1,5 @@ import pytest -from solana.rpc.commitment import Confirmed +from solana.rpc.commitment import Confirmed, Processed from solana.keypair import Keypair from spl.token.instructions import get_associated_token_address @@ -11,7 +11,7 @@ async def test_deposit_withdraw_sol(async_client, payer): fee = Fee(numerator=1, denominator=1000) referral_fee = 20 - (stake_pool_address, validator_list_address) = await create_all(async_client, payer, fee, referral_fee) + (stake_pool_address, validator_list_address, _) = await create_all(async_client, payer, fee, referral_fee) resp = await async_client.get_account_info(stake_pool_address, commitment=Confirmed) data = resp['result']['value']['data'] stake_pool = StakePool.decode(data[0], data[1]) @@ -22,5 +22,6 @@ async def test_deposit_withdraw_sol(async_client, payer): assert pool_token_balance['result']['value']['amount'] == str(deposit_amount) recipient = Keypair() await withdraw_sol(async_client, payer, token_account, stake_pool_address, recipient.public_key, deposit_amount) - pool_token_balance = await async_client.get_token_account_balance(token_account, Confirmed) + # for some reason, this is not always in sync when running all tests + pool_token_balance = await async_client.get_token_account_balance(token_account, Processed) assert pool_token_balance['result']['value']['amount'] == str('0') diff --git a/clients/py/tests/test_deposit_withdraw_stake.py b/clients/py/tests/test_deposit_withdraw_stake.py index 896960dc..1580db24 100644 --- a/clients/py/tests/test_deposit_withdraw_stake.py +++ b/clients/py/tests/test_deposit_withdraw_stake.py @@ -13,7 +13,7 @@ @pytest.mark.asyncio async def test_deposit_withdraw_stake(async_client, validators, payer, stake_pool_addresses, waiter): - (stake_pool_address, validator_list_address) = stake_pool_addresses + (stake_pool_address, validator_list_address, _) = stake_pool_addresses resp = await async_client.get_account_info(stake_pool_address, commitment=Confirmed) data = resp['result']['value']['data'] stake_pool = StakePool.decode(data[0], data[1]) @@ -26,18 +26,20 @@ async def test_deposit_withdraw_stake(async_client, validators, payer, stake_poo resp = await async_client.get_account_info(stake, commitment=Confirmed) data = resp['result']['value']['data'] stake_state = StakeState.decode(data[0], data[1]) + token_account = get_associated_token_address(payer.public_key, stake_pool.pool_mint) + pre_pool_token_balance = await async_client.get_token_account_balance(token_account, Confirmed) + pre_pool_token_balance = int(pre_pool_token_balance['result']['value']['amount']) print(stake_state) await waiter.wait_for_next_epoch(async_client) await update_stake_pool(async_client, payer, stake_pool_address) - token_account = get_associated_token_address(payer.public_key, stake_pool.pool_mint) await deposit_stake(async_client, payer, stake_pool_address, validator, stake, token_account) pool_token_balance = await async_client.get_token_account_balance(token_account, Confirmed) pool_token_balance = pool_token_balance['result']['value']['amount'] resp = await async_client.get_minimum_balance_for_rent_exemption(STAKE_LEN) stake_rent_exemption = resp['result'] - assert pool_token_balance == str(stake_amount + stake_rent_exemption) + assert pool_token_balance == str(stake_amount + stake_rent_exemption + pre_pool_token_balance) destination_stake = Keypair() await withdraw_stake( @@ -47,4 +49,4 @@ async def test_deposit_withdraw_stake(async_client, validators, payer, stake_poo pool_token_balance = await async_client.get_token_account_balance(token_account, Confirmed) pool_token_balance = pool_token_balance['result']['value']['amount'] - assert pool_token_balance == str(stake_rent_exemption) + assert pool_token_balance == str(stake_rent_exemption + pre_pool_token_balance) diff --git a/program/Cargo.toml b/program/Cargo.toml index 1ab55f01..6b57263f 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -22,7 +22,7 @@ serde = "1.0.130" serde_derive = "1.0.103" solana-program = "1.14.6" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } -spl-token = { version = "3.5", path = "../../token/program", features = [ "no-entrypoint" ] } +spl-token-2022 = { version = "0.4", path = "../../token/program-2022", features = [ "no-entrypoint" ] } thiserror = "1.0" bincode = "1.3.1" @@ -31,6 +31,8 @@ proptest = "1.0" solana-program-test = "1.14.6" solana-sdk = "1.14.6" solana-vote-program = "1.14.6" +spl-token = { version = "3.5", path = "../../token/program", features = [ "no-entrypoint" ] } +test-case = "2.2" [lib] crate-type = ["cdylib", "lib"] diff --git a/program/src/error.rs b/program/src/error.rs index 908b947d..6efcb389 100644 --- a/program/src/error.rs +++ b/program/src/error.rs @@ -135,6 +135,12 @@ pub enum StakePoolError { /// Provided metadata account does not match metadata account derived for pool mint #[error("InvalidMetadataAccount")] InvalidMetadataAccount, + /// The mint has an unsupported extension + #[error("UnsupportedMintExtension")] + UnsupportedMintExtension, + /// The fee account has an unsupported extension + #[error("UnsupportedFeeAccountExtension")] + UnsupportedFeeAccountExtension, } impl From for ProgramError { fn from(e: StakePoolError) -> Self { diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 4a11e759..799bf03e 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -16,6 +16,7 @@ use { pubkey::Pubkey, stake, system_program, sysvar, }, + std::num::NonZeroU32, }; /// Defines which validator vote account is set during the @@ -44,7 +45,7 @@ pub enum FundingType { /// Instructions supported by the StakePool program. #[repr(C)] -#[derive(Clone, Debug, PartialEq, BorshSerialize, BorshDeserialize, BorshSchema)] +#[derive(Clone, Debug, PartialEq, BorshSerialize, BorshDeserialize)] pub enum StakePoolInstruction { /// Initializes a new StakePool. /// @@ -84,10 +85,11 @@ pub enum StakePoolInstruction { /// /// The stake account will have the rent-exempt amount plus /// `max(crate::MINIMUM_ACTIVE_STAKE, solana_program::stake::tools::get_minimum_delegation())`. + /// It is funded from the stake pool reserve. /// /// 0. `[w]` Stake pool /// 1. `[s]` Staker - /// 2. `[ws]` Funding account (must be a system account) + /// 2. `[w]` Reserve stake account /// 3. `[]` Stake pool withdraw authority /// 4. `[w]` Validator stake list storage account /// 5. `[w]` Stake account to add to the pool @@ -98,9 +100,12 @@ pub enum StakePoolInstruction { /// 10. '[]' Stake config sysvar /// 11. `[]` System program /// 12. `[]` Stake program - AddValidatorToPool, + /// + /// userdata: optional non-zero u32 seed used for generating the validator + /// stake address + AddValidatorToPool(u32), - /// (Staker only) Removes validator from the pool + /// (Staker only) Removes validator from the pool, deactivating its stake /// /// Only succeeds if the validator stake account has the minimum of /// `max(crate::MINIMUM_ACTIVE_STAKE, solana_program::stake::tools::get_minimum_delegation())`. @@ -109,13 +114,11 @@ pub enum StakePoolInstruction { /// 0. `[w]` Stake pool /// 1. `[s]` Staker /// 2. `[]` Stake pool withdraw authority - /// 3. `[]` New withdraw/staker authority to set in the stake account - /// 4. `[w]` Validator stake list storage account - /// 5. `[w]` Stake account to remove from the pool - /// 6. `[]` Transient stake account, to check that that we're not trying to activate - /// 7. `[w]` Destination stake account, to receive the minimum SOL from the validator stake account - /// 8. `[]` Sysvar clock - /// 9. `[]` Stake program id, + /// 3. `[w]` Validator stake list storage account + /// 4. `[w]` Stake account to remove from the pool + /// 5. `[]` Transient stake account, to check that that we're not trying to activate + /// 6. `[]` Sysvar clock + /// 7. `[]` Stake program id, RemoveValidatorFromPool, /// (Staker only) Decrease active stake on a validator, eventually moving it to the reserve @@ -288,12 +291,12 @@ pub enum StakePoolInstruction { /// * preferred withdraw validator stake account (if set) /// * validator stake accounts /// * transient stake accounts - /// * reserve stake account + /// * reserve stake account OR totally remove validator stake accounts /// /// A user can freely withdraw from a validator stake account, and if they /// are all at the minimum, then they can withdraw from transient stake /// accounts, and if they are all at minimum, then they can withdraw from - /// the reserve. + /// the reserve or remove any validator from the pool. /// /// 0. `[w]` Stake pool /// 1. `[w]` Validator stake list storage account @@ -473,16 +476,17 @@ pub fn add_validator_to_pool( program_id: &Pubkey, stake_pool: &Pubkey, staker: &Pubkey, - funder: &Pubkey, + reserve: &Pubkey, stake_pool_withdraw: &Pubkey, validator_list: &Pubkey, stake: &Pubkey, validator: &Pubkey, + seed: Option, ) -> Instruction { let accounts = vec![ AccountMeta::new(*stake_pool, false), AccountMeta::new_readonly(*staker, true), - AccountMeta::new(*funder, true), + AccountMeta::new(*reserve, false), AccountMeta::new_readonly(*stake_pool_withdraw, false), AccountMeta::new(*validator_list, false), AccountMeta::new(*stake, false), @@ -494,12 +498,13 @@ pub fn add_validator_to_pool( AccountMeta::new_readonly(system_program::id(), false), AccountMeta::new_readonly(stake::program::id(), false), ]; + let data = StakePoolInstruction::AddValidatorToPool(seed.map(|s| s.get()).unwrap_or(0)) + .try_to_vec() + .unwrap(); Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::AddValidatorToPool - .try_to_vec() - .unwrap(), + data, } } @@ -509,21 +514,17 @@ pub fn remove_validator_from_pool( stake_pool: &Pubkey, staker: &Pubkey, stake_pool_withdraw: &Pubkey, - new_stake_authority: &Pubkey, validator_list: &Pubkey, stake_account: &Pubkey, transient_stake_account: &Pubkey, - destination_stake_account: &Pubkey, ) -> Instruction { let accounts = vec![ AccountMeta::new(*stake_pool, false), AccountMeta::new_readonly(*staker, true), AccountMeta::new_readonly(*stake_pool_withdraw, false), - AccountMeta::new_readonly(*new_stake_authority, false), AccountMeta::new(*validator_list, false), AccountMeta::new(*stake_account, false), AccountMeta::new_readonly(*transient_stake_account, false), - AccountMeta::new(*destination_stake_account, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(stake::program::id(), false), ]; @@ -647,22 +648,23 @@ pub fn add_validator_to_pool_with_vote( program_id: &Pubkey, stake_pool: &StakePool, stake_pool_address: &Pubkey, - funder: &Pubkey, vote_account_address: &Pubkey, + seed: Option, ) -> Instruction { let pool_withdraw_authority = find_withdraw_authority_program_address(program_id, stake_pool_address).0; let (stake_account_address, _) = - find_stake_program_address(program_id, vote_account_address, stake_pool_address); + find_stake_program_address(program_id, vote_account_address, stake_pool_address, seed); add_validator_to_pool( program_id, stake_pool_address, &stake_pool.staker, - funder, + &stake_pool.reserve_stake, &pool_withdraw_authority, &stake_pool.validator_list, &stake_account_address, vote_account_address, + seed, ) } @@ -673,14 +675,17 @@ pub fn remove_validator_from_pool_with_vote( stake_pool: &StakePool, stake_pool_address: &Pubkey, vote_account_address: &Pubkey, - new_stake_account_authority: &Pubkey, + validator_stake_seed: Option, transient_stake_seed: u64, - destination_stake_address: &Pubkey, ) -> Instruction { let pool_withdraw_authority = find_withdraw_authority_program_address(program_id, stake_pool_address).0; - let (stake_account_address, _) = - find_stake_program_address(program_id, vote_account_address, stake_pool_address); + let (stake_account_address, _) = find_stake_program_address( + program_id, + vote_account_address, + stake_pool_address, + validator_stake_seed, + ); let (transient_stake_account, _) = find_transient_stake_program_address( program_id, vote_account_address, @@ -692,11 +697,9 @@ pub fn remove_validator_from_pool_with_vote( stake_pool_address, &stake_pool.staker, &pool_withdraw_authority, - new_stake_account_authority, &stake_pool.validator_list, &stake_account_address, &transient_stake_account, - destination_stake_address, ) } @@ -708,6 +711,7 @@ pub fn increase_validator_stake_with_vote( stake_pool_address: &Pubkey, vote_account_address: &Pubkey, lamports: u64, + validator_stake_seed: Option, transient_stake_seed: u64, ) -> Instruction { let pool_withdraw_authority = @@ -718,8 +722,12 @@ pub fn increase_validator_stake_with_vote( stake_pool_address, transient_stake_seed, ); - let (validator_stake_address, _) = - find_stake_program_address(program_id, vote_account_address, stake_pool_address); + let (validator_stake_address, _) = find_stake_program_address( + program_id, + vote_account_address, + stake_pool_address, + validator_stake_seed, + ); increase_validator_stake( program_id, @@ -744,12 +752,17 @@ pub fn decrease_validator_stake_with_vote( stake_pool_address: &Pubkey, vote_account_address: &Pubkey, lamports: u64, + validator_stake_seed: Option, transient_stake_seed: u64, ) -> Instruction { let pool_withdraw_authority = find_withdraw_authority_program_address(program_id, stake_pool_address).0; - let (validator_stake_address, _) = - find_stake_program_address(program_id, vote_account_address, stake_pool_address); + let (validator_stake_address, _) = find_stake_program_address( + program_id, + vote_account_address, + stake_pool_address, + validator_stake_seed, + ); let (transient_stake_address, _) = find_transient_stake_program_address( program_id, vote_account_address, @@ -796,13 +809,17 @@ pub fn update_validator_list_balance( .flat_map(|vote_account_address| { let validator_stake_info = validator_list.find(vote_account_address); if let Some(validator_stake_info) = validator_stake_info { - let (validator_stake_account, _) = - find_stake_program_address(program_id, vote_account_address, stake_pool); + let (validator_stake_account, _) = find_stake_program_address( + program_id, + vote_account_address, + stake_pool, + NonZeroU32::new(validator_stake_info.validator_seed_suffix), + ); let (transient_stake_account, _) = find_transient_stake_program_address( program_id, vote_account_address, stake_pool, - validator_stake_info.transient_seed_suffix_start, + validator_stake_info.transient_seed_suffix, ); vec![ AccountMeta::new(validator_stake_account, false), diff --git a/program/src/lib.rs b/program/src/lib.rs index 0cca0342..940dc4c2 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -17,6 +17,7 @@ pub use solana_program; use { crate::state::Fee, solana_program::{pubkey::Pubkey, stake::state::Meta}, + std::num::NonZeroU32, }; /// Seed for deposit authority seed @@ -28,11 +29,11 @@ const AUTHORITY_WITHDRAW: &[u8] = b"withdraw"; /// Seed for transient stake account const TRANSIENT_STAKE_SEED_PREFIX: &[u8] = b"transient"; -/// Minimum amount of staked SOL required in a validator stake account to allow +/// Minimum amount of staked lamports required in a validator stake account to allow /// for merges without a mismatch on credits observed pub const MINIMUM_ACTIVE_STAKE: u64 = 1_000_000; -/// Minimum amount of SOL in the reserve +/// Minimum amount of lamports in the reserve /// NOTE: This can be changed to 0 once the `stake_allow_zero_undelegated_amount` /// feature is enabled on all clusters pub const MINIMUM_RESERVE_LAMPORTS: u64 = 1; @@ -86,7 +87,7 @@ pub fn find_deposit_authority_program_address( stake_pool_address: &Pubkey, ) -> (Pubkey, u8) { Pubkey::find_program_address( - &[&stake_pool_address.to_bytes()[..32], AUTHORITY_DEPOSIT], + &[stake_pool_address.as_ref(), AUTHORITY_DEPOSIT], program_id, ) } @@ -97,7 +98,7 @@ pub fn find_withdraw_authority_program_address( stake_pool_address: &Pubkey, ) -> (Pubkey, u8) { Pubkey::find_program_address( - &[&stake_pool_address.to_bytes(), AUTHORITY_WITHDRAW], + &[stake_pool_address.as_ref(), AUTHORITY_WITHDRAW], program_id, ) } @@ -107,11 +108,14 @@ pub fn find_stake_program_address( program_id: &Pubkey, vote_account_address: &Pubkey, stake_pool_address: &Pubkey, + seed: Option, ) -> (Pubkey, u8) { + let seed = seed.map(|s| s.get().to_le_bytes()); Pubkey::find_program_address( &[ - &vote_account_address.to_bytes(), - &stake_pool_address.to_bytes(), + vote_account_address.as_ref(), + stake_pool_address.as_ref(), + seed.as_ref().map(|s| s.as_slice()).unwrap_or(&[]), ], program_id, ) @@ -127,8 +131,8 @@ pub fn find_transient_stake_program_address( Pubkey::find_program_address( &[ TRANSIENT_STAKE_SEED_PREFIX, - &vote_account_address.to_bytes(), - &stake_pool_address.to_bytes(), + vote_account_address.as_ref(), + stake_pool_address.as_ref(), &seed.to_le_bytes(), ], program_id, @@ -136,3 +140,18 @@ pub fn find_transient_stake_program_address( } solana_program::declare_id!("SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy"); + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn validator_stake_account_derivation() { + let vote = Pubkey::new_unique(); + let stake_pool = Pubkey::new_unique(); + let function_derived = find_stake_program_address(&id(), &vote, &stake_pool, None); + let hand_derived = + Pubkey::find_program_address(&[vote.as_ref(), stake_pool.as_ref()], &id()); + assert_eq!(function_derived, hand_derived); + } +} diff --git a/program/src/processor.rs b/program/src/processor.rs index 15d011b6..1d0025ca 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -7,8 +7,8 @@ use { instruction::{FundingType, PreferredValidatorType, StakePoolInstruction}, minimum_delegation, minimum_reserve_lamports, minimum_stake_lamports, state::{ - AccountType, Fee, FeeType, StakePool, StakeStatus, ValidatorList, ValidatorListHeader, - ValidatorStakeInfo, + is_extension_supported_for_mint, AccountType, Fee, FeeType, StakePool, StakeStatus, + StakeWithdrawSource, ValidatorList, ValidatorListHeader, ValidatorStakeInfo, }, AUTHORITY_DEPOSIT, AUTHORITY_WITHDRAW, TRANSIENT_STAKE_SEED_PREFIX, }, @@ -28,13 +28,17 @@ use { msg, program::{invoke, invoke_signed}, program_error::{PrintProgramError, ProgramError}, - program_pack::Pack, pubkey::Pubkey, rent::Rent, stake, system_instruction, system_program, sysvar::Sysvar, }, - spl_token::state::Mint, + spl_token_2022::{ + check_spl_token_program_account, + extension::{BaseStateWithExtensions, StateWithExtensions}, + state::Mint, + }, + std::num::NonZeroU32, }; /// Deserialize the stake state from AccountInfo @@ -55,10 +59,11 @@ fn check_validator_stake_address( stake_pool_address: &Pubkey, stake_account_address: &Pubkey, vote_address: &Pubkey, + seed: Option, ) -> Result<(), ProgramError> { // Check stake account address validity let (validator_stake_address, _) = - crate::find_stake_program_address(program_id, vote_address, stake_pool_address); + crate::find_stake_program_address(program_id, vote_address, stake_pool_address, seed); if validator_stake_address != *stake_account_address { msg!( "Incorrect stake account address for vote {}, expected {}, received {}", @@ -191,83 +196,34 @@ fn stake_is_usable_by_pool( && meta.lockup == *expected_lockup } -/// Create a transient stake account without transferring lamports -fn create_transient_stake_account<'a>( - transient_stake_account_info: AccountInfo<'a>, - transient_stake_account_signer_seeds: &[&[u8]], +/// Checks if a stake acount is active, without taking into account cooldowns +fn stake_is_inactive_without_history(stake: &stake::state::Stake, epoch: Epoch) -> bool { + stake.delegation.deactivation_epoch < epoch + || (stake.delegation.activation_epoch == epoch + && stake.delegation.deactivation_epoch == epoch) +} + +/// Create a stake account on a PDA without transferring lamports +fn create_stake_account<'a>( + stake_account_info: AccountInfo<'a>, + stake_account_signer_seeds: &[&[u8]], system_program_info: AccountInfo<'a>, ) -> Result<(), ProgramError> { invoke_signed( &system_instruction::allocate( - transient_stake_account_info.key, + stake_account_info.key, std::mem::size_of::() as u64, ), - &[ - transient_stake_account_info.clone(), - system_program_info.clone(), - ], - &[transient_stake_account_signer_seeds], + &[stake_account_info.clone(), system_program_info.clone()], + &[stake_account_signer_seeds], )?; invoke_signed( - &system_instruction::assign(transient_stake_account_info.key, &stake::program::id()), - &[transient_stake_account_info, system_program_info], - &[transient_stake_account_signer_seeds], + &system_instruction::assign(stake_account_info.key, &stake::program::id()), + &[stake_account_info, system_program_info], + &[stake_account_signer_seeds], ) } -/// Create an account on a program-derived address -fn create_pda_account<'a>( - payer: &AccountInfo<'a>, - required_lamports: u64, - space: usize, - owner: &Pubkey, - system_program: &AccountInfo<'a>, - new_pda_account: &AccountInfo<'a>, - new_pda_signer_seeds: &[&[u8]], -) -> ProgramResult { - if new_pda_account.lamports() > 0 { - let required_lamports = required_lamports.saturating_sub(new_pda_account.lamports()); - if required_lamports > 0 { - invoke( - &system_instruction::transfer(payer.key, new_pda_account.key, required_lamports), - &[ - payer.clone(), - new_pda_account.clone(), - system_program.clone(), - ], - )?; - } - - invoke_signed( - &system_instruction::allocate(new_pda_account.key, space as u64), - &[new_pda_account.clone(), system_program.clone()], - &[new_pda_signer_seeds], - )?; - - invoke_signed( - &system_instruction::assign(new_pda_account.key, owner), - &[new_pda_account.clone(), system_program.clone()], - &[new_pda_signer_seeds], - ) - } else { - invoke_signed( - &system_instruction::create_account( - payer.key, - new_pda_account.key, - required_lamports, - space as u64, - owner, - ), - &[ - payer.clone(), - new_pda_account.clone(), - system_program.clone(), - ], - &[new_pda_signer_seeds], - ) - } -} - /// Program state handler. pub struct Processor {} impl Processor { @@ -523,7 +479,7 @@ impl Processor { authority: AccountInfo<'a>, amount: u64, ) -> Result<(), ProgramError> { - let ix = spl_token::instruction::burn( + let ix = spl_token_2022::instruction::burn( token_program.key, burn_account.key, mint.key, @@ -551,7 +507,7 @@ impl Processor { let authority_signature_seeds = [&me_bytes[..32], authority_type, &[bump_seed]]; let signers = &[&authority_signature_seeds[..]]; - let ix = spl_token::instruction::mint_to( + let ix = spl_token_2022::instruction::mint_to( token_program.key, mint.key, destination.key, @@ -568,19 +524,23 @@ impl Processor { fn token_transfer<'a>( token_program: AccountInfo<'a>, source: AccountInfo<'a>, + mint: AccountInfo<'a>, destination: AccountInfo<'a>, authority: AccountInfo<'a>, amount: u64, + decimals: u8, ) -> Result<(), ProgramError> { - let ix = spl_token::instruction::transfer( + let ix = spl_token_2022::instruction::transfer_checked( token_program.key, source.key, + mint.key, destination.key, authority.key, &[], amount, + decimals, )?; - invoke(&ix, &[source, destination, authority, token_program]) + invoke(&ix, &[source, mint, destination, authority, token_program]) } fn sol_transfer<'a>( @@ -678,28 +638,14 @@ impl Processor { return Err(StakePoolError::FeeTooHigh.into()); } - if *token_program_info.key != spl_token::id() { - msg!( - "Only the SPL token program is currently supported, expected {}, received {}", - spl_token::id(), - *token_program_info.key - ); - return Err(ProgramError::IncorrectProgramId); - } - - if manager_fee_info.owner != token_program_info.key { - return Err(ProgramError::IncorrectProgramId); - } + check_spl_token_program_account(token_program_info.key)?; if pool_mint_info.owner != token_program_info.key { return Err(ProgramError::IncorrectProgramId); } - if *pool_mint_info.key - != spl_token::state::Account::unpack_from_slice(&manager_fee_info.data.borrow())?.mint - { - return Err(StakePoolError::WrongAccountMint.into()); - } + stake_pool.token_program_id = *token_program_info.key; + stake_pool.pool_mint = *pool_mint_info.key; let (stake_deposit_authority, sol_deposit_authority) = match next_account_info(account_info_iter) { @@ -723,19 +669,35 @@ impl Processor { return Err(StakePoolError::InvalidProgramAddress.into()); } - let pool_mint = Mint::unpack_from_slice(&pool_mint_info.data.borrow())?; + { + let pool_mint_data = pool_mint_info.try_borrow_data()?; + let pool_mint = StateWithExtensions::::unpack(&pool_mint_data)?; - if pool_mint.supply != 0 { - return Err(StakePoolError::NonZeroPoolTokenSupply.into()); - } + if pool_mint.base.supply != 0 { + return Err(StakePoolError::NonZeroPoolTokenSupply.into()); + } - if !pool_mint.mint_authority.contains(&withdraw_authority_key) { - return Err(StakePoolError::WrongMintingAuthority.into()); - } + if !pool_mint + .base + .mint_authority + .contains(&withdraw_authority_key) + { + return Err(StakePoolError::WrongMintingAuthority.into()); + } - if pool_mint.freeze_authority.is_some() { - return Err(StakePoolError::InvalidMintFreezeAuthority.into()); + if pool_mint.base.freeze_authority.is_some() { + return Err(StakePoolError::InvalidMintFreezeAuthority.into()); + } + + let extensions = pool_mint.get_extension_types()?; + if extensions + .iter() + .any(|x| !is_extension_supported_for_mint(x)) + { + return Err(StakePoolError::UnsupportedMintExtension.into()); + } } + stake_pool.check_manager_fee_info(manager_fee_info)?; if *reserve_stake_info.owner != stake::program::id() { msg!("Reserve stake account not owned by stake program"); @@ -798,9 +760,7 @@ impl Processor { stake_pool.stake_withdraw_bump_seed = stake_withdraw_bump_seed; stake_pool.validator_list = *validator_list_info.key; stake_pool.reserve_stake = *reserve_stake_info.key; - stake_pool.pool_mint = *pool_mint_info.key; stake_pool.manager_fee_account = *manager_fee_info.key; - stake_pool.token_program_id = *token_program_info.key; stake_pool.total_lamports = total_lamports; stake_pool.pool_token_supply = total_lamports; stake_pool.last_update_epoch = Clock::get()?.epoch; @@ -832,11 +792,12 @@ impl Processor { fn process_add_validator_to_pool( program_id: &Pubkey, accounts: &[AccountInfo], + raw_validator_seed: u32, ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; let staker_info = next_account_info(account_info_iter)?; - let funder_info = next_account_info(account_info_iter)?; + let reserve_stake_info = next_account_info(account_info_iter)?; let withdraw_authority_info = next_account_info(account_info_iter)?; let validator_list_info = next_account_info(account_info_iter)?; let stake_info = next_account_info(account_info_iter)?; @@ -866,6 +827,7 @@ impl Processor { )?; stake_pool.check_staker(staker_info)?; + stake_pool.check_reserve_stake(reserve_stake_info)?; stake_pool.check_validator_list(validator_list_info)?; if stake_pool.last_update_epoch < clock.epoch { @@ -890,18 +852,25 @@ impl Processor { return Err(StakePoolError::ValidatorAlreadyAdded.into()); } + let validator_seed = NonZeroU32::new(raw_validator_seed); let (stake_address, bump_seed) = crate::find_stake_program_address( program_id, validator_vote_info.key, stake_pool_info.key, + validator_seed, ); if stake_address != *stake_info.key { return Err(StakePoolError::InvalidStakeAccountAddress.into()); } + let validator_seed_bytes = validator_seed.map(|s| s.get().to_le_bytes()); let stake_account_signer_seeds: &[&[_]] = &[ - &validator_vote_info.key.to_bytes()[..32], - &stake_pool_info.key.to_bytes()[..32], + validator_vote_info.key.as_ref(), + stake_pool_info.key.as_ref(), + validator_seed_bytes + .as_ref() + .map(|s| s.as_slice()) + .unwrap_or(&[]), &[bump_seed], ]; @@ -911,30 +880,39 @@ impl Processor { let required_lamports = minimum_delegation(stake_minimum_delegation) .saturating_add(rent.minimum_balance(space)); + // Check that we're not draining the reserve totally + let reserve_stake = try_from_slice_unchecked::( + &reserve_stake_info.data.borrow(), + )?; + let reserve_meta = reserve_stake + .meta() + .ok_or(StakePoolError::WrongStakeState)?; + let minimum_lamports = minimum_reserve_lamports(&reserve_meta); + let reserve_lamports = reserve_stake_info.lamports(); + if reserve_lamports.saturating_sub(required_lamports) < minimum_lamports { + msg!( + "Need to add {} lamports for the reserve stake to be rent-exempt after adding a validator, reserve currently has {} lamports", + required_lamports.saturating_add(minimum_lamports).saturating_sub(reserve_lamports), + reserve_lamports + ); + return Err(ProgramError::InsufficientFunds); + } + // Create new stake account - create_pda_account( - funder_info, - required_lamports, - space, - &stake::program::id(), - system_program_info, - stake_info, + create_stake_account( + stake_info.clone(), stake_account_signer_seeds, + system_program_info.clone(), )?; - invoke( - &stake::instruction::initialize( - stake_info.key, - &stake::state::Authorized { - staker: *withdraw_authority_info.key, - withdrawer: *withdraw_authority_info.key, - }, - &stake::state::Lockup::default(), - ), - &[ - stake_info.clone(), - rent_info.clone(), - stake_program_info.clone(), - ], + // split into validator stake account + Self::stake_split( + stake_pool_info.key, + reserve_stake_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + required_lamports, + stake_info.clone(), )?; Self::stake_delegate( @@ -952,11 +930,12 @@ impl Processor { validator_list.push(ValidatorStakeInfo { status: StakeStatus::Active, vote_account_address: *validator_vote_info.key, - active_stake_lamports: 0, + active_stake_lamports: required_lamports, transient_stake_lamports: 0, last_update_epoch: clock.epoch, - transient_seed_suffix_start: 0, - transient_seed_suffix_end: 0, + transient_seed_suffix: 0, + unused: 0, + validator_seed_suffix: raw_validator_seed, })?; Ok(()) @@ -972,11 +951,9 @@ impl Processor { let stake_pool_info = next_account_info(account_info_iter)?; let staker_info = next_account_info(account_info_iter)?; let withdraw_authority_info = next_account_info(account_info_iter)?; - let new_stake_authority_info = next_account_info(account_info_iter)?; let validator_list_info = next_account_info(account_info_iter)?; let stake_account_info = next_account_info(account_info_iter)?; let transient_stake_account_info = next_account_info(account_info_iter)?; - let destination_stake_account_info = next_account_info(account_info_iter)?; let clock_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(clock_info)?; let stake_program_info = next_account_info(account_info_iter)?; @@ -997,6 +974,11 @@ impl Processor { stake_pool.check_staker(staker_info)?; if stake_pool.last_update_epoch < clock.epoch { + msg!( + "clock {} pool {}", + clock.epoch, + stake_pool.last_update_epoch + ); return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); } @@ -1012,13 +994,6 @@ impl Processor { let (meta, stake) = get_stake_state(stake_account_info)?; let vote_account_address = stake.delegation.voter_pubkey; - check_validator_stake_address( - program_id, - stake_pool_info.key, - stake_account_info.key, - &vote_account_address, - )?; - let maybe_validator_stake_info = validator_list.find_mut::( vote_account_address.as_ref(), ValidatorStakeInfo::memcmp_pubkey, @@ -1031,6 +1006,18 @@ impl Processor { return Err(StakePoolError::ValidatorNotFound.into()); } let mut validator_stake_info = maybe_validator_stake_info.unwrap(); + check_validator_stake_address( + program_id, + stake_pool_info.key, + stake_account_info.key, + &vote_account_address, + NonZeroU32::new(validator_stake_info.validator_seed_suffix), + )?; + + if validator_stake_info.status != StakeStatus::Active { + msg!("Validator is already marked for removal"); + return Err(StakePoolError::ValidatorNotFound.into()); + } let stake_lamports = **stake_account_info.lamports.borrow(); let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; @@ -1060,13 +1047,16 @@ impl Processor { stake_pool_info.key, transient_stake_account_info.key, &vote_account_address, - validator_stake_info.transient_seed_suffix_start, + validator_stake_info.transient_seed_suffix, )?; match get_stake_state(transient_stake_account_info) { Ok((meta, stake)) - if meta.authorized.staker == *withdraw_authority_info.key - && meta.authorized.withdrawer == *withdraw_authority_info.key => + if stake_is_usable_by_pool( + &meta, + withdraw_authority_info.key, + &stake_pool.lockup, + ) => { if stake.delegation.deactivation_epoch == Epoch::MAX { msg!( @@ -1077,36 +1067,23 @@ impl Processor { ); return Err(StakePoolError::WrongStakeState.into()); } else { - // stake is deactivating, mark the entry as such - StakeStatus::DeactivatingTransient + StakeStatus::DeactivatingAll } } - _ => StakeStatus::ReadyForRemoval, + _ => StakeStatus::DeactivatingValidator, } } else { - StakeStatus::ReadyForRemoval + StakeStatus::DeactivatingValidator }; - // split whole thing into destination stake account - Self::stake_split( - stake_pool_info.key, + // deactivate stake + Self::stake_deactivate( stake_account_info.clone(), + clock_info.clone(), withdraw_authority_info.clone(), - AUTHORITY_WITHDRAW, - stake_pool.stake_withdraw_bump_seed, - stake_account_info.lamports(), - destination_stake_account_info.clone(), - )?; - - Self::stake_authorize_signed( stake_pool_info.key, - destination_stake_account_info.clone(), - withdraw_authority_info.clone(), AUTHORITY_WITHDRAW, stake_pool.stake_withdraw_bump_seed, - new_stake_authority_info.key, - clock_info.clone(), - stake_program_info.clone(), )?; validator_stake_info.status = new_status; @@ -1176,12 +1153,6 @@ impl Processor { let (meta, stake) = get_stake_state(validator_stake_account_info)?; let vote_account_address = stake.delegation.voter_pubkey; - check_validator_stake_address( - program_id, - stake_pool_info.key, - validator_stake_account_info.key, - &vote_account_address, - )?; let maybe_validator_stake_info = validator_list.find_mut::( vote_account_address.as_ref(), @@ -1195,6 +1166,13 @@ impl Processor { return Err(StakePoolError::ValidatorNotFound.into()); } let mut validator_stake_info = maybe_validator_stake_info.unwrap(); + check_validator_stake_address( + program_id, + stake_pool_info.key, + validator_stake_account_info.key, + &vote_account_address, + NonZeroU32::new(validator_stake_info.validator_seed_suffix), + )?; if validator_stake_info.transient_stake_lamports > 0 { return Err(StakePoolError::TransientAccountInUse.into()); } @@ -1241,7 +1219,7 @@ impl Processor { return Err(ProgramError::InsufficientFunds); } - create_transient_stake_account( + create_stake_account( transient_stake_account_info.clone(), transient_stake_account_signer_seeds, system_program_info.clone(), @@ -1273,7 +1251,7 @@ impl Processor { .checked_sub(lamports) .ok_or(StakePoolError::CalculationFailure)?; validator_stake_info.transient_stake_lamports = lamports; - validator_stake_info.transient_seed_suffix_start = transient_stake_seed; + validator_stake_info.transient_seed_suffix = transient_stake_seed; Ok(()) } @@ -1364,6 +1342,7 @@ impl Processor { stake_pool_info.key, validator_stake_account_info.key, vote_account_address, + NonZeroU32::new(validator_stake_info.validator_seed_suffix), )?; let (meta, stake) = get_stake_state(validator_stake_account_info)?; if !stake_is_usable_by_pool(&meta, withdraw_authority_info.key, &stake_pool.lockup) { @@ -1433,7 +1412,7 @@ impl Processor { return Err(ProgramError::InsufficientFunds); } - create_transient_stake_account( + create_stake_account( transient_stake_account_info.clone(), transient_stake_account_signer_seeds, system_program_info.clone(), @@ -1464,7 +1443,7 @@ impl Processor { )?; validator_stake_info.transient_stake_lamports = total_lamports; - validator_stake_info.transient_seed_suffix_start = transient_stake_seed; + validator_stake_info.transient_seed_suffix = transient_stake_seed; Ok(()) } @@ -1588,8 +1567,6 @@ impl Processor { return Err(StakePoolError::InvalidState.into()); } - let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; - let current_minimum_delegation = minimum_delegation(stake_minimum_delegation); let validator_iter = &mut validator_slice .iter_mut() .zip(validator_stake_accounts.chunks_exact(2)); @@ -1602,6 +1579,7 @@ impl Processor { stake_pool_info.key, validator_stake_info.key, &validator_stake_record.vote_account_address, + NonZeroU32::new(validator_stake_record.validator_seed_suffix), ) .is_err() { @@ -1612,7 +1590,7 @@ impl Processor { stake_pool_info.key, transient_stake_info.key, &validator_stake_record.vote_account_address, - validator_stake_record.transient_seed_suffix_start, + validator_stake_record.transient_seed_suffix, ) .is_err() { @@ -1658,11 +1636,7 @@ impl Processor { stake_history_info.clone(), stake_program_info.clone(), )?; - if validator_stake_record.status == StakeStatus::DeactivatingTransient { - // the validator stake was previously removed, and - // now this entry can be removed totally - validator_stake_record.status = StakeStatus::ReadyForRemoval; - } + validator_stake_record.status.remove_transient_stake(); } } } @@ -1672,12 +1646,9 @@ impl Processor { withdraw_authority_info.key, &stake_pool.lockup, ) { - let account_stake = meta - .rent_exempt_reserve - .saturating_add(stake.delegation.stake); if no_merge { - transient_stake_lamports = account_stake; - } else if stake.delegation.deactivation_epoch < clock.epoch { + transient_stake_lamports = transient_stake_info.lamports(); + } else if stake_is_inactive_without_history(&stake, clock.epoch) { // deactivated, merge into reserve Self::stake_merge( stake_pool_info.key, @@ -1690,19 +1661,12 @@ impl Processor { stake_history_info.clone(), stake_program_info.clone(), )?; - if validator_stake_record.status == StakeStatus::DeactivatingTransient { - // the validator stake was previously removed, and - // now this entry can be removed totally - validator_stake_record.status = StakeStatus::ReadyForRemoval; - } + validator_stake_record.status.remove_transient_stake(); } else if stake.delegation.activation_epoch < clock.epoch { if let Some(stake::state::StakeState::Stake(_, validator_stake)) = validator_stake_state { if validator_stake.delegation.activation_epoch < clock.epoch { - let additional_lamports = transient_stake_info - .lamports() - .saturating_sub(stake.delegation.stake); Self::stake_merge( stake_pool_info.key, transient_stake_info.clone(), @@ -1714,34 +1678,17 @@ impl Processor { stake_history_info.clone(), stake_program_info.clone(), )?; - - // post merge of two active stakes, withdraw - // the extra back to the reserve - if additional_lamports > 0 { - Self::stake_withdraw( - stake_pool_info.key, - validator_stake_info.clone(), - withdraw_authority_info.clone(), - AUTHORITY_WITHDRAW, - stake_pool.stake_withdraw_bump_seed, - reserve_stake_info.clone(), - clock_info.clone(), - stake_history_info.clone(), - stake_program_info.clone(), - additional_lamports, - )?; - } } else { msg!("Stake activating or just active, not ready to merge"); - transient_stake_lamports = account_stake; + transient_stake_lamports = transient_stake_info.lamports(); } } else { msg!("Transient stake is activating or active, but validator stake is not, need to add the validator stake account on {} back into the stake pool", stake.delegation.voter_pubkey); - transient_stake_lamports = account_stake; + transient_stake_lamports = transient_stake_info.lamports(); } } else { msg!("Transient stake not ready to be merged anywhere"); - transient_stake_lamports = account_stake; + transient_stake_lamports = transient_stake_info.lamports(); } } } @@ -1758,15 +1705,64 @@ impl Processor { ) .ok(); match validator_stake_state { - Some(stake::state::StakeState::Stake(_, stake)) => { - if validator_stake_record.status == StakeStatus::Active { - active_stake_lamports = stake - .delegation - .stake - .checked_sub(current_minimum_delegation) - .ok_or(StakePoolError::CalculationFailure)?; - } else { - msg!("Validator stake account no longer part of the pool, ignoring"); + Some(stake::state::StakeState::Stake(meta, stake)) => { + let additional_lamports = validator_stake_info + .lamports() + .saturating_sub(stake.delegation.stake) + .saturating_sub(meta.rent_exempt_reserve); + // withdraw any extra lamports back to the reserve + if additional_lamports > 0 + && stake_is_usable_by_pool( + &meta, + withdraw_authority_info.key, + &stake_pool.lockup, + ) + { + Self::stake_withdraw( + stake_pool_info.key, + validator_stake_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + reserve_stake_info.clone(), + clock_info.clone(), + stake_history_info.clone(), + stake_program_info.clone(), + additional_lamports, + )?; + } + match validator_stake_record.status { + StakeStatus::Active => { + active_stake_lamports = validator_stake_info.lamports(); + } + StakeStatus::DeactivatingValidator | StakeStatus::DeactivatingAll => { + if no_merge { + active_stake_lamports = validator_stake_info.lamports(); + } else if stake_is_usable_by_pool( + &meta, + withdraw_authority_info.key, + &stake_pool.lockup, + ) && stake_is_inactive_without_history(&stake, clock.epoch) + { + // Validator was removed through normal means. + // Absorb the lamports into the reserve. + Self::stake_merge( + stake_pool_info.key, + validator_stake_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + reserve_stake_info.clone(), + clock_info.clone(), + stake_history_info.clone(), + stake_program_info.clone(), + )?; + validator_stake_record.status.remove_validator_stake(); + } + } + StakeStatus::DeactivatingTransient | StakeStatus::ReadyForRemoval => { + msg!("Validator stake account no longer part of the pool, ignoring"); + } } } Some(stake::state::StakeState::Initialized(meta)) @@ -1777,9 +1773,9 @@ impl Processor { ) => { // If a validator stake is `Initialized`, the validator could - // have been destaked during a cluster restart. Either way, - // absorb those lamports into the reserve. The transient - // stake was likely absorbed into the reserve earlier. + // have been destaked during a cluster restart or removed through + // normal means. Either way, absorb those lamports into the reserve. + // The transient stake was likely absorbed into the reserve earlier. Self::stake_merge( stake_pool_info.key, validator_stake_info.clone(), @@ -1791,7 +1787,7 @@ impl Processor { stake_history_info.clone(), stake_program_info.clone(), )?; - validator_stake_record.status = StakeStatus::ReadyForRemoval; + validator_stake_record.status.remove_validator_stake(); } Some(stake::state::StakeState::Initialized(_)) | Some(stake::state::StakeState::Uninitialized) @@ -1919,8 +1915,9 @@ impl Processor { } stake_pool.total_lamports = total_lamports; - let pool_mint = Mint::unpack_from_slice(&pool_mint_info.data.borrow())?; - stake_pool.pool_token_supply = pool_mint.supply; + let pool_mint_data = pool_mint_info.try_borrow_data()?; + let pool_mint = StateWithExtensions::::unpack(&pool_mint_data)?; + stake_pool.pool_token_supply = pool_mint.base.supply; stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; @@ -2003,6 +2000,9 @@ impl Processor { if stake_pool.manager_fee_account != *manager_fee_info.key { return Err(StakePoolError::InvalidFeeAccount.into()); } + // There is no bypass if the manager fee account is invalid. Deposits + // don't hold user funds hostage, so if the fee account is invalid, users + // cannot deposit in the pool. Let it fail here! if stake_pool.last_update_epoch < clock.epoch { return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); @@ -2019,12 +2019,6 @@ impl Processor { let (_, validator_stake) = get_stake_state(validator_stake_account_info)?; let pre_all_validator_lamports = validator_stake_account_info.lamports(); let vote_account_address = validator_stake.delegation.voter_pubkey; - check_validator_stake_address( - program_id, - stake_pool_info.key, - validator_stake_account_info.key, - &vote_account_address, - )?; if let Some(preferred_deposit) = stake_pool.preferred_deposit_validator_vote_address { if preferred_deposit != vote_account_address { msg!( @@ -2042,6 +2036,13 @@ impl Processor { ValidatorStakeInfo::memcmp_pubkey, ) .ok_or(StakePoolError::ValidatorNotFound)?; + check_validator_stake_address( + program_id, + stake_pool_info.key, + validator_stake_account_info.key, + &vote_account_address, + NonZeroU32::new(validator_stake_info.validator_seed_suffix), + )?; if validator_stake_info.status != StakeStatus::Active { msg!("Validator is marked for removal and no longer accepting deposits"); @@ -2208,13 +2209,7 @@ impl Processor { .ok_or(StakePoolError::CalculationFailure)?; stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; - let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; - let current_minimum_delegation = minimum_delegation(stake_minimum_delegation); - validator_stake_info.active_stake_lamports = post_validator_stake - .delegation - .stake - .checked_sub(current_minimum_delegation) - .ok_or(StakePoolError::CalculationFailure)?; + validator_stake_info.active_stake_lamports = validator_stake_account_info.lamports(); Ok(()) } @@ -2264,6 +2259,9 @@ impl Processor { if stake_pool.manager_fee_account != *manager_fee_info.key { return Err(StakePoolError::InvalidFeeAccount.into()); } + // There is no bypass if the manager fee account is invalid. Deposits + // don't hold user funds hostage, so if the fee account is invalid, users + // cannot deposit in the pool. Let it fail here! // We want this to hold to ensure that deposit_sol mints pool tokens // at the right price @@ -2388,7 +2386,7 @@ impl Processor { return Err(StakePoolError::InvalidState.into()); } - stake_pool.check_mint(pool_mint_info)?; + let decimals = stake_pool.check_mint(pool_mint_info)?; stake_pool.check_validator_list(validator_list_info)?; stake_pool.check_authority_withdraw( withdraw_authority_info.key, @@ -2438,39 +2436,43 @@ impl Processor { return Err(StakePoolError::WithdrawalTooSmall.into()); } + let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; + let stake_state = + try_from_slice_unchecked::(&stake_split_from.data.borrow())?; + let meta = stake_state.meta().ok_or(StakePoolError::WrongStakeState)?; + let required_lamports = minimum_stake_lamports(&meta, stake_minimum_delegation); + let has_active_stake = validator_list .find::( - &0u64.to_le_bytes(), + &required_lamports.to_le_bytes(), ValidatorStakeInfo::active_lamports_not_equal, ) .is_some(); + let has_transient_stake = validator_list + .find::( + &0u64.to_le_bytes(), + ValidatorStakeInfo::transient_lamports_not_equal, + ) + .is_some(); let validator_list_item_info = if *stake_split_from.key == stake_pool.reserve_stake { // check that the validator stake accounts have no withdrawable stake - let has_transient_stake = validator_list - .find::( - &0u64.to_le_bytes(), - ValidatorStakeInfo::transient_lamports_not_equal, - ) - .is_some(); if has_transient_stake || has_active_stake { msg!("Error withdrawing from reserve: validator stake accounts have lamports available, please use those first."); return Err(StakePoolError::StakeLamportsNotEqualToMinimum.into()); } // check that reserve has enough (should never fail, but who knows?) - let stake_state = try_from_slice_unchecked::( - &stake_split_from.data.borrow(), - )?; - let meta = stake_state.meta().ok_or(StakePoolError::WrongStakeState)?; stake_split_from .lamports() .checked_sub(minimum_reserve_lamports(&meta)) .ok_or(StakePoolError::StakeLamportsNotEqualToMinimum)?; None } else { - let (_, stake) = get_stake_state(stake_split_from)?; - let vote_account_address = stake.delegation.voter_pubkey; + let delegation = stake_state + .delegation() + .ok_or(StakePoolError::WrongStakeState)?; + let vote_account_address = delegation.voter_pubkey; if let Some(preferred_withdraw_validator) = stake_pool.preferred_withdraw_validator_vote_address @@ -2481,9 +2483,10 @@ impl Processor { ValidatorStakeInfo::memcmp_pubkey, ) .ok_or(StakePoolError::ValidatorNotFound)?; - if preferred_withdraw_validator != vote_account_address - && preferred_validator_info.active_stake_lamports > 0 - { + let available_lamports = preferred_validator_info + .active_stake_lamports + .saturating_sub(required_lamports); + if preferred_withdraw_validator != vote_account_address && available_lamports > 0 { msg!("Validator vote address {} is preferred for withdrawals, it currently has {} lamports available. Please withdraw those before using other validator stake accounts.", preferred_withdraw_validator, preferred_validator_info.active_stake_lamports); return Err(StakePoolError::IncorrectWithdrawVoteAddress.into()); } @@ -2496,25 +2499,37 @@ impl Processor { ) .ok_or(StakePoolError::ValidatorNotFound)?; - // if there's any active stake, we must withdraw from an active - // stake account - let withdrawing_from_transient_stake = if has_active_stake { + let withdraw_source = if has_active_stake { + // if there's any active stake, we must withdraw from an active + // stake account check_validator_stake_address( program_id, stake_pool_info.key, stake_split_from.key, &vote_account_address, + NonZeroU32::new(validator_stake_info.validator_seed_suffix), )?; - false - } else { + StakeWithdrawSource::Active + } else if has_transient_stake { + // if there's any transient stake, we must withdraw from there check_transient_stake_address( program_id, stake_pool_info.key, stake_split_from.key, &vote_account_address, - validator_stake_info.transient_seed_suffix_start, + validator_stake_info.transient_seed_suffix, )?; - true + StakeWithdrawSource::Transient + } else { + // if there's no active or transient stake, we can take the whole account + check_validator_stake_address( + program_id, + stake_pool_info.key, + stake_split_from.key, + &vote_account_address, + NonZeroU32::new(validator_stake_info.validator_seed_suffix), + )?; + StakeWithdrawSource::ValidatorRemoval }; if validator_stake_info.status != StakeStatus::Active { @@ -2522,14 +2537,25 @@ impl Processor { return Err(StakePoolError::ValidatorNotFound.into()); } - let remaining_lamports = stake.delegation.stake.saturating_sub(withdraw_lamports); - let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; - let current_minimum_delegation = minimum_delegation(stake_minimum_delegation); - if remaining_lamports < current_minimum_delegation { - msg!("Attempting to withdraw {} lamports from validator account with {} stake lamports, {} must remain", withdraw_lamports, stake.delegation.stake, current_minimum_delegation); - return Err(StakePoolError::StakeLamportsNotEqualToMinimum.into()); + match withdraw_source { + StakeWithdrawSource::Active | StakeWithdrawSource::Transient => { + let remaining_lamports = stake_split_from + .lamports() + .saturating_sub(withdraw_lamports); + if remaining_lamports < required_lamports { + msg!("Attempting to withdraw {} lamports from validator account with {} stake lamports, {} must remain", withdraw_lamports, stake_split_from.lamports(), required_lamports); + return Err(StakePoolError::StakeLamportsNotEqualToMinimum.into()); + } + } + StakeWithdrawSource::ValidatorRemoval => { + if withdraw_lamports != stake_split_from.lamports() { + msg!("Cannot withdraw a whole account worth {} lamports, must withdraw exactly {} lamports worth of pool tokens", + withdraw_lamports, stake_split_from.lamports()); + return Err(StakePoolError::StakeLamportsNotEqualToMinimum.into()); + } + } } - Some((validator_stake_info, withdrawing_from_transient_stake)) + Some((validator_stake_info, withdraw_source)) }; Self::token_burn( @@ -2565,9 +2591,11 @@ impl Processor { Self::token_transfer( token_program_info.clone(), burn_from_pool_info.clone(), + pool_mint_info.clone(), manager_fee_info.clone(), user_transfer_authority_info.clone(), pool_tokens_fee, + decimals, )?; } @@ -2581,19 +2609,34 @@ impl Processor { .ok_or(StakePoolError::CalculationFailure)?; stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; - if let Some((validator_list_item, withdrawing_from_transient_stake_account)) = - validator_list_item_info - { - if withdrawing_from_transient_stake_account { - validator_list_item.transient_stake_lamports = validator_list_item - .transient_stake_lamports - .checked_sub(withdraw_lamports) - .ok_or(StakePoolError::CalculationFailure)?; - } else { - validator_list_item.active_stake_lamports = validator_list_item - .active_stake_lamports - .checked_sub(withdraw_lamports) - .ok_or(StakePoolError::CalculationFailure)?; + if let Some((validator_list_item, withdraw_source)) = validator_list_item_info { + match withdraw_source { + StakeWithdrawSource::Active => { + validator_list_item.active_stake_lamports = validator_list_item + .active_stake_lamports + .checked_sub(withdraw_lamports) + .ok_or(StakePoolError::CalculationFailure)? + } + StakeWithdrawSource::Transient => { + validator_list_item.transient_stake_lamports = validator_list_item + .transient_stake_lamports + .checked_sub(withdraw_lamports) + .ok_or(StakePoolError::CalculationFailure)? + } + StakeWithdrawSource::ValidatorRemoval => { + validator_list_item.active_stake_lamports = validator_list_item + .active_stake_lamports + .checked_sub(withdraw_lamports) + .ok_or(StakePoolError::CalculationFailure)?; + if validator_list_item.active_stake_lamports != 0 { + msg!("Attempting to remove a validator from the pool, but withdrawal leaves {} lamports, update the pool to merge any unaccounted lamports", + validator_list_item.active_stake_lamports); + return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); + } + // since we already checked that there's no transient stake, + // we can immediately set this as ready for removal + validator_list_item.status = StakeStatus::ReadyForRemoval; + } } } @@ -2634,7 +2677,7 @@ impl Processor { stake_pool_info.key, )?; stake_pool.check_sol_withdraw_authority(sol_withdraw_authority_info)?; - stake_pool.check_mint(pool_mint_info)?; + let decimals = stake_pool.check_mint(pool_mint_info)?; stake_pool.check_reserve_stake(reserve_stake_info)?; if stake_pool.token_program_id != *token_program_info.key { @@ -2707,9 +2750,11 @@ impl Processor { Self::token_transfer( token_program_info.clone(), burn_from_pool_info.clone(), + pool_mint_info.clone(), manager_fee_info.clone(), user_transfer_authority_info.clone(), pool_tokens_fee, + decimals, )?; } @@ -2930,12 +2975,7 @@ impl Processor { return Err(StakePoolError::SignatureMissing.into()); } - if stake_pool.pool_mint - != spl_token::state::Account::unpack_from_slice(&new_manager_fee_info.data.borrow())? - .mint - { - return Err(StakePoolError::WrongAccountMint.into()); - } + stake_pool.check_manager_fee_info(new_manager_fee_info)?; stake_pool.manager = *new_manager_info.key; stake_pool.manager_fee_account = *new_manager_fee_info.key; @@ -3052,9 +3092,9 @@ impl Processor { max_validators, ) } - StakePoolInstruction::AddValidatorToPool => { + StakePoolInstruction::AddValidatorToPool(seed) => { msg!("Instruction: AddValidatorToPool"); - Self::process_add_validator_to_pool(program_id, accounts) + Self::process_add_validator_to_pool(program_id, accounts, seed) } StakePoolInstruction::RemoveValidatorFromPool => { msg!("Instruction: RemoveValidatorFromPool"); @@ -3204,7 +3244,9 @@ impl PrintProgramError for StakePoolError { StakePoolError::TransientAccountInUse => msg!("Error: Provided validator stake account already has a transient stake account in use"), StakePoolError::InvalidSolWithdrawAuthority => msg!("Error: Provided sol withdraw authority does not match the program's"), StakePoolError::SolWithdrawalTooLarge => msg!("Error: Too much SOL withdrawn from the stake pool's reserve account"), - StakePoolError::InvalidMetadataAccount => msg!("Error: Metadata account derived from pool mint account does not match the one passed to program") + StakePoolError::InvalidMetadataAccount => msg!("Error: Metadata account derived from pool mint account does not match the one passed to program"), + StakePoolError::UnsupportedMintExtension => msg!("Error: mint has an unsupported extension"), + StakePoolError::UnsupportedFeeAccountExtension => msg!("Error: fee account has an unsupported extension"), } } } diff --git a/program/src/state.rs b/program/src/state.rs index ca7507f6..4eb044dc 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -18,7 +18,10 @@ use { pubkey::{Pubkey, PUBKEY_BYTES}, stake::state::Lockup, }, - spl_token::state::{Account, AccountState}, + spl_token_2022::{ + extension::{BaseStateWithExtensions, ExtensionType, StateWithExtensions}, + state::{Account, AccountState, Mint}, + }, std::{borrow::Borrow, convert::TryFrom, fmt, matches}, }; @@ -287,14 +290,22 @@ impl StakePool { &self, manager_fee_info: &AccountInfo, ) -> Result<(), ProgramError> { - let token_account = Account::unpack(&manager_fee_info.try_borrow_data()?)?; + let account_data = manager_fee_info.try_borrow_data()?; + let token_account = StateWithExtensions::::unpack(&account_data)?; if manager_fee_info.owner != &self.token_program_id - || token_account.state != AccountState::Initialized - || token_account.mint != self.pool_mint + || token_account.base.state != AccountState::Initialized + || token_account.base.mint != self.pool_mint { msg!("Manager fee account is not owned by token program, is not initialized, or does not match stake pool's mint"); return Err(StakePoolError::InvalidFeeAccount.into()); } + let extensions = token_account.get_extension_types()?; + if extensions + .iter() + .any(|x| !is_extension_supported_for_fee_account(x)) + { + return Err(StakePoolError::UnsupportedFeeAccountExtension.into()); + } Ok(()) } @@ -370,11 +381,13 @@ impl StakePool { /// Check mint is correct #[inline] - pub(crate) fn check_mint(&self, mint_info: &AccountInfo) -> Result<(), ProgramError> { + pub(crate) fn check_mint(&self, mint_info: &AccountInfo) -> Result { if *mint_info.key != self.pool_mint { Err(StakePoolError::WrongPoolMint.into()) } else { - Ok(()) + let mint_data = mint_info.try_borrow_data()?; + let mint = StateWithExtensions::::unpack(&mint_data)?; + Ok(mint.base.decimals) } } @@ -477,6 +490,45 @@ impl StakePool { } } +/// Checks if the given extension is supported for the stake pool mint +pub fn is_extension_supported_for_mint(extension_type: &ExtensionType) -> bool { + const SUPPORTED_EXTENSIONS: [ExtensionType; 5] = [ + ExtensionType::Uninitialized, + ExtensionType::TransferFeeConfig, + ExtensionType::ConfidentialTransferMint, + ExtensionType::DefaultAccountState, // ok, but a freeze authority is not + ExtensionType::InterestBearingConfig, + ]; + if !SUPPORTED_EXTENSIONS.contains(extension_type) { + msg!( + "Stake pool mint account cannot have the {:?} extension", + extension_type + ); + false + } else { + true + } +} + +/// Checks if the given extension is supported for the stake pool's fee account +pub fn is_extension_supported_for_fee_account(extension_type: &ExtensionType) -> bool { + // Note: this does not include the `ConfidentialTransferAccount` extension + // because it is possible to block non-confidential transfers with the + // extension enabled. + const SUPPORTED_EXTENSIONS: [ExtensionType; 4] = [ + ExtensionType::Uninitialized, + ExtensionType::TransferFeeAmount, + ExtensionType::ImmutableOwner, + ExtensionType::CpiGuard, + ]; + if !SUPPORTED_EXTENSIONS.contains(extension_type) { + msg!("Fee account cannot have the {:?} extension", extension_type); + false + } else { + true + } +} + /// Storage list for all validator stake accounts in the pool. #[repr(C)] #[derive(Clone, Debug, Default, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)] @@ -512,14 +564,50 @@ pub enum StakeStatus { /// No more validator stake accounts exist, entry ready for removal during /// `UpdateStakePoolBalance` ReadyForRemoval, + /// Only the validator stake account is deactivating, no transient stake + /// account exists + DeactivatingValidator, + /// Both the transient and validator stake account are deactivating, when + /// a validator is removed with a transient stake active + DeactivatingAll, +} +impl StakeStatus { + /// Downgrade the status towards ready for removal by removing the validator stake + pub fn remove_validator_stake(&mut self) { + let new_self = match self { + Self::Active | Self::DeactivatingTransient | Self::ReadyForRemoval => *self, + Self::DeactivatingAll => Self::DeactivatingTransient, + Self::DeactivatingValidator => Self::ReadyForRemoval, + }; + *self = new_self; + } + /// Downgrade the status towards ready for removal by removing the transient stake + pub fn remove_transient_stake(&mut self) { + let new_self = match self { + Self::Active | Self::DeactivatingValidator | Self::ReadyForRemoval => *self, + Self::DeactivatingAll => Self::DeactivatingValidator, + Self::DeactivatingTransient => Self::ReadyForRemoval, + }; + *self = new_self; + } } - impl Default for StakeStatus { fn default() -> Self { Self::Active } } +/// Withdrawal type, figured out during process_withdraw_stake +#[derive(Debug, PartialEq)] +pub(crate) enum StakeWithdrawSource { + /// Some of an active stake account, but not all + Active, + /// Some of a transient stake account + Transient, + /// Take a whole validator stake account + ValidatorRemoval, +} + /// Information about a validator in the pool /// /// NOTE: ORDER IS VERY IMPORTANT HERE, PLEASE DO NOT RE-ORDER THE FIELDS UNLESS @@ -531,9 +619,7 @@ impl Default for StakeStatus { #[repr(C)] #[derive(Clone, Copy, Debug, Default, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)] pub struct ValidatorStakeInfo { - /// Amount of active stake delegated to this validator, minus the minimum - /// required stake amount of rent-exemption + - /// `max(crate::MINIMUM_ACTIVE_STAKE, solana_program::stake::tools::get_minimum_delegation())`. + /// Amount of lamports on the validator stake account, including rent /// /// Note that if `last_update_epoch` does not match the current epoch then /// this field may not be accurate @@ -548,11 +634,14 @@ pub struct ValidatorStakeInfo { /// Last epoch the active and transient stake lamports fields were updated pub last_update_epoch: u64, - /// Start of the validator transient account seed suffixess - pub transient_seed_suffix_start: u64, + /// Transient account seed suffix, used to derive the transient stake account address + pub transient_seed_suffix: u64, + + /// Unused space, initially meant to specify the end of seed suffixes + pub unused: u32, - /// End of the validator transient account seed suffixes - pub transient_seed_suffix_end: u64, + /// Validator account seed suffix + pub validator_seed_suffix: u32, // really `Option` so 0 is `None` /// Status of the validator stake account pub status: StakeStatus, @@ -562,7 +651,7 @@ pub struct ValidatorStakeInfo { } impl ValidatorStakeInfo { - /// Get the total lamports delegated to this validator (active and transient) + /// Get the total lamports on this validator (active and transient) pub fn stake_lamports(&self) -> u64 { self.active_stake_lamports .checked_add(self.transient_stake_lamports) @@ -851,8 +940,9 @@ mod test { active_stake_lamports: u64::from_le_bytes([255; 8]), transient_stake_lamports: u64::from_le_bytes([128; 8]), last_update_epoch: u64::from_le_bytes([64; 8]), - transient_seed_suffix_start: 0, - transient_seed_suffix_end: 0, + transient_seed_suffix: 0, + unused: 0, + validator_seed_suffix: 0, }, ValidatorStakeInfo { status: StakeStatus::DeactivatingTransient, @@ -860,8 +950,9 @@ mod test { active_stake_lamports: 998877665544, transient_stake_lamports: 222222222, last_update_epoch: 11223445566, - transient_seed_suffix_start: 0, - transient_seed_suffix_end: 0, + transient_seed_suffix: 0, + unused: 0, + validator_seed_suffix: 0, }, ValidatorStakeInfo { status: StakeStatus::ReadyForRemoval, @@ -869,8 +960,9 @@ mod test { active_stake_lamports: 0, transient_stake_lamports: 0, last_update_epoch: 999999999999999, - transient_seed_suffix_start: 0, - transient_seed_suffix_end: 0, + transient_seed_suffix: 0, + unused: 0, + validator_seed_suffix: 0, }, ], } diff --git a/program/tests/create_pool_token_metadata.rs b/program/tests/create_pool_token_metadata.rs index e24a4978..01be0df6 100644 --- a/program/tests/create_pool_token_metadata.rs +++ b/program/tests/create_pool_token_metadata.rs @@ -18,13 +18,14 @@ use { error::StakePoolError::{AlreadyInUse, SignatureMissing, WrongManager}, instruction, MINIMUM_RESERVE_LAMPORTS, }, + test_case::test_case, }; -async fn setup() -> (ProgramTestContext, StakePoolAccounts) { +async fn setup(token_program_id: Pubkey) -> (ProgramTestContext, StakePoolAccounts) { let mut context = program_test_with_metadata_program() .start_with_context() .await; - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::new_with_token_program(token_program_id); stake_pool_accounts .initialize_stake_pool( &mut context.banks_client, @@ -38,9 +39,11 @@ async fn setup() -> (ProgramTestContext, StakePoolAccounts) { (context, stake_pool_accounts) } +#[test_case(spl_token::id(); "token")] +//#[test_case(spl_token_2022::id(); "token-2022")] enable once metaplex supports token-2022 #[tokio::test] -async fn success_create_pool_token_metadata() { - let (mut context, stake_pool_accounts) = setup().await; +async fn success(token_program_id: Pubkey) { + let (mut context, stake_pool_accounts) = setup(token_program_id).await; let name = "test_name"; let symbol = "SYM"; @@ -87,7 +90,7 @@ async fn success_create_pool_token_metadata() { #[tokio::test] async fn fail_manager_did_not_sign() { - let (mut context, stake_pool_accounts) = setup().await; + let (mut context, stake_pool_accounts) = setup(spl_token::id()).await; let name = "test_name"; let symbol = "SYM"; @@ -131,7 +134,7 @@ async fn fail_manager_did_not_sign() { #[tokio::test] async fn fail_wrong_manager_signed() { - let (mut context, stake_pool_accounts) = setup().await; + let (mut context, stake_pool_accounts) = setup(spl_token::id()).await; let name = "test_name"; let symbol = "SYM"; @@ -175,7 +178,7 @@ async fn fail_wrong_manager_signed() { #[tokio::test] async fn fail_wrong_mpl_metadata_program() { - let (mut context, stake_pool_accounts) = setup().await; + let (mut context, stake_pool_accounts) = setup(spl_token::id()).await; let name = "test_name"; let symbol = "SYM"; @@ -221,7 +224,7 @@ async fn fail_wrong_mpl_metadata_program() { #[tokio::test] async fn fail_create_metadata_twice() { - let (mut context, stake_pool_accounts) = setup().await; + let (mut context, stake_pool_accounts) = setup(spl_token::id()).await; let name = "test_name"; let symbol = "SYM"; diff --git a/program/tests/decrease.rs b/program/tests/decrease.rs index 008089e1..0c698efb 100644 --- a/program/tests/decrease.rs +++ b/program/tests/decrease.rs @@ -32,7 +32,10 @@ async fn setup() -> ( let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let rent = banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); - let stake_pool_accounts = StakePoolAccounts::new(); + let current_minimum_delegation = + stake_pool_get_minimum_delegation(&mut banks_client, &payer, &recent_blockhash).await; + + let stake_pool_accounts = StakePoolAccounts::default(); stake_pool_accounts .initialize_stake_pool( &mut banks_client, @@ -48,12 +51,10 @@ async fn setup() -> ( &payer, &recent_blockhash, &stake_pool_accounts, + None, ) .await; - let current_minimum_delegation = - stake_pool_get_minimum_delegation(&mut banks_client, &payer, &recent_blockhash).await; - let deposit_info = simple_deposit_stake( &mut banks_client, &payer, @@ -285,7 +286,7 @@ async fn fail_with_unknown_validator() { error, TransactionError::InstructionError( 0, - InstructionError::Custom(StakePoolError::InvalidStakeAccountAddress as u32) + InstructionError::Custom(StakePoolError::ValidatorNotFound as u32) ) ); } diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index f3ebe513..1b792909 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -4,7 +4,6 @@ mod helpers; use { - bincode::deserialize, borsh::BorshSerialize, helpers::*, solana_program::{ @@ -19,14 +18,14 @@ use { transaction::{Transaction, TransactionError}, transport::TransportError, }, - spl_stake_pool::{ - error::StakePoolError, id, instruction, minimum_stake_lamports, state, - MINIMUM_RESERVE_LAMPORTS, - }, + spl_stake_pool::{error::StakePoolError, id, instruction, state, MINIMUM_RESERVE_LAMPORTS}, spl_token::error as token_error, + test_case::test_case, }; -async fn setup() -> ( +async fn setup( + token_program_id: Pubkey, +) -> ( ProgramTestContext, StakePoolAccounts, ValidatorStakeAccount, @@ -37,7 +36,7 @@ async fn setup() -> ( ) { let mut context = program_test().start_with_context().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::new_with_token_program(token_program_id); stake_pool_accounts .initialize_stake_pool( &mut context.banks_client, @@ -53,6 +52,7 @@ async fn setup() -> ( &context.payer, &context.last_blockhash, &stake_pool_accounts, + None, ) .await; @@ -110,9 +110,11 @@ async fn setup() -> ( &mut context.banks_client, &context.payer, &context.last_blockhash, + &stake_pool_accounts.token_program_id, &pool_token_account, &stake_pool_accounts.pool_mint.pubkey(), - &user.pubkey(), + &user, + &[], ) .await .unwrap(); @@ -128,8 +130,10 @@ async fn setup() -> ( ) } +#[test_case(spl_token::id(); "token")] +#[test_case(spl_token_2022::id(); "token-2022")] #[tokio::test] -async fn success() { +async fn success(token_program_id: Pubkey) { let ( mut context, stake_pool_accounts, @@ -138,7 +142,7 @@ async fn success() { deposit_stake, pool_token_account, stake_lamports, - ) = setup().await; + ) = setup(token_program_id).await; let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); @@ -246,17 +250,8 @@ async fn success() { &validator_stake_account.stake_account, ) .await; - let stake_state = - deserialize::(&validator_stake_account.data).unwrap(); - let meta = stake_state.meta().unwrap(); - let stake_minimum_delegation = stake_get_minimum_delegation( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - ) - .await; assert_eq!( - validator_stake_account.lamports - minimum_stake_lamports(&meta, stake_minimum_delegation), + validator_stake_account.lamports, post_validator_stake_item.stake_lamports() ); assert_eq!(post_validator_stake_item.transient_stake_lamports, 0); @@ -281,7 +276,7 @@ async fn success_with_extra_stake_lamports() { deposit_stake, pool_token_account, stake_lamports, - ) = setup().await; + ) = setup(spl_token::id()).await; let extra_lamports = TEST_STAKE_AMOUNT * 3 + 1; @@ -300,9 +295,11 @@ async fn success_with_extra_stake_lamports() { &mut context.banks_client, &context.payer, &context.last_blockhash, + &stake_pool_accounts.token_program_id, &referrer_token_account, &stake_pool_accounts.pool_mint.pubkey(), - &referrer.pubkey(), + &referrer, + &[], ) .await .unwrap(); @@ -447,17 +444,8 @@ async fn success_with_extra_stake_lamports() { &validator_stake_account.stake_account, ) .await; - let stake_state = - deserialize::(&validator_stake_account.data).unwrap(); - let meta = stake_state.meta().unwrap(); - let stake_minimum_delegation = stake_get_minimum_delegation( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - ) - .await; assert_eq!( - validator_stake_account.lamports - minimum_stake_lamports(&meta, stake_minimum_delegation), + validator_stake_account.lamports, post_validator_stake_item.stake_lamports() ); assert_eq!(post_validator_stake_item.transient_stake_lamports, 0); @@ -485,7 +473,7 @@ async fn fail_with_wrong_stake_program_id() { deposit_stake, pool_token_account, _stake_lamports, - ) = setup().await; + ) = setup(spl_token::id()).await; let wrong_stake_program = Pubkey::new_unique(); @@ -545,7 +533,7 @@ async fn fail_with_wrong_token_program_id() { deposit_stake, pool_token_account, _stake_lamports, - ) = setup().await; + ) = setup(spl_token::id()).await; let wrong_token_program = Keypair::new(); @@ -595,7 +583,7 @@ async fn fail_with_wrong_validator_list_account() { deposit_stake, pool_token_account, _stake_lamports, - ) = setup().await; + ) = setup(spl_token::id()).await; let wrong_validator_list = Keypair::new(); stake_pool_accounts.validator_list = wrong_validator_list; @@ -629,7 +617,7 @@ async fn fail_with_wrong_validator_list_account() { #[tokio::test] async fn fail_with_unknown_validator() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::default(); stake_pool_accounts .initialize_stake_pool( &mut banks_client, @@ -654,9 +642,11 @@ async fn fail_with_unknown_validator() { &mut banks_client, &payer, &recent_blockhash, + &stake_pool_accounts.token_program_id, &user_pool_account, &stake_pool_accounts.pool_mint.pubkey(), - &user.pubkey(), + &user, + &[], ) .await .unwrap(); @@ -706,7 +696,7 @@ async fn fail_with_unknown_validator() { error, TransactionError::InstructionError( 2, - InstructionError::Custom(StakePoolError::InvalidStakeAccountAddress as u32) + InstructionError::Custom(StakePoolError::ValidatorNotFound as u32) ) ); } @@ -721,7 +711,7 @@ async fn fail_with_wrong_withdraw_authority() { deposit_stake, pool_token_account, _stake_lamports, - ) = setup().await; + ) = setup(spl_token::id()).await; stake_pool_accounts.withdraw_authority = Pubkey::new_unique(); @@ -758,7 +748,7 @@ async fn fail_with_wrong_mint_for_receiver_acc() { deposit_stake, _pool_token_account, _stake_lamports, - ) = setup().await; + ) = setup(spl_token::id()).await; let outside_mint = Keypair::new(); let outside_withdraw_auth = Keypair::new(); @@ -769,8 +759,11 @@ async fn fail_with_wrong_mint_for_receiver_acc() { &mut context.banks_client, &context.payer, &context.last_blockhash, + &stake_pool_accounts.token_program_id, &outside_mint, &outside_withdraw_auth.pubkey(), + 0, + &[], ) .await .unwrap(); @@ -779,9 +772,11 @@ async fn fail_with_wrong_mint_for_receiver_acc() { &mut context.banks_client, &context.payer, &context.last_blockhash, + &stake_pool_accounts.token_program_id, &outside_pool_fee_acc, &outside_mint.pubkey(), - &outside_manager.pubkey(), + &outside_manager, + &[], ) .await .unwrap(); @@ -827,7 +822,7 @@ async fn success_with_preferred_deposit() { deposit_stake, pool_token_account, _stake_lamports, - ) = setup().await; + ) = setup(spl_token::id()).await; stake_pool_accounts .set_preferred_validator( @@ -863,13 +858,14 @@ async fn fail_with_wrong_preferred_deposit() { deposit_stake, pool_token_account, _stake_lamports, - ) = setup().await; + ) = setup(spl_token::id()).await; let preferred_validator = simple_add_validator_to_pool( &mut context.banks_client, &context.payer, &context.last_blockhash, &stake_pool_accounts, + None, ) .await; @@ -917,7 +913,7 @@ async fn success_with_referral_fee() { deposit_stake, pool_token_account, stake_lamports, - ) = setup().await; + ) = setup(spl_token::id()).await; let referrer = Keypair::new(); let referrer_token_account = Keypair::new(); @@ -925,9 +921,11 @@ async fn success_with_referral_fee() { &mut context.banks_client, &context.payer, &context.last_blockhash, + &stake_pool_accounts.token_program_id, &referrer_token_account, &stake_pool_accounts.pool_mint.pubkey(), - &referrer.pubkey(), + &referrer, + &[], ) .await .unwrap(); @@ -992,7 +990,7 @@ async fn fail_with_invalid_referrer() { deposit_stake, pool_token_account, _stake_lamports, - ) = setup().await; + ) = setup(spl_token::id()).await; let invalid_token_account = Keypair::new(); diff --git a/program/tests/deposit_authority.rs b/program/tests/deposit_authority.rs index ba8de843..8e44178a 100644 --- a/program/tests/deposit_authority.rs +++ b/program/tests/deposit_authority.rs @@ -61,6 +61,7 @@ async fn success_deposit() { &payer, &recent_blockhash, &stake_pool_accounts, + stake_pool_accounts.stake_deposit_authority_keypair.as_ref(), ) .await; @@ -99,9 +100,11 @@ async fn success_deposit() { &mut banks_client, &payer, &recent_blockhash, + &stake_pool_accounts.token_program_id, &user_pool_account, &stake_pool_accounts.pool_mint.pubkey(), - &user.pubkey(), + &user, + &[], ) .await .unwrap(); @@ -141,6 +144,7 @@ async fn fail_deposit_without_authority_signature() { &payer, &recent_blockhash, &stake_pool_accounts, + stake_pool_accounts.stake_deposit_authority_keypair.as_ref(), ) .await; @@ -179,9 +183,11 @@ async fn fail_deposit_without_authority_signature() { &mut banks_client, &payer, &recent_blockhash, + &stake_pool_accounts.token_program_id, &user_pool_account, &stake_pool_accounts.pool_mint.pubkey(), - &user.pubkey(), + &user, + &[], ) .await .unwrap(); diff --git a/program/tests/deposit_sol.rs b/program/tests/deposit_sol.rs index 0e88e4f3..7d141746 100644 --- a/program/tests/deposit_sol.rs +++ b/program/tests/deposit_sol.rs @@ -20,12 +20,15 @@ use { state, MINIMUM_RESERVE_LAMPORTS, }, spl_token::error as token_error, + test_case::test_case, }; -async fn setup() -> (ProgramTestContext, StakePoolAccounts, Keypair, Pubkey) { +async fn setup( + token_program_id: Pubkey, +) -> (ProgramTestContext, StakePoolAccounts, Keypair, Pubkey) { let mut context = program_test().start_with_context().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::new_with_token_program(token_program_id); stake_pool_accounts .initialize_stake_pool( &mut context.banks_client, @@ -44,9 +47,11 @@ async fn setup() -> (ProgramTestContext, StakePoolAccounts, Keypair, Pubkey) { &mut context.banks_client, &context.payer, &context.last_blockhash, + &stake_pool_accounts.token_program_id, &pool_token_account, &stake_pool_accounts.pool_mint.pubkey(), - &user.pubkey(), + &user, + &[], ) .await .unwrap(); @@ -59,9 +64,12 @@ async fn setup() -> (ProgramTestContext, StakePoolAccounts, Keypair, Pubkey) { ) } +#[test_case(spl_token::id(); "token")] +#[test_case(spl_token_2022::id(); "token-2022")] #[tokio::test] -async fn success() { - let (mut context, stake_pool_accounts, _user, pool_token_account) = setup().await; +async fn success(token_program_id: Pubkey) { + let (mut context, stake_pool_accounts, _user, pool_token_account) = + setup(token_program_id).await; // Save stake pool state before depositing let pre_stake_pool = get_account( @@ -133,7 +141,8 @@ async fn success() { #[tokio::test] async fn fail_with_wrong_token_program_id() { - let (mut context, stake_pool_accounts, _user, pool_token_account) = setup().await; + let (mut context, stake_pool_accounts, _user, pool_token_account) = + setup(spl_token::id()).await; let wrong_token_program = Keypair::new(); @@ -173,7 +182,8 @@ async fn fail_with_wrong_token_program_id() { #[tokio::test] async fn fail_with_wrong_withdraw_authority() { - let (mut context, mut stake_pool_accounts, _user, pool_token_account) = setup().await; + let (mut context, mut stake_pool_accounts, _user, pool_token_account) = + setup(spl_token::id()).await; stake_pool_accounts.withdraw_authority = Pubkey::new_unique(); @@ -201,7 +211,8 @@ async fn fail_with_wrong_withdraw_authority() { #[tokio::test] async fn fail_with_wrong_mint_for_receiver_acc() { - let (mut context, stake_pool_accounts, _user, _pool_token_account) = setup().await; + let (mut context, stake_pool_accounts, _user, _pool_token_account) = + setup(spl_token::id()).await; let outside_mint = Keypair::new(); let outside_withdraw_auth = Keypair::new(); @@ -212,8 +223,11 @@ async fn fail_with_wrong_mint_for_receiver_acc() { &mut context.banks_client, &context.payer, &context.last_blockhash, + &stake_pool_accounts.token_program_id, &outside_mint, &outside_withdraw_auth.pubkey(), + 0, + &[], ) .await .unwrap(); @@ -222,9 +236,11 @@ async fn fail_with_wrong_mint_for_receiver_acc() { &mut context.banks_client, &context.payer, &context.last_blockhash, + &stake_pool_accounts.token_program_id, &outside_pool_fee_acc, &outside_mint.pubkey(), - &outside_manager.pubkey(), + &outside_manager, + &[], ) .await .unwrap(); @@ -256,7 +272,7 @@ async fn fail_with_wrong_mint_for_receiver_acc() { #[tokio::test] async fn success_with_sol_deposit_authority() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::default(); stake_pool_accounts .initialize_stake_pool( &mut banks_client, @@ -275,9 +291,11 @@ async fn success_with_sol_deposit_authority() { &mut banks_client, &payer, &recent_blockhash, + &stake_pool_accounts.token_program_id, &user_pool_account, &stake_pool_accounts.pool_mint.pubkey(), - &user.pubkey(), + &user, + &[], ) .await .unwrap(); @@ -326,7 +344,7 @@ async fn success_with_sol_deposit_authority() { async fn fail_without_sol_deposit_authority_signature() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let sol_deposit_authority = Keypair::new(); - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::default(); stake_pool_accounts .initialize_stake_pool( &mut banks_client, @@ -345,9 +363,11 @@ async fn fail_without_sol_deposit_authority_signature() { &mut banks_client, &payer, &recent_blockhash, + &stake_pool_accounts.token_program_id, &user_pool_account, &stake_pool_accounts.pool_mint.pubkey(), - &user.pubkey(), + &user, + &[], ) .await .unwrap(); @@ -393,7 +413,8 @@ async fn fail_without_sol_deposit_authority_signature() { #[tokio::test] async fn success_with_referral_fee() { - let (mut context, stake_pool_accounts, _user, pool_token_account) = setup().await; + let (mut context, stake_pool_accounts, _user, pool_token_account) = + setup(spl_token::id()).await; let referrer = Keypair::new(); let referrer_token_account = Keypair::new(); @@ -401,9 +422,11 @@ async fn success_with_referral_fee() { &mut context.banks_client, &context.payer, &context.last_blockhash, + &stake_pool_accounts.token_program_id, &referrer_token_account, &stake_pool_accounts.pool_mint.pubkey(), - &referrer.pubkey(), + &referrer, + &[], ) .await .unwrap(); @@ -445,7 +468,8 @@ async fn success_with_referral_fee() { #[tokio::test] async fn fail_with_invalid_referrer() { - let (mut context, stake_pool_accounts, _user, pool_token_account) = setup().await; + let (mut context, stake_pool_accounts, _user, pool_token_account) = + setup(spl_token::id()).await; let invalid_token_account = Keypair::new(); diff --git a/program/tests/force_destake.rs b/program/tests/force_destake.rs index a9520806..1aedc5e8 100644 --- a/program/tests/force_destake.rs +++ b/program/tests/force_destake.rs @@ -19,11 +19,17 @@ use { state::{StakeStatus, ValidatorStakeInfo}, MINIMUM_ACTIVE_STAKE, }, + std::num::NonZeroU32, }; -async fn setup() -> (ProgramTestContext, StakePoolAccounts, Pubkey) { +async fn setup() -> ( + ProgramTestContext, + StakePoolAccounts, + Pubkey, + Option, +) { let mut program_test = program_test(); - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::default(); let stake_pool_pubkey = stake_pool_accounts.stake_pool.pubkey(); let (mut stake_pool, mut validator_list) = stake_pool_accounts.state(); @@ -49,7 +55,10 @@ async fn setup() -> (ProgramTestContext, StakePoolAccounts, Pubkey) { Epoch::default(), ); - let (stake_address, _) = find_stake_program_address(&id(), &voter_pubkey, &stake_pool_pubkey); + let raw_validator_seed = 42; + let validator_seed = NonZeroU32::new(raw_validator_seed); + let (stake_address, _) = + find_stake_program_address(&id(), &voter_pubkey, &stake_pool_pubkey, validator_seed); program_test.add_account(stake_address, stake_account); let active_stake_lamports = TEST_STAKE_AMOUNT - MINIMUM_ACTIVE_STAKE; // add to validator list @@ -59,8 +68,9 @@ async fn setup() -> (ProgramTestContext, StakePoolAccounts, Pubkey) { active_stake_lamports, transient_stake_lamports: 0, last_update_epoch: 0, - transient_seed_suffix_start: 0, - transient_seed_suffix_end: 0, + transient_seed_suffix: 0, + unused: 0, + validator_seed_suffix: raw_validator_seed, }); stake_pool.total_lamports += active_stake_lamports; @@ -86,24 +96,26 @@ async fn setup() -> (ProgramTestContext, StakePoolAccounts, Pubkey) { add_mint_account( &mut program_test, + &stake_pool_accounts.token_program_id, &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.withdraw_authority, stake_pool.pool_token_supply, ); add_token_account( &mut program_test, + &stake_pool_accounts.token_program_id, &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.manager.pubkey(), ); let context = program_test.start_with_context().await; - (context, stake_pool_accounts, voter_pubkey) + (context, stake_pool_accounts, voter_pubkey, validator_seed) } #[tokio::test] async fn success_update() { - let (mut context, stake_pool_accounts, voter_pubkey) = setup().await; + let (mut context, stake_pool_accounts, voter_pubkey, validator_seed) = setup().await; let pre_reserve_lamports = context .banks_client .get_account(stake_pool_accounts.reserve_stake.pubkey()) @@ -115,6 +127,7 @@ async fn success_update() { &id(), &voter_pubkey, &stake_pool_accounts.stake_pool.pubkey(), + validator_seed, ); let validator_stake_lamports = context .banks_client @@ -156,11 +169,12 @@ async fn success_update() { #[tokio::test] async fn fail_increase() { - let (mut context, stake_pool_accounts, voter_pubkey) = setup().await; + let (mut context, stake_pool_accounts, voter_pubkey, validator_seed) = setup().await; let (stake_address, _) = find_stake_program_address( &id(), &voter_pubkey, &stake_pool_accounts.stake_pool.pubkey(), + validator_seed, ); let transient_stake_seed = 0; let transient_stake_address = find_transient_stake_program_address( diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 202f77b7..d5ee5811 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -13,9 +13,8 @@ use { }, solana_program_test::{processor, BanksClient, ProgramTest}, solana_sdk::{ - account::{Account, WritableAccount}, + account::{Account as SolanaAccount, WritableAccount}, clock::{Clock, Epoch}, - native_token::LAMPORTS_PER_SOL, signature::{Keypair, Signer}, transaction::Transaction, transport::TransportError, @@ -29,30 +28,49 @@ use { find_transient_stake_program_address, find_withdraw_authority_program_address, id, instruction, minimum_delegation, processor::Processor, - state::{self, FeeType, ValidatorList}, + state::{self, FeeType, StakePool, ValidatorList}, MINIMUM_RESERVE_LAMPORTS, }, - std::convert::TryInto, + spl_token_2022::{ + extension::{ExtensionType, StateWithExtensionsOwned}, + state::{Account, Mint}, + }, + std::{convert::TryInto, num::NonZeroU32}, }; +pub const FIRST_NORMAL_EPOCH: u64 = 15; pub const TEST_STAKE_AMOUNT: u64 = 1_500_000_000; pub const MAX_TEST_VALIDATORS: u32 = 10_000; +pub const DEFAULT_VALIDATOR_STAKE_SEED: Option = NonZeroU32::new(1_010); pub const DEFAULT_TRANSIENT_STAKE_SEED: u64 = 42; pub const STAKE_ACCOUNT_RENT_EXEMPTION: u64 = 2_282_880; const ACCOUNT_RENT_EXEMPTION: u64 = 1_000_000_000; // go with something big to be safe pub fn program_test() -> ProgramTest { - ProgramTest::new("spl_stake_pool", id(), processor!(Processor::process)) + let mut program_test = ProgramTest::new("spl_stake_pool", id(), processor!(Processor::process)); + program_test.prefer_bpf(false); + program_test.add_program( + "spl_token_2022", + spl_token_2022::id(), + processor!(spl_token_2022::processor::Processor::process), + ); + program_test } pub fn program_test_with_metadata_program() -> ProgramTest { let mut program_test = ProgramTest::default(); program_test.add_program("spl_stake_pool", id(), processor!(Processor::process)); program_test.add_program("mpl_token_metadata", mpl_token_metadata::id(), None); + program_test.prefer_bpf(false); + program_test.add_program( + "spl_token_2022", + spl_token_2022::id(), + processor!(spl_token_2022::processor::Processor::process), + ); program_test } -pub async fn get_account(banks_client: &mut BanksClient, pubkey: &Pubkey) -> Account { +pub async fn get_account(banks_client: &mut BanksClient, pubkey: &Pubkey) -> SolanaAccount { banks_client .get_account(*pubkey) .await @@ -60,37 +78,80 @@ pub async fn get_account(banks_client: &mut BanksClient, pubkey: &Pubkey) -> Acc .expect("account empty") } +#[allow(clippy::too_many_arguments)] pub async fn create_mint( banks_client: &mut BanksClient, payer: &Keypair, recent_blockhash: &Hash, + program_id: &Pubkey, pool_mint: &Keypair, manager: &Pubkey, + decimals: u8, + extension_types: &[ExtensionType], ) -> Result<(), TransportError> { + assert!(extension_types.is_empty() || program_id != &spl_token::id()); let rent = banks_client.get_rent().await.unwrap(); - let mint_rent = rent.minimum_balance(spl_token::state::Mint::LEN); + let space = ExtensionType::get_account_len::(extension_types); + let mint_rent = rent.minimum_balance(space); + let mint_pubkey = pool_mint.pubkey(); - let mut transaction = Transaction::new_with_payer( - &[ - system_instruction::create_account( - &payer.pubkey(), - &pool_mint.pubkey(), - mint_rent, - spl_token::state::Mint::LEN as u64, - &spl_token::id(), + let mut instructions = vec![system_instruction::create_account( + &payer.pubkey(), + &mint_pubkey, + mint_rent, + space as u64, + program_id, + )]; + for extension_type in extension_types { + let instruction = match extension_type { + ExtensionType::MintCloseAuthority => + spl_token_2022::instruction::initialize_mint_close_authority( + program_id, + &mint_pubkey, + Some(manager), + ), + ExtensionType::DefaultAccountState => + spl_token_2022::extension::default_account_state::instruction::initialize_default_account_state( + program_id, + &mint_pubkey, + &spl_token_2022::state::AccountState::Initialized, + ), + ExtensionType::TransferFeeConfig => spl_token_2022::extension::transfer_fee::instruction::initialize_transfer_fee_config( + program_id, + &mint_pubkey, + Some(manager), + Some(manager), + 100, + 1_000_000, ), - spl_token::instruction::initialize_mint( - &spl_token::id(), - &pool_mint.pubkey(), - manager, - None, - 0, - ) - .unwrap(), - ], + ExtensionType::InterestBearingConfig => spl_token_2022::extension::interest_bearing_mint::instruction::initialize( + program_id, + &mint_pubkey, + Some(*manager), + 600, + ), + ExtensionType::NonTransferable => + spl_token_2022::instruction::initialize_non_transferable_mint(program_id, &mint_pubkey), + _ => unimplemented!(), + }; + instructions.push(instruction.unwrap()); + } + instructions.push( + spl_token_2022::instruction::initialize_mint( + program_id, + &pool_mint.pubkey(), + manager, + None, + decimals, + ) + .unwrap(), + ); + let transaction = Transaction::new_signed_with_payer( + &instructions, Some(&payer.pubkey()), + &[payer, pool_mint], + *recent_blockhash, ); - transaction.sign(&[payer, pool_mint], *recent_blockhash); #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 banks_client .process_transaction(transaction) @@ -118,23 +179,29 @@ pub async fn transfer( banks_client.process_transaction(transaction).await.unwrap(); } +#[allow(clippy::too_many_arguments)] pub async fn transfer_spl_tokens( banks_client: &mut BanksClient, payer: &Keypair, recent_blockhash: &Hash, + program_id: &Pubkey, source: &Pubkey, + mint: &Pubkey, destination: &Pubkey, authority: &Keypair, amount: u64, + decimals: u8, ) { let transaction = Transaction::new_signed_with_payer( - &[spl_token::instruction::transfer( - &spl_token::id(), + &[spl_token_2022::instruction::transfer_checked( + program_id, source, + mint, destination, &authority.pubkey(), &[], amount, + decimals, ) .unwrap()], Some(&payer.pubkey()), @@ -144,37 +211,93 @@ pub async fn transfer_spl_tokens( banks_client.process_transaction(transaction).await.unwrap(); } +#[allow(clippy::too_many_arguments)] pub async fn create_token_account( banks_client: &mut BanksClient, payer: &Keypair, recent_blockhash: &Hash, + program_id: &Pubkey, account: &Keypair, pool_mint: &Pubkey, - manager: &Pubkey, + authority: &Keypair, + extensions: &[ExtensionType], ) -> Result<(), TransportError> { let rent = banks_client.get_rent().await.unwrap(); - let account_rent = rent.minimum_balance(spl_token::state::Account::LEN); + let space = ExtensionType::get_account_len::(extensions); + let account_rent = rent.minimum_balance(space); - let mut transaction = Transaction::new_with_payer( - &[ - system_instruction::create_account( - &payer.pubkey(), - &account.pubkey(), - account_rent, - spl_token::state::Account::LEN as u64, - &spl_token::id(), + let mut instructions = vec![system_instruction::create_account( + &payer.pubkey(), + &account.pubkey(), + account_rent, + space as u64, + program_id, + )]; + + for extension in extensions { + match extension { + ExtensionType::ImmutableOwner => instructions.push( + spl_token_2022::instruction::initialize_immutable_owner( + program_id, + &account.pubkey(), + ) + .unwrap(), ), - spl_token::instruction::initialize_account( - &spl_token::id(), - &account.pubkey(), - pool_mint, - manager, - ) - .unwrap(), - ], + ExtensionType::TransferFeeAmount + | ExtensionType::MemoTransfer + | ExtensionType::CpiGuard => (), + _ => unimplemented!(), + }; + } + + instructions.push( + spl_token_2022::instruction::initialize_account( + program_id, + &account.pubkey(), + pool_mint, + &authority.pubkey(), + ) + .unwrap(), + ); + + let mut signers = vec![payer, account]; + for extension in extensions { + match extension { + ExtensionType::MemoTransfer => { + signers.push(authority); + instructions.push( + spl_token_2022::extension::memo_transfer::instruction::enable_required_transfer_memos( + program_id, + &account.pubkey(), + &authority.pubkey(), + &[], + ) + .unwrap() + ) + } + ExtensionType::CpiGuard => { + signers.push(authority); + instructions.push( + spl_token_2022::extension::cpi_guard::instruction::enable_cpi_guard( + program_id, + &account.pubkey(), + &authority.pubkey(), + &[], + ) + .unwrap(), + ) + } + ExtensionType::ImmutableOwner | ExtensionType::TransferFeeAmount => (), + _ => unimplemented!(), + } + } + + let transaction = Transaction::new_signed_with_payer( + &instructions, Some(&payer.pubkey()), + &signers, + *recent_blockhash, ); - transaction.sign(&[payer, account], *recent_blockhash); #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 banks_client .process_transaction(transaction) @@ -186,13 +309,14 @@ pub async fn close_token_account( banks_client: &mut BanksClient, payer: &Keypair, recent_blockhash: &Hash, + program_id: &Pubkey, account: &Pubkey, lamports_destination: &Pubkey, manager: &Keypair, ) -> Result<(), TransportError> { let mut transaction = Transaction::new_with_payer( - &[spl_token::instruction::close_account( - &spl_token::id(), + &[spl_token_2022::instruction::close_account( + program_id, account, lamports_destination, &manager.pubkey(), @@ -213,13 +337,14 @@ pub async fn freeze_token_account( banks_client: &mut BanksClient, payer: &Keypair, recent_blockhash: &Hash, + program_id: &Pubkey, account: &Pubkey, pool_mint: &Pubkey, manager: &Keypair, ) -> Result<(), TransportError> { let mut transaction = Transaction::new_with_payer( - &[spl_token::instruction::freeze_account( - &spl_token::id(), + &[spl_token_2022::instruction::freeze_account( + program_id, account, pool_mint, &manager.pubkey(), @@ -236,18 +361,20 @@ pub async fn freeze_token_account( .map_err(|e| e.into()) } +#[allow(clippy::too_many_arguments)] pub async fn mint_tokens( banks_client: &mut BanksClient, payer: &Keypair, recent_blockhash: &Hash, + program_id: &Pubkey, mint: &Pubkey, account: &Pubkey, mint_authority: &Keypair, amount: u64, ) -> Result<(), TransportError> { let transaction = Transaction::new_signed_with_payer( - &[spl_token::instruction::mint_to( - &spl_token::id(), + &[spl_token_2022::instruction::mint_to( + program_id, mint, account, &mint_authority.pubkey(), @@ -266,18 +393,20 @@ pub async fn mint_tokens( .map_err(|e| e.into()) } +#[allow(clippy::too_many_arguments)] pub async fn burn_tokens( banks_client: &mut BanksClient, payer: &Keypair, recent_blockhash: &Hash, + program_id: &Pubkey, mint: &Pubkey, account: &Pubkey, authority: &Keypair, amount: u64, ) -> Result<(), TransportError> { let transaction = Transaction::new_signed_with_payer( - &[spl_token::instruction::burn( - &spl_token::id(), + &[spl_token_2022::instruction::burn( + program_id, account, mint, &authority.pubkey(), @@ -298,9 +427,8 @@ pub async fn burn_tokens( pub async fn get_token_balance(banks_client: &mut BanksClient, token: &Pubkey) -> u64 { let token_account = banks_client.get_account(*token).await.unwrap().unwrap(); - let account_info: spl_token::state::Account = - spl_token::state::Account::unpack_from_slice(token_account.data.as_slice()).unwrap(); - account_info.amount + let account_info = StateWithExtensionsOwned::::unpack(token_account.data).unwrap(); + account_info.base.amount } pub async fn get_metadata_account(banks_client: &mut BanksClient, token_mint: &Pubkey) -> Metadata { @@ -315,23 +443,24 @@ pub async fn get_metadata_account(banks_client: &mut BanksClient, token_mint: &P pub async fn get_token_supply(banks_client: &mut BanksClient, mint: &Pubkey) -> u64 { let mint_account = banks_client.get_account(*mint).await.unwrap().unwrap(); - let account_info = - spl_token::state::Mint::unpack_from_slice(mint_account.data.as_slice()).unwrap(); - account_info.supply + let account_info = StateWithExtensionsOwned::::unpack(mint_account.data).unwrap(); + account_info.base.supply } +#[allow(clippy::too_many_arguments)] pub async fn delegate_tokens( banks_client: &mut BanksClient, payer: &Keypair, recent_blockhash: &Hash, + program_id: &Pubkey, account: &Pubkey, manager: &Keypair, delegate: &Pubkey, amount: u64, ) { let transaction = Transaction::new_signed_with_payer( - &[spl_token::instruction::approve( - &spl_token::id(), + &[spl_token_2022::instruction::approve( + program_id, account, delegate, &manager.pubkey(), @@ -346,6 +475,26 @@ pub async fn delegate_tokens( banks_client.process_transaction(transaction).await.unwrap(); } +pub async fn revoke_tokens( + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + program_id: &Pubkey, + account: &Pubkey, + manager: &Keypair, +) { + let transaction = Transaction::new_signed_with_payer( + &[ + spl_token_2022::instruction::revoke(program_id, account, &manager.pubkey(), &[]) + .unwrap(), + ], + Some(&payer.pubkey()), + &[payer, manager], + *recent_blockhash, + ); + banks_client.process_transaction(transaction).await.unwrap(); +} + #[allow(clippy::too_many_arguments)] pub async fn create_stake_pool( banks_client: &mut BanksClient, @@ -354,6 +503,7 @@ pub async fn create_stake_pool( stake_pool: &Keypair, validator_list: &Keypair, reserve_stake: &Pubkey, + token_program_id: &Pubkey, pool_mint: &Pubkey, pool_token_account: &Pubkey, manager: &Keypair, @@ -400,7 +550,7 @@ pub async fn create_stake_pool( reserve_stake, pool_mint, pool_token_account, - &spl_token::id(), + token_program_id, stake_deposit_authority.as_ref().map(|k| k.pubkey()), *epoch_fee, *withdrawal_fee, @@ -610,7 +760,7 @@ pub async fn create_unknown_validator_stake( recent_blockhash: &Hash, stake_pool: &Pubkey, ) -> ValidatorStakeAccount { - let mut unknown_stake = ValidatorStakeAccount::new(stake_pool, 222); + let mut unknown_stake = ValidatorStakeAccount::new(stake_pool, NonZeroU32::new(1), 222); create_vote( banks_client, payer, @@ -654,16 +804,22 @@ pub struct ValidatorStakeAccount { pub stake_account: Pubkey, pub transient_stake_account: Pubkey, pub transient_stake_seed: u64, + pub validator_stake_seed: Option, pub vote: Keypair, pub validator: Keypair, pub stake_pool: Pubkey, } impl ValidatorStakeAccount { - pub fn new(stake_pool: &Pubkey, transient_stake_seed: u64) -> Self { + pub fn new( + stake_pool: &Pubkey, + validator_stake_seed: Option, + transient_stake_seed: u64, + ) -> Self { let validator = Keypair::new(); let vote = Keypair::new(); - let (stake_account, _) = find_stake_program_address(&id(), &vote.pubkey(), stake_pool); + let (stake_account, _) = + find_stake_program_address(&id(), &vote.pubkey(), stake_pool, validator_stake_seed); let (transient_stake_account, _) = find_transient_stake_program_address( &id(), &vote.pubkey(), @@ -674,6 +830,7 @@ impl ValidatorStakeAccount { stake_account, transient_stake_account, transient_stake_seed, + validator_stake_seed, vote, validator, stake_pool: *stake_pool, @@ -685,8 +842,10 @@ pub struct StakePoolAccounts { pub stake_pool: Keypair, pub validator_list: Keypair, pub reserve_stake: Keypair, + pub token_program_id: Pubkey, pub pool_mint: Keypair, pub pool_fee_account: Keypair, + pub pool_decimals: u8, pub manager: Keypair, pub staker: Keypair, pub withdraw_authority: Pubkey, @@ -702,58 +861,19 @@ pub struct StakePoolAccounts { } impl StakePoolAccounts { - pub fn new() -> Self { - let stake_pool = Keypair::new(); - let validator_list = Keypair::new(); - let stake_pool_address = &stake_pool.pubkey(); - let (stake_deposit_authority, _) = - find_deposit_authority_program_address(&id(), stake_pool_address); - let (withdraw_authority, _) = - find_withdraw_authority_program_address(&id(), stake_pool_address); - let reserve_stake = Keypair::new(); - let pool_mint = Keypair::new(); - let pool_fee_account = Keypair::new(); - let manager = Keypair::new(); - let staker = Keypair::new(); - + pub fn new_with_deposit_authority(stake_deposit_authority: Keypair) -> Self { Self { - stake_pool, - validator_list, - reserve_stake, - pool_mint, - pool_fee_account, - manager, - staker, - withdraw_authority, - stake_deposit_authority, - stake_deposit_authority_keypair: None, - epoch_fee: state::Fee { - numerator: 1, - denominator: 100, - }, - withdrawal_fee: state::Fee { - numerator: 3, - denominator: 1000, - }, - deposit_fee: state::Fee { - numerator: 1, - denominator: 1000, - }, - referral_fee: 25, - sol_deposit_fee: state::Fee { - numerator: 3, - denominator: 100, - }, - sol_referral_fee: 50, - max_validators: MAX_TEST_VALIDATORS, + stake_deposit_authority: stake_deposit_authority.pubkey(), + stake_deposit_authority_keypair: Some(stake_deposit_authority), + ..Default::default() } } - pub fn new_with_deposit_authority(stake_deposit_authority: Keypair) -> Self { - let mut stake_pool_accounts = Self::new(); - stake_pool_accounts.stake_deposit_authority = stake_deposit_authority.pubkey(); - stake_pool_accounts.stake_deposit_authority_keypair = Some(stake_deposit_authority); - stake_pool_accounts + pub fn new_with_token_program(token_program_id: Pubkey) -> Self { + Self { + token_program_id, + ..Default::default() + } } pub fn calculate_fee(&self, amount: u64) -> u64 { @@ -764,6 +884,11 @@ impl StakePoolAccounts { pool_tokens * self.withdrawal_fee.numerator / self.withdrawal_fee.denominator } + pub fn calculate_inverse_withdrawal_fee(&self, pool_tokens: u64) -> u64 { + pool_tokens * self.withdrawal_fee.denominator + / (self.withdrawal_fee.denominator - self.withdrawal_fee.numerator) + } + pub fn calculate_referral_fee(&self, deposit_fee_collected: u64) -> u64 { deposit_fee_collected * self.referral_fee as u64 / 100 } @@ -787,17 +912,22 @@ impl StakePoolAccounts { banks_client, payer, recent_blockhash, + &self.token_program_id, &self.pool_mint, &self.withdraw_authority, + self.pool_decimals, + &[], ) .await?; create_token_account( banks_client, payer, recent_blockhash, + &self.token_program_id, &self.pool_fee_account, &self.pool_mint.pubkey(), - &self.manager.pubkey(), + &self.manager, + &[], ) .await?; create_independent_stake_account( @@ -820,6 +950,7 @@ impl StakePoolAccounts { &self.stake_pool, &self.validator_list, &self.reserve_stake.pubkey(), + &self.token_program_id, &self.pool_mint.pubkey(), &self.pool_fee_account.pubkey(), &self.manager, @@ -893,7 +1024,7 @@ impl StakePoolAccounts { &self.pool_fee_account.pubkey(), referrer, &self.pool_mint.pubkey(), - &spl_token::id(), + &self.token_program_id, ) } else { instruction::deposit_stake( @@ -909,7 +1040,7 @@ impl StakePoolAccounts { &self.pool_fee_account.pubkey(), referrer, &self.pool_mint.pubkey(), - &spl_token::id(), + &self.token_program_id, ) }; let transaction = Transaction::new_signed_with_payer( @@ -950,7 +1081,7 @@ impl StakePoolAccounts { &self.pool_fee_account.pubkey(), &self.pool_fee_account.pubkey(), &self.pool_mint.pubkey(), - &spl_token::id(), + &self.token_program_id, amount, ) } else { @@ -964,7 +1095,7 @@ impl StakePoolAccounts { &self.pool_fee_account.pubkey(), &self.pool_fee_account.pubkey(), &self.pool_mint.pubkey(), - &spl_token::id(), + &self.token_program_id, amount, ) }; @@ -1008,7 +1139,7 @@ impl StakePoolAccounts { pool_account, &self.pool_fee_account.pubkey(), &self.pool_mint.pubkey(), - &spl_token::id(), + &self.token_program_id, amount, )], Some(&payer.pubkey()), @@ -1048,7 +1179,7 @@ impl StakePoolAccounts { &user.pubkey(), &self.pool_fee_account.pubkey(), &self.pool_mint.pubkey(), - &spl_token::id(), + &self.token_program_id, amount, ) } else { @@ -1062,7 +1193,7 @@ impl StakePoolAccounts { &user.pubkey(), &self.pool_fee_account.pubkey(), &self.pool_mint.pubkey(), - &spl_token::id(), + &self.token_program_id, amount, ) }; @@ -1080,6 +1211,11 @@ impl StakePoolAccounts { .err() } + pub async fn get_stake_pool(&self, banks_client: &mut BanksClient) -> StakePool { + let stake_pool_account = get_account(banks_client, &self.stake_pool.pubkey()).await; + try_from_slice_unchecked::(stake_pool_account.data.as_slice()).unwrap() + } + pub async fn get_validator_list(&self, banks_client: &mut BanksClient) -> ValidatorList { let validator_list_account = get_account(banks_client, &self.validator_list.pubkey()).await; try_from_slice_unchecked::(validator_list_account.data.as_slice()).unwrap() @@ -1133,7 +1269,7 @@ impl StakePoolAccounts { &self.reserve_stake.pubkey(), &self.pool_fee_account.pubkey(), &self.pool_mint.pubkey(), - &spl_token::id(), + &self.token_program_id, )], Some(&payer.pubkey()), &[payer], @@ -1201,7 +1337,7 @@ impl StakePoolAccounts { &self.reserve_stake.pubkey(), &self.pool_fee_account.pubkey(), &self.pool_mint.pubkey(), - &spl_token::id(), + &self.token_program_id, ), instruction::cleanup_removed_validator_entries( &id(), @@ -1228,17 +1364,19 @@ impl StakePoolAccounts { recent_blockhash: &Hash, stake: &Pubkey, validator: &Pubkey, + seed: Option, ) -> Option { let transaction = Transaction::new_signed_with_payer( &[instruction::add_validator_to_pool( &id(), &self.stake_pool.pubkey(), &self.staker.pubkey(), - &payer.pubkey(), + &self.reserve_stake.pubkey(), &self.withdraw_authority, &self.validator_list.pubkey(), stake, validator, + seed, )], Some(&payer.pubkey()), &[payer, &self.staker], @@ -1258,34 +1396,21 @@ impl StakePoolAccounts { banks_client: &mut BanksClient, payer: &Keypair, recent_blockhash: &Hash, - new_authority: &Pubkey, validator_stake: &Pubkey, transient_stake: &Pubkey, - destination_stake: &Keypair, ) -> Option { let transaction = Transaction::new_signed_with_payer( - &[ - system_instruction::create_account( - &payer.pubkey(), - &destination_stake.pubkey(), - 0, - std::mem::size_of::() as u64, - &stake::program::id(), - ), - instruction::remove_validator_from_pool( - &id(), - &self.stake_pool.pubkey(), - &self.staker.pubkey(), - &self.withdraw_authority, - new_authority, - &self.validator_list.pubkey(), - validator_stake, - transient_stake, - &destination_stake.pubkey(), - ), - ], + &[instruction::remove_validator_from_pool( + &id(), + &self.stake_pool.pubkey(), + &self.staker.pubkey(), + &self.withdraw_authority, + &self.validator_list.pubkey(), + validator_stake, + transient_stake, + )], Some(&payer.pubkey()), - &[payer, &self.staker, destination_stake], + &[payer, &self.staker], *recent_blockhash, ); #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 @@ -1411,7 +1536,7 @@ impl StakePoolAccounts { reserve_stake: self.reserve_stake.pubkey(), pool_mint: self.pool_mint.pubkey(), manager_fee_account: self.pool_fee_account.pubkey(), - token_program_id: spl_token::id(), + token_program_id: self.token_program_id, total_lamports: 0, pool_token_supply: 0, last_update_epoch: 0, @@ -1438,18 +1563,100 @@ impl StakePoolAccounts { (stake_pool, validator_list) } } +impl Default for StakePoolAccounts { + fn default() -> Self { + let stake_pool = Keypair::new(); + let validator_list = Keypair::new(); + let stake_pool_address = &stake_pool.pubkey(); + let (stake_deposit_authority, _) = + find_deposit_authority_program_address(&id(), stake_pool_address); + let (withdraw_authority, _) = + find_withdraw_authority_program_address(&id(), stake_pool_address); + let reserve_stake = Keypair::new(); + let pool_mint = Keypair::new(); + let pool_fee_account = Keypair::new(); + let manager = Keypair::new(); + let staker = Keypair::new(); + + Self { + stake_pool, + validator_list, + reserve_stake, + token_program_id: spl_token::id(), + pool_mint, + pool_fee_account, + pool_decimals: 0, + manager, + staker, + withdraw_authority, + stake_deposit_authority, + stake_deposit_authority_keypair: None, + epoch_fee: state::Fee { + numerator: 1, + denominator: 100, + }, + withdrawal_fee: state::Fee { + numerator: 3, + denominator: 1000, + }, + deposit_fee: state::Fee { + numerator: 1, + denominator: 1000, + }, + referral_fee: 25, + sol_deposit_fee: state::Fee { + numerator: 3, + denominator: 100, + }, + sol_referral_fee: 50, + max_validators: MAX_TEST_VALIDATORS, + } + } +} pub async fn simple_add_validator_to_pool( banks_client: &mut BanksClient, payer: &Keypair, recent_blockhash: &Hash, stake_pool_accounts: &StakePoolAccounts, + sol_deposit_authority: Option<&Keypair>, ) -> ValidatorStakeAccount { let validator_stake = ValidatorStakeAccount::new( &stake_pool_accounts.stake_pool.pubkey(), + DEFAULT_VALIDATOR_STAKE_SEED, DEFAULT_TRANSIENT_STAKE_SEED, ); + let rent = banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let current_minimum_delegation = + stake_pool_get_minimum_delegation(banks_client, payer, recent_blockhash).await; + + let pool_token_account = Keypair::new(); + create_token_account( + banks_client, + payer, + recent_blockhash, + &stake_pool_accounts.token_program_id, + &pool_token_account, + &stake_pool_accounts.pool_mint.pubkey(), + payer, + &[], + ) + .await + .unwrap(); + let error = stake_pool_accounts + .deposit_sol( + banks_client, + payer, + recent_blockhash, + &pool_token_account.pubkey(), + stake_rent + current_minimum_delegation, + sol_deposit_authority, + ) + .await; + assert!(error.is_none()); + create_vote( banks_client, payer, @@ -1466,6 +1673,7 @@ pub async fn simple_add_validator_to_pool( recent_blockhash, &validator_stake.stake_account, &validator_stake.vote.pubkey(), + validator_stake.validator_stake_seed, ) .await; assert!(error.is_none()); @@ -1548,9 +1756,11 @@ impl DepositStakeAccount { banks_client, payer, recent_blockhash, + &stake_pool_accounts.token_program_id, &self.pool_account, &stake_pool_accounts.pool_mint.pubkey(), - &self.authority.pubkey(), + &self.authority, + &[], ) .await .unwrap(); @@ -1613,9 +1823,11 @@ pub async fn simple_deposit_stake( banks_client, payer, recent_blockhash, + &stake_pool_accounts.token_program_id, &pool_account, &stake_pool_accounts.pool_mint.pubkey(), - &authority.pubkey(), + &authority, + &[], ) .await .unwrap(); @@ -1695,7 +1907,7 @@ pub fn add_vote_account(program_test: &mut ProgramTest) -> Pubkey { }, &Clock::default(), )); - let vote_account = Account::create( + let vote_account = SolanaAccount::create( ACCOUNT_RENT_EXEMPTION, bincode::serialize::(&vote_state).unwrap(), solana_vote_program::id(), @@ -1731,14 +1943,14 @@ pub fn add_validator_stake_account( delegation: stake::state::Delegation { voter_pubkey: *voter_pubkey, stake: stake_amount, - activation_epoch: 0, + activation_epoch: FIRST_NORMAL_EPOCH, deactivation_epoch: u64::MAX, warmup_cooldown_rate: 0.25, // default }, credits_observed: 0, }; - let stake_account = Account::create( + let stake_account = SolanaAccount::create( stake_amount + STAKE_ACCOUNT_RENT_EXEMPTION, bincode::serialize::(&stake::state::StakeState::Stake( meta, stake, @@ -1749,22 +1961,27 @@ pub fn add_validator_stake_account( Epoch::default(), ); - let (stake_address, _) = find_stake_program_address(&id(), voter_pubkey, stake_pool_pubkey); + let raw_suffix = 0; + let validator_seed_suffix = NonZeroU32::new(raw_suffix); + let (stake_address, _) = find_stake_program_address( + &id(), + voter_pubkey, + stake_pool_pubkey, + validator_seed_suffix, + ); program_test.add_account(stake_address, stake_account); - // Hack the active stake lamports to the current amount given by the runtime. - // Since program_test hasn't been started, there's no usable banks_client for - // fetching the minimum stake delegation. - let active_stake_lamports = stake_amount - LAMPORTS_PER_SOL; + let active_stake_lamports = stake_amount + STAKE_ACCOUNT_RENT_EXEMPTION; validator_list.validators.push(state::ValidatorStakeInfo { status, vote_account_address: *voter_pubkey, active_stake_lamports, transient_stake_lamports: 0, - last_update_epoch: 0, - transient_seed_suffix_start: 0, - transient_seed_suffix_end: 0, + last_update_epoch: FIRST_NORMAL_EPOCH, + transient_seed_suffix: 0, + unused: 0, + validator_seed_suffix: raw_suffix, }); stake_pool.total_lamports += active_stake_lamports; @@ -1785,7 +2002,7 @@ pub fn add_reserve_stake_account( }, lockup: stake::state::Lockup::default(), }; - let reserve_stake_account = Account::create( + let reserve_stake_account = SolanaAccount::create( stake_amount + STAKE_ACCOUNT_RENT_EXEMPTION, bincode::serialize::(&stake::state::StakeState::Initialized( meta, @@ -1807,7 +2024,7 @@ pub fn add_stake_pool_account( // more room for optionals stake_pool_bytes.extend_from_slice(&Pubkey::default().to_bytes()); stake_pool_bytes.extend_from_slice(&Pubkey::default().to_bytes()); - let stake_pool_account = Account::create( + let stake_pool_account = SolanaAccount::create( ACCOUNT_RENT_EXEMPTION, stake_pool_bytes, id(), @@ -1829,7 +2046,7 @@ pub fn add_validator_list_account( validator_list_bytes .append(&mut state::ValidatorStakeInfo::default().try_to_vec().unwrap()); } - let validator_list_account = Account::create( + let validator_list_account = SolanaAccount::create( ACCOUNT_RENT_EXEMPTION, validator_list_bytes, id(), @@ -1841,12 +2058,13 @@ pub fn add_validator_list_account( pub fn add_mint_account( program_test: &mut ProgramTest, + program_id: &Pubkey, mint_key: &Pubkey, mint_authority: &Pubkey, supply: u64, ) { - let mut mint_vec = vec![0u8; spl_token::state::Mint::LEN]; - let mint = spl_token::state::Mint { + let mut mint_vec = vec![0u8; Mint::LEN]; + let mint = Mint { mint_authority: COption::Some(*mint_authority), supply, decimals: 9, @@ -1854,10 +2072,10 @@ pub fn add_mint_account( freeze_authority: COption::None, }; Pack::pack(mint, &mut mint_vec).unwrap(); - let stake_pool_mint = Account::create( + let stake_pool_mint = SolanaAccount::create( ACCOUNT_RENT_EXEMPTION, mint_vec, - spl_token::id(), + *program_id, false, Epoch::default(), ); @@ -1866,26 +2084,27 @@ pub fn add_mint_account( pub fn add_token_account( program_test: &mut ProgramTest, + program_id: &Pubkey, account_key: &Pubkey, mint_key: &Pubkey, owner: &Pubkey, ) { - let mut fee_account_vec = vec![0u8; spl_token::state::Account::LEN]; - let fee_account_data = spl_token::state::Account { + let mut fee_account_vec = vec![0u8; Account::LEN]; + let fee_account_data = Account { mint: *mint_key, owner: *owner, amount: 0, delegate: COption::None, - state: spl_token::state::AccountState::Initialized, + state: spl_token_2022::state::AccountState::Initialized, is_native: COption::None, delegated_amount: 0, close_authority: COption::None, }; Pack::pack(fee_account_data, &mut fee_account_vec).unwrap(); - let fee_account = Account::create( + let fee_account = SolanaAccount::create( ACCOUNT_RENT_EXEMPTION, fee_account_vec, - spl_token::id(), + *program_id, false, Epoch::default(), ); diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index 71b97e5e..bdee3cc9 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -20,7 +20,7 @@ use { }, }; -const HUGE_POOL_SIZE: u32 = 2_950; +const HUGE_POOL_SIZE: u32 = 2_300; const STAKE_AMOUNT: u64 = 200_000_000_000; async fn setup( @@ -38,11 +38,14 @@ async fn setup( ) { let mut program_test = program_test(); let mut vote_account_pubkeys = vec![]; - let mut stake_pool_accounts = StakePoolAccounts::new(); - stake_pool_accounts.max_validators = max_validators; + let stake_pool_accounts = StakePoolAccounts { + max_validators, + ..Default::default() + }; let stake_pool_pubkey = stake_pool_accounts.stake_pool.pubkey(); let (mut stake_pool, mut validator_list) = stake_pool_accounts.state(); + stake_pool.last_update_epoch = FIRST_NORMAL_EPOCH; for _ in 0..max_validators { vote_account_pubkeys.push(add_vote_account(&mut program_test)); @@ -81,18 +84,23 @@ async fn setup( add_mint_account( &mut program_test, + &stake_pool_accounts.token_program_id, &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.withdraw_authority, stake_pool.pool_token_supply, ); add_token_account( &mut program_test, + &stake_pool_accounts.token_program_id, &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.manager.pubkey(), ); let mut context = program_test.start_with_context().await; + let epoch_schedule = context.genesis_config().epoch_schedule; + let slot = epoch_schedule.first_normal_slot + epoch_schedule.slots_per_epoch; + context.warp_to_slot(slot).unwrap(); let vote_pubkey = vote_account_pubkeys[HUGE_POOL_SIZE as usize - 1]; // make stake account @@ -132,9 +140,11 @@ async fn setup( &mut context.banks_client, &context.payer, &context.last_blockhash, + &stake_pool_accounts.token_program_id, &pool_token_account, &stake_pool_accounts.pool_mint.pubkey(), - &user.pubkey(), + &user, + &[], ) .await .unwrap(); @@ -227,8 +237,12 @@ async fn remove_validator_from_pool() { setup(HUGE_POOL_SIZE, HUGE_POOL_SIZE, LAMPORTS_PER_SOL).await; let first_vote = vote_account_pubkeys[0]; - let (stake_address, _) = - find_stake_program_address(&id(), &first_vote, &stake_pool_accounts.stake_pool.pubkey()); + let (stake_address, _) = find_stake_program_address( + &id(), + &first_vote, + &stake_pool_accounts.stake_pool.pubkey(), + None, + ); let transient_stake_seed = u64::MAX; let (transient_stake_address, _) = find_transient_stake_program_address( &id(), @@ -237,17 +251,13 @@ async fn remove_validator_from_pool() { transient_stake_seed, ); - let new_authority = Pubkey::new_unique(); - let destination_stake = Keypair::new(); let error = stake_pool_accounts .remove_validator_from_pool( &mut context.banks_client, &context.payer, &context.last_blockhash, - &new_authority, &stake_address, &transient_stake_address, - &destination_stake, ) .await; assert!(error.is_none()); @@ -258,6 +268,7 @@ async fn remove_validator_from_pool() { &id(), &middle_vote, &stake_pool_accounts.stake_pool.pubkey(), + None, ); let (transient_stake_address, _) = find_transient_stake_program_address( &id(), @@ -266,25 +277,25 @@ async fn remove_validator_from_pool() { transient_stake_seed, ); - let new_authority = Pubkey::new_unique(); - let destination_stake = Keypair::new(); let error = stake_pool_accounts .remove_validator_from_pool( &mut context.banks_client, &context.payer, &context.last_blockhash, - &new_authority, &stake_address, &transient_stake_address, - &destination_stake, ) .await; assert!(error.is_none()); let last_index = HUGE_POOL_SIZE as usize - 1; let last_vote = vote_account_pubkeys[last_index]; - let (stake_address, _) = - find_stake_program_address(&id(), &last_vote, &stake_pool_accounts.stake_pool.pubkey()); + let (stake_address, _) = find_stake_program_address( + &id(), + &last_vote, + &stake_pool_accounts.stake_pool.pubkey(), + None, + ); let (transient_stake_address, _) = find_transient_stake_program_address( &id(), &last_vote, @@ -292,17 +303,13 @@ async fn remove_validator_from_pool() { transient_stake_seed, ); - let new_authority = Pubkey::new_unique(); - let destination_stake = Keypair::new(); let error = stake_pool_accounts .remove_validator_from_pool( &mut context.banks_client, &context.payer, &context.last_blockhash, - &new_authority, &stake_address, &transient_stake_address, - &destination_stake, ) .await; assert!(error.is_none()); @@ -315,20 +322,98 @@ async fn remove_validator_from_pool() { let validator_list = try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); let first_element = &validator_list.validators[0]; - assert_eq!(first_element.status, StakeStatus::ReadyForRemoval); - assert_eq!(first_element.active_stake_lamports, 0); + assert_eq!(first_element.status, StakeStatus::DeactivatingValidator); + assert_eq!( + first_element.active_stake_lamports, + LAMPORTS_PER_SOL + STAKE_ACCOUNT_RENT_EXEMPTION + ); assert_eq!(first_element.transient_stake_lamports, 0); let middle_element = &validator_list.validators[middle_index]; - assert_eq!(middle_element.status, StakeStatus::ReadyForRemoval); - assert_eq!(middle_element.active_stake_lamports, 0); + assert_eq!(middle_element.status, StakeStatus::DeactivatingValidator); + assert_eq!( + middle_element.active_stake_lamports, + LAMPORTS_PER_SOL + STAKE_ACCOUNT_RENT_EXEMPTION + ); assert_eq!(middle_element.transient_stake_lamports, 0); let last_element = &validator_list.validators[last_index]; - assert_eq!(last_element.status, StakeStatus::ReadyForRemoval); - assert_eq!(last_element.active_stake_lamports, 0); + assert_eq!(last_element.status, StakeStatus::DeactivatingValidator); + assert_eq!( + last_element.active_stake_lamports, + LAMPORTS_PER_SOL + STAKE_ACCOUNT_RENT_EXEMPTION + ); assert_eq!(last_element.transient_stake_lamports, 0); + let transaction = Transaction::new_signed_with_payer( + &[instruction::update_validator_list_balance( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), + &validator_list, + &[first_vote], + 0, + /* no_merge = */ false, + )], + Some(&context.payer.pubkey()), + &[&context.payer], + context.last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err(); + assert!(error.is_none()); + + let transaction = Transaction::new_signed_with_payer( + &[instruction::update_validator_list_balance( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), + &validator_list, + &[middle_vote], + middle_index as u32, + /* no_merge = */ false, + )], + Some(&context.payer.pubkey()), + &[&context.payer], + context.last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err(); + assert!(error.is_none()); + + let transaction = Transaction::new_signed_with_payer( + &[instruction::update_validator_list_balance( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), + &validator_list, + &[last_vote], + last_index as u32, + /* no_merge = */ false, + )], + Some(&context.payer.pubkey()), + &[&context.payer], + context.last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err(); + assert!(error.is_none()); + let transaction = Transaction::new_signed_with_payer( &[instruction::cleanup_removed_validator_entries( &id(), @@ -396,7 +481,7 @@ async fn add_validator_to_pool() { let last_index = HUGE_POOL_SIZE as usize - 1; let stake_pool_pubkey = stake_pool_accounts.stake_pool.pubkey(); let (stake_address, _) = - find_stake_program_address(&id(), &test_vote_address, &stake_pool_pubkey); + find_stake_program_address(&id(), &test_vote_address, &stake_pool_pubkey, None); let error = stake_pool_accounts .add_validator_to_pool( @@ -405,6 +490,7 @@ async fn add_validator_to_pool() { &context.last_blockhash, &stake_address, &test_vote_address, + None, ) .await; assert!(error.is_none()); @@ -419,7 +505,10 @@ async fn add_validator_to_pool() { assert_eq!(validator_list.validators.len(), last_index + 1); let last_element = validator_list.validators[last_index]; assert_eq!(last_element.status, StakeStatus::Active); - assert_eq!(last_element.active_stake_lamports, 0); + assert_eq!( + last_element.active_stake_lamports, + LAMPORTS_PER_SOL + STAKE_ACCOUNT_RENT_EXEMPTION + ); assert_eq!(last_element.transient_stake_lamports, 0); assert_eq!(last_element.vote_account_address, test_vote_address); @@ -454,7 +543,10 @@ async fn add_validator_to_pool() { try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); let last_element = validator_list.validators[last_index]; assert_eq!(last_element.status, StakeStatus::Active); - assert_eq!(last_element.active_stake_lamports, 0); + assert_eq!( + last_element.active_stake_lamports, + LAMPORTS_PER_SOL + STAKE_ACCOUNT_RENT_EXEMPTION + ); assert_eq!( last_element.transient_stake_lamports, increase_amount + STAKE_ACCOUNT_RENT_EXEMPTION @@ -514,6 +606,7 @@ async fn deposit_stake() { &id(), &vote_pubkey, &stake_pool_accounts.stake_pool.pubkey(), + None, ); let error = stake_pool_accounts @@ -539,6 +632,7 @@ async fn withdraw() { &id(), &vote_pubkey, &stake_pool_accounts.stake_pool.pubkey(), + None, ); let error = stake_pool_accounts @@ -584,7 +678,7 @@ async fn withdraw() { async fn cleanup_all() { let mut program_test = program_test(); let mut vote_account_pubkeys = vec![]; - let mut stake_pool_accounts = StakePoolAccounts::new(); + let mut stake_pool_accounts = StakePoolAccounts::default(); let max_validators = HUGE_POOL_SIZE; stake_pool_accounts.max_validators = max_validators; diff --git a/program/tests/increase.rs b/program/tests/increase.rs index 70d7cbf7..4bc69f75 100644 --- a/program/tests/increase.rs +++ b/program/tests/increase.rs @@ -30,7 +30,7 @@ async fn setup() -> ( u64, ) { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::default(); let reserve_lamports = 100_000_000_000 + MINIMUM_RESERVE_LAMPORTS; stake_pool_accounts .initialize_stake_pool( @@ -47,6 +47,7 @@ async fn setup() -> ( &payer, &recent_blockhash, &stake_pool_accounts, + None, ) .await; diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index 00d04ff6..cfe8c47c 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -22,6 +22,8 @@ use { transport::TransportError, }, spl_stake_pool::{error, id, instruction, state, MINIMUM_RESERVE_LAMPORTS}, + spl_token_2022::extension::ExtensionType, + test_case::test_case, }; async fn create_required_accounts( @@ -29,24 +31,31 @@ async fn create_required_accounts( payer: &Keypair, recent_blockhash: &Hash, stake_pool_accounts: &StakePoolAccounts, + mint_extensions: &[ExtensionType], ) { create_mint( banks_client, payer, recent_blockhash, + &stake_pool_accounts.token_program_id, &stake_pool_accounts.pool_mint, &stake_pool_accounts.withdraw_authority, + stake_pool_accounts.pool_decimals, + mint_extensions, ) .await .unwrap(); + let required_extensions = ExtensionType::get_required_init_account_extensions(mint_extensions); create_token_account( banks_client, payer, recent_blockhash, + &stake_pool_accounts.token_program_id, &stake_pool_accounts.pool_fee_account, &stake_pool_accounts.pool_mint.pubkey(), - &stake_pool_accounts.manager.pubkey(), + &stake_pool_accounts.manager, + &required_extensions, ) .await .unwrap(); @@ -66,10 +75,12 @@ async fn create_required_accounts( .await; } +#[test_case(spl_token::id(); "token")] +#[test_case(spl_token_2022::id(); "token-2022")] #[tokio::test] -async fn success() { +async fn success(token_program_id: Pubkey) { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::new_with_token_program(token_program_id); stake_pool_accounts .initialize_stake_pool( &mut banks_client, @@ -99,7 +110,7 @@ async fn success() { #[tokio::test] async fn fail_double_initialize() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::default(); stake_pool_accounts .initialize_stake_pool( &mut banks_client, @@ -112,8 +123,10 @@ async fn fail_double_initialize() { let latest_blockhash = banks_client.get_latest_blockhash().await.unwrap(); - let mut second_stake_pool_accounts = StakePoolAccounts::new(); - second_stake_pool_accounts.stake_pool = stake_pool_accounts.stake_pool; + let second_stake_pool_accounts = StakePoolAccounts { + stake_pool: stake_pool_accounts.stake_pool, + ..Default::default() + }; let transaction_error = second_stake_pool_accounts .initialize_stake_pool( @@ -140,7 +153,7 @@ async fn fail_double_initialize() { #[tokio::test] async fn fail_with_already_initialized_validator_list() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::default(); stake_pool_accounts .initialize_stake_pool( &mut banks_client, @@ -153,8 +166,10 @@ async fn fail_with_already_initialized_validator_list() { let latest_blockhash = banks_client.get_latest_blockhash().await.unwrap(); - let mut second_stake_pool_accounts = StakePoolAccounts::new(); - second_stake_pool_accounts.validator_list = stake_pool_accounts.validator_list; + let second_stake_pool_accounts = StakePoolAccounts { + validator_list: stake_pool_accounts.validator_list, + ..Default::default() + }; let transaction_error = second_stake_pool_accounts .initialize_stake_pool( @@ -181,10 +196,12 @@ async fn fail_with_already_initialized_validator_list() { #[tokio::test] async fn fail_with_high_fee() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let mut stake_pool_accounts = StakePoolAccounts::new(); - stake_pool_accounts.epoch_fee = state::Fee { - numerator: 100001, - denominator: 100000, + let stake_pool_accounts = StakePoolAccounts { + epoch_fee: state::Fee { + numerator: 100_001, + denominator: 100_000, + }, + ..Default::default() }; let transaction_error = stake_pool_accounts @@ -212,10 +229,12 @@ async fn fail_with_high_fee() { #[tokio::test] async fn fail_with_high_withdrawal_fee() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let mut stake_pool_accounts = StakePoolAccounts::new(); - stake_pool_accounts.withdrawal_fee = state::Fee { - numerator: 100_001, - denominator: 100_000, + let stake_pool_accounts = StakePoolAccounts { + withdrawal_fee: state::Fee { + numerator: 100_001, + denominator: 100_000, + }, + ..Default::default() }; let transaction_error = stake_pool_accounts @@ -245,13 +264,14 @@ async fn fail_with_high_withdrawal_fee() { #[tokio::test] async fn fail_with_wrong_max_validators() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::default(); create_required_accounts( &mut banks_client, &payer, &recent_blockhash, &stake_pool_accounts, + &[], ) .await; @@ -332,7 +352,7 @@ async fn fail_with_wrong_max_validators() { #[tokio::test] async fn fail_with_wrong_mint_authority() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::default(); let wrong_mint = Keypair::new(); create_required_accounts( @@ -340,6 +360,7 @@ async fn fail_with_wrong_mint_authority() { &payer, &recent_blockhash, &stake_pool_accounts, + &[], ) .await; @@ -348,8 +369,11 @@ async fn fail_with_wrong_mint_authority() { &mut banks_client, &payer, &recent_blockhash, + &stake_pool_accounts.token_program_id, &wrong_mint, &stake_pool_accounts.withdraw_authority, + stake_pool_accounts.pool_decimals, + &[], ) .await .unwrap(); @@ -361,6 +385,7 @@ async fn fail_with_wrong_mint_authority() { &stake_pool_accounts.stake_pool, &stake_pool_accounts.validator_list, &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.token_program_id, &wrong_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.manager, @@ -384,7 +409,7 @@ async fn fail_with_wrong_mint_authority() { _, InstructionError::Custom(error_index), )) => { - let program_error = error::StakePoolError::WrongAccountMint as u32; + let program_error = error::StakePoolError::InvalidFeeAccount as u32; assert_eq!(error_index, program_error); } _ => panic!("Wrong error occurs while try to initialize stake pool with wrong mint authority of pool fee account"), @@ -394,13 +419,14 @@ async fn fail_with_wrong_mint_authority() { #[tokio::test] async fn fail_with_freeze_authority() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::default(); create_required_accounts( &mut banks_client, &payer, &recent_blockhash, &stake_pool_accounts, + &[], ) .await; @@ -438,9 +464,11 @@ async fn fail_with_freeze_authority() { &mut banks_client, &payer, &recent_blockhash, + &stake_pool_accounts.token_program_id, &pool_fee_account, &wrong_mint.pubkey(), - &stake_pool_accounts.manager.pubkey(), + &stake_pool_accounts.manager, + &[], ) .await .unwrap(); @@ -452,6 +480,7 @@ async fn fail_with_freeze_authority() { &stake_pool_accounts.stake_pool, &stake_pool_accounts.validator_list, &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.token_program_id, &wrong_mint.pubkey(), &pool_fee_account.pubkey(), &stake_pool_accounts.manager, @@ -480,10 +509,199 @@ async fn fail_with_freeze_authority() { ); } +#[tokio::test] +async fn success_with_supported_extensions() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new_with_token_program(spl_token_2022::id()); + + let mint_extensions = vec![ExtensionType::TransferFeeConfig]; + create_required_accounts( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + &mint_extensions, + ) + .await; + + let mut account_extensions = + ExtensionType::get_required_init_account_extensions(&mint_extensions); + account_extensions.push(ExtensionType::CpiGuard); + let pool_fee_account = Keypair::new(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.token_program_id, + &pool_fee_account, + &stake_pool_accounts.pool_mint.pubkey(), + &stake_pool_accounts.manager, + &account_extensions, + ) + .await + .unwrap(); + + create_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.stake_pool, + &stake_pool_accounts.validator_list, + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.token_program_id, + &stake_pool_accounts.pool_mint.pubkey(), + &pool_fee_account.pubkey(), + &stake_pool_accounts.manager, + &stake_pool_accounts.staker.pubkey(), + &stake_pool_accounts.withdraw_authority, + &None, + &stake_pool_accounts.epoch_fee, + &stake_pool_accounts.withdrawal_fee, + &stake_pool_accounts.deposit_fee, + stake_pool_accounts.referral_fee, + &stake_pool_accounts.sol_deposit_fee, + stake_pool_accounts.sol_referral_fee, + stake_pool_accounts.max_validators, + ) + .await + .unwrap(); +} + +#[tokio::test] +async fn fail_with_unsupported_mint_extension() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new_with_token_program(spl_token_2022::id()); + + let mint_extensions = vec![ExtensionType::NonTransferable]; + create_required_accounts( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + &mint_extensions, + ) + .await; + + let required_extensions = ExtensionType::get_required_init_account_extensions(&mint_extensions); + let pool_fee_account = Keypair::new(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.token_program_id, + &pool_fee_account, + &stake_pool_accounts.pool_mint.pubkey(), + &stake_pool_accounts.manager, + &required_extensions, + ) + .await + .unwrap(); + + let error = create_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.stake_pool, + &stake_pool_accounts.validator_list, + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.token_program_id, + &stake_pool_accounts.pool_mint.pubkey(), + &pool_fee_account.pubkey(), + &stake_pool_accounts.manager, + &stake_pool_accounts.staker.pubkey(), + &stake_pool_accounts.withdraw_authority, + &None, + &stake_pool_accounts.epoch_fee, + &stake_pool_accounts.withdrawal_fee, + &stake_pool_accounts.deposit_fee, + stake_pool_accounts.referral_fee, + &stake_pool_accounts.sol_deposit_fee, + stake_pool_accounts.sol_referral_fee, + stake_pool_accounts.max_validators, + ) + .await + .err() + .unwrap() + .unwrap(); + + assert_eq!( + error, + TransactionError::InstructionError( + 2, + InstructionError::Custom(error::StakePoolError::UnsupportedMintExtension as u32), + ) + ); +} + +#[tokio::test] +async fn fail_with_unsupported_account_extension() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts::new_with_token_program(spl_token_2022::id()); + + create_required_accounts( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts, + &[], + ) + .await; + + let extensions = vec![ExtensionType::MemoTransfer]; + let pool_fee_account = Keypair::new(); + create_token_account( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.token_program_id, + &pool_fee_account, + &stake_pool_accounts.pool_mint.pubkey(), + &stake_pool_accounts.manager, + &extensions, + ) + .await + .unwrap(); + + let error = create_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &stake_pool_accounts.stake_pool, + &stake_pool_accounts.validator_list, + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.token_program_id, + &stake_pool_accounts.pool_mint.pubkey(), + &pool_fee_account.pubkey(), + &stake_pool_accounts.manager, + &stake_pool_accounts.staker.pubkey(), + &stake_pool_accounts.withdraw_authority, + &None, + &stake_pool_accounts.epoch_fee, + &stake_pool_accounts.withdrawal_fee, + &stake_pool_accounts.deposit_fee, + stake_pool_accounts.referral_fee, + &stake_pool_accounts.sol_deposit_fee, + stake_pool_accounts.sol_referral_fee, + stake_pool_accounts.max_validators, + ) + .await + .err() + .unwrap() + .unwrap(); + + assert_eq!( + error, + TransactionError::InstructionError( + 2, + InstructionError::Custom(error::StakePoolError::UnsupportedFeeAccountExtension as u32), + ) + ); +} + #[tokio::test] async fn fail_with_wrong_token_program_id() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::default(); let wrong_token_program = Keypair::new(); @@ -491,8 +709,11 @@ async fn fail_with_wrong_token_program_id() { &mut banks_client, &payer, &recent_blockhash, + &stake_pool_accounts.token_program_id, &stake_pool_accounts.pool_mint, &stake_pool_accounts.withdraw_authority, + stake_pool_accounts.pool_decimals, + &[], ) .await .unwrap(); @@ -501,9 +722,11 @@ async fn fail_with_wrong_token_program_id() { &mut banks_client, &payer, &recent_blockhash, + &stake_pool_accounts.token_program_id, &stake_pool_accounts.pool_fee_account, &stake_pool_accounts.pool_mint.pubkey(), - &stake_pool_accounts.manager.pubkey(), + &stake_pool_accounts.manager, + &[], ) .await .unwrap(); @@ -583,7 +806,7 @@ async fn fail_with_wrong_token_program_id() { #[tokio::test] async fn fail_with_fee_owned_by_wrong_token_program_id() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::default(); let wrong_token_program = Keypair::new(); @@ -591,8 +814,11 @@ async fn fail_with_fee_owned_by_wrong_token_program_id() { &mut banks_client, &payer, &recent_blockhash, + &stake_pool_accounts.token_program_id, &stake_pool_accounts.pool_mint, &stake_pool_accounts.withdraw_authority, + stake_pool_accounts.pool_decimals, + &[], ) .await .unwrap(); @@ -688,14 +914,17 @@ async fn fail_with_fee_owned_by_wrong_token_program_id() { #[tokio::test] async fn fail_with_wrong_fee_account() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::default(); create_mint( &mut banks_client, &payer, &recent_blockhash, + &stake_pool_accounts.token_program_id, &stake_pool_accounts.pool_mint, &stake_pool_accounts.withdraw_authority, + stake_pool_accounts.pool_decimals, + &[], ) .await .unwrap(); @@ -725,6 +954,7 @@ async fn fail_with_wrong_fee_account() { &stake_pool_accounts.stake_pool, &stake_pool_accounts.validator_list, &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.token_program_id, &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.manager, @@ -746,16 +976,17 @@ async fn fail_with_wrong_fee_account() { assert_eq!( transaction_error, - TransactionError::InstructionError(2, InstructionError::IncorrectProgramId) + TransactionError::InstructionError(2, InstructionError::UninitializedAccount) ); } #[tokio::test] async fn fail_with_wrong_withdraw_authority() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let mut stake_pool_accounts = StakePoolAccounts::new(); - - stake_pool_accounts.withdraw_authority = Keypair::new().pubkey(); + let stake_pool_accounts = StakePoolAccounts { + withdraw_authority: Keypair::new().pubkey(), + ..Default::default() + }; let transaction_error = stake_pool_accounts .initialize_stake_pool( @@ -785,13 +1016,14 @@ async fn fail_with_wrong_withdraw_authority() { #[tokio::test] async fn fail_with_not_rent_exempt_pool() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::default(); create_required_accounts( &mut banks_client, &payer, &recent_blockhash, &stake_pool_accounts, + &[], ) .await; @@ -863,13 +1095,14 @@ async fn fail_with_not_rent_exempt_pool() { #[tokio::test] async fn fail_with_not_rent_exempt_validator_list() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::default(); create_required_accounts( &mut banks_client, &payer, &recent_blockhash, &stake_pool_accounts, + &[], ) .await; @@ -943,13 +1176,14 @@ async fn fail_with_not_rent_exempt_validator_list() { #[tokio::test] async fn fail_without_manager_signature() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::default(); create_required_accounts( &mut banks_client, &payer, &recent_blockhash, &stake_pool_accounts, + &[], ) .await; @@ -1040,15 +1274,18 @@ async fn fail_without_manager_signature() { #[tokio::test] async fn fail_with_pre_minted_pool_tokens() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::default(); let mint_authority = Keypair::new(); create_mint( &mut banks_client, &payer, &recent_blockhash, + &stake_pool_accounts.token_program_id, &stake_pool_accounts.pool_mint, &mint_authority.pubkey(), + stake_pool_accounts.pool_decimals, + &[], ) .await .unwrap(); @@ -1057,9 +1294,11 @@ async fn fail_with_pre_minted_pool_tokens() { &mut banks_client, &payer, &recent_blockhash, + &stake_pool_accounts.token_program_id, &stake_pool_accounts.pool_fee_account, &stake_pool_accounts.pool_mint.pubkey(), - &stake_pool_accounts.manager.pubkey(), + &stake_pool_accounts.manager, + &[], ) .await .unwrap(); @@ -1068,6 +1307,7 @@ async fn fail_with_pre_minted_pool_tokens() { &mut banks_client, &payer, &recent_blockhash, + &stake_pool_accounts.token_program_id, &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), &mint_authority, @@ -1083,6 +1323,7 @@ async fn fail_with_pre_minted_pool_tokens() { &stake_pool_accounts.stake_pool, &stake_pool_accounts.validator_list, &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.token_program_id, &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.manager, @@ -1116,7 +1357,7 @@ async fn fail_with_pre_minted_pool_tokens() { #[tokio::test] async fn fail_with_bad_reserve() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::default(); let wrong_authority = Pubkey::new_unique(); create_required_accounts( @@ -1124,6 +1365,7 @@ async fn fail_with_bad_reserve() { &payer, &recent_blockhash, &stake_pool_accounts, + &[], ) .await; @@ -1150,6 +1392,7 @@ async fn fail_with_bad_reserve() { &stake_pool_accounts.stake_pool, &stake_pool_accounts.validator_list, &bad_stake.pubkey(), + &stake_pool_accounts.token_program_id, &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.manager, @@ -1201,6 +1444,7 @@ async fn fail_with_bad_reserve() { &stake_pool_accounts.stake_pool, &stake_pool_accounts.validator_list, &bad_stake.pubkey(), + &stake_pool_accounts.token_program_id, &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.manager, @@ -1255,6 +1499,7 @@ async fn fail_with_bad_reserve() { &stake_pool_accounts.stake_pool, &stake_pool_accounts.validator_list, &bad_stake.pubkey(), + &stake_pool_accounts.token_program_id, &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.manager, @@ -1310,6 +1555,7 @@ async fn fail_with_bad_reserve() { &stake_pool_accounts.stake_pool, &stake_pool_accounts.validator_list, &bad_stake.pubkey(), + &stake_pool_accounts.token_program_id, &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.manager, @@ -1342,7 +1588,7 @@ async fn fail_with_bad_reserve() { #[tokio::test] async fn success_with_extra_reserve_lamports() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::default(); let init_lamports = 1_000_000_000_000; stake_pool_accounts .initialize_stake_pool( diff --git a/program/tests/set_deposit_fee.rs b/program/tests/set_deposit_fee.rs index 19025d37..85397ffb 100644 --- a/program/tests/set_deposit_fee.rs +++ b/program/tests/set_deposit_fee.rs @@ -21,7 +21,7 @@ use { async fn setup(fee: Option) -> (ProgramTestContext, StakePoolAccounts, Fee) { let mut context = program_test().start_with_context().await; - let mut stake_pool_accounts = StakePoolAccounts::new(); + let mut stake_pool_accounts = StakePoolAccounts::default(); if let Some(fee) = fee { stake_pool_accounts.deposit_fee = fee; } diff --git a/program/tests/set_epoch_fee.rs b/program/tests/set_epoch_fee.rs index 0f33acbd..aff29f1e 100644 --- a/program/tests/set_epoch_fee.rs +++ b/program/tests/set_epoch_fee.rs @@ -21,7 +21,7 @@ use { async fn setup() -> (ProgramTestContext, StakePoolAccounts, Fee) { let mut context = program_test().start_with_context().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::default(); stake_pool_accounts .initialize_stake_pool( &mut context.banks_client, @@ -176,7 +176,7 @@ async fn fail_high_fee() { #[tokio::test] async fn fail_not_updated() { let mut context = program_test().start_with_context().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::default(); stake_pool_accounts .initialize_stake_pool( &mut context.banks_client, diff --git a/program/tests/set_funding_authority.rs b/program/tests/set_funding_authority.rs index c719a780..0d51227d 100644 --- a/program/tests/set_funding_authority.rs +++ b/program/tests/set_funding_authority.rs @@ -27,7 +27,7 @@ use { async fn setup() -> (BanksClient, Keypair, Hash, StakePoolAccounts, Keypair) { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::default(); stake_pool_accounts .initialize_stake_pool( &mut banks_client, diff --git a/program/tests/set_manager.rs b/program/tests/set_manager.rs index f813d429..e1200f5d 100644 --- a/program/tests/set_manager.rs +++ b/program/tests/set_manager.rs @@ -30,7 +30,7 @@ async fn setup() -> ( Keypair, ) { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::default(); stake_pool_accounts .initialize_stake_pool( &mut banks_client, @@ -47,9 +47,11 @@ async fn setup() -> ( &mut banks_client, &payer, &recent_blockhash, + &stake_pool_accounts.token_program_id, &new_pool_fee, &stake_pool_accounts.pool_mint.pubkey(), - &new_manager.pubkey(), + &new_manager, + &[], ) .await .unwrap(); @@ -219,7 +221,7 @@ async fn test_set_manager_without_new_signature() { #[tokio::test] async fn test_set_manager_with_wrong_mint_for_pool_fee_acc() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::default(); stake_pool_accounts .initialize_stake_pool( &mut banks_client, @@ -239,8 +241,11 @@ async fn test_set_manager_with_wrong_mint_for_pool_fee_acc() { &mut banks_client, &payer, &recent_blockhash, + &stake_pool_accounts.token_program_id, &new_mint, &new_withdraw_auth.pubkey(), + 0, + &[], ) .await .unwrap(); @@ -248,9 +253,11 @@ async fn test_set_manager_with_wrong_mint_for_pool_fee_acc() { &mut banks_client, &payer, &recent_blockhash, + &stake_pool_accounts.token_program_id, &new_pool_fee, &new_mint.pubkey(), - &new_manager.pubkey(), + &new_manager, + &[], ) .await .unwrap(); @@ -282,7 +289,7 @@ async fn test_set_manager_with_wrong_mint_for_pool_fee_acc() { _, InstructionError::Custom(error_index), )) => { - let program_error = error::StakePoolError::WrongAccountMint as u32; + let program_error = error::StakePoolError::InvalidFeeAccount as u32; assert_eq!(error_index, program_error); } _ => panic!("Wrong error occurs while try to set new manager with wrong mint"), diff --git a/program/tests/set_preferred.rs b/program/tests/set_preferred.rs index 43e3251f..8c280277 100644 --- a/program/tests/set_preferred.rs +++ b/program/tests/set_preferred.rs @@ -30,7 +30,7 @@ async fn setup() -> ( ValidatorStakeAccount, ) { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::default(); stake_pool_accounts .initialize_stake_pool( &mut banks_client, @@ -46,6 +46,7 @@ async fn setup() -> ( &payer, &recent_blockhash, &stake_pool_accounts, + None, ) .await; @@ -229,17 +230,13 @@ async fn fail_ready_for_removal() { &stake_pool_accounts.stake_pool.pubkey(), transient_stake_seed, ); - let new_authority = Pubkey::new_unique(); - let destination_stake = Keypair::new(); let remove_err = stake_pool_accounts .remove_validator_from_pool( &mut banks_client, &payer, &recent_blockhash, - &new_authority, &validator_stake_account.stake_account, &transient_stake_address, - &destination_stake, ) .await; assert!(remove_err.is_none()); diff --git a/program/tests/set_referral_fee.rs b/program/tests/set_referral_fee.rs index f4a1afbb..829a2fb6 100644 --- a/program/tests/set_referral_fee.rs +++ b/program/tests/set_referral_fee.rs @@ -21,7 +21,7 @@ use { async fn setup(fee: Option) -> (ProgramTestContext, StakePoolAccounts, u8) { let mut context = program_test().start_with_context().await; - let mut stake_pool_accounts = StakePoolAccounts::new(); + let mut stake_pool_accounts = StakePoolAccounts::default(); if let Some(fee) = fee { stake_pool_accounts.referral_fee = fee; } diff --git a/program/tests/set_staker.rs b/program/tests/set_staker.rs index 0121493b..ab2e0b29 100644 --- a/program/tests/set_staker.rs +++ b/program/tests/set_staker.rs @@ -23,7 +23,7 @@ use { async fn setup() -> (BanksClient, Keypair, Hash, StakePoolAccounts, Keypair) { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::default(); stake_pool_accounts .initialize_stake_pool( &mut banks_client, diff --git a/program/tests/set_withdrawal_fee.rs b/program/tests/set_withdrawal_fee.rs index 81b7152d..1ca7df81 100644 --- a/program/tests/set_withdrawal_fee.rs +++ b/program/tests/set_withdrawal_fee.rs @@ -21,7 +21,7 @@ use { async fn setup(fee: Option) -> (ProgramTestContext, StakePoolAccounts, Fee) { let mut context = program_test().start_with_context().await; - let mut stake_pool_accounts = StakePoolAccounts::new(); + let mut stake_pool_accounts = StakePoolAccounts::default(); if let Some(fee) = fee { stake_pool_accounts.withdrawal_fee = fee; } @@ -619,7 +619,7 @@ async fn fail_high_sol_fee_increase_from_0() { #[tokio::test] async fn fail_not_updated() { let mut context = program_test().start_with_context().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::default(); stake_pool_accounts .initialize_stake_pool( &mut context.banks_client, diff --git a/program/tests/update_pool_token_metadata.rs b/program/tests/update_pool_token_metadata.rs index 393ee9ed..881d7f0b 100644 --- a/program/tests/update_pool_token_metadata.rs +++ b/program/tests/update_pool_token_metadata.rs @@ -24,7 +24,7 @@ async fn setup() -> (ProgramTestContext, StakePoolAccounts) { let mut context = program_test_with_metadata_program() .start_with_context() .await; - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::default(); stake_pool_accounts .initialize_stake_pool( &mut context.banks_client, diff --git a/program/tests/update_stake_pool_balance.rs b/program/tests/update_stake_pool_balance.rs index 0801d1af..c924e625 100644 --- a/program/tests/update_stake_pool_balance.rs +++ b/program/tests/update_stake_pool_balance.rs @@ -11,18 +11,28 @@ use { solana_program_test::*, solana_sdk::{ signature::{Keypair, Signer}, + stake, transaction::TransactionError, }, spl_stake_pool::{error::StakePoolError, state::StakePool, MINIMUM_RESERVE_LAMPORTS}, + std::num::NonZeroU32, }; -async fn setup() -> ( +const NUM_VALIDATORS: u64 = 3; + +async fn setup( + num_validators: u64, +) -> ( ProgramTestContext, StakePoolAccounts, Vec, + u64, ) { let mut context = program_test().start_with_context().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let slot = context.genesis_config().epoch_schedule.first_normal_slot; + context.warp_to_slot(slot).unwrap(); + + let stake_pool_accounts = StakePoolAccounts::default(); stake_pool_accounts .initialize_stake_pool( &mut context.banks_client, @@ -33,38 +43,87 @@ async fn setup() -> ( .await .unwrap(); - // Add several accounts - let mut stake_accounts: Vec = vec![]; - const STAKE_ACCOUNTS: u64 = 3; - for _ in 0..STAKE_ACCOUNTS { - let validator_stake_account = simple_add_validator_to_pool( + let rent = context.banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let current_minimum_delegation = stake_pool_get_minimum_delegation( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; + + let error = stake_pool_accounts + .deposit_sol( &mut context.banks_client, &context.payer, &context.last_blockhash, - &stake_pool_accounts, + &stake_pool_accounts.pool_fee_account.pubkey(), + (stake_rent + current_minimum_delegation) * num_validators, + None, ) .await; + assert!(error.is_none()); - let _deposit_info = simple_deposit_stake( + // Add several accounts + let mut stake_accounts: Vec = vec![]; + for i in 0..num_validators { + let stake_account = ValidatorStakeAccount::new( + &stake_pool_accounts.stake_pool.pubkey(), + NonZeroU32::new(i as u32), + u64::MAX, + ); + create_vote( &mut context.banks_client, &context.payer, &context.last_blockhash, - &stake_pool_accounts, - &validator_stake_account, - TEST_STAKE_AMOUNT, + &stake_account.validator, + &stake_account.vote, ) - .await - .unwrap(); + .await; - stake_accounts.push(validator_stake_account); + let error = stake_pool_accounts + .add_validator_to_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_account.stake_account, + &stake_account.vote.pubkey(), + stake_account.validator_stake_seed, + ) + .await; + assert!(error.is_none()); + + let mut deposit_account = DepositStakeAccount::new_with_vote( + stake_account.vote.pubkey(), + stake_account.stake_account, + TEST_STAKE_AMOUNT, + ); + deposit_account + .create_and_delegate( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; + + deposit_account + .deposit_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + ) + .await; + + stake_accounts.push(stake_account); } - (context, stake_pool_accounts, stake_accounts) + (context, stake_pool_accounts, stake_accounts, slot) } #[tokio::test] async fn success() { - let (mut context, stake_pool_accounts, stake_accounts) = setup().await; + let (mut context, stake_pool_accounts, stake_accounts, slot) = setup(NUM_VALIDATORS).await; let pre_fee = get_token_balance( &mut context.banks_client, @@ -108,11 +167,8 @@ async fn success() { } // Update epoch - let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; - context - .warp_to_slot(first_normal_slot + slots_per_epoch) - .unwrap(); + context.warp_to_slot(slot + slots_per_epoch).unwrap(); // Update list and pool let error = stake_pool_accounts @@ -172,8 +228,8 @@ async fn success() { } #[tokio::test] -async fn success_ignoring_extra_lamports() { - let (mut context, stake_pool_accounts, stake_accounts) = setup().await; +async fn success_absorbing_extra_lamports() { + let (mut context, stake_pool_accounts, stake_accounts, slot) = setup(NUM_VALIDATORS).await; let pre_balance = get_validator_list_sum( &mut context.banks_client, @@ -204,7 +260,7 @@ async fn success_ignoring_extra_lamports() { .await; assert!(error.is_none()); - // Transfer extra funds, should not be taken into account + // Transfer extra funds, will be absorbed during update const EXTRA_STAKE_AMOUNT: u64 = 1_000_000; for stake_account in &stake_accounts { transfer( @@ -217,12 +273,12 @@ async fn success_ignoring_extra_lamports() { .await; } + let extra_lamports = EXTRA_STAKE_AMOUNT * stake_accounts.len() as u64; + let expected_fee = stake_pool.calc_epoch_fee_amount(extra_lamports).unwrap(); + // Update epoch - let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; - context - .warp_to_slot(first_normal_slot + slots_per_epoch) - .unwrap(); + context.warp_to_slot(slot + slots_per_epoch).unwrap(); // Update list and pool let error = stake_pool_accounts @@ -240,26 +296,26 @@ async fn success_ignoring_extra_lamports() { .await; assert!(error.is_none()); - // Check fee + // Check extra lamports are absorbed and fee'd as rewards let post_balance = get_validator_list_sum( &mut context.banks_client, &stake_pool_accounts.reserve_stake.pubkey(), &stake_pool_accounts.validator_list.pubkey(), ) .await; - assert_eq!(post_balance, pre_balance); + assert_eq!(post_balance, pre_balance + extra_lamports); let pool_token_supply = get_token_supply( &mut context.banks_client, &stake_pool_accounts.pool_mint.pubkey(), ) .await; - assert_eq!(pool_token_supply, pre_token_supply); + assert_eq!(pool_token_supply, pre_token_supply + expected_fee); } #[tokio::test] async fn fail_with_wrong_validator_list() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let mut stake_pool_accounts = StakePoolAccounts::new(); + let mut stake_pool_accounts = StakePoolAccounts::default(); stake_pool_accounts .initialize_stake_pool( &mut banks_client, @@ -293,7 +349,7 @@ async fn fail_with_wrong_validator_list() { #[tokio::test] async fn fail_with_wrong_pool_fee_account() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let mut stake_pool_accounts = StakePoolAccounts::new(); + let mut stake_pool_accounts = StakePoolAccounts::default(); stake_pool_accounts .initialize_stake_pool( &mut banks_client, @@ -327,7 +383,7 @@ async fn fail_with_wrong_pool_fee_account() { #[tokio::test] async fn fail_with_wrong_reserve() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let mut stake_pool_accounts = StakePoolAccounts::new(); + let mut stake_pool_accounts = StakePoolAccounts::default(); stake_pool_accounts .initialize_stake_pool( &mut banks_client, diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index fa1e38da..e146ec12 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -8,18 +8,21 @@ use { solana_program::{borsh::try_from_slice_unchecked, program_pack::Pack, pubkey::Pubkey, stake}, solana_program_test::*, solana_sdk::{ - signature::{Keypair, Signer}, + instruction::InstructionError, + signature::Signer, stake::state::{Authorized, Lockup, StakeState}, system_instruction, - transaction::Transaction, + transaction::{Transaction, TransactionError}, }, spl_stake_pool::{ - find_transient_stake_program_address, find_withdraw_authority_program_address, id, - instruction, + error::StakePoolError, + find_stake_program_address, find_transient_stake_program_address, + find_withdraw_authority_program_address, id, instruction, state::{StakePool, StakeStatus, ValidatorList}, MAX_VALIDATORS_TO_UPDATE, MINIMUM_RESERVE_LAMPORTS, }, spl_token::state::Mint, + std::num::NonZeroU32, }; async fn setup( @@ -39,8 +42,8 @@ async fn setup( let mut slot = first_normal_slot; context.warp_to_slot(slot).unwrap(); - let reserve_stake_amount = TEST_STAKE_AMOUNT * num_validators as u64; - let stake_pool_accounts = StakePoolAccounts::new(); + let reserve_stake_amount = TEST_STAKE_AMOUNT * 2 * num_validators as u64; + let stake_pool_accounts = StakePoolAccounts::default(); stake_pool_accounts .initialize_stake_pool( &mut context.banks_client, @@ -54,9 +57,12 @@ async fn setup( // Add several accounts with some stake let mut stake_accounts: Vec = vec![]; let mut deposit_accounts: Vec = vec![]; - for _ in 0..num_validators { - let stake_account = - ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), u64::MAX); + for i in 0..num_validators { + let stake_account = ValidatorStakeAccount::new( + &stake_pool_accounts.stake_pool.pubkey(), + NonZeroU32::new(i as u32), + u64::MAX, + ); create_vote( &mut context.banks_client, &context.payer, @@ -73,6 +79,7 @@ async fn setup( &context.last_blockhash, &stake_account.stake_account, &stake_account.vote.pubkey(), + stake_account.validator_stake_seed, ) .await; assert!(error.is_none()); @@ -152,7 +159,7 @@ async fn setup( } #[tokio::test] -async fn success() { +async fn success_with_normal() { let num_validators = 5; let ( mut context, @@ -167,18 +174,23 @@ async fn success() { // Check current balance in the list let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_pool_info = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data).unwrap(); + let validator_list_sum = get_validator_list_sum( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + assert_eq!(stake_pool.total_lamports, validator_list_sum); // initially, have all of the deposits plus their rent, and the reserve stake let initial_lamports = (validator_lamports + stake_rent) * num_validators as u64 + reserve_lamports; - assert_eq!( - get_validator_list_sum( - &mut context.banks_client, - &stake_pool_accounts.reserve_stake.pubkey(), - &stake_pool_accounts.validator_list.pubkey() - ) - .await, - initial_lamports, - ); + assert_eq!(validator_list_sum, initial_lamports); // Simulate rewards for stake_account in &stake_accounts { @@ -345,6 +357,16 @@ async fn merge_into_validator_stake() { .await; // Increase stake to all validators + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let current_minimum_delegation = stake_pool_get_minimum_delegation( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; + let available_lamports = + reserve_lamports - (stake_rent + current_minimum_delegation) * stake_accounts.len() as u64; + let increase_amount = available_lamports / stake_accounts.len() as u64; for stake_account in &stake_accounts { let error = stake_pool_accounts .increase_validator_stake( @@ -354,7 +376,7 @@ async fn merge_into_validator_stake() { &stake_account.transient_stake_account, &stake_account.stake_account, &stake_account.vote.pubkey(), - reserve_lamports / stake_accounts.len() as u64, + increase_amount, stake_account.transient_stake_seed, ) .await; @@ -440,17 +462,7 @@ async fn merge_into_validator_stake() { // Check validator stake accounts have the expected balance now: // validator stake account minimum + deposited lamports + rents + increased lamports - let stake_rent = rent.minimum_balance(std::mem::size_of::()); - let current_minimum_delegation = stake_pool_get_minimum_delegation( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - ) - .await; - let expected_lamports = current_minimum_delegation - + lamports - + reserve_lamports / stake_accounts.len() as u64 - + stake_rent; + let expected_lamports = current_minimum_delegation + lamports + increase_amount + stake_rent; for stake_account in &stake_accounts { let validator_stake = get_account(&mut context.banks_client, &stake_account.stake_account).await; @@ -477,9 +489,13 @@ async fn merge_transient_stake_after_remove() { let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let current_minimum_delegation = stake_pool_get_minimum_delegation( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; let deactivated_lamports = lamports; - let new_authority = Pubkey::new_unique(); - let destination_stake = Keypair::new(); // Decrease and remove all validators for stake_account in &stake_accounts { let error = stake_pool_accounts @@ -499,10 +515,8 @@ async fn merge_transient_stake_after_remove() { &mut context.banks_client, &context.payer, &context.last_blockhash, - &new_authority, &stake_account.stake_account, &stake_account.transient_stake_account, - &destination_stake, ) .await; assert!(error.is_none()); @@ -539,9 +553,12 @@ async fn merge_transient_stake_after_remove() { assert_eq!(validator_list.validators.len(), 1); assert_eq!( validator_list.validators[0].status, - StakeStatus::DeactivatingTransient + StakeStatus::DeactivatingAll + ); + assert_eq!( + validator_list.validators[0].active_stake_lamports, + stake_rent + current_minimum_delegation ); - assert_eq!(validator_list.validators[0].active_stake_lamports, 0); assert_eq!( validator_list.validators[0].transient_stake_lamports, deactivated_lamports @@ -563,6 +580,21 @@ async fn merge_transient_stake_after_remove() { .await; assert!(error.is_none()); + // stake accounts were merged in, none exist anymore + for stake_account in &stake_accounts { + let not_found_account = context + .banks_client + .get_account(stake_account.stake_account) + .await + .unwrap(); + assert!(not_found_account.is_none()); + let not_found_account = context + .banks_client + .get_account(stake_account.transient_stake_account) + .await + .unwrap(); + assert!(not_found_account.is_none()); + } let validator_list = get_account( &mut context.banks_client, &stake_pool_accounts.validator_list.pubkey(), @@ -585,7 +617,7 @@ async fn merge_transient_stake_after_remove() { .unwrap(); assert_eq!( reserve_stake.lamports, - reserve_lamports + deactivated_lamports + 2 * stake_rent + MINIMUM_RESERVE_LAMPORTS + reserve_lamports + deactivated_lamports + stake_rent * 2 + MINIMUM_RESERVE_LAMPORTS ); // Update stake pool balance and cleanup, should be gone @@ -642,6 +674,7 @@ async fn success_with_burned_tokens() { &mut context.banks_client, &context.payer, &context.last_blockhash, + &stake_pool_accounts.token_program_id, &stake_pool_accounts.pool_mint.pubkey(), &deposit_accounts[0].pool_account.pubkey(), &deposit_accounts[0].authority, @@ -838,6 +871,219 @@ async fn check_ignored_hijacked_transient_stake( assert_eq!(pre_lamports, stake_pool.total_lamports); } +#[tokio::test] +async fn success_ignoring_hijacked_validator_stake_with_authorized() { + let hijacker = Pubkey::new_unique(); + check_ignored_hijacked_transient_stake(Some(&Authorized::auto(&hijacker)), None).await; +} + +#[tokio::test] +async fn success_ignoring_hijacked_validator_stake_with_lockup() { + let hijacker = Pubkey::new_unique(); + check_ignored_hijacked_validator_stake( + None, + Some(&Lockup { + custodian: hijacker, + ..Lockup::default() + }), + ) + .await; +} + +async fn check_ignored_hijacked_validator_stake( + hijack_authorized: Option<&Authorized>, + hijack_lockup: Option<&Lockup>, +) { + let num_validators = 1; + let (mut context, stake_pool_accounts, stake_accounts, _, lamports, _, mut slot) = + setup(num_validators).await; + + let rent = context.banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + + let pre_lamports = get_validator_list_sum( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + let (withdraw_authority, _) = + find_withdraw_authority_program_address(&id(), &stake_pool_accounts.stake_pool.pubkey()); + + let stake_account = &stake_accounts[0]; + let error = stake_pool_accounts + .decrease_validator_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_account.stake_account, + &stake_account.transient_stake_account, + lamports, + stake_account.transient_stake_seed, + ) + .await; + assert!(error.is_none()); + + let error = stake_pool_accounts + .remove_validator_from_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_account.stake_account, + &stake_account.transient_stake_account, + ) + .await; + assert!(error.is_none()); + + println!("Warp one epoch so the stakes deactivate and merge"); + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + slot += slots_per_epoch; + context.warp_to_slot(slot).unwrap(); + + println!("During update, hijack the validator stake account"); + let validator_list = stake_pool_accounts + .get_validator_list(&mut context.banks_client) + .await; + let transaction = Transaction::new_signed_with_payer( + &[ + instruction::update_validator_list_balance( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), + &validator_list, + &[stake_account.vote.pubkey()], + 0, + /* no_merge = */ false, + ), + system_instruction::transfer( + &context.payer.pubkey(), + &stake_account.stake_account, + stake_rent + MINIMUM_RESERVE_LAMPORTS, + ), + stake::instruction::initialize( + &stake_account.stake_account, + hijack_authorized.unwrap_or(&Authorized::auto(&withdraw_authority)), + hijack_lockup.unwrap_or(&Lockup::default()), + ), + instruction::update_stake_pool_balance( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.pool_fee_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &spl_token::id(), + ), + instruction::cleanup_removed_validator_entries( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + ), + ], + Some(&context.payer.pubkey()), + &[&context.payer], + context.last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err(); + assert!(error.is_none()); + + println!("Update again normally, should be no change in the lamports"); + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + stake_accounts + .iter() + .map(|v| v.vote.pubkey()) + .collect::>() + .as_slice(), + false, + ) + .await; + + let expected_lamports = get_validator_list_sum( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + assert_eq!(pre_lamports, expected_lamports); + + let stake_pool_info = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data).unwrap(); + assert_eq!(pre_lamports, stake_pool.total_lamports); + + println!("Fail adding validator back in with first seed"); + let error = stake_pool_accounts + .add_validator_to_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_account.stake_account, + &stake_account.vote.pubkey(), + stake_account.validator_stake_seed, + ) + .await + .unwrap() + .unwrap(); + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::AlreadyInUse as u32), + ) + ); + + println!("Succeed adding validator back in with new seed"); + let seed = NonZeroU32::new(1); + let validator = stake_account.vote.pubkey(); + let (stake_account, _) = find_stake_program_address( + &id(), + &validator, + &stake_pool_accounts.stake_pool.pubkey(), + seed, + ); + let error = stake_pool_accounts + .add_validator_to_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_account, + &validator, + seed, + ) + .await; + assert!(error.is_none()); + + let stake_pool_info = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data).unwrap(); + assert_eq!(pre_lamports, stake_pool.total_lamports); + + let expected_lamports = get_validator_list_sum( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + assert_eq!(pre_lamports, expected_lamports); +} + #[tokio::test] async fn fail_with_uninitialized_validator_list() {} // TODO diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index 79878732..0b195ae8 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -26,7 +26,9 @@ use { }, }; -async fn setup() -> ( +async fn setup( + num_validators: u64, +) -> ( BanksClient, Keypair, Hash, @@ -34,18 +36,25 @@ async fn setup() -> ( ValidatorStakeAccount, ) { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let rent = banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let current_minimum_delegation = + stake_pool_get_minimum_delegation(&mut banks_client, &payer, &recent_blockhash).await; + let minimum_for_validator = stake_rent + current_minimum_delegation; + + let stake_pool_accounts = StakePoolAccounts::default(); stake_pool_accounts .initialize_stake_pool( &mut banks_client, &payer, &recent_blockhash, - MINIMUM_RESERVE_LAMPORTS, + MINIMUM_RESERVE_LAMPORTS + num_validators * minimum_for_validator, ) .await .unwrap(); - let validator_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), 0); + let validator_stake = + ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), None, 0); create_vote( &mut banks_client, &payer, @@ -67,7 +76,7 @@ async fn setup() -> ( #[tokio::test] async fn success() { let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = - setup().await; + setup(1).await; let error = stake_pool_accounts .add_validator_to_pool( @@ -76,6 +85,7 @@ async fn success() { &recent_blockhash, &validator_stake.stake_account, &validator_stake.vote.pubkey(), + validator_stake.validator_stake_seed, ) .await; assert!(error.is_none()); @@ -88,6 +98,10 @@ async fn success() { .await; let validator_list = try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); + let rent = banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let current_minimum_delegation = + stake_pool_get_minimum_delegation(&mut banks_client, &payer, &recent_blockhash).await; assert_eq!( validator_list, state::ValidatorList { @@ -99,10 +113,14 @@ async fn success() { status: state::StakeStatus::Active, vote_account_address: validator_stake.vote.pubkey(), last_update_epoch: 0, - active_stake_lamports: 0, + active_stake_lamports: stake_rent + current_minimum_delegation, transient_stake_lamports: 0, - transient_seed_suffix_start: 0, - transient_seed_suffix_end: 0, + transient_seed_suffix: 0, + unused: 0, + validator_seed_suffix: validator_stake + .validator_stake_seed + .map(|s| s.get()) + .unwrap_or(0), }] } ); @@ -128,7 +146,7 @@ async fn success() { #[tokio::test] async fn fail_with_wrong_validator_list_account() { let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = - setup().await; + setup(1).await; let wrong_validator_list = Keypair::new(); @@ -137,11 +155,12 @@ async fn fail_with_wrong_validator_list_account() { &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.staker.pubkey(), - &payer.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), &stake_pool_accounts.withdraw_authority, &wrong_validator_list.pubkey(), &validator_stake.stake_account, &validator_stake.vote.pubkey(), + validator_stake.validator_stake_seed, )], Some(&payer.pubkey()), ); @@ -169,7 +188,7 @@ async fn fail_with_wrong_validator_list_account() { #[tokio::test] async fn fail_double_add() { let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = - setup().await; + setup(2).await; stake_pool_accounts .add_validator_to_pool( @@ -178,6 +197,7 @@ async fn fail_double_add() { &recent_blockhash, &validator_stake.stake_account, &validator_stake.vote.pubkey(), + validator_stake.validator_stake_seed, ) .await; @@ -190,6 +210,7 @@ async fn fail_double_add() { &latest_blockhash, &validator_stake.stake_account, &validator_stake.vote.pubkey(), + validator_stake.validator_stake_seed, ) .await .unwrap(); @@ -209,7 +230,7 @@ async fn fail_double_add() { #[tokio::test] async fn fail_wrong_staker() { let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = - setup().await; + setup(1).await; let malicious = Keypair::new(); @@ -218,11 +239,12 @@ async fn fail_wrong_staker() { &id(), &stake_pool_accounts.stake_pool.pubkey(), &malicious.pubkey(), - &payer.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), &stake_pool_accounts.withdraw_authority, &stake_pool_accounts.validator_list.pubkey(), &validator_stake.stake_account, &validator_stake.vote.pubkey(), + validator_stake.validator_stake_seed, )], Some(&payer.pubkey()), ); @@ -250,7 +272,7 @@ async fn fail_wrong_staker() { #[tokio::test] async fn fail_without_signature() { let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = - setup().await; + setup(1).await; let accounts = vec![ AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), @@ -270,9 +292,14 @@ async fn fail_without_signature() { let instruction = Instruction { program_id: id(), accounts, - data: instruction::StakePoolInstruction::AddValidatorToPool - .try_to_vec() - .unwrap(), + data: instruction::StakePoolInstruction::AddValidatorToPool( + validator_stake + .validator_stake_seed + .map(|s| s.get()) + .unwrap_or(0), + ) + .try_to_vec() + .unwrap(), }; let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); @@ -300,7 +327,7 @@ async fn fail_without_signature() { #[tokio::test] async fn fail_with_wrong_stake_program_id() { let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = - setup().await; + setup(1).await; let wrong_stake_program = Pubkey::new_unique(); let accounts = vec![ @@ -321,9 +348,14 @@ async fn fail_with_wrong_stake_program_id() { let instruction = Instruction { program_id: id(), accounts, - data: instruction::StakePoolInstruction::AddValidatorToPool - .try_to_vec() - .unwrap(), + data: instruction::StakePoolInstruction::AddValidatorToPool( + validator_stake + .validator_stake_seed + .map(|s| s.get()) + .unwrap_or(0), + ) + .try_to_vec() + .unwrap(), }; let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); @@ -348,7 +380,7 @@ async fn fail_with_wrong_stake_program_id() { #[tokio::test] async fn fail_with_wrong_system_program_id() { let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = - setup().await; + setup(1).await; let wrong_system_program = Pubkey::new_unique(); @@ -370,9 +402,14 @@ async fn fail_with_wrong_system_program_id() { let instruction = Instruction { program_id: id(), accounts, - data: instruction::StakePoolInstruction::AddValidatorToPool - .try_to_vec() - .unwrap(), + data: instruction::StakePoolInstruction::AddValidatorToPool( + validator_stake + .validator_stake_seed + .map(|s| s.get()) + .unwrap_or(0), + ) + .try_to_vec() + .unwrap(), }; let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); @@ -397,19 +434,28 @@ async fn fail_with_wrong_system_program_id() { #[tokio::test] async fn fail_add_too_many_validator_stake_accounts() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let mut stake_pool_accounts = StakePoolAccounts::new(); - stake_pool_accounts.max_validators = 1; + let rent = banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let current_minimum_delegation = + stake_pool_get_minimum_delegation(&mut banks_client, &payer, &recent_blockhash).await; + let minimum_for_validator = stake_rent + current_minimum_delegation; + + let stake_pool_accounts = StakePoolAccounts { + max_validators: 1, + ..Default::default() + }; stake_pool_accounts .initialize_stake_pool( &mut banks_client, &payer, &recent_blockhash, - MINIMUM_RESERVE_LAMPORTS, + MINIMUM_RESERVE_LAMPORTS + 2 * minimum_for_validator, ) .await .unwrap(); - let validator_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), 0); + let validator_stake = + ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), None, 0); create_vote( &mut banks_client, &payer, @@ -426,11 +472,13 @@ async fn fail_add_too_many_validator_stake_accounts() { &recent_blockhash, &validator_stake.stake_account, &validator_stake.vote.pubkey(), + validator_stake.validator_stake_seed, ) .await; assert!(error.is_none()); - let validator_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), 0); + let validator_stake = + ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), None, 0); create_vote( &mut banks_client, &payer, @@ -446,6 +494,7 @@ async fn fail_add_too_many_validator_stake_accounts() { &recent_blockhash, &validator_stake.stake_account, &validator_stake.vote.pubkey(), + validator_stake.validator_stake_seed, ) .await .unwrap() @@ -464,11 +513,15 @@ async fn fail_with_uninitialized_validator_list_account() {} // TODO #[tokio::test] async fn fail_on_non_vote_account() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, _) = setup().await; + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, _) = setup(1).await; let validator = Pubkey::new_unique(); - let (stake_account, _) = - find_stake_program_address(&id(), &validator, &stake_pool_accounts.stake_pool.pubkey()); + let (stake_account, _) = find_stake_program_address( + &id(), + &validator, + &stake_pool_accounts.stake_pool.pubkey(), + None, + ); let error = stake_pool_accounts .add_validator_to_pool( @@ -477,6 +530,7 @@ async fn fail_on_non_vote_account() { &recent_blockhash, &stake_account, &validator, + None, ) .await .unwrap() @@ -491,7 +545,7 @@ async fn fail_on_non_vote_account() { #[tokio::test] async fn fail_on_incorrectly_derived_stake_account() { let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = - setup().await; + setup(1).await; let bad_stake_account = Pubkey::new_unique(); let error = stake_pool_accounts @@ -501,6 +555,7 @@ async fn fail_on_incorrectly_derived_stake_account() { &recent_blockhash, &bad_stake_account, &validator_stake.vote.pubkey(), + validator_stake.validator_stake_seed, ) .await .unwrap() @@ -518,7 +573,7 @@ async fn fail_on_incorrectly_derived_stake_account() { #[tokio::test] async fn success_with_lamports_in_account() { let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = - setup().await; + setup(1).await; transfer( &mut banks_client, @@ -536,6 +591,7 @@ async fn success_with_lamports_in_account() { &recent_blockhash, &validator_stake.stake_account, &validator_stake.vote.pubkey(), + validator_stake.validator_stake_seed, ) .await; assert!(error.is_none()); @@ -557,3 +613,114 @@ async fn success_with_lamports_in_account() { _ => panic!(), } } + +#[tokio::test] +async fn fail_with_not_enough_reserve_lamports() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = + setup(0).await; + + let error = stake_pool_accounts + .add_validator_to_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &validator_stake.stake_account, + &validator_stake.vote.pubkey(), + validator_stake.validator_stake_seed, + ) + .await + .unwrap() + .unwrap(); + assert_eq!( + error, + TransactionError::InstructionError(0, InstructionError::InsufficientFunds) + ); +} + +#[tokio::test] +async fn fail_with_wrong_reserve() { + let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = + setup(1).await; + + let wrong_reserve = Pubkey::new_unique(); + + let mut transaction = Transaction::new_with_payer( + &[instruction::add_validator_to_pool( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.staker.pubkey(), + &wrong_reserve, + &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts.validator_list.pubkey(), + &validator_stake.stake_account, + &validator_stake.vote.pubkey(), + validator_stake.validator_stake_seed, + )], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 + let transaction_error = banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .into(); + + match transaction_error { + TransportError::TransactionError(TransactionError::InstructionError( + _, + InstructionError::Custom(error_index), + )) => { + let program_error = StakePoolError::InvalidProgramAddress as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error occurs while try to add validator stake address with wrong validator stake list account"), + } +} + +#[tokio::test] +async fn fail_with_draining_reserve() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let current_minimum_delegation = + stake_pool_get_minimum_delegation(&mut banks_client, &payer, &recent_blockhash).await; + + let stake_pool_accounts = StakePoolAccounts::default(); + stake_pool_accounts + .initialize_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + current_minimum_delegation, // add exactly enough for a validator + ) + .await + .unwrap(); + + let validator_stake = + ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), None, 0); + create_vote( + &mut banks_client, + &payer, + &recent_blockhash, + &validator_stake.validator, + &validator_stake.vote, + ) + .await; + + let error = stake_pool_accounts + .add_validator_to_pool( + &mut banks_client, + &payer, + &recent_blockhash, + &validator_stake.stake_account, + &validator_stake.vote.pubkey(), + validator_stake.validator_stake_seed, + ) + .await + .unwrap() + .unwrap(); + assert_eq!( + error, + TransactionError::InstructionError(0, InstructionError::InsufficientFunds), + ); +} diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 142d9da9..4dd07a26 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -4,7 +4,6 @@ mod helpers; use { - bincode::deserialize, borsh::BorshSerialize, helpers::*, solana_program::{ @@ -23,17 +22,12 @@ use { error::StakePoolError, find_transient_stake_program_address, id, instruction, state, MINIMUM_RESERVE_LAMPORTS, }, + std::num::NonZeroU32, }; -async fn setup() -> ( - ProgramTestContext, - StakePoolAccounts, - ValidatorStakeAccount, - Pubkey, - Keypair, -) { +async fn setup() -> (ProgramTestContext, StakePoolAccounts, ValidatorStakeAccount) { let mut context = program_test().start_with_context().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::default(); stake_pool_accounts .initialize_stake_pool( &mut context.banks_client, @@ -44,8 +38,11 @@ async fn setup() -> ( .await .unwrap(); - let validator_stake = - ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), u64::MAX); + let validator_stake = ValidatorStakeAccount::new( + &stake_pool_accounts.stake_pool.pubkey(), + NonZeroU32::new(u32::MAX), + u64::MAX, + ); create_vote( &mut context.banks_client, &context.payer, @@ -62,45 +59,35 @@ async fn setup() -> ( &context.last_blockhash, &validator_stake.stake_account, &validator_stake.vote.pubkey(), + validator_stake.validator_stake_seed, ) .await; assert!(error.is_none()); - - let new_authority = Pubkey::new_unique(); - let destination_stake = Keypair::new(); - - ( - context, - stake_pool_accounts, - validator_stake, - new_authority, - destination_stake, - ) + (context, stake_pool_accounts, validator_stake) } #[tokio::test] async fn success() { - let (mut context, stake_pool_accounts, validator_stake, new_authority, destination_stake) = - setup().await; + let (mut context, stake_pool_accounts, validator_stake) = setup().await; let error = stake_pool_accounts .remove_validator_from_pool( &mut context.banks_client, &context.payer, &context.last_blockhash, - &new_authority, &validator_stake.stake_account, &validator_stake.transient_stake_account, - &destination_stake, ) .await; assert!(error.is_none()); let error = stake_pool_accounts - .cleanup_removed_validator_entries( + .update_all( &mut context.banks_client, &context.payer, &context.last_blockhash, + &[validator_stake.vote.pubkey()], + false, ) .await; assert!(error.is_none()); @@ -131,21 +118,11 @@ async fn success() { .await .unwrap(); assert!(account.is_none()); - let stake = get_account(&mut context.banks_client, &destination_stake.pubkey()).await; - let stake_state = deserialize::(&stake.data).unwrap(); - match stake_state { - stake::state::StakeState::Stake(meta, _) => { - assert_eq!(&meta.authorized.staker, &new_authority); - assert_eq!(&meta.authorized.withdrawer, &new_authority); - } - _ => panic!(), - } } #[tokio::test] async fn fail_with_wrong_stake_program_id() { - let (mut context, stake_pool_accounts, validator_stake, new_authority, destination_stake) = - setup().await; + let (mut context, stake_pool_accounts, validator_stake) = setup().await; let wrong_stake_program = Pubkey::new_unique(); @@ -153,11 +130,9 @@ async fn fail_with_wrong_stake_program_id() { AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), AccountMeta::new_readonly(stake_pool_accounts.staker.pubkey(), true), AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false), - AccountMeta::new_readonly(new_authority, false), AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false), AccountMeta::new(validator_stake.stake_account, false), AccountMeta::new_readonly(validator_stake.transient_stake_account, false), - AccountMeta::new(destination_stake.pubkey(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(wrong_stake_program, false), ]; @@ -197,8 +172,7 @@ async fn fail_with_wrong_stake_program_id() { #[tokio::test] async fn fail_with_wrong_validator_list_account() { - let (mut context, stake_pool_accounts, validator_stake, new_authority, destination_stake) = - setup().await; + let (mut context, stake_pool_accounts, validator_stake) = setup().await; let wrong_validator_list = Keypair::new(); @@ -208,11 +182,9 @@ async fn fail_with_wrong_validator_list_account() { &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.staker.pubkey(), &stake_pool_accounts.withdraw_authority, - &new_authority, &wrong_validator_list.pubkey(), &validator_stake.stake_account, &validator_stake.transient_stake_account, - &destination_stake.pubkey(), )], Some(&context.payer.pubkey()), ); @@ -243,8 +215,7 @@ async fn fail_with_wrong_validator_list_account() { #[tokio::test] async fn fail_not_at_minimum() { - let (mut context, stake_pool_accounts, validator_stake, new_authority, destination_stake) = - setup().await; + let (mut context, stake_pool_accounts, validator_stake) = setup().await; transfer( &mut context.banks_client, @@ -260,10 +231,8 @@ async fn fail_not_at_minimum() { &mut context.banks_client, &context.payer, &context.last_blockhash, - &new_authority, &validator_stake.stake_account, &validator_stake.transient_stake_account, - &destination_stake, ) .await .unwrap() @@ -271,7 +240,7 @@ async fn fail_not_at_minimum() { assert_eq!( error, TransactionError::InstructionError( - 1, + 0, InstructionError::Custom(StakePoolError::StakeLamportsNotEqualToMinimum as u32) ), ); @@ -279,58 +248,60 @@ async fn fail_not_at_minimum() { #[tokio::test] async fn fail_double_remove() { - let (mut context, stake_pool_accounts, validator_stake, new_authority, destination_stake) = - setup().await; + let (mut context, stake_pool_accounts, validator_stake) = setup().await; let error = stake_pool_accounts .remove_validator_from_pool( &mut context.banks_client, &context.payer, &context.last_blockhash, - &new_authority, &validator_stake.stake_account, &validator_stake.transient_stake_account, - &destination_stake, ) .await; assert!(error.is_none()); let error = stake_pool_accounts - .cleanup_removed_validator_entries( + .update_all( &mut context.banks_client, &context.payer, &context.last_blockhash, + &[validator_stake.vote.pubkey()], + false, ) .await; assert!(error.is_none()); - let _latest_blockhash = context.banks_client.get_latest_blockhash().await.unwrap(); + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&context.last_blockhash) + .await + .unwrap(); - let destination_stake = Keypair::new(); let error = stake_pool_accounts .remove_validator_from_pool( &mut context.banks_client, &context.payer, - &context.last_blockhash, - &new_authority, + &last_blockhash, &validator_stake.stake_account, &validator_stake.transient_stake_account, - &destination_stake, ) .await .unwrap() .unwrap(); - assert!(matches!( + assert_eq!( error, - TransactionError::InstructionError(1, InstructionError::BorshIoError(_),) - )); + TransactionError::InstructionError( + 0, + InstructionError::BorshIoError("Unknown".to_string()) + ) + ); } #[tokio::test] async fn fail_wrong_staker() { - let (mut context, stake_pool_accounts, validator_stake, new_authority, destination_stake) = - setup().await; + let (mut context, stake_pool_accounts, validator_stake) = setup().await; let malicious = Keypair::new(); @@ -340,11 +311,9 @@ async fn fail_wrong_staker() { &stake_pool_accounts.stake_pool.pubkey(), &malicious.pubkey(), &stake_pool_accounts.withdraw_authority, - &new_authority, &stake_pool_accounts.validator_list.pubkey(), &validator_stake.stake_account, &validator_stake.transient_stake_account, - &destination_stake.pubkey(), )], Some(&context.payer.pubkey()), ); @@ -374,18 +343,15 @@ async fn fail_wrong_staker() { #[tokio::test] async fn fail_no_signature() { - let (mut context, stake_pool_accounts, validator_stake, new_authority, destination_stake) = - setup().await; + let (mut context, stake_pool_accounts, validator_stake) = setup().await; let accounts = vec![ AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), AccountMeta::new_readonly(stake_pool_accounts.staker.pubkey(), false), AccountMeta::new_readonly(stake_pool_accounts.withdraw_authority, false), - AccountMeta::new_readonly(new_authority, false), AccountMeta::new(stake_pool_accounts.validator_list.pubkey(), false), AccountMeta::new(validator_stake.stake_account, false), AccountMeta::new_readonly(validator_stake.transient_stake_account, false), - AccountMeta::new(destination_stake.pubkey(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(stake::program::id(), false), ]; @@ -426,8 +392,7 @@ async fn fail_no_signature() { #[tokio::test] async fn fail_with_activating_transient_stake() { - let (mut context, stake_pool_accounts, validator_stake, new_authority, destination_stake) = - setup().await; + let (mut context, stake_pool_accounts, validator_stake) = setup().await; // increase the validator stake let error = stake_pool_accounts @@ -449,10 +414,8 @@ async fn fail_with_activating_transient_stake() { &mut context.banks_client, &context.payer, &context.last_blockhash, - &new_authority, &validator_stake.stake_account, &validator_stake.transient_stake_account, - &destination_stake, ) .await .unwrap() @@ -471,11 +434,16 @@ async fn fail_with_activating_transient_stake() { #[tokio::test] async fn success_with_deactivating_transient_stake() { - let (mut context, stake_pool_accounts, validator_stake, new_authority, destination_stake) = - setup().await; + let (mut context, stake_pool_accounts, validator_stake) = setup().await; let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let current_minimum_delegation = stake_pool_get_minimum_delegation( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; let deposit_info = simple_deposit_stake( &mut context.banks_client, &context.payer, @@ -506,10 +474,8 @@ async fn success_with_deactivating_transient_stake() { &mut context.banks_client, &context.payer, &context.last_blockhash, - &new_authority, &validator_stake.stake_account, &validator_stake.transient_stake_account, - &destination_stake, ) .await; assert!(error.is_none()); @@ -542,6 +508,7 @@ async fn success_with_deactivating_transient_stake() { &mut context.banks_client, &context.payer, &context.last_blockhash, + &stake_pool_accounts.token_program_id, &deposit_info.pool_account.pubkey(), &deposit_info.authority, &user_transfer_authority.pubkey(), @@ -577,18 +544,22 @@ async fn success_with_deactivating_transient_stake() { max_validators: stake_pool_accounts.max_validators, }, validators: vec![state::ValidatorStakeInfo { - status: state::StakeStatus::DeactivatingTransient, + status: state::StakeStatus::DeactivatingAll, vote_account_address: validator_stake.vote.pubkey(), last_update_epoch: 0, - active_stake_lamports: 0, + active_stake_lamports: stake_rent + current_minimum_delegation, transient_stake_lamports: TEST_STAKE_AMOUNT + stake_rent, - transient_seed_suffix_start: validator_stake.transient_stake_seed, - transient_seed_suffix_end: 0, + transient_seed_suffix: validator_stake.transient_stake_seed, + unused: 0, + validator_seed_suffix: validator_stake + .validator_stake_seed + .map(|s| s.get()) + .unwrap_or(0), }], }; assert_eq!(validator_list, expected_list); - // Update, should not change, no merges yet + // Update will merge since activation and deactivation were in the same epoch let error = stake_pool_accounts .update_all( &mut context.banks_client, @@ -607,13 +578,19 @@ async fn success_with_deactivating_transient_stake() { .await; let validator_list = try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); + let expected_list = state::ValidatorList { + header: state::ValidatorListHeader { + account_type: state::AccountType::ValidatorList, + max_validators: stake_pool_accounts.max_validators, + }, + validators: vec![], + }; assert_eq!(validator_list, expected_list); } #[tokio::test] async fn success_resets_preferred_validator() { - let (mut context, stake_pool_accounts, validator_stake, new_authority, destination_stake) = - setup().await; + let (mut context, stake_pool_accounts, validator_stake) = setup().await; stake_pool_accounts .set_preferred_validator( @@ -639,19 +616,19 @@ async fn success_resets_preferred_validator() { &mut context.banks_client, &context.payer, &context.last_blockhash, - &new_authority, &validator_stake.stake_account, &validator_stake.transient_stake_account, - &destination_stake, ) .await; assert!(error.is_none()); let error = stake_pool_accounts - .cleanup_removed_validator_entries( + .update_all( &mut context.banks_client, &context.payer, &context.last_blockhash, + &[validator_stake.vote.pubkey()], + false, ) .await; assert!(error.is_none()); @@ -675,22 +652,18 @@ async fn success_resets_preferred_validator() { } ); - // Check of stake account authority has changed - let stake = get_account(&mut context.banks_client, &destination_stake.pubkey()).await; - let stake_state = deserialize::(&stake.data).unwrap(); - match stake_state { - stake::state::StakeState::Stake(meta, _) => { - assert_eq!(&meta.authorized.staker, &new_authority); - assert_eq!(&meta.authorized.withdrawer, &new_authority); - } - _ => panic!(), - } + // Check stake account no longer exists + let account = context + .banks_client + .get_account(validator_stake.stake_account) + .await + .unwrap(); + assert!(account.is_none()); } #[tokio::test] async fn success_with_hijacked_transient_account() { - let (mut context, stake_pool_accounts, validator_stake, new_authority, destination_stake) = - setup().await; + let (mut context, stake_pool_accounts, validator_stake) = setup().await; let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); let current_minimum_delegation = stake_pool_get_minimum_delegation( @@ -831,19 +804,23 @@ async fn success_with_hijacked_transient_account() { &mut context.banks_client, &context.payer, &context.last_blockhash, - &new_authority, &validator_stake.stake_account, &validator_stake.transient_stake_account, - &destination_stake, ) .await; assert!(error.is_none()); + // warp forward to merge + slot += slots_per_epoch; + context.warp_to_slot(slot).unwrap(); + let error = stake_pool_accounts - .cleanup_removed_validator_entries( + .update_all( &mut context.banks_client, &context.payer, &context.last_blockhash, + &[validator_stake.vote.pubkey()], + false, ) .await; assert!(error.is_none()); diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 74b3ede1..7afeb28d 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -9,7 +9,6 @@ use { helpers::*, solana_program::{ borsh::try_from_slice_unchecked, - hash::Hash, instruction::{AccountMeta, Instruction, InstructionError}, pubkey::Pubkey, stake, sysvar, @@ -25,12 +24,13 @@ use { MINIMUM_RESERVE_LAMPORTS, }, spl_token::error::TokenError, + test_case::test_case, }; -async fn setup() -> ( - BanksClient, - Keypair, - Hash, +async fn setup( + token_program_id: Pubkey, +) -> ( + ProgramTestContext, StakePoolAccounts, ValidatorStakeAccount, DepositStakeAccount, @@ -38,33 +38,38 @@ async fn setup() -> ( Keypair, u64, ) { - let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let mut context = program_test().start_with_context().await; + let stake_pool_accounts = StakePoolAccounts::new_with_token_program(token_program_id); stake_pool_accounts .initialize_stake_pool( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, MINIMUM_RESERVE_LAMPORTS, ) .await .unwrap(); let validator_stake_account = simple_add_validator_to_pool( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &stake_pool_accounts, + None, ) .await; - let current_minimum_delegation = - stake_pool_get_minimum_delegation(&mut banks_client, &payer, &recent_blockhash).await; + let current_minimum_delegation = stake_pool_get_minimum_delegation( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; let deposit_info = simple_deposit_stake( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &stake_pool_accounts, &validator_stake_account, current_minimum_delegation * 3, @@ -77,9 +82,10 @@ async fn setup() -> ( // Delegate tokens for withdrawing let user_transfer_authority = Keypair::new(); delegate_tokens( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts.token_program_id, &deposit_info.pool_account.pubkey(), &deposit_info.authority, &user_transfer_authority.pubkey(), @@ -90,17 +96,15 @@ async fn setup() -> ( // Create stake account to withdraw to let user_stake_recipient = Keypair::new(); create_blank_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &user_stake_recipient, ) .await; ( - banks_client, - payer, - recent_blockhash, + context, stake_pool_accounts, validator_stake_account, deposit_info, @@ -110,14 +114,16 @@ async fn setup() -> ( ) } +#[test_case(spl_token::id(); "token")] +#[test_case(spl_token_2022::id(); "token-2022")] #[tokio::test] -async fn success() { - _success(SuccessTestType::Success).await; +async fn success(token_program_id: Pubkey) { + _success(token_program_id, SuccessTestType::Success).await; } #[tokio::test] async fn success_with_closed_manager_fee_account() { - _success(SuccessTestType::UninitializedManagerFee).await; + _success(spl_token::id(), SuccessTestType::UninitializedManagerFee).await; } enum SuccessTestType { @@ -125,33 +131,35 @@ enum SuccessTestType { UninitializedManagerFee, } -async fn _success(test_type: SuccessTestType) { +async fn _success(token_program_id: Pubkey, test_type: SuccessTestType) { let ( - mut banks_client, - payer, - recent_blockhash, + mut context, stake_pool_accounts, validator_stake_account, deposit_info, user_transfer_authority, user_stake_recipient, tokens_to_withdraw, - ) = setup().await; + ) = setup(token_program_id).await; // Save stake pool state before withdrawal - let stake_pool_before = - get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; + let stake_pool_before = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; let stake_pool_before = try_from_slice_unchecked::(stake_pool_before.data.as_slice()).unwrap(); // Check user recipient stake account balance - let initial_stake_lamports = get_account(&mut banks_client, &user_stake_recipient.pubkey()) - .await - .lamports; + let initial_stake_lamports = + get_account(&mut context.banks_client, &user_stake_recipient.pubkey()) + .await + .lamports; // Save validator stake account record before withdrawal let validator_list = get_account( - &mut banks_client, + &mut context.banks_client, &stake_pool_accounts.validator_list.pubkey(), ) .await; @@ -162,45 +170,54 @@ async fn _success(test_type: SuccessTestType) { .unwrap(); // Save user token balance - let user_token_balance_before = - get_token_balance(&mut banks_client, &deposit_info.pool_account.pubkey()).await; + let user_token_balance_before = get_token_balance( + &mut context.banks_client, + &deposit_info.pool_account.pubkey(), + ) + .await; // Save pool fee token balance let pool_fee_balance_before = get_token_balance( - &mut banks_client, + &mut context.banks_client, &stake_pool_accounts.pool_fee_account.pubkey(), ) .await; let destination_keypair = Keypair::new(); create_token_account( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts.token_program_id, &destination_keypair, &stake_pool_accounts.pool_mint.pubkey(), - &Keypair::new().pubkey(), + &Keypair::new(), + &[], ) .await .unwrap(); if let SuccessTestType::UninitializedManagerFee = test_type { transfer_spl_tokens( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts.token_program_id, &stake_pool_accounts.pool_fee_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), &destination_keypair.pubkey(), &stake_pool_accounts.manager, pool_fee_balance_before, + stake_pool_accounts.pool_decimals, ) .await; // Check that the account cannot be frozen due to lack of // freeze authority. let transaction_error = freeze_token_account( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts.token_program_id, &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.manager, @@ -215,9 +232,10 @@ async fn _success(test_type: SuccessTestType) { _ => panic!("Wrong error occurs while try to withdraw with wrong stake program ID"), } close_token_account( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts.token_program_id, &stake_pool_accounts.pool_fee_account.pubkey(), &destination_keypair.pubkey(), &stake_pool_accounts.manager, @@ -229,9 +247,9 @@ async fn _success(test_type: SuccessTestType) { let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts .withdraw_stake( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &user_stake_recipient.pubkey(), &user_transfer_authority, &deposit_info.pool_account.pubkey(), @@ -243,7 +261,11 @@ async fn _success(test_type: SuccessTestType) { assert!(error.is_none()); // Check pool stats - let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); // first and only deposit, lamports:pool 1:1 @@ -266,7 +288,7 @@ async fn _success(test_type: SuccessTestType) { if let SuccessTestType::Success = test_type { // Check manager received withdrawal fee let pool_fee_balance = get_token_balance( - &mut banks_client, + &mut context.banks_client, &stake_pool_accounts.pool_fee_account.pubkey(), ) .await; @@ -278,7 +300,7 @@ async fn _success(test_type: SuccessTestType) { // Check validator stake list storage let validator_list = get_account( - &mut banks_client, + &mut context.banks_client, &stake_pool_accounts.validator_list.pubkey(), ) .await; @@ -297,29 +319,30 @@ async fn _success(test_type: SuccessTestType) { ); // Check tokens used - let user_token_balance = - get_token_balance(&mut banks_client, &deposit_info.pool_account.pubkey()).await; + let user_token_balance = get_token_balance( + &mut context.banks_client, + &deposit_info.pool_account.pubkey(), + ) + .await; assert_eq!( user_token_balance, user_token_balance_before - tokens_to_withdraw ); // Check validator stake account balance - let validator_stake_account = - get_account(&mut banks_client, &validator_stake_account.stake_account).await; - let stake_state = - deserialize::(&validator_stake_account.data).unwrap(); - let meta = stake_state.meta().unwrap(); - let stake_minimum_delegation = - stake_get_minimum_delegation(&mut banks_client, &payer, &recent_blockhash).await; + let validator_stake_account = get_account( + &mut context.banks_client, + &validator_stake_account.stake_account, + ) + .await; assert_eq!( - validator_stake_account.lamports - minimum_stake_lamports(&meta, stake_minimum_delegation), + validator_stake_account.lamports, validator_stake_item.active_stake_lamports ); // Check user recipient stake account balance let user_stake_recipient_account = - get_account(&mut banks_client, &user_stake_recipient.pubkey()).await; + get_account(&mut context.banks_client, &user_stake_recipient.pubkey()).await; assert_eq!( user_stake_recipient_account.lamports, initial_stake_lamports + tokens_burnt @@ -329,16 +352,14 @@ async fn _success(test_type: SuccessTestType) { #[tokio::test] async fn fail_with_wrong_stake_program() { let ( - mut banks_client, - payer, - recent_blockhash, + mut context, stake_pool_accounts, validator_stake_account, deposit_info, user_transfer_authority, user_stake_recipient, tokens_to_burn, - ) = setup().await; + ) = setup(spl_token::id()).await; let new_authority = Pubkey::new_unique(); let wrong_stake_program = Pubkey::new_unique(); @@ -368,12 +389,13 @@ async fn fail_with_wrong_stake_program() { let transaction = Transaction::new_signed_with_payer( &[instruction], - Some(&payer.pubkey()), - &[&payer, &user_transfer_authority], - recent_blockhash, + Some(&context.payer.pubkey()), + &[&context.payer, &user_transfer_authority], + context.last_blockhash, ); #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 - let transaction_error = banks_client + let transaction_error = context + .banks_client .process_transaction(transaction) .await .err() @@ -391,25 +413,23 @@ async fn fail_with_wrong_stake_program() { #[tokio::test] async fn fail_with_wrong_withdraw_authority() { let ( - mut banks_client, - payer, - recent_blockhash, + mut context, mut stake_pool_accounts, validator_stake_account, deposit_info, user_transfer_authority, user_stake_recipient, tokens_to_burn, - ) = setup().await; + ) = setup(spl_token::id()).await; let new_authority = Pubkey::new_unique(); stake_pool_accounts.withdraw_authority = Keypair::new().pubkey(); let transaction_error = stake_pool_accounts .withdraw_stake( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &user_stake_recipient.pubkey(), &user_transfer_authority, &deposit_info.pool_account.pubkey(), @@ -435,16 +455,14 @@ async fn fail_with_wrong_withdraw_authority() { #[tokio::test] async fn fail_with_wrong_token_program_id() { let ( - mut banks_client, - payer, - recent_blockhash, + mut context, stake_pool_accounts, validator_stake_account, deposit_info, user_transfer_authority, user_stake_recipient, tokens_to_burn, - ) = setup().await; + ) = setup(spl_token::id()).await; let new_authority = Pubkey::new_unique(); let wrong_token_program = Keypair::new(); @@ -465,12 +483,13 @@ async fn fail_with_wrong_token_program_id() { &wrong_token_program.pubkey(), tokens_to_burn, )], - Some(&payer.pubkey()), - &[&payer, &user_transfer_authority], - recent_blockhash, + Some(&context.payer.pubkey()), + &[&context.payer, &user_transfer_authority], + context.last_blockhash, ); #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 - let transaction_error = banks_client + let transaction_error = context + .banks_client .process_transaction(transaction) .await .err() @@ -488,25 +507,23 @@ async fn fail_with_wrong_token_program_id() { #[tokio::test] async fn fail_with_wrong_validator_list() { let ( - mut banks_client, - payer, - recent_blockhash, + mut context, mut stake_pool_accounts, validator_stake, deposit_info, user_transfer_authority, user_stake_recipient, tokens_to_burn, - ) = setup().await; + ) = setup(spl_token::id()).await; let new_authority = Pubkey::new_unique(); stake_pool_accounts.validator_list = Keypair::new(); let transaction_error = stake_pool_accounts .withdraw_stake( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &user_stake_recipient.pubkey(), &user_transfer_authority, &deposit_info.pool_account.pubkey(), @@ -534,21 +551,19 @@ async fn fail_with_wrong_validator_list() { #[tokio::test] async fn fail_with_unknown_validator() { let ( - mut banks_client, - payer, - recent_blockhash, + mut context, stake_pool_accounts, _, deposit_info, user_transfer_authority, user_stake_recipient, tokens_to_withdraw, - ) = setup().await; + ) = setup(spl_token::id()).await; let unknown_stake = create_unknown_validator_stake( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &stake_pool_accounts.stake_pool.pubkey(), ) .await; @@ -556,9 +571,9 @@ async fn fail_with_unknown_validator() { let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts .withdraw_stake( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &user_stake_recipient.pubkey(), &user_transfer_authority, &deposit_info.pool_account.pubkey(), @@ -582,23 +597,21 @@ async fn fail_with_unknown_validator() { #[tokio::test] async fn fail_double_withdraw_to_the_same_account() { let ( - mut banks_client, - payer, - recent_blockhash, + mut context, stake_pool_accounts, validator_stake_account, deposit_info, user_transfer_authority, user_stake_recipient, tokens_to_burn, - ) = setup().await; + ) = setup(spl_token::id()).await; let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts .withdraw_stake( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &user_stake_recipient.pubkey(), &user_transfer_authority, &deposit_info.pool_account.pubkey(), @@ -609,13 +622,14 @@ async fn fail_double_withdraw_to_the_same_account() { .await; assert!(error.is_none()); - let latest_blockhash = banks_client.get_latest_blockhash().await.unwrap(); + let latest_blockhash = context.banks_client.get_latest_blockhash().await.unwrap(); // Delegate tokens for burning delegate_tokens( - &mut banks_client, - &payer, + &mut context.banks_client, + &context.payer, &latest_blockhash, + &stake_pool_accounts.token_program_id, &deposit_info.pool_account.pubkey(), &deposit_info.authority, &user_transfer_authority.pubkey(), @@ -625,8 +639,8 @@ async fn fail_double_withdraw_to_the_same_account() { let transaction_error = stake_pool_accounts .withdraw_stake( - &mut banks_client, - &payer, + &mut context.banks_client, + &context.payer, &latest_blockhash, &user_stake_recipient.pubkey(), &user_transfer_authority, @@ -648,56 +662,32 @@ async fn fail_double_withdraw_to_the_same_account() { #[tokio::test] async fn fail_without_token_approval() { - let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); - stake_pool_accounts - .initialize_stake_pool( - &mut banks_client, - &payer, - &recent_blockhash, - MINIMUM_RESERVE_LAMPORTS, - ) - .await - .unwrap(); - - let validator_stake_account = simple_add_validator_to_pool( - &mut banks_client, - &payer, - &recent_blockhash, - &stake_pool_accounts, - ) - .await; - - let deposit_info = simple_deposit_stake( - &mut banks_client, - &payer, - &recent_blockhash, - &stake_pool_accounts, - &validator_stake_account, - TEST_STAKE_AMOUNT, - ) - .await - .unwrap(); - - let tokens_to_burn = deposit_info.pool_tokens / 4; + let ( + mut context, + stake_pool_accounts, + validator_stake_account, + deposit_info, + user_transfer_authority, + user_stake_recipient, + tokens_to_burn, + ) = setup(spl_token::id()).await; - // Create stake account to withdraw to - let user_stake_recipient = Keypair::new(); - create_blank_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake_recipient, + revoke_tokens( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts.token_program_id, + &deposit_info.pool_account.pubkey(), + &deposit_info.authority, ) .await; let new_authority = Pubkey::new_unique(); - let user_transfer_authority = Keypair::new(); let transaction_error = stake_pool_accounts .withdraw_stake( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &user_stake_recipient.pubkey(), &user_transfer_authority, &deposit_info.pool_account.pubkey(), @@ -723,69 +713,67 @@ async fn fail_without_token_approval() { } #[tokio::test] -async fn fail_with_low_delegation() { - let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let stake_pool_accounts = StakePoolAccounts::new(); - stake_pool_accounts - .initialize_stake_pool( - &mut banks_client, - &payer, - &recent_blockhash, - MINIMUM_RESERVE_LAMPORTS, - ) - .await - .unwrap(); +async fn fail_with_not_enough_tokens() { + let ( + mut context, + stake_pool_accounts, + validator_stake_account, + deposit_info, + user_transfer_authority, + user_stake_recipient, + tokens_to_burn, + ) = setup(spl_token::id()).await; - let validator_stake_account = simple_add_validator_to_pool( - &mut banks_client, - &payer, - &recent_blockhash, + // Empty validator stake account + let empty_stake_account = simple_add_validator_to_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &stake_pool_accounts, + None, ) .await; - let deposit_info = simple_deposit_stake( - &mut banks_client, - &payer, - &recent_blockhash, - &stake_pool_accounts, - &validator_stake_account, - TEST_STAKE_AMOUNT, - ) - .await - .unwrap(); - - let tokens_to_burn = deposit_info.pool_tokens / 4; + let new_authority = Pubkey::new_unique(); + let error = stake_pool_accounts + .withdraw_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user_stake_recipient.pubkey(), + &user_transfer_authority, + &deposit_info.pool_account.pubkey(), + &empty_stake_account.stake_account, + &new_authority, + tokens_to_burn, + ) + .await + .unwrap() + .unwrap(); + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::StakeLamportsNotEqualToMinimum as u32) + ), + ); - let user_transfer_authority = Keypair::new(); - // Delegate tokens for burning - delegate_tokens( - &mut banks_client, - &payer, - &recent_blockhash, + // revoked delegation + revoke_tokens( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts.token_program_id, &deposit_info.pool_account.pubkey(), &deposit_info.authority, - &user_transfer_authority.pubkey(), - 1, - ) - .await; - - // Create stake account to withdraw to - let user_stake_recipient = Keypair::new(); - create_blank_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake_recipient, ) .await; - let new_authority = Pubkey::new_unique(); let transaction_error = stake_pool_accounts .withdraw_stake( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &user_stake_recipient.pubkey(), &user_transfer_authority, &deposit_info.pool_account.pubkey(), @@ -794,50 +782,36 @@ async fn fail_with_low_delegation() { tokens_to_burn, ) .await + .unwrap() .unwrap(); - match transaction_error { - TransportError::TransactionError(TransactionError::InstructionError( - _, - InstructionError::Custom(error_index), - )) => { - let program_error = TokenError::InsufficientFunds as u32; - assert_eq!(error_index, program_error); - } - _ => panic!( - "Wrong error occurs while try to do withdraw with not enough delegated tokens to burn" - ), - } -} - -#[tokio::test] -async fn fail_overdraw_validator() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - _validator_stake_account, - deposit_info, - user_transfer_authority, - user_stake_recipient, - tokens_to_burn, - ) = setup().await; + assert_eq!( + transaction_error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(TokenError::OwnerMismatch as u32), + ) + ); - let validator_stake_account = simple_add_validator_to_pool( - &mut banks_client, - &payer, - &recent_blockhash, - &stake_pool_accounts, + // Delegate few tokens for burning + delegate_tokens( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts.token_program_id, + &deposit_info.pool_account.pubkey(), + &deposit_info.authority, + &user_transfer_authority.pubkey(), + 1, ) .await; let new_authority = Pubkey::new_unique(); - let error = stake_pool_accounts + let transaction_error = stake_pool_accounts .withdraw_stake( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &user_stake_recipient.pubkey(), &user_transfer_authority, &deposit_info.pool_account.pubkey(), @@ -848,60 +822,105 @@ async fn fail_overdraw_validator() { .await .unwrap() .unwrap(); + assert_eq!( - error, + transaction_error, TransactionError::InstructionError( 0, - InstructionError::Custom(StakePoolError::StakeLamportsNotEqualToMinimum as u32) - ), + InstructionError::Custom(TokenError::InsufficientFunds as u32), + ) ); } #[tokio::test] -async fn success_with_reserve() { - let mut context = program_test().start_with_context().await; - let stake_pool_accounts = StakePoolAccounts::new(); - let initial_reserve_lamports = MINIMUM_RESERVE_LAMPORTS; - stake_pool_accounts - .initialize_stake_pool( +async fn fail_remove_validator() { + let ( + mut context, + stake_pool_accounts, + validator_stake, + deposit_info, + user_transfer_authority, + user_stake_recipient, + _, + ) = setup(spl_token::id()).await; + + // decrease a little stake, not all + let error = stake_pool_accounts + .decrease_validator_stake( &mut context.banks_client, &context.payer, &context.last_blockhash, - initial_reserve_lamports, + &validator_stake.stake_account, + &validator_stake.transient_stake_account, + deposit_info.stake_lamports / 2, + validator_stake.transient_stake_seed, + ) + .await; + assert!(error.is_none()); + + // warp forward to deactivation + let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + context + .warp_to_slot(first_normal_slot + slots_per_epoch) + .unwrap(); + + // update to merge deactivated stake into reserve + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &[validator_stake.vote.pubkey()], + false, + ) + .await; + + // Withdraw entire account, fail because some stake left + let validator_stake_account = + get_account(&mut context.banks_client, &validator_stake.stake_account).await; + let remaining_lamports = validator_stake_account.lamports; + let new_user_authority = Pubkey::new_unique(); + let error = stake_pool_accounts + .withdraw_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user_stake_recipient.pubkey(), + &user_transfer_authority, + &deposit_info.pool_account.pubkey(), + &validator_stake.stake_account, + &new_user_authority, + remaining_lamports, ) .await + .unwrap() .unwrap(); + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::StakeLamportsNotEqualToMinimum as u32) + ) + ); +} - let validator_stake = simple_add_validator_to_pool( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts, - ) - .await; +#[tokio::test] +async fn success_remove_validator() { + let ( + mut context, + stake_pool_accounts, + validator_stake, + deposit_info, + user_transfer_authority, + user_stake_recipient, + _, + ) = setup(spl_token::id()).await; let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); - let current_minimum_delegation = stake_pool_get_minimum_delegation( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - ) - .await; - let deposit_lamports = (current_minimum_delegation + stake_rent) * 2; - - let deposit_info = simple_deposit_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts, - &validator_stake, - deposit_lamports, - ) - .await - .unwrap(); - // decrease some stake + // decrease all of stake let error = stake_pool_accounts .decrease_validator_stake( &mut context.banks_client, @@ -909,7 +928,7 @@ async fn success_with_reserve() { &context.last_blockhash, &validator_stake.stake_account, &validator_stake.transient_stake_account, - deposit_lamports / 2, + deposit_info.stake_lamports + stake_rent, validator_stake.transient_stake_seed, ) .await; @@ -933,40 +952,119 @@ async fn success_with_reserve() { ) .await; - // Delegate tokens for using for withdrawal - let user_transfer_authority = Keypair::new(); - delegate_tokens( + let validator_stake_account = + get_account(&mut context.banks_client, &validator_stake.stake_account).await; + let remaining_lamports = validator_stake_account.lamports; + let new_user_authority = Pubkey::new_unique(); + let pool_tokens = stake_pool_accounts.calculate_inverse_withdrawal_fee(remaining_lamports); + let error = stake_pool_accounts + .withdraw_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user_stake_recipient.pubkey(), + &user_transfer_authority, + &deposit_info.pool_account.pubkey(), + &validator_stake.stake_account, + &new_user_authority, + pool_tokens, + ) + .await; + assert!(error.is_none()); + + // Check validator stake account gone + let validator_stake_account = context + .banks_client + .get_account(validator_stake.stake_account) + .await + .unwrap(); + assert!(validator_stake_account.is_none()); + + // Check user recipient stake account balance + let user_stake_recipient_account = + get_account(&mut context.banks_client, &user_stake_recipient.pubkey()).await; + assert_eq!( + user_stake_recipient_account.lamports, + remaining_lamports + stake_rent + 1 + ); + + // Check that cleanup happens correctly + stake_pool_accounts + .cleanup_removed_validator_entries( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; + + let validator_list = get_account( &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &deposit_info.pool_account.pubkey(), - &deposit_info.authority, - &user_transfer_authority.pubkey(), - deposit_info.pool_tokens, + &stake_pool_accounts.validator_list.pubkey(), ) .await; + let validator_list = + try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); + let validator_stake_item = validator_list.find(&validator_stake.vote.pubkey()); + assert!(validator_stake_item.is_none()); +} + +#[tokio::test] +async fn fail_with_reserve() { + let ( + mut context, + stake_pool_accounts, + validator_stake, + deposit_info, + user_transfer_authority, + user_stake_recipient, + tokens_to_burn, + ) = setup(spl_token::id()).await; + + // decrease a little stake, not all + let error = stake_pool_accounts + .decrease_validator_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &validator_stake.stake_account, + &validator_stake.transient_stake_account, + deposit_info.stake_lamports / 2, + validator_stake.transient_stake_seed, + ) + .await; + assert!(error.is_none()); + + // warp forward to deactivation + let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + context + .warp_to_slot(first_normal_slot + slots_per_epoch) + .unwrap(); + + // update to merge deactivated stake into reserve + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &[validator_stake.vote.pubkey()], + false, + ) + .await; // Withdraw directly from reserve, fail because some stake left - let withdraw_destination = Keypair::new(); - let withdraw_destination_authority = Pubkey::new_unique(); - let initial_stake_lamports = create_blank_stake_account( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &withdraw_destination, - ) - .await; + let new_user_authority = Pubkey::new_unique(); let error = stake_pool_accounts .withdraw_stake( &mut context.banks_client, &context.payer, &context.last_blockhash, - &withdraw_destination.pubkey(), + &user_stake_recipient.pubkey(), &user_transfer_authority, &deposit_info.pool_account.pubkey(), &stake_pool_accounts.reserve_stake.pubkey(), - &withdraw_destination_authority, - deposit_info.pool_tokens, + &new_user_authority, + tokens_to_burn, ) .await .unwrap() @@ -978,8 +1076,24 @@ async fn success_with_reserve() { InstructionError::Custom(StakePoolError::StakeLamportsNotEqualToMinimum as u32) ) ); +} - // decrease rest of stake +#[tokio::test] +async fn success_with_reserve() { + let ( + mut context, + stake_pool_accounts, + validator_stake, + deposit_info, + user_transfer_authority, + user_stake_recipient, + _, + ) = setup(spl_token::id()).await; + + let rent = context.banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + + // decrease all of stake let error = stake_pool_accounts .decrease_validator_stake( &mut context.banks_client, @@ -987,15 +1101,17 @@ async fn success_with_reserve() { &context.last_blockhash, &validator_stake.stake_account, &validator_stake.transient_stake_account, - deposit_lamports / 2 + stake_rent, + deposit_info.stake_lamports + stake_rent, validator_stake.transient_stake_seed, ) .await; assert!(error.is_none()); // warp forward to deactivation + let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; context - .warp_to_slot(first_normal_slot + 2 * slots_per_epoch) + .warp_to_slot(first_normal_slot + slots_per_epoch) .unwrap(); // update to merge deactivated stake into reserve @@ -1010,16 +1126,17 @@ async fn success_with_reserve() { .await; // now it works + let new_user_authority = Pubkey::new_unique(); let error = stake_pool_accounts .withdraw_stake( &mut context.banks_client, &context.payer, &context.last_blockhash, - &withdraw_destination.pubkey(), + &user_stake_recipient.pubkey(), &user_transfer_authority, &deposit_info.pool_account.pubkey(), &stake_pool_accounts.reserve_stake.pubkey(), - &withdraw_destination_authority, + &new_user_authority, deposit_info.pool_tokens, ) .await; @@ -1067,116 +1184,83 @@ async fn success_with_reserve() { let stake_state = deserialize::(&reserve_stake_account.data).unwrap(); let meta = stake_state.meta().unwrap(); assert_eq!( - initial_reserve_lamports + meta.rent_exempt_reserve + withdrawal_fee + deposit_fee, + MINIMUM_RESERVE_LAMPORTS + meta.rent_exempt_reserve + withdrawal_fee + deposit_fee, reserve_stake_account.lamports ); // Check user recipient stake account balance let user_stake_recipient_account = - get_account(&mut context.banks_client, &withdraw_destination.pubkey()).await; + get_account(&mut context.banks_client, &user_stake_recipient.pubkey()).await; assert_eq!( user_stake_recipient_account.lamports, - initial_stake_lamports + deposit_info.stake_lamports + stake_rent + MINIMUM_RESERVE_LAMPORTS + deposit_info.stake_lamports + stake_rent * 2 - withdrawal_fee - deposit_fee ); } #[tokio::test] -async fn success_with_preferred_validator() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - validator_stake, - deposit_info, - user_transfer_authority, - user_stake_recipient, - tokens_to_burn, - ) = setup().await; - - stake_pool_accounts - .set_preferred_validator( - &mut banks_client, - &payer, - &recent_blockhash, - instruction::PreferredValidatorType::Withdraw, - Some(validator_stake.vote.pubkey()), - ) - .await; - - let new_authority = Pubkey::new_unique(); - let error = stake_pool_accounts - .withdraw_stake( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake_recipient.pubkey(), - &user_transfer_authority, - &deposit_info.pool_account.pubkey(), - &validator_stake.stake_account, - &new_authority, - tokens_to_burn, - ) - .await; - assert!(error.is_none()); -} - -#[tokio::test] -async fn fail_with_wrong_preferred_withdraw() { +async fn success_and_fail_with_preferred_withdraw() { let ( - mut banks_client, - payer, - recent_blockhash, + mut context, stake_pool_accounts, validator_stake, deposit_info, user_transfer_authority, user_stake_recipient, tokens_to_burn, - ) = setup().await; + ) = setup(spl_token::id()).await; let preferred_validator = simple_add_validator_to_pool( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &stake_pool_accounts, + None, ) .await; stake_pool_accounts .set_preferred_validator( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, instruction::PreferredValidatorType::Withdraw, Some(preferred_validator.vote.pubkey()), ) .await; - // preferred is empty, this works + // preferred is empty, withdrawing from non-preferred works let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts .withdraw_stake( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &user_stake_recipient.pubkey(), &user_transfer_authority, &deposit_info.pool_account.pubkey(), &validator_stake.stake_account, &new_authority, - tokens_to_burn, + tokens_to_burn / 2, ) .await; assert!(error.is_none()); - // deposit into preferred, then fail + // Deposit into preferred, then fail + let user_stake_recipient = Keypair::new(); + create_blank_stake_account( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user_stake_recipient, + ) + .await; + let _preferred_deposit = simple_deposit_stake( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &stake_pool_accounts, &preferred_validator, TEST_STAKE_AMOUNT, @@ -1184,56 +1268,57 @@ async fn fail_with_wrong_preferred_withdraw() { .await .unwrap(); - // Create stake account to withdraw to - let user_stake_recipient = Keypair::new(); - create_blank_stake_account( - &mut banks_client, - &payer, - &recent_blockhash, - &user_stake_recipient, - ) - .await; - let error = stake_pool_accounts .withdraw_stake( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &user_stake_recipient.pubkey(), &user_transfer_authority, &deposit_info.pool_account.pubkey(), &validator_stake.stake_account, &new_authority, - tokens_to_burn, + tokens_to_burn / 2, ) .await .unwrap() .unwrap(); - match error { - TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { - assert_eq!( - error_index, - StakePoolError::IncorrectWithdrawVoteAddress as u32 - ); - } - _ => panic!("Wrong error occurs while try to make a deposit with wrong stake program ID"), - } -} + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::IncorrectWithdrawVoteAddress as u32) + ) + ); -#[tokio::test] -async fn fail_withdraw_from_transient() { - let mut context = program_test().start_with_context().await; - let stake_pool_accounts = StakePoolAccounts::new(); - let initial_reserve_lamports = MINIMUM_RESERVE_LAMPORTS; - stake_pool_accounts - .initialize_stake_pool( + // success from preferred + let error = stake_pool_accounts + .withdraw_stake( &mut context.banks_client, &context.payer, &context.last_blockhash, - initial_reserve_lamports, + &user_stake_recipient.pubkey(), + &user_transfer_authority, + &deposit_info.pool_account.pubkey(), + &preferred_validator.stake_account, + &new_authority, + tokens_to_burn / 2, ) - .await - .unwrap(); + .await; + assert!(error.is_none()); +} + +#[tokio::test] +async fn fail_withdraw_from_transient() { + let ( + mut context, + stake_pool_accounts, + validator_stake_account, + deposit_info, + user_transfer_authority, + user_stake_recipient, + tokens_to_withdraw, + ) = setup(spl_token::id()).await; // add a preferred withdraw validator, keep it empty, to be sure that this works let preferred_validator = simple_add_validator_to_pool( @@ -1241,6 +1326,7 @@ async fn fail_withdraw_from_transient() { &context.payer, &context.last_blockhash, &stake_pool_accounts, + None, ) .await; @@ -1254,47 +1340,8 @@ async fn fail_withdraw_from_transient() { ) .await; - let validator_stake = simple_add_validator_to_pool( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts, - ) - .await; - let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); - let current_minimum_delegation = stake_pool_get_minimum_delegation( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - ) - .await; - let deposit_lamports = (current_minimum_delegation + stake_rent) * 2; - - let deposit_info = simple_deposit_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts, - &validator_stake, - deposit_lamports, - ) - .await - .unwrap(); - - // Delegate tokens for burning during withdraw - let user_transfer_authority = Keypair::new(); - delegate_tokens( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &deposit_info.pool_account.pubkey(), - &deposit_info.authority, - &user_transfer_authority.pubkey(), - deposit_info.pool_tokens, - ) - .await; // decrease to minimum stake + 1 lamport let error = stake_pool_accounts @@ -1302,36 +1349,27 @@ async fn fail_withdraw_from_transient() { &mut context.banks_client, &context.payer, &context.last_blockhash, - &validator_stake.stake_account, - &validator_stake.transient_stake_account, - deposit_lamports + stake_rent - 1, - validator_stake.transient_stake_seed, + &validator_stake_account.stake_account, + &validator_stake_account.transient_stake_account, + deposit_info.stake_lamports + stake_rent - 1, + validator_stake_account.transient_stake_seed, ) .await; assert!(error.is_none()); - let withdraw_destination = Keypair::new(); - let withdraw_destination_authority = Pubkey::new_unique(); - let _initial_stake_lamports = create_blank_stake_account( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &withdraw_destination, - ) - .await; - // fail withdrawing from transient, still a lamport in the validator stake account + let new_user_authority = Pubkey::new_unique(); let error = stake_pool_accounts .withdraw_stake( &mut context.banks_client, &context.payer, &context.last_blockhash, - &withdraw_destination.pubkey(), + &user_stake_recipient.pubkey(), &user_transfer_authority, &deposit_info.pool_account.pubkey(), - &validator_stake.transient_stake_account, - &withdraw_destination_authority, - deposit_info.pool_tokens / 2, + &validator_stake_account.transient_stake_account, + &new_user_authority, + tokens_to_withdraw, ) .await .unwrap() @@ -1347,18 +1385,15 @@ async fn fail_withdraw_from_transient() { #[tokio::test] async fn success_withdraw_from_transient() { - let mut context = program_test().start_with_context().await; - let stake_pool_accounts = StakePoolAccounts::new(); - let initial_reserve_lamports = MINIMUM_RESERVE_LAMPORTS; - stake_pool_accounts - .initialize_stake_pool( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - initial_reserve_lamports, - ) - .await - .unwrap(); + let ( + mut context, + stake_pool_accounts, + validator_stake_account, + deposit_info, + user_transfer_authority, + user_stake_recipient, + tokens_to_withdraw, + ) = setup(spl_token::id()).await; // add a preferred withdraw validator, keep it empty, to be sure that this works let preferred_validator = simple_add_validator_to_pool( @@ -1366,6 +1401,7 @@ async fn success_withdraw_from_transient() { &context.payer, &context.last_blockhash, &stake_pool_accounts, + None, ) .await; @@ -1379,87 +1415,37 @@ async fn success_withdraw_from_transient() { ) .await; - let validator_stake = simple_add_validator_to_pool( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts, - ) - .await; - let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); - // compensate for the fee and the minimum balance in the transient stake account - let current_minimum_delegation = stake_pool_get_minimum_delegation( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - ) - .await; - let deposit_lamports = (current_minimum_delegation + stake_rent) * 3; - - let deposit_info = simple_deposit_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts, - &validator_stake, - deposit_lamports, - ) - .await - .unwrap(); - - // Delegate tokens for burning during withdraw - let user_transfer_authority = Keypair::new(); - delegate_tokens( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &deposit_info.pool_account.pubkey(), - &deposit_info.authority, - &user_transfer_authority.pubkey(), - deposit_info.pool_tokens, - ) - .await; - - let withdraw_destination = Keypair::new(); - let withdraw_destination_authority = Pubkey::new_unique(); - let _initial_stake_lamports = create_blank_stake_account( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &withdraw_destination, - ) - .await; - // decrease all of stake let error = stake_pool_accounts .decrease_validator_stake( &mut context.banks_client, &context.payer, &context.last_blockhash, - &validator_stake.stake_account, - &validator_stake.transient_stake_account, - deposit_lamports + stake_rent, - validator_stake.transient_stake_seed, + &validator_stake_account.stake_account, + &validator_stake_account.transient_stake_account, + deposit_info.stake_lamports + stake_rent, + validator_stake_account.transient_stake_seed, ) .await; assert!(error.is_none()); // nothing left in the validator stake account (or any others), so withdrawing // from the transient account is ok! + let new_user_authority = Pubkey::new_unique(); let error = stake_pool_accounts .withdraw_stake( &mut context.banks_client, &context.payer, &context.last_blockhash, - &withdraw_destination.pubkey(), + &user_stake_recipient.pubkey(), &user_transfer_authority, &deposit_info.pool_account.pubkey(), - &validator_stake.transient_stake_account, - &withdraw_destination_authority, - deposit_info.pool_tokens / 2, + &validator_stake_account.transient_stake_account, + &new_user_authority, + tokens_to_withdraw / 2, ) .await; assert!(error.is_none()); @@ -1468,40 +1454,42 @@ async fn success_withdraw_from_transient() { #[tokio::test] async fn success_withdraw_all_fee_tokens() { let ( - mut banks_client, - payer, - recent_blockhash, + mut context, stake_pool_accounts, validator_stake_account, deposit_info, user_transfer_authority, user_stake_recipient, tokens_to_withdraw, - ) = setup().await; + ) = setup(spl_token::id()).await; // move tokens to fee account transfer_spl_tokens( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts.token_program_id, &deposit_info.pool_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), &stake_pool_accounts.pool_fee_account.pubkey(), &user_transfer_authority, - tokens_to_withdraw, + tokens_to_withdraw / 2, + stake_pool_accounts.pool_decimals, ) .await; let fee_tokens = get_token_balance( - &mut banks_client, + &mut context.banks_client, &stake_pool_accounts.pool_fee_account.pubkey(), ) .await; let user_transfer_authority = Keypair::new(); delegate_tokens( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts.token_program_id, &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.manager, &user_transfer_authority.pubkey(), @@ -1512,9 +1500,9 @@ async fn success_withdraw_all_fee_tokens() { let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts .withdraw_stake( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &user_stake_recipient.pubkey(), &user_transfer_authority, &stake_pool_accounts.pool_fee_account.pubkey(), @@ -1527,7 +1515,7 @@ async fn success_withdraw_all_fee_tokens() { // Check balance is 0 let fee_tokens = get_token_balance( - &mut banks_client, + &mut context.banks_client, &stake_pool_accounts.pool_fee_account.pubkey(), ) .await; @@ -1537,30 +1525,29 @@ async fn success_withdraw_all_fee_tokens() { #[tokio::test] async fn success_empty_out_stake_with_fee() { let ( - mut banks_client, - payer, - recent_blockhash, + mut context, stake_pool_accounts, _, deposit_info, user_transfer_authority, user_stake_recipient, tokens_to_withdraw, - ) = setup().await; + ) = setup(spl_token::id()).await; // add another validator and deposit into it let other_validator_stake_account = simple_add_validator_to_pool( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &stake_pool_accounts, + None, ) .await; let other_deposit_info = simple_deposit_stake( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &stake_pool_accounts, &other_validator_stake_account, TEST_STAKE_AMOUNT, @@ -1570,24 +1557,31 @@ async fn success_empty_out_stake_with_fee() { // move tokens to new account transfer_spl_tokens( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts.token_program_id, &deposit_info.pool_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), &other_deposit_info.pool_account.pubkey(), &user_transfer_authority, tokens_to_withdraw, + stake_pool_accounts.pool_decimals, ) .await; - let user_tokens = - get_token_balance(&mut banks_client, &other_deposit_info.pool_account.pubkey()).await; + let user_tokens = get_token_balance( + &mut context.banks_client, + &other_deposit_info.pool_account.pubkey(), + ) + .await; let user_transfer_authority = Keypair::new(); delegate_tokens( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts.token_program_id, &other_deposit_info.pool_account.pubkey(), &other_deposit_info.authority, &user_transfer_authority.pubkey(), @@ -1598,19 +1592,26 @@ async fn success_empty_out_stake_with_fee() { // calculate exactly how much to withdraw, given the fee, to get the account // down to 0, using an inverse fee calculation let validator_stake_account = get_account( - &mut banks_client, + &mut context.banks_client, &other_validator_stake_account.stake_account, ) .await; let stake_state = deserialize::(&validator_stake_account.data).unwrap(); let meta = stake_state.meta().unwrap(); - let stake_minimum_delegation = - stake_get_minimum_delegation(&mut banks_client, &payer, &recent_blockhash).await; + let stake_minimum_delegation = stake_get_minimum_delegation( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; let lamports_to_withdraw = validator_stake_account.lamports - minimum_stake_lamports(&meta, stake_minimum_delegation); - let stake_pool_account = - get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; + let stake_pool_account = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; let stake_pool = try_from_slice_unchecked::(stake_pool_account.data.as_slice()).unwrap(); let fee = stake_pool.stake_withdrawal_fee; @@ -1624,9 +1625,9 @@ async fn success_empty_out_stake_with_fee() { let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts .withdraw_stake( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &user_stake_recipient.pubkey(), &user_transfer_authority, &other_deposit_info.pool_account.pubkey(), @@ -1639,7 +1640,7 @@ async fn success_empty_out_stake_with_fee() { // Check balance of validator stake account is MINIMUM + rent-exemption let validator_stake_account = get_account( - &mut banks_client, + &mut context.banks_client, &other_validator_stake_account.stake_account, ) .await; diff --git a/program/tests/withdraw_sol.rs b/program/tests/withdraw_sol.rs index 1dcdaf8f..3e029b56 100644 --- a/program/tests/withdraw_sol.rs +++ b/program/tests/withdraw_sol.rs @@ -19,12 +19,15 @@ use { instruction::{self, FundingType}, state, MINIMUM_RESERVE_LAMPORTS, }, + test_case::test_case, }; -async fn setup() -> (ProgramTestContext, StakePoolAccounts, Keypair, Pubkey, u64) { +async fn setup( + token_program_id: Pubkey, +) -> (ProgramTestContext, StakePoolAccounts, Keypair, Pubkey, u64) { let mut context = program_test().start_with_context().await; - let stake_pool_accounts = StakePoolAccounts::new(); + let stake_pool_accounts = StakePoolAccounts::new_with_token_program(token_program_id); stake_pool_accounts .initialize_stake_pool( &mut context.banks_client, @@ -43,9 +46,11 @@ async fn setup() -> (ProgramTestContext, StakePoolAccounts, Keypair, Pubkey, u64 &mut context.banks_client, &context.payer, &context.last_blockhash, + &stake_pool_accounts.token_program_id, &pool_token_account, &stake_pool_accounts.pool_mint.pubkey(), - &user.pubkey(), + &user, + &[], ) .await .unwrap(); @@ -74,9 +79,12 @@ async fn setup() -> (ProgramTestContext, StakePoolAccounts, Keypair, Pubkey, u64 ) } +#[test_case(spl_token::id(); "token")] +#[test_case(spl_token_2022::id(); "token-2022")] #[tokio::test] -async fn success() { - let (mut context, stake_pool_accounts, user, pool_token_account, pool_tokens) = setup().await; +async fn success(token_program_id: Pubkey) { + let (mut context, stake_pool_accounts, user, pool_token_account, pool_tokens) = + setup(token_program_id).await; // Save stake pool state before withdrawing let pre_stake_pool = get_account( @@ -148,7 +156,7 @@ async fn success() { #[tokio::test] async fn fail_with_wrong_withdraw_authority() { let (mut context, mut stake_pool_accounts, user, pool_token_account, pool_tokens) = - setup().await; + setup(spl_token::id()).await; stake_pool_accounts.withdraw_authority = Pubkey::new_unique(); @@ -177,7 +185,8 @@ async fn fail_with_wrong_withdraw_authority() { #[tokio::test] async fn fail_overdraw_reserve() { - let (mut context, stake_pool_accounts, user, pool_token_account, _) = setup().await; + let (mut context, stake_pool_accounts, user, pool_token_account, _) = + setup(spl_token::id()).await; // add a validator and increase stake to drain the reserve let validator_stake = simple_add_validator_to_pool( @@ -185,6 +194,7 @@ async fn fail_overdraw_reserve() { &context.payer, &context.last_blockhash, &stake_pool_accounts, + None, ) .await; @@ -230,7 +240,8 @@ async fn fail_overdraw_reserve() { #[tokio::test] async fn success_with_sol_withdraw_authority() { - let (mut context, stake_pool_accounts, user, pool_token_account, pool_tokens) = setup().await; + let (mut context, stake_pool_accounts, user, pool_token_account, pool_tokens) = + setup(spl_token::id()).await; let sol_withdraw_authority = Keypair::new(); let transaction = Transaction::new_signed_with_payer( @@ -267,7 +278,8 @@ async fn success_with_sol_withdraw_authority() { #[tokio::test] async fn fail_without_sol_withdraw_authority_signature() { - let (mut context, stake_pool_accounts, user, pool_token_account, pool_tokens) = setup().await; + let (mut context, stake_pool_accounts, user, pool_token_account, pool_tokens) = + setup(spl_token::id()).await; let sol_withdraw_authority = Keypair::new(); let transaction = Transaction::new_signed_with_payer( From 94cc53d3f7bcc358a1e641bc3a3b0756186308be Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Mon, 21 Nov 2022 20:45:52 +0100 Subject: [PATCH 0269/1076] stake-pool: Bump token-2022 to 0.5 (#3837) --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 6b57263f..e0c20846 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -22,7 +22,7 @@ serde = "1.0.130" serde_derive = "1.0.103" solana-program = "1.14.6" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } -spl-token-2022 = { version = "0.4", path = "../../token/program-2022", features = [ "no-entrypoint" ] } +spl-token-2022 = { version = "0.5", path = "../../token/program-2022", features = [ "no-entrypoint" ] } thiserror = "1.0" bincode = "1.3.1" From c36bb8249d0f155fffd75e9c4497f0719236b517 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 29 Nov 2022 02:22:18 +0100 Subject: [PATCH 0270/1076] stake-pool: Split up tests to avoid CI failures (#3850) --- program/tests/withdraw.rs | 829 +----------------------- program/tests/withdraw_edge_cases.rs | 928 +++++++++++++++++++++++++++ 2 files changed, 930 insertions(+), 827 deletions(-) create mode 100644 program/tests/withdraw_edge_cases.rs diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 7afeb28d..ec6217b0 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -4,14 +4,13 @@ mod helpers; use { - bincode::deserialize, borsh::BorshSerialize, helpers::*, solana_program::{ borsh::try_from_slice_unchecked, instruction::{AccountMeta, Instruction, InstructionError}, pubkey::Pubkey, - stake, sysvar, + sysvar, }, solana_program_test::*, solana_sdk::{ @@ -19,10 +18,7 @@ use { transaction::{Transaction, TransactionError}, transport::TransportError, }, - spl_stake_pool::{ - error::StakePoolError, id, instruction, minimum_stake_lamports, state, - MINIMUM_RESERVE_LAMPORTS, - }, + spl_stake_pool::{error::StakePoolError, id, instruction, state, MINIMUM_RESERVE_LAMPORTS}, spl_token::error::TokenError, test_case::test_case, }; @@ -831,824 +827,3 @@ async fn fail_with_not_enough_tokens() { ) ); } - -#[tokio::test] -async fn fail_remove_validator() { - let ( - mut context, - stake_pool_accounts, - validator_stake, - deposit_info, - user_transfer_authority, - user_stake_recipient, - _, - ) = setup(spl_token::id()).await; - - // decrease a little stake, not all - let error = stake_pool_accounts - .decrease_validator_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &validator_stake.stake_account, - &validator_stake.transient_stake_account, - deposit_info.stake_lamports / 2, - validator_stake.transient_stake_seed, - ) - .await; - assert!(error.is_none()); - - // warp forward to deactivation - let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; - let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; - context - .warp_to_slot(first_normal_slot + slots_per_epoch) - .unwrap(); - - // update to merge deactivated stake into reserve - stake_pool_accounts - .update_all( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &[validator_stake.vote.pubkey()], - false, - ) - .await; - - // Withdraw entire account, fail because some stake left - let validator_stake_account = - get_account(&mut context.banks_client, &validator_stake.stake_account).await; - let remaining_lamports = validator_stake_account.lamports; - let new_user_authority = Pubkey::new_unique(); - let error = stake_pool_accounts - .withdraw_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &user_stake_recipient.pubkey(), - &user_transfer_authority, - &deposit_info.pool_account.pubkey(), - &validator_stake.stake_account, - &new_user_authority, - remaining_lamports, - ) - .await - .unwrap() - .unwrap(); - assert_eq!( - error, - TransactionError::InstructionError( - 0, - InstructionError::Custom(StakePoolError::StakeLamportsNotEqualToMinimum as u32) - ) - ); -} - -#[tokio::test] -async fn success_remove_validator() { - let ( - mut context, - stake_pool_accounts, - validator_stake, - deposit_info, - user_transfer_authority, - user_stake_recipient, - _, - ) = setup(spl_token::id()).await; - - let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); - - // decrease all of stake - let error = stake_pool_accounts - .decrease_validator_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &validator_stake.stake_account, - &validator_stake.transient_stake_account, - deposit_info.stake_lamports + stake_rent, - validator_stake.transient_stake_seed, - ) - .await; - assert!(error.is_none()); - - // warp forward to deactivation - let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; - let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; - context - .warp_to_slot(first_normal_slot + slots_per_epoch) - .unwrap(); - - // update to merge deactivated stake into reserve - stake_pool_accounts - .update_all( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &[validator_stake.vote.pubkey()], - false, - ) - .await; - - let validator_stake_account = - get_account(&mut context.banks_client, &validator_stake.stake_account).await; - let remaining_lamports = validator_stake_account.lamports; - let new_user_authority = Pubkey::new_unique(); - let pool_tokens = stake_pool_accounts.calculate_inverse_withdrawal_fee(remaining_lamports); - let error = stake_pool_accounts - .withdraw_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &user_stake_recipient.pubkey(), - &user_transfer_authority, - &deposit_info.pool_account.pubkey(), - &validator_stake.stake_account, - &new_user_authority, - pool_tokens, - ) - .await; - assert!(error.is_none()); - - // Check validator stake account gone - let validator_stake_account = context - .banks_client - .get_account(validator_stake.stake_account) - .await - .unwrap(); - assert!(validator_stake_account.is_none()); - - // Check user recipient stake account balance - let user_stake_recipient_account = - get_account(&mut context.banks_client, &user_stake_recipient.pubkey()).await; - assert_eq!( - user_stake_recipient_account.lamports, - remaining_lamports + stake_rent + 1 - ); - - // Check that cleanup happens correctly - stake_pool_accounts - .cleanup_removed_validator_entries( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - ) - .await; - - let validator_list = get_account( - &mut context.banks_client, - &stake_pool_accounts.validator_list.pubkey(), - ) - .await; - let validator_list = - try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); - let validator_stake_item = validator_list.find(&validator_stake.vote.pubkey()); - assert!(validator_stake_item.is_none()); -} - -#[tokio::test] -async fn fail_with_reserve() { - let ( - mut context, - stake_pool_accounts, - validator_stake, - deposit_info, - user_transfer_authority, - user_stake_recipient, - tokens_to_burn, - ) = setup(spl_token::id()).await; - - // decrease a little stake, not all - let error = stake_pool_accounts - .decrease_validator_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &validator_stake.stake_account, - &validator_stake.transient_stake_account, - deposit_info.stake_lamports / 2, - validator_stake.transient_stake_seed, - ) - .await; - assert!(error.is_none()); - - // warp forward to deactivation - let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; - let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; - context - .warp_to_slot(first_normal_slot + slots_per_epoch) - .unwrap(); - - // update to merge deactivated stake into reserve - stake_pool_accounts - .update_all( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &[validator_stake.vote.pubkey()], - false, - ) - .await; - - // Withdraw directly from reserve, fail because some stake left - let new_user_authority = Pubkey::new_unique(); - let error = stake_pool_accounts - .withdraw_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &user_stake_recipient.pubkey(), - &user_transfer_authority, - &deposit_info.pool_account.pubkey(), - &stake_pool_accounts.reserve_stake.pubkey(), - &new_user_authority, - tokens_to_burn, - ) - .await - .unwrap() - .unwrap(); - assert_eq!( - error, - TransactionError::InstructionError( - 0, - InstructionError::Custom(StakePoolError::StakeLamportsNotEqualToMinimum as u32) - ) - ); -} - -#[tokio::test] -async fn success_with_reserve() { - let ( - mut context, - stake_pool_accounts, - validator_stake, - deposit_info, - user_transfer_authority, - user_stake_recipient, - _, - ) = setup(spl_token::id()).await; - - let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); - - // decrease all of stake - let error = stake_pool_accounts - .decrease_validator_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &validator_stake.stake_account, - &validator_stake.transient_stake_account, - deposit_info.stake_lamports + stake_rent, - validator_stake.transient_stake_seed, - ) - .await; - assert!(error.is_none()); - - // warp forward to deactivation - let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; - let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; - context - .warp_to_slot(first_normal_slot + slots_per_epoch) - .unwrap(); - - // update to merge deactivated stake into reserve - stake_pool_accounts - .update_all( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &[validator_stake.vote.pubkey()], - false, - ) - .await; - - // now it works - let new_user_authority = Pubkey::new_unique(); - let error = stake_pool_accounts - .withdraw_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &user_stake_recipient.pubkey(), - &user_transfer_authority, - &deposit_info.pool_account.pubkey(), - &stake_pool_accounts.reserve_stake.pubkey(), - &new_user_authority, - deposit_info.pool_tokens, - ) - .await; - assert!(error.is_none()); - - // first and only deposit, lamports:pool 1:1 - let stake_pool = get_account( - &mut context.banks_client, - &stake_pool_accounts.stake_pool.pubkey(), - ) - .await; - let stake_pool = - try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); - // the entire deposit is actually stake since it isn't activated, so only - // the stake deposit fee is charged - let deposit_fee = stake_pool - .calc_pool_tokens_stake_deposit_fee(stake_rent + deposit_info.stake_lamports) - .unwrap(); - assert_eq!( - deposit_info.stake_lamports + stake_rent - deposit_fee, - deposit_info.pool_tokens, - "stake {} rent {} deposit fee {} pool tokens {}", - deposit_info.stake_lamports, - stake_rent, - deposit_fee, - deposit_info.pool_tokens - ); - - let withdrawal_fee = stake_pool_accounts.calculate_withdrawal_fee(deposit_info.pool_tokens); - - // Check tokens used - let user_token_balance = get_token_balance( - &mut context.banks_client, - &deposit_info.pool_account.pubkey(), - ) - .await; - assert_eq!(user_token_balance, 0); - - // Check reserve stake account balance - let reserve_stake_account = get_account( - &mut context.banks_client, - &stake_pool_accounts.reserve_stake.pubkey(), - ) - .await; - let stake_state = deserialize::(&reserve_stake_account.data).unwrap(); - let meta = stake_state.meta().unwrap(); - assert_eq!( - MINIMUM_RESERVE_LAMPORTS + meta.rent_exempt_reserve + withdrawal_fee + deposit_fee, - reserve_stake_account.lamports - ); - - // Check user recipient stake account balance - let user_stake_recipient_account = - get_account(&mut context.banks_client, &user_stake_recipient.pubkey()).await; - assert_eq!( - user_stake_recipient_account.lamports, - MINIMUM_RESERVE_LAMPORTS + deposit_info.stake_lamports + stake_rent * 2 - - withdrawal_fee - - deposit_fee - ); -} - -#[tokio::test] -async fn success_and_fail_with_preferred_withdraw() { - let ( - mut context, - stake_pool_accounts, - validator_stake, - deposit_info, - user_transfer_authority, - user_stake_recipient, - tokens_to_burn, - ) = setup(spl_token::id()).await; - - let preferred_validator = simple_add_validator_to_pool( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts, - None, - ) - .await; - - stake_pool_accounts - .set_preferred_validator( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - instruction::PreferredValidatorType::Withdraw, - Some(preferred_validator.vote.pubkey()), - ) - .await; - - // preferred is empty, withdrawing from non-preferred works - let new_authority = Pubkey::new_unique(); - let error = stake_pool_accounts - .withdraw_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &user_stake_recipient.pubkey(), - &user_transfer_authority, - &deposit_info.pool_account.pubkey(), - &validator_stake.stake_account, - &new_authority, - tokens_to_burn / 2, - ) - .await; - assert!(error.is_none()); - - // Deposit into preferred, then fail - let user_stake_recipient = Keypair::new(); - create_blank_stake_account( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &user_stake_recipient, - ) - .await; - - let _preferred_deposit = simple_deposit_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts, - &preferred_validator, - TEST_STAKE_AMOUNT, - ) - .await - .unwrap(); - - let error = stake_pool_accounts - .withdraw_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &user_stake_recipient.pubkey(), - &user_transfer_authority, - &deposit_info.pool_account.pubkey(), - &validator_stake.stake_account, - &new_authority, - tokens_to_burn / 2, - ) - .await - .unwrap() - .unwrap(); - assert_eq!( - error, - TransactionError::InstructionError( - 0, - InstructionError::Custom(StakePoolError::IncorrectWithdrawVoteAddress as u32) - ) - ); - - // success from preferred - let error = stake_pool_accounts - .withdraw_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &user_stake_recipient.pubkey(), - &user_transfer_authority, - &deposit_info.pool_account.pubkey(), - &preferred_validator.stake_account, - &new_authority, - tokens_to_burn / 2, - ) - .await; - assert!(error.is_none()); -} - -#[tokio::test] -async fn fail_withdraw_from_transient() { - let ( - mut context, - stake_pool_accounts, - validator_stake_account, - deposit_info, - user_transfer_authority, - user_stake_recipient, - tokens_to_withdraw, - ) = setup(spl_token::id()).await; - - // add a preferred withdraw validator, keep it empty, to be sure that this works - let preferred_validator = simple_add_validator_to_pool( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts, - None, - ) - .await; - - stake_pool_accounts - .set_preferred_validator( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - instruction::PreferredValidatorType::Withdraw, - Some(preferred_validator.vote.pubkey()), - ) - .await; - - let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); - - // decrease to minimum stake + 1 lamport - let error = stake_pool_accounts - .decrease_validator_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &validator_stake_account.stake_account, - &validator_stake_account.transient_stake_account, - deposit_info.stake_lamports + stake_rent - 1, - validator_stake_account.transient_stake_seed, - ) - .await; - assert!(error.is_none()); - - // fail withdrawing from transient, still a lamport in the validator stake account - let new_user_authority = Pubkey::new_unique(); - let error = stake_pool_accounts - .withdraw_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &user_stake_recipient.pubkey(), - &user_transfer_authority, - &deposit_info.pool_account.pubkey(), - &validator_stake_account.transient_stake_account, - &new_user_authority, - tokens_to_withdraw, - ) - .await - .unwrap() - .unwrap(); - assert_eq!( - error, - TransactionError::InstructionError( - 0, - InstructionError::Custom(StakePoolError::InvalidStakeAccountAddress as u32) - ) - ); -} - -#[tokio::test] -async fn success_withdraw_from_transient() { - let ( - mut context, - stake_pool_accounts, - validator_stake_account, - deposit_info, - user_transfer_authority, - user_stake_recipient, - tokens_to_withdraw, - ) = setup(spl_token::id()).await; - - // add a preferred withdraw validator, keep it empty, to be sure that this works - let preferred_validator = simple_add_validator_to_pool( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts, - None, - ) - .await; - - stake_pool_accounts - .set_preferred_validator( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - instruction::PreferredValidatorType::Withdraw, - Some(preferred_validator.vote.pubkey()), - ) - .await; - - let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); - - // decrease all of stake - let error = stake_pool_accounts - .decrease_validator_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &validator_stake_account.stake_account, - &validator_stake_account.transient_stake_account, - deposit_info.stake_lamports + stake_rent, - validator_stake_account.transient_stake_seed, - ) - .await; - assert!(error.is_none()); - - // nothing left in the validator stake account (or any others), so withdrawing - // from the transient account is ok! - let new_user_authority = Pubkey::new_unique(); - let error = stake_pool_accounts - .withdraw_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &user_stake_recipient.pubkey(), - &user_transfer_authority, - &deposit_info.pool_account.pubkey(), - &validator_stake_account.transient_stake_account, - &new_user_authority, - tokens_to_withdraw / 2, - ) - .await; - assert!(error.is_none()); -} - -#[tokio::test] -async fn success_withdraw_all_fee_tokens() { - let ( - mut context, - stake_pool_accounts, - validator_stake_account, - deposit_info, - user_transfer_authority, - user_stake_recipient, - tokens_to_withdraw, - ) = setup(spl_token::id()).await; - - // move tokens to fee account - transfer_spl_tokens( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts.token_program_id, - &deposit_info.pool_account.pubkey(), - &stake_pool_accounts.pool_mint.pubkey(), - &stake_pool_accounts.pool_fee_account.pubkey(), - &user_transfer_authority, - tokens_to_withdraw / 2, - stake_pool_accounts.pool_decimals, - ) - .await; - - let fee_tokens = get_token_balance( - &mut context.banks_client, - &stake_pool_accounts.pool_fee_account.pubkey(), - ) - .await; - - let user_transfer_authority = Keypair::new(); - delegate_tokens( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts.token_program_id, - &stake_pool_accounts.pool_fee_account.pubkey(), - &stake_pool_accounts.manager, - &user_transfer_authority.pubkey(), - fee_tokens, - ) - .await; - - let new_authority = Pubkey::new_unique(); - let error = stake_pool_accounts - .withdraw_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &user_stake_recipient.pubkey(), - &user_transfer_authority, - &stake_pool_accounts.pool_fee_account.pubkey(), - &validator_stake_account.stake_account, - &new_authority, - fee_tokens, - ) - .await; - assert!(error.is_none()); - - // Check balance is 0 - let fee_tokens = get_token_balance( - &mut context.banks_client, - &stake_pool_accounts.pool_fee_account.pubkey(), - ) - .await; - assert_eq!(fee_tokens, 0); -} - -#[tokio::test] -async fn success_empty_out_stake_with_fee() { - let ( - mut context, - stake_pool_accounts, - _, - deposit_info, - user_transfer_authority, - user_stake_recipient, - tokens_to_withdraw, - ) = setup(spl_token::id()).await; - - // add another validator and deposit into it - let other_validator_stake_account = simple_add_validator_to_pool( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts, - None, - ) - .await; - - let other_deposit_info = simple_deposit_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts, - &other_validator_stake_account, - TEST_STAKE_AMOUNT, - ) - .await - .unwrap(); - - // move tokens to new account - transfer_spl_tokens( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts.token_program_id, - &deposit_info.pool_account.pubkey(), - &stake_pool_accounts.pool_mint.pubkey(), - &other_deposit_info.pool_account.pubkey(), - &user_transfer_authority, - tokens_to_withdraw, - stake_pool_accounts.pool_decimals, - ) - .await; - - let user_tokens = get_token_balance( - &mut context.banks_client, - &other_deposit_info.pool_account.pubkey(), - ) - .await; - - let user_transfer_authority = Keypair::new(); - delegate_tokens( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts.token_program_id, - &other_deposit_info.pool_account.pubkey(), - &other_deposit_info.authority, - &user_transfer_authority.pubkey(), - user_tokens, - ) - .await; - - // calculate exactly how much to withdraw, given the fee, to get the account - // down to 0, using an inverse fee calculation - let validator_stake_account = get_account( - &mut context.banks_client, - &other_validator_stake_account.stake_account, - ) - .await; - let stake_state = - deserialize::(&validator_stake_account.data).unwrap(); - let meta = stake_state.meta().unwrap(); - let stake_minimum_delegation = stake_get_minimum_delegation( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - ) - .await; - let lamports_to_withdraw = - validator_stake_account.lamports - minimum_stake_lamports(&meta, stake_minimum_delegation); - let stake_pool_account = get_account( - &mut context.banks_client, - &stake_pool_accounts.stake_pool.pubkey(), - ) - .await; - let stake_pool = - try_from_slice_unchecked::(stake_pool_account.data.as_slice()).unwrap(); - let fee = stake_pool.stake_withdrawal_fee; - let inverse_fee = state::Fee { - numerator: fee.denominator - fee.numerator, - denominator: fee.denominator, - }; - let pool_tokens_to_withdraw = - lamports_to_withdraw * inverse_fee.denominator / inverse_fee.numerator; - - let new_authority = Pubkey::new_unique(); - let error = stake_pool_accounts - .withdraw_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &user_stake_recipient.pubkey(), - &user_transfer_authority, - &other_deposit_info.pool_account.pubkey(), - &other_validator_stake_account.stake_account, - &new_authority, - pool_tokens_to_withdraw, - ) - .await; - assert!(error.is_none()); - - // Check balance of validator stake account is MINIMUM + rent-exemption - let validator_stake_account = get_account( - &mut context.banks_client, - &other_validator_stake_account.stake_account, - ) - .await; - let stake_state = - deserialize::(&validator_stake_account.data).unwrap(); - let meta = stake_state.meta().unwrap(); - assert_eq!( - validator_stake_account.lamports, - minimum_stake_lamports(&meta, stake_minimum_delegation) - ); -} diff --git a/program/tests/withdraw_edge_cases.rs b/program/tests/withdraw_edge_cases.rs new file mode 100644 index 00000000..c506b973 --- /dev/null +++ b/program/tests/withdraw_edge_cases.rs @@ -0,0 +1,928 @@ +#![allow(clippy::integer_arithmetic)] +#![cfg(feature = "test-sbf")] + +mod helpers; + +use { + bincode::deserialize, + helpers::*, + solana_program::{ + borsh::try_from_slice_unchecked, instruction::InstructionError, pubkey::Pubkey, stake, + }, + solana_program_test::*, + solana_sdk::{ + signature::{Keypair, Signer}, + transaction::TransactionError, + }, + spl_stake_pool::{ + error::StakePoolError, instruction, minimum_stake_lamports, state, MINIMUM_RESERVE_LAMPORTS, + }, +}; + +async fn setup( + token_program_id: Pubkey, +) -> ( + ProgramTestContext, + StakePoolAccounts, + ValidatorStakeAccount, + DepositStakeAccount, + Keypair, + Keypair, + u64, +) { + let mut context = program_test().start_with_context().await; + let stake_pool_accounts = StakePoolAccounts::new_with_token_program(token_program_id); + stake_pool_accounts + .initialize_stake_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) + .await + .unwrap(); + + let validator_stake_account = simple_add_validator_to_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + None, + ) + .await; + + let current_minimum_delegation = stake_pool_get_minimum_delegation( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; + + let deposit_info = simple_deposit_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + &validator_stake_account, + current_minimum_delegation * 3, + ) + .await + .unwrap(); + + let tokens_to_withdraw = deposit_info.pool_tokens; + + // Delegate tokens for withdrawing + let user_transfer_authority = Keypair::new(); + delegate_tokens( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts.token_program_id, + &deposit_info.pool_account.pubkey(), + &deposit_info.authority, + &user_transfer_authority.pubkey(), + tokens_to_withdraw, + ) + .await; + + // Create stake account to withdraw to + let user_stake_recipient = Keypair::new(); + create_blank_stake_account( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user_stake_recipient, + ) + .await; + + ( + context, + stake_pool_accounts, + validator_stake_account, + deposit_info, + user_transfer_authority, + user_stake_recipient, + tokens_to_withdraw, + ) +} + +#[tokio::test] +async fn fail_remove_validator() { + let ( + mut context, + stake_pool_accounts, + validator_stake, + deposit_info, + user_transfer_authority, + user_stake_recipient, + _, + ) = setup(spl_token::id()).await; + + // decrease a little stake, not all + let error = stake_pool_accounts + .decrease_validator_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &validator_stake.stake_account, + &validator_stake.transient_stake_account, + deposit_info.stake_lamports / 2, + validator_stake.transient_stake_seed, + ) + .await; + assert!(error.is_none()); + + // warp forward to deactivation + let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + context + .warp_to_slot(first_normal_slot + slots_per_epoch) + .unwrap(); + + // update to merge deactivated stake into reserve + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &[validator_stake.vote.pubkey()], + false, + ) + .await; + + // Withdraw entire account, fail because some stake left + let validator_stake_account = + get_account(&mut context.banks_client, &validator_stake.stake_account).await; + let remaining_lamports = validator_stake_account.lamports; + let new_user_authority = Pubkey::new_unique(); + let error = stake_pool_accounts + .withdraw_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user_stake_recipient.pubkey(), + &user_transfer_authority, + &deposit_info.pool_account.pubkey(), + &validator_stake.stake_account, + &new_user_authority, + remaining_lamports, + ) + .await + .unwrap() + .unwrap(); + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::StakeLamportsNotEqualToMinimum as u32) + ) + ); +} + +#[tokio::test] +async fn success_remove_validator() { + let ( + mut context, + stake_pool_accounts, + validator_stake, + deposit_info, + user_transfer_authority, + user_stake_recipient, + _, + ) = setup(spl_token::id()).await; + + let rent = context.banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + + // decrease all of stake + let error = stake_pool_accounts + .decrease_validator_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &validator_stake.stake_account, + &validator_stake.transient_stake_account, + deposit_info.stake_lamports + stake_rent, + validator_stake.transient_stake_seed, + ) + .await; + assert!(error.is_none()); + + // warp forward to deactivation + let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + context + .warp_to_slot(first_normal_slot + slots_per_epoch) + .unwrap(); + + // update to merge deactivated stake into reserve + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &[validator_stake.vote.pubkey()], + false, + ) + .await; + + let validator_stake_account = + get_account(&mut context.banks_client, &validator_stake.stake_account).await; + let remaining_lamports = validator_stake_account.lamports; + let new_user_authority = Pubkey::new_unique(); + let pool_tokens = stake_pool_accounts.calculate_inverse_withdrawal_fee(remaining_lamports); + let error = stake_pool_accounts + .withdraw_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user_stake_recipient.pubkey(), + &user_transfer_authority, + &deposit_info.pool_account.pubkey(), + &validator_stake.stake_account, + &new_user_authority, + pool_tokens, + ) + .await; + assert!(error.is_none()); + + // Check validator stake account gone + let validator_stake_account = context + .banks_client + .get_account(validator_stake.stake_account) + .await + .unwrap(); + assert!(validator_stake_account.is_none()); + + // Check user recipient stake account balance + let user_stake_recipient_account = + get_account(&mut context.banks_client, &user_stake_recipient.pubkey()).await; + assert_eq!( + user_stake_recipient_account.lamports, + remaining_lamports + stake_rent + 1 + ); + + // Check that cleanup happens correctly + stake_pool_accounts + .cleanup_removed_validator_entries( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; + + let validator_list = get_account( + &mut context.banks_client, + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + let validator_list = + try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); + let validator_stake_item = validator_list.find(&validator_stake.vote.pubkey()); + assert!(validator_stake_item.is_none()); +} + +#[tokio::test] +async fn fail_with_reserve() { + let ( + mut context, + stake_pool_accounts, + validator_stake, + deposit_info, + user_transfer_authority, + user_stake_recipient, + tokens_to_burn, + ) = setup(spl_token::id()).await; + + // decrease a little stake, not all + let error = stake_pool_accounts + .decrease_validator_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &validator_stake.stake_account, + &validator_stake.transient_stake_account, + deposit_info.stake_lamports / 2, + validator_stake.transient_stake_seed, + ) + .await; + assert!(error.is_none()); + + // warp forward to deactivation + let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + context + .warp_to_slot(first_normal_slot + slots_per_epoch) + .unwrap(); + + // update to merge deactivated stake into reserve + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &[validator_stake.vote.pubkey()], + false, + ) + .await; + + // Withdraw directly from reserve, fail because some stake left + let new_user_authority = Pubkey::new_unique(); + let error = stake_pool_accounts + .withdraw_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user_stake_recipient.pubkey(), + &user_transfer_authority, + &deposit_info.pool_account.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), + &new_user_authority, + tokens_to_burn, + ) + .await + .unwrap() + .unwrap(); + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::StakeLamportsNotEqualToMinimum as u32) + ) + ); +} + +#[tokio::test] +async fn success_with_reserve() { + let ( + mut context, + stake_pool_accounts, + validator_stake, + deposit_info, + user_transfer_authority, + user_stake_recipient, + _, + ) = setup(spl_token::id()).await; + + let rent = context.banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + + // decrease all of stake + let error = stake_pool_accounts + .decrease_validator_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &validator_stake.stake_account, + &validator_stake.transient_stake_account, + deposit_info.stake_lamports + stake_rent, + validator_stake.transient_stake_seed, + ) + .await; + assert!(error.is_none()); + + // warp forward to deactivation + let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + context + .warp_to_slot(first_normal_slot + slots_per_epoch) + .unwrap(); + + // update to merge deactivated stake into reserve + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &[validator_stake.vote.pubkey()], + false, + ) + .await; + + // now it works + let new_user_authority = Pubkey::new_unique(); + let error = stake_pool_accounts + .withdraw_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user_stake_recipient.pubkey(), + &user_transfer_authority, + &deposit_info.pool_account.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), + &new_user_authority, + deposit_info.pool_tokens, + ) + .await; + assert!(error.is_none()); + + // first and only deposit, lamports:pool 1:1 + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = + try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); + // the entire deposit is actually stake since it isn't activated, so only + // the stake deposit fee is charged + let deposit_fee = stake_pool + .calc_pool_tokens_stake_deposit_fee(stake_rent + deposit_info.stake_lamports) + .unwrap(); + assert_eq!( + deposit_info.stake_lamports + stake_rent - deposit_fee, + deposit_info.pool_tokens, + "stake {} rent {} deposit fee {} pool tokens {}", + deposit_info.stake_lamports, + stake_rent, + deposit_fee, + deposit_info.pool_tokens + ); + + let withdrawal_fee = stake_pool_accounts.calculate_withdrawal_fee(deposit_info.pool_tokens); + + // Check tokens used + let user_token_balance = get_token_balance( + &mut context.banks_client, + &deposit_info.pool_account.pubkey(), + ) + .await; + assert_eq!(user_token_balance, 0); + + // Check reserve stake account balance + let reserve_stake_account = get_account( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + ) + .await; + let stake_state = deserialize::(&reserve_stake_account.data).unwrap(); + let meta = stake_state.meta().unwrap(); + assert_eq!( + MINIMUM_RESERVE_LAMPORTS + meta.rent_exempt_reserve + withdrawal_fee + deposit_fee, + reserve_stake_account.lamports + ); + + // Check user recipient stake account balance + let user_stake_recipient_account = + get_account(&mut context.banks_client, &user_stake_recipient.pubkey()).await; + assert_eq!( + user_stake_recipient_account.lamports, + MINIMUM_RESERVE_LAMPORTS + deposit_info.stake_lamports + stake_rent * 2 + - withdrawal_fee + - deposit_fee + ); +} + +#[tokio::test] +async fn success_and_fail_with_preferred_withdraw() { + let ( + mut context, + stake_pool_accounts, + validator_stake, + deposit_info, + user_transfer_authority, + user_stake_recipient, + tokens_to_burn, + ) = setup(spl_token::id()).await; + + let preferred_validator = simple_add_validator_to_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + None, + ) + .await; + + stake_pool_accounts + .set_preferred_validator( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + instruction::PreferredValidatorType::Withdraw, + Some(preferred_validator.vote.pubkey()), + ) + .await; + + // preferred is empty, withdrawing from non-preferred works + let new_authority = Pubkey::new_unique(); + let error = stake_pool_accounts + .withdraw_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user_stake_recipient.pubkey(), + &user_transfer_authority, + &deposit_info.pool_account.pubkey(), + &validator_stake.stake_account, + &new_authority, + tokens_to_burn / 2, + ) + .await; + assert!(error.is_none()); + + // Deposit into preferred, then fail + let user_stake_recipient = Keypair::new(); + create_blank_stake_account( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user_stake_recipient, + ) + .await; + + let _preferred_deposit = simple_deposit_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + &preferred_validator, + TEST_STAKE_AMOUNT, + ) + .await + .unwrap(); + + let error = stake_pool_accounts + .withdraw_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user_stake_recipient.pubkey(), + &user_transfer_authority, + &deposit_info.pool_account.pubkey(), + &validator_stake.stake_account, + &new_authority, + tokens_to_burn / 2, + ) + .await + .unwrap() + .unwrap(); + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::IncorrectWithdrawVoteAddress as u32) + ) + ); + + // success from preferred + let error = stake_pool_accounts + .withdraw_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user_stake_recipient.pubkey(), + &user_transfer_authority, + &deposit_info.pool_account.pubkey(), + &preferred_validator.stake_account, + &new_authority, + tokens_to_burn / 2, + ) + .await; + assert!(error.is_none()); +} + +#[tokio::test] +async fn fail_withdraw_from_transient() { + let ( + mut context, + stake_pool_accounts, + validator_stake_account, + deposit_info, + user_transfer_authority, + user_stake_recipient, + tokens_to_withdraw, + ) = setup(spl_token::id()).await; + + // add a preferred withdraw validator, keep it empty, to be sure that this works + let preferred_validator = simple_add_validator_to_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + None, + ) + .await; + + stake_pool_accounts + .set_preferred_validator( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + instruction::PreferredValidatorType::Withdraw, + Some(preferred_validator.vote.pubkey()), + ) + .await; + + let rent = context.banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + + // decrease to minimum stake + 1 lamport + let error = stake_pool_accounts + .decrease_validator_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &validator_stake_account.stake_account, + &validator_stake_account.transient_stake_account, + deposit_info.stake_lamports + stake_rent - 1, + validator_stake_account.transient_stake_seed, + ) + .await; + assert!(error.is_none()); + + // fail withdrawing from transient, still a lamport in the validator stake account + let new_user_authority = Pubkey::new_unique(); + let error = stake_pool_accounts + .withdraw_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user_stake_recipient.pubkey(), + &user_transfer_authority, + &deposit_info.pool_account.pubkey(), + &validator_stake_account.transient_stake_account, + &new_user_authority, + tokens_to_withdraw, + ) + .await + .unwrap() + .unwrap(); + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::InvalidStakeAccountAddress as u32) + ) + ); +} + +#[tokio::test] +async fn success_withdraw_from_transient() { + let ( + mut context, + stake_pool_accounts, + validator_stake_account, + deposit_info, + user_transfer_authority, + user_stake_recipient, + tokens_to_withdraw, + ) = setup(spl_token::id()).await; + + // add a preferred withdraw validator, keep it empty, to be sure that this works + let preferred_validator = simple_add_validator_to_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + None, + ) + .await; + + stake_pool_accounts + .set_preferred_validator( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + instruction::PreferredValidatorType::Withdraw, + Some(preferred_validator.vote.pubkey()), + ) + .await; + + let rent = context.banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + + // decrease all of stake + let error = stake_pool_accounts + .decrease_validator_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &validator_stake_account.stake_account, + &validator_stake_account.transient_stake_account, + deposit_info.stake_lamports + stake_rent, + validator_stake_account.transient_stake_seed, + ) + .await; + assert!(error.is_none()); + + // nothing left in the validator stake account (or any others), so withdrawing + // from the transient account is ok! + let new_user_authority = Pubkey::new_unique(); + let error = stake_pool_accounts + .withdraw_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user_stake_recipient.pubkey(), + &user_transfer_authority, + &deposit_info.pool_account.pubkey(), + &validator_stake_account.transient_stake_account, + &new_user_authority, + tokens_to_withdraw / 2, + ) + .await; + assert!(error.is_none()); +} + +#[tokio::test] +async fn success_withdraw_all_fee_tokens() { + let ( + mut context, + stake_pool_accounts, + validator_stake_account, + deposit_info, + user_transfer_authority, + user_stake_recipient, + tokens_to_withdraw, + ) = setup(spl_token::id()).await; + + // move tokens to fee account + transfer_spl_tokens( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts.token_program_id, + &deposit_info.pool_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &stake_pool_accounts.pool_fee_account.pubkey(), + &user_transfer_authority, + tokens_to_withdraw / 2, + stake_pool_accounts.pool_decimals, + ) + .await; + + let fee_tokens = get_token_balance( + &mut context.banks_client, + &stake_pool_accounts.pool_fee_account.pubkey(), + ) + .await; + + let user_transfer_authority = Keypair::new(); + delegate_tokens( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts.token_program_id, + &stake_pool_accounts.pool_fee_account.pubkey(), + &stake_pool_accounts.manager, + &user_transfer_authority.pubkey(), + fee_tokens, + ) + .await; + + let new_authority = Pubkey::new_unique(); + let error = stake_pool_accounts + .withdraw_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user_stake_recipient.pubkey(), + &user_transfer_authority, + &stake_pool_accounts.pool_fee_account.pubkey(), + &validator_stake_account.stake_account, + &new_authority, + fee_tokens, + ) + .await; + assert!(error.is_none()); + + // Check balance is 0 + let fee_tokens = get_token_balance( + &mut context.banks_client, + &stake_pool_accounts.pool_fee_account.pubkey(), + ) + .await; + assert_eq!(fee_tokens, 0); +} + +#[tokio::test] +async fn success_empty_out_stake_with_fee() { + let ( + mut context, + stake_pool_accounts, + _, + deposit_info, + user_transfer_authority, + user_stake_recipient, + tokens_to_withdraw, + ) = setup(spl_token::id()).await; + + // add another validator and deposit into it + let other_validator_stake_account = simple_add_validator_to_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + None, + ) + .await; + + let other_deposit_info = simple_deposit_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + &other_validator_stake_account, + TEST_STAKE_AMOUNT, + ) + .await + .unwrap(); + + // move tokens to new account + transfer_spl_tokens( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts.token_program_id, + &deposit_info.pool_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &other_deposit_info.pool_account.pubkey(), + &user_transfer_authority, + tokens_to_withdraw, + stake_pool_accounts.pool_decimals, + ) + .await; + + let user_tokens = get_token_balance( + &mut context.banks_client, + &other_deposit_info.pool_account.pubkey(), + ) + .await; + + let user_transfer_authority = Keypair::new(); + delegate_tokens( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts.token_program_id, + &other_deposit_info.pool_account.pubkey(), + &other_deposit_info.authority, + &user_transfer_authority.pubkey(), + user_tokens, + ) + .await; + + // calculate exactly how much to withdraw, given the fee, to get the account + // down to 0, using an inverse fee calculation + let validator_stake_account = get_account( + &mut context.banks_client, + &other_validator_stake_account.stake_account, + ) + .await; + let stake_state = + deserialize::(&validator_stake_account.data).unwrap(); + let meta = stake_state.meta().unwrap(); + let stake_minimum_delegation = stake_get_minimum_delegation( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; + let lamports_to_withdraw = + validator_stake_account.lamports - minimum_stake_lamports(&meta, stake_minimum_delegation); + let stake_pool_account = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = + try_from_slice_unchecked::(stake_pool_account.data.as_slice()).unwrap(); + let fee = stake_pool.stake_withdrawal_fee; + let inverse_fee = state::Fee { + numerator: fee.denominator - fee.numerator, + denominator: fee.denominator, + }; + let pool_tokens_to_withdraw = + lamports_to_withdraw * inverse_fee.denominator / inverse_fee.numerator; + + let new_authority = Pubkey::new_unique(); + let error = stake_pool_accounts + .withdraw_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user_stake_recipient.pubkey(), + &user_transfer_authority, + &other_deposit_info.pool_account.pubkey(), + &other_validator_stake_account.stake_account, + &new_authority, + pool_tokens_to_withdraw, + ) + .await; + assert!(error.is_none()); + + // Check balance of validator stake account is MINIMUM + rent-exemption + let validator_stake_account = get_account( + &mut context.banks_client, + &other_validator_stake_account.stake_account, + ) + .await; + let stake_state = + deserialize::(&validator_stake_account.data).unwrap(); + let meta = stake_state.meta().unwrap(); + assert_eq!( + validator_stake_account.lamports, + minimum_stake_lamports(&meta, stake_minimum_delegation) + ); +} From a441c841ab8c40fdcba1fcc6658a24304f79b48a Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 29 Nov 2022 15:49:55 +0100 Subject: [PATCH 0271/1076] stake-pool: Split up more tests to help CI, avoid warping (#3852) * stake-pool: Split up more tests to help CI, avoid warping * Remove unnecessary updates * Split preferred test that keeps failing --- program/tests/deposit.rs | 232 +------- program/tests/deposit_edge_cases.rs | 336 +++++++++++ program/tests/update_stake_pool_balance.rs | 36 +- .../tests/update_validator_list_balance.rs | 378 +------------ .../update_validator_list_balance_hijack.rs | 521 ++++++++++++++++++ program/tests/withdraw_edge_cases.rs | 33 +- 6 files changed, 896 insertions(+), 640 deletions(-) create mode 100644 program/tests/deposit_edge_cases.rs create mode 100644 program/tests/update_validator_list_balance_hijack.rs diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 1b792909..bea72864 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -56,11 +56,6 @@ async fn setup( ) .await; - let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; - let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; - let mut slot = first_normal_slot; - context.warp_to_slot(slot).unwrap(); - let user = Keypair::new(); // make stake account let deposit_stake = Keypair::new(); @@ -92,8 +87,8 @@ async fn setup( ) .await; - slot += slots_per_epoch; - context.warp_to_slot(slot).unwrap(); + let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; + context.warp_to_slot(first_normal_slot).unwrap(); stake_pool_accounts .update_all( &mut context.banks_client, @@ -805,226 +800,3 @@ async fn fail_with_wrong_mint_for_receiver_acc() { } } } - -#[tokio::test] -async fn fail_with_uninitialized_validator_list() {} // TODO - -#[tokio::test] -async fn fail_with_out_of_dated_pool_balances() {} // TODO - -#[tokio::test] -async fn success_with_preferred_deposit() { - let ( - mut context, - stake_pool_accounts, - validator_stake, - user, - deposit_stake, - pool_token_account, - _stake_lamports, - ) = setup(spl_token::id()).await; - - stake_pool_accounts - .set_preferred_validator( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - instruction::PreferredValidatorType::Deposit, - Some(validator_stake.vote.pubkey()), - ) - .await; - - let error = stake_pool_accounts - .deposit_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &deposit_stake, - &pool_token_account, - &validator_stake.stake_account, - &user, - ) - .await; - assert!(error.is_none()); -} - -#[tokio::test] -async fn fail_with_wrong_preferred_deposit() { - let ( - mut context, - stake_pool_accounts, - validator_stake, - user, - deposit_stake, - pool_token_account, - _stake_lamports, - ) = setup(spl_token::id()).await; - - let preferred_validator = simple_add_validator_to_pool( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts, - None, - ) - .await; - - stake_pool_accounts - .set_preferred_validator( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - instruction::PreferredValidatorType::Deposit, - Some(preferred_validator.vote.pubkey()), - ) - .await; - - let error = stake_pool_accounts - .deposit_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &deposit_stake, - &pool_token_account, - &validator_stake.stake_account, - &user, - ) - .await - .unwrap() - .unwrap(); - match error { - TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { - assert_eq!( - error_index, - StakePoolError::IncorrectDepositVoteAddress as u32 - ); - } - _ => panic!("Wrong error occurs while try to make a deposit with wrong stake program ID"), - } -} - -#[tokio::test] -async fn success_with_referral_fee() { - let ( - mut context, - stake_pool_accounts, - validator_stake_account, - user, - deposit_stake, - pool_token_account, - stake_lamports, - ) = setup(spl_token::id()).await; - - let referrer = Keypair::new(); - let referrer_token_account = Keypair::new(); - create_token_account( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts.token_program_id, - &referrer_token_account, - &stake_pool_accounts.pool_mint.pubkey(), - &referrer, - &[], - ) - .await - .unwrap(); - - let referrer_balance_pre = - get_token_balance(&mut context.banks_client, &referrer_token_account.pubkey()).await; - - let mut transaction = Transaction::new_with_payer( - &instruction::deposit_stake( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.validator_list.pubkey(), - &stake_pool_accounts.withdraw_authority, - &deposit_stake, - &user.pubkey(), - &validator_stake_account.stake_account, - &stake_pool_accounts.reserve_stake.pubkey(), - &pool_token_account, - &stake_pool_accounts.pool_fee_account.pubkey(), - &referrer_token_account.pubkey(), - &stake_pool_accounts.pool_mint.pubkey(), - &spl_token::id(), - ), - Some(&context.payer.pubkey()), - ); - transaction.sign(&[&context.payer, &user], context.last_blockhash); - context - .banks_client - .process_transaction(transaction) - .await - .unwrap(); - - let referrer_balance_post = - get_token_balance(&mut context.banks_client, &referrer_token_account.pubkey()).await; - let stake_pool = get_account( - &mut context.banks_client, - &stake_pool_accounts.stake_pool.pubkey(), - ) - .await; - let stake_pool = - try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); - let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); - let fee_tokens = stake_pool - .calc_pool_tokens_sol_deposit_fee(stake_rent) - .unwrap() - + stake_pool - .calc_pool_tokens_stake_deposit_fee(stake_lamports - stake_rent) - .unwrap(); - let referral_fee = stake_pool_accounts.calculate_referral_fee(fee_tokens); - assert!(referral_fee > 0); - assert_eq!(referrer_balance_pre + referral_fee, referrer_balance_post); -} - -#[tokio::test] -async fn fail_with_invalid_referrer() { - let ( - mut context, - stake_pool_accounts, - validator_stake_account, - user, - deposit_stake, - pool_token_account, - _stake_lamports, - ) = setup(spl_token::id()).await; - - let invalid_token_account = Keypair::new(); - - let mut transaction = Transaction::new_with_payer( - &instruction::deposit_stake( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.validator_list.pubkey(), - &stake_pool_accounts.withdraw_authority, - &deposit_stake, - &user.pubkey(), - &validator_stake_account.stake_account, - &stake_pool_accounts.reserve_stake.pubkey(), - &pool_token_account, - &stake_pool_accounts.pool_fee_account.pubkey(), - &invalid_token_account.pubkey(), - &stake_pool_accounts.pool_mint.pubkey(), - &spl_token::id(), - ), - Some(&context.payer.pubkey()), - ); - transaction.sign(&[&context.payer, &user], context.last_blockhash); - let transaction_error = context - .banks_client - .process_transaction(transaction) - .await - .err() - .unwrap() - .unwrap(); - - match transaction_error { - TransactionError::InstructionError(_, InstructionError::InvalidAccountData) => (), - _ => panic!( - "Wrong error occurs while try to make a deposit with an invalid referrer account" - ), - } -} diff --git a/program/tests/deposit_edge_cases.rs b/program/tests/deposit_edge_cases.rs new file mode 100644 index 00000000..13482fd5 --- /dev/null +++ b/program/tests/deposit_edge_cases.rs @@ -0,0 +1,336 @@ +#![allow(clippy::integer_arithmetic)] +#![cfg(feature = "test-sbf")] + +mod helpers; + +use { + helpers::*, + solana_program::{ + borsh::try_from_slice_unchecked, instruction::InstructionError, pubkey::Pubkey, stake, + }, + solana_program_test::*, + solana_sdk::{ + signature::{Keypair, Signer}, + transaction::{Transaction, TransactionError}, + }, + spl_stake_pool::{error::StakePoolError, id, instruction, state, MINIMUM_RESERVE_LAMPORTS}, +}; + +async fn setup( + token_program_id: Pubkey, +) -> ( + ProgramTestContext, + StakePoolAccounts, + ValidatorStakeAccount, + Keypair, + Pubkey, + Pubkey, + u64, +) { + let mut context = program_test().start_with_context().await; + + let stake_pool_accounts = StakePoolAccounts::new_with_token_program(token_program_id); + stake_pool_accounts + .initialize_stake_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) + .await + .unwrap(); + + let validator_stake_account = simple_add_validator_to_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + None, + ) + .await; + + let user = Keypair::new(); + // make stake account + let deposit_stake = Keypair::new(); + let lockup = stake::state::Lockup::default(); + + let authorized = stake::state::Authorized { + staker: user.pubkey(), + withdrawer: user.pubkey(), + }; + + let stake_lamports = create_independent_stake_account( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &deposit_stake, + &authorized, + &lockup, + TEST_STAKE_AMOUNT, + ) + .await; + + delegate_stake_account( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &deposit_stake.pubkey(), + &user, + &validator_stake_account.vote.pubkey(), + ) + .await; + + let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; + context.warp_to_slot(first_normal_slot).unwrap(); + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &[validator_stake_account.vote.pubkey()], + false, + ) + .await; + + // make pool token account + let pool_token_account = Keypair::new(); + create_token_account( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts.token_program_id, + &pool_token_account, + &stake_pool_accounts.pool_mint.pubkey(), + &user, + &[], + ) + .await + .unwrap(); + + ( + context, + stake_pool_accounts, + validator_stake_account, + user, + deposit_stake.pubkey(), + pool_token_account.pubkey(), + stake_lamports, + ) +} + +#[tokio::test] +async fn success_with_preferred_deposit() { + let ( + mut context, + stake_pool_accounts, + validator_stake, + user, + deposit_stake, + pool_token_account, + _stake_lamports, + ) = setup(spl_token::id()).await; + + stake_pool_accounts + .set_preferred_validator( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + instruction::PreferredValidatorType::Deposit, + Some(validator_stake.vote.pubkey()), + ) + .await; + + let error = stake_pool_accounts + .deposit_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &deposit_stake, + &pool_token_account, + &validator_stake.stake_account, + &user, + ) + .await; + assert!(error.is_none()); +} + +#[tokio::test] +async fn fail_with_wrong_preferred_deposit() { + let ( + mut context, + stake_pool_accounts, + validator_stake, + user, + deposit_stake, + pool_token_account, + _stake_lamports, + ) = setup(spl_token::id()).await; + + let preferred_validator = simple_add_validator_to_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + None, + ) + .await; + + stake_pool_accounts + .set_preferred_validator( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + instruction::PreferredValidatorType::Deposit, + Some(preferred_validator.vote.pubkey()), + ) + .await; + + let error = stake_pool_accounts + .deposit_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &deposit_stake, + &pool_token_account, + &validator_stake.stake_account, + &user, + ) + .await + .unwrap() + .unwrap(); + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + assert_eq!( + error_index, + StakePoolError::IncorrectDepositVoteAddress as u32 + ); + } + _ => panic!("Wrong error occurs while try to make a deposit with wrong stake program ID"), + } +} + +#[tokio::test] +async fn success_with_referral_fee() { + let ( + mut context, + stake_pool_accounts, + validator_stake_account, + user, + deposit_stake, + pool_token_account, + stake_lamports, + ) = setup(spl_token::id()).await; + + let referrer = Keypair::new(); + let referrer_token_account = Keypair::new(); + create_token_account( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts.token_program_id, + &referrer_token_account, + &stake_pool_accounts.pool_mint.pubkey(), + &referrer, + &[], + ) + .await + .unwrap(); + + let referrer_balance_pre = + get_token_balance(&mut context.banks_client, &referrer_token_account.pubkey()).await; + + let mut transaction = Transaction::new_with_payer( + &instruction::deposit_stake( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.withdraw_authority, + &deposit_stake, + &user.pubkey(), + &validator_stake_account.stake_account, + &stake_pool_accounts.reserve_stake.pubkey(), + &pool_token_account, + &stake_pool_accounts.pool_fee_account.pubkey(), + &referrer_token_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &spl_token::id(), + ), + Some(&context.payer.pubkey()), + ); + transaction.sign(&[&context.payer, &user], context.last_blockhash); + context + .banks_client + .process_transaction(transaction) + .await + .unwrap(); + + let referrer_balance_post = + get_token_balance(&mut context.banks_client, &referrer_token_account.pubkey()).await; + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = + try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); + let rent = context.banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let fee_tokens = stake_pool + .calc_pool_tokens_sol_deposit_fee(stake_rent) + .unwrap() + + stake_pool + .calc_pool_tokens_stake_deposit_fee(stake_lamports - stake_rent) + .unwrap(); + let referral_fee = stake_pool_accounts.calculate_referral_fee(fee_tokens); + assert!(referral_fee > 0); + assert_eq!(referrer_balance_pre + referral_fee, referrer_balance_post); +} + +#[tokio::test] +async fn fail_with_invalid_referrer() { + let ( + mut context, + stake_pool_accounts, + validator_stake_account, + user, + deposit_stake, + pool_token_account, + _stake_lamports, + ) = setup(spl_token::id()).await; + + let invalid_token_account = Keypair::new(); + + let mut transaction = Transaction::new_with_payer( + &instruction::deposit_stake( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.withdraw_authority, + &deposit_stake, + &user.pubkey(), + &validator_stake_account.stake_account, + &stake_pool_accounts.reserve_stake.pubkey(), + &pool_token_account, + &stake_pool_accounts.pool_fee_account.pubkey(), + &invalid_token_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &spl_token::id(), + ), + Some(&context.payer.pubkey()), + ); + transaction.sign(&[&context.payer, &user], context.last_blockhash); + let transaction_error = context + .banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + match transaction_error { + TransactionError::InstructionError(_, InstructionError::InvalidAccountData) => (), + _ => panic!( + "Wrong error occurs while try to make a deposit with an invalid referrer account" + ), + } +} diff --git a/program/tests/update_stake_pool_balance.rs b/program/tests/update_stake_pool_balance.rs index c924e625..b678b03c 100644 --- a/program/tests/update_stake_pool_balance.rs +++ b/program/tests/update_stake_pool_balance.rs @@ -26,12 +26,8 @@ async fn setup( ProgramTestContext, StakePoolAccounts, Vec, - u64, ) { let mut context = program_test().start_with_context().await; - let slot = context.genesis_config().epoch_schedule.first_normal_slot; - context.warp_to_slot(slot).unwrap(); - let stake_pool_accounts = StakePoolAccounts::default(); stake_pool_accounts .initialize_stake_pool( @@ -118,12 +114,12 @@ async fn setup( stake_accounts.push(stake_account); } - (context, stake_pool_accounts, stake_accounts, slot) + (context, stake_pool_accounts, stake_accounts) } #[tokio::test] async fn success() { - let (mut context, stake_pool_accounts, stake_accounts, slot) = setup(NUM_VALIDATORS).await; + let (mut context, stake_pool_accounts, stake_accounts) = setup(NUM_VALIDATORS).await; let pre_fee = get_token_balance( &mut context.banks_client, @@ -151,15 +147,6 @@ async fn success() { ) .await; - let error = stake_pool_accounts - .update_stake_pool_balance( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - ) - .await; - assert!(error.is_none()); - // Increment vote credits to earn rewards const VOTE_CREDITS: u64 = 1_000; for stake_account in &stake_accounts { @@ -167,8 +154,8 @@ async fn success() { } // Update epoch - let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; - context.warp_to_slot(slot + slots_per_epoch).unwrap(); + let slot = context.genesis_config().epoch_schedule.first_normal_slot; + context.warp_to_slot(slot).unwrap(); // Update list and pool let error = stake_pool_accounts @@ -229,7 +216,7 @@ async fn success() { #[tokio::test] async fn success_absorbing_extra_lamports() { - let (mut context, stake_pool_accounts, stake_accounts, slot) = setup(NUM_VALIDATORS).await; + let (mut context, stake_pool_accounts, stake_accounts) = setup(NUM_VALIDATORS).await; let pre_balance = get_validator_list_sum( &mut context.banks_client, @@ -251,15 +238,6 @@ async fn success_absorbing_extra_lamports() { ) .await; - let error = stake_pool_accounts - .update_stake_pool_balance( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - ) - .await; - assert!(error.is_none()); - // Transfer extra funds, will be absorbed during update const EXTRA_STAKE_AMOUNT: u64 = 1_000_000; for stake_account in &stake_accounts { @@ -277,8 +255,8 @@ async fn success_absorbing_extra_lamports() { let expected_fee = stake_pool.calc_epoch_fee_amount(extra_lamports).unwrap(); // Update epoch - let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; - context.warp_to_slot(slot + slots_per_epoch).unwrap(); + let slot = context.genesis_config().epoch_schedule.first_normal_slot; + context.warp_to_slot(slot).unwrap(); // Update list and pool let error = stake_pool_accounts diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index e146ec12..f333eac6 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -5,19 +5,10 @@ mod helpers; use { helpers::*, - solana_program::{borsh::try_from_slice_unchecked, program_pack::Pack, pubkey::Pubkey, stake}, + solana_program::{borsh::try_from_slice_unchecked, program_pack::Pack, pubkey::Pubkey}, solana_program_test::*, - solana_sdk::{ - instruction::InstructionError, - signature::Signer, - stake::state::{Authorized, Lockup, StakeState}, - system_instruction, - transaction::{Transaction, TransactionError}, - }, + solana_sdk::{signature::Signer, stake::state::StakeState}, spl_stake_pool::{ - error::StakePoolError, - find_stake_program_address, find_transient_stake_program_address, - find_withdraw_authority_program_address, id, instruction, state::{StakePool, StakeStatus, ValidatorList}, MAX_VALIDATORS_TO_UPDATE, MINIMUM_RESERVE_LAMPORTS, }, @@ -719,371 +710,6 @@ async fn success_with_burned_tokens() { assert_eq!(mint.supply, stake_pool.pool_token_supply); } -#[tokio::test] -async fn success_ignoring_hijacked_transient_stake_with_authorized() { - let hijacker = Pubkey::new_unique(); - check_ignored_hijacked_transient_stake(Some(&Authorized::auto(&hijacker)), None).await; -} - -#[tokio::test] -async fn success_ignoring_hijacked_transient_stake_with_lockup() { - let hijacker = Pubkey::new_unique(); - check_ignored_hijacked_transient_stake( - None, - Some(&Lockup { - custodian: hijacker, - ..Lockup::default() - }), - ) - .await; -} - -async fn check_ignored_hijacked_transient_stake( - hijack_authorized: Option<&Authorized>, - hijack_lockup: Option<&Lockup>, -) { - let num_validators = 1; - let (mut context, stake_pool_accounts, stake_accounts, _, lamports, _, mut slot) = - setup(num_validators).await; - - let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); - - let pre_lamports = get_validator_list_sum( - &mut context.banks_client, - &stake_pool_accounts.reserve_stake.pubkey(), - &stake_pool_accounts.validator_list.pubkey(), - ) - .await; - let (withdraw_authority, _) = - find_withdraw_authority_program_address(&id(), &stake_pool_accounts.stake_pool.pubkey()); - - println!("Decrease from all validators"); - let stake_account = &stake_accounts[0]; - let error = stake_pool_accounts - .decrease_validator_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_account.stake_account, - &stake_account.transient_stake_account, - lamports, - stake_account.transient_stake_seed, - ) - .await; - assert!(error.is_none()); - - println!("Warp one epoch so the stakes deactivate and merge"); - let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; - slot += slots_per_epoch; - context.warp_to_slot(slot).unwrap(); - - println!("During update, hijack the transient stake account"); - let validator_list = stake_pool_accounts - .get_validator_list(&mut context.banks_client) - .await; - let transient_stake_address = find_transient_stake_program_address( - &id(), - &stake_account.vote.pubkey(), - &stake_pool_accounts.stake_pool.pubkey(), - stake_account.transient_stake_seed, - ) - .0; - let transaction = Transaction::new_signed_with_payer( - &[ - instruction::update_validator_list_balance( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.withdraw_authority, - &stake_pool_accounts.validator_list.pubkey(), - &stake_pool_accounts.reserve_stake.pubkey(), - &validator_list, - &[stake_account.vote.pubkey()], - 0, - /* no_merge = */ false, - ), - system_instruction::transfer( - &context.payer.pubkey(), - &transient_stake_address, - stake_rent + MINIMUM_RESERVE_LAMPORTS, - ), - stake::instruction::initialize( - &transient_stake_address, - hijack_authorized.unwrap_or(&Authorized::auto(&withdraw_authority)), - hijack_lockup.unwrap_or(&Lockup::default()), - ), - instruction::update_stake_pool_balance( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.withdraw_authority, - &stake_pool_accounts.validator_list.pubkey(), - &stake_pool_accounts.reserve_stake.pubkey(), - &stake_pool_accounts.pool_fee_account.pubkey(), - &stake_pool_accounts.pool_mint.pubkey(), - &spl_token::id(), - ), - instruction::cleanup_removed_validator_entries( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.validator_list.pubkey(), - ), - ], - Some(&context.payer.pubkey()), - &[&context.payer], - context.last_blockhash, - ); - let error = context - .banks_client - .process_transaction(transaction) - .await - .err(); - assert!(error.is_none()); - - println!("Update again normally, should be no change in the lamports"); - stake_pool_accounts - .update_all( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - stake_accounts - .iter() - .map(|v| v.vote.pubkey()) - .collect::>() - .as_slice(), - false, - ) - .await; - - let expected_lamports = get_validator_list_sum( - &mut context.banks_client, - &stake_pool_accounts.reserve_stake.pubkey(), - &stake_pool_accounts.validator_list.pubkey(), - ) - .await; - assert_eq!(pre_lamports, expected_lamports); - - let stake_pool_info = get_account( - &mut context.banks_client, - &stake_pool_accounts.stake_pool.pubkey(), - ) - .await; - let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data).unwrap(); - assert_eq!(pre_lamports, stake_pool.total_lamports); -} - -#[tokio::test] -async fn success_ignoring_hijacked_validator_stake_with_authorized() { - let hijacker = Pubkey::new_unique(); - check_ignored_hijacked_transient_stake(Some(&Authorized::auto(&hijacker)), None).await; -} - -#[tokio::test] -async fn success_ignoring_hijacked_validator_stake_with_lockup() { - let hijacker = Pubkey::new_unique(); - check_ignored_hijacked_validator_stake( - None, - Some(&Lockup { - custodian: hijacker, - ..Lockup::default() - }), - ) - .await; -} - -async fn check_ignored_hijacked_validator_stake( - hijack_authorized: Option<&Authorized>, - hijack_lockup: Option<&Lockup>, -) { - let num_validators = 1; - let (mut context, stake_pool_accounts, stake_accounts, _, lamports, _, mut slot) = - setup(num_validators).await; - - let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); - - let pre_lamports = get_validator_list_sum( - &mut context.banks_client, - &stake_pool_accounts.reserve_stake.pubkey(), - &stake_pool_accounts.validator_list.pubkey(), - ) - .await; - let (withdraw_authority, _) = - find_withdraw_authority_program_address(&id(), &stake_pool_accounts.stake_pool.pubkey()); - - let stake_account = &stake_accounts[0]; - let error = stake_pool_accounts - .decrease_validator_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_account.stake_account, - &stake_account.transient_stake_account, - lamports, - stake_account.transient_stake_seed, - ) - .await; - assert!(error.is_none()); - - let error = stake_pool_accounts - .remove_validator_from_pool( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_account.stake_account, - &stake_account.transient_stake_account, - ) - .await; - assert!(error.is_none()); - - println!("Warp one epoch so the stakes deactivate and merge"); - let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; - slot += slots_per_epoch; - context.warp_to_slot(slot).unwrap(); - - println!("During update, hijack the validator stake account"); - let validator_list = stake_pool_accounts - .get_validator_list(&mut context.banks_client) - .await; - let transaction = Transaction::new_signed_with_payer( - &[ - instruction::update_validator_list_balance( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.withdraw_authority, - &stake_pool_accounts.validator_list.pubkey(), - &stake_pool_accounts.reserve_stake.pubkey(), - &validator_list, - &[stake_account.vote.pubkey()], - 0, - /* no_merge = */ false, - ), - system_instruction::transfer( - &context.payer.pubkey(), - &stake_account.stake_account, - stake_rent + MINIMUM_RESERVE_LAMPORTS, - ), - stake::instruction::initialize( - &stake_account.stake_account, - hijack_authorized.unwrap_or(&Authorized::auto(&withdraw_authority)), - hijack_lockup.unwrap_or(&Lockup::default()), - ), - instruction::update_stake_pool_balance( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.withdraw_authority, - &stake_pool_accounts.validator_list.pubkey(), - &stake_pool_accounts.reserve_stake.pubkey(), - &stake_pool_accounts.pool_fee_account.pubkey(), - &stake_pool_accounts.pool_mint.pubkey(), - &spl_token::id(), - ), - instruction::cleanup_removed_validator_entries( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.validator_list.pubkey(), - ), - ], - Some(&context.payer.pubkey()), - &[&context.payer], - context.last_blockhash, - ); - let error = context - .banks_client - .process_transaction(transaction) - .await - .err(); - assert!(error.is_none()); - - println!("Update again normally, should be no change in the lamports"); - stake_pool_accounts - .update_all( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - stake_accounts - .iter() - .map(|v| v.vote.pubkey()) - .collect::>() - .as_slice(), - false, - ) - .await; - - let expected_lamports = get_validator_list_sum( - &mut context.banks_client, - &stake_pool_accounts.reserve_stake.pubkey(), - &stake_pool_accounts.validator_list.pubkey(), - ) - .await; - assert_eq!(pre_lamports, expected_lamports); - - let stake_pool_info = get_account( - &mut context.banks_client, - &stake_pool_accounts.stake_pool.pubkey(), - ) - .await; - let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data).unwrap(); - assert_eq!(pre_lamports, stake_pool.total_lamports); - - println!("Fail adding validator back in with first seed"); - let error = stake_pool_accounts - .add_validator_to_pool( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_account.stake_account, - &stake_account.vote.pubkey(), - stake_account.validator_stake_seed, - ) - .await - .unwrap() - .unwrap(); - assert_eq!( - error, - TransactionError::InstructionError( - 0, - InstructionError::Custom(StakePoolError::AlreadyInUse as u32), - ) - ); - - println!("Succeed adding validator back in with new seed"); - let seed = NonZeroU32::new(1); - let validator = stake_account.vote.pubkey(); - let (stake_account, _) = find_stake_program_address( - &id(), - &validator, - &stake_pool_accounts.stake_pool.pubkey(), - seed, - ); - let error = stake_pool_accounts - .add_validator_to_pool( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_account, - &validator, - seed, - ) - .await; - assert!(error.is_none()); - - let stake_pool_info = get_account( - &mut context.banks_client, - &stake_pool_accounts.stake_pool.pubkey(), - ) - .await; - let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data).unwrap(); - assert_eq!(pre_lamports, stake_pool.total_lamports); - - let expected_lamports = get_validator_list_sum( - &mut context.banks_client, - &stake_pool_accounts.reserve_stake.pubkey(), - &stake_pool_accounts.validator_list.pubkey(), - ) - .await; - assert_eq!(pre_lamports, expected_lamports); -} - #[tokio::test] async fn fail_with_uninitialized_validator_list() {} // TODO diff --git a/program/tests/update_validator_list_balance_hijack.rs b/program/tests/update_validator_list_balance_hijack.rs new file mode 100644 index 00000000..5ebf72c8 --- /dev/null +++ b/program/tests/update_validator_list_balance_hijack.rs @@ -0,0 +1,521 @@ +#![allow(clippy::integer_arithmetic)] +#![cfg(feature = "test-sbf")] + +mod helpers; + +use { + helpers::*, + solana_program::{borsh::try_from_slice_unchecked, pubkey::Pubkey, stake}, + solana_program_test::*, + solana_sdk::{ + instruction::InstructionError, + signature::Signer, + stake::state::{Authorized, Lockup, StakeState}, + system_instruction, + transaction::{Transaction, TransactionError}, + }, + spl_stake_pool::{ + error::StakePoolError, find_stake_program_address, find_transient_stake_program_address, + find_withdraw_authority_program_address, id, instruction, state::StakePool, + MINIMUM_RESERVE_LAMPORTS, + }, + std::num::NonZeroU32, +}; + +async fn setup( + num_validators: usize, +) -> ( + ProgramTestContext, + StakePoolAccounts, + Vec, + Vec, + u64, + u64, + u64, +) { + let mut context = program_test().start_with_context().await; + let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + let mut slot = first_normal_slot; + context.warp_to_slot(slot).unwrap(); + + let reserve_stake_amount = TEST_STAKE_AMOUNT * 2 * num_validators as u64; + let stake_pool_accounts = StakePoolAccounts::default(); + stake_pool_accounts + .initialize_stake_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + reserve_stake_amount + MINIMUM_RESERVE_LAMPORTS, + ) + .await + .unwrap(); + + // Add several accounts with some stake + let mut stake_accounts: Vec = vec![]; + let mut deposit_accounts: Vec = vec![]; + for i in 0..num_validators { + let stake_account = ValidatorStakeAccount::new( + &stake_pool_accounts.stake_pool.pubkey(), + NonZeroU32::new(i as u32), + u64::MAX, + ); + create_vote( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_account.validator, + &stake_account.vote, + ) + .await; + + let error = stake_pool_accounts + .add_validator_to_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_account.stake_account, + &stake_account.vote.pubkey(), + stake_account.validator_stake_seed, + ) + .await; + assert!(error.is_none()); + + let deposit_account = DepositStakeAccount::new_with_vote( + stake_account.vote.pubkey(), + stake_account.stake_account, + TEST_STAKE_AMOUNT, + ); + deposit_account + .create_and_delegate( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; + + stake_accounts.push(stake_account); + deposit_accounts.push(deposit_account); + } + + // Warp forward so the stakes properly activate, and deposit + slot += slots_per_epoch; + context.warp_to_slot(slot).unwrap(); + + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + stake_accounts + .iter() + .map(|v| v.vote.pubkey()) + .collect::>() + .as_slice(), + false, + ) + .await; + + for deposit_account in &mut deposit_accounts { + deposit_account + .deposit_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + ) + .await; + } + + slot += slots_per_epoch; + context.warp_to_slot(slot).unwrap(); + + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + stake_accounts + .iter() + .map(|v| v.vote.pubkey()) + .collect::>() + .as_slice(), + false, + ) + .await; + + ( + context, + stake_pool_accounts, + stake_accounts, + deposit_accounts, + TEST_STAKE_AMOUNT, + reserve_stake_amount, + slot, + ) +} + +#[tokio::test] +async fn success_ignoring_hijacked_transient_stake_with_authorized() { + let hijacker = Pubkey::new_unique(); + check_ignored_hijacked_transient_stake(Some(&Authorized::auto(&hijacker)), None).await; +} + +#[tokio::test] +async fn success_ignoring_hijacked_transient_stake_with_lockup() { + let hijacker = Pubkey::new_unique(); + check_ignored_hijacked_transient_stake( + None, + Some(&Lockup { + custodian: hijacker, + ..Lockup::default() + }), + ) + .await; +} + +async fn check_ignored_hijacked_transient_stake( + hijack_authorized: Option<&Authorized>, + hijack_lockup: Option<&Lockup>, +) { + let num_validators = 1; + let (mut context, stake_pool_accounts, stake_accounts, _, lamports, _, mut slot) = + setup(num_validators).await; + + let rent = context.banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + + let pre_lamports = get_validator_list_sum( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + let (withdraw_authority, _) = + find_withdraw_authority_program_address(&id(), &stake_pool_accounts.stake_pool.pubkey()); + + println!("Decrease from all validators"); + let stake_account = &stake_accounts[0]; + let error = stake_pool_accounts + .decrease_validator_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_account.stake_account, + &stake_account.transient_stake_account, + lamports, + stake_account.transient_stake_seed, + ) + .await; + assert!(error.is_none()); + + println!("Warp one epoch so the stakes deactivate and merge"); + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + slot += slots_per_epoch; + context.warp_to_slot(slot).unwrap(); + + println!("During update, hijack the transient stake account"); + let validator_list = stake_pool_accounts + .get_validator_list(&mut context.banks_client) + .await; + let transient_stake_address = find_transient_stake_program_address( + &id(), + &stake_account.vote.pubkey(), + &stake_pool_accounts.stake_pool.pubkey(), + stake_account.transient_stake_seed, + ) + .0; + let transaction = Transaction::new_signed_with_payer( + &[ + instruction::update_validator_list_balance( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), + &validator_list, + &[stake_account.vote.pubkey()], + 0, + /* no_merge = */ false, + ), + system_instruction::transfer( + &context.payer.pubkey(), + &transient_stake_address, + stake_rent + MINIMUM_RESERVE_LAMPORTS, + ), + stake::instruction::initialize( + &transient_stake_address, + hijack_authorized.unwrap_or(&Authorized::auto(&withdraw_authority)), + hijack_lockup.unwrap_or(&Lockup::default()), + ), + instruction::update_stake_pool_balance( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.pool_fee_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &spl_token::id(), + ), + instruction::cleanup_removed_validator_entries( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + ), + ], + Some(&context.payer.pubkey()), + &[&context.payer], + context.last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err(); + assert!(error.is_none()); + + println!("Update again normally, should be no change in the lamports"); + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + stake_accounts + .iter() + .map(|v| v.vote.pubkey()) + .collect::>() + .as_slice(), + false, + ) + .await; + + let expected_lamports = get_validator_list_sum( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + assert_eq!(pre_lamports, expected_lamports); + + let stake_pool_info = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data).unwrap(); + assert_eq!(pre_lamports, stake_pool.total_lamports); +} + +#[tokio::test] +async fn success_ignoring_hijacked_validator_stake_with_authorized() { + let hijacker = Pubkey::new_unique(); + check_ignored_hijacked_transient_stake(Some(&Authorized::auto(&hijacker)), None).await; +} + +#[tokio::test] +async fn success_ignoring_hijacked_validator_stake_with_lockup() { + let hijacker = Pubkey::new_unique(); + check_ignored_hijacked_validator_stake( + None, + Some(&Lockup { + custodian: hijacker, + ..Lockup::default() + }), + ) + .await; +} + +async fn check_ignored_hijacked_validator_stake( + hijack_authorized: Option<&Authorized>, + hijack_lockup: Option<&Lockup>, +) { + let num_validators = 1; + let (mut context, stake_pool_accounts, stake_accounts, _, lamports, _, mut slot) = + setup(num_validators).await; + + let rent = context.banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + + let pre_lamports = get_validator_list_sum( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + let (withdraw_authority, _) = + find_withdraw_authority_program_address(&id(), &stake_pool_accounts.stake_pool.pubkey()); + + let stake_account = &stake_accounts[0]; + let error = stake_pool_accounts + .decrease_validator_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_account.stake_account, + &stake_account.transient_stake_account, + lamports, + stake_account.transient_stake_seed, + ) + .await; + assert!(error.is_none()); + + let error = stake_pool_accounts + .remove_validator_from_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_account.stake_account, + &stake_account.transient_stake_account, + ) + .await; + assert!(error.is_none()); + + println!("Warp one epoch so the stakes deactivate and merge"); + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + slot += slots_per_epoch; + context.warp_to_slot(slot).unwrap(); + + println!("During update, hijack the validator stake account"); + let validator_list = stake_pool_accounts + .get_validator_list(&mut context.banks_client) + .await; + let transaction = Transaction::new_signed_with_payer( + &[ + instruction::update_validator_list_balance( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), + &validator_list, + &[stake_account.vote.pubkey()], + 0, + /* no_merge = */ false, + ), + system_instruction::transfer( + &context.payer.pubkey(), + &stake_account.stake_account, + stake_rent + MINIMUM_RESERVE_LAMPORTS, + ), + stake::instruction::initialize( + &stake_account.stake_account, + hijack_authorized.unwrap_or(&Authorized::auto(&withdraw_authority)), + hijack_lockup.unwrap_or(&Lockup::default()), + ), + instruction::update_stake_pool_balance( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.pool_fee_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &spl_token::id(), + ), + instruction::cleanup_removed_validator_entries( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + ), + ], + Some(&context.payer.pubkey()), + &[&context.payer], + context.last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err(); + assert!(error.is_none()); + + println!("Update again normally, should be no change in the lamports"); + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + stake_accounts + .iter() + .map(|v| v.vote.pubkey()) + .collect::>() + .as_slice(), + false, + ) + .await; + + let expected_lamports = get_validator_list_sum( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + assert_eq!(pre_lamports, expected_lamports); + + let stake_pool_info = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data).unwrap(); + assert_eq!(pre_lamports, stake_pool.total_lamports); + + println!("Fail adding validator back in with first seed"); + let error = stake_pool_accounts + .add_validator_to_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_account.stake_account, + &stake_account.vote.pubkey(), + stake_account.validator_stake_seed, + ) + .await + .unwrap() + .unwrap(); + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::AlreadyInUse as u32), + ) + ); + + println!("Succeed adding validator back in with new seed"); + let seed = NonZeroU32::new(1); + let validator = stake_account.vote.pubkey(); + let (stake_account, _) = find_stake_program_address( + &id(), + &validator, + &stake_pool_accounts.stake_pool.pubkey(), + seed, + ); + let error = stake_pool_accounts + .add_validator_to_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_account, + &validator, + seed, + ) + .await; + assert!(error.is_none()); + + let stake_pool_info = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data).unwrap(); + assert_eq!(pre_lamports, stake_pool.total_lamports); + + let expected_lamports = get_validator_list_sum( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + assert_eq!(pre_lamports, expected_lamports); +} diff --git a/program/tests/withdraw_edge_cases.rs b/program/tests/withdraw_edge_cases.rs index c506b973..32a30612 100644 --- a/program/tests/withdraw_edge_cases.rs +++ b/program/tests/withdraw_edge_cases.rs @@ -474,7 +474,7 @@ async fn success_with_reserve() { } #[tokio::test] -async fn success_and_fail_with_preferred_withdraw() { +async fn success_with_empty_preferred_withdraw() { let ( mut context, stake_pool_accounts, @@ -520,17 +520,39 @@ async fn success_and_fail_with_preferred_withdraw() { ) .await; assert!(error.is_none()); +} - // Deposit into preferred, then fail - let user_stake_recipient = Keypair::new(); - create_blank_stake_account( +#[tokio::test] +async fn success_and_fail_with_preferred_withdraw() { + let ( + mut context, + stake_pool_accounts, + validator_stake, + deposit_info, + user_transfer_authority, + user_stake_recipient, + tokens_to_burn, + ) = setup(spl_token::id()).await; + + let preferred_validator = simple_add_validator_to_pool( &mut context.banks_client, &context.payer, &context.last_blockhash, - &user_stake_recipient, + &stake_pool_accounts, + None, ) .await; + stake_pool_accounts + .set_preferred_validator( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + instruction::PreferredValidatorType::Withdraw, + Some(preferred_validator.vote.pubkey()), + ) + .await; + let _preferred_deposit = simple_deposit_stake( &mut context.banks_client, &context.payer, @@ -542,6 +564,7 @@ async fn success_and_fail_with_preferred_withdraw() { .await .unwrap(); + let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts .withdraw_stake( &mut context.banks_client, From 4384810d634938f423e078f9fde00965e8d0f9a8 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 29 Nov 2022 19:15:46 +0100 Subject: [PATCH 0272/1076] stake-pool: Refresh blockhash more often on update tests (#3853) * stake-pool: Refresh blockhash more often on update tests * Bump down max pool size, updated correctly in #3839 * Move withdraw test to another file * Refactor withdraw tests more * Get more blockhashes during `update_stake_pool_balance` --- program/tests/helpers/mod.rs | 89 ++++- program/tests/huge_pool.rs | 2 +- program/tests/update_stake_pool_balance.rs | 57 +++- .../tests/update_validator_list_balance.rs | 123 +++++-- .../update_validator_list_balance_hijack.rs | 69 +++- program/tests/withdraw.rs | 107 +----- program/tests/withdraw_edge_cases.rs | 314 +----------------- program/tests/withdraw_with_fee.rs | 215 ++++++++++++ 8 files changed, 513 insertions(+), 463 deletions(-) create mode 100644 program/tests/withdraw_with_fee.rs diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index d5ee5811..30d3c40f 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -11,7 +11,7 @@ use { pubkey::Pubkey, stake, system_instruction, system_program, }, - solana_program_test::{processor, BanksClient, ProgramTest}, + solana_program_test::{processor, BanksClient, ProgramTest, ProgramTestContext}, solana_sdk::{ account::{Account as SolanaAccount, WritableAccount}, clock::{Clock, Epoch}, @@ -2110,3 +2110,90 @@ pub fn add_token_account( ); program_test.add_account(*account_key, fee_account); } + +pub async fn setup_for_withdraw( + token_program_id: Pubkey, +) -> ( + ProgramTestContext, + StakePoolAccounts, + ValidatorStakeAccount, + DepositStakeAccount, + Keypair, + Keypair, + u64, +) { + let mut context = program_test().start_with_context().await; + let stake_pool_accounts = StakePoolAccounts::new_with_token_program(token_program_id); + stake_pool_accounts + .initialize_stake_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) + .await + .unwrap(); + + let validator_stake_account = simple_add_validator_to_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + None, + ) + .await; + + let current_minimum_delegation = stake_pool_get_minimum_delegation( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; + + let deposit_info = simple_deposit_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + &validator_stake_account, + current_minimum_delegation * 3, + ) + .await + .unwrap(); + + let tokens_to_withdraw = deposit_info.pool_tokens; + + // Delegate tokens for withdrawing + let user_transfer_authority = Keypair::new(); + delegate_tokens( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts.token_program_id, + &deposit_info.pool_account.pubkey(), + &deposit_info.authority, + &user_transfer_authority.pubkey(), + tokens_to_withdraw, + ) + .await; + + // Create stake account to withdraw to + let user_stake_recipient = Keypair::new(); + create_blank_stake_account( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user_stake_recipient, + ) + .await; + + ( + context, + stake_pool_accounts, + validator_stake_account, + deposit_info, + user_transfer_authority, + user_stake_recipient, + tokens_to_withdraw, + ) +} diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index bdee3cc9..66fcbfc8 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -20,7 +20,7 @@ use { }, }; -const HUGE_POOL_SIZE: u32 = 2_300; +const HUGE_POOL_SIZE: u32 = 2_000; const STAKE_AMOUNT: u64 = 200_000_000_000; async fn setup( diff --git a/program/tests/update_stake_pool_balance.rs b/program/tests/update_stake_pool_balance.rs index b678b03c..b0623550 100644 --- a/program/tests/update_stake_pool_balance.rs +++ b/program/tests/update_stake_pool_balance.rs @@ -10,6 +10,7 @@ use { }, solana_program_test::*, solana_sdk::{ + hash::Hash, signature::{Keypair, Signer}, stake, transaction::TransactionError, @@ -24,6 +25,7 @@ async fn setup( num_validators: u64, ) -> ( ProgramTestContext, + Hash, StakePoolAccounts, Vec, ) { @@ -60,6 +62,12 @@ async fn setup( .await; assert!(error.is_none()); + let mut last_blockhash = context + .banks_client + .get_new_latest_blockhash(&context.last_blockhash) + .await + .unwrap(); + // Add several accounts let mut stake_accounts: Vec = vec![]; for i in 0..num_validators { @@ -71,7 +79,7 @@ async fn setup( create_vote( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &stake_account.validator, &stake_account.vote, ) @@ -81,7 +89,7 @@ async fn setup( .add_validator_to_pool( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &stake_account.stake_account, &stake_account.vote.pubkey(), stake_account.validator_stake_seed, @@ -95,31 +103,34 @@ async fn setup( TEST_STAKE_AMOUNT, ); deposit_account - .create_and_delegate( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - ) + .create_and_delegate(&mut context.banks_client, &context.payer, &last_blockhash) .await; deposit_account .deposit_stake( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &stake_pool_accounts, ) .await; + last_blockhash = context + .banks_client + .get_new_latest_blockhash(&last_blockhash) + .await + .unwrap(); + stake_accounts.push(stake_account); } - (context, stake_pool_accounts, stake_accounts) + (context, last_blockhash, stake_pool_accounts, stake_accounts) } #[tokio::test] async fn success() { - let (mut context, stake_pool_accounts, stake_accounts) = setup(NUM_VALIDATORS).await; + let (mut context, last_blockhash, stake_pool_accounts, stake_accounts) = + setup(NUM_VALIDATORS).await; let pre_fee = get_token_balance( &mut context.banks_client, @@ -157,12 +168,18 @@ async fn success() { let slot = context.genesis_config().epoch_schedule.first_normal_slot; context.warp_to_slot(slot).unwrap(); + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&last_blockhash) + .await + .unwrap(); + // Update list and pool let error = stake_pool_accounts .update_all( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, stake_accounts .iter() .map(|v| v.vote.pubkey()) @@ -216,7 +233,8 @@ async fn success() { #[tokio::test] async fn success_absorbing_extra_lamports() { - let (mut context, stake_pool_accounts, stake_accounts) = setup(NUM_VALIDATORS).await; + let (mut context, mut last_blockhash, stake_pool_accounts, stake_accounts) = + setup(NUM_VALIDATORS).await; let pre_balance = get_validator_list_sum( &mut context.banks_client, @@ -244,11 +262,17 @@ async fn success_absorbing_extra_lamports() { transfer( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &stake_account.stake_account, EXTRA_STAKE_AMOUNT, ) .await; + + last_blockhash = context + .banks_client + .get_new_latest_blockhash(&last_blockhash) + .await + .unwrap(); } let extra_lamports = EXTRA_STAKE_AMOUNT * stake_accounts.len() as u64; @@ -257,13 +281,18 @@ async fn success_absorbing_extra_lamports() { // Update epoch let slot = context.genesis_config().epoch_schedule.first_normal_slot; context.warp_to_slot(slot).unwrap(); + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&last_blockhash) + .await + .unwrap(); // Update list and pool let error = stake_pool_accounts .update_all( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, stake_accounts .iter() .map(|v| v.vote.pubkey()) diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index f333eac6..7ace0cf8 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -7,7 +7,7 @@ use { helpers::*, solana_program::{borsh::try_from_slice_unchecked, program_pack::Pack, pubkey::Pubkey}, solana_program_test::*, - solana_sdk::{signature::Signer, stake::state::StakeState}, + solana_sdk::{hash::Hash, signature::Signer, stake::state::StakeState}, spl_stake_pool::{ state::{StakePool, StakeStatus, ValidatorList}, MAX_VALIDATORS_TO_UPDATE, MINIMUM_RESERVE_LAMPORTS, @@ -20,6 +20,7 @@ async fn setup( num_validators: usize, ) -> ( ProgramTestContext, + Hash, StakePoolAccounts, Vec, Vec, @@ -110,12 +111,18 @@ async fn setup( ) .await; + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&context.last_blockhash) + .await + .unwrap(); + for deposit_account in &mut deposit_accounts { deposit_account .deposit_stake( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &stake_pool_accounts, ) .await; @@ -128,7 +135,7 @@ async fn setup( .update_all( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, stake_accounts .iter() .map(|v| v.vote.pubkey()) @@ -138,8 +145,15 @@ async fn setup( ) .await; + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&context.last_blockhash) + .await + .unwrap(); + ( context, + last_blockhash, stake_pool_accounts, stake_accounts, deposit_accounts, @@ -154,6 +168,7 @@ async fn success_with_normal() { let num_validators = 5; let ( mut context, + last_blockhash, stake_pool_accounts, stake_accounts, _, @@ -193,11 +208,17 @@ async fn success_with_normal() { slot += slots_per_epoch; context.warp_to_slot(slot).unwrap(); + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&last_blockhash) + .await + .unwrap(); + stake_pool_accounts .update_all( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, stake_accounts .iter() .map(|v| v.vote.pubkey()) @@ -225,8 +246,16 @@ async fn success_with_normal() { #[tokio::test] async fn merge_into_reserve() { - let (mut context, stake_pool_accounts, stake_accounts, _, lamports, _, mut slot) = - setup(MAX_VALIDATORS_TO_UPDATE).await; + let ( + mut context, + last_blockhash, + stake_pool_accounts, + stake_accounts, + _, + lamports, + _, + mut slot, + ) = setup(MAX_VALIDATORS_TO_UPDATE).await; let pre_lamports = get_validator_list_sum( &mut context.banks_client, @@ -249,7 +278,7 @@ async fn merge_into_reserve() { .decrease_validator_stake( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &stake_account.stake_account, &stake_account.transient_stake_account, lamports, @@ -264,7 +293,7 @@ async fn merge_into_reserve() { .update_all( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, stake_accounts .iter() .map(|v| v.vote.pubkey()) @@ -295,11 +324,16 @@ async fn merge_into_reserve() { slot += slots_per_epoch; context.warp_to_slot(slot).unwrap(); + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&last_blockhash) + .await + .unwrap(); stake_pool_accounts .update_all( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, stake_accounts .iter() .map(|v| v.vote.pubkey()) @@ -336,8 +370,16 @@ async fn merge_into_reserve() { #[tokio::test] async fn merge_into_validator_stake() { - let (mut context, stake_pool_accounts, stake_accounts, _, lamports, reserve_lamports, mut slot) = - setup(MAX_VALIDATORS_TO_UPDATE).await; + let ( + mut context, + last_blockhash, + stake_pool_accounts, + stake_accounts, + _, + lamports, + reserve_lamports, + mut slot, + ) = setup(MAX_VALIDATORS_TO_UPDATE).await; let rent = context.banks_client.get_rent().await.unwrap(); let pre_lamports = get_validator_list_sum( @@ -352,7 +394,7 @@ async fn merge_into_validator_stake() { let current_minimum_delegation = stake_pool_get_minimum_delegation( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, ) .await; let available_lamports = @@ -363,7 +405,7 @@ async fn merge_into_validator_stake() { .increase_validator_stake( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &stake_account.transient_stake_account, &stake_account.stake_account, &stake_account.vote.pubkey(), @@ -382,7 +424,7 @@ async fn merge_into_validator_stake() { .update_all( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, stake_accounts .iter() .map(|v| v.vote.pubkey()) @@ -413,11 +455,16 @@ async fn merge_into_validator_stake() { slot += slots_per_epoch; context.warp_to_slot(slot).unwrap(); + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&last_blockhash) + .await + .unwrap(); let error = stake_pool_accounts .update_all( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, stake_accounts .iter() .map(|v| v.vote.pubkey()) @@ -475,15 +522,23 @@ async fn merge_into_validator_stake() { #[tokio::test] async fn merge_transient_stake_after_remove() { - let (mut context, stake_pool_accounts, stake_accounts, _, lamports, reserve_lamports, mut slot) = - setup(1).await; + let ( + mut context, + last_blockhash, + stake_pool_accounts, + stake_accounts, + _, + lamports, + reserve_lamports, + mut slot, + ) = setup(1).await; let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); let current_minimum_delegation = stake_pool_get_minimum_delegation( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, ) .await; let deactivated_lamports = lamports; @@ -493,7 +548,7 @@ async fn merge_transient_stake_after_remove() { .decrease_validator_stake( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &stake_account.stake_account, &stake_account.transient_stake_account, deactivated_lamports, @@ -505,7 +560,7 @@ async fn merge_transient_stake_after_remove() { .remove_validator_from_pool( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &stake_account.stake_account, &stake_account.transient_stake_account, ) @@ -523,7 +578,7 @@ async fn merge_transient_stake_after_remove() { .update_all( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, stake_accounts .iter() .map(|v| v.vote.pubkey()) @@ -560,7 +615,7 @@ async fn merge_transient_stake_after_remove() { .update_validator_list_balance( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, stake_accounts .iter() .map(|v| v.vote.pubkey()) @@ -613,11 +668,7 @@ async fn merge_transient_stake_after_remove() { // Update stake pool balance and cleanup, should be gone let error = stake_pool_accounts - .update_stake_pool_balance( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - ) + .update_stake_pool_balance(&mut context.banks_client, &context.payer, &last_blockhash) .await; assert!(error.is_none()); @@ -625,7 +676,7 @@ async fn merge_transient_stake_after_remove() { .cleanup_removed_validator_entries( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, ) .await; assert!(error.is_none()); @@ -643,8 +694,16 @@ async fn merge_transient_stake_after_remove() { #[tokio::test] async fn success_with_burned_tokens() { let num_validators = 5; - let (mut context, stake_pool_accounts, stake_accounts, deposit_accounts, _, _, mut slot) = - setup(num_validators).await; + let ( + mut context, + last_blockhash, + stake_pool_accounts, + stake_accounts, + deposit_accounts, + _, + _, + mut slot, + ) = setup(num_validators).await; let mint_info = get_account( &mut context.banks_client, @@ -664,7 +723,7 @@ async fn success_with_burned_tokens() { burn_tokens( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &stake_pool_accounts.token_program_id, &stake_pool_accounts.pool_mint.pubkey(), &deposit_accounts[0].pool_account.pubkey(), @@ -690,7 +749,7 @@ async fn success_with_burned_tokens() { .update_all( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, stake_accounts .iter() .map(|v| v.vote.pubkey()) diff --git a/program/tests/update_validator_list_balance_hijack.rs b/program/tests/update_validator_list_balance_hijack.rs index 5ebf72c8..71e8f13c 100644 --- a/program/tests/update_validator_list_balance_hijack.rs +++ b/program/tests/update_validator_list_balance_hijack.rs @@ -8,6 +8,7 @@ use { solana_program::{borsh::try_from_slice_unchecked, pubkey::Pubkey, stake}, solana_program_test::*, solana_sdk::{ + hash::Hash, instruction::InstructionError, signature::Signer, stake::state::{Authorized, Lockup, StakeState}, @@ -26,6 +27,7 @@ async fn setup( num_validators: usize, ) -> ( ProgramTestContext, + Hash, StakePoolAccounts, Vec, Vec, @@ -130,11 +132,17 @@ async fn setup( slot += slots_per_epoch; context.warp_to_slot(slot).unwrap(); + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&context.last_blockhash) + .await + .unwrap(); + stake_pool_accounts .update_all( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, stake_accounts .iter() .map(|v| v.vote.pubkey()) @@ -144,8 +152,15 @@ async fn setup( ) .await; + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&last_blockhash) + .await + .unwrap(); + ( context, + last_blockhash, stake_pool_accounts, stake_accounts, deposit_accounts, @@ -179,8 +194,16 @@ async fn check_ignored_hijacked_transient_stake( hijack_lockup: Option<&Lockup>, ) { let num_validators = 1; - let (mut context, stake_pool_accounts, stake_accounts, _, lamports, _, mut slot) = - setup(num_validators).await; + let ( + mut context, + last_blockhash, + stake_pool_accounts, + stake_accounts, + _, + lamports, + _, + mut slot, + ) = setup(num_validators).await; let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); @@ -200,7 +223,7 @@ async fn check_ignored_hijacked_transient_stake( .decrease_validator_stake( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &stake_account.stake_account, &stake_account.transient_stake_account, lamports, @@ -266,7 +289,7 @@ async fn check_ignored_hijacked_transient_stake( ], Some(&context.payer.pubkey()), &[&context.payer], - context.last_blockhash, + last_blockhash, ); let error = context .banks_client @@ -276,11 +299,16 @@ async fn check_ignored_hijacked_transient_stake( assert!(error.is_none()); println!("Update again normally, should be no change in the lamports"); + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&last_blockhash) + .await + .unwrap(); stake_pool_accounts .update_all( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, stake_accounts .iter() .map(|v| v.vote.pubkey()) @@ -331,8 +359,16 @@ async fn check_ignored_hijacked_validator_stake( hijack_lockup: Option<&Lockup>, ) { let num_validators = 1; - let (mut context, stake_pool_accounts, stake_accounts, _, lamports, _, mut slot) = - setup(num_validators).await; + let ( + mut context, + last_blockhash, + stake_pool_accounts, + stake_accounts, + _, + lamports, + _, + mut slot, + ) = setup(num_validators).await; let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); @@ -351,7 +387,7 @@ async fn check_ignored_hijacked_validator_stake( .decrease_validator_stake( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &stake_account.stake_account, &stake_account.transient_stake_account, lamports, @@ -364,7 +400,7 @@ async fn check_ignored_hijacked_validator_stake( .remove_validator_from_pool( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &stake_account.stake_account, &stake_account.transient_stake_account, ) @@ -421,7 +457,7 @@ async fn check_ignored_hijacked_validator_stake( ], Some(&context.payer.pubkey()), &[&context.payer], - context.last_blockhash, + last_blockhash, ); let error = context .banks_client @@ -431,11 +467,16 @@ async fn check_ignored_hijacked_validator_stake( assert!(error.is_none()); println!("Update again normally, should be no change in the lamports"); + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&last_blockhash) + .await + .unwrap(); stake_pool_accounts .update_all( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, stake_accounts .iter() .map(|v| v.vote.pubkey()) @@ -466,7 +507,7 @@ async fn check_ignored_hijacked_validator_stake( .add_validator_to_pool( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &stake_account.stake_account, &stake_account.vote.pubkey(), stake_account.validator_stake_seed, @@ -495,7 +536,7 @@ async fn check_ignored_hijacked_validator_stake( .add_validator_to_pool( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &stake_account, &validator, seed, diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index ec6217b0..46102400 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -18,98 +18,11 @@ use { transaction::{Transaction, TransactionError}, transport::TransportError, }, - spl_stake_pool::{error::StakePoolError, id, instruction, state, MINIMUM_RESERVE_LAMPORTS}, + spl_stake_pool::{error::StakePoolError, id, instruction, state}, spl_token::error::TokenError, test_case::test_case, }; -async fn setup( - token_program_id: Pubkey, -) -> ( - ProgramTestContext, - StakePoolAccounts, - ValidatorStakeAccount, - DepositStakeAccount, - Keypair, - Keypair, - u64, -) { - let mut context = program_test().start_with_context().await; - let stake_pool_accounts = StakePoolAccounts::new_with_token_program(token_program_id); - stake_pool_accounts - .initialize_stake_pool( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - MINIMUM_RESERVE_LAMPORTS, - ) - .await - .unwrap(); - - let validator_stake_account = simple_add_validator_to_pool( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts, - None, - ) - .await; - - let current_minimum_delegation = stake_pool_get_minimum_delegation( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - ) - .await; - - let deposit_info = simple_deposit_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts, - &validator_stake_account, - current_minimum_delegation * 3, - ) - .await - .unwrap(); - - let tokens_to_withdraw = deposit_info.pool_tokens; - - // Delegate tokens for withdrawing - let user_transfer_authority = Keypair::new(); - delegate_tokens( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts.token_program_id, - &deposit_info.pool_account.pubkey(), - &deposit_info.authority, - &user_transfer_authority.pubkey(), - tokens_to_withdraw, - ) - .await; - - // Create stake account to withdraw to - let user_stake_recipient = Keypair::new(); - create_blank_stake_account( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &user_stake_recipient, - ) - .await; - - ( - context, - stake_pool_accounts, - validator_stake_account, - deposit_info, - user_transfer_authority, - user_stake_recipient, - tokens_to_withdraw, - ) -} - #[test_case(spl_token::id(); "token")] #[test_case(spl_token_2022::id(); "token-2022")] #[tokio::test] @@ -136,7 +49,7 @@ async fn _success(token_program_id: Pubkey, test_type: SuccessTestType) { user_transfer_authority, user_stake_recipient, tokens_to_withdraw, - ) = setup(token_program_id).await; + ) = setup_for_withdraw(token_program_id).await; // Save stake pool state before withdrawal let stake_pool_before = get_account( @@ -355,7 +268,7 @@ async fn fail_with_wrong_stake_program() { user_transfer_authority, user_stake_recipient, tokens_to_burn, - ) = setup(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id()).await; let new_authority = Pubkey::new_unique(); let wrong_stake_program = Pubkey::new_unique(); @@ -416,7 +329,7 @@ async fn fail_with_wrong_withdraw_authority() { user_transfer_authority, user_stake_recipient, tokens_to_burn, - ) = setup(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id()).await; let new_authority = Pubkey::new_unique(); stake_pool_accounts.withdraw_authority = Keypair::new().pubkey(); @@ -458,7 +371,7 @@ async fn fail_with_wrong_token_program_id() { user_transfer_authority, user_stake_recipient, tokens_to_burn, - ) = setup(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id()).await; let new_authority = Pubkey::new_unique(); let wrong_token_program = Keypair::new(); @@ -510,7 +423,7 @@ async fn fail_with_wrong_validator_list() { user_transfer_authority, user_stake_recipient, tokens_to_burn, - ) = setup(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id()).await; let new_authority = Pubkey::new_unique(); stake_pool_accounts.validator_list = Keypair::new(); @@ -554,7 +467,7 @@ async fn fail_with_unknown_validator() { user_transfer_authority, user_stake_recipient, tokens_to_withdraw, - ) = setup(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id()).await; let unknown_stake = create_unknown_validator_stake( &mut context.banks_client, @@ -600,7 +513,7 @@ async fn fail_double_withdraw_to_the_same_account() { user_transfer_authority, user_stake_recipient, tokens_to_burn, - ) = setup(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id()).await; let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts @@ -666,7 +579,7 @@ async fn fail_without_token_approval() { user_transfer_authority, user_stake_recipient, tokens_to_burn, - ) = setup(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id()).await; revoke_tokens( &mut context.banks_client, @@ -718,7 +631,7 @@ async fn fail_with_not_enough_tokens() { user_transfer_authority, user_stake_recipient, tokens_to_burn, - ) = setup(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id()).await; // Empty validator stake account let empty_stake_account = simple_add_validator_to_pool( diff --git a/program/tests/withdraw_edge_cases.rs b/program/tests/withdraw_edge_cases.rs index 32a30612..b97d9300 100644 --- a/program/tests/withdraw_edge_cases.rs +++ b/program/tests/withdraw_edge_cases.rs @@ -10,102 +10,10 @@ use { borsh::try_from_slice_unchecked, instruction::InstructionError, pubkey::Pubkey, stake, }, solana_program_test::*, - solana_sdk::{ - signature::{Keypair, Signer}, - transaction::TransactionError, - }, - spl_stake_pool::{ - error::StakePoolError, instruction, minimum_stake_lamports, state, MINIMUM_RESERVE_LAMPORTS, - }, + solana_sdk::{signature::Signer, transaction::TransactionError}, + spl_stake_pool::{error::StakePoolError, instruction, state, MINIMUM_RESERVE_LAMPORTS}, }; -async fn setup( - token_program_id: Pubkey, -) -> ( - ProgramTestContext, - StakePoolAccounts, - ValidatorStakeAccount, - DepositStakeAccount, - Keypair, - Keypair, - u64, -) { - let mut context = program_test().start_with_context().await; - let stake_pool_accounts = StakePoolAccounts::new_with_token_program(token_program_id); - stake_pool_accounts - .initialize_stake_pool( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - MINIMUM_RESERVE_LAMPORTS, - ) - .await - .unwrap(); - - let validator_stake_account = simple_add_validator_to_pool( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts, - None, - ) - .await; - - let current_minimum_delegation = stake_pool_get_minimum_delegation( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - ) - .await; - - let deposit_info = simple_deposit_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts, - &validator_stake_account, - current_minimum_delegation * 3, - ) - .await - .unwrap(); - - let tokens_to_withdraw = deposit_info.pool_tokens; - - // Delegate tokens for withdrawing - let user_transfer_authority = Keypair::new(); - delegate_tokens( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts.token_program_id, - &deposit_info.pool_account.pubkey(), - &deposit_info.authority, - &user_transfer_authority.pubkey(), - tokens_to_withdraw, - ) - .await; - - // Create stake account to withdraw to - let user_stake_recipient = Keypair::new(); - create_blank_stake_account( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &user_stake_recipient, - ) - .await; - - ( - context, - stake_pool_accounts, - validator_stake_account, - deposit_info, - user_transfer_authority, - user_stake_recipient, - tokens_to_withdraw, - ) -} - #[tokio::test] async fn fail_remove_validator() { let ( @@ -116,7 +24,7 @@ async fn fail_remove_validator() { user_transfer_authority, user_stake_recipient, _, - ) = setup(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id()).await; // decrease a little stake, not all let error = stake_pool_accounts @@ -189,7 +97,7 @@ async fn success_remove_validator() { user_transfer_authority, user_stake_recipient, _, - ) = setup(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id()).await; let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); @@ -292,7 +200,7 @@ async fn fail_with_reserve() { user_transfer_authority, user_stake_recipient, tokens_to_burn, - ) = setup(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id()).await; // decrease a little stake, not all let error = stake_pool_accounts @@ -362,7 +270,7 @@ async fn success_with_reserve() { user_transfer_authority, user_stake_recipient, _, - ) = setup(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id()).await; let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); @@ -483,7 +391,7 @@ async fn success_with_empty_preferred_withdraw() { user_transfer_authority, user_stake_recipient, tokens_to_burn, - ) = setup(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id()).await; let preferred_validator = simple_add_validator_to_pool( &mut context.banks_client, @@ -532,7 +440,7 @@ async fn success_and_fail_with_preferred_withdraw() { user_transfer_authority, user_stake_recipient, tokens_to_burn, - ) = setup(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id()).await; let preferred_validator = simple_add_validator_to_pool( &mut context.banks_client, @@ -615,7 +523,7 @@ async fn fail_withdraw_from_transient() { user_transfer_authority, user_stake_recipient, tokens_to_withdraw, - ) = setup(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id()).await; // add a preferred withdraw validator, keep it empty, to be sure that this works let preferred_validator = simple_add_validator_to_pool( @@ -690,7 +598,7 @@ async fn success_withdraw_from_transient() { user_transfer_authority, user_stake_recipient, tokens_to_withdraw, - ) = setup(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id()).await; // add a preferred withdraw validator, keep it empty, to be sure that this works let preferred_validator = simple_add_validator_to_pool( @@ -747,205 +655,3 @@ async fn success_withdraw_from_transient() { .await; assert!(error.is_none()); } - -#[tokio::test] -async fn success_withdraw_all_fee_tokens() { - let ( - mut context, - stake_pool_accounts, - validator_stake_account, - deposit_info, - user_transfer_authority, - user_stake_recipient, - tokens_to_withdraw, - ) = setup(spl_token::id()).await; - - // move tokens to fee account - transfer_spl_tokens( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts.token_program_id, - &deposit_info.pool_account.pubkey(), - &stake_pool_accounts.pool_mint.pubkey(), - &stake_pool_accounts.pool_fee_account.pubkey(), - &user_transfer_authority, - tokens_to_withdraw / 2, - stake_pool_accounts.pool_decimals, - ) - .await; - - let fee_tokens = get_token_balance( - &mut context.banks_client, - &stake_pool_accounts.pool_fee_account.pubkey(), - ) - .await; - - let user_transfer_authority = Keypair::new(); - delegate_tokens( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts.token_program_id, - &stake_pool_accounts.pool_fee_account.pubkey(), - &stake_pool_accounts.manager, - &user_transfer_authority.pubkey(), - fee_tokens, - ) - .await; - - let new_authority = Pubkey::new_unique(); - let error = stake_pool_accounts - .withdraw_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &user_stake_recipient.pubkey(), - &user_transfer_authority, - &stake_pool_accounts.pool_fee_account.pubkey(), - &validator_stake_account.stake_account, - &new_authority, - fee_tokens, - ) - .await; - assert!(error.is_none()); - - // Check balance is 0 - let fee_tokens = get_token_balance( - &mut context.banks_client, - &stake_pool_accounts.pool_fee_account.pubkey(), - ) - .await; - assert_eq!(fee_tokens, 0); -} - -#[tokio::test] -async fn success_empty_out_stake_with_fee() { - let ( - mut context, - stake_pool_accounts, - _, - deposit_info, - user_transfer_authority, - user_stake_recipient, - tokens_to_withdraw, - ) = setup(spl_token::id()).await; - - // add another validator and deposit into it - let other_validator_stake_account = simple_add_validator_to_pool( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts, - None, - ) - .await; - - let other_deposit_info = simple_deposit_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts, - &other_validator_stake_account, - TEST_STAKE_AMOUNT, - ) - .await - .unwrap(); - - // move tokens to new account - transfer_spl_tokens( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts.token_program_id, - &deposit_info.pool_account.pubkey(), - &stake_pool_accounts.pool_mint.pubkey(), - &other_deposit_info.pool_account.pubkey(), - &user_transfer_authority, - tokens_to_withdraw, - stake_pool_accounts.pool_decimals, - ) - .await; - - let user_tokens = get_token_balance( - &mut context.banks_client, - &other_deposit_info.pool_account.pubkey(), - ) - .await; - - let user_transfer_authority = Keypair::new(); - delegate_tokens( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts.token_program_id, - &other_deposit_info.pool_account.pubkey(), - &other_deposit_info.authority, - &user_transfer_authority.pubkey(), - user_tokens, - ) - .await; - - // calculate exactly how much to withdraw, given the fee, to get the account - // down to 0, using an inverse fee calculation - let validator_stake_account = get_account( - &mut context.banks_client, - &other_validator_stake_account.stake_account, - ) - .await; - let stake_state = - deserialize::(&validator_stake_account.data).unwrap(); - let meta = stake_state.meta().unwrap(); - let stake_minimum_delegation = stake_get_minimum_delegation( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - ) - .await; - let lamports_to_withdraw = - validator_stake_account.lamports - minimum_stake_lamports(&meta, stake_minimum_delegation); - let stake_pool_account = get_account( - &mut context.banks_client, - &stake_pool_accounts.stake_pool.pubkey(), - ) - .await; - let stake_pool = - try_from_slice_unchecked::(stake_pool_account.data.as_slice()).unwrap(); - let fee = stake_pool.stake_withdrawal_fee; - let inverse_fee = state::Fee { - numerator: fee.denominator - fee.numerator, - denominator: fee.denominator, - }; - let pool_tokens_to_withdraw = - lamports_to_withdraw * inverse_fee.denominator / inverse_fee.numerator; - - let new_authority = Pubkey::new_unique(); - let error = stake_pool_accounts - .withdraw_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &user_stake_recipient.pubkey(), - &user_transfer_authority, - &other_deposit_info.pool_account.pubkey(), - &other_validator_stake_account.stake_account, - &new_authority, - pool_tokens_to_withdraw, - ) - .await; - assert!(error.is_none()); - - // Check balance of validator stake account is MINIMUM + rent-exemption - let validator_stake_account = get_account( - &mut context.banks_client, - &other_validator_stake_account.stake_account, - ) - .await; - let stake_state = - deserialize::(&validator_stake_account.data).unwrap(); - let meta = stake_state.meta().unwrap(); - assert_eq!( - validator_stake_account.lamports, - minimum_stake_lamports(&meta, stake_minimum_delegation) - ); -} diff --git a/program/tests/withdraw_with_fee.rs b/program/tests/withdraw_with_fee.rs new file mode 100644 index 00000000..866367b4 --- /dev/null +++ b/program/tests/withdraw_with_fee.rs @@ -0,0 +1,215 @@ +#![allow(clippy::integer_arithmetic)] +#![cfg(feature = "test-sbf")] + +mod helpers; + +use { + bincode::deserialize, + helpers::*, + solana_program::{borsh::try_from_slice_unchecked, pubkey::Pubkey, stake}, + solana_program_test::*, + solana_sdk::signature::{Keypair, Signer}, + spl_stake_pool::{minimum_stake_lamports, state}, +}; + +#[tokio::test] +async fn success_withdraw_all_fee_tokens() { + let ( + mut context, + stake_pool_accounts, + validator_stake_account, + deposit_info, + user_transfer_authority, + user_stake_recipient, + tokens_to_withdraw, + ) = setup_for_withdraw(spl_token::id()).await; + + // move tokens to fee account + transfer_spl_tokens( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts.token_program_id, + &deposit_info.pool_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &stake_pool_accounts.pool_fee_account.pubkey(), + &user_transfer_authority, + tokens_to_withdraw / 2, + stake_pool_accounts.pool_decimals, + ) + .await; + + let fee_tokens = get_token_balance( + &mut context.banks_client, + &stake_pool_accounts.pool_fee_account.pubkey(), + ) + .await; + + let user_transfer_authority = Keypair::new(); + delegate_tokens( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts.token_program_id, + &stake_pool_accounts.pool_fee_account.pubkey(), + &stake_pool_accounts.manager, + &user_transfer_authority.pubkey(), + fee_tokens, + ) + .await; + + let new_authority = Pubkey::new_unique(); + let error = stake_pool_accounts + .withdraw_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user_stake_recipient.pubkey(), + &user_transfer_authority, + &stake_pool_accounts.pool_fee_account.pubkey(), + &validator_stake_account.stake_account, + &new_authority, + fee_tokens, + ) + .await; + assert!(error.is_none()); + + // Check balance is 0 + let fee_tokens = get_token_balance( + &mut context.banks_client, + &stake_pool_accounts.pool_fee_account.pubkey(), + ) + .await; + assert_eq!(fee_tokens, 0); +} + +#[tokio::test] +async fn success_empty_out_stake_with_fee() { + let ( + mut context, + stake_pool_accounts, + _, + deposit_info, + user_transfer_authority, + user_stake_recipient, + tokens_to_withdraw, + ) = setup_for_withdraw(spl_token::id()).await; + + // add another validator and deposit into it + let other_validator_stake_account = simple_add_validator_to_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + None, + ) + .await; + + let other_deposit_info = simple_deposit_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + &other_validator_stake_account, + TEST_STAKE_AMOUNT, + ) + .await + .unwrap(); + + // move tokens to new account + transfer_spl_tokens( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts.token_program_id, + &deposit_info.pool_account.pubkey(), + &stake_pool_accounts.pool_mint.pubkey(), + &other_deposit_info.pool_account.pubkey(), + &user_transfer_authority, + tokens_to_withdraw, + stake_pool_accounts.pool_decimals, + ) + .await; + + let user_tokens = get_token_balance( + &mut context.banks_client, + &other_deposit_info.pool_account.pubkey(), + ) + .await; + + let user_transfer_authority = Keypair::new(); + delegate_tokens( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts.token_program_id, + &other_deposit_info.pool_account.pubkey(), + &other_deposit_info.authority, + &user_transfer_authority.pubkey(), + user_tokens, + ) + .await; + + // calculate exactly how much to withdraw, given the fee, to get the account + // down to 0, using an inverse fee calculation + let validator_stake_account = get_account( + &mut context.banks_client, + &other_validator_stake_account.stake_account, + ) + .await; + let stake_state = + deserialize::(&validator_stake_account.data).unwrap(); + let meta = stake_state.meta().unwrap(); + let stake_minimum_delegation = stake_get_minimum_delegation( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; + let lamports_to_withdraw = + validator_stake_account.lamports - minimum_stake_lamports(&meta, stake_minimum_delegation); + let stake_pool_account = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = + try_from_slice_unchecked::(stake_pool_account.data.as_slice()).unwrap(); + let fee = stake_pool.stake_withdrawal_fee; + let inverse_fee = state::Fee { + numerator: fee.denominator - fee.numerator, + denominator: fee.denominator, + }; + let pool_tokens_to_withdraw = + lamports_to_withdraw * inverse_fee.denominator / inverse_fee.numerator; + + let new_authority = Pubkey::new_unique(); + let error = stake_pool_accounts + .withdraw_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user_stake_recipient.pubkey(), + &user_transfer_authority, + &other_deposit_info.pool_account.pubkey(), + &other_validator_stake_account.stake_account, + &new_authority, + pool_tokens_to_withdraw, + ) + .await; + assert!(error.is_none()); + + // Check balance of validator stake account is MINIMUM + rent-exemption + let validator_stake_account = get_account( + &mut context.banks_client, + &other_validator_stake_account.stake_account, + ) + .await; + let stake_state = + deserialize::(&validator_stake_account.data).unwrap(); + let meta = stake_state.meta().unwrap(); + assert_eq!( + validator_stake_account.lamports, + minimum_stake_lamports(&meta, stake_minimum_delegation) + ); +} From 35fc1804d45e65f33e4fa56edf8f976a93368fe3 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 29 Nov 2022 20:54:46 +0100 Subject: [PATCH 0273/1076] stake-pool: Make transaction signatures unique in withdraw test (#3854) --- program/tests/withdraw.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 46102400..d66c5f95 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -678,6 +678,8 @@ async fn fail_with_not_enough_tokens() { ) .await; + // generate a new authority each time to make each transaction unique + let new_authority = Pubkey::new_unique(); let transaction_error = stake_pool_accounts .withdraw_stake( &mut context.banks_client, @@ -715,6 +717,7 @@ async fn fail_with_not_enough_tokens() { ) .await; + // generate a new authority each time to make each transaction unique let new_authority = Pubkey::new_unique(); let transaction_error = stake_pool_accounts .withdraw_stake( From 54b42c8b0acdd18d44a5e601ff704d6c24fc8ae9 Mon Sep 17 00:00:00 2001 From: Tyera Date: Tue, 29 Nov 2022 13:48:49 -0700 Subject: [PATCH 0274/1076] Bump ATA to v1.1.2 (#3855) --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 3e3e02f0..1f5a3a9c 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -23,7 +23,7 @@ solana-logger = "=1.14.6" solana-program = "=1.14.6" solana-remote-wallet = "=1.14.6" solana-sdk = "=1.14.6" -spl-associated-token-account = { version = "=1.1.1", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } +spl-associated-token-account = { version = "=1.1.2", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "=0.7.0", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "=3.5.0", path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" From bdaec42319b8334ba9b2db0612706992937cd138 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Mon, 5 Dec 2022 12:23:36 +0100 Subject: [PATCH 0275/1076] stake-pool: Add tolerance for stake accounts at minimum (#3839) * stake-pool: Add tolerance for stake accounts at minimum * Use test-case to check more cases * Add more tolerance on withdrawal * Potentially fix test per #3854 * Keep throwing solutions until CI passes * Fix repeated transaction issue * Fix preferred withdrawal tolerance too * Remove doubled tolerance --- program/src/big_vec.rs | 39 ++-- program/src/processor.rs | 102 +++++---- program/src/state.rs | 29 ++- program/tests/huge_pool.rs | 2 +- .../tests/update_validator_list_balance.rs | 21 +- program/tests/withdraw_edge_cases.rs | 205 +++++++++++++++++- 6 files changed, 301 insertions(+), 97 deletions(-) diff --git a/program/src/big_vec.rs b/program/src/big_vec.rs index b98a29ec..6d02142c 100644 --- a/program/src/big_vec.rs +++ b/program/src/big_vec.rs @@ -148,14 +148,14 @@ impl<'data> BigVec<'data> { } /// Find matching data in the array - pub fn find(&self, data: &[u8], predicate: fn(&[u8], &[u8]) -> bool) -> Option<&T> { + pub fn find bool>(&self, predicate: F) -> Option<&T> { let len = self.len() as usize; let mut current = 0; let mut current_index = VEC_SIZE_BYTES; while current != len { let end_index = current_index + T::LEN; let current_slice = &self.data[current_index..end_index]; - if predicate(current_slice, data) { + if predicate(current_slice) { return Some(unsafe { &*(current_slice.as_ptr() as *const T) }); } current_index = end_index; @@ -165,18 +165,14 @@ impl<'data> BigVec<'data> { } /// Find matching data in the array - pub fn find_mut( - &mut self, - data: &[u8], - predicate: fn(&[u8], &[u8]) -> bool, - ) -> Option<&mut T> { + pub fn find_mut bool>(&mut self, predicate: F) -> Option<&mut T> { let len = self.len() as usize; let mut current = 0; let mut current_index = VEC_SIZE_BYTES; while current != len { let end_index = current_index + T::LEN; let current_slice = &self.data[current_index..end_index]; - if predicate(current_slice, data) { + if predicate(current_slice) { return Some(unsafe { &mut *(current_slice.as_ptr() as *mut T) }); } current_index = end_index; @@ -242,10 +238,7 @@ impl<'data, 'vec, T: Pack + 'data> Iterator for IterMut<'data, 'vec, T> { #[cfg(test)] mod tests { - use { - super::*, - solana_program::{program_memory::sol_memcmp, program_pack::Sealed}, - }; + use {super::*, solana_program::program_pack::Sealed}; #[derive(Debug, PartialEq)] struct TestStruct { @@ -317,11 +310,11 @@ mod tests { check_big_vec_eq(&v, &[2, 4]); } - fn find_predicate(a: &[u8], b: &[u8]) -> bool { - if a.len() != b.len() { + fn find_predicate(a: &[u8], b: u64) -> bool { + if a.len() != 8 { false } else { - sol_memcmp(a, b, a.len()) == 0 + u64::try_from_slice(&a[0..8]).unwrap() == b } } @@ -330,17 +323,14 @@ mod tests { let mut data = [0u8; 4 + 8 * 4]; let v = from_slice(&mut data, &[1, 2, 3, 4]); assert_eq!( - v.find::(&1u64.to_le_bytes(), find_predicate), + v.find::(|x| find_predicate(x, 1)), Some(&TestStruct::new(1)) ); assert_eq!( - v.find::(&4u64.to_le_bytes(), find_predicate), + v.find::(|x| find_predicate(x, 4)), Some(&TestStruct::new(4)) ); - assert_eq!( - v.find::(&5u64.to_le_bytes(), find_predicate), - None - ); + assert_eq!(v.find::(|x| find_predicate(x, 5)), None); } #[test] @@ -348,14 +338,11 @@ mod tests { let mut data = [0u8; 4 + 8 * 4]; let mut v = from_slice(&mut data, &[1, 2, 3, 4]); let mut test_struct = v - .find_mut::(&1u64.to_le_bytes(), find_predicate) + .find_mut::(|x| find_predicate(x, 1)) .unwrap(); test_struct.value = 0; check_big_vec_eq(&v, &[0, 2, 3, 4]); - assert_eq!( - v.find_mut::(&5u64.to_le_bytes(), find_predicate), - None - ); + assert_eq!(v.find_mut::(|x| find_predicate(x, 5)), None); } #[test] diff --git a/program/src/processor.rs b/program/src/processor.rs index 1d0025ca..f0a6f102 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -844,10 +844,9 @@ impl Processor { if header.max_validators == validator_list.len() { return Err(ProgramError::AccountDataTooSmall); } - let maybe_validator_stake_info = validator_list.find::( - validator_vote_info.key.as_ref(), - ValidatorStakeInfo::memcmp_pubkey, - ); + let maybe_validator_stake_info = validator_list.find::(|x| { + ValidatorStakeInfo::memcmp_pubkey(x, validator_vote_info.key) + }); if maybe_validator_stake_info.is_some() { return Err(StakePoolError::ValidatorAlreadyAdded.into()); } @@ -994,10 +993,9 @@ impl Processor { let (meta, stake) = get_stake_state(stake_account_info)?; let vote_account_address = stake.delegation.voter_pubkey; - let maybe_validator_stake_info = validator_list.find_mut::( - vote_account_address.as_ref(), - ValidatorStakeInfo::memcmp_pubkey, - ); + let maybe_validator_stake_info = validator_list.find_mut::(|x| { + ValidatorStakeInfo::memcmp_pubkey(x, &vote_account_address) + }); if maybe_validator_stake_info.is_none() { msg!( "Vote account {} not found in stake pool", @@ -1154,10 +1152,9 @@ impl Processor { let (meta, stake) = get_stake_state(validator_stake_account_info)?; let vote_account_address = stake.delegation.voter_pubkey; - let maybe_validator_stake_info = validator_list.find_mut::( - vote_account_address.as_ref(), - ValidatorStakeInfo::memcmp_pubkey, - ); + let maybe_validator_stake_info = validator_list.find_mut::(|x| { + ValidatorStakeInfo::memcmp_pubkey(x, &vote_account_address) + }); if maybe_validator_stake_info.is_none() { msg!( "Vote account {} not found in stake pool", @@ -1316,10 +1313,9 @@ impl Processor { let vote_account_address = validator_vote_account_info.key; - let maybe_validator_stake_info = validator_list.find_mut::( - vote_account_address.as_ref(), - ValidatorStakeInfo::memcmp_pubkey, - ); + let maybe_validator_stake_info = validator_list.find_mut::(|x| { + ValidatorStakeInfo::memcmp_pubkey(x, vote_account_address) + }); if maybe_validator_stake_info.is_none() { msg!( "Vote account {} not found in stake pool", @@ -1481,10 +1477,9 @@ impl Processor { } if let Some(vote_account_address) = vote_account_address { - let maybe_validator_stake_info = validator_list.find::( - vote_account_address.as_ref(), - ValidatorStakeInfo::memcmp_pubkey, - ); + let maybe_validator_stake_info = validator_list.find::(|x| { + ValidatorStakeInfo::memcmp_pubkey(x, &vote_account_address) + }); match maybe_validator_stake_info { Some(vsi) => { if vsi.status != StakeStatus::Active { @@ -2031,10 +2026,9 @@ impl Processor { } let mut validator_stake_info = validator_list - .find_mut::( - vote_account_address.as_ref(), - ValidatorStakeInfo::memcmp_pubkey, - ) + .find_mut::(|x| { + ValidatorStakeInfo::memcmp_pubkey(x, &vote_account_address) + }) .ok_or(StakePoolError::ValidatorNotFound)?; check_validator_stake_address( program_id, @@ -2428,7 +2422,7 @@ impl Processor { .checked_sub(pool_tokens_fee) .ok_or(StakePoolError::CalculationFailure)?; - let withdraw_lamports = stake_pool + let mut withdraw_lamports = stake_pool .calc_lamports_withdraw_amount(pool_tokens_burnt) .ok_or(StakePoolError::CalculationFailure)?; @@ -2442,17 +2436,27 @@ impl Processor { let meta = stake_state.meta().ok_or(StakePoolError::WrongStakeState)?; let required_lamports = minimum_stake_lamports(&meta, stake_minimum_delegation); + let lamports_per_pool_token = stake_pool + .get_lamports_per_pool_token() + .ok_or(StakePoolError::CalculationFailure)?; + let minimum_lamports_with_tolerance = + required_lamports.saturating_add(lamports_per_pool_token); + let has_active_stake = validator_list - .find::( - &required_lamports.to_le_bytes(), - ValidatorStakeInfo::active_lamports_not_equal, - ) + .find::(|x| { + ValidatorStakeInfo::active_lamports_greater_than( + x, + &minimum_lamports_with_tolerance, + ) + }) .is_some(); let has_transient_stake = validator_list - .find::( - &0u64.to_le_bytes(), - ValidatorStakeInfo::transient_lamports_not_equal, - ) + .find::(|x| { + ValidatorStakeInfo::transient_lamports_greater_than( + x, + &minimum_lamports_with_tolerance, + ) + }) .is_some(); let validator_list_item_info = if *stake_split_from.key == stake_pool.reserve_stake { @@ -2478,14 +2482,13 @@ impl Processor { stake_pool.preferred_withdraw_validator_vote_address { let preferred_validator_info = validator_list - .find::( - preferred_withdraw_validator.as_ref(), - ValidatorStakeInfo::memcmp_pubkey, - ) + .find::(|x| { + ValidatorStakeInfo::memcmp_pubkey(x, &preferred_withdraw_validator) + }) .ok_or(StakePoolError::ValidatorNotFound)?; let available_lamports = preferred_validator_info .active_stake_lamports - .saturating_sub(required_lamports); + .saturating_sub(minimum_lamports_with_tolerance); if preferred_withdraw_validator != vote_account_address && available_lamports > 0 { msg!("Validator vote address {} is preferred for withdrawals, it currently has {} lamports available. Please withdraw those before using other validator stake accounts.", preferred_withdraw_validator, preferred_validator_info.active_stake_lamports); return Err(StakePoolError::IncorrectWithdrawVoteAddress.into()); @@ -2493,10 +2496,9 @@ impl Processor { } let validator_stake_info = validator_list - .find_mut::( - vote_account_address.as_ref(), - ValidatorStakeInfo::memcmp_pubkey, - ) + .find_mut::(|x| { + ValidatorStakeInfo::memcmp_pubkey(x, &vote_account_address) + }) .ok_or(StakePoolError::ValidatorNotFound)?; let withdraw_source = if has_active_stake { @@ -2548,11 +2550,21 @@ impl Processor { } } StakeWithdrawSource::ValidatorRemoval => { - if withdraw_lamports != stake_split_from.lamports() { - msg!("Cannot withdraw a whole account worth {} lamports, must withdraw exactly {} lamports worth of pool tokens", - withdraw_lamports, stake_split_from.lamports()); + let split_from_lamports = stake_split_from.lamports(); + let upper_bound = split_from_lamports.saturating_add(lamports_per_pool_token); + if withdraw_lamports < split_from_lamports || withdraw_lamports > upper_bound { + msg!( + "Cannot withdraw a whole account worth {} lamports, \ + must withdraw at least {} lamports worth of pool tokens \ + with a margin of {} lamports", + withdraw_lamports, + split_from_lamports, + lamports_per_pool_token + ); return Err(StakePoolError::StakeLamportsNotEqualToMinimum.into()); } + // truncate the lamports down to the amount in the account + withdraw_lamports = split_from_lamports; } } Some((validator_stake_info, withdraw_source)) diff --git a/program/src/state.rs b/program/src/state.rs index 4eb044dc..ab533dcf 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -255,6 +255,15 @@ impl StakePool { } } + /// Get the current value of pool tokens, rounded up + #[inline] + pub fn get_lamports_per_pool_token(&self) -> Option { + self.total_lamports + .checked_add(self.pool_token_supply)? + .checked_sub(1)? + .checked_div(self.pool_token_supply) + } + /// Checks that the withdraw or deposit authority is valid fn check_program_derived_authority( authority_address: &Pubkey, @@ -660,24 +669,24 @@ impl ValidatorStakeInfo { /// Performs a very cheap comparison, for checking if this validator stake /// info matches the vote account address - pub fn memcmp_pubkey(data: &[u8], vote_address_bytes: &[u8]) -> bool { + pub fn memcmp_pubkey(data: &[u8], vote_address: &Pubkey) -> bool { sol_memcmp( &data[41..41 + PUBKEY_BYTES], - vote_address_bytes, + vote_address.as_ref(), PUBKEY_BYTES, ) == 0 } - /// Performs a very cheap comparison, for checking if this validator stake - /// info does not have active lamports equal to the given bytes - pub fn active_lamports_not_equal(data: &[u8], lamports_le_bytes: &[u8]) -> bool { - sol_memcmp(&data[0..8], lamports_le_bytes, 8) != 0 + /// Performs a comparison, used to check if this validator stake + /// info has more active lamports than some limit + pub fn active_lamports_greater_than(data: &[u8], lamports: &u64) -> bool { + u64::try_from_slice(&data[0..8]).unwrap() > *lamports } - /// Performs a very cheap comparison, for checking if this validator stake - /// info does not have lamports equal to the given bytes - pub fn transient_lamports_not_equal(data: &[u8], lamports_le_bytes: &[u8]) -> bool { - sol_memcmp(&data[8..16], lamports_le_bytes, 8) != 0 + /// Performs a comparison, used to check if this validator stake + /// info has more transient lamports than some limit + pub fn transient_lamports_greater_than(data: &[u8], lamports: &u64) -> bool { + u64::try_from_slice(&data[8..16]).unwrap() > *lamports } /// Check that the validator stake info is valid diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index 66fcbfc8..40028e69 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -20,7 +20,7 @@ use { }, }; -const HUGE_POOL_SIZE: u32 = 2_000; +const HUGE_POOL_SIZE: u32 = 3_300; const STAKE_AMOUNT: u64 = 200_000_000_000; async fn setup( diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index 7ace0cf8..827189a2 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -96,6 +96,11 @@ async fn setup( // Warp forward so the stakes properly activate, and deposit slot += slots_per_epoch; context.warp_to_slot(slot).unwrap(); + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&context.last_blockhash) + .await + .unwrap(); stake_pool_accounts .update_all( @@ -111,12 +116,6 @@ async fn setup( ) .await; - let last_blockhash = context - .banks_client - .get_new_latest_blockhash(&context.last_blockhash) - .await - .unwrap(); - for deposit_account in &mut deposit_accounts { deposit_account .deposit_stake( @@ -130,6 +129,11 @@ async fn setup( slot += slots_per_epoch; context.warp_to_slot(slot).unwrap(); + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&context.last_blockhash) + .await + .unwrap(); stake_pool_accounts .update_all( @@ -418,6 +422,11 @@ async fn merge_into_validator_stake() { // Warp just a little bit to get a new blockhash and update again context.warp_to_slot(slot + 10).unwrap(); + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&last_blockhash) + .await + .unwrap(); // Update, should not change, no merges yet let error = stake_pool_accounts diff --git a/program/tests/withdraw_edge_cases.rs b/program/tests/withdraw_edge_cases.rs index b97d9300..5c1f0a45 100644 --- a/program/tests/withdraw_edge_cases.rs +++ b/program/tests/withdraw_edge_cases.rs @@ -12,6 +12,7 @@ use { solana_program_test::*, solana_sdk::{signature::Signer, transaction::TransactionError}, spl_stake_pool::{error::StakePoolError, instruction, state, MINIMUM_RESERVE_LAMPORTS}, + test_case::test_case, }; #[tokio::test] @@ -87,8 +88,12 @@ async fn fail_remove_validator() { ); } +#[test_case(0; "equal")] +#[test_case(5; "big")] +#[test_case(11; "bigger")] +#[test_case(29; "biggest")] #[tokio::test] -async fn success_remove_validator() { +async fn success_remove_validator(multiple: u64) { let ( mut context, stake_pool_accounts, @@ -99,10 +104,33 @@ async fn success_remove_validator() { _, ) = setup_for_withdraw(spl_token::id()).await; + // make pool tokens very valuable, so it isn't possible to exactly get down to the minimum + transfer( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts.reserve_stake.pubkey(), + deposit_info.stake_lamports * multiple, // each pool token is worth more than one lamport + ) + .await; + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &[validator_stake.vote.pubkey()], + false, + ) + .await; + let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_pool = stake_pool_accounts + .get_stake_pool(&mut context.banks_client) + .await; + let lamports_per_pool_token = stake_pool.get_lamports_per_pool_token().unwrap(); - // decrease all of stake + // decrease all of stake except for lamports_per_pool_token lamports, must be withdrawable let error = stake_pool_accounts .decrease_validator_stake( &mut context.banks_client, @@ -110,7 +138,7 @@ async fn success_remove_validator() { &context.last_blockhash, &validator_stake.stake_account, &validator_stake.transient_stake_account, - deposit_info.stake_lamports + stake_rent, + deposit_info.stake_lamports + stake_rent - lamports_per_pool_token, validator_stake.transient_stake_seed, ) .await; @@ -123,12 +151,18 @@ async fn success_remove_validator() { .warp_to_slot(first_normal_slot + slots_per_epoch) .unwrap(); + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&context.last_blockhash) + .await + .unwrap(); + // update to merge deactivated stake into reserve stake_pool_accounts .update_all( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &[validator_stake.vote.pubkey()], false, ) @@ -137,13 +171,23 @@ async fn success_remove_validator() { let validator_stake_account = get_account(&mut context.banks_client, &validator_stake.stake_account).await; let remaining_lamports = validator_stake_account.lamports; + let stake_minimum_delegation = + stake_get_minimum_delegation(&mut context.banks_client, &context.payer, &last_blockhash) + .await; + // make sure it's actually more than the minimum + assert!(remaining_lamports > stake_rent + stake_minimum_delegation); + + // round up to force one more pool token if needed + let pool_tokens_post_fee = + (remaining_lamports * stake_pool.pool_token_supply + stake_pool.total_lamports - 1) + / stake_pool.total_lamports; let new_user_authority = Pubkey::new_unique(); - let pool_tokens = stake_pool_accounts.calculate_inverse_withdrawal_fee(remaining_lamports); + let pool_tokens = stake_pool_accounts.calculate_inverse_withdrawal_fee(pool_tokens_post_fee); let error = stake_pool_accounts .withdraw_stake( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &user_stake_recipient.pubkey(), &user_transfer_authority, &deposit_info.pool_account.pubkey(), @@ -175,7 +219,7 @@ async fn success_remove_validator() { .cleanup_removed_validator_entries( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, ) .await; @@ -497,6 +541,7 @@ async fn success_and_fail_with_preferred_withdraw() { ); // success from preferred + let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts .withdraw_stake( &mut context.banks_client, @@ -548,7 +593,7 @@ async fn fail_withdraw_from_transient() { let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); - // decrease to minimum stake + 1 lamport + // decrease to minimum stake + 2 lamports let error = stake_pool_accounts .decrease_validator_stake( &mut context.banks_client, @@ -556,7 +601,7 @@ async fn fail_withdraw_from_transient() { &context.last_blockhash, &validator_stake_account.stake_account, &validator_stake_account.transient_stake_account, - deposit_info.stake_lamports + stake_rent - 1, + deposit_info.stake_lamports + stake_rent - 2, validator_stake_account.transient_stake_seed, ) .await; @@ -655,3 +700,145 @@ async fn success_withdraw_from_transient() { .await; assert!(error.is_none()); } + +#[tokio::test] +async fn success_with_small_preferred_withdraw() { + let ( + mut context, + stake_pool_accounts, + validator_stake, + deposit_info, + user_transfer_authority, + user_stake_recipient, + tokens_to_burn, + ) = setup_for_withdraw(spl_token::id()).await; + + // make pool tokens very valuable, so it isn't possible to exactly get down to the minimum + transfer( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts.reserve_stake.pubkey(), + deposit_info.stake_lamports * 5, // each pool token is worth more than one lamport + ) + .await; + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &[validator_stake.vote.pubkey()], + false, + ) + .await; + + let preferred_validator = simple_add_validator_to_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + None, + ) + .await; + + stake_pool_accounts + .set_preferred_validator( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + instruction::PreferredValidatorType::Withdraw, + Some(preferred_validator.vote.pubkey()), + ) + .await; + + // add a tiny bit of stake, less than lamports per pool token to preferred validator + let rent = context.banks_client.get_rent().await.unwrap(); + let rent_exempt = rent.minimum_balance(std::mem::size_of::()); + let stake_minimum_delegation = stake_get_minimum_delegation( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; + let minimum_lamports = stake_minimum_delegation + rent_exempt; + + simple_deposit_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + &preferred_validator, + stake_minimum_delegation + 1, // stake_rent gets deposited too + ) + .await + .unwrap(); + + // decrease all stake except for 1 lamport + let error = stake_pool_accounts + .decrease_validator_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &preferred_validator.stake_account, + &preferred_validator.transient_stake_account, + minimum_lamports, + preferred_validator.transient_stake_seed, + ) + .await; + assert!(error.is_none()); + + // warp forward to deactivation + let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + context + .warp_to_slot(first_normal_slot + slots_per_epoch) + .unwrap(); + + // update to merge deactivated stake into reserve + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &[ + validator_stake.vote.pubkey(), + preferred_validator.vote.pubkey(), + ], + false, + ) + .await; + + // withdraw from preferred fails + let new_authority = Pubkey::new_unique(); + let error = stake_pool_accounts + .withdraw_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user_stake_recipient.pubkey(), + &user_transfer_authority, + &deposit_info.pool_account.pubkey(), + &preferred_validator.stake_account, + &new_authority, + 1, + ) + .await; + assert!(error.is_some()); + + // preferred is empty, withdrawing from non-preferred works + let new_authority = Pubkey::new_unique(); + let error = stake_pool_accounts + .withdraw_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user_stake_recipient.pubkey(), + &user_transfer_authority, + &deposit_info.pool_account.pubkey(), + &validator_stake.stake_account, + &new_authority, + tokens_to_burn / 6, + ) + .await; + assert!(error.is_none()); +} From d4a99cc9e12b9f060ef051d2926b82b185eb3547 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Mon, 5 Dec 2022 18:47:22 +0100 Subject: [PATCH 0276/1076] stake-pool: Test max pool size with compute unit limit (#3870) --- program/tests/helpers/mod.rs | 286 ++++++++++++++++++++--------------- program/tests/huge_pool.rs | 273 +++++++++++++++------------------ 2 files changed, 281 insertions(+), 278 deletions(-) diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 30d3c40f..b4bd79bb 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -6,6 +6,7 @@ use { solana_program::{ borsh::{get_instance_packed_len, get_packed_len, try_from_slice_unchecked}, hash::Hash, + instruction::Instruction, program_option::COption, program_pack::Pack, pubkey::Pubkey, @@ -15,6 +16,7 @@ use { solana_sdk::{ account::{Account as SolanaAccount, WritableAccount}, clock::{Clock, Epoch}, + compute_budget::ComputeBudgetInstruction, signature::{Keypair, Signer}, transaction::Transaction, transport::TransportError, @@ -858,6 +860,7 @@ pub struct StakePoolAccounts { pub sol_deposit_fee: state::Fee, pub sol_referral_fee: u8, pub max_validators: u32, + pub compute_unit_limit: Option, } impl StakePoolAccounts { @@ -1007,7 +1010,7 @@ impl StakePoolAccounts { referrer: &Pubkey, ) -> Option { let mut signers = vec![payer, current_staker]; - let instructions = + let mut instructions = if let Some(stake_deposit_authority) = self.stake_deposit_authority_keypair.as_ref() { signers.push(stake_deposit_authority); instruction::deposit_stake_with_authority( @@ -1043,6 +1046,7 @@ impl StakePoolAccounts { &self.token_program_id, ) }; + self.maybe_add_compute_budget_instruction(&mut instructions); let transaction = Transaction::new_signed_with_payer( &instructions, Some(&payer.pubkey()), @@ -1099,8 +1103,10 @@ impl StakePoolAccounts { amount, ) }; + let mut instructions = vec![instruction]; + self.maybe_add_compute_budget_instruction(&mut instructions); let transaction = Transaction::new_signed_with_payer( - &[instruction], + &instructions, Some(&payer.pubkey()), &signers, *recent_blockhash, @@ -1126,22 +1132,24 @@ impl StakePoolAccounts { recipient_new_authority: &Pubkey, amount: u64, ) -> Option { + let mut instructions = vec![instruction::withdraw_stake( + &id(), + &self.stake_pool.pubkey(), + &self.validator_list.pubkey(), + &self.withdraw_authority, + validator_stake_account, + stake_recipient, + recipient_new_authority, + &user_transfer_authority.pubkey(), + pool_account, + &self.pool_fee_account.pubkey(), + &self.pool_mint.pubkey(), + &self.token_program_id, + amount, + )]; + self.maybe_add_compute_budget_instruction(&mut instructions); let transaction = Transaction::new_signed_with_payer( - &[instruction::withdraw_stake( - &id(), - &self.stake_pool.pubkey(), - &self.validator_list.pubkey(), - &self.withdraw_authority, - validator_stake_account, - stake_recipient, - recipient_new_authority, - &user_transfer_authority.pubkey(), - pool_account, - &self.pool_fee_account.pubkey(), - &self.pool_mint.pubkey(), - &self.token_program_id, - amount, - )], + &instructions, Some(&payer.pubkey()), &[payer, user_transfer_authority], *recent_blockhash, @@ -1197,8 +1205,10 @@ impl StakePoolAccounts { amount, ) }; + let mut instructions = vec![instruction]; + self.maybe_add_compute_budget_instruction(&mut instructions); let transaction = Transaction::new_signed_with_payer( - &[instruction], + &instructions, Some(&payer.pubkey()), &signers, *recent_blockhash, @@ -1230,18 +1240,20 @@ impl StakePoolAccounts { no_merge: bool, ) -> Option { let validator_list = self.get_validator_list(banks_client).await; + let mut instructions = vec![instruction::update_validator_list_balance( + &id(), + &self.stake_pool.pubkey(), + &self.withdraw_authority, + &self.validator_list.pubkey(), + &self.reserve_stake.pubkey(), + &validator_list, + validator_vote_accounts, + 0, + no_merge, + )]; + self.maybe_add_compute_budget_instruction(&mut instructions); let transaction = Transaction::new_signed_with_payer( - &[instruction::update_validator_list_balance( - &id(), - &self.stake_pool.pubkey(), - &self.withdraw_authority, - &self.validator_list.pubkey(), - &self.reserve_stake.pubkey(), - &validator_list, - validator_vote_accounts, - 0, - no_merge, - )], + &instructions, Some(&payer.pubkey()), &[payer], *recent_blockhash, @@ -1260,17 +1272,19 @@ impl StakePoolAccounts { payer: &Keypair, recent_blockhash: &Hash, ) -> Option { + let mut instructions = vec![instruction::update_stake_pool_balance( + &id(), + &self.stake_pool.pubkey(), + &self.withdraw_authority, + &self.validator_list.pubkey(), + &self.reserve_stake.pubkey(), + &self.pool_fee_account.pubkey(), + &self.pool_mint.pubkey(), + &self.token_program_id, + )]; + self.maybe_add_compute_budget_instruction(&mut instructions); let transaction = Transaction::new_signed_with_payer( - &[instruction::update_stake_pool_balance( - &id(), - &self.stake_pool.pubkey(), - &self.withdraw_authority, - &self.validator_list.pubkey(), - &self.reserve_stake.pubkey(), - &self.pool_fee_account.pubkey(), - &self.pool_mint.pubkey(), - &self.token_program_id, - )], + &instructions, Some(&payer.pubkey()), &[payer], *recent_blockhash, @@ -1289,12 +1303,14 @@ impl StakePoolAccounts { payer: &Keypair, recent_blockhash: &Hash, ) -> Option { + let mut instructions = vec![instruction::cleanup_removed_validator_entries( + &id(), + &self.stake_pool.pubkey(), + &self.validator_list.pubkey(), + )]; + self.maybe_add_compute_budget_instruction(&mut instructions); let transaction = Transaction::new_signed_with_payer( - &[instruction::cleanup_removed_validator_entries( - &id(), - &self.stake_pool.pubkey(), - &self.validator_list.pubkey(), - )], + &instructions, Some(&payer.pubkey()), &[payer], *recent_blockhash, @@ -1316,35 +1332,37 @@ impl StakePoolAccounts { no_merge: bool, ) -> Option { let validator_list = self.get_validator_list(banks_client).await; + let mut instructions = vec![ + instruction::update_validator_list_balance( + &id(), + &self.stake_pool.pubkey(), + &self.withdraw_authority, + &self.validator_list.pubkey(), + &self.reserve_stake.pubkey(), + &validator_list, + validator_vote_accounts, + 0, + no_merge, + ), + instruction::update_stake_pool_balance( + &id(), + &self.stake_pool.pubkey(), + &self.withdraw_authority, + &self.validator_list.pubkey(), + &self.reserve_stake.pubkey(), + &self.pool_fee_account.pubkey(), + &self.pool_mint.pubkey(), + &self.token_program_id, + ), + instruction::cleanup_removed_validator_entries( + &id(), + &self.stake_pool.pubkey(), + &self.validator_list.pubkey(), + ), + ]; + self.maybe_add_compute_budget_instruction(&mut instructions); let transaction = Transaction::new_signed_with_payer( - &[ - instruction::update_validator_list_balance( - &id(), - &self.stake_pool.pubkey(), - &self.withdraw_authority, - &self.validator_list.pubkey(), - &self.reserve_stake.pubkey(), - &validator_list, - validator_vote_accounts, - 0, - no_merge, - ), - instruction::update_stake_pool_balance( - &id(), - &self.stake_pool.pubkey(), - &self.withdraw_authority, - &self.validator_list.pubkey(), - &self.reserve_stake.pubkey(), - &self.pool_fee_account.pubkey(), - &self.pool_mint.pubkey(), - &self.token_program_id, - ), - instruction::cleanup_removed_validator_entries( - &id(), - &self.stake_pool.pubkey(), - &self.validator_list.pubkey(), - ), - ], + &instructions, Some(&payer.pubkey()), &[payer], *recent_blockhash, @@ -1366,18 +1384,20 @@ impl StakePoolAccounts { validator: &Pubkey, seed: Option, ) -> Option { + let mut instructions = vec![instruction::add_validator_to_pool( + &id(), + &self.stake_pool.pubkey(), + &self.staker.pubkey(), + &self.reserve_stake.pubkey(), + &self.withdraw_authority, + &self.validator_list.pubkey(), + stake, + validator, + seed, + )]; + self.maybe_add_compute_budget_instruction(&mut instructions); let transaction = Transaction::new_signed_with_payer( - &[instruction::add_validator_to_pool( - &id(), - &self.stake_pool.pubkey(), - &self.staker.pubkey(), - &self.reserve_stake.pubkey(), - &self.withdraw_authority, - &self.validator_list.pubkey(), - stake, - validator, - seed, - )], + &instructions, Some(&payer.pubkey()), &[payer, &self.staker], *recent_blockhash, @@ -1399,16 +1419,18 @@ impl StakePoolAccounts { validator_stake: &Pubkey, transient_stake: &Pubkey, ) -> Option { + let mut instructions = vec![instruction::remove_validator_from_pool( + &id(), + &self.stake_pool.pubkey(), + &self.staker.pubkey(), + &self.withdraw_authority, + &self.validator_list.pubkey(), + validator_stake, + transient_stake, + )]; + self.maybe_add_compute_budget_instruction(&mut instructions); let transaction = Transaction::new_signed_with_payer( - &[instruction::remove_validator_from_pool( - &id(), - &self.stake_pool.pubkey(), - &self.staker.pubkey(), - &self.withdraw_authority, - &self.validator_list.pubkey(), - validator_stake, - transient_stake, - )], + &instructions, Some(&payer.pubkey()), &[payer, &self.staker], *recent_blockhash, @@ -1432,18 +1454,20 @@ impl StakePoolAccounts { lamports: u64, transient_stake_seed: u64, ) -> Option { + let mut instructions = vec![instruction::decrease_validator_stake( + &id(), + &self.stake_pool.pubkey(), + &self.staker.pubkey(), + &self.withdraw_authority, + &self.validator_list.pubkey(), + validator_stake, + transient_stake, + lamports, + transient_stake_seed, + )]; + self.maybe_add_compute_budget_instruction(&mut instructions); let transaction = Transaction::new_signed_with_payer( - &[instruction::decrease_validator_stake( - &id(), - &self.stake_pool.pubkey(), - &self.staker.pubkey(), - &self.withdraw_authority, - &self.validator_list.pubkey(), - validator_stake, - transient_stake, - lamports, - transient_stake_seed, - )], + &instructions, Some(&payer.pubkey()), &[payer, &self.staker], *recent_blockhash, @@ -1468,20 +1492,22 @@ impl StakePoolAccounts { lamports: u64, transient_stake_seed: u64, ) -> Option { + let mut instructions = vec![instruction::increase_validator_stake( + &id(), + &self.stake_pool.pubkey(), + &self.staker.pubkey(), + &self.withdraw_authority, + &self.validator_list.pubkey(), + &self.reserve_stake.pubkey(), + transient_stake, + validator_stake, + validator, + lamports, + transient_stake_seed, + )]; + self.maybe_add_compute_budget_instruction(&mut instructions); let transaction = Transaction::new_signed_with_payer( - &[instruction::increase_validator_stake( - &id(), - &self.stake_pool.pubkey(), - &self.staker.pubkey(), - &self.withdraw_authority, - &self.validator_list.pubkey(), - &self.reserve_stake.pubkey(), - transient_stake, - validator_stake, - validator, - lamports, - transient_stake_seed, - )], + &instructions, Some(&payer.pubkey()), &[payer, &self.staker], *recent_blockhash, @@ -1502,15 +1528,17 @@ impl StakePoolAccounts { validator_type: instruction::PreferredValidatorType, validator: Option, ) -> Option { + let mut instructions = vec![instruction::set_preferred_validator( + &id(), + &self.stake_pool.pubkey(), + &self.staker.pubkey(), + &self.validator_list.pubkey(), + validator_type, + validator, + )]; + self.maybe_add_compute_budget_instruction(&mut instructions); let transaction = Transaction::new_signed_with_payer( - &[instruction::set_preferred_validator( - &id(), - &self.stake_pool.pubkey(), - &self.staker.pubkey(), - &self.validator_list.pubkey(), - validator_type, - validator, - )], + &instructions, Some(&payer.pubkey()), &[payer, &self.staker], *recent_blockhash, @@ -1562,6 +1590,15 @@ impl StakePoolAccounts { validator_list.validators = vec![]; (stake_pool, validator_list) } + + pub fn maybe_add_compute_budget_instruction(&self, instructions: &mut Vec) { + if let Some(compute_unit_limit) = self.compute_unit_limit { + instructions.insert( + 0, + ComputeBudgetInstruction::set_compute_unit_limit(compute_unit_limit), + ); + } + } } impl Default for StakePoolAccounts { fn default() -> Self { @@ -1610,6 +1647,7 @@ impl Default for StakePoolAccounts { }, sol_referral_fee: 50, max_validators: MAX_TEST_VALIDATORS, + compute_unit_limit: None, } } } diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index 40028e69..a82fbed9 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -18,9 +18,14 @@ use { state::{StakePool, StakeStatus, ValidatorList}, MAX_VALIDATORS_TO_UPDATE, }, + test_case::test_case, }; -const HUGE_POOL_SIZE: u32 = 3_300; +// Note: this is not the real max! The testing framework starts to blow out because +// the test require so many helper accounts. +// 20k is also a very safe number for the current upper bound of the network. +const MAX_POOL_SIZE_WITH_REQUESTED_COMPUTE_UNITS: u32 = 20_000; +const MAX_POOL_SIZE: u32 = 3_300; const STAKE_AMOUNT: u64 = 200_000_000_000; async fn setup( @@ -38,10 +43,13 @@ async fn setup( ) { let mut program_test = program_test(); let mut vote_account_pubkeys = vec![]; - let stake_pool_accounts = StakePoolAccounts { + let mut stake_pool_accounts = StakePoolAccounts { max_validators, ..Default::default() }; + if max_validators > MAX_POOL_SIZE { + stake_pool_accounts.compute_unit_limit = Some(1_400_000); + } let stake_pool_pubkey = stake_pool_accounts.stake_pool.pubkey(); let (mut stake_pool, mut validator_list) = stake_pool_accounts.state(); @@ -102,7 +110,7 @@ async fn setup( let slot = epoch_schedule.first_normal_slot + epoch_schedule.slots_per_epoch; context.warp_to_slot(slot).unwrap(); - let vote_pubkey = vote_account_pubkeys[HUGE_POOL_SIZE as usize - 1]; + let vote_pubkey = vote_account_pubkeys[max_validators as usize - 1]; // make stake account let user = Keypair::new(); let deposit_stake = Keypair::new(); @@ -160,81 +168,49 @@ async fn setup( ) } +#[test_case(MAX_POOL_SIZE_WITH_REQUESTED_COMPUTE_UNITS; "compute-budget")] +#[test_case(MAX_POOL_SIZE; "no-compute-budget")] #[tokio::test] -async fn update() { +async fn update(max_validators: u32) { let (mut context, stake_pool_accounts, vote_account_pubkeys, _, _, _, _) = - setup(HUGE_POOL_SIZE, HUGE_POOL_SIZE, STAKE_AMOUNT).await; + setup(max_validators, max_validators, STAKE_AMOUNT).await; - let validator_list = stake_pool_accounts - .get_validator_list(&mut context.banks_client) - .await; - let transaction = Transaction::new_signed_with_payer( - &[instruction::update_validator_list_balance( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.withdraw_authority, - &stake_pool_accounts.validator_list.pubkey(), - &stake_pool_accounts.reserve_stake.pubkey(), - &validator_list, + let error = stake_pool_accounts + .update_validator_list_balance( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &vote_account_pubkeys[0..MAX_VALIDATORS_TO_UPDATE], - 0, - /* no_merge = */ false, - )], - Some(&context.payer.pubkey()), - &[&context.payer], - context.last_blockhash, - ); - let error = context - .banks_client - .process_transaction(transaction) - .await - .err(); + false, /* no_merge */ + ) + .await; assert!(error.is_none()); - let transaction = Transaction::new_signed_with_payer( - &[instruction::update_stake_pool_balance( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.withdraw_authority, - &stake_pool_accounts.validator_list.pubkey(), - &stake_pool_accounts.reserve_stake.pubkey(), - &stake_pool_accounts.pool_fee_account.pubkey(), - &stake_pool_accounts.pool_mint.pubkey(), - &spl_token::id(), - )], - Some(&context.payer.pubkey()), - &[&context.payer], - context.last_blockhash, - ); - let error = context - .banks_client - .process_transaction(transaction) - .await - .err(); + let error = stake_pool_accounts + .update_stake_pool_balance( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; assert!(error.is_none()); - let transaction = Transaction::new_signed_with_payer( - &[instruction::cleanup_removed_validator_entries( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.validator_list.pubkey(), - )], - Some(&context.payer.pubkey()), - &[&context.payer], - context.last_blockhash, - ); - let error = context - .banks_client - .process_transaction(transaction) - .await - .err(); + let error = stake_pool_accounts + .cleanup_removed_validator_entries( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; assert!(error.is_none()); } +//#[test_case(MAX_POOL_SIZE_WITH_REQUESTED_COMPUTE_UNITS; "compute-budget")] +#[test_case(MAX_POOL_SIZE; "no-compute-budget")] #[tokio::test] -async fn remove_validator_from_pool() { +async fn remove_validator_from_pool(max_validators: u32) { let (mut context, stake_pool_accounts, vote_account_pubkeys, _, _, _, _) = - setup(HUGE_POOL_SIZE, HUGE_POOL_SIZE, LAMPORTS_PER_SOL).await; + setup(max_validators, max_validators, LAMPORTS_PER_SOL).await; let first_vote = vote_account_pubkeys[0]; let (stake_address, _) = find_stake_program_address( @@ -262,7 +238,7 @@ async fn remove_validator_from_pool() { .await; assert!(error.is_none()); - let middle_index = HUGE_POOL_SIZE as usize / 2; + let middle_index = max_validators as usize / 2; let middle_vote = vote_account_pubkeys[middle_index]; let (stake_address, _) = find_stake_program_address( &id(), @@ -288,7 +264,7 @@ async fn remove_validator_from_pool() { .await; assert!(error.is_none()); - let last_index = HUGE_POOL_SIZE as usize - 1; + let last_index = max_validators as usize - 1; let last_vote = vote_account_pubkeys[last_index]; let (stake_address, _) = find_stake_program_address( &id(), @@ -345,41 +321,31 @@ async fn remove_validator_from_pool() { ); assert_eq!(last_element.transient_stake_lamports, 0); - let transaction = Transaction::new_signed_with_payer( - &[instruction::update_validator_list_balance( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.withdraw_authority, - &stake_pool_accounts.validator_list.pubkey(), - &stake_pool_accounts.reserve_stake.pubkey(), - &validator_list, + let error = stake_pool_accounts + .update_validator_list_balance( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &[first_vote], - 0, - /* no_merge = */ false, - )], - Some(&context.payer.pubkey()), - &[&context.payer], - context.last_blockhash, - ); - let error = context - .banks_client - .process_transaction(transaction) - .await - .err(); + false, /* no_merge */ + ) + .await; assert!(error.is_none()); + let mut instructions = vec![instruction::update_validator_list_balance( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), + &validator_list, + &[middle_vote], + middle_index as u32, + /* no_merge = */ false, + )]; + stake_pool_accounts.maybe_add_compute_budget_instruction(&mut instructions); let transaction = Transaction::new_signed_with_payer( - &[instruction::update_validator_list_balance( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.withdraw_authority, - &stake_pool_accounts.validator_list.pubkey(), - &stake_pool_accounts.reserve_stake.pubkey(), - &validator_list, - &[middle_vote], - middle_index as u32, - /* no_merge = */ false, - )], + &instructions, Some(&context.payer.pubkey()), &[&context.payer], context.last_blockhash, @@ -391,18 +357,20 @@ async fn remove_validator_from_pool() { .err(); assert!(error.is_none()); + let mut instructions = vec![instruction::update_validator_list_balance( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), + &validator_list, + &[last_vote], + last_index as u32, + /* no_merge = */ false, + )]; + stake_pool_accounts.maybe_add_compute_budget_instruction(&mut instructions); let transaction = Transaction::new_signed_with_payer( - &[instruction::update_validator_list_balance( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.withdraw_authority, - &stake_pool_accounts.validator_list.pubkey(), - &stake_pool_accounts.reserve_stake.pubkey(), - &validator_list, - &[last_vote], - last_index as u32, - /* no_merge = */ false, - )], + &instructions, Some(&context.payer.pubkey()), &[&context.payer], context.last_blockhash, @@ -414,22 +382,13 @@ async fn remove_validator_from_pool() { .err(); assert!(error.is_none()); - let transaction = Transaction::new_signed_with_payer( - &[instruction::cleanup_removed_validator_entries( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.validator_list.pubkey(), - )], - Some(&context.payer.pubkey()), - &[&context.payer], - context.last_blockhash, - ); - - let error = context - .banks_client - .process_transaction(transaction) - .await - .err(); + let error = stake_pool_accounts + .cleanup_removed_validator_entries( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; assert!(error.is_none()); let validator_list = get_account( @@ -439,7 +398,7 @@ async fn remove_validator_from_pool() { .await; let validator_list = try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); - assert_eq!(validator_list.validators.len() as u32, HUGE_POOL_SIZE - 3); + assert_eq!(validator_list.validators.len() as u32, max_validators - 3); // assert they're gone assert!(!validator_list .validators @@ -473,12 +432,14 @@ async fn remove_validator_from_pool() { .any(|x| x.vote_account_address == vote_account_pubkeys[last_index - 1])); } +//#[test_case(MAX_POOL_SIZE_WITH_REQUESTED_COMPUTE_UNITS; "compute-budget")] +#[test_case(MAX_POOL_SIZE; "no-compute-budget")] #[tokio::test] -async fn add_validator_to_pool() { +async fn add_validator_to_pool(max_validators: u32) { let (mut context, stake_pool_accounts, _, test_vote_address, _, _, _) = - setup(HUGE_POOL_SIZE, HUGE_POOL_SIZE - 1, STAKE_AMOUNT).await; + setup(max_validators, max_validators - 1, STAKE_AMOUNT).await; - let last_index = HUGE_POOL_SIZE as usize - 1; + let last_index = max_validators as usize - 1; let stake_pool_pubkey = stake_pool_accounts.stake_pool.pubkey(); let (stake_address, _) = find_stake_program_address(&id(), &test_vote_address, &stake_pool_pubkey, None); @@ -554,10 +515,12 @@ async fn add_validator_to_pool() { assert_eq!(last_element.vote_account_address, test_vote_address); } +//#[test_case(MAX_POOL_SIZE_WITH_REQUESTED_COMPUTE_UNITS; "compute-budget")] +#[test_case(MAX_POOL_SIZE; "no-compute-budget")] #[tokio::test] -async fn set_preferred() { +async fn set_preferred(max_validators: u32) { let (mut context, stake_pool_accounts, _, vote_account_address, _, _, _) = - setup(HUGE_POOL_SIZE, HUGE_POOL_SIZE, STAKE_AMOUNT).await; + setup(max_validators, max_validators, STAKE_AMOUNT).await; let error = stake_pool_accounts .set_preferred_validator( @@ -597,10 +560,12 @@ async fn set_preferred() { ); } +#[test_case(MAX_POOL_SIZE_WITH_REQUESTED_COMPUTE_UNITS; "compute-budget")] +#[test_case(MAX_POOL_SIZE; "no-compute-budget")] #[tokio::test] -async fn deposit_stake() { +async fn deposit_stake(max_validators: u32) { let (mut context, stake_pool_accounts, _, vote_pubkey, user, stake_pubkey, pool_account_pubkey) = - setup(HUGE_POOL_SIZE, HUGE_POOL_SIZE, STAKE_AMOUNT).await; + setup(max_validators, max_validators, STAKE_AMOUNT).await; let (stake_address, _) = find_stake_program_address( &id(), @@ -623,10 +588,12 @@ async fn deposit_stake() { assert!(error.is_none()); } +#[test_case(MAX_POOL_SIZE_WITH_REQUESTED_COMPUTE_UNITS; "compute-budget")] +#[test_case(MAX_POOL_SIZE; "no-compute-budget")] #[tokio::test] -async fn withdraw() { +async fn withdraw(max_validators: u32) { let (mut context, stake_pool_accounts, _, vote_pubkey, user, stake_pubkey, pool_account_pubkey) = - setup(HUGE_POOL_SIZE, HUGE_POOL_SIZE, STAKE_AMOUNT).await; + setup(max_validators, max_validators, STAKE_AMOUNT).await; let (stake_address, _) = find_stake_program_address( &id(), @@ -674,13 +641,19 @@ async fn withdraw() { assert!(error.is_none(), "{:?}", error); } +//#[test_case(MAX_POOL_SIZE_WITH_REQUESTED_COMPUTE_UNITS; "compute-budget")] +#[test_case(MAX_POOL_SIZE; "no-compute-budget")] #[tokio::test] -async fn cleanup_all() { +async fn cleanup_all(max_validators: u32) { let mut program_test = program_test(); let mut vote_account_pubkeys = vec![]; - let mut stake_pool_accounts = StakePoolAccounts::default(); - let max_validators = HUGE_POOL_SIZE; - stake_pool_accounts.max_validators = max_validators; + let mut stake_pool_accounts = StakePoolAccounts { + max_validators, + ..Default::default() + }; + if max_validators > MAX_POOL_SIZE { + stake_pool_accounts.compute_unit_limit = Some(1_400_000); + } let stake_pool_pubkey = stake_pool_accounts.stake_pool.pubkey(); let (mut stake_pool, mut validator_list) = stake_pool_accounts.state(); @@ -715,20 +688,12 @@ async fn cleanup_all() { ); let mut context = program_test.start_with_context().await; - let transaction = Transaction::new_signed_with_payer( - &[instruction::cleanup_removed_validator_entries( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.validator_list.pubkey(), - )], - Some(&context.payer.pubkey()), - &[&context.payer], - context.last_blockhash, - ); - let error = context - .banks_client - .process_transaction(transaction) - .await - .err(); + let error = stake_pool_accounts + .cleanup_removed_validator_entries( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; assert!(error.is_none()); } From 97b0f2bb8ccd0cd787e104d5a954df5cd188c4c4 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 6 Dec 2022 02:23:18 +0100 Subject: [PATCH 0277/1076] stake-pool: Keep trying to fix tests for CI (#3871) --- program/tests/withdraw_edge_cases.rs | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/program/tests/withdraw_edge_cases.rs b/program/tests/withdraw_edge_cases.rs index 5c1f0a45..8d5ee16c 100644 --- a/program/tests/withdraw_edge_cases.rs +++ b/program/tests/withdraw_edge_cases.rs @@ -751,21 +751,24 @@ async fn success_with_small_preferred_withdraw() { ) .await; + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&context.last_blockhash) + .await + .unwrap(); + // add a tiny bit of stake, less than lamports per pool token to preferred validator let rent = context.banks_client.get_rent().await.unwrap(); let rent_exempt = rent.minimum_balance(std::mem::size_of::()); - let stake_minimum_delegation = stake_get_minimum_delegation( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - ) - .await; + let stake_minimum_delegation = + stake_get_minimum_delegation(&mut context.banks_client, &context.payer, &last_blockhash) + .await; let minimum_lamports = stake_minimum_delegation + rent_exempt; simple_deposit_stake( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &stake_pool_accounts, &preferred_validator, stake_minimum_delegation + 1, // stake_rent gets deposited too @@ -778,7 +781,7 @@ async fn success_with_small_preferred_withdraw() { .decrease_validator_stake( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &preferred_validator.stake_account, &preferred_validator.transient_stake_account, minimum_lamports, @@ -799,7 +802,7 @@ async fn success_with_small_preferred_withdraw() { .update_all( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &[ validator_stake.vote.pubkey(), preferred_validator.vote.pubkey(), @@ -814,7 +817,7 @@ async fn success_with_small_preferred_withdraw() { .withdraw_stake( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &user_stake_recipient.pubkey(), &user_transfer_authority, &deposit_info.pool_account.pubkey(), @@ -831,7 +834,7 @@ async fn success_with_small_preferred_withdraw() { .withdraw_stake( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &user_stake_recipient.pubkey(), &user_transfer_authority, &deposit_info.pool_account.pubkey(), From eb171ac28cee189b3fb99316e8c5481aa04d37ca Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Tue, 6 Dec 2022 12:59:00 +0900 Subject: [PATCH 0278/1076] update solana to 1.14.10 (#3872) --- clients/cli/Cargo.toml | 18 +++++++++--------- program/Cargo.toml | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 1f5a3a9c..28323464 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -14,15 +14,15 @@ clap = "2.33.3" serde = "1.0.130" serde_derive = "1.0.130" serde_json = "1.0.68" -solana-account-decoder = "=1.14.6" -solana-clap-utils = "=1.14.6" -solana-cli-config = "=1.14.6" -solana-cli-output = "=1.14.6" -solana-client = "=1.14.6" -solana-logger = "=1.14.6" -solana-program = "=1.14.6" -solana-remote-wallet = "=1.14.6" -solana-sdk = "=1.14.6" +solana-account-decoder = "=1.14.10" +solana-clap-utils = "=1.14.10" +solana-cli-config = "=1.14.10" +solana-cli-output = "=1.14.10" +solana-client = "=1.14.10" +solana-logger = "=1.14.10" +solana-program = "=1.14.10" +solana-remote-wallet = "=1.14.10" +solana-sdk = "=1.14.10" spl-associated-token-account = { version = "=1.1.2", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "=0.7.0", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "=3.5.0", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/program/Cargo.toml b/program/Cargo.toml index e0c20846..9c2592f1 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -20,7 +20,7 @@ num-traits = "0.2" num_enum = "0.5.4" serde = "1.0.130" serde_derive = "1.0.103" -solana-program = "1.14.6" +solana-program = "1.14.10" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-token-2022 = { version = "0.5", path = "../../token/program-2022", features = [ "no-entrypoint" ] } thiserror = "1.0" @@ -28,9 +28,9 @@ bincode = "1.3.1" [dev-dependencies] proptest = "1.0" -solana-program-test = "1.14.6" -solana-sdk = "1.14.6" -solana-vote-program = "1.14.6" +solana-program-test = "1.14.10" +solana-sdk = "1.14.10" +solana-vote-program = "1.14.10" spl-token = { version = "3.5", path = "../../token/program", features = [ "no-entrypoint" ] } test-case = "2.2" From 287831b4ca9ba5c76aea3e77c70d840cd0cf51fe Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 13 Dec 2022 16:32:52 +0100 Subject: [PATCH 0279/1076] stake-pool: Cleanup clippy, maybe fix a test (#3898) * stake-pool: Cleanup clippy, maybe fix a test * Change withdraw instructions more * Refresh blockhashes --- program/src/big_vec.rs | 1 + program/src/instruction.rs | 22 +------------------ program/src/lib.rs | 1 - program/src/processor.rs | 2 +- program/src/state.rs | 13 ++++++----- program/tests/deposit.rs | 2 -- program/tests/deposit_sol.rs | 1 - program/tests/helpers/mod.rs | 20 ----------------- program/tests/initialize.rs | 4 ---- program/tests/set_funding_authority.rs | 2 -- program/tests/set_manager.rs | 4 ---- program/tests/set_staker.rs | 2 -- program/tests/vsa_add.rs | 6 ------ program/tests/vsa_remove.rs | 4 ---- program/tests/withdraw.rs | 30 ++++++++++++++++++++------ program/tests/withdraw_edge_cases.rs | 2 +- 16 files changed, 35 insertions(+), 81 deletions(-) diff --git a/program/src/big_vec.rs b/program/src/big_vec.rs index 6d02142c..97d141bc 100644 --- a/program/src/big_vec.rs +++ b/program/src/big_vec.rs @@ -1,4 +1,5 @@ //! Big vector type, used with vectors that can't be serde'd +#![allow(clippy::integer_arithmetic)] // checked math involves too many compute units use { arrayref::array_ref, diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 799bf03e..ff0ecdc4 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -64,19 +64,14 @@ pub enum StakePoolInstruction { /// `find_deposit_authority_program_address`, making deposits permissionless. Initialize { /// Fee assessed as percentage of perceived rewards - #[allow(dead_code)] // but it's not fee: Fee, /// Fee charged per withdrawal as percentage of withdrawal - #[allow(dead_code)] // but it's not withdrawal_fee: Fee, /// Fee charged per deposit as percentage of deposit - #[allow(dead_code)] // but it's not deposit_fee: Fee, /// Percentage [0-100] of deposit_fee that goes to referrer - #[allow(dead_code)] // but it's not referral_fee: u8, /// Maximum expected number of validators - #[allow(dead_code)] // but it's not max_validators: u32, }, @@ -147,10 +142,8 @@ pub enum StakePoolInstruction { /// 9. `[]` Stake program DecreaseValidatorStake { /// amount of lamports to split into the transient stake account - #[allow(dead_code)] // but it's not lamports: u64, /// seed used to create transient stake account - #[allow(dead_code)] // but it's not transient_stake_seed: u64, }, @@ -185,10 +178,8 @@ pub enum StakePoolInstruction { /// after it is merged. IncreaseValidatorStake { /// amount of lamports to increase on the given validator - #[allow(dead_code)] // but it's not lamports: u64, /// seed used to create transient stake account - #[allow(dead_code)] // but it's not transient_stake_seed: u64, }, @@ -206,11 +197,9 @@ pub enum StakePoolInstruction { /// Fails if the validator is not part of the stake pool. SetPreferredValidator { /// Affected operation (deposit or withdraw) - #[allow(dead_code)] // but it's not validator_type: PreferredValidatorType, /// Validator vote account that deposits or withdraws must go through, /// unset with None - #[allow(dead_code)] // but it's not validator_vote_address: Option, }, @@ -233,12 +222,10 @@ pub enum StakePoolInstruction { /// 7. ..7+N ` [] N pairs of validator and transient stake accounts UpdateValidatorListBalance { /// Index to start updating on the validator list - #[allow(dead_code)] // but it's not start_index: u32, /// If true, don't try merging transient stake accounts into the reserve or /// validator stake account. Useful for testing or if a particular stake /// account is in a bad state, but we still want to update - #[allow(dead_code)] // but it's not no_merge: bool, }, @@ -328,7 +315,6 @@ pub enum StakePoolInstruction { /// 1. `[s]` Manager SetFee { /// Type of fee to update and value to update it to - #[allow(dead_code)] // but it's not fee: FeeType, }, @@ -392,14 +378,11 @@ pub enum StakePoolInstruction { /// 7. `[]` System program id /// 8. `[]` Rent sysvar CreateTokenMetadata { - #[allow(dead_code)] /// Token name name: String, - #[allow(dead_code)] /// Token symbol e.g. stkSOL symbol: String, /// URI of the uploaded metadata of the spl-token - #[allow(dead_code)] uri: String, }, /// Update token metadata for the stake-pool token in the @@ -411,14 +394,11 @@ pub enum StakePoolInstruction { /// 3. `[w]` Token metadata account /// 4. `[]` Metadata program id UpdateTokenMetadata { - #[allow(dead_code)] /// Token name name: String, - #[allow(dead_code)] /// Token symbol e.g. stkSOL symbol: String, /// URI of the uploaded metadata of the spl-token - #[allow(dead_code)] uri: String, }, } @@ -923,7 +903,7 @@ pub fn update_stake_pool( start_index, no_merge, )); - start_index += MAX_VALIDATORS_TO_UPDATE as u32; + start_index = start_index.saturating_add(MAX_VALIDATORS_TO_UPDATE as u32); } let final_instructions = vec![ diff --git a/program/src/lib.rs b/program/src/lib.rs index 940dc4c2..e5fbcfaa 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -1,4 +1,3 @@ -#![allow(clippy::integer_arithmetic)] #![deny(missing_docs)] //! A program for creating and managing pools of stake diff --git a/program/src/processor.rs b/program/src/processor.rs index f0a6f102..4a3ba627 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1399,7 +1399,7 @@ impl Processor { { let max_split_amount = reserve_stake_account_info .lamports() - .saturating_sub(2 * stake_rent); + .saturating_sub(stake_rent.saturating_mul(2)); msg!( "Reserve stake does not have enough lamports for increase, must be less than {}, {} requested", max_split_amount, diff --git a/program/src/state.rs b/program/src/state.rs index ab533dcf..1a601d99 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -671,7 +671,7 @@ impl ValidatorStakeInfo { /// info matches the vote account address pub fn memcmp_pubkey(data: &[u8], vote_address: &Pubkey) -> bool { sol_memcmp( - &data[41..41 + PUBKEY_BYTES], + &data[41..41_usize.saturating_add(PUBKEY_BYTES)], vote_address.as_ref(), PUBKEY_BYTES, ) == 0 @@ -723,8 +723,10 @@ impl ValidatorList { /// Calculate the number of validator entries that fit in the provided length pub fn calculate_max_validators(buffer_length: usize) -> usize { - let header_size = ValidatorListHeader::LEN + 4; - buffer_length.saturating_sub(header_size) / ValidatorStakeInfo::LEN + let header_size = ValidatorListHeader::LEN.saturating_add(4); + buffer_length + .saturating_sub(header_size) + .saturating_div(ValidatorStakeInfo::LEN) } /// Check if contains validator with particular pubkey @@ -847,8 +849,8 @@ impl Fee { { msg!( "Fee increase exceeds maximum allowed, proposed increase factor ({} / {})", - self.numerator * old_denom, - old_num * self.denominator, + self.numerator.saturating_mul(old_denom), + old_num.saturating_mul(self.denominator), ); return Err(StakePoolError::FeeIncreaseTooHigh); } @@ -916,6 +918,7 @@ impl FeeType { #[cfg(test)] mod test { + #![allow(clippy::integer_arithmetic)] use { super::*, proptest::prelude::*, diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index bea72864..0ccea7bd 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -501,7 +501,6 @@ async fn fail_with_wrong_stake_program_id() { let mut transaction = Transaction::new_with_payer(&[instruction], Some(&context.payer.pubkey())); transaction.sign(&[&context.payer], context.last_blockhash); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = context .banks_client .process_transaction(transaction) @@ -551,7 +550,6 @@ async fn fail_with_wrong_token_program_id() { Some(&context.payer.pubkey()), ); transaction.sign(&[&context.payer, &user], context.last_blockhash); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = context .banks_client .process_transaction(transaction) diff --git a/program/tests/deposit_sol.rs b/program/tests/deposit_sol.rs index 7d141746..e083419c 100644 --- a/program/tests/deposit_sol.rs +++ b/program/tests/deposit_sol.rs @@ -163,7 +163,6 @@ async fn fail_with_wrong_token_program_id() { Some(&context.payer.pubkey()), ); transaction.sign(&[&context.payer], context.last_blockhash); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = context .banks_client .process_transaction(transaction) diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index b4bd79bb..a9db0f78 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -154,7 +154,6 @@ pub async fn create_mint( &[payer, pool_mint], *recent_blockhash, ); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 banks_client .process_transaction(transaction) .await @@ -300,7 +299,6 @@ pub async fn create_token_account( &signers, *recent_blockhash, ); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 banks_client .process_transaction(transaction) .await @@ -328,7 +326,6 @@ pub async fn close_token_account( Some(&payer.pubkey()), ); transaction.sign(&[payer, manager], *recent_blockhash); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 banks_client .process_transaction(transaction) .await @@ -356,7 +353,6 @@ pub async fn freeze_token_account( Some(&payer.pubkey()), ); transaction.sign(&[payer, manager], *recent_blockhash); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 banks_client .process_transaction(transaction) .await @@ -388,7 +384,6 @@ pub async fn mint_tokens( &[payer, mint_authority], *recent_blockhash, ); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 banks_client .process_transaction(transaction) .await @@ -420,7 +415,6 @@ pub async fn burn_tokens( &[payer, authority], *recent_blockhash, ); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 banks_client .process_transaction(transaction) .await @@ -580,7 +574,6 @@ pub async fn create_stake_pool( signers.push(stake_deposit_authority); } transaction.sign(&signers, *recent_blockhash); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 banks_client .process_transaction(transaction) .await @@ -1053,7 +1046,6 @@ impl StakePoolAccounts { &signers, *recent_blockhash, ); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 banks_client .process_transaction(transaction) .await @@ -1111,7 +1103,6 @@ impl StakePoolAccounts { &signers, *recent_blockhash, ); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 banks_client .process_transaction(transaction) .await @@ -1154,7 +1145,6 @@ impl StakePoolAccounts { &[payer, user_transfer_authority], *recent_blockhash, ); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 banks_client .process_transaction(transaction) .await @@ -1213,7 +1203,6 @@ impl StakePoolAccounts { &signers, *recent_blockhash, ); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 banks_client .process_transaction(transaction) .await @@ -1258,7 +1247,6 @@ impl StakePoolAccounts { &[payer], *recent_blockhash, ); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 banks_client .process_transaction(transaction) .await @@ -1289,7 +1277,6 @@ impl StakePoolAccounts { &[payer], *recent_blockhash, ); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 banks_client .process_transaction(transaction) .await @@ -1315,7 +1302,6 @@ impl StakePoolAccounts { &[payer], *recent_blockhash, ); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 banks_client .process_transaction(transaction) .await @@ -1367,7 +1353,6 @@ impl StakePoolAccounts { &[payer], *recent_blockhash, ); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 banks_client .process_transaction(transaction) .await @@ -1402,7 +1387,6 @@ impl StakePoolAccounts { &[payer, &self.staker], *recent_blockhash, ); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 banks_client .process_transaction(transaction) .await @@ -1435,7 +1419,6 @@ impl StakePoolAccounts { &[payer, &self.staker], *recent_blockhash, ); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 banks_client .process_transaction(transaction) .await @@ -1472,7 +1455,6 @@ impl StakePoolAccounts { &[payer, &self.staker], *recent_blockhash, ); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 banks_client .process_transaction(transaction) .await @@ -1512,7 +1494,6 @@ impl StakePoolAccounts { &[payer, &self.staker], *recent_blockhash, ); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 banks_client .process_transaction(transaction) .await @@ -1543,7 +1524,6 @@ impl StakePoolAccounts { &[payer, &self.staker], *recent_blockhash, ); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 banks_client .process_transaction(transaction) .await diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index cfe8c47c..750ab08b 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -329,7 +329,6 @@ async fn fail_with_wrong_max_validators() { ], recent_blockhash, ); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await @@ -785,7 +784,6 @@ async fn fail_with_wrong_token_program_id() { ], recent_blockhash, ); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await @@ -893,7 +891,6 @@ async fn fail_with_fee_owned_by_wrong_token_program_id() { ], recent_blockhash, ); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await @@ -1249,7 +1246,6 @@ async fn fail_without_manager_signature() { ], recent_blockhash, ); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await diff --git a/program/tests/set_funding_authority.rs b/program/tests/set_funding_authority.rs index 0d51227d..5fe7b8a9 100644 --- a/program/tests/set_funding_authority.rs +++ b/program/tests/set_funding_authority.rs @@ -112,7 +112,6 @@ async fn fail_wrong_manager() { Some(&payer.pubkey()), ); transaction.sign(&[&payer, &new_authority], recent_blockhash); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await @@ -153,7 +152,6 @@ async fn fail_without_signature() { let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); transaction.sign(&[&payer], recent_blockhash); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await diff --git a/program/tests/set_manager.rs b/program/tests/set_manager.rs index e1200f5d..0dff30aa 100644 --- a/program/tests/set_manager.rs +++ b/program/tests/set_manager.rs @@ -110,7 +110,6 @@ async fn test_set_manager_by_malicious() { Some(&payer.pubkey()), ); transaction.sign(&[&payer, &new_manager], recent_blockhash); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await @@ -152,7 +151,6 @@ async fn test_set_manager_without_existing_signature() { let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); transaction.sign(&[&payer, &new_manager], recent_blockhash); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await @@ -196,7 +194,6 @@ async fn test_set_manager_without_new_signature() { let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); transaction.sign(&[&payer, &stake_pool_accounts.manager], recent_blockhash); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await @@ -276,7 +273,6 @@ async fn test_set_manager_with_wrong_mint_for_pool_fee_acc() { &[&payer, &stake_pool_accounts.manager, &new_manager], recent_blockhash, ); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await diff --git a/program/tests/set_staker.rs b/program/tests/set_staker.rs index ab2e0b29..bf30fac6 100644 --- a/program/tests/set_staker.rs +++ b/program/tests/set_staker.rs @@ -126,7 +126,6 @@ async fn fail_wrong_manager() { Some(&payer.pubkey()), ); transaction.sign(&[&payer, &new_staker], recent_blockhash); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await @@ -167,7 +166,6 @@ async fn fail_set_staker_without_signature() { let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); transaction.sign(&[&payer], recent_blockhash); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index 0b195ae8..9b71900c 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -165,7 +165,6 @@ async fn fail_with_wrong_validator_list_account() { Some(&payer.pubkey()), ); transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await @@ -249,7 +248,6 @@ async fn fail_wrong_staker() { Some(&payer.pubkey()), ); transaction.sign(&[&payer, &malicious], recent_blockhash); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await @@ -304,7 +302,6 @@ async fn fail_without_signature() { let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); transaction.sign(&[&payer], recent_blockhash); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await @@ -359,7 +356,6 @@ async fn fail_with_wrong_stake_program_id() { }; let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await @@ -413,7 +409,6 @@ async fn fail_with_wrong_system_program_id() { }; let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await @@ -659,7 +654,6 @@ async fn fail_with_wrong_reserve() { Some(&payer.pubkey()), ); transaction.sign(&[&payer, &stake_pool_accounts.staker], recent_blockhash); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = banks_client .process_transaction(transaction) .await diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 4dd07a26..980f87e2 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -150,7 +150,6 @@ async fn fail_with_wrong_stake_program_id() { &[&context.payer, &stake_pool_accounts.staker], context.last_blockhash, ); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = context .banks_client .process_transaction(transaction) @@ -192,7 +191,6 @@ async fn fail_with_wrong_validator_list_account() { &[&context.payer, &stake_pool_accounts.staker], context.last_blockhash, ); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = context .banks_client .process_transaction(transaction) @@ -318,7 +316,6 @@ async fn fail_wrong_staker() { Some(&context.payer.pubkey()), ); transaction.sign(&[&context.payer, &malicious], context.last_blockhash); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = context .banks_client .process_transaction(transaction) @@ -369,7 +366,6 @@ async fn fail_no_signature() { &[&context.payer], context.last_blockhash, ); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = context .banks_client .process_transaction(transaction) diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index d66c5f95..393e6504 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -302,7 +302,6 @@ async fn fail_with_wrong_stake_program() { &[&context.payer, &user_transfer_authority], context.last_blockhash, ); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = context .banks_client .process_transaction(transaction) @@ -396,7 +395,6 @@ async fn fail_with_wrong_token_program_id() { &[&context.payer, &user_transfer_authority], context.last_blockhash, ); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 let transaction_error = context .banks_client .process_transaction(transaction) @@ -643,12 +641,18 @@ async fn fail_with_not_enough_tokens() { ) .await; + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&context.last_blockhash) + .await + .unwrap(); + let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts .withdraw_stake( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &user_stake_recipient.pubkey(), &user_transfer_authority, &deposit_info.pool_account.pubkey(), @@ -671,20 +675,26 @@ async fn fail_with_not_enough_tokens() { revoke_tokens( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &stake_pool_accounts.token_program_id, &deposit_info.pool_account.pubkey(), &deposit_info.authority, ) .await; + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&last_blockhash) + .await + .unwrap(); + // generate a new authority each time to make each transaction unique let new_authority = Pubkey::new_unique(); let transaction_error = stake_pool_accounts .withdraw_stake( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &user_stake_recipient.pubkey(), &user_transfer_authority, &deposit_info.pool_account.pubkey(), @@ -708,7 +718,7 @@ async fn fail_with_not_enough_tokens() { delegate_tokens( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &stake_pool_accounts.token_program_id, &deposit_info.pool_account.pubkey(), &deposit_info.authority, @@ -717,13 +727,19 @@ async fn fail_with_not_enough_tokens() { ) .await; + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&last_blockhash) + .await + .unwrap(); + // generate a new authority each time to make each transaction unique let new_authority = Pubkey::new_unique(); let transaction_error = stake_pool_accounts .withdraw_stake( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &user_stake_recipient.pubkey(), &user_transfer_authority, &deposit_info.pool_account.pubkey(), diff --git a/program/tests/withdraw_edge_cases.rs b/program/tests/withdraw_edge_cases.rs index 8d5ee16c..84e9390f 100644 --- a/program/tests/withdraw_edge_cases.rs +++ b/program/tests/withdraw_edge_cases.rs @@ -527,7 +527,7 @@ async fn success_and_fail_with_preferred_withdraw() { &deposit_info.pool_account.pubkey(), &validator_stake.stake_account, &new_authority, - tokens_to_burn / 2, + tokens_to_burn / 2 + 1, ) .await .unwrap() From 238d1cf0b4a0a9bed4ce1ec0e0a683840f67a7af Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 13 Dec 2022 23:46:26 +0100 Subject: [PATCH 0280/1076] Update repo to `edition = "2021"` (#3900) --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 28323464..be39c048 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -1,7 +1,7 @@ [package] authors = ["Solana Maintainers "] description = "SPL-Stake-Pool Command-line Utility" -edition = "2018" +edition = "2021" homepage = "https://spl.solana.com/stake-pool" license = "Apache-2.0" name = "spl-stake-pool-cli" diff --git a/program/Cargo.toml b/program/Cargo.toml index 9c2592f1..3df76911 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -5,7 +5,7 @@ description = "Solana Program Library Stake Pool" authors = ["Solana Maintainers "] repository = "https://github.com/solana-labs/solana-program-library" license = "Apache-2.0" -edition = "2018" +edition = "2021" [features] no-entrypoint = [] From 3824755533b4349f65b51013a3cb3cdd62a9ea19 Mon Sep 17 00:00:00 2001 From: hanako mumei <81144685+2501babe@users.noreply.github.com> Date: Mon, 12 Dec 2022 22:13:39 -0800 Subject: [PATCH 0281/1076] stake-pool: allow removing validator below minimum also minor comment errors --- program/src/instruction.rs | 8 ++++---- program/src/processor.rs | 12 +++++++----- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/program/src/instruction.rs b/program/src/instruction.rs index ff0ecdc4..e3c5e965 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -127,8 +127,8 @@ pub enum StakePoolInstruction { /// validator stake account, into its "transient" stake account. /// /// The instruction only succeeds if the transient stake account does not - /// exist. The amount of lamports to move must be at least rent-exemption - /// plus 1 lamport. + /// exist. The amount of lamports to move must be at least rent-exemption plus + /// `max(crate::MINIMUM_ACTIVE_STAKE, solana_program::stake::tools::get_minimum_delegation())`. /// /// 0. `[]` Stake pool /// 1. `[s]` Stake pool staker @@ -219,7 +219,7 @@ pub enum StakePoolInstruction { /// 4. `[]` Sysvar clock /// 5. `[]` Sysvar stake history /// 6. `[]` Stake program - /// 7. ..7+N ` [] N pairs of validator and transient stake accounts + /// 7. ..7+2N ` [] N pairs of validator and transient stake accounts UpdateValidatorListBalance { /// Index to start updating on the validator list start_index: u32, @@ -341,7 +341,7 @@ pub enum StakePoolInstruction { /// 10. `[s]` (Optional) Stake pool sol deposit authority. DepositSol(u64), - /// (Manager only) Update SOL deposit authority + /// (Manager only) Update SOL deposit, stake deposit, or SOL withdrawal authority. /// /// 0. `[w]` StakePool /// 1. `[s]` Manager diff --git a/program/src/processor.rs b/program/src/processor.rs index 4a3ba627..08caa1cc 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1020,9 +1020,10 @@ impl Processor { let stake_lamports = **stake_account_info.lamports.borrow(); let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; let required_lamports = minimum_stake_lamports(&meta, stake_minimum_delegation); - if stake_lamports != required_lamports { + if stake_lamports > required_lamports { msg!( - "Attempting to remove validator account with {} lamports, must have {} lamports", + "Attempting to remove validator account with {} lamports, must have no more than {} lamports; \ + reduce using DecreaseValidatorStake first", stake_lamports, required_lamports ); @@ -1030,9 +1031,10 @@ impl Processor { } let current_minimum_delegation = minimum_delegation(stake_minimum_delegation); - if stake.delegation.stake != current_minimum_delegation { + if stake.delegation.stake > current_minimum_delegation { msg!( - "Error: attempting to remove stake with delegation of {} lamports, must have {} lamports", + "Error: attempting to remove stake with delegation of {} lamports, must have no more than {} lamports; \ + reduce using DecreaseValidatorStake first", stake.delegation.stake, current_minimum_delegation ); @@ -1195,7 +1197,7 @@ impl Processor { stake_rent.saturating_add(minimum_delegation(stake_minimum_delegation)); if lamports < current_minimum_lamports { msg!( - "Need at least {} lamports for transient stake meet minimum delegation and rent-exempt requirements, {} provided", + "Need at least {} lamports for transient stake to meet minimum delegation and rent-exempt requirements, {} provided", current_minimum_lamports, lamports ); From 8499a8e6e24a6fe51e4b7936ecdcd666e62defd2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Dec 2022 02:42:47 +0100 Subject: [PATCH 0282/1076] build(deps): bump certifi from 2022.6.15 to 2022.12.7 in /stake-pool/py (#3886) Bumps [certifi](https://github.com/certifi/python-certifi) from 2022.6.15 to 2022.12.7. - [Release notes](https://github.com/certifi/python-certifi/releases) - [Commits](https://github.com/certifi/python-certifi/compare/2022.06.15...2022.12.07) --- updated-dependencies: - dependency-name: certifi dependency-type: direct:production ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/py/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/py/requirements.txt b/clients/py/requirements.txt index 1b72ffc6..7cd54097 100644 --- a/clients/py/requirements.txt +++ b/clients/py/requirements.txt @@ -1,7 +1,7 @@ anyio==3.6.1 base58==2.1.1 cachetools==4.2.4 -certifi==2022.6.15 +certifi==2022.12.7 cffi==1.15.1 charset-normalizer==2.1.0 construct==2.10.68 From 1917bbb912b6eb66bb0c77808be6dc7d29a6d847 Mon Sep 17 00:00:00 2001 From: Dmitri Makarov Date: Wed, 14 Dec 2022 14:53:33 -0500 Subject: [PATCH 0283/1076] Decrease MAX_POOL_SIZE in huge_pool test to make it work with rust 1.65 (#3909) --- program/tests/huge_pool.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index a82fbed9..ad1ac200 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -25,7 +25,7 @@ use { // the test require so many helper accounts. // 20k is also a very safe number for the current upper bound of the network. const MAX_POOL_SIZE_WITH_REQUESTED_COMPUTE_UNITS: u32 = 20_000; -const MAX_POOL_SIZE: u32 = 3_300; +const MAX_POOL_SIZE: u32 = 3_000; const STAKE_AMOUNT: u64 = 200_000_000_000; async fn setup( From bcb91ba2099098e53951685109e5b3fd0370d832 Mon Sep 17 00:00:00 2001 From: Jordan Sexton Date: Wed, 14 Dec 2022 19:25:46 -0600 Subject: [PATCH 0284/1076] fix: stake-pool-js: add browser CJS build (#3910) * fix: stake-pool-js: add browser CJS build * update package-lock.json * run prettier * only emit ts declaration files --- clients/js-legacy/package-lock.json | 4 +- clients/js-legacy/package.json | 5 +- clients/js-legacy/rollup.config.js | 132 +++++++++++++--------------- clients/js-legacy/tsconfig.json | 5 +- 4 files changed, 66 insertions(+), 80 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 6550b98c..a7e5e195 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1,12 +1,12 @@ { "name": "@solana/spl-stake-pool", - "version": "0.6.4", + "version": "0.6.5", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@solana/spl-stake-pool", - "version": "0.6.4", + "version": "0.6.5", "license": "ISC", "dependencies": { "@project-serum/borsh": "^0.2.2", diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index e2bc8021..38d5f06d 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-stake-pool", - "version": "0.6.4", + "version": "0.6.5", "description": "SPL Stake Pool Program JS API", "scripts": { "build": "npm run clean && tsc && cross-env NODE_ENV=production rollup -c", @@ -27,7 +27,7 @@ "access": "public" }, "browser": { - "./dist/index.cjs.js": "./dist/index.browser.esm.js", + "./dist/index.cjs.js": "./dist/index.browser.cjs.js", "./dist/index.esm.js": "./dist/index.browser.esm.js" }, "main": "dist/index.cjs.js", @@ -90,4 +90,3 @@ "testEnvironment": "node" } } - diff --git a/clients/js-legacy/rollup.config.js b/clients/js-legacy/rollup.config.js index 03c9c198..f926a9de 100644 --- a/clients/js-legacy/rollup.config.js +++ b/clients/js-legacy/rollup.config.js @@ -31,88 +31,76 @@ function generateConfig(configType, format) { }, }; - if (configType !== 'browser') { - // Prevent dependencies from being bundled - config.external = [ - '@project-serum/borsh', - '@solana/buffer-layout', - '@solana/spl-token', - '@solana/web3.js', - 'bn.js', - 'buffer', - ]; - } + if (browser) { + if (format === 'iife') { + config.external = ['http', 'https']; - switch (configType) { - case 'browser': - switch (format) { - case 'esm': { - config.output = [ - { - file: 'dist/index.browser.esm.js', - format: 'es', - sourcemap: true, - }, - ]; - - // Prevent dependencies from being bundled - config.external = [ - '@project-serum/borsh', - '@solana/buffer-layout', - '@solana/spl-token', - '@solana/web3.js', - 'bn.js', - 'buffer', - ]; - - break; - } - case 'iife': { - config.external = ['http', 'https']; - - config.output = [ - { - file: 'dist/index.iife.js', - format: 'iife', - name: 'solanaStakePool', - sourcemap: true, - }, - { - file: 'dist/index.iife.min.js', - format: 'iife', - name: 'solanaStakePool', - sourcemap: true, - plugins: [terser({ mangle: false, compress: false })], - }, - ]; - - break; - } - default: - throw new Error(`Unknown format: ${format}`); - } - - // TODO: Find a workaround to avoid resolving the following JSON file: - // `node_modules/secp256k1/node_modules/elliptic/package.json` - config.plugins.push(json()); - - break; - case 'node': config.output = [ { - file: 'dist/index.cjs.js', + file: 'dist/index.iife.js', + format: 'iife', + name: 'solanaStakePool', + sourcemap: true, + }, + { + file: 'dist/index.iife.min.js', + format: 'iife', + name: 'solanaStakePool', + sourcemap: true, + plugins: [terser({ mangle: false, compress: false })], + }, + ]; + } else { + config.output = [ + { + file: 'dist/index.browser.cjs.js', format: 'cjs', sourcemap: true, }, { - file: 'dist/index.esm.js', + file: 'dist/index.browser.esm.js', format: 'es', sourcemap: true, }, ]; - break; - default: - throw new Error(`Unknown configType: ${configType}`); + + // Prevent dependencies from being bundled + config.external = [ + '@project-serum/borsh', + '@solana/buffer-layout', + '@solana/spl-token', + '@solana/web3.js', + 'bn.js', + 'buffer', + ]; + } + + // TODO: Find a workaround to avoid resolving the following JSON file: + // `node_modules/secp256k1/node_modules/elliptic/package.json` + config.plugins.push(json()); + } else { + config.output = [ + { + file: 'dist/index.cjs.js', + format: 'cjs', + sourcemap: true, + }, + { + file: 'dist/index.esm.js', + format: 'es', + sourcemap: true, + }, + ]; + + // Prevent dependencies from being bundled + config.external = [ + '@project-serum/borsh', + '@solana/buffer-layout', + '@solana/spl-token', + '@solana/web3.js', + 'bn.js', + 'buffer', + ]; } return config; @@ -120,6 +108,6 @@ function generateConfig(configType, format) { export default [ generateConfig('node'), - generateConfig('browser', 'esm'), + generateConfig('browser'), generateConfig('browser', 'iife'), ]; diff --git a/clients/js-legacy/tsconfig.json b/clients/js-legacy/tsconfig.json index d8b2a264..9e8b3120 100644 --- a/clients/js-legacy/tsconfig.json +++ b/clients/js-legacy/tsconfig.json @@ -6,6 +6,7 @@ "outDir": "dist", "declaration": true, "declarationDir": "dist", + "emitDeclarationOnly": true, "esModuleInterop": true, "allowSyntheticDefaultImports": true, "strict": true, @@ -16,7 +17,5 @@ "noFallthroughCasesInSwitch": true, "noImplicitReturns": true }, - "include": [ - "src/**/*.ts" - ] + "include": ["src/**/*.ts"] } From d98e811583d4d489d31a947709eeec01b6b676b3 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 23 Dec 2022 13:31:41 +0100 Subject: [PATCH 0285/1076] stake-pool: Add "IncreaseAdditionalValidatorStake" instruction (#3924) * stake-pool: Add "IncreaseAdditionalValidatorStake" instruction * Address feedback * Always check transient stake account address --- program/src/instruction.rs | 137 ++++++++++- program/src/lib.rs | 19 ++ program/src/processor.rs | 229 ++++++++++++++---- program/tests/helpers/mod.rs | 98 +++++++- program/tests/increase.rs | 440 ++++++++++++++++++++++++----------- 5 files changed, 738 insertions(+), 185 deletions(-) diff --git a/program/src/instruction.rs b/program/src/instruction.rs index e3c5e965..6d3d6fd5 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -4,8 +4,9 @@ use { crate::{ - find_deposit_authority_program_address, find_stake_program_address, - find_transient_stake_program_address, find_withdraw_authority_program_address, + find_deposit_authority_program_address, find_ephemeral_stake_program_address, + find_stake_program_address, find_transient_stake_program_address, + find_withdraw_authority_program_address, state::{Fee, FeeType, StakePool, ValidatorList}, MAX_VALIDATORS_TO_UPDATE, }, @@ -401,6 +402,46 @@ pub enum StakePoolInstruction { /// URI of the uploaded metadata of the spl-token uri: String, }, + + /// (Staker only) Increase stake on a validator again in an epoch. + /// + /// Works regardless if the transient stake account exists. + /// + /// Internally, this instruction splits reserve stake into an ephemeral stake + /// account, activates it, then merges or splits it into the transient stake + /// account delegated to the appropriate validator. `UpdateValidatorListBalance` + /// will do the work of merging once it's ready. + /// + /// The minimum amount to move is rent-exemption plus + /// `max(crate::MINIMUM_ACTIVE_STAKE, solana_program::stake::tools::get_minimum_delegation())`. + /// + /// 0. `[]` Stake pool + /// 1. `[s]` Stake pool staker + /// 2. `[]` Stake pool withdraw authority + /// 3. `[w]` Validator list + /// 4. `[w]` Stake pool reserve stake + /// 5. `[w]` Uninitialized ephemeral stake account to receive stake + /// 6. `[w]` Transient stake account + /// 7. `[]` Validator stake account + /// 8. `[]` Validator vote account to delegate to + /// 9. '[]' Clock sysvar + /// 10. `[]` Stake History sysvar + /// 11. `[]` Stake Config sysvar + /// 12. `[]` System program + /// 13. `[]` Stake program + /// userdata: amount of lamports to increase on the given validator. + /// The actual amount split into the transient stake account is: + /// `lamports + stake_rent_exemption` + /// The rent-exemption of the stake account is withdrawn back to the reserve + /// after it is merged. + IncreaseAdditionalValidatorStake { + /// amount of lamports to increase on the given validator + lamports: u64, + /// seed used to create transient stake account + transient_stake_seed: u64, + /// seed used to create ephemeral account. + ephemeral_stake_seed: u64, + }, } /// Creates an 'initialize' instruction. @@ -597,6 +638,52 @@ pub fn increase_validator_stake( } } +/// Creates `IncreaseAdditionalValidatorStake` instruction (rebalance from reserve account to +/// transient account) +pub fn increase_additional_validator_stake( + program_id: &Pubkey, + stake_pool: &Pubkey, + staker: &Pubkey, + stake_pool_withdraw_authority: &Pubkey, + validator_list: &Pubkey, + reserve_stake: &Pubkey, + ephemeral_stake: &Pubkey, + transient_stake: &Pubkey, + validator_stake: &Pubkey, + validator: &Pubkey, + lamports: u64, + transient_stake_seed: u64, + ephemeral_stake_seed: u64, +) -> Instruction { + let accounts = vec![ + AccountMeta::new_readonly(*stake_pool, false), + AccountMeta::new_readonly(*staker, true), + AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), + AccountMeta::new(*validator_list, false), + AccountMeta::new(*reserve_stake, false), + AccountMeta::new(*ephemeral_stake, false), + AccountMeta::new(*transient_stake, false), + AccountMeta::new_readonly(*validator_stake, false), + AccountMeta::new_readonly(*validator, false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(sysvar::stake_history::id(), false), + AccountMeta::new_readonly(stake::config::id(), false), + AccountMeta::new_readonly(system_program::id(), false), + AccountMeta::new_readonly(stake::program::id(), false), + ]; + Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::IncreaseAdditionalValidatorStake { + lamports, + transient_stake_seed, + ephemeral_stake_seed, + } + .try_to_vec() + .unwrap(), + } +} + /// Creates `SetPreferredDepositValidator` instruction pub fn set_preferred_validator( program_id: &Pubkey, @@ -724,6 +811,52 @@ pub fn increase_validator_stake_with_vote( ) } +/// Create an `IncreaseAdditionalValidatorStake` instruction given an existing +/// stake pool and vote account +pub fn increase_additional_validator_stake_with_vote( + program_id: &Pubkey, + stake_pool: &StakePool, + stake_pool_address: &Pubkey, + vote_account_address: &Pubkey, + lamports: u64, + validator_stake_seed: Option, + transient_stake_seed: u64, + ephemeral_stake_seed: u64, +) -> Instruction { + let pool_withdraw_authority = + find_withdraw_authority_program_address(program_id, stake_pool_address).0; + let (ephemeral_stake_address, _) = + find_ephemeral_stake_program_address(program_id, stake_pool_address, ephemeral_stake_seed); + let (transient_stake_address, _) = find_transient_stake_program_address( + program_id, + vote_account_address, + stake_pool_address, + transient_stake_seed, + ); + let (validator_stake_address, _) = find_stake_program_address( + program_id, + vote_account_address, + stake_pool_address, + validator_stake_seed, + ); + + increase_additional_validator_stake( + program_id, + stake_pool_address, + &stake_pool.staker, + &pool_withdraw_authority, + &stake_pool.validator_list, + &stake_pool.reserve_stake, + &ephemeral_stake_address, + &transient_stake_address, + &validator_stake_address, + vote_account_address, + lamports, + transient_stake_seed, + ephemeral_stake_seed, + ) +} + /// Create a `DecreaseValidatorStake` instruction given an existing stake pool and /// vote account pub fn decrease_validator_stake_with_vote( diff --git a/program/src/lib.rs b/program/src/lib.rs index e5fbcfaa..66c9dd2c 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -28,6 +28,9 @@ const AUTHORITY_WITHDRAW: &[u8] = b"withdraw"; /// Seed for transient stake account const TRANSIENT_STAKE_SEED_PREFIX: &[u8] = b"transient"; +/// Seed for ephemeral stake account +const EPHEMERAL_STAKE_SEED_PREFIX: &[u8] = b"ephemeral"; + /// Minimum amount of staked lamports required in a validator stake account to allow /// for merges without a mismatch on credits observed pub const MINIMUM_ACTIVE_STAKE: u64 = 1_000_000; @@ -138,6 +141,22 @@ pub fn find_transient_stake_program_address( ) } +/// Generates the ephemeral program address for stake pool redelegation +pub fn find_ephemeral_stake_program_address( + program_id: &Pubkey, + stake_pool_address: &Pubkey, + seed: u64, +) -> (Pubkey, u8) { + Pubkey::find_program_address( + &[ + EPHEMERAL_STAKE_SEED_PREFIX, + stake_pool_address.as_ref(), + &seed.to_le_bytes(), + ], + program_id, + ) +} + solana_program::declare_id!("SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy"); #[cfg(test)] diff --git a/program/src/processor.rs b/program/src/processor.rs index 08caa1cc..6aa9c67b 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -10,7 +10,8 @@ use { is_extension_supported_for_mint, AccountType, Fee, FeeType, StakePool, StakeStatus, StakeWithdrawSource, ValidatorList, ValidatorListHeader, ValidatorStakeInfo, }, - AUTHORITY_DEPOSIT, AUTHORITY_WITHDRAW, TRANSIENT_STAKE_SEED_PREFIX, + AUTHORITY_DEPOSIT, AUTHORITY_WITHDRAW, EPHEMERAL_STAKE_SEED_PREFIX, + TRANSIENT_STAKE_SEED_PREFIX, }, borsh::{BorshDeserialize, BorshSerialize}, mpl_token_metadata::{ @@ -99,6 +100,23 @@ fn check_transient_stake_address( } } +/// Check address validity for an ephemeral stake account +fn check_ephemeral_stake_address( + program_id: &Pubkey, + stake_pool_address: &Pubkey, + stake_account_address: &Pubkey, + seed: u64, +) -> Result { + // Check stake account address validity + let (ephemeral_stake_address, bump_seed) = + crate::find_ephemeral_stake_program_address(program_id, stake_pool_address, seed); + if ephemeral_stake_address != *stake_account_address { + Err(StakePoolError::InvalidStakeAccountAddress.into()) + } else { + Ok(bump_seed) + } +} + /// Check mpl metadata account address for the pool mint fn check_mpl_metadata_account_address( metadata_address: &Pubkey, @@ -1262,6 +1280,7 @@ impl Processor { accounts: &[AccountInfo], lamports: u64, transient_stake_seed: u64, + maybe_ephemeral_stake_seed: Option, ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; @@ -1269,13 +1288,22 @@ impl Processor { let withdraw_authority_info = next_account_info(account_info_iter)?; let validator_list_info = next_account_info(account_info_iter)?; let reserve_stake_account_info = next_account_info(account_info_iter)?; + let maybe_ephemeral_stake_account_info = maybe_ephemeral_stake_seed + .map(|_| next_account_info(account_info_iter)) + .transpose()?; let transient_stake_account_info = next_account_info(account_info_iter)?; let validator_stake_account_info = next_account_info(account_info_iter)?; let validator_vote_account_info = next_account_info(account_info_iter)?; let clock_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(clock_info)?; - let rent_info = next_account_info(account_info_iter)?; - let rent = &Rent::from_account_info(rent_info)?; + let rent = if maybe_ephemeral_stake_seed.is_some() { + // instruction with ephemeral account doesn't take the rent account + Rent::get()? + } else { + // legacy instruction takes the rent account + let rent_info = next_account_info(account_info_iter)?; + Rent::from_account_info(rent_info)? + }; let stake_history_info = next_account_info(account_info_iter)?; let stake_config_info = next_account_info(account_info_iter)?; let system_program_info = next_account_info(account_info_iter)?; @@ -1327,7 +1355,19 @@ impl Processor { } let mut validator_stake_info = maybe_validator_stake_info.unwrap(); if validator_stake_info.transient_stake_lamports > 0 { - return Err(StakePoolError::TransientAccountInUse.into()); + if maybe_ephemeral_stake_seed.is_none() { + msg!("Attempting to increase stake on a validator with pending transient stake, use IncreaseAdditionalValidatorStake with the existing seed"); + return Err(StakePoolError::TransientAccountInUse.into()); + } + if transient_stake_seed != validator_stake_info.transient_seed_suffix { + msg!( + "Transient stake already exists with seed {}, you must use that one", + validator_stake_info.transient_seed_suffix + ); + return Err(ProgramError::InvalidSeeds); + } + // Let the runtime check to see if the merge is valid, so there's no + // explicit check here that the transient stake is increasing } // Check that the validator stake account is actually delegated to the right @@ -1357,21 +1397,6 @@ impl Processor { } } - let transient_stake_bump_seed = check_transient_stake_address( - program_id, - stake_pool_info.key, - transient_stake_account_info.key, - vote_account_address, - transient_stake_seed, - )?; - let transient_stake_account_signer_seeds: &[&[_]] = &[ - TRANSIENT_STAKE_SEED_PREFIX, - &vote_account_address.to_bytes(), - &stake_pool_info.key.to_bytes(), - &transient_stake_seed.to_le_bytes(), - &[transient_stake_bump_seed], - ]; - if validator_stake_info.status != StakeStatus::Active { msg!("Validator is marked for removal and no longer allows increases"); return Err(StakePoolError::ValidatorNotFound.into()); @@ -1410,37 +1435,136 @@ impl Processor { return Err(ProgramError::InsufficientFunds); } - create_stake_account( - transient_stake_account_info.clone(), - transient_stake_account_signer_seeds, - system_program_info.clone(), - )?; + let source_stake_account_info = + if let Some((ephemeral_stake_seed, ephemeral_stake_account_info)) = + maybe_ephemeral_stake_seed.zip(maybe_ephemeral_stake_account_info) + { + let ephemeral_stake_bump_seed = check_ephemeral_stake_address( + program_id, + stake_pool_info.key, + ephemeral_stake_account_info.key, + ephemeral_stake_seed, + )?; + let ephemeral_stake_account_signer_seeds: &[&[_]] = &[ + EPHEMERAL_STAKE_SEED_PREFIX, + &stake_pool_info.key.to_bytes(), + &ephemeral_stake_seed.to_le_bytes(), + &[ephemeral_stake_bump_seed], + ]; + create_stake_account( + ephemeral_stake_account_info.clone(), + ephemeral_stake_account_signer_seeds, + system_program_info.clone(), + )?; - // split into transient stake account - Self::stake_split( - stake_pool_info.key, - reserve_stake_account_info.clone(), - withdraw_authority_info.clone(), - AUTHORITY_WITHDRAW, - stake_pool.stake_withdraw_bump_seed, - total_lamports, - transient_stake_account_info.clone(), - )?; + // split into ephemeral stake account + Self::stake_split( + stake_pool_info.key, + reserve_stake_account_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + total_lamports, + ephemeral_stake_account_info.clone(), + )?; - // activate transient stake to validator - Self::stake_delegate( - transient_stake_account_info.clone(), - validator_vote_account_info.clone(), - clock_info.clone(), - stake_history_info.clone(), - stake_config_info.clone(), - withdraw_authority_info.clone(), + // activate stake to validator + Self::stake_delegate( + ephemeral_stake_account_info.clone(), + validator_vote_account_info.clone(), + clock_info.clone(), + stake_history_info.clone(), + stake_config_info.clone(), + withdraw_authority_info.clone(), + stake_pool_info.key, + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + )?; + ephemeral_stake_account_info + } else { + // if no ephemeral account is provided, split everything from the + // reserve account, into the transient stake account + reserve_stake_account_info + }; + + let transient_stake_bump_seed = check_transient_stake_address( + program_id, stake_pool_info.key, - AUTHORITY_WITHDRAW, - stake_pool.stake_withdraw_bump_seed, + transient_stake_account_info.key, + vote_account_address, + transient_stake_seed, )?; - validator_stake_info.transient_stake_lamports = total_lamports; + if validator_stake_info.transient_stake_lamports > 0 { + // transient stake exists, try to merge from the source account, + // which is always an ephemeral account + Self::stake_merge( + stake_pool_info.key, + source_stake_account_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + transient_stake_account_info.clone(), + clock_info.clone(), + stake_history_info.clone(), + stake_program_info.clone(), + )?; + } else { + // no transient stake, split + let transient_stake_account_signer_seeds: &[&[_]] = &[ + TRANSIENT_STAKE_SEED_PREFIX, + &vote_account_address.to_bytes(), + &stake_pool_info.key.to_bytes(), + &transient_stake_seed.to_le_bytes(), + &[transient_stake_bump_seed], + ]; + + create_stake_account( + transient_stake_account_info.clone(), + transient_stake_account_signer_seeds, + system_program_info.clone(), + )?; + + // split into transient stake account + Self::stake_split( + stake_pool_info.key, + source_stake_account_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + total_lamports, + transient_stake_account_info.clone(), + )?; + + // Activate transient stake to validator if necessary + let stake_state = try_from_slice_unchecked::( + &transient_stake_account_info.data.borrow(), + )?; + match stake_state { + // if it was delegated on or before this epoch, we're good + stake::state::StakeState::Stake(_, stake) + if stake.delegation.activation_epoch <= clock.epoch => {} + // all other situations, delegate! + _ => { + Self::stake_delegate( + transient_stake_account_info.clone(), + validator_vote_account_info.clone(), + clock_info.clone(), + stake_history_info.clone(), + stake_config_info.clone(), + withdraw_authority_info.clone(), + stake_pool_info.key, + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + )?; + } + } + } + + validator_stake_info.transient_stake_lamports = validator_stake_info + .transient_stake_lamports + .checked_add(total_lamports) + .ok_or(StakePoolError::CalculationFailure)?; validator_stake_info.transient_seed_suffix = transient_stake_seed; Ok(()) @@ -3136,6 +3260,21 @@ impl Processor { accounts, lamports, transient_stake_seed, + None, + ) + } + StakePoolInstruction::IncreaseAdditionalValidatorStake { + lamports, + transient_stake_seed, + ephemeral_stake_seed, + } => { + msg!("Instruction: IncreaseAdditionalValidatorStake"); + Self::process_increase_validator_stake( + program_id, + accounts, + lamports, + transient_stake_seed, + Some(ephemeral_stake_seed), ) } StakePoolInstruction::SetPreferredValidator { diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index a9db0f78..dd032e7c 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -26,9 +26,9 @@ use { vote_state::{VoteInit, VoteState, VoteStateVersions}, }, spl_stake_pool::{ - find_deposit_authority_program_address, find_stake_program_address, - find_transient_stake_program_address, find_withdraw_authority_program_address, id, - instruction, minimum_delegation, + find_deposit_authority_program_address, find_ephemeral_stake_program_address, + find_stake_program_address, find_transient_stake_program_address, + find_withdraw_authority_program_address, id, instruction, minimum_delegation, processor::Processor, state::{self, FeeType, StakePool, ValidatorList}, MINIMUM_RESERVE_LAMPORTS, @@ -1501,6 +1501,98 @@ impl StakePoolAccounts { .err() } + #[allow(clippy::too_many_arguments)] + pub async fn increase_additional_validator_stake( + &self, + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + ephemeral_stake: &Pubkey, + transient_stake: &Pubkey, + validator_stake: &Pubkey, + validator: &Pubkey, + lamports: u64, + transient_stake_seed: u64, + ephemeral_stake_seed: u64, + ) -> Option { + let mut instructions = vec![instruction::increase_additional_validator_stake( + &id(), + &self.stake_pool.pubkey(), + &self.staker.pubkey(), + &self.withdraw_authority, + &self.validator_list.pubkey(), + &self.reserve_stake.pubkey(), + ephemeral_stake, + transient_stake, + validator_stake, + validator, + lamports, + transient_stake_seed, + ephemeral_stake_seed, + )]; + self.maybe_add_compute_budget_instruction(&mut instructions); + let transaction = Transaction::new_signed_with_payer( + &instructions, + Some(&payer.pubkey()), + &[payer, &self.staker], + *recent_blockhash, + ); + banks_client + .process_transaction(transaction) + .await + .map_err(|e| e.into()) + .err() + } + + #[allow(clippy::too_many_arguments)] + pub async fn increase_validator_stake_either( + &self, + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + transient_stake: &Pubkey, + validator_stake: &Pubkey, + validator: &Pubkey, + lamports: u64, + transient_stake_seed: u64, + use_additional_instruction: bool, + ) -> Option { + if use_additional_instruction { + let ephemeral_stake_seed = 0; + let ephemeral_stake = find_ephemeral_stake_program_address( + &id(), + &self.stake_pool.pubkey(), + ephemeral_stake_seed, + ) + .0; + self.increase_additional_validator_stake( + banks_client, + payer, + recent_blockhash, + &ephemeral_stake, + transient_stake, + validator_stake, + validator, + lamports, + transient_stake_seed, + ephemeral_stake_seed, + ) + .await + } else { + self.increase_validator_stake( + banks_client, + payer, + recent_blockhash, + transient_stake, + validator_stake, + validator, + lamports, + transient_stake_seed, + ) + .await + } + } + pub async fn set_preferred_validator( &self, banks_client: &mut BanksClient, diff --git a/program/tests/increase.rs b/program/tests/increase.rs index 4bc69f75..7967907c 100644 --- a/program/tests/increase.rs +++ b/program/tests/increase.rs @@ -6,120 +6,118 @@ mod helpers; use { bincode::deserialize, helpers::*, - solana_program::{ - clock::Epoch, hash::Hash, instruction::InstructionError, pubkey::Pubkey, stake, - }, + solana_program::{clock::Epoch, instruction::InstructionError, pubkey::Pubkey, stake}, solana_program_test::*, solana_sdk::{ - signature::{Keypair, Signer}, + signature::Signer, stake::instruction::StakeError, transaction::{Transaction, TransactionError}, }, spl_stake_pool::{ - error::StakePoolError, find_transient_stake_program_address, id, instruction, - MINIMUM_RESERVE_LAMPORTS, + error::StakePoolError, find_ephemeral_stake_program_address, + find_transient_stake_program_address, id, instruction, MINIMUM_RESERVE_LAMPORTS, }, + test_case::test_case, }; async fn setup() -> ( - BanksClient, - Keypair, - Hash, + ProgramTestContext, StakePoolAccounts, ValidatorStakeAccount, u64, ) { - let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let mut context = program_test().start_with_context().await; let stake_pool_accounts = StakePoolAccounts::default(); let reserve_lamports = 100_000_000_000 + MINIMUM_RESERVE_LAMPORTS; stake_pool_accounts .initialize_stake_pool( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, reserve_lamports, ) .await .unwrap(); let validator_stake_account = simple_add_validator_to_pool( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &stake_pool_accounts, None, ) .await; - let current_minimum_delegation = - stake_pool_get_minimum_delegation(&mut banks_client, &payer, &recent_blockhash).await; + let current_minimum_delegation = stake_pool_get_minimum_delegation( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; + let rent = context.banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let _deposit_info = simple_deposit_stake( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &stake_pool_accounts, &validator_stake_account, - current_minimum_delegation, + current_minimum_delegation * 2 + stake_rent, ) .await .unwrap(); ( - banks_client, - payer, - recent_blockhash, + context, stake_pool_accounts, validator_stake_account, reserve_lamports, ) } +#[test_case(true; "additional")] +#[test_case(false; "non-additional")] #[tokio::test] -async fn success() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - validator_stake, - reserve_lamports, - ) = setup().await; +async fn success(use_additional_instruction: bool) { + let (mut context, stake_pool_accounts, validator_stake, reserve_lamports) = setup().await; // Save reserve stake let pre_reserve_stake_account = get_account( - &mut banks_client, + &mut context.banks_client, &stake_pool_accounts.reserve_stake.pubkey(), ) .await; // Check no transient stake - let transient_account = banks_client + let transient_account = context + .banks_client .get_account(validator_stake.transient_stake_account) .await .unwrap(); assert!(transient_account.is_none()); - let rent = banks_client.get_rent().await.unwrap(); + let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); let increase_amount = reserve_lamports - stake_rent - MINIMUM_RESERVE_LAMPORTS; let error = stake_pool_accounts - .increase_validator_stake( - &mut banks_client, - &payer, - &recent_blockhash, + .increase_validator_stake_either( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &validator_stake.transient_stake_account, &validator_stake.stake_account, &validator_stake.vote.pubkey(), increase_amount, validator_stake.transient_stake_seed, + use_additional_instruction, ) .await; assert!(error.is_none()); // Check reserve stake account balance let reserve_stake_account = get_account( - &mut banks_client, + &mut context.banks_client, &stake_pool_accounts.reserve_stake.pubkey(), ) .await; @@ -132,8 +130,11 @@ async fn success() { assert!(reserve_stake_state.delegation().is_none()); // Check transient stake account state and balance - let transient_stake_account = - get_account(&mut banks_client, &validator_stake.transient_stake_account).await; + let transient_stake_account = get_account( + &mut context.banks_client, + &validator_stake.transient_stake_account, + ) + .await; let transient_stake_state = deserialize::(&transient_stake_account.data).unwrap(); assert_eq!( @@ -148,14 +149,7 @@ async fn success() { #[tokio::test] async fn fail_with_wrong_withdraw_authority() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - validator_stake, - reserve_lamports, - ) = setup().await; + let (mut context, stake_pool_accounts, validator_stake, reserve_lamports) = setup().await; let wrong_authority = Pubkey::new_unique(); @@ -173,11 +167,12 @@ async fn fail_with_wrong_withdraw_authority() { reserve_lamports / 2, validator_stake.transient_stake_seed, )], - Some(&payer.pubkey()), - &[&payer, &stake_pool_accounts.staker], - recent_blockhash, + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.staker], + context.last_blockhash, ); - let error = banks_client + let error = context + .banks_client .process_transaction(transaction) .await .err() @@ -195,14 +190,7 @@ async fn fail_with_wrong_withdraw_authority() { #[tokio::test] async fn fail_with_wrong_validator_list() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - validator_stake, - reserve_lamports, - ) = setup().await; + let (mut context, stake_pool_accounts, validator_stake, reserve_lamports) = setup().await; let wrong_validator_list = Pubkey::new_unique(); @@ -220,11 +208,12 @@ async fn fail_with_wrong_validator_list() { reserve_lamports / 2, validator_stake.transient_stake_seed, )], - Some(&payer.pubkey()), - &[&payer, &stake_pool_accounts.staker], - recent_blockhash, + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.staker], + context.last_blockhash, ); - let error = banks_client + let error = context + .banks_client .process_transaction(transaction) .await .err() @@ -242,19 +231,12 @@ async fn fail_with_wrong_validator_list() { #[tokio::test] async fn fail_with_unknown_validator() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - _validator_stake, - reserve_lamports, - ) = setup().await; + let (mut context, stake_pool_accounts, _validator_stake, reserve_lamports) = setup().await; let unknown_stake = create_unknown_validator_stake( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &stake_pool_accounts.stake_pool.pubkey(), ) .await; @@ -273,11 +255,12 @@ async fn fail_with_unknown_validator() { reserve_lamports / 2, unknown_stake.transient_stake_seed, )], - Some(&payer.pubkey()), - &[&payer, &stake_pool_accounts.staker], - recent_blockhash, + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.staker], + context.last_blockhash, ); - let error = banks_client + let error = context + .banks_client .process_transaction(transaction) .await .err() @@ -293,27 +276,25 @@ async fn fail_with_unknown_validator() { ); } +#[test_case(true; "additional")] +#[test_case(false; "non-additional")] #[tokio::test] -async fn fail_increase_twice() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - validator_stake, - reserve_lamports, - ) = setup().await; +async fn fail_twice_diff_seed(use_additional_instruction: bool) { + let (mut context, stake_pool_accounts, validator_stake, reserve_lamports) = setup().await; + let first_increase = reserve_lamports / 3; + let second_increase = reserve_lamports / 4; let error = stake_pool_accounts - .increase_validator_stake( - &mut banks_client, - &payer, - &recent_blockhash, + .increase_validator_stake_either( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &validator_stake.transient_stake_account, &validator_stake.stake_account, &validator_stake.vote.pubkey(), - reserve_lamports / 3, + first_increase, validator_stake.transient_stake_seed, + use_additional_instruction, ) .await; assert!(error.is_none()); @@ -327,52 +308,176 @@ async fn fail_increase_twice() { ) .0; let error = stake_pool_accounts - .increase_validator_stake( - &mut banks_client, - &payer, - &recent_blockhash, + .increase_validator_stake_either( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &transient_stake_address, &validator_stake.stake_account, &validator_stake.vote.pubkey(), - reserve_lamports / 4, + second_increase, transient_stake_seed, + use_additional_instruction, ) .await .unwrap() .unwrap(); - match error { - TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { - let program_error = StakePoolError::TransientAccountInUse as u32; - assert_eq!(error_index, program_error); + + if use_additional_instruction { + assert_eq!( + error, + TransactionError::InstructionError(0, InstructionError::InvalidSeeds) + ); + } else { + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::TransientAccountInUse as u32) + ) + ); + } +} + +#[test_case(true, true, true; "success-all-additional")] +#[test_case(true, false, true; "success-with-additional")] +#[test_case(false, true, false; "fail-without-additional")] +#[test_case(false, false, false; "fail-no-additional")] +#[tokio::test] +async fn twice(success: bool, use_additional_first_time: bool, use_additional_second_time: bool) { + let (mut context, stake_pool_accounts, validator_stake, reserve_lamports) = setup().await; + + let pre_reserve_stake_account = get_account( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + ) + .await; + + let first_increase = reserve_lamports / 3; + let second_increase = reserve_lamports / 4; + let total_increase = first_increase + second_increase; + let error = stake_pool_accounts + .increase_validator_stake_either( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &validator_stake.transient_stake_account, + &validator_stake.stake_account, + &validator_stake.vote.pubkey(), + first_increase, + validator_stake.transient_stake_seed, + use_additional_first_time, + ) + .await; + assert!(error.is_none()); + + let error = stake_pool_accounts + .increase_validator_stake_either( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &validator_stake.transient_stake_account, + &validator_stake.stake_account, + &validator_stake.vote.pubkey(), + second_increase, + validator_stake.transient_stake_seed, + use_additional_second_time, + ) + .await; + + if success { + assert!(error.is_none()); + let rent = context.banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + // no ephemeral account + let ephemeral_stake = find_ephemeral_stake_program_address( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + 0, + ) + .0; + let ephemeral_account = context + .banks_client + .get_account(ephemeral_stake) + .await + .unwrap(); + assert!(ephemeral_account.is_none()); + // Check reserve stake account balance + let reserve_stake_account = get_account( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + ) + .await; + let reserve_stake_state = + deserialize::(&reserve_stake_account.data).unwrap(); + assert_eq!( + pre_reserve_stake_account.lamports - total_increase - stake_rent * 2, + reserve_stake_account.lamports + ); + assert!(reserve_stake_state.delegation().is_none()); + + // Check transient stake account state and balance + let transient_stake_account = get_account( + &mut context.banks_client, + &validator_stake.transient_stake_account, + ) + .await; + let transient_stake_state = + deserialize::(&transient_stake_account.data).unwrap(); + assert_eq!( + transient_stake_account.lamports, + total_increase + stake_rent * 2 + ); + assert_ne!( + transient_stake_state.delegation().unwrap().activation_epoch, + Epoch::MAX + ); + + // marked correctly in the list + let validator_list = stake_pool_accounts + .get_validator_list(&mut context.banks_client) + .await; + let entry = validator_list.find(&validator_stake.vote.pubkey()).unwrap(); + assert_eq!( + entry.transient_stake_lamports, + total_increase + stake_rent * 2 + ); + } else { + let error = error.unwrap().unwrap(); + match error { + TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { + let program_error = StakePoolError::TransientAccountInUse as u32; + assert_eq!(error_index, program_error); + } + _ => panic!("Wrong error"), } - _ => panic!("Wrong error"), } } +#[test_case(true; "additional")] +#[test_case(false; "non-additional")] #[tokio::test] -async fn fail_with_small_lamport_amount() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - validator_stake, - _reserve_lamports, - ) = setup().await; +async fn fail_with_small_lamport_amount(use_additional_instruction: bool) { + let (mut context, stake_pool_accounts, validator_stake, _reserve_lamports) = setup().await; - let current_minimum_delegation = - stake_pool_get_minimum_delegation(&mut banks_client, &payer, &recent_blockhash).await; + let current_minimum_delegation = stake_pool_get_minimum_delegation( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; let error = stake_pool_accounts - .increase_validator_stake( - &mut banks_client, - &payer, - &recent_blockhash, + .increase_validator_stake_either( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &validator_stake.transient_stake_account, &validator_stake.stake_account, &validator_stake.vote.pubkey(), current_minimum_delegation - 1, validator_stake.transient_stake_seed, + use_additional_instruction, ) .await .unwrap() @@ -387,27 +492,23 @@ async fn fail_with_small_lamport_amount() { } } +#[test_case(true; "additional")] +#[test_case(false; "non-additional")] #[tokio::test] -async fn fail_overdraw_reserve() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - validator_stake, - reserve_lamports, - ) = setup().await; +async fn fail_overdraw_reserve(use_additional_instruction: bool) { + let (mut context, stake_pool_accounts, validator_stake, reserve_lamports) = setup().await; let error = stake_pool_accounts - .increase_validator_stake( - &mut banks_client, - &payer, - &recent_blockhash, + .increase_validator_stake_either( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &validator_stake.transient_stake_account, &validator_stake.stake_account, &validator_stake.vote.pubkey(), reserve_lamports, validator_stake.transient_stake_seed, + use_additional_instruction, ) .await .unwrap() @@ -419,5 +520,74 @@ async fn fail_overdraw_reserve() { } } +#[tokio::test] +async fn fail_additional_with_decreasing() { + let (mut context, stake_pool_accounts, validator_stake, reserve_lamports) = setup().await; + + let current_minimum_delegation = stake_pool_get_minimum_delegation( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; + let rent = context.banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + + // warp forward to activation + let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; + context.warp_to_slot(first_normal_slot).unwrap(); + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&context.last_blockhash) + .await + .unwrap(); + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &last_blockhash, + &[validator_stake.vote.pubkey()], + false, + ) + .await; + + let error = stake_pool_accounts + .decrease_validator_stake( + &mut context.banks_client, + &context.payer, + &last_blockhash, + &validator_stake.stake_account, + &validator_stake.transient_stake_account, + current_minimum_delegation + stake_rent, + validator_stake.transient_stake_seed, + ) + .await; + assert!(error.is_none()); + + let error = stake_pool_accounts + .increase_validator_stake_either( + &mut context.banks_client, + &context.payer, + &last_blockhash, + &validator_stake.transient_stake_account, + &validator_stake.stake_account, + &validator_stake.vote.pubkey(), + reserve_lamports / 2, + validator_stake.transient_stake_seed, + true, + ) + .await + .unwrap() + .unwrap(); + + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakeError::MergeTransientStake as u32) + ) + ); +} + #[tokio::test] async fn fail_with_force_destaked_validator() {} From 5a8ae986a1f0a736e891f8543c3634d75d75587a Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 23 Dec 2022 17:27:16 +0100 Subject: [PATCH 0286/1076] stake-pool: Add `DecreaseAdditionalValidatorStake` instruction (#3925) * stake-pool: Add `DecreaseAdditionalValidatorStake` instruction * Update checks for deduping --- program/src/instruction.rs | 115 +++++++++ program/src/processor.rs | 195 +++++++++++---- program/tests/decrease.rs | 456 +++++++++++++++++++++++------------ program/tests/helpers/mod.rs | 86 +++++++ 4 files changed, 654 insertions(+), 198 deletions(-) diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 6d3d6fd5..ad468443 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -442,6 +442,37 @@ pub enum StakePoolInstruction { /// seed used to create ephemeral account. ephemeral_stake_seed: u64, }, + + /// (Staker only) Decrease active stake again from a validator, eventually moving it to the reserve + /// + /// Works regardless if the transient stake account already exists. + /// + /// Internally, this instruction splits a validator stake account into an + /// ephemeral stake account, deactivates it, then merges or splits it into + /// the transient stake account delegated to the appropriate validator. + /// + /// The amount of lamports to move must be at least rent-exemption plus + /// `max(crate::MINIMUM_ACTIVE_STAKE, solana_program::stake::tools::get_minimum_delegation())`. + /// + /// 0. `[]` Stake pool + /// 1. `[s]` Stake pool staker + /// 2. `[]` Stake pool withdraw authority + /// 3. `[w]` Validator list + /// 4. `[w]` Canonical stake account to split from + /// 5. `[w]` Uninitialized ephemeral stake account to receive stake + /// 6. `[w]` Transient stake account + /// 7. `[]` Clock sysvar + /// 8. '[]' Stake history sysvar + /// 9. `[]` System program + /// 10. `[]` Stake program + DecreaseAdditionalValidatorStake { + /// amount of lamports to split into the transient stake account + lamports: u64, + /// seed used to create transient stake account + transient_stake_seed: u64, + /// seed used to create ephemeral account. + ephemeral_stake_seed: u64, + }, } /// Creates an 'initialize' instruction. @@ -595,6 +626,47 @@ pub fn decrease_validator_stake( } } +/// Creates `DecreaseAdditionalValidatorStake` instruction (rebalance from +/// validator account to transient account) +pub fn decrease_additional_validator_stake( + program_id: &Pubkey, + stake_pool: &Pubkey, + staker: &Pubkey, + stake_pool_withdraw_authority: &Pubkey, + validator_list: &Pubkey, + validator_stake: &Pubkey, + ephemeral_stake: &Pubkey, + transient_stake: &Pubkey, + lamports: u64, + transient_stake_seed: u64, + ephemeral_stake_seed: u64, +) -> Instruction { + let accounts = vec![ + AccountMeta::new_readonly(*stake_pool, false), + AccountMeta::new_readonly(*staker, true), + AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), + AccountMeta::new(*validator_list, false), + AccountMeta::new(*validator_stake, false), + AccountMeta::new(*ephemeral_stake, false), + AccountMeta::new(*transient_stake, false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(sysvar::stake_history::id(), false), + AccountMeta::new_readonly(system_program::id(), false), + AccountMeta::new_readonly(stake::program::id(), false), + ]; + Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::DecreaseAdditionalValidatorStake { + lamports, + transient_stake_seed, + ephemeral_stake_seed, + } + .try_to_vec() + .unwrap(), + } +} + /// Creates `IncreaseValidatorStake` instruction (rebalance from reserve account to /// transient account) pub fn increase_validator_stake( @@ -895,6 +967,49 @@ pub fn decrease_validator_stake_with_vote( ) } +/// Create a `DecreaseAdditionalValidatorStake` instruction given an existing +/// stake pool and vote account +pub fn decrease_additional_validator_stake_with_vote( + program_id: &Pubkey, + stake_pool: &StakePool, + stake_pool_address: &Pubkey, + vote_account_address: &Pubkey, + lamports: u64, + validator_stake_seed: Option, + transient_stake_seed: u64, + ephemeral_stake_seed: u64, +) -> Instruction { + let pool_withdraw_authority = + find_withdraw_authority_program_address(program_id, stake_pool_address).0; + let (validator_stake_address, _) = find_stake_program_address( + program_id, + vote_account_address, + stake_pool_address, + validator_stake_seed, + ); + let (ephemeral_stake_address, _) = + find_ephemeral_stake_program_address(program_id, stake_pool_address, ephemeral_stake_seed); + let (transient_stake_address, _) = find_transient_stake_program_address( + program_id, + vote_account_address, + stake_pool_address, + transient_stake_seed, + ); + decrease_additional_validator_stake( + program_id, + stake_pool_address, + &stake_pool.staker, + &pool_withdraw_authority, + &stake_pool.validator_list, + &validator_stake_address, + &ephemeral_stake_address, + &transient_stake_address, + lamports, + transient_stake_seed, + ephemeral_stake_seed, + ) +} + /// Creates `UpdateValidatorListBalance` instruction (update validator stake account balances) pub fn update_validator_list_balance( program_id: &Pubkey, diff --git a/program/src/processor.rs b/program/src/processor.rs index 6aa9c67b..761272e1 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1124,6 +1124,7 @@ impl Processor { accounts: &[AccountInfo], lamports: u64, transient_stake_seed: u64, + maybe_ephemeral_stake_seed: Option, ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; @@ -1131,11 +1132,23 @@ impl Processor { let withdraw_authority_info = next_account_info(account_info_iter)?; let validator_list_info = next_account_info(account_info_iter)?; let validator_stake_account_info = next_account_info(account_info_iter)?; + let maybe_ephemeral_stake_account_info = maybe_ephemeral_stake_seed + .map(|_| next_account_info(account_info_iter)) + .transpose()?; let transient_stake_account_info = next_account_info(account_info_iter)?; let clock_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(clock_info)?; - let rent_info = next_account_info(account_info_iter)?; - let rent = &Rent::from_account_info(rent_info)?; + let rent = if maybe_ephemeral_stake_seed.is_some() { + // instruction with ephemeral account doesn't take the rent account + Rent::get()? + } else { + // legacy instruction takes the rent account + let rent_info = next_account_info(account_info_iter)?; + Rent::from_account_info(rent_info)? + }; + let maybe_stake_history_info = maybe_ephemeral_stake_seed + .map(|_| next_account_info(account_info_iter)) + .transpose()?; let system_program_info = next_account_info(account_info_iter)?; let stake_program_info = next_account_info(account_info_iter)?; @@ -1191,24 +1204,21 @@ impl Processor { NonZeroU32::new(validator_stake_info.validator_seed_suffix), )?; if validator_stake_info.transient_stake_lamports > 0 { - return Err(StakePoolError::TransientAccountInUse.into()); + if maybe_ephemeral_stake_seed.is_none() { + msg!("Attempting to decrease stake on a validator with pending transient stake, use DecreaseAdditionalValidatorStake with the existing seed"); + return Err(StakePoolError::TransientAccountInUse.into()); + } + if transient_stake_seed != validator_stake_info.transient_seed_suffix { + msg!( + "Transient stake already exists with seed {}, you must use that one", + validator_stake_info.transient_seed_suffix + ); + return Err(ProgramError::InvalidSeeds); + } + // Let the runtime check to see if the merge is valid, so there's no + // explicit check here that the transient stake is decreasing } - let transient_stake_bump_seed = check_transient_stake_address( - program_id, - stake_pool_info.key, - transient_stake_account_info.key, - &vote_account_address, - transient_stake_seed, - )?; - let transient_stake_account_signer_seeds: &[&[_]] = &[ - TRANSIENT_STAKE_SEED_PREFIX, - &vote_account_address.to_bytes(), - &stake_pool_info.key.to_bytes(), - &transient_stake_seed.to_le_bytes(), - &[transient_stake_bump_seed], - ]; - let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; let stake_rent = rent.minimum_balance(std::mem::size_of::()); let current_minimum_lamports = @@ -1236,38 +1246,126 @@ impl Processor { return Err(ProgramError::InsufficientFunds); } - create_stake_account( - transient_stake_account_info.clone(), - transient_stake_account_signer_seeds, - system_program_info.clone(), - )?; + let source_stake_account_info = + if let Some((ephemeral_stake_seed, ephemeral_stake_account_info)) = + maybe_ephemeral_stake_seed.zip(maybe_ephemeral_stake_account_info) + { + let ephemeral_stake_bump_seed = check_ephemeral_stake_address( + program_id, + stake_pool_info.key, + ephemeral_stake_account_info.key, + ephemeral_stake_seed, + )?; + let ephemeral_stake_account_signer_seeds: &[&[_]] = &[ + EPHEMERAL_STAKE_SEED_PREFIX, + &stake_pool_info.key.to_bytes(), + &ephemeral_stake_seed.to_le_bytes(), + &[ephemeral_stake_bump_seed], + ]; + create_stake_account( + ephemeral_stake_account_info.clone(), + ephemeral_stake_account_signer_seeds, + system_program_info.clone(), + )?; - // split into transient stake account - Self::stake_split( - stake_pool_info.key, - validator_stake_account_info.clone(), - withdraw_authority_info.clone(), - AUTHORITY_WITHDRAW, - stake_pool.stake_withdraw_bump_seed, - lamports, - transient_stake_account_info.clone(), - )?; + // split into ephemeral stake account + Self::stake_split( + stake_pool_info.key, + validator_stake_account_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + lamports, + ephemeral_stake_account_info.clone(), + )?; - // deactivate transient stake - Self::stake_deactivate( - transient_stake_account_info.clone(), - clock_info.clone(), - withdraw_authority_info.clone(), + Self::stake_deactivate( + ephemeral_stake_account_info.clone(), + clock_info.clone(), + withdraw_authority_info.clone(), + stake_pool_info.key, + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + )?; + + ephemeral_stake_account_info + } else { + // if no ephemeral account is provided, split everything from the + // validator stake account, into the transient stake account + validator_stake_account_info + }; + + let transient_stake_bump_seed = check_transient_stake_address( + program_id, stake_pool_info.key, - AUTHORITY_WITHDRAW, - stake_pool.stake_withdraw_bump_seed, + transient_stake_account_info.key, + &vote_account_address, + transient_stake_seed, )?; + if validator_stake_info.transient_stake_lamports > 0 { + let stake_history_info = maybe_stake_history_info.unwrap(); + // transient stake exists, try to merge from the source account, + // which is always an ephemeral account + Self::stake_merge( + stake_pool_info.key, + source_stake_account_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + transient_stake_account_info.clone(), + clock_info.clone(), + stake_history_info.clone(), + stake_program_info.clone(), + )?; + } else { + let transient_stake_account_signer_seeds: &[&[_]] = &[ + TRANSIENT_STAKE_SEED_PREFIX, + &vote_account_address.to_bytes(), + &stake_pool_info.key.to_bytes(), + &transient_stake_seed.to_le_bytes(), + &[transient_stake_bump_seed], + ]; + + create_stake_account( + transient_stake_account_info.clone(), + transient_stake_account_signer_seeds, + system_program_info.clone(), + )?; + + // split into transient stake account + Self::stake_split( + stake_pool_info.key, + source_stake_account_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + lamports, + transient_stake_account_info.clone(), + )?; + + // Deactivate transient stake if necessary + let (_, stake) = get_stake_state(transient_stake_account_info)?; + if stake.delegation.deactivation_epoch == Epoch::MAX { + Self::stake_deactivate( + transient_stake_account_info.clone(), + clock_info.clone(), + withdraw_authority_info.clone(), + stake_pool_info.key, + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + )?; + } + } + validator_stake_info.active_stake_lamports = validator_stake_info .active_stake_lamports .checked_sub(lamports) .ok_or(StakePoolError::CalculationFailure)?; - validator_stake_info.transient_stake_lamports = lamports; + validator_stake_info.transient_stake_lamports = validator_stake_info + .transient_stake_lamports + .checked_add(lamports) + .ok_or(StakePoolError::CalculationFailure)?; validator_stake_info.transient_seed_suffix = transient_stake_seed; Ok(()) @@ -3248,6 +3346,21 @@ impl Processor { accounts, lamports, transient_stake_seed, + None, + ) + } + StakePoolInstruction::DecreaseAdditionalValidatorStake { + lamports, + transient_stake_seed, + ephemeral_stake_seed, + } => { + msg!("Instruction: DecreaseAdditionalValidatorStake"); + Self::process_decrease_validator_stake( + program_id, + accounts, + lamports, + transient_stake_seed, + Some(ephemeral_stake_seed), ) } StakePoolInstruction::IncreaseValidatorStake { diff --git a/program/tests/decrease.rs b/program/tests/decrease.rs index 0c698efb..7d263597 100644 --- a/program/tests/decrease.rs +++ b/program/tests/decrease.rs @@ -6,72 +6,70 @@ mod helpers; use { bincode::deserialize, helpers::*, - solana_program::{ - clock::Epoch, hash::Hash, instruction::InstructionError, pubkey::Pubkey, stake, - }, + solana_program::{clock::Epoch, instruction::InstructionError, pubkey::Pubkey, stake}, solana_program_test::*, solana_sdk::{ signature::{Keypair, Signer}, transaction::{Transaction, TransactionError}, }, spl_stake_pool::{ - error::StakePoolError, find_transient_stake_program_address, id, instruction, - MINIMUM_RESERVE_LAMPORTS, + error::StakePoolError, find_ephemeral_stake_program_address, + find_transient_stake_program_address, id, instruction, MINIMUM_RESERVE_LAMPORTS, }, + test_case::test_case, }; async fn setup() -> ( - BanksClient, - Keypair, - Hash, + ProgramTestContext, StakePoolAccounts, ValidatorStakeAccount, DepositStakeAccount, u64, ) { - let (mut banks_client, payer, recent_blockhash) = program_test().start().await; - let rent = banks_client.get_rent().await.unwrap(); + let mut context = program_test().start_with_context().await; + let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); - let current_minimum_delegation = - stake_pool_get_minimum_delegation(&mut banks_client, &payer, &recent_blockhash).await; + let current_minimum_delegation = stake_pool_get_minimum_delegation( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; let stake_pool_accounts = StakePoolAccounts::default(); stake_pool_accounts .initialize_stake_pool( - &mut banks_client, - &payer, - &recent_blockhash, - MINIMUM_RESERVE_LAMPORTS, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + MINIMUM_RESERVE_LAMPORTS + stake_rent + current_minimum_delegation, ) .await .unwrap(); let validator_stake_account = simple_add_validator_to_pool( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &stake_pool_accounts, None, ) .await; + let decrease_lamports = (current_minimum_delegation + stake_rent) * 3; let deposit_info = simple_deposit_stake( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &stake_pool_accounts, &validator_stake_account, - current_minimum_delegation * 2 + stake_rent, + decrease_lamports, ) .await .unwrap(); - let decrease_lamports = current_minimum_delegation + stake_rent; - ( - banks_client, - payer, - recent_blockhash, + context, stake_pool_accounts, validator_stake_account, deposit_info, @@ -79,45 +77,42 @@ async fn setup() -> ( ) } +#[test_case(true; "additional")] +#[test_case(false; "no-additional")] #[tokio::test] -async fn success() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - validator_stake, - _deposit_info, - decrease_lamports, - ) = setup().await; +async fn success(use_additional_instruction: bool) { + let (mut context, stake_pool_accounts, validator_stake, _deposit_info, decrease_lamports) = + setup().await; // Save validator stake let pre_validator_stake_account = - get_account(&mut banks_client, &validator_stake.stake_account).await; + get_account(&mut context.banks_client, &validator_stake.stake_account).await; // Check no transient stake - let transient_account = banks_client + let transient_account = context + .banks_client .get_account(validator_stake.transient_stake_account) .await .unwrap(); assert!(transient_account.is_none()); let error = stake_pool_accounts - .decrease_validator_stake( - &mut banks_client, - &payer, - &recent_blockhash, + .decrease_validator_stake_either( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &validator_stake.stake_account, &validator_stake.transient_stake_account, decrease_lamports, validator_stake.transient_stake_seed, + use_additional_instruction, ) .await; assert!(error.is_none()); // Check validator stake account balance let validator_stake_account = - get_account(&mut banks_client, &validator_stake.stake_account).await; + get_account(&mut context.banks_client, &validator_stake.stake_account).await; let validator_stake_state = deserialize::(&validator_stake_account.data).unwrap(); assert_eq!( @@ -133,8 +128,11 @@ async fn success() { ); // Check transient stake account state and balance - let transient_stake_account = - get_account(&mut banks_client, &validator_stake.transient_stake_account).await; + let transient_stake_account = get_account( + &mut context.banks_client, + &validator_stake.transient_stake_account, + ) + .await; let transient_stake_state = deserialize::(&transient_stake_account.data).unwrap(); assert_eq!(transient_stake_account.lamports, decrease_lamports); @@ -149,15 +147,8 @@ async fn success() { #[tokio::test] async fn fail_with_wrong_withdraw_authority() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - validator_stake, - _deposit_info, - decrease_lamports, - ) = setup().await; + let (mut context, stake_pool_accounts, validator_stake, _deposit_info, decrease_lamports) = + setup().await; let wrong_authority = Pubkey::new_unique(); @@ -173,11 +164,12 @@ async fn fail_with_wrong_withdraw_authority() { decrease_lamports, validator_stake.transient_stake_seed, )], - Some(&payer.pubkey()), - &[&payer, &stake_pool_accounts.staker], - recent_blockhash, + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.staker], + context.last_blockhash, ); - let error = banks_client + let error = context + .banks_client .process_transaction(transaction) .await .err() @@ -195,15 +187,8 @@ async fn fail_with_wrong_withdraw_authority() { #[tokio::test] async fn fail_with_wrong_validator_list() { - let ( - mut banks_client, - payer, - recent_blockhash, - mut stake_pool_accounts, - validator_stake, - _deposit_info, - decrease_lamports, - ) = setup().await; + let (mut context, mut stake_pool_accounts, validator_stake, _deposit_info, decrease_lamports) = + setup().await; stake_pool_accounts.validator_list = Keypair::new(); @@ -219,11 +204,12 @@ async fn fail_with_wrong_validator_list() { decrease_lamports, validator_stake.transient_stake_seed, )], - Some(&payer.pubkey()), - &[&payer, &stake_pool_accounts.staker], - recent_blockhash, + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.staker], + context.last_blockhash, ); - let error = banks_client + let error = context + .banks_client .process_transaction(transaction) .await .err() @@ -241,20 +227,13 @@ async fn fail_with_wrong_validator_list() { #[tokio::test] async fn fail_with_unknown_validator() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - _validator_stake, - _deposit_info, - decrease_lamports, - ) = setup().await; + let (mut context, stake_pool_accounts, _validator_stake, _deposit_info, decrease_lamports) = + setup().await; let unknown_stake = create_unknown_validator_stake( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &stake_pool_accounts.stake_pool.pubkey(), ) .await; @@ -271,11 +250,12 @@ async fn fail_with_unknown_validator() { decrease_lamports, unknown_stake.transient_stake_seed, )], - Some(&payer.pubkey()), - &[&payer, &stake_pool_accounts.staker], - recent_blockhash, + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.staker], + context.last_blockhash, ); - let error = banks_client + let error = context + .banks_client .process_transaction(transaction) .await .err() @@ -291,27 +271,23 @@ async fn fail_with_unknown_validator() { ); } +#[test_case(true; "additional")] +#[test_case(false; "no-additional")] #[tokio::test] -async fn fail_decrease_twice() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - validator_stake, - _deposit_info, - decrease_lamports, - ) = setup().await; +async fn fail_twice_diff_seed(use_additional_instruction: bool) { + let (mut context, stake_pool_accounts, validator_stake, _deposit_info, decrease_lamports) = + setup().await; let error = stake_pool_accounts - .decrease_validator_stake( - &mut banks_client, - &payer, - &recent_blockhash, + .decrease_validator_stake_either( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &validator_stake.stake_account, &validator_stake.transient_stake_account, - decrease_lamports, + decrease_lamports / 3, validator_stake.transient_stake_seed, + use_additional_instruction, ) .await; assert!(error.is_none()); @@ -325,51 +301,161 @@ async fn fail_decrease_twice() { ) .0; let error = stake_pool_accounts - .decrease_validator_stake( - &mut banks_client, - &payer, - &recent_blockhash, + .decrease_validator_stake_either( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &validator_stake.stake_account, &transient_stake_address, - decrease_lamports, + decrease_lamports / 2, transient_stake_seed, + use_additional_instruction, ) .await .unwrap() .unwrap(); - match error { - TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { - let program_error = StakePoolError::TransientAccountInUse as u32; - assert_eq!(error_index, program_error); - } - _ => panic!("Wrong error"), + if use_additional_instruction { + assert_eq!( + error, + TransactionError::InstructionError(0, InstructionError::InvalidSeeds) + ); + } else { + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::TransientAccountInUse as u32) + ) + ); } } +#[test_case(true, true, true; "success-all-additional")] +#[test_case(true, false, true; "success-with-additional")] +#[test_case(false, true, false; "fail-without-additional")] +#[test_case(false, false, false; "fail-no-additional")] #[tokio::test] -async fn fail_with_small_lamport_amount() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - validator_stake, - _deposit_info, - _decrease_lamports, - ) = setup().await; +async fn twice(success: bool, use_additional_first_time: bool, use_additional_second_time: bool) { + let (mut context, stake_pool_accounts, validator_stake, _deposit_info, decrease_lamports) = + setup().await; + + let pre_stake_account = + get_account(&mut context.banks_client, &validator_stake.stake_account).await; + + let first_decrease = decrease_lamports / 3; + let second_decrease = decrease_lamports / 2; + let total_decrease = first_decrease + second_decrease; + let error = stake_pool_accounts + .decrease_validator_stake_either( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &validator_stake.stake_account, + &validator_stake.transient_stake_account, + first_decrease, + validator_stake.transient_stake_seed, + use_additional_first_time, + ) + .await; + assert!(error.is_none()); + + let error = stake_pool_accounts + .decrease_validator_stake_either( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &validator_stake.stake_account, + &validator_stake.transient_stake_account, + second_decrease, + validator_stake.transient_stake_seed, + use_additional_second_time, + ) + .await; + + if success { + assert!(error.is_none()); + // no ephemeral account + let ephemeral_stake = find_ephemeral_stake_program_address( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + 0, + ) + .0; + let ephemeral_account = context + .banks_client + .get_account(ephemeral_stake) + .await + .unwrap(); + assert!(ephemeral_account.is_none()); + + // Check validator stake account balance + let stake_account = + get_account(&mut context.banks_client, &validator_stake.stake_account).await; + let stake_state = deserialize::(&stake_account.data).unwrap(); + assert_eq!( + pre_stake_account.lamports - total_decrease, + stake_account.lamports + ); + assert_eq!( + stake_state.delegation().unwrap().deactivation_epoch, + Epoch::MAX + ); + + // Check transient stake account state and balance + let transient_stake_account = get_account( + &mut context.banks_client, + &validator_stake.transient_stake_account, + ) + .await; + let transient_stake_state = + deserialize::(&transient_stake_account.data).unwrap(); + assert_eq!(transient_stake_account.lamports, total_decrease); + assert_ne!( + transient_stake_state + .delegation() + .unwrap() + .deactivation_epoch, + Epoch::MAX + ); + + // marked correctly in the list + let validator_list = stake_pool_accounts + .get_validator_list(&mut context.banks_client) + .await; + let entry = validator_list.find(&validator_stake.vote.pubkey()).unwrap(); + assert_eq!(entry.transient_stake_lamports, total_decrease); + } else { + let error = error.unwrap().unwrap(); + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::TransientAccountInUse as u32) + ) + ); + } +} + +#[test_case(true; "additional")] +#[test_case(false; "no-additional")] +#[tokio::test] +async fn fail_with_small_lamport_amount(use_additional_instruction: bool) { + let (mut context, stake_pool_accounts, validator_stake, _deposit_info, _decrease_lamports) = + setup().await; - let rent = banks_client.get_rent().await.unwrap(); + let rent = context.banks_client.get_rent().await.unwrap(); let lamports = rent.minimum_balance(std::mem::size_of::()); let error = stake_pool_accounts - .decrease_validator_stake( - &mut banks_client, - &payer, - &recent_blockhash, + .decrease_validator_stake_either( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &validator_stake.stake_account, &validator_stake.transient_stake_account, lamports, validator_stake.transient_stake_seed, + use_additional_instruction, ) .await .unwrap() @@ -383,21 +469,14 @@ async fn fail_with_small_lamport_amount() { #[tokio::test] async fn fail_big_overdraw() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - validator_stake, - deposit_info, - _decrease_lamports, - ) = setup().await; + let (mut context, stake_pool_accounts, validator_stake, deposit_info, _decrease_lamports) = + setup().await; let error = stake_pool_accounts .decrease_validator_stake( - &mut banks_client, - &payer, - &recent_blockhash, + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &validator_stake.stake_account, &validator_stake.transient_stake_account, deposit_info.stake_lamports * 1_000_000, @@ -413,30 +492,26 @@ async fn fail_big_overdraw() { ); } +#[test_case(true; "additional")] +#[test_case(false; "no-additional")] #[tokio::test] -async fn fail_overdraw() { - let ( - mut banks_client, - payer, - recent_blockhash, - stake_pool_accounts, - validator_stake, - deposit_info, - _decrease_lamports, - ) = setup().await; +async fn fail_overdraw(use_additional_instruction: bool) { + let (mut context, stake_pool_accounts, validator_stake, deposit_info, _decrease_lamports) = + setup().await; - let rent = banks_client.get_rent().await.unwrap(); + let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); let error = stake_pool_accounts - .decrease_validator_stake( - &mut banks_client, - &payer, - &recent_blockhash, + .decrease_validator_stake_either( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, &validator_stake.stake_account, &validator_stake.transient_stake_account, deposit_info.stake_lamports + stake_rent + 1, validator_stake.transient_stake_seed, + use_additional_instruction, ) .await .unwrap() @@ -447,3 +522,70 @@ async fn fail_overdraw() { TransactionError::InstructionError(0, InstructionError::InsufficientFunds) ); } + +#[tokio::test] +async fn fail_additional_with_increasing() { + let (mut context, stake_pool_accounts, validator_stake, _, decrease_lamports) = setup().await; + + let current_minimum_delegation = stake_pool_get_minimum_delegation( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; + + // warp forward to activation + let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; + context.warp_to_slot(first_normal_slot).unwrap(); + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&context.last_blockhash) + .await + .unwrap(); + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &last_blockhash, + &[validator_stake.vote.pubkey()], + false, + ) + .await; + + let error = stake_pool_accounts + .increase_validator_stake( + &mut context.banks_client, + &context.payer, + &last_blockhash, + &validator_stake.transient_stake_account, + &validator_stake.stake_account, + &validator_stake.vote.pubkey(), + current_minimum_delegation, + validator_stake.transient_stake_seed, + ) + .await; + assert!(error.is_none()); + + let error = stake_pool_accounts + .decrease_validator_stake_either( + &mut context.banks_client, + &context.payer, + &last_blockhash, + &validator_stake.stake_account, + &validator_stake.transient_stake_account, + decrease_lamports / 2, + validator_stake.transient_stake_seed, + true, + ) + .await + .unwrap() + .unwrap(); + + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(stake::instruction::StakeError::MergeTransientStake as u32) + ) + ); +} diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index dd032e7c..07e9ff61 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -1462,6 +1462,92 @@ impl StakePoolAccounts { .err() } + #[allow(clippy::too_many_arguments)] + pub async fn decrease_additional_validator_stake( + &self, + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + validator_stake: &Pubkey, + ephemeral_stake: &Pubkey, + transient_stake: &Pubkey, + lamports: u64, + transient_stake_seed: u64, + ephemeral_stake_seed: u64, + ) -> Option { + let mut instructions = vec![instruction::decrease_additional_validator_stake( + &id(), + &self.stake_pool.pubkey(), + &self.staker.pubkey(), + &self.withdraw_authority, + &self.validator_list.pubkey(), + validator_stake, + ephemeral_stake, + transient_stake, + lamports, + transient_stake_seed, + ephemeral_stake_seed, + )]; + self.maybe_add_compute_budget_instruction(&mut instructions); + let transaction = Transaction::new_signed_with_payer( + &instructions, + Some(&payer.pubkey()), + &[payer, &self.staker], + *recent_blockhash, + ); + banks_client + .process_transaction(transaction) + .await + .map_err(|e| e.into()) + .err() + } + + #[allow(clippy::too_many_arguments)] + pub async fn decrease_validator_stake_either( + &self, + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + validator_stake: &Pubkey, + transient_stake: &Pubkey, + lamports: u64, + transient_stake_seed: u64, + use_additional_instruction: bool, + ) -> Option { + if use_additional_instruction { + let ephemeral_stake_seed = 0; + let ephemeral_stake = find_ephemeral_stake_program_address( + &id(), + &self.stake_pool.pubkey(), + ephemeral_stake_seed, + ) + .0; + self.decrease_additional_validator_stake( + banks_client, + payer, + recent_blockhash, + validator_stake, + &ephemeral_stake, + transient_stake, + lamports, + transient_stake_seed, + ephemeral_stake_seed, + ) + .await + } else { + self.decrease_validator_stake( + banks_client, + payer, + recent_blockhash, + validator_stake, + transient_stake, + lamports, + transient_stake_seed, + ) + .await + } + } + #[allow(clippy::too_many_arguments)] pub async fn increase_validator_stake( &self, From 4b0c35659ae46d96e4208f13a40b41975ffa92dc Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Sat, 24 Dec 2022 15:45:39 +0100 Subject: [PATCH 0287/1076] stake-pool: Support stake redelegation (#3856) * stake-pool: Add redelegate implementation * Remove rent account from instruction * Update validator searching due to rebase * Use new blockhash in test to avoid timeout in CI * Clarify error message * Fix instruction comment * Refresh blockhash in failing test more often --- program/src/instruction.rs | 100 +++ program/src/processor.rs | 488 ++++++++++- program/tests/decrease.rs | 1 + program/tests/deposit.rs | 1 + program/tests/helpers/mod.rs | 52 +- program/tests/increase.rs | 1 + program/tests/redelegate.rs | 1129 ++++++++++++++++++++++++++ program/tests/withdraw.rs | 1 + program/tests/withdraw_edge_cases.rs | 22 +- 9 files changed, 1760 insertions(+), 35 deletions(-) create mode 100644 program/tests/redelegate.rs diff --git a/program/src/instruction.rs b/program/src/instruction.rs index ad468443..9f2d36c7 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -473,6 +473,57 @@ pub enum StakePoolInstruction { /// seed used to create ephemeral account. ephemeral_stake_seed: u64, }, + + /// (Staker only) Redelegate active stake on a validator, eventually moving it to another + /// + /// Internally, this instruction splits a validator stake account into its + /// corresponding transient stake account, redelegates it to an ephemeral stake + /// account, then merges that stake into the destination transient stake account. + /// + /// In order to rebalance the pool without taking custody, the staker needs + /// a way of reducing the stake on a stake account. This instruction splits + /// some amount of stake, up to the total activated stake, from the canonical + /// validator stake account, into its "transient" stake account. + /// + /// The instruction only succeeds if the source transient stake account and + /// ephemeral stake account do not exist. + /// + /// The amount of lamports to move must be at least twice rent-exemption + /// plus the minimum delegation amount. Rent-exemption is required for the + /// source transient stake account, and rent-exemption plus minimum delegation + /// is required for the destination ephemeral stake account. + /// + /// 0. `[]` Stake pool + /// 1. `[s]` Stake pool staker + /// 2. `[]` Stake pool withdraw authority + /// 3. `[w]` Validator list + /// 4. `[w]` Source canonical stake account to split from + /// 5. `[w]` Source transient stake account to receive split and be redelegated + /// 6. `[w]` Uninitialized ephemeral stake account to receive redelegation + /// 7. `[w]` Destination transient stake account to receive ephemeral stake by merge + /// 8. `[]` Destination stake account to receive transient stake after activation + /// 9. `[]` Destination validator vote account + /// 10. `[]` Clock sysvar + /// 11. `[]` Stake History sysvar + /// 12. `[]` Stake Config sysvar + /// 13. `[]` System program + /// 14. `[]` Stake program + Redelegate { + /// Amount of lamports to redelegate + #[allow(dead_code)] // but it's not + lamports: u64, + /// Seed used to create source transient stake account + #[allow(dead_code)] // but it's not + source_transient_stake_seed: u64, + /// Seed used to create destination ephemeral account. + #[allow(dead_code)] // but it's not + ephemeral_stake_seed: u64, + /// Seed used to create destination transient stake account. If there is + /// already transient stake, this must match the current seed, otherwise + /// it can be anything + #[allow(dead_code)] // but it's not + destination_transient_stake_seed: u64, + }, } /// Creates an 'initialize' instruction. @@ -756,6 +807,55 @@ pub fn increase_additional_validator_stake( } } +/// Creates `Redelegate` instruction (rebalance from one validator account to another) +pub fn redelegate( + program_id: &Pubkey, + stake_pool: &Pubkey, + staker: &Pubkey, + stake_pool_withdraw_authority: &Pubkey, + validator_list: &Pubkey, + source_validator_stake: &Pubkey, + source_transient_stake: &Pubkey, + ephemeral_stake: &Pubkey, + destination_transient_stake: &Pubkey, + destination_validator_stake: &Pubkey, + validator: &Pubkey, + lamports: u64, + source_transient_stake_seed: u64, + ephemeral_stake_seed: u64, + destination_transient_stake_seed: u64, +) -> Instruction { + let accounts = vec![ + AccountMeta::new_readonly(*stake_pool, false), + AccountMeta::new_readonly(*staker, true), + AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), + AccountMeta::new(*validator_list, false), + AccountMeta::new(*source_validator_stake, false), + AccountMeta::new(*source_transient_stake, false), + AccountMeta::new(*ephemeral_stake, false), + AccountMeta::new(*destination_transient_stake, false), + AccountMeta::new_readonly(*destination_validator_stake, false), + AccountMeta::new_readonly(*validator, false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(sysvar::stake_history::id(), false), + AccountMeta::new_readonly(stake::config::id(), false), + AccountMeta::new_readonly(system_program::id(), false), + AccountMeta::new_readonly(stake::program::id(), false), + ]; + Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::Redelegate { + lamports, + source_transient_stake_seed, + ephemeral_stake_seed, + destination_transient_stake_seed, + } + .try_to_vec() + .unwrap(), + } +} + /// Creates `SetPreferredDepositValidator` instruction pub fn set_preferred_validator( program_id: &Pubkey, diff --git a/program/src/processor.rs b/program/src/processor.rs index 761272e1..33355dc0 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -203,7 +203,7 @@ fn check_account_owner( } } -/// Checks if a stake acount can be managed by the pool +/// Checks if a stake account can be managed by the pool fn stake_is_usable_by_pool( meta: &stake::state::Meta, expected_authority: &Pubkey, @@ -214,13 +214,98 @@ fn stake_is_usable_by_pool( && meta.lockup == *expected_lockup } -/// Checks if a stake acount is active, without taking into account cooldowns +/// Checks if a stake account is active, without taking into account cooldowns fn stake_is_inactive_without_history(stake: &stake::state::Stake, epoch: Epoch) -> bool { stake.delegation.deactivation_epoch < epoch || (stake.delegation.activation_epoch == epoch && stake.delegation.deactivation_epoch == epoch) } +/// Check that the stake state is correct: usable by the pool and delegated to +/// the expected validator +fn check_stake_state( + stake_account_info: &AccountInfo, + withdraw_authority: &Pubkey, + vote_account_address: &Pubkey, + lockup: &stake::state::Lockup, +) -> Result<(), ProgramError> { + let (meta, stake) = get_stake_state(stake_account_info)?; + if !stake_is_usable_by_pool(&meta, withdraw_authority, lockup) { + msg!( + "Validator stake for {} not usable by pool, must be owned by withdraw authority", + vote_account_address + ); + return Err(StakePoolError::WrongStakeState.into()); + } + if stake.delegation.voter_pubkey != *vote_account_address { + msg!( + "Validator stake {} not delegated to {}", + stake_account_info.key, + vote_account_address + ); + return Err(StakePoolError::WrongStakeState.into()); + } + Ok(()) +} + +/// Checks if a validator stake account is valid, which means that it's usable by +/// the pool and delegated to the expected validator. These conditions can be violated +/// if a validator was force destaked during a cluster restart. +fn check_validator_stake_account( + stake_account_info: &AccountInfo, + program_id: &Pubkey, + stake_pool: &Pubkey, + withdraw_authority: &Pubkey, + vote_account_address: &Pubkey, + seed: u32, + lockup: &stake::state::Lockup, +) -> Result<(), ProgramError> { + check_account_owner(stake_account_info, &stake::program::id())?; + check_validator_stake_address( + program_id, + stake_pool, + stake_account_info.key, + vote_account_address, + NonZeroU32::new(seed), + )?; + check_stake_state( + stake_account_info, + withdraw_authority, + vote_account_address, + lockup, + )?; + Ok(()) +} + +/// Checks if a transient stake account is valid, which means that it's usable by +/// the pool and delegated to the expected validator. These conditions can be violated +/// if a validator was force destaked during a cluster restart. +fn check_transient_stake_account( + stake_account_info: &AccountInfo, + program_id: &Pubkey, + stake_pool: &Pubkey, + withdraw_authority: &Pubkey, + vote_account_address: &Pubkey, + seed: u64, + lockup: &stake::state::Lockup, +) -> Result<(), ProgramError> { + check_account_owner(stake_account_info, &stake::program::id())?; + check_transient_stake_address( + program_id, + stake_pool, + stake_account_info.key, + vote_account_address, + seed, + )?; + check_stake_state( + stake_account_info, + withdraw_authority, + vote_account_address, + lockup, + )?; + Ok(()) +} + /// Create a stake account on a PDA without transferring lamports fn create_stake_account<'a>( stake_account_info: AccountInfo<'a>, @@ -488,6 +573,42 @@ impl Processor { ) } + /// Issue stake::instruction::redelegate instruction to redelegate stake + #[allow(clippy::too_many_arguments)] + fn stake_redelegate<'a>( + stake_pool: &Pubkey, + source_account: AccountInfo<'a>, + authority: AccountInfo<'a>, + authority_type: &[u8], + bump_seed: u8, + destination_account: AccountInfo<'a>, + vote_account: AccountInfo<'a>, + stake_config: AccountInfo<'a>, + ) -> Result<(), ProgramError> { + let me_bytes = stake_pool.to_bytes(); + let authority_signature_seeds = [&me_bytes[..32], authority_type, &[bump_seed]]; + let signers = &[&authority_signature_seeds[..]]; + + let redelegate_instruction = &stake::instruction::redelegate( + source_account.key, + authority.key, + vote_account.key, + destination_account.key, + )[2]; + + invoke_signed( + redelegate_instruction, + &[ + source_account, + destination_account, + vote_account, + stake_config, + authority, + ], + signers, + ) + } + /// Issue a spl_token `Burn` instruction. #[allow(clippy::too_many_arguments)] fn token_burn<'a>( @@ -1468,32 +1589,15 @@ impl Processor { // explicit check here that the transient stake is increasing } - // Check that the validator stake account is actually delegated to the right - // validator. This can happen if a validator was force destaked during a - // cluster restart. - { - check_account_owner(validator_stake_account_info, stake_program_info.key)?; - check_validator_stake_address( - program_id, - stake_pool_info.key, - validator_stake_account_info.key, - vote_account_address, - NonZeroU32::new(validator_stake_info.validator_seed_suffix), - )?; - let (meta, stake) = get_stake_state(validator_stake_account_info)?; - if !stake_is_usable_by_pool(&meta, withdraw_authority_info.key, &stake_pool.lockup) { - msg!("Validator stake for {} not usable by pool, must be owned by withdraw authority", vote_account_address); - return Err(StakePoolError::WrongStakeState.into()); - } - if stake.delegation.voter_pubkey != *vote_account_address { - msg!( - "Validator stake {} not delegated to {}", - validator_stake_account_info.key, - vote_account_address - ); - return Err(StakePoolError::WrongStakeState.into()); - } - } + check_validator_stake_account( + validator_stake_account_info, + program_id, + stake_pool_info.key, + withdraw_authority_info.key, + vote_account_address, + validator_stake_info.validator_seed_suffix, + &stake_pool.lockup, + )?; if validator_stake_info.status != StakeStatus::Active { msg!("Validator is marked for removal and no longer allows increases"); @@ -1515,6 +1619,8 @@ impl Processor { } // the stake account rent exemption is withdrawn after the merge, so + // to add `lamports` to a validator, we need to create a stake account + // with `lamports + stake_rent` let total_lamports = lamports.saturating_add(stake_rent); if reserve_stake_account_info @@ -1668,6 +1774,316 @@ impl Processor { Ok(()) } + /// Processes `Redelegate` instruction. + #[inline(never)] // needed due to stack size violation + fn process_redelegate( + program_id: &Pubkey, + accounts: &[AccountInfo], + lamports: u64, + source_transient_stake_seed: u64, + ephemeral_stake_seed: u64, + destination_transient_stake_seed: u64, + ) -> ProgramResult { + let account_info_iter = &mut accounts.iter(); + let stake_pool_info = next_account_info(account_info_iter)?; + let staker_info = next_account_info(account_info_iter)?; + let withdraw_authority_info = next_account_info(account_info_iter)?; + let validator_list_info = next_account_info(account_info_iter)?; + let source_validator_stake_account_info = next_account_info(account_info_iter)?; + let source_transient_stake_account_info = next_account_info(account_info_iter)?; + let ephemeral_stake_account_info = next_account_info(account_info_iter)?; + let destination_transient_stake_account_info = next_account_info(account_info_iter)?; + let destination_validator_stake_account_info = next_account_info(account_info_iter)?; + let validator_vote_account_info = next_account_info(account_info_iter)?; + let clock_info = next_account_info(account_info_iter)?; + let clock = &Clock::from_account_info(clock_info)?; + let stake_history_info = next_account_info(account_info_iter)?; + let stake_config_info = next_account_info(account_info_iter)?; + let system_program_info = next_account_info(account_info_iter)?; + let stake_program_info = next_account_info(account_info_iter)?; + + check_system_program(system_program_info.key)?; + check_stake_program(stake_program_info.key)?; + check_account_owner(stake_pool_info, program_id)?; + + let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; + if !stake_pool.is_valid() { + msg!("Expected valid stake pool"); + return Err(StakePoolError::InvalidState.into()); + } + + stake_pool.check_authority_withdraw( + withdraw_authority_info.key, + program_id, + stake_pool_info.key, + )?; + stake_pool.check_staker(staker_info)?; + + if stake_pool.last_update_epoch < clock.epoch { + return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); + } + + stake_pool.check_validator_list(validator_list_info)?; + check_account_owner(validator_list_info, program_id)?; + + let mut validator_list_data = validator_list_info.data.borrow_mut(); + let (header, mut validator_list) = + ValidatorListHeader::deserialize_vec(&mut validator_list_data)?; + if !header.is_valid() { + return Err(StakePoolError::InvalidState.into()); + } + + let rent = Rent::get()?; + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; + let current_minimum_delegation = minimum_delegation(stake_minimum_delegation); + + // check that we're redelegating enough + let destination_transient_lamports = { + // redelegation requires that the source account maintains rent exemption and that + // the destination account has rent-exemption and minimum delegation + let minimum_redelegation_lamports = + current_minimum_delegation.saturating_add(stake_rent.saturating_mul(2)); + if lamports < minimum_redelegation_lamports { + msg!( + "Need more than {} lamports for redelegated stake and transient stake to meet minimum delegation requirement, {} provided", + minimum_redelegation_lamports, + lamports + ); + return Err(ProgramError::Custom( + stake::instruction::StakeError::InsufficientDelegation as u32, + )); + } + + // check that we're not draining the source account + let current_minimum_lamports = stake_rent.saturating_add(current_minimum_delegation); + if source_validator_stake_account_info + .lamports() + .saturating_sub(lamports) + < current_minimum_lamports + { + let max_split_amount = source_validator_stake_account_info + .lamports() + .saturating_sub(current_minimum_lamports); + msg!( + "Source stake does not have {} lamports for redelegation, must be {} at most", + lamports, + max_split_amount, + ); + return Err(ProgramError::InsufficientFunds); + } + lamports + .checked_sub(stake_rent) + .ok_or(StakePoolError::CalculationFailure)? + }; + + // check source account state + let (_, stake) = get_stake_state(source_validator_stake_account_info)?; + let vote_account_address = stake.delegation.voter_pubkey; + { + let maybe_validator_stake_info = + validator_list.find_mut::(|x| { + ValidatorStakeInfo::memcmp_pubkey(x, &vote_account_address) + }); + if maybe_validator_stake_info.is_none() { + msg!( + "Source vote account {} not found in stake pool", + vote_account_address + ); + return Err(StakePoolError::ValidatorNotFound.into()); + } + let mut validator_stake_info = maybe_validator_stake_info.unwrap(); + check_validator_stake_address( + program_id, + stake_pool_info.key, + source_validator_stake_account_info.key, + &vote_account_address, + NonZeroU32::new(validator_stake_info.validator_seed_suffix), + )?; + if validator_stake_info.transient_stake_lamports > 0 { + return Err(StakePoolError::TransientAccountInUse.into()); + } + if validator_stake_info.status != StakeStatus::Active { + msg!("Validator is marked for removal and no longer allows redelegation"); + return Err(StakePoolError::ValidatorNotFound.into()); + } + validator_stake_info.active_stake_lamports = validator_stake_info + .active_stake_lamports + .checked_sub(lamports) + .ok_or(StakePoolError::CalculationFailure)?; + validator_stake_info.transient_stake_lamports = stake_rent; + validator_stake_info.transient_seed_suffix = source_transient_stake_seed; + } + + // split from source, into source transient + { + // check transient account + let source_transient_stake_bump_seed = check_transient_stake_address( + program_id, + stake_pool_info.key, + source_transient_stake_account_info.key, + &vote_account_address, + source_transient_stake_seed, + )?; + let source_transient_stake_account_signer_seeds: &[&[_]] = &[ + TRANSIENT_STAKE_SEED_PREFIX, + &vote_account_address.to_bytes(), + &stake_pool_info.key.to_bytes(), + &source_transient_stake_seed.to_le_bytes(), + &[source_transient_stake_bump_seed], + ]; + + create_stake_account( + source_transient_stake_account_info.clone(), + source_transient_stake_account_signer_seeds, + system_program_info.clone(), + )?; + + Self::stake_split( + stake_pool_info.key, + source_validator_stake_account_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + lamports, + source_transient_stake_account_info.clone(), + )?; + } + + // redelegate from source transient to ephemeral + { + let ephemeral_stake_bump_seed = check_ephemeral_stake_address( + program_id, + stake_pool_info.key, + ephemeral_stake_account_info.key, + ephemeral_stake_seed, + )?; + let ephemeral_stake_account_signer_seeds: &[&[_]] = &[ + EPHEMERAL_STAKE_SEED_PREFIX, + &stake_pool_info.key.to_bytes(), + &ephemeral_stake_seed.to_le_bytes(), + &[ephemeral_stake_bump_seed], + ]; + create_stake_account( + ephemeral_stake_account_info.clone(), + ephemeral_stake_account_signer_seeds, + system_program_info.clone(), + )?; + Self::stake_redelegate( + stake_pool_info.key, + source_transient_stake_account_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + ephemeral_stake_account_info.clone(), + validator_vote_account_info.clone(), + stake_config_info.clone(), + )?; + } + + { + // check destination stake and transient stake accounts + let vote_account_address = validator_vote_account_info.key; + let maybe_validator_stake_info = + validator_list.find_mut::(|x| { + ValidatorStakeInfo::memcmp_pubkey(x, vote_account_address) + }); + if maybe_validator_stake_info.is_none() { + msg!( + "Destination vote account {} not found in stake pool", + vote_account_address + ); + return Err(StakePoolError::ValidatorNotFound.into()); + } + let mut validator_stake_info = maybe_validator_stake_info.unwrap(); + check_validator_stake_account( + destination_validator_stake_account_info, + program_id, + stake_pool_info.key, + withdraw_authority_info.key, + vote_account_address, + validator_stake_info.validator_seed_suffix, + &stake_pool.lockup, + )?; + if validator_stake_info.status != StakeStatus::Active { + msg!( + "Destination validator is marked for removal and no longer allows redelegation" + ); + return Err(StakePoolError::ValidatorNotFound.into()); + } + let transient_account_exists = validator_stake_info.transient_stake_lamports > 0; + validator_stake_info.transient_stake_lamports = validator_stake_info + .transient_stake_lamports + .checked_add(destination_transient_lamports) + .ok_or(StakePoolError::CalculationFailure)?; + + if transient_account_exists { + // if transient stake exists, make sure it's the right one and that it's + // usable by the pool + if validator_stake_info.transient_seed_suffix != destination_transient_stake_seed { + msg!("Provided seed {} does not match current seed {} for transient stake account", + destination_transient_stake_seed, + validator_stake_info.transient_seed_suffix + ); + return Err(StakePoolError::InvalidStakeAccountAddress.into()); + } + check_transient_stake_account( + destination_transient_stake_account_info, + program_id, + stake_pool_info.key, + withdraw_authority_info.key, + vote_account_address, + destination_transient_stake_seed, + &stake_pool.lockup, + )?; + Self::stake_merge( + stake_pool_info.key, + ephemeral_stake_account_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + destination_transient_stake_account_info.clone(), + clock_info.clone(), + stake_history_info.clone(), + stake_program_info.clone(), + )?; + } else { + // otherwise, create the new account and split into it + let destination_transient_stake_bump_seed = check_transient_stake_address( + program_id, + stake_pool_info.key, + destination_transient_stake_account_info.key, + vote_account_address, + destination_transient_stake_seed, + )?; + let destination_transient_stake_account_signer_seeds: &[&[_]] = &[ + TRANSIENT_STAKE_SEED_PREFIX, + &vote_account_address.to_bytes(), + &stake_pool_info.key.to_bytes(), + &destination_transient_stake_seed.to_le_bytes(), + &[destination_transient_stake_bump_seed], + ]; + create_stake_account( + destination_transient_stake_account_info.clone(), + destination_transient_stake_account_signer_seeds, + system_program_info.clone(), + )?; + Self::stake_split( + stake_pool_info.key, + ephemeral_stake_account_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + destination_transient_lamports, + destination_transient_stake_account_info.clone(), + )?; + validator_stake_info.transient_seed_suffix = destination_transient_stake_seed; + } + } + + Ok(()) + } + /// Process `SetPreferredValidator` instruction #[inline(never)] // needed due to stack size violation fn process_set_preferred_validator( @@ -3462,6 +3878,22 @@ impl Processor { msg!("Instruction: UpdateTokenMetadata"); Self::process_update_pool_token_metadata(program_id, accounts, name, symbol, uri) } + StakePoolInstruction::Redelegate { + lamports, + source_transient_stake_seed, + ephemeral_stake_seed, + destination_transient_stake_seed, + } => { + msg!("Instruction: Redelegate"); + Self::process_redelegate( + program_id, + accounts, + lamports, + source_transient_stake_seed, + ephemeral_stake_seed, + destination_transient_stake_seed, + ) + } } } } diff --git a/program/tests/decrease.rs b/program/tests/decrease.rs index 7d263597..b8033440 100644 --- a/program/tests/decrease.rs +++ b/program/tests/decrease.rs @@ -235,6 +235,7 @@ async fn fail_with_unknown_validator() { &context.payer, &context.last_blockhash, &stake_pool_accounts.stake_pool.pubkey(), + 0, ) .await; diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 0ccea7bd..585f43ff 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -626,6 +626,7 @@ async fn fail_with_unknown_validator() { &payer, &recent_blockhash, &stake_pool_accounts.stake_pool.pubkey(), + 0, ) .await; diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 07e9ff61..4a684233 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -76,8 +76,8 @@ pub async fn get_account(banks_client: &mut BanksClient, pubkey: &Pubkey) -> Sol banks_client .get_account(*pubkey) .await + .expect("client error") .expect("account not found") - .expect("account empty") } #[allow(clippy::too_many_arguments)] @@ -754,6 +754,7 @@ pub async fn create_unknown_validator_stake( payer: &Keypair, recent_blockhash: &Hash, stake_pool: &Pubkey, + lamports: u64, ) -> ValidatorStakeAccount { let mut unknown_stake = ValidatorStakeAccount::new(stake_pool, NonZeroU32::new(1), 222); create_vote( @@ -779,7 +780,7 @@ pub async fn create_unknown_validator_stake( withdrawer: user.pubkey(), }, &stake::state::Lockup::default(), - current_minimum_delegation, + current_minimum_delegation + lamports, ) .await; delegate_stake_account( @@ -1679,6 +1680,53 @@ impl StakePoolAccounts { } } + #[allow(clippy::too_many_arguments)] + pub async fn redelegate( + &self, + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + source_validator_stake: &Pubkey, + source_transient_stake: &Pubkey, + ephemeral_stake: &Pubkey, + destination_transient_stake: &Pubkey, + destination_validator_stake: &Pubkey, + validator: &Pubkey, + lamports: u64, + source_transient_stake_seed: u64, + ephemeral_stake_seed: u64, + destination_transient_stake_seed: u64, + ) -> Option { + let transaction = Transaction::new_signed_with_payer( + &[instruction::redelegate( + &id(), + &self.stake_pool.pubkey(), + &self.staker.pubkey(), + &self.withdraw_authority, + &self.validator_list.pubkey(), + source_validator_stake, + source_transient_stake, + ephemeral_stake, + destination_transient_stake, + destination_validator_stake, + validator, + lamports, + source_transient_stake_seed, + ephemeral_stake_seed, + destination_transient_stake_seed, + )], + Some(&payer.pubkey()), + &[payer, &self.staker], + *recent_blockhash, + ); + #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 + banks_client + .process_transaction(transaction) + .await + .map_err(|e| e.into()) + .err() + } + pub async fn set_preferred_validator( &self, banks_client: &mut BanksClient, diff --git a/program/tests/increase.rs b/program/tests/increase.rs index 7967907c..647525d7 100644 --- a/program/tests/increase.rs +++ b/program/tests/increase.rs @@ -238,6 +238,7 @@ async fn fail_with_unknown_validator() { &context.payer, &context.last_blockhash, &stake_pool_accounts.stake_pool.pubkey(), + 0, ) .await; diff --git a/program/tests/redelegate.rs b/program/tests/redelegate.rs new file mode 100644 index 00000000..7bc6c948 --- /dev/null +++ b/program/tests/redelegate.rs @@ -0,0 +1,1129 @@ +#![allow(clippy::integer_arithmetic)] +#![cfg(feature = "test-sbf")] + +mod helpers; + +use { + bincode::deserialize, + helpers::*, + solana_program::{ + clock::Epoch, hash::Hash, instruction::InstructionError, pubkey::Pubkey, stake, + }, + solana_program_test::*, + solana_sdk::{ + signature::{Keypair, Signer}, + stake::instruction::StakeError, + transaction::{Transaction, TransactionError}, + }, + spl_stake_pool::{ + error::StakePoolError, find_ephemeral_stake_program_address, + find_transient_stake_program_address, id, instruction, MINIMUM_RESERVE_LAMPORTS, + }, +}; + +async fn setup( + do_warp: bool, +) -> ( + ProgramTestContext, + Hash, + StakePoolAccounts, + ValidatorStakeAccount, + ValidatorStakeAccount, + u64, + u64, +) { + let mut context = program_test().start_with_context().await; + let rent = context.banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let current_minimum_delegation = stake_pool_get_minimum_delegation( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + ) + .await; + + let stake_pool_accounts = StakePoolAccounts::default(); + stake_pool_accounts + .initialize_stake_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + MINIMUM_RESERVE_LAMPORTS + current_minimum_delegation + stake_rent, + ) + .await + .unwrap(); + + let source_validator_stake = simple_add_validator_to_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + None, + ) + .await; + + let destination_validator_stake = simple_add_validator_to_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + None, + ) + .await; + + let minimum_redelegate_lamports = current_minimum_delegation + stake_rent * 2; + simple_deposit_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + &source_validator_stake, + minimum_redelegate_lamports, + ) + .await + .unwrap(); + + let mut slot = 0; + if do_warp { + slot = context.genesis_config().epoch_schedule.first_normal_slot; + context.warp_to_slot(slot).unwrap(); + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &[ + source_validator_stake.vote.pubkey(), + destination_validator_stake.vote.pubkey(), + ], + false, + ) + .await; + } + + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&context.last_blockhash) + .await + .unwrap(); + + ( + context, + last_blockhash, + stake_pool_accounts, + source_validator_stake, + destination_validator_stake, + minimum_redelegate_lamports, + slot, + ) +} + +#[tokio::test] +async fn success() { + let ( + mut context, + last_blockhash, + stake_pool_accounts, + source_validator_stake, + destination_validator_stake, + redelegate_lamports, + mut slot, + ) = setup(true).await; + + // Save validator stake + let pre_validator_stake_account = get_account( + &mut context.banks_client, + &source_validator_stake.stake_account, + ) + .await; + + // Save validator stake + let pre_destination_validator_stake_account = get_account( + &mut context.banks_client, + &destination_validator_stake.stake_account, + ) + .await; + + // Check no transient stake + let transient_account = context + .banks_client + .get_account(source_validator_stake.transient_stake_account) + .await + .unwrap(); + assert!(transient_account.is_none()); + + let ephemeral_stake_seed = 100; + let ephemeral_stake = find_ephemeral_stake_program_address( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + ephemeral_stake_seed, + ) + .0; + let error = stake_pool_accounts + .redelegate( + &mut context.banks_client, + &context.payer, + &last_blockhash, + &source_validator_stake.stake_account, + &source_validator_stake.transient_stake_account, + &ephemeral_stake, + &destination_validator_stake.transient_stake_account, + &destination_validator_stake.stake_account, + &destination_validator_stake.vote.pubkey(), + redelegate_lamports, + source_validator_stake.transient_stake_seed, + ephemeral_stake_seed, + destination_validator_stake.transient_stake_seed, + ) + .await; + assert!(error.is_none()); + + // Check validator stake account balance + let validator_stake_account = get_account( + &mut context.banks_client, + &source_validator_stake.stake_account, + ) + .await; + let validator_stake_state = + deserialize::(&validator_stake_account.data).unwrap(); + assert_eq!( + pre_validator_stake_account.lamports - redelegate_lamports, + validator_stake_account.lamports + ); + assert_eq!( + validator_stake_state + .delegation() + .unwrap() + .deactivation_epoch, + Epoch::MAX + ); + + // Check source transient stake account state and balance + let rent = context.banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + + let source_transient_stake_account = get_account( + &mut context.banks_client, + &source_validator_stake.transient_stake_account, + ) + .await; + let transient_stake_state = + deserialize::(&source_transient_stake_account.data).unwrap(); + assert_eq!(source_transient_stake_account.lamports, stake_rent); + let transient_delegation = transient_stake_state.delegation().unwrap(); + assert_ne!(transient_delegation.deactivation_epoch, Epoch::MAX); + assert_eq!(transient_delegation.stake, redelegate_lamports - stake_rent); + + // Check ephemeral account doesn't exist + let maybe_account = context + .banks_client + .get_account(ephemeral_stake) + .await + .unwrap(); + assert!(maybe_account.is_none()); + + // Check destination transient stake account + let destination_transient_stake_account = get_account( + &mut context.banks_client, + &destination_validator_stake.transient_stake_account, + ) + .await; + let transient_stake_state = + deserialize::(&destination_transient_stake_account.data).unwrap(); + assert_eq!( + destination_transient_stake_account.lamports, + redelegate_lamports - stake_rent + ); + let transient_delegation = transient_stake_state.delegation().unwrap(); + assert_eq!(transient_delegation.deactivation_epoch, Epoch::MAX); + assert_ne!(transient_delegation.activation_epoch, Epoch::MAX); + assert_eq!( + transient_delegation.stake, + redelegate_lamports - stake_rent * 2 + ); + + // Check validator list + let validator_list = stake_pool_accounts + .get_validator_list(&mut context.banks_client) + .await; + let source_item = validator_list + .find(&source_validator_stake.vote.pubkey()) + .unwrap(); + assert_eq!( + source_item.active_stake_lamports, + validator_stake_account.lamports + ); + assert_eq!( + source_item.transient_stake_lamports, + source_transient_stake_account.lamports + ); + assert_eq!( + source_item.transient_seed_suffix, + source_validator_stake.transient_stake_seed + ); + + let destination_item = validator_list + .find(&destination_validator_stake.vote.pubkey()) + .unwrap(); + assert_eq!( + destination_item.transient_stake_lamports, + destination_transient_stake_account.lamports + ); + assert_eq!( + destination_item.transient_seed_suffix, + destination_validator_stake.transient_stake_seed + ); + + // Warp forward and merge all + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + slot += slots_per_epoch; + context.warp_to_slot(slot).unwrap(); + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &last_blockhash, + &[ + source_validator_stake.vote.pubkey(), + destination_validator_stake.vote.pubkey(), + ], + false, + ) + .await; + + // Check transient accounts are gone + let maybe_account = context + .banks_client + .get_account(destination_validator_stake.transient_stake_account) + .await + .unwrap(); + assert!(maybe_account.is_none()); + let maybe_account = context + .banks_client + .get_account(source_validator_stake.transient_stake_account) + .await + .unwrap(); + assert!(maybe_account.is_none()); + + // Check validator list + let validator_list = stake_pool_accounts + .get_validator_list(&mut context.banks_client) + .await; + let source_item = validator_list + .find(&source_validator_stake.vote.pubkey()) + .unwrap(); + assert_eq!( + source_item.active_stake_lamports, + validator_stake_account.lamports + ); + assert_eq!(source_item.transient_stake_lamports, 0); + + let destination_item = validator_list + .find(&destination_validator_stake.vote.pubkey()) + .unwrap(); + assert_eq!(destination_item.transient_stake_lamports, 0); + assert_eq!( + destination_item.active_stake_lamports, + pre_destination_validator_stake_account.lamports + redelegate_lamports - stake_rent * 2 + ); + let post_destination_validator_stake_account = get_account( + &mut context.banks_client, + &destination_validator_stake.stake_account, + ) + .await; + assert_eq!( + post_destination_validator_stake_account.lamports, + pre_destination_validator_stake_account.lamports + redelegate_lamports - stake_rent * 2 + ); +} + +#[tokio::test] +async fn success_with_increasing_stake() { + let ( + mut context, + last_blockhash, + stake_pool_accounts, + source_validator_stake, + destination_validator_stake, + redelegate_lamports, + mut slot, + ) = setup(true).await; + + // Save validator stake + let pre_validator_stake_account = get_account( + &mut context.banks_client, + &destination_validator_stake.stake_account, + ) + .await; + + let current_minimum_delegation = stake_pool_get_minimum_delegation( + &mut context.banks_client, + &context.payer, + &last_blockhash, + ) + .await; + let rent = context.banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + + let error = stake_pool_accounts + .increase_validator_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &destination_validator_stake.transient_stake_account, + &destination_validator_stake.stake_account, + &destination_validator_stake.vote.pubkey(), + current_minimum_delegation, + destination_validator_stake.transient_stake_seed, + ) + .await; + assert!(error.is_none()); + + let validator_list = stake_pool_accounts + .get_validator_list(&mut context.banks_client) + .await; + let destination_item = validator_list + .find(&destination_validator_stake.vote.pubkey()) + .unwrap(); + assert_eq!( + destination_item.transient_stake_lamports, + current_minimum_delegation + stake_rent + ); + let pre_transient_stake_account = get_account( + &mut context.banks_client, + &destination_validator_stake.transient_stake_account, + ) + .await; + assert_eq!( + pre_transient_stake_account.lamports, + current_minimum_delegation + stake_rent + ); + + let ephemeral_stake_seed = 10; + let ephemeral_stake = find_ephemeral_stake_program_address( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + ephemeral_stake_seed, + ) + .0; + + // fail with incorrect transient stake derivation + let wrong_transient_stake_seed = destination_validator_stake + .transient_stake_seed + .wrapping_add(1); + let (wrong_transient_stake_account, _) = find_transient_stake_program_address( + &id(), + &destination_validator_stake.vote.pubkey(), + &stake_pool_accounts.stake_pool.pubkey(), + wrong_transient_stake_seed, + ); + let error = stake_pool_accounts + .redelegate( + &mut context.banks_client, + &context.payer, + &last_blockhash, + &source_validator_stake.stake_account, + &source_validator_stake.transient_stake_account, + &ephemeral_stake, + &wrong_transient_stake_account, + &destination_validator_stake.stake_account, + &destination_validator_stake.vote.pubkey(), + redelegate_lamports, + source_validator_stake.transient_stake_seed, + ephemeral_stake_seed, + wrong_transient_stake_seed, + ) + .await + .unwrap() + .unwrap(); + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::InvalidStakeAccountAddress as u32) + ) + ); + + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&context.last_blockhash) + .await + .unwrap(); + + let error = stake_pool_accounts + .redelegate( + &mut context.banks_client, + &context.payer, + &last_blockhash, + &source_validator_stake.stake_account, + &source_validator_stake.transient_stake_account, + &ephemeral_stake, + &destination_validator_stake.transient_stake_account, + &destination_validator_stake.stake_account, + &destination_validator_stake.vote.pubkey(), + redelegate_lamports, + source_validator_stake.transient_stake_seed, + ephemeral_stake_seed, + destination_validator_stake.transient_stake_seed, + ) + .await; + assert!(error.is_none()); + + // Check destination transient stake account + let destination_transient_stake_account = get_account( + &mut context.banks_client, + &destination_validator_stake.transient_stake_account, + ) + .await; + let transient_stake_state = + deserialize::(&destination_transient_stake_account.data).unwrap(); + // stake rent cancels out + assert_eq!( + destination_transient_stake_account.lamports, + redelegate_lamports + current_minimum_delegation + ); + + let transient_delegation = transient_stake_state.delegation().unwrap(); + assert_eq!(transient_delegation.deactivation_epoch, Epoch::MAX); + assert_ne!(transient_delegation.activation_epoch, Epoch::MAX); + assert_eq!( + transient_delegation.stake, + redelegate_lamports + current_minimum_delegation - stake_rent + ); + + // Check validator list + let validator_list = stake_pool_accounts + .get_validator_list(&mut context.banks_client) + .await; + let destination_item = validator_list + .find(&destination_validator_stake.vote.pubkey()) + .unwrap(); + assert_eq!( + destination_item.transient_stake_lamports, + destination_transient_stake_account.lamports + ); + assert_eq!( + destination_item.transient_seed_suffix, + destination_validator_stake.transient_stake_seed + ); + + // Warp forward and merge all + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + slot += slots_per_epoch; + context.warp_to_slot(slot).unwrap(); + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &last_blockhash, + &[ + source_validator_stake.vote.pubkey(), + destination_validator_stake.vote.pubkey(), + ], + false, + ) + .await; + + // Check transient account is gone + let maybe_account = context + .banks_client + .get_account(destination_validator_stake.transient_stake_account) + .await + .unwrap(); + assert!(maybe_account.is_none()); + + // Check validator list + let validator_list = stake_pool_accounts + .get_validator_list(&mut context.banks_client) + .await; + let destination_item = validator_list + .find(&destination_validator_stake.vote.pubkey()) + .unwrap(); + assert_eq!(destination_item.transient_stake_lamports, 0); + // redelegate is smart enough to activate *everything*, so there's only one rent-exemption + // worth of inactive stake! + assert_eq!( + destination_item.active_stake_lamports, + pre_validator_stake_account.lamports + redelegate_lamports + current_minimum_delegation + - stake_rent + ); + let post_validator_stake_account = get_account( + &mut context.banks_client, + &destination_validator_stake.stake_account, + ) + .await; + assert_eq!( + post_validator_stake_account.lamports, + pre_validator_stake_account.lamports + redelegate_lamports + current_minimum_delegation + - stake_rent + ); +} + +#[tokio::test] +async fn fail_with_decreasing_stake() { + let ( + mut context, + last_blockhash, + stake_pool_accounts, + source_validator_stake, + destination_validator_stake, + redelegate_lamports, + mut slot, + ) = setup(false).await; + + let current_minimum_delegation = stake_pool_get_minimum_delegation( + &mut context.banks_client, + &context.payer, + &last_blockhash, + ) + .await; + let rent = context.banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let minimum_decrease_lamports = current_minimum_delegation + stake_rent; + + simple_deposit_stake( + &mut context.banks_client, + &context.payer, + &last_blockhash, + &stake_pool_accounts, + &destination_validator_stake, + redelegate_lamports, + ) + .await + .unwrap(); + + slot += context.genesis_config().epoch_schedule.first_normal_slot; + context.warp_to_slot(slot).unwrap(); + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &last_blockhash, + &[ + source_validator_stake.vote.pubkey(), + destination_validator_stake.vote.pubkey(), + ], + false, + ) + .await; + + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&last_blockhash) + .await + .unwrap(); + + let error = stake_pool_accounts + .decrease_validator_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &destination_validator_stake.stake_account, + &destination_validator_stake.transient_stake_account, + minimum_decrease_lamports, + destination_validator_stake.transient_stake_seed, + ) + .await; + assert!(error.is_none()); + + let ephemeral_stake_seed = 20; + let ephemeral_stake = find_ephemeral_stake_program_address( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + ephemeral_stake_seed, + ) + .0; + + let error = stake_pool_accounts + .redelegate( + &mut context.banks_client, + &context.payer, + &last_blockhash, + &source_validator_stake.stake_account, + &source_validator_stake.transient_stake_account, + &ephemeral_stake, + &destination_validator_stake.transient_stake_account, + &destination_validator_stake.stake_account, + &destination_validator_stake.vote.pubkey(), + redelegate_lamports, + source_validator_stake.transient_stake_seed, + ephemeral_stake_seed, + destination_validator_stake.transient_stake_seed, + ) + .await + .unwrap() + .unwrap(); + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakeError::MergeTransientStake as u32) + ) + ); +} + +#[tokio::test] +async fn fail_with_wrong_withdraw_authority() { + let ( + mut context, + last_blockhash, + stake_pool_accounts, + source_validator_stake, + destination_validator_stake, + redelegate_lamports, + _, + ) = setup(true).await; + + let ephemeral_stake_seed = 2; + let ephemeral_stake = find_ephemeral_stake_program_address( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + ephemeral_stake_seed, + ) + .0; + + let wrong_withdraw_authority = Pubkey::new_unique(); + let transaction = Transaction::new_signed_with_payer( + &[instruction::redelegate( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.staker.pubkey(), + &wrong_withdraw_authority, + &stake_pool_accounts.validator_list.pubkey(), + &source_validator_stake.stake_account, + &source_validator_stake.transient_stake_account, + &ephemeral_stake, + &destination_validator_stake.transient_stake_account, + &destination_validator_stake.stake_account, + &destination_validator_stake.vote.pubkey(), + redelegate_lamports, + source_validator_stake.transient_stake_seed, + ephemeral_stake_seed, + destination_validator_stake.transient_stake_seed, + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.staker], + last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::InvalidProgramAddress as u32) + ) + ); +} + +#[tokio::test] +async fn fail_with_wrong_validator_list() { + let ( + mut context, + last_blockhash, + stake_pool_accounts, + source_validator_stake, + destination_validator_stake, + redelegate_lamports, + _, + ) = setup(true).await; + + let ephemeral_stake_seed = 2; + let ephemeral_stake = find_ephemeral_stake_program_address( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + ephemeral_stake_seed, + ) + .0; + + let wrong_validator_list = Pubkey::new_unique(); + let transaction = Transaction::new_signed_with_payer( + &[instruction::redelegate( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.staker.pubkey(), + &stake_pool_accounts.withdraw_authority, + &wrong_validator_list, + &source_validator_stake.stake_account, + &source_validator_stake.transient_stake_account, + &ephemeral_stake, + &destination_validator_stake.transient_stake_account, + &destination_validator_stake.stake_account, + &destination_validator_stake.vote.pubkey(), + redelegate_lamports, + source_validator_stake.transient_stake_seed, + ephemeral_stake_seed, + destination_validator_stake.transient_stake_seed, + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.staker], + last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::InvalidValidatorStakeList as u32) + ) + ); +} + +#[tokio::test] +async fn fail_with_wrong_staker() { + let ( + mut context, + last_blockhash, + stake_pool_accounts, + source_validator_stake, + destination_validator_stake, + redelegate_lamports, + _, + ) = setup(true).await; + + let ephemeral_stake_seed = 2; + let ephemeral_stake = find_ephemeral_stake_program_address( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + ephemeral_stake_seed, + ) + .0; + + let wrong_staker = Keypair::new(); + let transaction = Transaction::new_signed_with_payer( + &[instruction::redelegate( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &wrong_staker.pubkey(), + &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts.validator_list.pubkey(), + &source_validator_stake.stake_account, + &source_validator_stake.transient_stake_account, + &ephemeral_stake, + &destination_validator_stake.transient_stake_account, + &destination_validator_stake.stake_account, + &destination_validator_stake.vote.pubkey(), + redelegate_lamports, + source_validator_stake.transient_stake_seed, + ephemeral_stake_seed, + destination_validator_stake.transient_stake_seed, + )], + Some(&context.payer.pubkey()), + &[&context.payer, &wrong_staker], + last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::WrongStaker as u32) + ) + ); +} + +#[tokio::test] +async fn fail_with_unknown_validator() { + let ( + mut context, + last_blockhash, + stake_pool_accounts, + source_validator_stake, + destination_validator_stake, + redelegate_lamports, + _, + ) = setup(true).await; + + let unknown_validator_stake = create_unknown_validator_stake( + &mut context.banks_client, + &context.payer, + &last_blockhash, + &stake_pool_accounts.stake_pool.pubkey(), + redelegate_lamports, + ) + .await; + + let ephemeral_stake_seed = 42; + let ephemeral_stake = find_ephemeral_stake_program_address( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + ephemeral_stake_seed, + ) + .0; + let error = stake_pool_accounts + .redelegate( + &mut context.banks_client, + &context.payer, + &last_blockhash, + &source_validator_stake.stake_account, + &source_validator_stake.transient_stake_account, + &ephemeral_stake, + &unknown_validator_stake.transient_stake_account, + &unknown_validator_stake.stake_account, + &unknown_validator_stake.vote.pubkey(), + redelegate_lamports, + source_validator_stake.transient_stake_seed, + ephemeral_stake_seed, + unknown_validator_stake.transient_stake_seed, + ) + .await + .unwrap() + .unwrap(); + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::ValidatorNotFound as u32) + ) + ); + + let error = stake_pool_accounts + .redelegate( + &mut context.banks_client, + &context.payer, + &last_blockhash, + &unknown_validator_stake.stake_account, + &unknown_validator_stake.transient_stake_account, + &ephemeral_stake, + &destination_validator_stake.transient_stake_account, + &destination_validator_stake.stake_account, + &destination_validator_stake.vote.pubkey(), + redelegate_lamports, + unknown_validator_stake.transient_stake_seed, + ephemeral_stake_seed, + destination_validator_stake.transient_stake_seed, + ) + .await + .unwrap() + .unwrap(); + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::ValidatorNotFound as u32) + ) + ); +} + +#[tokio::test] +async fn fail_redelegate_twice() { + let ( + mut context, + last_blockhash, + stake_pool_accounts, + source_validator_stake, + destination_validator_stake, + redelegate_lamports, + mut slot, + ) = setup(false).await; + + simple_deposit_stake( + &mut context.banks_client, + &context.payer, + &last_blockhash, + &stake_pool_accounts, + &source_validator_stake, + redelegate_lamports, + ) + .await + .unwrap(); + + slot += context.genesis_config().epoch_schedule.first_normal_slot; + context.warp_to_slot(slot).unwrap(); + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &last_blockhash, + &[ + source_validator_stake.vote.pubkey(), + destination_validator_stake.vote.pubkey(), + ], + false, + ) + .await; + + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&last_blockhash) + .await + .unwrap(); + + let ephemeral_stake_seed = 100; + let ephemeral_stake = find_ephemeral_stake_program_address( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + ephemeral_stake_seed, + ) + .0; + let error = stake_pool_accounts + .redelegate( + &mut context.banks_client, + &context.payer, + &last_blockhash, + &source_validator_stake.stake_account, + &source_validator_stake.transient_stake_account, + &ephemeral_stake, + &destination_validator_stake.transient_stake_account, + &destination_validator_stake.stake_account, + &destination_validator_stake.vote.pubkey(), + redelegate_lamports, + source_validator_stake.transient_stake_seed, + ephemeral_stake_seed, + destination_validator_stake.transient_stake_seed, + ) + .await; + assert!(error.is_none()); + + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&last_blockhash) + .await + .unwrap(); + + let error = stake_pool_accounts + .redelegate( + &mut context.banks_client, + &context.payer, + &last_blockhash, + &source_validator_stake.stake_account, + &source_validator_stake.transient_stake_account, + &ephemeral_stake, + &destination_validator_stake.transient_stake_account, + &destination_validator_stake.stake_account, + &destination_validator_stake.vote.pubkey(), + redelegate_lamports, + source_validator_stake.transient_stake_seed, + ephemeral_stake_seed, + destination_validator_stake.transient_stake_seed, + ) + .await + .unwrap() + .unwrap(); + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::TransientAccountInUse as u32) + ) + ); +} + +#[tokio::test] +async fn fail_with_small_lamport_amount() { + let ( + mut context, + last_blockhash, + stake_pool_accounts, + source_validator_stake, + destination_validator_stake, + redelegate_lamports, + _, + ) = setup(true).await; + + let ephemeral_stake_seed = 7_000; + let ephemeral_stake = find_ephemeral_stake_program_address( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + ephemeral_stake_seed, + ) + .0; + + let error = stake_pool_accounts + .redelegate( + &mut context.banks_client, + &context.payer, + &last_blockhash, + &source_validator_stake.stake_account, + &source_validator_stake.transient_stake_account, + &ephemeral_stake, + &destination_validator_stake.transient_stake_account, + &destination_validator_stake.stake_account, + &destination_validator_stake.vote.pubkey(), + redelegate_lamports - 1, + source_validator_stake.transient_stake_seed, + ephemeral_stake_seed, + destination_validator_stake.transient_stake_seed, + ) + .await + .unwrap() + .unwrap(); + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakeError::InsufficientDelegation as u32) + ) + ); +} + +#[tokio::test] +async fn fail_drain_source_account() { + let ( + mut context, + last_blockhash, + stake_pool_accounts, + source_validator_stake, + destination_validator_stake, + _, + _, + ) = setup(true).await; + + let validator_stake_account = get_account( + &mut context.banks_client, + &source_validator_stake.stake_account, + ) + .await; + + let ephemeral_stake_seed = 2; + let ephemeral_stake = find_ephemeral_stake_program_address( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + ephemeral_stake_seed, + ) + .0; + + let error = stake_pool_accounts + .redelegate( + &mut context.banks_client, + &context.payer, + &last_blockhash, + &source_validator_stake.stake_account, + &source_validator_stake.transient_stake_account, + &ephemeral_stake, + &destination_validator_stake.transient_stake_account, + &destination_validator_stake.stake_account, + &destination_validator_stake.vote.pubkey(), + validator_stake_account.lamports, + source_validator_stake.transient_stake_seed, + ephemeral_stake_seed, + destination_validator_stake.transient_stake_seed, + ) + .await + .unwrap() + .unwrap(); + assert_eq!( + error, + TransactionError::InstructionError(0, InstructionError::InsufficientFunds) + ); +} diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 393e6504..2c426af0 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -472,6 +472,7 @@ async fn fail_with_unknown_validator() { &context.payer, &context.last_blockhash, &stake_pool_accounts.stake_pool.pubkey(), + 0, ) .await; diff --git a/program/tests/withdraw_edge_cases.rs b/program/tests/withdraw_edge_cases.rs index 84e9390f..b1abb9ce 100644 --- a/program/tests/withdraw_edge_cases.rs +++ b/program/tests/withdraw_edge_cases.rs @@ -486,10 +486,16 @@ async fn success_and_fail_with_preferred_withdraw() { tokens_to_burn, ) = setup_for_withdraw(spl_token::id()).await; + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&context.last_blockhash) + .await + .unwrap(); + let preferred_validator = simple_add_validator_to_pool( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &stake_pool_accounts, None, ) @@ -499,7 +505,7 @@ async fn success_and_fail_with_preferred_withdraw() { .set_preferred_validator( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, instruction::PreferredValidatorType::Withdraw, Some(preferred_validator.vote.pubkey()), ) @@ -508,7 +514,7 @@ async fn success_and_fail_with_preferred_withdraw() { let _preferred_deposit = simple_deposit_stake( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &stake_pool_accounts, &preferred_validator, TEST_STAKE_AMOUNT, @@ -521,7 +527,7 @@ async fn success_and_fail_with_preferred_withdraw() { .withdraw_stake( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &user_stake_recipient.pubkey(), &user_transfer_authority, &deposit_info.pool_account.pubkey(), @@ -540,13 +546,19 @@ async fn success_and_fail_with_preferred_withdraw() { ) ); + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&last_blockhash) + .await + .unwrap(); + // success from preferred let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts .withdraw_stake( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &user_stake_recipient.pubkey(), &user_transfer_authority, &deposit_info.pool_account.pubkey(), From 9bd18d3cbc2b8316a4bccf17d1e52c5bf35187a8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Jan 2023 00:11:27 +0100 Subject: [PATCH 0288/1076] build(deps): bump json5 from 2.2.0 to 2.2.3 in /stake-pool/js (#3952) Bumps [json5](https://github.com/json5/json5) from 2.2.0 to 2.2.3. - [Release notes](https://github.com/json5/json5/releases) - [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md) - [Commits](https://github.com/json5/json5/compare/v2.2.0...v2.2.3) --- updated-dependencies: - dependency-name: json5 dependency-type: indirect ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 32 +++++++---------------------- 1 file changed, 7 insertions(+), 25 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index a7e5e195..25ae2a8e 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -4495,13 +4495,10 @@ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, "node_modules/json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, "bin": { "json5": "lib/cli.js" }, @@ -4754,12 +4751,6 @@ "node": "*" } }, - "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -9648,13 +9639,10 @@ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true }, "jsonparse": { "version": "1.3.1", @@ -9846,12 +9834,6 @@ "brace-expansion": "^1.1.7" } }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", From e728d98fbdc914a43ed5948a1c944b477f40e867 Mon Sep 17 00:00:00 2001 From: Alexander Ray Date: Thu, 12 Jan 2023 19:56:06 +0100 Subject: [PATCH 0289/1076] stake-pool: add redelegate js bindings (#3960) * - add ts/js binding for redelegate functionality * - add redelegate instructions * - refactor * - force rebuild * - refactor * - force rebuild * - force rebuild --- clients/js-legacy/README.md | 2 +- clients/js-legacy/src/constants.ts | 3 + clients/js-legacy/src/index.ts | 174 +++++++++++-- clients/js-legacy/src/instructions.ts | 234 +++++++++++++++++- .../js-legacy/src/utils/program-address.ts | 19 +- clients/js-legacy/test/instructions.test.ts | 27 ++ clients/js-legacy/test/mocks.ts | 5 +- 7 files changed, 434 insertions(+), 30 deletions(-) diff --git a/clients/js-legacy/README.md b/clients/js-legacy/README.md index b4030d23..947ec739 100644 --- a/clients/js-legacy/README.md +++ b/clients/js-legacy/README.md @@ -51,4 +51,4 @@ console.log(solanaStakePool); ```javascript // `solanaStakePool` is provided in the global namespace by the script bundle. console.log(solanaStakePool); -``` \ No newline at end of file +``` diff --git a/clients/js-legacy/src/constants.ts b/clients/js-legacy/src/constants.ts index 447835fa..9423f7ce 100644 --- a/clients/js-legacy/src/constants.ts +++ b/clients/js-legacy/src/constants.ts @@ -7,6 +7,9 @@ export const STAKE_POOL_PROGRAM_ID = new PublicKey('SPoo1Ku8WFXoNDMHPsrGSTSG1Y47 // Maximum number of validators to update during UpdateValidatorListBalance. export const MAX_VALIDATORS_TO_UPDATE = 5; +// Seed for ephemeral stake account +export const EPHEMERAL_STAKE_SEED_PREFIX = Buffer.from('ephemeral'); + // Seed used to derive transient stake accounts. export const TRANSIENT_STAKE_SEED_PREFIX = Buffer.from('transient'); diff --git a/clients/js-legacy/src/index.ts b/clients/js-legacy/src/index.ts index 6cd146b3..d18495f4 100644 --- a/clients/js-legacy/src/index.ts +++ b/clients/js-legacy/src/index.ts @@ -24,6 +24,7 @@ import { prepareWithdrawAccounts, lamportsToSol, solToLamports, + findEphemeralStakeProgramAddress, } from './utils'; import { StakePoolInstruction } from './instructions'; import { @@ -36,6 +37,7 @@ import { } from './layouts'; import { MAX_VALIDATORS_TO_UPDATE, MINIMUM_ACTIVE_STAKE, STAKE_POOL_PROGRAM_ID } from './constants'; import { create } from 'superstruct'; +import BN from 'bn.js'; export type { StakePool, AccountType, ValidatorList, ValidatorStakeInfo } from './layouts'; export { STAKE_POOL_PROGRAM_ID } from './constants'; @@ -66,6 +68,17 @@ export interface StakePoolAccounts { validatorList: ValidatorListAccount | undefined; } +interface RedelegateProps { + connection: Connection; + stakePoolAddress: PublicKey; + sourceVoteAccount: PublicKey; + destinationVoteAccount: PublicKey; + sourceTransientStakeSeed: number | BN; + destinationTransientStakeSeed: number | BN; + ephemeralStakeSeed: number | BN; + lamports: number | BN; +} + /** * Retrieves and deserializes a StakePool account using a web3js connection and the stake pool address. * @param connection: An active web3js connection. @@ -401,7 +414,7 @@ export async function withdrawStake( val.voteAccountAddress.equals(voteAccount), ); if (voteAccountAddress && voteAccountAddress !== voteAccount) { - throw new Error(`Provided withdrawal vote account ${voteAccountAddress} does not match delegation on stake receiver account ${voteAccount}, + throw new Error(`Provided withdrawal vote account ${voteAccountAddress} does not match delegation on stake receiver account ${voteAccount}, remove this flag or provide a different stake account delegated to ${voteAccountAddress}`); } if (isValidVoter) { @@ -668,6 +681,7 @@ export async function increaseValidatorStake( stakePoolAddress: PublicKey, validatorVote: PublicKey, lamports: number, + ephemeralStakeSeed?: number, ) { const stakePool = await getStakePoolAccount(connection, stakePoolAddress); @@ -705,8 +719,14 @@ export async function increaseValidatorStake( ); const instructions: TransactionInstruction[] = []; - instructions.push( - StakePoolInstruction.increaseValidatorStake({ + + if (ephemeralStakeSeed != undefined) { + const ephemeralStake = await findEphemeralStakeProgramAddress( + STAKE_POOL_PROGRAM_ID, + stakePoolAddress, + new BN(ephemeralStakeSeed), + ); + StakePoolInstruction.increaseAdditionalValidatorStake({ stakePool: stakePoolAddress, staker: stakePool.account.data.staker, validatorList: stakePool.account.data.validatorList, @@ -717,8 +737,25 @@ export async function increaseValidatorStake( validatorStake, validatorVote, lamports, - }), - ); + ephemeralStake, + ephemeralStakeSeed, + }); + } else { + instructions.push( + StakePoolInstruction.increaseValidatorStake({ + stakePool: stakePoolAddress, + staker: stakePool.account.data.staker, + validatorList: stakePool.account.data.validatorList, + reserveStake: stakePool.account.data.reserveStake, + transientStakeSeed: transientStakeSeed.toNumber(), + withdrawAuthority, + transientStake, + validatorStake, + validatorVote, + lamports, + }), + ); + } return { instructions, @@ -733,6 +770,7 @@ export async function decreaseValidatorStake( stakePoolAddress: PublicKey, validatorVote: PublicKey, lamports: number, + ephemeralStakeSeed?: number, ) { const stakePool = await getStakePoolAccount(connection, stakePoolAddress); const validatorList = await getValidatorListAccount( @@ -769,18 +807,41 @@ export async function decreaseValidatorStake( ); const instructions: TransactionInstruction[] = []; - instructions.push( - StakePoolInstruction.decreaseValidatorStake({ - stakePool: stakePoolAddress, - staker: stakePool.account.data.staker, - validatorList: stakePool.account.data.validatorList, - transientStakeSeed: transientStakeSeed.toNumber(), - withdrawAuthority, - validatorStake, - transientStake, - lamports, - }), - ); + + if (ephemeralStakeSeed != undefined) { + const ephemeralStake = await findEphemeralStakeProgramAddress( + STAKE_POOL_PROGRAM_ID, + stakePoolAddress, + new BN(ephemeralStakeSeed), + ); + instructions.push( + StakePoolInstruction.decreaseAdditionalValidatorStake({ + stakePool: stakePoolAddress, + staker: stakePool.account.data.staker, + validatorList: stakePool.account.data.validatorList, + transientStakeSeed: transientStakeSeed.toNumber(), + withdrawAuthority, + validatorStake, + transientStake, + lamports, + ephemeralStake, + ephemeralStakeSeed, + }), + ); + } else { + instructions.push( + StakePoolInstruction.decreaseValidatorStake({ + stakePool: stakePoolAddress, + staker: stakePool.account.data.staker, + validatorList: stakePool.account.data.validatorList, + transientStakeSeed: transientStakeSeed.toNumber(), + withdrawAuthority, + validatorStake, + transientStake, + lamports, + }), + ); + } return { instructions, @@ -993,3 +1054,82 @@ export async function stakePoolInfo(connection: Connection, stakePoolAddress: Pu }, // CliStakePoolDetails }; } + +/** + * Creates instructions required to redelegate stake. + */ +export async function redelegate(props: RedelegateProps) { + const { + connection, + stakePoolAddress, + sourceVoteAccount, + sourceTransientStakeSeed, + destinationVoteAccount, + destinationTransientStakeSeed, + ephemeralStakeSeed, + lamports, + } = props; + const stakePool = await getStakePoolAccount(connection, stakePoolAddress); + + const stakePoolWithdrawAuthority = await findWithdrawAuthorityProgramAddress( + STAKE_POOL_PROGRAM_ID, + stakePoolAddress, + ); + + const sourceValidatorStake = await findStakeProgramAddress( + STAKE_POOL_PROGRAM_ID, + sourceVoteAccount, + stakePoolAddress, + ); + + const sourceTransientStake = await findTransientStakeProgramAddress( + STAKE_POOL_PROGRAM_ID, + sourceVoteAccount, + stakePoolAddress, + new BN(sourceTransientStakeSeed), + ); + + const destinationValidatorStake = await findStakeProgramAddress( + STAKE_POOL_PROGRAM_ID, + destinationVoteAccount, + stakePoolAddress, + ); + + const destinationTransientStake = await findTransientStakeProgramAddress( + STAKE_POOL_PROGRAM_ID, + destinationVoteAccount, + stakePoolAddress, + new BN(destinationTransientStakeSeed), + ); + + const ephemeralStake = await findEphemeralStakeProgramAddress( + STAKE_POOL_PROGRAM_ID, + stakePoolAddress, + new BN(ephemeralStakeSeed), + ); + + const instructions: TransactionInstruction[] = []; + + instructions.push( + StakePoolInstruction.redelegate({ + stakePool: stakePool.pubkey, + staker: stakePool.account.data.staker, + validatorList: stakePool.account.data.validatorList, + stakePoolWithdrawAuthority, + ephemeralStake, + ephemeralStakeSeed, + sourceValidatorStake, + sourceTransientStake, + sourceTransientStakeSeed, + destinationValidatorStake, + destinationTransientStake, + destinationTransientStakeSeed, + validator: destinationVoteAccount, + lamports, + }), + ); + + return { + instructions, + }; +} diff --git a/clients/js-legacy/src/instructions.ts b/clients/js-legacy/src/instructions.ts index babcc2cd..bfc35f38 100644 --- a/clients/js-legacy/src/instructions.ts +++ b/clients/js-legacy/src/instructions.ts @@ -12,6 +12,7 @@ import * as BufferLayout from '@solana/buffer-layout'; import { TOKEN_PROGRAM_ID } from '@solana/spl-token'; import { STAKE_POOL_PROGRAM_ID } from './constants'; import { InstructionType, encodeData, decodeData } from './utils'; +import BN from 'bn.js'; /** * An enumeration of valid StakePoolInstructionType's @@ -25,7 +26,10 @@ export type StakePoolInstructionType = | 'DepositStake' | 'DepositSol' | 'WithdrawStake' - | 'WithdrawSol'; + | 'WithdrawSol' + | 'IncreaseAdditionalValidatorStake' + | 'DecreaseAdditionalValidatorStake' + | 'Redelegate'; const MOVE_STAKE_LAYOUT = BufferLayout.struct([ BufferLayout.u8('instruction'), @@ -96,6 +100,40 @@ export const STAKE_POOL_INSTRUCTION_LAYOUTS: { BufferLayout.ns64('poolTokens'), ]), }, + IncreaseAdditionalValidatorStake: { + index: 19, + layout: BufferLayout.struct([ + BufferLayout.u8('instruction'), + BufferLayout.ns64('lamports'), + BufferLayout.ns64('transientStakeSeed'), + BufferLayout.ns64('ephemeralStakeSeed'), + ]), + }, + DecreaseAdditionalValidatorStake: { + index: 20, + layout: BufferLayout.struct([ + BufferLayout.u8('instruction'), + BufferLayout.ns64('lamports'), + BufferLayout.ns64('transientStakeSeed'), + BufferLayout.ns64('ephemeralStakeSeed'), + ]), + }, + Redelegate: { + index: 21, + layout: BufferLayout.struct([ + BufferLayout.u8('instruction'), + /// Amount of lamports to redelegate + BufferLayout.ns64('lamports'), + /// Seed used to create source transient stake account + BufferLayout.ns64('sourceTransientStakeSeed'), + /// Seed used to create destination ephemeral account. + BufferLayout.ns64('ephemeralStakeSeed'), + /// Seed used to create destination transient stake account. If there is + /// already transient stake, this must match the current seed, otherwise + /// it can be anything + BufferLayout.ns64('destinationTransientStakeSeed'), + ]), + }, }); /** @@ -141,12 +179,17 @@ export type DecreaseValidatorStakeParams = { validatorList: PublicKey; validatorStake: PublicKey; transientStake: PublicKey; - // Amount of lamports to split into the transient stake account. + // Amount of lamports to split into the transient stake account lamports: number; - // Seed to used to create the transient stake account. + // Seed to used to create the transient stake account transientStakeSeed: number; }; +export interface DecreaseAdditionalValidatorStakeParams extends DecreaseValidatorStakeParams { + ephemeralStake: PublicKey; + ephemeralStakeSeed: number; +} + /** * (Staker only) Increase stake on a validator from the reserve account. */ @@ -159,12 +202,17 @@ export type IncreaseValidatorStakeParams = { transientStake: PublicKey; validatorStake: PublicKey; validatorVote: PublicKey; - // Amount of lamports to split into the transient stake account. + // Amount of lamports to split into the transient stake account lamports: number; - // Seed to used to create the transient stake account. + // Seed to used to create the transient stake account transientStakeSeed: number; }; +export interface IncreaseAdditionalValidatorStakeParams extends IncreaseValidatorStakeParams { + ephemeralStake: PublicKey; + ephemeralStakeSeed: number; +} + /** * Deposits a stake account into the pool in exchange for pool tokens */ @@ -232,6 +280,29 @@ export type DepositSolParams = { lamports: number; }; +export type RedelegateParams = { + stakePool: PublicKey; + staker: PublicKey; + stakePoolWithdrawAuthority: PublicKey; + validatorList: PublicKey; + sourceValidatorStake: PublicKey; + sourceTransientStake: PublicKey; + ephemeralStake: PublicKey; + destinationTransientStake: PublicKey; + destinationValidatorStake: PublicKey; + validator: PublicKey; + // Amount of lamports to redelegate + lamports: number | BN; + // Seed used to create source transient stake account + sourceTransientStakeSeed: number | BN; + // Seed used to create destination ephemeral account + ephemeralStakeSeed: number | BN; + // Seed used to create destination transient stake account. If there is + // already transient stake, this must match the current seed, otherwise + // it can be anything + destinationTransientStakeSeed: number | BN; +}; + /** * Stake Pool Instruction class */ @@ -334,7 +405,8 @@ export class StakePoolInstruction { } /** - * Creates instruction to increase the stake on a validator. + * Creates `IncreaseValidatorStake` instruction (rebalance from reserve account to + * transient account) */ static increaseValidatorStake(params: IncreaseValidatorStakeParams): TransactionInstruction { const { @@ -378,7 +450,57 @@ export class StakePoolInstruction { } /** - * Creates instruction to decrease the stake on a validator. + * Creates `IncreaseAdditionalValidatorStake` instruction (rebalance from reserve account to + * transient account) + */ + static increaseAdditionalValidatorStake( + params: IncreaseAdditionalValidatorStakeParams, + ): TransactionInstruction { + const { + stakePool, + staker, + withdrawAuthority, + validatorList, + reserveStake, + transientStake, + validatorStake, + validatorVote, + lamports, + transientStakeSeed, + ephemeralStake, + ephemeralStakeSeed, + } = params; + + const type = STAKE_POOL_INSTRUCTION_LAYOUTS.IncreaseAdditionalValidatorStake; + const data = encodeData(type, { lamports, transientStakeSeed, ephemeralStakeSeed }); + + const keys = [ + { pubkey: stakePool, isSigner: false, isWritable: false }, + { pubkey: staker, isSigner: true, isWritable: false }, + { pubkey: withdrawAuthority, isSigner: false, isWritable: false }, + { pubkey: validatorList, isSigner: false, isWritable: true }, + { pubkey: reserveStake, isSigner: false, isWritable: true }, + { pubkey: ephemeralStake, isSigner: false, isWritable: true }, + { pubkey: transientStake, isSigner: false, isWritable: true }, + { pubkey: validatorStake, isSigner: false, isWritable: false }, + { pubkey: validatorVote, isSigner: false, isWritable: false }, + { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false }, + { pubkey: SYSVAR_STAKE_HISTORY_PUBKEY, isSigner: false, isWritable: false }, + { pubkey: STAKE_CONFIG_ID, isSigner: false, isWritable: false }, + { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, + { pubkey: StakeProgram.programId, isSigner: false, isWritable: false }, + ]; + + return new TransactionInstruction({ + programId: STAKE_POOL_PROGRAM_ID, + keys, + data, + }); + } + + /** + * Creates `DecreaseValidatorStake` instruction (rebalance from validator account to + * transient account) */ static decreaseValidatorStake(params: DecreaseValidatorStakeParams): TransactionInstruction { const { @@ -415,6 +537,50 @@ export class StakePoolInstruction { }); } + /** + * Creates `DecreaseAdditionalValidatorStake` instruction (rebalance from + * validator account to transient account) + */ + static decreaseAdditionalValidatorStake( + params: DecreaseAdditionalValidatorStakeParams, + ): TransactionInstruction { + const { + stakePool, + staker, + withdrawAuthority, + validatorList, + validatorStake, + transientStake, + lamports, + transientStakeSeed, + ephemeralStakeSeed, + ephemeralStake, + } = params; + + const type = STAKE_POOL_INSTRUCTION_LAYOUTS.DecreaseAdditionalValidatorStake; + const data = encodeData(type, { lamports, transientStakeSeed, ephemeralStakeSeed }); + + const keys = [ + { pubkey: stakePool, isSigner: false, isWritable: false }, + { pubkey: staker, isSigner: true, isWritable: false }, + { pubkey: withdrawAuthority, isSigner: false, isWritable: false }, + { pubkey: validatorList, isSigner: false, isWritable: true }, + { pubkey: validatorStake, isSigner: false, isWritable: true }, + { pubkey: ephemeralStake, isSigner: false, isWritable: true }, + { pubkey: transientStake, isSigner: false, isWritable: true }, + { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false }, + { pubkey: SYSVAR_STAKE_HISTORY_PUBKEY, isSigner: false, isWritable: false }, + { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, + { pubkey: StakeProgram.programId, isSigner: false, isWritable: false }, + ]; + + return new TransactionInstruction({ + programId: STAKE_POOL_PROGRAM_ID, + keys, + data, + }); + } + /** * Creates a transaction instruction to deposit a stake account into a stake pool. */ @@ -603,6 +769,60 @@ export class StakePoolInstruction { }); } + /** + * Creates `Redelegate` instruction (rebalance from one validator account to another) + * @param params + */ + static redelegate(params: RedelegateParams): TransactionInstruction { + const { + stakePool, + staker, + stakePoolWithdrawAuthority, + validatorList, + sourceValidatorStake, + sourceTransientStake, + ephemeralStake, + destinationTransientStake, + destinationValidatorStake, + validator, + lamports, + sourceTransientStakeSeed, + ephemeralStakeSeed, + destinationTransientStakeSeed, + } = params; + + const keys = [ + { pubkey: stakePool, isSigner: false, isWritable: false }, + { pubkey: staker, isSigner: true, isWritable: false }, + { pubkey: stakePoolWithdrawAuthority, isSigner: false, isWritable: false }, + { pubkey: validatorList, isSigner: false, isWritable: true }, + { pubkey: sourceValidatorStake, isSigner: false, isWritable: true }, + { pubkey: sourceTransientStake, isSigner: false, isWritable: true }, + { pubkey: ephemeralStake, isSigner: false, isWritable: true }, + { pubkey: destinationTransientStake, isSigner: false, isWritable: true }, + { pubkey: destinationValidatorStake, isSigner: false, isWritable: false }, + { pubkey: validator, isSigner: false, isWritable: false }, + { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false }, + { pubkey: SYSVAR_STAKE_HISTORY_PUBKEY, isSigner: false, isWritable: false }, + { pubkey: STAKE_CONFIG_ID, isSigner: false, isWritable: false }, + { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, + { pubkey: StakeProgram.programId, isSigner: false, isWritable: false }, + ]; + + const data = encodeData(STAKE_POOL_INSTRUCTION_LAYOUTS.Redelegate, { + lamports, + sourceTransientStakeSeed, + ephemeralStakeSeed, + destinationTransientStakeSeed, + }); + + return new TransactionInstruction({ + programId: STAKE_POOL_PROGRAM_ID, + keys, + data, + }); + } + /** * Decode a deposit stake pool instruction and retrieve the instruction params. */ diff --git a/clients/js-legacy/src/utils/program-address.ts b/clients/js-legacy/src/utils/program-address.ts index 2eb364c1..7d198235 100644 --- a/clients/js-legacy/src/utils/program-address.ts +++ b/clients/js-legacy/src/utils/program-address.ts @@ -1,7 +1,7 @@ import { PublicKey } from '@solana/web3.js'; import BN from 'bn.js'; import { Buffer } from 'buffer'; -import { TRANSIENT_STAKE_SEED_PREFIX } from '../constants'; +import { EPHEMERAL_STAKE_SEED_PREFIX, TRANSIENT_STAKE_SEED_PREFIX } from '../constants'; /** * Generates the withdraw authority program address for the stake pool @@ -46,9 +46,24 @@ export async function findTransientStakeProgramAddress( TRANSIENT_STAKE_SEED_PREFIX, voteAccountAddress.toBuffer(), stakePoolAddress.toBuffer(), - new Uint8Array(seed.toArray('le', 8)), + seed.toBuffer('le', 8), ], programId, ); return publicKey; } + +/** + * Generates the ephemeral program address for stake pool redelegation + */ +export async function findEphemeralStakeProgramAddress( + programId: PublicKey, + stakePoolAddress: PublicKey, + seed: BN, +) { + const [publicKey] = await PublicKey.findProgramAddress( + [EPHEMERAL_STAKE_SEED_PREFIX, stakePoolAddress.toBuffer(), seed.toBuffer('le', 8)], + programId, + ); + return publicKey; +} diff --git a/clients/js-legacy/test/instructions.test.ts b/clients/js-legacy/test/instructions.test.ts index 458eb0cb..204d85d5 100644 --- a/clients/js-legacy/test/instructions.test.ts +++ b/clients/js-legacy/test/instructions.test.ts @@ -15,6 +15,7 @@ import { depositSol, withdrawSol, withdrawStake, + redelegate, getStakeAccount, } from '../src'; @@ -317,4 +318,30 @@ describe('StakePoolProgram', () => { expect(parsedStakeAccount).toEqual(uninitializedStakeAccount.parsed); }); }); + + describe('redelegation', () => { + it.only('should call successfully', async () => { + const data = { + connection, + stakePoolAddress, + sourceVoteAccount: PublicKey.default, + sourceTransientStakeSeed: 10, + destinationVoteAccount: PublicKey.default, + destinationTransientStakeSeed: 20, + ephemeralStakeSeed: 100, + lamports: 100, + }; + const res = await redelegate(data); + + const decodedData = STAKE_POOL_INSTRUCTION_LAYOUTS.Redelegate.layout.decode( + res.instructions[0].data, + ); + + expect(decodedData.instruction).toBe(21); + expect(decodedData.lamports).toBe(data.lamports); + expect(decodedData.sourceTransientStakeSeed).toBe(data.sourceTransientStakeSeed); + expect(decodedData.destinationTransientStakeSeed).toBe(data.destinationTransientStakeSeed); + expect(decodedData.ephemeralStakeSeed).toBe(data.ephemeralStakeSeed); + }); + }); }); diff --git a/clients/js-legacy/test/mocks.ts b/clients/js-legacy/test/mocks.ts index db93fa5a..dd123dc4 100644 --- a/clients/js-legacy/test/mocks.ts +++ b/clients/js-legacy/test/mocks.ts @@ -1,7 +1,7 @@ import { AccountInfo, LAMPORTS_PER_SOL, PublicKey, StakeProgram } from '@solana/web3.js'; import BN from 'bn.js'; import { ValidatorStakeInfo } from '../src'; -import { ValidatorStakeInfoStatus, AccountLayout, ValidatorListLayout } from '../src/layouts'; +import { AccountLayout, ValidatorListLayout, ValidatorStakeInfoStatus } from '../src/layouts'; export const CONSTANTS = { poolTokenAccount: new PublicKey( @@ -149,13 +149,12 @@ export const mockRpc = (data: any): any => { executable: false, rentEpoch: 0, }; - const result = { + return { context: { slot: 11, }, value: value, }; - return result; }; export const stakeAccountData = { From 5392137a831bd017708176c29cfc672796d2cba0 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 18 Jan 2023 19:18:02 +0100 Subject: [PATCH 0290/1076] stake-pool: Refresh blockhash more on failing test (#3981) --- program/tests/withdraw_edge_cases.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/program/tests/withdraw_edge_cases.rs b/program/tests/withdraw_edge_cases.rs index b1abb9ce..ef14e250 100644 --- a/program/tests/withdraw_edge_cases.rs +++ b/program/tests/withdraw_edge_cases.rs @@ -725,11 +725,17 @@ async fn success_with_small_preferred_withdraw() { tokens_to_burn, ) = setup_for_withdraw(spl_token::id()).await; + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&context.last_blockhash) + .await + .unwrap(); + // make pool tokens very valuable, so it isn't possible to exactly get down to the minimum transfer( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &stake_pool_accounts.reserve_stake.pubkey(), deposit_info.stake_lamports * 5, // each pool token is worth more than one lamport ) @@ -738,7 +744,7 @@ async fn success_with_small_preferred_withdraw() { .update_all( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &[validator_stake.vote.pubkey()], false, ) @@ -747,7 +753,7 @@ async fn success_with_small_preferred_withdraw() { let preferred_validator = simple_add_validator_to_pool( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &stake_pool_accounts, None, ) @@ -757,7 +763,7 @@ async fn success_with_small_preferred_withdraw() { .set_preferred_validator( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, instruction::PreferredValidatorType::Withdraw, Some(preferred_validator.vote.pubkey()), ) @@ -765,7 +771,7 @@ async fn success_with_small_preferred_withdraw() { let last_blockhash = context .banks_client - .get_new_latest_blockhash(&context.last_blockhash) + .get_new_latest_blockhash(&last_blockhash) .await .unwrap(); From 96a2b517b1525973579a78789ccd3fabcbb710eb Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 18 Jan 2023 22:40:20 +0100 Subject: [PATCH 0291/1076] stake-pool: Refresh blockhash more in another test (#3982) --- program/tests/withdraw_with_fee.rs | 48 +++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/program/tests/withdraw_with_fee.rs b/program/tests/withdraw_with_fee.rs index 866367b4..1817ba40 100644 --- a/program/tests/withdraw_with_fee.rs +++ b/program/tests/withdraw_with_fee.rs @@ -24,11 +24,17 @@ async fn success_withdraw_all_fee_tokens() { tokens_to_withdraw, ) = setup_for_withdraw(spl_token::id()).await; + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&context.last_blockhash) + .await + .unwrap(); + // move tokens to fee account transfer_spl_tokens( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &stake_pool_accounts.token_program_id, &deposit_info.pool_account.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), @@ -49,7 +55,7 @@ async fn success_withdraw_all_fee_tokens() { delegate_tokens( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &stake_pool_accounts.token_program_id, &stake_pool_accounts.pool_fee_account.pubkey(), &stake_pool_accounts.manager, @@ -63,7 +69,7 @@ async fn success_withdraw_all_fee_tokens() { .withdraw_stake( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &user_stake_recipient.pubkey(), &user_transfer_authority, &stake_pool_accounts.pool_fee_account.pubkey(), @@ -95,11 +101,17 @@ async fn success_empty_out_stake_with_fee() { tokens_to_withdraw, ) = setup_for_withdraw(spl_token::id()).await; + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&context.last_blockhash) + .await + .unwrap(); + // add another validator and deposit into it let other_validator_stake_account = simple_add_validator_to_pool( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &stake_pool_accounts, None, ) @@ -108,7 +120,7 @@ async fn success_empty_out_stake_with_fee() { let other_deposit_info = simple_deposit_stake( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &stake_pool_accounts, &other_validator_stake_account, TEST_STAKE_AMOUNT, @@ -120,7 +132,7 @@ async fn success_empty_out_stake_with_fee() { transfer_spl_tokens( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &stake_pool_accounts.token_program_id, &deposit_info.pool_account.pubkey(), &stake_pool_accounts.pool_mint.pubkey(), @@ -137,11 +149,17 @@ async fn success_empty_out_stake_with_fee() { ) .await; + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&last_blockhash) + .await + .unwrap(); + let user_transfer_authority = Keypair::new(); delegate_tokens( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &stake_pool_accounts.token_program_id, &other_deposit_info.pool_account.pubkey(), &other_deposit_info.authority, @@ -160,12 +178,9 @@ async fn success_empty_out_stake_with_fee() { let stake_state = deserialize::(&validator_stake_account.data).unwrap(); let meta = stake_state.meta().unwrap(); - let stake_minimum_delegation = stake_get_minimum_delegation( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - ) - .await; + let stake_minimum_delegation = + stake_get_minimum_delegation(&mut context.banks_client, &context.payer, &last_blockhash) + .await; let lamports_to_withdraw = validator_stake_account.lamports - minimum_stake_lamports(&meta, stake_minimum_delegation); let stake_pool_account = get_account( @@ -183,12 +198,17 @@ async fn success_empty_out_stake_with_fee() { let pool_tokens_to_withdraw = lamports_to_withdraw * inverse_fee.denominator / inverse_fee.numerator; + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&last_blockhash) + .await + .unwrap(); let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts .withdraw_stake( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &user_stake_recipient.pubkey(), &user_transfer_authority, &other_deposit_info.pool_account.pubkey(), From 5963147836e112d1ea86be27365aff722c8ff7a8 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 19 Jan 2023 21:47:03 +0100 Subject: [PATCH 0292/1076] ci: Update repo to Solana 1.14.12 (#3989) --- clients/cli/Cargo.toml | 18 +++++++++--------- program/Cargo.toml | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index be39c048..5265b607 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -14,15 +14,15 @@ clap = "2.33.3" serde = "1.0.130" serde_derive = "1.0.130" serde_json = "1.0.68" -solana-account-decoder = "=1.14.10" -solana-clap-utils = "=1.14.10" -solana-cli-config = "=1.14.10" -solana-cli-output = "=1.14.10" -solana-client = "=1.14.10" -solana-logger = "=1.14.10" -solana-program = "=1.14.10" -solana-remote-wallet = "=1.14.10" -solana-sdk = "=1.14.10" +solana-account-decoder = "=1.14.12" +solana-clap-utils = "=1.14.12" +solana-cli-config = "=1.14.12" +solana-cli-output = "=1.14.12" +solana-client = "=1.14.12" +solana-logger = "=1.14.12" +solana-program = "=1.14.12" +solana-remote-wallet = "=1.14.12" +solana-sdk = "=1.14.12" spl-associated-token-account = { version = "=1.1.2", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "=0.7.0", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "=3.5.0", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/program/Cargo.toml b/program/Cargo.toml index 3df76911..9073216d 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -20,7 +20,7 @@ num-traits = "0.2" num_enum = "0.5.4" serde = "1.0.130" serde_derive = "1.0.103" -solana-program = "1.14.10" +solana-program = "1.14.12" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-token-2022 = { version = "0.5", path = "../../token/program-2022", features = [ "no-entrypoint" ] } thiserror = "1.0" @@ -28,9 +28,9 @@ bincode = "1.3.1" [dev-dependencies] proptest = "1.0" -solana-program-test = "1.14.10" -solana-sdk = "1.14.10" -solana-vote-program = "1.14.10" +solana-program-test = "1.14.12" +solana-sdk = "1.14.12" +solana-vote-program = "1.14.12" spl-token = { version = "3.5", path = "../../token/program", features = [ "no-entrypoint" ] } test-case = "2.2" From 8e57d32a8c63766d5f195a4d2495b9bf8f5e251f Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 19 Jan 2023 21:47:16 +0100 Subject: [PATCH 0293/1076] stake-pool: Refresh blockhash earlier (#3988) --- program/tests/withdraw.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 2c426af0..63d2c76e 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -632,22 +632,22 @@ async fn fail_with_not_enough_tokens() { tokens_to_burn, ) = setup_for_withdraw(spl_token::id()).await; + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&context.last_blockhash) + .await + .unwrap(); + // Empty validator stake account let empty_stake_account = simple_add_validator_to_pool( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &stake_pool_accounts, None, ) .await; - let last_blockhash = context - .banks_client - .get_new_latest_blockhash(&context.last_blockhash) - .await - .unwrap(); - let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts .withdraw_stake( From 784721cf9e322c4ed702629bbf997a475f83ffd6 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 27 Jan 2023 02:10:24 +0100 Subject: [PATCH 0294/1076] stake-pool: Wait at least two epoch boundaries to set fee (#3979) --- clients/cli/src/output.rs | 9 +- program/src/processor.rs | 32 +-- program/src/state.rs | 68 ++++++- program/tests/helpers/mod.rs | 8 +- program/tests/set_epoch_fee.rs | 33 ++- program/tests/set_withdrawal_fee.rs | 304 ++++++++++++++++++++++++++-- 6 files changed, 403 insertions(+), 51 deletions(-) diff --git a/clients/cli/src/output.rs b/clients/cli/src/output.rs index f9b0cd27..097e9334 100644 --- a/clients/cli/src/output.rs +++ b/clients/cli/src/output.rs @@ -475,7 +475,8 @@ impl From<(Pubkey, StakePool, ValidatorList, Pubkey)> for CliStakePool { last_update_epoch: stake_pool.last_update_epoch, lockup: CliStakePoolLockup::from(stake_pool.lockup), epoch_fee: CliStakePoolFee::from(stake_pool.epoch_fee), - next_epoch_fee: stake_pool.next_epoch_fee.map(CliStakePoolFee::from), + next_epoch_fee: Option::::from(stake_pool.next_epoch_fee) + .map(CliStakePoolFee::from), preferred_deposit_validator_vote_address: stake_pool .preferred_deposit_validator_vote_address .map(|x| x.to_string()), @@ -484,8 +485,7 @@ impl From<(Pubkey, StakePool, ValidatorList, Pubkey)> for CliStakePool { .map(|x| x.to_string()), stake_deposit_fee: CliStakePoolFee::from(stake_pool.stake_deposit_fee), stake_withdrawal_fee: CliStakePoolFee::from(stake_pool.stake_withdrawal_fee), - next_stake_withdrawal_fee: stake_pool - .next_stake_withdrawal_fee + next_stake_withdrawal_fee: Option::::from(stake_pool.next_stake_withdrawal_fee) .map(CliStakePoolFee::from), stake_referral_fee: stake_pool.stake_referral_fee, sol_deposit_authority: stake_pool.sol_deposit_authority.map(|x| x.to_string()), @@ -493,8 +493,7 @@ impl From<(Pubkey, StakePool, ValidatorList, Pubkey)> for CliStakePool { sol_referral_fee: stake_pool.sol_referral_fee, sol_withdraw_authority: stake_pool.sol_withdraw_authority.map(|x| x.to_string()), sol_withdrawal_fee: CliStakePoolFee::from(stake_pool.sol_withdrawal_fee), - next_sol_withdrawal_fee: stake_pool - .next_sol_withdrawal_fee + next_sol_withdrawal_fee: Option::::from(stake_pool.next_sol_withdrawal_fee) .map(CliStakePoolFee::from), last_epoch_pool_token_supply: stake_pool.last_epoch_pool_token_supply, last_epoch_total_lamports: stake_pool.last_epoch_total_lamports, diff --git a/program/src/processor.rs b/program/src/processor.rs index 33355dc0..9ffffd01 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -7,8 +7,9 @@ use { instruction::{FundingType, PreferredValidatorType, StakePoolInstruction}, minimum_delegation, minimum_reserve_lamports, minimum_stake_lamports, state::{ - is_extension_supported_for_mint, AccountType, Fee, FeeType, StakePool, StakeStatus, - StakeWithdrawSource, ValidatorList, ValidatorListHeader, ValidatorStakeInfo, + is_extension_supported_for_mint, AccountType, Fee, FeeType, FutureEpoch, StakePool, + StakeStatus, StakeWithdrawSource, ValidatorList, ValidatorListHeader, + ValidatorStakeInfo, }, AUTHORITY_DEPOSIT, AUTHORITY_WITHDRAW, EPHEMERAL_STAKE_SEED_PREFIX, TRANSIENT_STAKE_SEED_PREFIX, @@ -905,19 +906,19 @@ impl Processor { stake_pool.last_update_epoch = Clock::get()?.epoch; stake_pool.lockup = stake::state::Lockup::default(); stake_pool.epoch_fee = epoch_fee; - stake_pool.next_epoch_fee = None; + stake_pool.next_epoch_fee = FutureEpoch::None; stake_pool.preferred_deposit_validator_vote_address = None; stake_pool.preferred_withdraw_validator_vote_address = None; stake_pool.stake_deposit_fee = deposit_fee; stake_pool.stake_withdrawal_fee = withdrawal_fee; - stake_pool.next_stake_withdrawal_fee = None; + stake_pool.next_stake_withdrawal_fee = FutureEpoch::None; stake_pool.stake_referral_fee = referral_fee; stake_pool.sol_deposit_authority = sol_deposit_authority; stake_pool.sol_deposit_fee = deposit_fee; stake_pool.sol_referral_fee = referral_fee; stake_pool.sol_withdraw_authority = None; stake_pool.sol_withdrawal_fee = withdrawal_fee; - stake_pool.next_sol_withdrawal_fee = None; + stake_pool.next_sol_withdrawal_fee = FutureEpoch::None; stake_pool.last_epoch_pool_token_supply = 0; stake_pool.last_epoch_total_lamports = 0; @@ -2532,18 +2533,21 @@ impl Processor { } if stake_pool.last_update_epoch < clock.epoch { - if let Some(fee) = stake_pool.next_epoch_fee { - stake_pool.epoch_fee = fee; - stake_pool.next_epoch_fee = None; + if let Some(fee) = stake_pool.next_epoch_fee.get() { + stake_pool.epoch_fee = *fee; } - if let Some(fee) = stake_pool.next_stake_withdrawal_fee { - stake_pool.stake_withdrawal_fee = fee; - stake_pool.next_stake_withdrawal_fee = None; + stake_pool.next_epoch_fee.update_epoch(); + + if let Some(fee) = stake_pool.next_stake_withdrawal_fee.get() { + stake_pool.stake_withdrawal_fee = *fee; } - if let Some(fee) = stake_pool.next_sol_withdrawal_fee { - stake_pool.sol_withdrawal_fee = fee; - stake_pool.next_sol_withdrawal_fee = None; + stake_pool.next_stake_withdrawal_fee.update_epoch(); + + if let Some(fee) = stake_pool.next_sol_withdrawal_fee.get() { + stake_pool.sol_withdrawal_fee = *fee; } + stake_pool.next_sol_withdrawal_fee.update_epoch(); + stake_pool.last_update_epoch = clock.epoch; stake_pool.last_epoch_total_lamports = previous_lamports; stake_pool.last_epoch_pool_token_supply = previous_pool_token_supply; diff --git a/program/src/state.rs b/program/src/state.rs index 1a601d99..30b2ef43 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -104,7 +104,7 @@ pub struct StakePool { pub epoch_fee: Fee, /// Fee for next epoch - pub next_epoch_fee: Option, + pub next_epoch_fee: FutureEpoch, /// Preferred deposit validator vote account pubkey pub preferred_deposit_validator_vote_address: Option, @@ -119,7 +119,7 @@ pub struct StakePool { pub stake_withdrawal_fee: Fee, /// Future stake withdrawal fee, to be set for the following epoch - pub next_stake_withdrawal_fee: Option, + pub next_stake_withdrawal_fee: FutureEpoch, /// Fees paid out to referrers on referred stake deposits. /// Expressed as a percentage (0 - 100) of deposit fees. @@ -148,7 +148,7 @@ pub struct StakePool { pub sol_withdrawal_fee: Fee, /// Future SOL withdrawal fee, to be set for the following epoch - pub next_sol_withdrawal_fee: Option, + pub next_sol_withdrawal_fee: FutureEpoch, /// Last epoch's total pool tokens, used only for APR estimation pub last_epoch_pool_token_supply: u64, @@ -483,14 +483,14 @@ impl StakePool { match fee { FeeType::SolReferral(new_fee) => self.sol_referral_fee = *new_fee, FeeType::StakeReferral(new_fee) => self.stake_referral_fee = *new_fee, - FeeType::Epoch(new_fee) => self.next_epoch_fee = Some(*new_fee), + FeeType::Epoch(new_fee) => self.next_epoch_fee = FutureEpoch::new(*new_fee), FeeType::StakeWithdrawal(new_fee) => { new_fee.check_withdrawal(&self.stake_withdrawal_fee)?; - self.next_stake_withdrawal_fee = Some(*new_fee) + self.next_stake_withdrawal_fee = FutureEpoch::new(*new_fee) } FeeType::SolWithdrawal(new_fee) => { new_fee.check_withdrawal(&self.sol_withdrawal_fee)?; - self.next_sol_withdrawal_fee = Some(*new_fee) + self.next_sol_withdrawal_fee = FutureEpoch::new(*new_fee) } FeeType::SolDeposit(new_fee) => self.sol_deposit_fee = *new_fee, FeeType::StakeDeposit(new_fee) => self.stake_deposit_fee = *new_fee, @@ -793,6 +793,62 @@ impl ValidatorListHeader { } } +/// Wrapper type that "counts down" epochs, which is Borsh-compatible with the +/// native `Option` +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq, BorshSerialize, BorshDeserialize, BorshSchema)] +pub enum FutureEpoch { + /// Nothing is set + None, + /// Value is ready after the next epoch boundary + One(T), + /// Value is ready after two epoch boundaries + Two(T), +} +impl Default for FutureEpoch { + fn default() -> Self { + Self::None + } +} +impl FutureEpoch { + /// Create a new value to be unlocked in a two epochs + pub fn new(value: T) -> Self { + Self::Two(value) + } +} +impl FutureEpoch { + /// Update the epoch, to be done after `get`ting the underlying value + pub fn update_epoch(&mut self) { + match self { + Self::None => {} + Self::One(_) => { + // The value has waited its last epoch + *self = Self::None; + } + // The value still has to wait one more epoch after this + Self::Two(v) => { + *self = Self::One(v.clone()); + } + } + } + + /// Get the value if it's ready, which is only at `One` epoch remaining + pub fn get(&self) -> Option<&T> { + match self { + Self::None | Self::Two(_) => None, + Self::One(v) => Some(v), + } + } +} +impl From> for Option { + fn from(v: FutureEpoch) -> Option { + match v { + FutureEpoch::None => None, + FutureEpoch::One(inner) | FutureEpoch::Two(inner) => Some(inner), + } + } +} + /// Fee rate as a ratio, minted on `UpdateStakePoolBalance` as a proportion of /// the rewards /// If either the numerator or the denominator is 0, the fee is considered to be 0 diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 4a684233..a7691f59 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -30,7 +30,7 @@ use { find_stake_program_address, find_transient_stake_program_address, find_withdraw_authority_program_address, id, instruction, minimum_delegation, processor::Processor, - state::{self, FeeType, StakePool, ValidatorList}, + state::{self, FeeType, FutureEpoch, StakePool, ValidatorList}, MINIMUM_RESERVE_LAMPORTS, }, spl_token_2022::{ @@ -1776,19 +1776,19 @@ impl StakePoolAccounts { last_update_epoch: 0, lockup: stake::state::Lockup::default(), epoch_fee: self.epoch_fee, - next_epoch_fee: None, + next_epoch_fee: FutureEpoch::None, preferred_deposit_validator_vote_address: None, preferred_withdraw_validator_vote_address: None, stake_deposit_fee: state::Fee::default(), sol_deposit_fee: state::Fee::default(), stake_withdrawal_fee: state::Fee::default(), - next_stake_withdrawal_fee: None, + next_stake_withdrawal_fee: FutureEpoch::None, stake_referral_fee: 0, sol_referral_fee: 0, sol_deposit_authority: None, sol_withdraw_authority: None, sol_withdrawal_fee: state::Fee::default(), - next_sol_withdrawal_fee: None, + next_sol_withdrawal_fee: FutureEpoch::None, last_epoch_pool_token_supply: 0, last_epoch_total_lamports: 0, }; diff --git a/program/tests/set_epoch_fee.rs b/program/tests/set_epoch_fee.rs index aff29f1e..57d183bd 100644 --- a/program/tests/set_epoch_fee.rs +++ b/program/tests/set_epoch_fee.rs @@ -14,7 +14,7 @@ use { }, spl_stake_pool::{ error, id, instruction, - state::{Fee, FeeType, StakePool}, + state::{Fee, FeeType, FutureEpoch, StakePool}, MINIMUM_RESERVE_LAMPORTS, }, }; @@ -76,7 +76,7 @@ async fn success() { let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); assert_eq!(stake_pool.epoch_fee, old_fee); - assert_eq!(stake_pool.next_epoch_fee, Some(new_fee)); + assert_eq!(stake_pool.next_epoch_fee, FutureEpoch::Two(new_fee)); let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; @@ -94,6 +94,33 @@ async fn success() { ) .await; + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); + assert_eq!(stake_pool.epoch_fee, old_fee); + assert_eq!(stake_pool.next_epoch_fee, FutureEpoch::One(new_fee)); + + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&context.last_blockhash) + .await + .unwrap(); + context + .warp_to_slot(first_normal_slot + 2 * slots_per_epoch) + .unwrap(); + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &last_blockhash, + &[], + false, + ) + .await; + let stake_pool = get_account( &mut context.banks_client, &stake_pool_accounts.stake_pool.pubkey(), @@ -101,7 +128,7 @@ async fn success() { .await; let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); assert_eq!(stake_pool.epoch_fee, new_fee); - assert_eq!(stake_pool.next_epoch_fee, None); + assert_eq!(stake_pool.next_epoch_fee, FutureEpoch::None); } #[tokio::test] diff --git a/program/tests/set_withdrawal_fee.rs b/program/tests/set_withdrawal_fee.rs index 1ca7df81..6ebf6ea3 100644 --- a/program/tests/set_withdrawal_fee.rs +++ b/program/tests/set_withdrawal_fee.rs @@ -14,7 +14,7 @@ use { }, spl_stake_pool::{ error, id, instruction, - state::{Fee, FeeType, StakePool}, + state::{Fee, FeeType, FutureEpoch, StakePool}, MINIMUM_RESERVE_LAMPORTS, }, }; @@ -99,10 +99,13 @@ async fn success() { assert_eq!(stake_pool.stake_withdrawal_fee, old_stake_withdrawal_fee); assert_eq!( stake_pool.next_stake_withdrawal_fee, - Some(new_withdrawal_fee) + FutureEpoch::Two(new_withdrawal_fee) ); assert_eq!(stake_pool.sol_withdrawal_fee, old_sol_withdrawal_fee); - assert_eq!(stake_pool.next_sol_withdrawal_fee, Some(new_withdrawal_fee)); + assert_eq!( + stake_pool.next_sol_withdrawal_fee, + FutureEpoch::Two(new_withdrawal_fee) + ); let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; @@ -120,6 +123,41 @@ async fn success() { ) .await; + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); + assert_eq!(stake_pool.stake_withdrawal_fee, old_stake_withdrawal_fee); + assert_eq!( + stake_pool.next_stake_withdrawal_fee, + FutureEpoch::One(new_withdrawal_fee) + ); + assert_eq!(stake_pool.sol_withdrawal_fee, old_sol_withdrawal_fee); + assert_eq!( + stake_pool.next_sol_withdrawal_fee, + FutureEpoch::One(new_withdrawal_fee) + ); + + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&context.last_blockhash) + .await + .unwrap(); + context + .warp_to_slot(first_normal_slot + 2 * slots_per_epoch) + .unwrap(); + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &last_blockhash, + &[], + false, + ) + .await; + let stake_pool = get_account( &mut context.banks_client, &stake_pool_accounts.stake_pool.pubkey(), @@ -127,9 +165,9 @@ async fn success() { .await; let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); assert_eq!(stake_pool.stake_withdrawal_fee, new_withdrawal_fee); - assert_eq!(stake_pool.next_stake_withdrawal_fee, None); + assert_eq!(stake_pool.next_stake_withdrawal_fee, FutureEpoch::None); assert_eq!(stake_pool.sol_withdrawal_fee, new_withdrawal_fee); - assert_eq!(stake_pool.next_sol_withdrawal_fee, None); + assert_eq!(stake_pool.next_sol_withdrawal_fee, FutureEpoch::None); } #[tokio::test] @@ -189,10 +227,13 @@ async fn success_fee_cannot_increase_more_than_once() { assert_eq!(stake_pool.stake_withdrawal_fee, old_stake_withdrawal_fee); assert_eq!( stake_pool.next_stake_withdrawal_fee, - Some(new_withdrawal_fee) + FutureEpoch::Two(new_withdrawal_fee) ); assert_eq!(stake_pool.sol_withdrawal_fee, old_sol_withdrawal_fee); - assert_eq!(stake_pool.next_sol_withdrawal_fee, Some(new_withdrawal_fee)); + assert_eq!( + stake_pool.next_sol_withdrawal_fee, + FutureEpoch::Two(new_withdrawal_fee) + ); let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; @@ -216,10 +257,46 @@ async fn success_fee_cannot_increase_more_than_once() { ) .await; let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); + assert_eq!(stake_pool.stake_withdrawal_fee, old_stake_withdrawal_fee); + assert_eq!( + stake_pool.next_stake_withdrawal_fee, + FutureEpoch::One(new_withdrawal_fee) + ); + assert_eq!(stake_pool.sol_withdrawal_fee, old_sol_withdrawal_fee); + assert_eq!( + stake_pool.next_sol_withdrawal_fee, + FutureEpoch::One(new_withdrawal_fee) + ); + + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&context.last_blockhash) + .await + .unwrap(); + context + .warp_to_slot(first_normal_slot + 2 * slots_per_epoch) + .unwrap(); + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &last_blockhash, + &[], + false, + ) + .await; + + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); + assert_eq!(stake_pool.stake_withdrawal_fee, new_withdrawal_fee); - assert_eq!(stake_pool.next_stake_withdrawal_fee, None); + assert_eq!(stake_pool.next_stake_withdrawal_fee, FutureEpoch::None); assert_eq!(stake_pool.sol_withdrawal_fee, new_withdrawal_fee); - assert_eq!(stake_pool.next_sol_withdrawal_fee, None); + assert_eq!(stake_pool.next_sol_withdrawal_fee, FutureEpoch::None); // try setting to the old fee in the same epoch let transaction = Transaction::new_signed_with_payer( @@ -231,7 +308,7 @@ async fn success_fee_cannot_increase_more_than_once() { )], Some(&context.payer.pubkey()), &[&context.payer, &stake_pool_accounts.manager], - context.last_blockhash, + last_blockhash, ); context .banks_client @@ -247,7 +324,7 @@ async fn success_fee_cannot_increase_more_than_once() { )], Some(&context.payer.pubkey()), &[&context.payer, &stake_pool_accounts.manager], - context.last_blockhash, + last_blockhash, ); context .banks_client @@ -264,12 +341,12 @@ async fn success_fee_cannot_increase_more_than_once() { assert_eq!(stake_pool.stake_withdrawal_fee, new_withdrawal_fee); assert_eq!( stake_pool.next_stake_withdrawal_fee, - Some(old_stake_withdrawal_fee) + FutureEpoch::Two(old_stake_withdrawal_fee) ); assert_eq!(stake_pool.sol_withdrawal_fee, new_withdrawal_fee); assert_eq!( stake_pool.next_sol_withdrawal_fee, - Some(old_sol_withdrawal_fee) + FutureEpoch::Two(old_sol_withdrawal_fee) ); let error = stake_pool_accounts @@ -291,12 +368,163 @@ async fn success_fee_cannot_increase_more_than_once() { assert_eq!(stake_pool.stake_withdrawal_fee, new_withdrawal_fee); assert_eq!( stake_pool.next_stake_withdrawal_fee, - Some(old_stake_withdrawal_fee) + FutureEpoch::Two(old_stake_withdrawal_fee) ); assert_eq!(stake_pool.sol_withdrawal_fee, new_withdrawal_fee); assert_eq!( stake_pool.next_sol_withdrawal_fee, - Some(old_sol_withdrawal_fee) + FutureEpoch::Two(old_sol_withdrawal_fee) + ); +} + +#[tokio::test] +async fn success_reset_fee_after_one_epoch() { + let (mut context, stake_pool_accounts, new_withdrawal_fee) = setup(None).await; + + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); + let old_stake_withdrawal_fee = stake_pool.stake_withdrawal_fee; + let old_sol_withdrawal_fee = stake_pool.sol_withdrawal_fee; + + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + FeeType::StakeWithdrawal(new_withdrawal_fee), + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + context + .banks_client + .process_transaction(transaction) + .await + .unwrap(); + + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + FeeType::SolWithdrawal(new_withdrawal_fee), + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + context + .banks_client + .process_transaction(transaction) + .await + .unwrap(); + + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); + + assert_eq!(stake_pool.stake_withdrawal_fee, old_stake_withdrawal_fee); + assert_eq!( + stake_pool.next_stake_withdrawal_fee, + FutureEpoch::Two(new_withdrawal_fee) + ); + assert_eq!(stake_pool.sol_withdrawal_fee, old_sol_withdrawal_fee); + assert_eq!( + stake_pool.next_sol_withdrawal_fee, + FutureEpoch::Two(new_withdrawal_fee) + ); + + let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + + context + .warp_to_slot(first_normal_slot + slots_per_epoch) + .unwrap(); + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &[], + false, + ) + .await; + + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); + assert_eq!(stake_pool.stake_withdrawal_fee, old_stake_withdrawal_fee); + assert_eq!( + stake_pool.next_stake_withdrawal_fee, + FutureEpoch::One(new_withdrawal_fee) + ); + assert_eq!(stake_pool.sol_withdrawal_fee, old_sol_withdrawal_fee); + assert_eq!( + stake_pool.next_sol_withdrawal_fee, + FutureEpoch::One(new_withdrawal_fee) + ); + + // Flip the two fees, resets the counter to two future epochs + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + FeeType::StakeWithdrawal(old_sol_withdrawal_fee), + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + context + .banks_client + .process_transaction(transaction) + .await + .unwrap(); + + let transaction = Transaction::new_signed_with_payer( + &[instruction::set_fee( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.manager.pubkey(), + FeeType::SolWithdrawal(old_stake_withdrawal_fee), + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.manager], + context.last_blockhash, + ); + context + .banks_client + .process_transaction(transaction) + .await + .unwrap(); + + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); + assert_eq!(stake_pool.stake_withdrawal_fee, old_stake_withdrawal_fee); + assert_eq!( + stake_pool.next_stake_withdrawal_fee, + FutureEpoch::Two(old_sol_withdrawal_fee) + ); + assert_eq!(stake_pool.sol_withdrawal_fee, old_sol_withdrawal_fee); + assert_eq!( + stake_pool.next_sol_withdrawal_fee, + FutureEpoch::Two(old_stake_withdrawal_fee) ); } @@ -365,10 +593,13 @@ async fn success_increase_fee_from_0() { assert_eq!(stake_pool.stake_withdrawal_fee, old_stake_withdrawal_fee); assert_eq!( stake_pool.next_stake_withdrawal_fee, - Some(new_withdrawal_fee) + FutureEpoch::Two(new_withdrawal_fee) ); assert_eq!(stake_pool.sol_withdrawal_fee, old_sol_withdrawal_fee); - assert_eq!(stake_pool.next_sol_withdrawal_fee, Some(new_withdrawal_fee)); + assert_eq!( + stake_pool.next_sol_withdrawal_fee, + FutureEpoch::Two(new_withdrawal_fee) + ); let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; @@ -386,6 +617,41 @@ async fn success_increase_fee_from_0() { ) .await; + let stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); + assert_eq!(stake_pool.stake_withdrawal_fee, old_stake_withdrawal_fee); + assert_eq!( + stake_pool.next_stake_withdrawal_fee, + FutureEpoch::One(new_withdrawal_fee) + ); + assert_eq!(stake_pool.sol_withdrawal_fee, old_sol_withdrawal_fee); + assert_eq!( + stake_pool.next_sol_withdrawal_fee, + FutureEpoch::One(new_withdrawal_fee) + ); + + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&context.last_blockhash) + .await + .unwrap(); + context + .warp_to_slot(first_normal_slot + 2 * slots_per_epoch) + .unwrap(); + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &last_blockhash, + &[], + false, + ) + .await; + let stake_pool = get_account( &mut context.banks_client, &stake_pool_accounts.stake_pool.pubkey(), @@ -393,9 +659,9 @@ async fn success_increase_fee_from_0() { .await; let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); assert_eq!(stake_pool.stake_withdrawal_fee, new_withdrawal_fee); - assert_eq!(stake_pool.next_stake_withdrawal_fee, None); + assert_eq!(stake_pool.next_stake_withdrawal_fee, FutureEpoch::None); assert_eq!(stake_pool.sol_withdrawal_fee, new_withdrawal_fee); - assert_eq!(stake_pool.next_sol_withdrawal_fee, None); + assert_eq!(stake_pool.next_sol_withdrawal_fee, FutureEpoch::None); } #[tokio::test] From 404ebd91c1d255c6b4eeb72008eac5997eb019bb Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 27 Jan 2023 16:09:03 +0100 Subject: [PATCH 0295/1076] stake-pool: Check transient stake state (#3987) --- program/src/processor.rs | 52 ++++++++++++++++++++++++++++++++++--- program/tests/decrease.rs | 2 +- program/tests/increase.rs | 2 +- program/tests/redelegate.rs | 2 +- 4 files changed, 51 insertions(+), 7 deletions(-) diff --git a/program/src/processor.rs b/program/src/processor.rs index 9ffffd01..5d61a157 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -222,6 +222,42 @@ fn stake_is_inactive_without_history(stake: &stake::state::Stake, epoch: Epoch) && stake.delegation.deactivation_epoch == epoch) } +/// Roughly checks if a stake account is deactivating or inactive +fn check_if_stake_is_deactivating_or_inactive( + account_info: &AccountInfo, + vote_account_address: &Pubkey, +) -> Result<(), ProgramError> { + let (_, stake) = get_stake_state(account_info)?; + if stake.delegation.deactivation_epoch == Epoch::MAX { + msg!( + "Existing stake {} delegated to {} is activating or active", + account_info.key, + vote_account_address + ); + Err(StakePoolError::WrongStakeState.into()) + } else { + Ok(()) + } +} + +/// Roughly checks if a stake account is activating or active +fn check_if_stake_is_activating_or_active( + account_info: &AccountInfo, + vote_account_address: &Pubkey, +) -> Result<(), ProgramError> { + let (_, stake) = get_stake_state(account_info)?; + if stake.delegation.deactivation_epoch != Epoch::MAX { + msg!( + "Existing stake {} delegated to {} is deactivating or inactive", + account_info.key, + vote_account_address + ); + Err(StakePoolError::WrongStakeState.into()) + } else { + Ok(()) + } +} + /// Check that the stake state is correct: usable by the pool and delegated to /// the expected validator fn check_stake_state( @@ -1337,8 +1373,10 @@ impl Processor { ); return Err(ProgramError::InvalidSeeds); } - // Let the runtime check to see if the merge is valid, so there's no - // explicit check here that the transient stake is decreasing + check_if_stake_is_deactivating_or_inactive( + transient_stake_account_info, + &vote_account_address, + )?; } let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; @@ -1586,8 +1624,10 @@ impl Processor { ); return Err(ProgramError::InvalidSeeds); } - // Let the runtime check to see if the merge is valid, so there's no - // explicit check here that the transient stake is increasing + check_if_stake_is_activating_or_active( + transient_stake_account_info, + vote_account_address, + )?; } check_validator_stake_account( @@ -2037,6 +2077,10 @@ impl Processor { destination_transient_stake_seed, &stake_pool.lockup, )?; + check_if_stake_is_activating_or_active( + destination_transient_stake_account_info, + vote_account_address, + )?; Self::stake_merge( stake_pool_info.key, ephemeral_stake_account_info.clone(), diff --git a/program/tests/decrease.rs b/program/tests/decrease.rs index b8033440..1293fd78 100644 --- a/program/tests/decrease.rs +++ b/program/tests/decrease.rs @@ -586,7 +586,7 @@ async fn fail_additional_with_increasing() { error, TransactionError::InstructionError( 0, - InstructionError::Custom(stake::instruction::StakeError::MergeTransientStake as u32) + InstructionError::Custom(StakePoolError::WrongStakeState as u32) ) ); } diff --git a/program/tests/increase.rs b/program/tests/increase.rs index 647525d7..4cb8f128 100644 --- a/program/tests/increase.rs +++ b/program/tests/increase.rs @@ -585,7 +585,7 @@ async fn fail_additional_with_decreasing() { error, TransactionError::InstructionError( 0, - InstructionError::Custom(StakeError::MergeTransientStake as u32) + InstructionError::Custom(StakePoolError::WrongStakeState as u32) ) ); } diff --git a/program/tests/redelegate.rs b/program/tests/redelegate.rs index 7bc6c948..24191842 100644 --- a/program/tests/redelegate.rs +++ b/program/tests/redelegate.rs @@ -657,7 +657,7 @@ async fn fail_with_decreasing_stake() { error, TransactionError::InstructionError( 0, - InstructionError::Custom(StakeError::MergeTransientStake as u32) + InstructionError::Custom(StakePoolError::WrongStakeState as u32) ) ); } From 4cfbff3ffbdfc5c0c31f49868df5ed60cb43d407 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 27 Jan 2023 23:52:52 +0100 Subject: [PATCH 0296/1076] stake-pool: Remove lamport minimum for validator removal by staker (#3999) * stake-pool: Relax lamport minimum for validator removal by staker * Completely remove the lamport check --- program/src/processor.rs | 26 +------------------------- program/tests/vsa_remove.rs | 30 ++++++++++++++++-------------- 2 files changed, 17 insertions(+), 39 deletions(-) diff --git a/program/src/processor.rs b/program/src/processor.rs index 5d61a157..6a2ae57f 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1167,7 +1167,7 @@ impl Processor { return Err(StakePoolError::InvalidState.into()); } - let (meta, stake) = get_stake_state(stake_account_info)?; + let (_, stake) = get_stake_state(stake_account_info)?; let vote_account_address = stake.delegation.voter_pubkey; let maybe_validator_stake_info = validator_list.find_mut::(|x| { ValidatorStakeInfo::memcmp_pubkey(x, &vote_account_address) @@ -1193,30 +1193,6 @@ impl Processor { return Err(StakePoolError::ValidatorNotFound.into()); } - let stake_lamports = **stake_account_info.lamports.borrow(); - let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; - let required_lamports = minimum_stake_lamports(&meta, stake_minimum_delegation); - if stake_lamports > required_lamports { - msg!( - "Attempting to remove validator account with {} lamports, must have no more than {} lamports; \ - reduce using DecreaseValidatorStake first", - stake_lamports, - required_lamports - ); - return Err(StakePoolError::StakeLamportsNotEqualToMinimum.into()); - } - - let current_minimum_delegation = minimum_delegation(stake_minimum_delegation); - if stake.delegation.stake > current_minimum_delegation { - msg!( - "Error: attempting to remove stake with delegation of {} lamports, must have no more than {} lamports; \ - reduce using DecreaseValidatorStake first", - stake.delegation.stake, - current_minimum_delegation - ); - return Err(StakePoolError::StakeLamportsNotEqualToMinimum.into()); - } - let new_status = if validator_stake_info.transient_stake_lamports > 0 { check_transient_stake_address( program_id, diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 980f87e2..b2594bb7 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -212,18 +212,28 @@ async fn fail_with_wrong_validator_list_account() { } #[tokio::test] -async fn fail_not_at_minimum() { +async fn success_at_large_value() { let (mut context, stake_pool_accounts, validator_stake) = setup().await; - transfer( + let current_minimum_delegation = stake_pool_get_minimum_delegation( &mut context.banks_client, &context.payer, &context.last_blockhash, - &validator_stake.stake_account, - 1_000_001, ) .await; + let threshold_amount = current_minimum_delegation * 1_000; + let _ = simple_deposit_stake( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_pool_accounts, + &validator_stake, + threshold_amount, + ) + .await + .unwrap(); + let error = stake_pool_accounts .remove_validator_from_pool( &mut context.banks_client, @@ -232,16 +242,8 @@ async fn fail_not_at_minimum() { &validator_stake.stake_account, &validator_stake.transient_stake_account, ) - .await - .unwrap() - .unwrap(); - assert_eq!( - error, - TransactionError::InstructionError( - 0, - InstructionError::Custom(StakePoolError::StakeLamportsNotEqualToMinimum as u32) - ), - ); + .await; + assert!(error.is_none()); } #[tokio::test] From 3b3b955a7f715dc6a5e5958c99dd9f9e45eca012 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 27 Jan 2023 23:53:02 +0100 Subject: [PATCH 0297/1076] stake-pool: Make activating / deactivating check stricter (#4002) --- program/src/processor.rs | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/program/src/processor.rs b/program/src/processor.rs index 6a2ae57f..581aa941 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -222,17 +222,19 @@ fn stake_is_inactive_without_history(stake: &stake::state::Stake, epoch: Epoch) && stake.delegation.deactivation_epoch == epoch) } -/// Roughly checks if a stake account is deactivating or inactive -fn check_if_stake_is_deactivating_or_inactive( +/// Roughly checks if a stake account is deactivating +fn check_if_stake_deactivating( account_info: &AccountInfo, vote_account_address: &Pubkey, + epoch: Epoch, ) -> Result<(), ProgramError> { let (_, stake) = get_stake_state(account_info)?; - if stake.delegation.deactivation_epoch == Epoch::MAX { + if stake.delegation.deactivation_epoch != epoch { msg!( - "Existing stake {} delegated to {} is activating or active", + "Existing stake {} delegated to {} not deactivated in epoch {}", account_info.key, - vote_account_address + vote_account_address, + epoch, ); Err(StakePoolError::WrongStakeState.into()) } else { @@ -240,17 +242,21 @@ fn check_if_stake_is_deactivating_or_inactive( } } -/// Roughly checks if a stake account is activating or active -fn check_if_stake_is_activating_or_active( +/// Roughly checks if a stake account is activating +fn check_if_stake_activating( account_info: &AccountInfo, vote_account_address: &Pubkey, + epoch: Epoch, ) -> Result<(), ProgramError> { let (_, stake) = get_stake_state(account_info)?; - if stake.delegation.deactivation_epoch != Epoch::MAX { + if stake.delegation.deactivation_epoch != Epoch::MAX + || stake.delegation.activation_epoch != epoch + { msg!( - "Existing stake {} delegated to {} is deactivating or inactive", + "Existing stake {} delegated to {} not activated in epoch {}", account_info.key, - vote_account_address + vote_account_address, + epoch, ); Err(StakePoolError::WrongStakeState.into()) } else { @@ -1349,9 +1355,10 @@ impl Processor { ); return Err(ProgramError::InvalidSeeds); } - check_if_stake_is_deactivating_or_inactive( + check_if_stake_deactivating( transient_stake_account_info, &vote_account_address, + clock.epoch, )?; } @@ -1600,9 +1607,10 @@ impl Processor { ); return Err(ProgramError::InvalidSeeds); } - check_if_stake_is_activating_or_active( + check_if_stake_activating( transient_stake_account_info, vote_account_address, + clock.epoch, )?; } @@ -2053,9 +2061,10 @@ impl Processor { destination_transient_stake_seed, &stake_pool.lockup, )?; - check_if_stake_is_activating_or_active( + check_if_stake_activating( destination_transient_stake_account_info, vote_account_address, + clock.epoch, )?; Self::stake_merge( stake_pool_info.key, From 6551a3dff33df67c7e0809777f4bb381b05bed37 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Sat, 28 Jan 2023 01:23:41 +0100 Subject: [PATCH 0298/1076] stake-pool: Document redelegate behavior better (#3986) --- program/src/instruction.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 9f2d36c7..d61319df 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -493,6 +493,14 @@ pub enum StakePoolInstruction { /// source transient stake account, and rent-exemption plus minimum delegation /// is required for the destination ephemeral stake account. /// + /// The amount that arrives at the destination validator in the end is + /// `redelegate_lamports - 2 * rent_exemption` if the destination transient + /// account does *not* exist, and `redelegate_lamports - rent_exemption` if + /// the destination transient account already exists. One `rent_exemption` + /// is deactivated with the source transient account during redelegation, + /// and another `rent_exemption` is deactivated when creating the destination + /// transient stake account. + /// /// 0. `[]` Stake pool /// 1. `[s]` Stake pool staker /// 2. `[]` Stake pool withdraw authority From 28153f23658b2896eda5438a95e9c98893dc30e4 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Sat, 28 Jan 2023 02:13:46 +0100 Subject: [PATCH 0299/1076] stake-pool: Remove some unwraps (#4003) * stake-pool: Remove a couple of unwraps * Remove one more unwrap * Update CLI too --- clients/cli/src/main.rs | 2 +- program/src/processor.rs | 14 ++++++++++---- program/src/state.rs | 8 ++++++-- program/tests/deposit.rs | 12 ++++++------ program/tests/helpers/mod.rs | 2 +- program/tests/update_validator_list_balance.rs | 2 +- program/tests/withdraw.rs | 6 +++--- 7 files changed, 28 insertions(+), 18 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index cba12254..2319c6e3 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -1103,7 +1103,7 @@ fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { stake_account_address: stake_account_address.to_string(), validator_active_stake_lamports: validator.active_stake_lamports, validator_last_update_epoch: validator.last_update_epoch, - validator_lamports: validator.stake_lamports(), + validator_lamports: validator.stake_lamports().unwrap(), validator_transient_stake_account_address: transient_stake_account_address .to_string(), validator_transient_stake_lamports: validator.transient_stake_lamports, diff --git a/program/src/processor.rs b/program/src/processor.rs index 581aa941..83ad845b 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -446,7 +446,9 @@ impl Processor { stake::instruction::split(stake_account.key, authority.key, amount, split_stake.key); invoke_signed( - split_instruction.last().unwrap(), + split_instruction + .last() + .ok_or(ProgramError::InvalidInstructionData)?, &[stake_account, split_stake, authority], signers, ) @@ -2237,8 +2239,12 @@ impl Processor { .zip(validator_stake_accounts.chunks_exact(2)); for (validator_stake_record, validator_stakes) in validator_iter { // chunks_exact means that we always get 2 elements, making this safe - let validator_stake_info = validator_stakes.first().unwrap(); - let transient_stake_info = validator_stakes.last().unwrap(); + let validator_stake_info = validator_stakes + .first() + .ok_or(ProgramError::InvalidInstructionData)?; + let transient_stake_info = validator_stakes + .last() + .ok_or(ProgramError::InvalidInstructionData)?; if check_validator_stake_address( program_id, stake_pool_info.key, @@ -2533,7 +2539,7 @@ impl Processor { return Err(StakePoolError::StakeListOutOfDate.into()); } total_lamports = total_lamports - .checked_add(validator_stake_record.stake_lamports()) + .checked_add(validator_stake_record.stake_lamports()?) .ok_or(StakePoolError::CalculationFailure)?; } diff --git a/program/src/state.rs b/program/src/state.rs index 30b2ef43..cede91c1 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -661,10 +661,10 @@ pub struct ValidatorStakeInfo { impl ValidatorStakeInfo { /// Get the total lamports on this validator (active and transient) - pub fn stake_lamports(&self) -> u64 { + pub fn stake_lamports(&self) -> Result { self.active_stake_lamports .checked_add(self.transient_stake_lamports) - .unwrap() + .ok_or(StakePoolError::CalculationFailure) } /// Performs a very cheap comparison, for checking if this validator stake @@ -680,12 +680,14 @@ impl ValidatorStakeInfo { /// Performs a comparison, used to check if this validator stake /// info has more active lamports than some limit pub fn active_lamports_greater_than(data: &[u8], lamports: &u64) -> bool { + // without this unwrap, compute usage goes up significantly u64::try_from_slice(&data[0..8]).unwrap() > *lamports } /// Performs a comparison, used to check if this validator stake /// info has more transient lamports than some limit pub fn transient_lamports_greater_than(data: &[u8], lamports: &u64) -> bool { + // without this unwrap, compute usage goes up significantly u64::try_from_slice(&data[8..16]).unwrap() > *lamports } @@ -701,6 +703,8 @@ impl Pack for ValidatorStakeInfo { const LEN: usize = 73; fn pack_into_slice(&self, data: &mut [u8]) { let mut data = data; + // Removing this unwrap would require changing from `Pack` to some other + // trait or `bytemuck`, so it stays in for now self.serialize(&mut data).unwrap(); } fn unpack_from_slice(src: &[u8]) -> Result { diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 585f43ff..07955b9e 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -235,8 +235,8 @@ async fn success(token_program_id: Pubkey) { .find(&validator_stake_account.vote.pubkey()) .unwrap(); assert_eq!( - post_validator_stake_item.stake_lamports(), - pre_validator_stake_item.stake_lamports() + stake_lamports - stake_rent, + post_validator_stake_item.stake_lamports().unwrap(), + pre_validator_stake_item.stake_lamports().unwrap() + stake_lamports - stake_rent, ); // Check validator stake account actual SOL balance @@ -247,7 +247,7 @@ async fn success(token_program_id: Pubkey) { .await; assert_eq!( validator_stake_account.lamports, - post_validator_stake_item.stake_lamports() + post_validator_stake_item.stake_lamports().unwrap() ); assert_eq!(post_validator_stake_item.transient_stake_lamports, 0); @@ -429,8 +429,8 @@ async fn success_with_extra_stake_lamports() { .find(&validator_stake_account.vote.pubkey()) .unwrap(); assert_eq!( - post_validator_stake_item.stake_lamports(), - pre_validator_stake_item.stake_lamports() + stake_lamports - stake_rent, + post_validator_stake_item.stake_lamports().unwrap(), + pre_validator_stake_item.stake_lamports().unwrap() + stake_lamports - stake_rent, ); // Check validator stake account actual SOL balance @@ -441,7 +441,7 @@ async fn success_with_extra_stake_lamports() { .await; assert_eq!( validator_stake_account.lamports, - post_validator_stake_item.stake_lamports() + post_validator_stake_item.stake_lamports().unwrap() ); assert_eq!(post_validator_stake_item.transient_stake_lamports, 0); diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index a7691f59..f8a1a9e1 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -2127,7 +2127,7 @@ pub async fn get_validator_list_sum( let validator_sum: u64 = validator_list .validators .iter() - .map(|info| info.stake_lamports()) + .map(|info| info.stake_lamports().unwrap()) .sum(); let rent = banks_client.get_rent().await.unwrap(); let rent = rent.minimum_balance(std::mem::size_of::()); diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index 827189a2..841b8b88 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -662,7 +662,7 @@ async fn merge_transient_stake_after_remove() { validator_list.validators[0].status, StakeStatus::ReadyForRemoval ); - assert_eq!(validator_list.validators[0].stake_lamports(), 0); + assert_eq!(validator_list.validators[0].stake_lamports().unwrap(), 0); let reserve_stake = context .banks_client diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 63d2c76e..85c60e71 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -219,12 +219,12 @@ async fn _success(token_program_id: Pubkey, test_type: SuccessTestType) { .find(&validator_stake_account.vote.pubkey()) .unwrap(); assert_eq!( - validator_stake_item.stake_lamports(), - validator_stake_item_before.stake_lamports() - tokens_burnt + validator_stake_item.stake_lamports().unwrap(), + validator_stake_item_before.stake_lamports().unwrap() - tokens_burnt ); assert_eq!( validator_stake_item.active_stake_lamports, - validator_stake_item.stake_lamports(), + validator_stake_item.stake_lamports().unwrap(), ); // Check tokens used From dab15c9e1e67b3f1acdf181e9e99a26e7b9186b4 Mon Sep 17 00:00:00 2001 From: joeaba <77398477+joeaba@users.noreply.github.com> Date: Tue, 31 Jan 2023 08:06:36 -0500 Subject: [PATCH 0300/1076] chore: update maintainer references (#4008) --- clients/cli/Cargo.toml | 2 +- clients/js-legacy/package.json | 2 +- program/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 5265b607..c1498f28 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -1,5 +1,5 @@ [package] -authors = ["Solana Maintainers "] +authors = ["Solana Labs Maintainers "] description = "SPL-Stake-Pool Command-line Utility" edition = "2021" homepage = "https://spl.solana.com/stake-pool" diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 38d5f06d..418c854d 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -13,7 +13,7 @@ }, "keywords": [], "contributors": [ - "Solana Maintainers ", + "Solana Labs Maintainers ", "Lieu Zheng Hong", "mFactory Team (https://mfactory.ch/)", "SolBlaze (https://solblaze.org/)" diff --git a/program/Cargo.toml b/program/Cargo.toml index 9073216d..ef8c7ecc 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -2,7 +2,7 @@ name = "spl-stake-pool" version = "0.7.0" description = "Solana Program Library Stake Pool" -authors = ["Solana Maintainers "] +authors = ["Solana Labs Maintainers "] repository = "https://github.com/solana-labs/solana-program-library" license = "Apache-2.0" edition = "2021" From df605cb0655e965acb691d1879a0fd5361c2d4af Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 1 Feb 2023 12:16:07 +0100 Subject: [PATCH 0301/1076] stake-pool: Add slippage to all deposit and withdraw ixs (#3980) --- program/src/error.rs | 3 + program/src/instruction.rs | 799 ++++++++++++++++++++++++++++------ program/src/processor.rs | 84 +++- program/tests/deposit.rs | 102 +++++ program/tests/deposit_sol.rs | 101 +++++ program/tests/helpers/mod.rs | 163 +++++++ program/tests/withdraw.rs | 78 ++++ program/tests/withdraw_sol.rs | 69 +++ 8 files changed, 1262 insertions(+), 137 deletions(-) diff --git a/program/src/error.rs b/program/src/error.rs index 6efcb389..39fae329 100644 --- a/program/src/error.rs +++ b/program/src/error.rs @@ -141,6 +141,9 @@ pub enum StakePoolError { /// The fee account has an unsupported extension #[error("UnsupportedFeeAccountExtension")] UnsupportedFeeAccountExtension, + /// Instruction exceeds desired slippage limit + #[error("Instruction exceeds desired slippage limit")] + ExceededSlippage, } impl From for ProgramError { fn from(e: StakePoolError) -> Self { diff --git a/program/src/instruction.rs b/program/src/instruction.rs index d61319df..5725eb70 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -532,6 +532,105 @@ pub enum StakePoolInstruction { #[allow(dead_code)] // but it's not destination_transient_stake_seed: u64, }, + + /// Deposit some stake into the pool, with a specified slippage constraint. + /// The output is a "pool" token representing ownership into the pool. + /// Inputs are converted at the current ratio. + /// + /// 0. `[w]` Stake pool + /// 1. `[w]` Validator stake list storage account + /// 2. `[s]/[]` Stake pool deposit authority + /// 3. `[]` Stake pool withdraw authority + /// 4. `[w]` Stake account to join the pool (withdraw authority for the stake account should be first set to the stake pool deposit authority) + /// 5. `[w]` Validator stake account for the stake account to be merged with + /// 6. `[w]` Reserve stake account, to withdraw rent exempt reserve + /// 7. `[w]` User account to receive pool tokens + /// 8. `[w]` Account to receive pool fee tokens + /// 9. `[w]` Account to receive a portion of pool fee tokens as referral fees + /// 10. `[w]` Pool token mint account + /// 11. '[]' Sysvar clock account + /// 12. '[]' Sysvar stake history account + /// 13. `[]` Pool token program id, + /// 14. `[]` Stake program id, + DepositStakeWithSlippage { + /// Minimum amount of pool tokens that must be received + minimum_pool_tokens_out: u64, + }, + + /// Withdraw the token from the pool at the current ratio, specifying a + /// minimum expected output lamport amount. + /// + /// Succeeds if the stake account has enough SOL to cover the desired amount + /// of pool tokens, and if the withdrawal keeps the total staked amount + /// above the minimum of rent-exempt amount + + /// `max(crate::MINIMUM_ACTIVE_STAKE, solana_program::stake::tools::get_minimum_delegation())`. + /// + /// 0. `[w]` Stake pool + /// 1. `[w]` Validator stake list storage account + /// 2. `[]` Stake pool withdraw authority + /// 3. `[w]` Validator or reserve stake account to split + /// 4. `[w]` Unitialized stake account to receive withdrawal + /// 5. `[]` User account to set as a new withdraw authority + /// 6. `[s]` User transfer authority, for pool token account + /// 7. `[w]` User account with pool tokens to burn from + /// 8. `[w]` Account to receive pool fee tokens + /// 9. `[w]` Pool token mint account + /// 10. `[]` Sysvar clock account (required) + /// 11. `[]` Pool token program id + /// 12. `[]` Stake program id, + /// userdata: amount of pool tokens to withdraw + WithdrawStakeWithSlippage { + /// Pool tokens to burn in exchange for lamports + pool_tokens_in: u64, + /// Minimum amount of lamports that must be received + minimum_lamports_out: u64, + }, + + /// Deposit SOL directly into the pool's reserve account, with a specified + /// slippage constraint. The output is a "pool" token representing ownership + /// into the pool. Inputs are converted at the current ratio. + /// + /// 0. `[w]` Stake pool + /// 1. `[]` Stake pool withdraw authority + /// 2. `[w]` Reserve stake account, to deposit SOL + /// 3. `[s]` Account providing the lamports to be deposited into the pool + /// 4. `[w]` User account to receive pool tokens + /// 5. `[w]` Account to receive fee tokens + /// 6. `[w]` Account to receive a portion of fee as referral fees + /// 7. `[w]` Pool token mint account + /// 8. `[]` System program account + /// 9. `[]` Token program id + /// 10. `[s]` (Optional) Stake pool sol deposit authority. + DepositSolWithSlippage { + /// Amount of lamports to deposit into the reserve + lamports_in: u64, + /// Minimum amount of pool tokens that must be received + minimum_pool_tokens_out: u64, + }, + + /// Withdraw SOL directly from the pool's reserve account. Fails if the + /// reserve does not have enough SOL or if the slippage constraint is not + /// met. + /// + /// 0. `[w]` Stake pool + /// 1. `[]` Stake pool withdraw authority + /// 2. `[s]` User transfer authority, for pool token account + /// 3. `[w]` User account to burn pool tokens + /// 4. `[w]` Reserve stake account, to withdraw SOL + /// 5. `[w]` Account receiving the lamports from the reserve, must be a system account + /// 6. `[w]` Account to receive pool fee tokens + /// 7. `[w]` Pool token mint account + /// 8. '[]' Clock sysvar + /// 9. '[]' Stake history sysvar + /// 10. `[]` Stake program account + /// 11. `[]` Token program id + /// 12. `[s]` (Optional) Stake pool sol withdraw authority + WithdrawSolWithSlippage { + /// Pool tokens to burn in exchange for lamports + pool_tokens_in: u64, + /// Minimum amount of lamports that must be received + minimum_lamports_out: u64, + }, } /// Creates an 'initialize' instruction. @@ -1282,12 +1381,11 @@ pub fn update_stake_pool( (update_list_instructions, final_instructions) } -/// Creates instructions required to deposit into a stake pool, given a stake -/// account owned by the user. -pub fn deposit_stake( +fn deposit_stake_internal( program_id: &Pubkey, stake_pool: &Pubkey, validator_list_storage: &Pubkey, + stake_pool_deposit_authority: Option<&Pubkey>, stake_pool_withdraw_authority: &Pubkey, deposit_stake_address: &Pubkey, deposit_stake_withdraw_authority: &Pubkey, @@ -1298,13 +1396,60 @@ pub fn deposit_stake( referrer_pool_tokens_account: &Pubkey, pool_mint: &Pubkey, token_program_id: &Pubkey, + minimum_pool_tokens_out: Option, ) -> Vec { - let stake_pool_deposit_authority = - find_deposit_authority_program_address(program_id, stake_pool).0; - let accounts = vec![ + let mut instructions = vec![]; + let mut accounts = vec![ AccountMeta::new(*stake_pool, false), AccountMeta::new(*validator_list_storage, false), - AccountMeta::new_readonly(stake_pool_deposit_authority, false), + ]; + if let Some(stake_pool_deposit_authority) = stake_pool_deposit_authority { + accounts.push(AccountMeta::new_readonly( + *stake_pool_deposit_authority, + true, + )); + instructions.extend_from_slice(&[ + stake::instruction::authorize( + deposit_stake_address, + deposit_stake_withdraw_authority, + stake_pool_deposit_authority, + stake::state::StakeAuthorize::Staker, + None, + ), + stake::instruction::authorize( + deposit_stake_address, + deposit_stake_withdraw_authority, + stake_pool_deposit_authority, + stake::state::StakeAuthorize::Withdrawer, + None, + ), + ]); + } else { + let stake_pool_deposit_authority = + find_deposit_authority_program_address(program_id, stake_pool).0; + accounts.push(AccountMeta::new_readonly( + stake_pool_deposit_authority, + false, + )); + instructions.extend_from_slice(&[ + stake::instruction::authorize( + deposit_stake_address, + deposit_stake_withdraw_authority, + &stake_pool_deposit_authority, + stake::state::StakeAuthorize::Staker, + None, + ), + stake::instruction::authorize( + deposit_stake_address, + deposit_stake_withdraw_authority, + &stake_pool_deposit_authority, + stake::state::StakeAuthorize::Withdrawer, + None, + ), + ]); + }; + + accounts.extend_from_slice(&[ AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), AccountMeta::new(*deposit_stake_address, false), AccountMeta::new(*validator_stake_account, false), @@ -1317,28 +1462,99 @@ pub fn deposit_stake( AccountMeta::new_readonly(sysvar::stake_history::id(), false), AccountMeta::new_readonly(*token_program_id, false), AccountMeta::new_readonly(stake::program::id(), false), - ]; - vec![ - stake::instruction::authorize( - deposit_stake_address, - deposit_stake_withdraw_authority, - &stake_pool_deposit_authority, - stake::state::StakeAuthorize::Staker, - None, - ), - stake::instruction::authorize( - deposit_stake_address, - deposit_stake_withdraw_authority, - &stake_pool_deposit_authority, - stake::state::StakeAuthorize::Withdrawer, - None, - ), - Instruction { - program_id: *program_id, - accounts, - data: StakePoolInstruction::DepositStake.try_to_vec().unwrap(), + ]); + instructions.push( + if let Some(minimum_pool_tokens_out) = minimum_pool_tokens_out { + Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::DepositStakeWithSlippage { + minimum_pool_tokens_out, + } + .try_to_vec() + .unwrap(), + } + } else { + Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::DepositStake.try_to_vec().unwrap(), + } }, - ] + ); + instructions +} + +/// Creates instructions required to deposit into a stake pool, given a stake +/// account owned by the user. +pub fn deposit_stake( + program_id: &Pubkey, + stake_pool: &Pubkey, + validator_list_storage: &Pubkey, + stake_pool_withdraw_authority: &Pubkey, + deposit_stake_address: &Pubkey, + deposit_stake_withdraw_authority: &Pubkey, + validator_stake_account: &Pubkey, + reserve_stake_account: &Pubkey, + pool_tokens_to: &Pubkey, + manager_fee_account: &Pubkey, + referrer_pool_tokens_account: &Pubkey, + pool_mint: &Pubkey, + token_program_id: &Pubkey, +) -> Vec { + deposit_stake_internal( + program_id, + stake_pool, + validator_list_storage, + None, + stake_pool_withdraw_authority, + deposit_stake_address, + deposit_stake_withdraw_authority, + validator_stake_account, + reserve_stake_account, + pool_tokens_to, + manager_fee_account, + referrer_pool_tokens_account, + pool_mint, + token_program_id, + None, + ) +} + +/// Creates instructions to deposit into a stake pool with slippage +pub fn deposit_stake_with_slippage( + program_id: &Pubkey, + stake_pool: &Pubkey, + validator_list_storage: &Pubkey, + stake_pool_withdraw_authority: &Pubkey, + deposit_stake_address: &Pubkey, + deposit_stake_withdraw_authority: &Pubkey, + validator_stake_account: &Pubkey, + reserve_stake_account: &Pubkey, + pool_tokens_to: &Pubkey, + manager_fee_account: &Pubkey, + referrer_pool_tokens_account: &Pubkey, + pool_mint: &Pubkey, + token_program_id: &Pubkey, + minimum_pool_tokens_out: u64, +) -> Vec { + deposit_stake_internal( + program_id, + stake_pool, + validator_list_storage, + None, + stake_pool_withdraw_authority, + deposit_stake_address, + deposit_stake_withdraw_authority, + validator_stake_account, + reserve_stake_account, + pool_tokens_to, + manager_fee_account, + referrer_pool_tokens_account, + pool_mint, + token_program_id, + Some(minimum_pool_tokens_out), + ) } /// Creates instructions required to deposit into a stake pool, given a stake @@ -1360,48 +1576,66 @@ pub fn deposit_stake_with_authority( pool_mint: &Pubkey, token_program_id: &Pubkey, ) -> Vec { - let accounts = vec![ - AccountMeta::new(*stake_pool, false), - AccountMeta::new(*validator_list_storage, false), - AccountMeta::new_readonly(*stake_pool_deposit_authority, true), - AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), - AccountMeta::new(*deposit_stake_address, false), - AccountMeta::new(*validator_stake_account, false), - AccountMeta::new(*reserve_stake_account, false), - AccountMeta::new(*pool_tokens_to, false), - AccountMeta::new(*manager_fee_account, false), - AccountMeta::new(*referrer_pool_tokens_account, false), - AccountMeta::new(*pool_mint, false), - AccountMeta::new_readonly(sysvar::clock::id(), false), - AccountMeta::new_readonly(sysvar::stake_history::id(), false), - AccountMeta::new_readonly(*token_program_id, false), - AccountMeta::new_readonly(stake::program::id(), false), - ]; - vec![ - stake::instruction::authorize( - deposit_stake_address, - deposit_stake_withdraw_authority, - stake_pool_deposit_authority, - stake::state::StakeAuthorize::Staker, - None, - ), - stake::instruction::authorize( - deposit_stake_address, - deposit_stake_withdraw_authority, - stake_pool_deposit_authority, - stake::state::StakeAuthorize::Withdrawer, - None, - ), - Instruction { - program_id: *program_id, - accounts, - data: StakePoolInstruction::DepositStake.try_to_vec().unwrap(), - }, - ] + deposit_stake_internal( + program_id, + stake_pool, + validator_list_storage, + Some(stake_pool_deposit_authority), + stake_pool_withdraw_authority, + deposit_stake_address, + deposit_stake_withdraw_authority, + validator_stake_account, + reserve_stake_account, + pool_tokens_to, + manager_fee_account, + referrer_pool_tokens_account, + pool_mint, + token_program_id, + None, + ) +} + +/// Creates instructions required to deposit into a stake pool with slippage, given +/// a stake account owned by the user. The difference with `deposit()` is that a deposit +/// authority must sign this instruction, which is required for private pools. +pub fn deposit_stake_with_authority_and_slippage( + program_id: &Pubkey, + stake_pool: &Pubkey, + validator_list_storage: &Pubkey, + stake_pool_deposit_authority: &Pubkey, + stake_pool_withdraw_authority: &Pubkey, + deposit_stake_address: &Pubkey, + deposit_stake_withdraw_authority: &Pubkey, + validator_stake_account: &Pubkey, + reserve_stake_account: &Pubkey, + pool_tokens_to: &Pubkey, + manager_fee_account: &Pubkey, + referrer_pool_tokens_account: &Pubkey, + pool_mint: &Pubkey, + token_program_id: &Pubkey, + minimum_pool_tokens_out: u64, +) -> Vec { + deposit_stake_internal( + program_id, + stake_pool, + validator_list_storage, + Some(stake_pool_deposit_authority), + stake_pool_withdraw_authority, + deposit_stake_address, + deposit_stake_withdraw_authority, + validator_stake_account, + reserve_stake_account, + pool_tokens_to, + manager_fee_account, + referrer_pool_tokens_account, + pool_mint, + token_program_id, + Some(minimum_pool_tokens_out), + ) } /// Creates instructions required to deposit SOL directly into a stake pool. -pub fn deposit_sol( +fn deposit_sol_internal( program_id: &Pubkey, stake_pool: &Pubkey, stake_pool_withdraw_authority: &Pubkey, @@ -1412,9 +1646,11 @@ pub fn deposit_sol( referrer_pool_tokens_account: &Pubkey, pool_mint: &Pubkey, token_program_id: &Pubkey, - amount: u64, + sol_deposit_authority: Option<&Pubkey>, + lamports_in: u64, + minimum_pool_tokens_out: Option, ) -> Instruction { - let accounts = vec![ + let mut accounts = vec![ AccountMeta::new(*stake_pool, false), AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), AccountMeta::new(*reserve_stake_account, false), @@ -1426,15 +1662,94 @@ pub fn deposit_sol( AccountMeta::new_readonly(system_program::id(), false), AccountMeta::new_readonly(*token_program_id, false), ]; - Instruction { - program_id: *program_id, - accounts, - data: StakePoolInstruction::DepositSol(amount) + if let Some(sol_deposit_authority) = sol_deposit_authority { + accounts.push(AccountMeta::new_readonly(*sol_deposit_authority, true)); + } + if let Some(minimum_pool_tokens_out) = minimum_pool_tokens_out { + Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::DepositSolWithSlippage { + lamports_in, + minimum_pool_tokens_out, + } .try_to_vec() .unwrap(), + } + } else { + Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::DepositSol(lamports_in) + .try_to_vec() + .unwrap(), + } } } +/// Creates instruction to deposit SOL directly into a stake pool. +pub fn deposit_sol( + program_id: &Pubkey, + stake_pool: &Pubkey, + stake_pool_withdraw_authority: &Pubkey, + reserve_stake_account: &Pubkey, + lamports_from: &Pubkey, + pool_tokens_to: &Pubkey, + manager_fee_account: &Pubkey, + referrer_pool_tokens_account: &Pubkey, + pool_mint: &Pubkey, + token_program_id: &Pubkey, + lamports_in: u64, +) -> Instruction { + deposit_sol_internal( + program_id, + stake_pool, + stake_pool_withdraw_authority, + reserve_stake_account, + lamports_from, + pool_tokens_to, + manager_fee_account, + referrer_pool_tokens_account, + pool_mint, + token_program_id, + None, + lamports_in, + None, + ) +} + +/// Creates instruction to deposit SOL directly into a stake pool with slippage constraint. +pub fn deposit_sol_with_slippage( + program_id: &Pubkey, + stake_pool: &Pubkey, + stake_pool_withdraw_authority: &Pubkey, + reserve_stake_account: &Pubkey, + lamports_from: &Pubkey, + pool_tokens_to: &Pubkey, + manager_fee_account: &Pubkey, + referrer_pool_tokens_account: &Pubkey, + pool_mint: &Pubkey, + token_program_id: &Pubkey, + lamports_in: u64, + minimum_pool_tokens_out: u64, +) -> Instruction { + deposit_sol_internal( + program_id, + stake_pool, + stake_pool_withdraw_authority, + reserve_stake_account, + lamports_from, + pool_tokens_to, + manager_fee_account, + referrer_pool_tokens_account, + pool_mint, + token_program_id, + None, + lamports_in, + Some(minimum_pool_tokens_out), + ) +} + /// Creates instruction required to deposit SOL directly into a stake pool. /// The difference with `deposit_sol()` is that a deposit /// authority must sign this instruction. @@ -1450,32 +1765,59 @@ pub fn deposit_sol_with_authority( referrer_pool_tokens_account: &Pubkey, pool_mint: &Pubkey, token_program_id: &Pubkey, - amount: u64, + lamports_in: u64, ) -> Instruction { - let accounts = vec![ - AccountMeta::new(*stake_pool, false), - AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), - AccountMeta::new(*reserve_stake_account, false), - AccountMeta::new(*lamports_from, true), - AccountMeta::new(*pool_tokens_to, false), - AccountMeta::new(*manager_fee_account, false), - AccountMeta::new(*referrer_pool_tokens_account, false), - AccountMeta::new(*pool_mint, false), - AccountMeta::new_readonly(system_program::id(), false), - AccountMeta::new_readonly(*token_program_id, false), - AccountMeta::new_readonly(*sol_deposit_authority, true), - ]; - Instruction { - program_id: *program_id, - accounts, - data: StakePoolInstruction::DepositSol(amount) - .try_to_vec() - .unwrap(), - } + deposit_sol_internal( + program_id, + stake_pool, + stake_pool_withdraw_authority, + reserve_stake_account, + lamports_from, + pool_tokens_to, + manager_fee_account, + referrer_pool_tokens_account, + pool_mint, + token_program_id, + Some(sol_deposit_authority), + lamports_in, + None, + ) } -/// Creates a 'WithdrawStake' instruction. -pub fn withdraw_stake( +/// Creates instruction to deposit SOL directly into a stake pool with slippage constraint. +pub fn deposit_sol_with_authority_and_slippage( + program_id: &Pubkey, + stake_pool: &Pubkey, + sol_deposit_authority: &Pubkey, + stake_pool_withdraw_authority: &Pubkey, + reserve_stake_account: &Pubkey, + lamports_from: &Pubkey, + pool_tokens_to: &Pubkey, + manager_fee_account: &Pubkey, + referrer_pool_tokens_account: &Pubkey, + pool_mint: &Pubkey, + token_program_id: &Pubkey, + lamports_in: u64, + minimum_pool_tokens_out: u64, +) -> Instruction { + deposit_sol_internal( + program_id, + stake_pool, + stake_pool_withdraw_authority, + reserve_stake_account, + lamports_from, + pool_tokens_to, + manager_fee_account, + referrer_pool_tokens_account, + pool_mint, + token_program_id, + Some(sol_deposit_authority), + lamports_in, + Some(minimum_pool_tokens_out), + ) +} + +fn withdraw_stake_internal( program_id: &Pubkey, stake_pool: &Pubkey, validator_list_storage: &Pubkey, @@ -1488,7 +1830,8 @@ pub fn withdraw_stake( manager_fee_account: &Pubkey, pool_mint: &Pubkey, token_program_id: &Pubkey, - amount: u64, + pool_tokens_in: u64, + minimum_lamports_out: Option, ) -> Instruction { let accounts = vec![ AccountMeta::new(*stake_pool, false), @@ -1505,17 +1848,98 @@ pub fn withdraw_stake( AccountMeta::new_readonly(*token_program_id, false), AccountMeta::new_readonly(stake::program::id(), false), ]; - Instruction { - program_id: *program_id, - accounts, - data: StakePoolInstruction::WithdrawStake(amount) + if let Some(minimum_lamports_out) = minimum_lamports_out { + Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::WithdrawStakeWithSlippage { + pool_tokens_in, + minimum_lamports_out, + } .try_to_vec() .unwrap(), + } + } else { + Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::WithdrawStake(pool_tokens_in) + .try_to_vec() + .unwrap(), + } } } -/// Creates instruction required to withdraw SOL directly from a stake pool. -pub fn withdraw_sol( +/// Creates a 'WithdrawStake' instruction. +pub fn withdraw_stake( + program_id: &Pubkey, + stake_pool: &Pubkey, + validator_list_storage: &Pubkey, + stake_pool_withdraw: &Pubkey, + stake_to_split: &Pubkey, + stake_to_receive: &Pubkey, + user_stake_authority: &Pubkey, + user_transfer_authority: &Pubkey, + user_pool_token_account: &Pubkey, + manager_fee_account: &Pubkey, + pool_mint: &Pubkey, + token_program_id: &Pubkey, + pool_tokens_in: u64, +) -> Instruction { + withdraw_stake_internal( + program_id, + stake_pool, + validator_list_storage, + stake_pool_withdraw, + stake_to_split, + stake_to_receive, + user_stake_authority, + user_transfer_authority, + user_pool_token_account, + manager_fee_account, + pool_mint, + token_program_id, + pool_tokens_in, + None, + ) +} + +/// Creates a 'WithdrawStakeWithSlippage' instruction. +pub fn withdraw_stake_with_slippage( + program_id: &Pubkey, + stake_pool: &Pubkey, + validator_list_storage: &Pubkey, + stake_pool_withdraw: &Pubkey, + stake_to_split: &Pubkey, + stake_to_receive: &Pubkey, + user_stake_authority: &Pubkey, + user_transfer_authority: &Pubkey, + user_pool_token_account: &Pubkey, + manager_fee_account: &Pubkey, + pool_mint: &Pubkey, + token_program_id: &Pubkey, + pool_tokens_in: u64, + minimum_lamports_out: u64, +) -> Instruction { + withdraw_stake_internal( + program_id, + stake_pool, + validator_list_storage, + stake_pool_withdraw, + stake_to_split, + stake_to_receive, + user_stake_authority, + user_transfer_authority, + user_pool_token_account, + manager_fee_account, + pool_mint, + token_program_id, + pool_tokens_in, + Some(minimum_lamports_out), + ) +} + +fn withdraw_sol_internal( program_id: &Pubkey, stake_pool: &Pubkey, stake_pool_withdraw_authority: &Pubkey, @@ -1526,9 +1950,11 @@ pub fn withdraw_sol( manager_fee_account: &Pubkey, pool_mint: &Pubkey, token_program_id: &Pubkey, - pool_tokens: u64, + sol_withdraw_authority: Option<&Pubkey>, + pool_tokens_in: u64, + minimum_lamports_out: Option, ) -> Instruction { - let accounts = vec![ + let mut accounts = vec![ AccountMeta::new(*stake_pool, false), AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), AccountMeta::new_readonly(*user_transfer_authority, true), @@ -1542,15 +1968,95 @@ pub fn withdraw_sol( AccountMeta::new_readonly(stake::program::id(), false), AccountMeta::new_readonly(*token_program_id, false), ]; - Instruction { - program_id: *program_id, - accounts, - data: StakePoolInstruction::WithdrawSol(pool_tokens) + if let Some(sol_withdraw_authority) = sol_withdraw_authority { + accounts.push(AccountMeta::new_readonly(*sol_withdraw_authority, true)); + } + if let Some(minimum_lamports_out) = minimum_lamports_out { + Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::WithdrawSolWithSlippage { + pool_tokens_in, + minimum_lamports_out, + } .try_to_vec() .unwrap(), + } + } else { + Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::WithdrawSol(pool_tokens_in) + .try_to_vec() + .unwrap(), + } } } +/// Creates instruction required to withdraw SOL directly from a stake pool. +pub fn withdraw_sol( + program_id: &Pubkey, + stake_pool: &Pubkey, + stake_pool_withdraw_authority: &Pubkey, + user_transfer_authority: &Pubkey, + pool_tokens_from: &Pubkey, + reserve_stake_account: &Pubkey, + lamports_to: &Pubkey, + manager_fee_account: &Pubkey, + pool_mint: &Pubkey, + token_program_id: &Pubkey, + pool_tokens_in: u64, +) -> Instruction { + withdraw_sol_internal( + program_id, + stake_pool, + stake_pool_withdraw_authority, + user_transfer_authority, + pool_tokens_from, + reserve_stake_account, + lamports_to, + manager_fee_account, + pool_mint, + token_program_id, + None, + pool_tokens_in, + None, + ) +} + +/// Creates instruction required to withdraw SOL directly from a stake pool with +/// slippage constraints. +pub fn withdraw_sol_with_slippage( + program_id: &Pubkey, + stake_pool: &Pubkey, + stake_pool_withdraw_authority: &Pubkey, + user_transfer_authority: &Pubkey, + pool_tokens_from: &Pubkey, + reserve_stake_account: &Pubkey, + lamports_to: &Pubkey, + manager_fee_account: &Pubkey, + pool_mint: &Pubkey, + token_program_id: &Pubkey, + pool_tokens_in: u64, + minimum_lamports_out: u64, +) -> Instruction { + withdraw_sol_internal( + program_id, + stake_pool, + stake_pool_withdraw_authority, + user_transfer_authority, + pool_tokens_from, + reserve_stake_account, + lamports_to, + manager_fee_account, + pool_mint, + token_program_id, + None, + pool_tokens_in, + Some(minimum_lamports_out), + ) +} + /// Creates instruction required to withdraw SOL directly from a stake pool. /// The difference with `withdraw_sol()` is that the sol withdraw authority /// must sign this instruction. @@ -1566,30 +2072,59 @@ pub fn withdraw_sol_with_authority( manager_fee_account: &Pubkey, pool_mint: &Pubkey, token_program_id: &Pubkey, - pool_tokens: u64, + pool_tokens_in: u64, ) -> Instruction { - let accounts = vec![ - AccountMeta::new(*stake_pool, false), - AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), - AccountMeta::new_readonly(*user_transfer_authority, true), - AccountMeta::new(*pool_tokens_from, false), - AccountMeta::new(*reserve_stake_account, false), - AccountMeta::new(*lamports_to, false), - AccountMeta::new(*manager_fee_account, false), - AccountMeta::new(*pool_mint, false), - AccountMeta::new_readonly(sysvar::clock::id(), false), - AccountMeta::new_readonly(sysvar::stake_history::id(), false), - AccountMeta::new_readonly(stake::program::id(), false), - AccountMeta::new_readonly(*token_program_id, false), - AccountMeta::new_readonly(*sol_withdraw_authority, true), - ]; - Instruction { - program_id: *program_id, - accounts, - data: StakePoolInstruction::WithdrawSol(pool_tokens) - .try_to_vec() - .unwrap(), - } + withdraw_sol_internal( + program_id, + stake_pool, + stake_pool_withdraw_authority, + user_transfer_authority, + pool_tokens_from, + reserve_stake_account, + lamports_to, + manager_fee_account, + pool_mint, + token_program_id, + Some(sol_withdraw_authority), + pool_tokens_in, + None, + ) +} + +/// Creates instruction required to withdraw SOL directly from a stake pool with +/// a slippage constraint. +/// The difference with `withdraw_sol()` is that the sol withdraw authority +/// must sign this instruction. +pub fn withdraw_sol_with_authority_and_slippage( + program_id: &Pubkey, + stake_pool: &Pubkey, + sol_withdraw_authority: &Pubkey, + stake_pool_withdraw_authority: &Pubkey, + user_transfer_authority: &Pubkey, + pool_tokens_from: &Pubkey, + reserve_stake_account: &Pubkey, + lamports_to: &Pubkey, + manager_fee_account: &Pubkey, + pool_mint: &Pubkey, + token_program_id: &Pubkey, + pool_tokens_in: u64, + minimum_lamports_out: u64, +) -> Instruction { + withdraw_sol_internal( + program_id, + stake_pool, + stake_pool_withdraw_authority, + user_transfer_authority, + pool_tokens_from, + reserve_stake_account, + lamports_to, + manager_fee_account, + pool_mint, + token_program_id, + Some(sol_withdraw_authority), + pool_tokens_in, + Some(minimum_lamports_out), + ) } /// Creates a 'set manager' instruction. diff --git a/program/src/processor.rs b/program/src/processor.rs index 83ad845b..28842c5c 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -2630,7 +2630,11 @@ impl Processor { /// Processes [DepositStake](enum.Instruction.html). #[inline(never)] // needed to avoid stack size violation - fn process_deposit_stake(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { + fn process_deposit_stake( + program_id: &Pubkey, + accounts: &[AccountInfo], + minimum_pool_tokens_out: Option, + ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; let validator_list_info = next_account_info(account_info_iter)?; @@ -2819,6 +2823,12 @@ impl Processor { return Err(StakePoolError::DepositTooSmall.into()); } + if let Some(minimum_pool_tokens_out) = minimum_pool_tokens_out { + if pool_tokens_user < minimum_pool_tokens_out { + return Err(StakePoolError::ExceededSlippage.into()); + } + } + Self::token_mint_to( stake_pool_info.key, token_program_info.clone(), @@ -2893,6 +2903,7 @@ impl Processor { program_id: &Pubkey, accounts: &[AccountInfo], deposit_lamports: u64, + minimum_pool_tokens_out: Option, ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; @@ -2972,6 +2983,12 @@ impl Processor { return Err(StakePoolError::DepositTooSmall.into()); } + if let Some(minimum_pool_tokens_out) = minimum_pool_tokens_out { + if pool_tokens_user < minimum_pool_tokens_out { + return Err(StakePoolError::ExceededSlippage.into()); + } + } + Self::sol_transfer( from_user_lamports_info.clone(), reserve_stake_account_info.clone(), @@ -3035,6 +3052,7 @@ impl Processor { program_id: &Pubkey, accounts: &[AccountInfo], pool_tokens: u64, + minimum_lamports_out: Option, ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; @@ -3109,6 +3127,12 @@ impl Processor { return Err(StakePoolError::WithdrawalTooSmall.into()); } + if let Some(minimum_lamports_out) = minimum_lamports_out { + if withdraw_lamports < minimum_lamports_out { + return Err(StakePoolError::ExceededSlippage.into()); + } + } + let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; let stake_state = try_from_slice_unchecked::(&stake_split_from.data.borrow())?; @@ -3340,6 +3364,7 @@ impl Processor { program_id: &Pubkey, accounts: &[AccountInfo], pool_tokens: u64, + minimum_lamports_out: Option, ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; @@ -3409,6 +3434,12 @@ impl Processor { return Err(StakePoolError::WithdrawalTooSmall.into()); } + if let Some(minimum_lamports_out) = minimum_lamports_out { + if withdraw_lamports < minimum_lamports_out { + return Err(StakePoolError::ExceededSlippage.into()); + } + } + let new_reserve_lamports = reserve_stake_info .lamports() .saturating_sub(withdraw_lamports); @@ -3879,11 +3910,11 @@ impl Processor { } StakePoolInstruction::DepositStake => { msg!("Instruction: DepositStake"); - Self::process_deposit_stake(program_id, accounts) + Self::process_deposit_stake(program_id, accounts, None) } StakePoolInstruction::WithdrawStake(amount) => { msg!("Instruction: WithdrawStake"); - Self::process_withdraw_stake(program_id, accounts, amount) + Self::process_withdraw_stake(program_id, accounts, amount, None) } StakePoolInstruction::SetFee { fee } => { msg!("Instruction: SetFee"); @@ -3903,11 +3934,11 @@ impl Processor { } StakePoolInstruction::DepositSol(lamports) => { msg!("Instruction: DepositSol"); - Self::process_deposit_sol(program_id, accounts, lamports) + Self::process_deposit_sol(program_id, accounts, lamports, None) } StakePoolInstruction::WithdrawSol(pool_tokens) => { msg!("Instruction: WithdrawSol"); - Self::process_withdraw_sol(program_id, accounts, pool_tokens) + Self::process_withdraw_sol(program_id, accounts, pool_tokens, None) } StakePoolInstruction::CreateTokenMetadata { name, symbol, uri } => { msg!("Instruction: CreateTokenMetadata"); @@ -3933,6 +3964,48 @@ impl Processor { destination_transient_stake_seed, ) } + StakePoolInstruction::DepositStakeWithSlippage { + minimum_pool_tokens_out, + } => { + msg!("Instruction: DepositStakeWithSlippage"); + Self::process_deposit_stake(program_id, accounts, Some(minimum_pool_tokens_out)) + } + StakePoolInstruction::WithdrawStakeWithSlippage { + pool_tokens_in, + minimum_lamports_out, + } => { + msg!("Instruction: WithdrawStakeWithSlippage"); + Self::process_withdraw_stake( + program_id, + accounts, + pool_tokens_in, + Some(minimum_lamports_out), + ) + } + StakePoolInstruction::DepositSolWithSlippage { + lamports_in, + minimum_pool_tokens_out, + } => { + msg!("Instruction: DepositSolWithSlippage"); + Self::process_deposit_sol( + program_id, + accounts, + lamports_in, + Some(minimum_pool_tokens_out), + ) + } + StakePoolInstruction::WithdrawSolWithSlippage { + pool_tokens_in, + minimum_lamports_out, + } => { + msg!("Instruction: WithdrawSolWithSlippage"); + Self::process_withdraw_sol( + program_id, + accounts, + pool_tokens_in, + Some(minimum_lamports_out), + ) + } } } } @@ -3984,6 +4057,7 @@ impl PrintProgramError for StakePoolError { StakePoolError::InvalidMetadataAccount => msg!("Error: Metadata account derived from pool mint account does not match the one passed to program"), StakePoolError::UnsupportedMintExtension => msg!("Error: mint has an unsupported extension"), StakePoolError::UnsupportedFeeAccountExtension => msg!("Error: fee account has an unsupported extension"), + StakePoolError::ExceededSlippage => msg!("Error: instruction exceeds desired slippage limit"), } } } diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 07955b9e..7736918c 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -799,3 +799,105 @@ async fn fail_with_wrong_mint_for_receiver_acc() { } } } + +#[test_case(spl_token::id(); "token")] +#[test_case(spl_token_2022::id(); "token-2022")] +#[tokio::test] +async fn success_with_slippage(token_program_id: Pubkey) { + let ( + mut context, + stake_pool_accounts, + validator_stake_account, + user, + deposit_stake, + pool_token_account, + stake_lamports, + ) = setup(token_program_id).await; + + let rent = context.banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + + // Save stake pool state before depositing + let pre_stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let pre_stake_pool = + try_from_slice_unchecked::(pre_stake_pool.data.as_slice()).unwrap(); + + let tokens_issued = stake_lamports; // For now tokens are 1:1 to stake + let tokens_issued_user = tokens_issued + - pre_stake_pool + .calc_pool_tokens_sol_deposit_fee(stake_rent) + .unwrap() + - pre_stake_pool + .calc_pool_tokens_stake_deposit_fee(stake_lamports - stake_rent) + .unwrap(); + + let error = stake_pool_accounts + .deposit_stake_with_slippage( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &deposit_stake, + &pool_token_account, + &validator_stake_account.stake_account, + &user, + tokens_issued_user + 1, + ) + .await + .unwrap() + .unwrap(); + assert_eq!( + error, + TransactionError::InstructionError( + 2, + InstructionError::Custom(StakePoolError::ExceededSlippage as u32) + ) + ); + + let error = stake_pool_accounts + .deposit_stake_with_slippage( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &deposit_stake, + &pool_token_account, + &validator_stake_account.stake_account, + &user, + tokens_issued_user, + ) + .await; + assert!(error.is_none()); + + // Original stake account should be drained + assert!(context + .banks_client + .get_account(deposit_stake) + .await + .expect("get_account") + .is_none()); + + // Stake pool should add its balance to the pool balance + let post_stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let post_stake_pool = + try_from_slice_unchecked::(post_stake_pool.data.as_slice()).unwrap(); + assert_eq!( + post_stake_pool.total_lamports, + pre_stake_pool.total_lamports + stake_lamports + ); + assert_eq!( + post_stake_pool.pool_token_supply, + pre_stake_pool.pool_token_supply + tokens_issued + ); + + // Check minted tokens + let user_token_balance = + get_token_balance(&mut context.banks_client, &pool_token_account).await; + assert_eq!(user_token_balance, tokens_issued_user); +} diff --git a/program/tests/deposit_sol.rs b/program/tests/deposit_sol.rs index e083419c..5d390f00 100644 --- a/program/tests/deposit_sol.rs +++ b/program/tests/deposit_sol.rs @@ -504,3 +504,104 @@ async fn fail_with_invalid_referrer() { ), } } + +#[test_case(spl_token::id(); "token")] +#[test_case(spl_token_2022::id(); "token-2022")] +#[tokio::test] +async fn success_with_slippage(token_program_id: Pubkey) { + let (mut context, stake_pool_accounts, _user, pool_token_account) = + setup(token_program_id).await; + + // Save stake pool state before depositing + let pre_stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let pre_stake_pool = + try_from_slice_unchecked::(pre_stake_pool.data.as_slice()).unwrap(); + + // Save reserve state before depositing + let pre_reserve_lamports = get_account( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + ) + .await + .lamports; + + let new_pool_tokens = pre_stake_pool + .calc_pool_tokens_for_deposit(TEST_STAKE_AMOUNT) + .unwrap(); + let pool_tokens_sol_deposit_fee = pre_stake_pool + .calc_pool_tokens_sol_deposit_fee(new_pool_tokens) + .unwrap(); + let tokens_issued = new_pool_tokens - pool_tokens_sol_deposit_fee; + + // Fail with 1 more token in slippage + let error = stake_pool_accounts + .deposit_sol_with_slippage( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &pool_token_account, + TEST_STAKE_AMOUNT, + tokens_issued + 1, + ) + .await + .unwrap() + .unwrap(); + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(error::StakePoolError::ExceededSlippage as u32) + ) + ); + + // Succeed with exact return amount + let error = stake_pool_accounts + .deposit_sol_with_slippage( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &pool_token_account, + TEST_STAKE_AMOUNT, + tokens_issued, + ) + .await; + assert!(error.is_none()); + + // Stake pool should add its balance to the pool balance + let post_stake_pool = get_account( + &mut context.banks_client, + &stake_pool_accounts.stake_pool.pubkey(), + ) + .await; + let post_stake_pool = + try_from_slice_unchecked::(post_stake_pool.data.as_slice()).unwrap(); + assert_eq!( + post_stake_pool.total_lamports, + pre_stake_pool.total_lamports + TEST_STAKE_AMOUNT + ); + assert_eq!( + post_stake_pool.pool_token_supply, + pre_stake_pool.pool_token_supply + new_pool_tokens + ); + + // Check minted tokens + let user_token_balance = + get_token_balance(&mut context.banks_client, &pool_token_account).await; + assert_eq!(user_token_balance, tokens_issued); + + // Check reserve + let post_reserve_lamports = get_account( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + ) + .await + .lamports; + assert_eq!( + post_reserve_lamports, + pre_reserve_lamports + TEST_STAKE_AMOUNT + ); +} diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index f8a1a9e1..498cd961 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -967,6 +967,48 @@ impl StakePoolAccounts { Ok(()) } + #[allow(clippy::too_many_arguments)] + pub async fn deposit_stake_with_slippage( + &self, + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + stake: &Pubkey, + pool_account: &Pubkey, + validator_stake_account: &Pubkey, + current_staker: &Keypair, + minimum_pool_tokens_out: u64, + ) -> Option { + let mut instructions = instruction::deposit_stake_with_slippage( + &id(), + &self.stake_pool.pubkey(), + &self.validator_list.pubkey(), + &self.withdraw_authority, + stake, + ¤t_staker.pubkey(), + validator_stake_account, + &self.reserve_stake.pubkey(), + pool_account, + &self.pool_fee_account.pubkey(), + &self.pool_fee_account.pubkey(), + &self.pool_mint.pubkey(), + &self.token_program_id, + minimum_pool_tokens_out, + ); + self.maybe_add_compute_budget_instruction(&mut instructions); + let transaction = Transaction::new_signed_with_payer( + &instructions, + Some(&payer.pubkey()), + &[payer, current_staker], + *recent_blockhash, + ); + banks_client + .process_transaction(transaction) + .await + .map_err(|e| e.into()) + .err() + } + #[allow(clippy::too_many_arguments)] pub async fn deposit_stake( &self, @@ -1111,6 +1153,88 @@ impl StakePoolAccounts { .err() } + #[allow(clippy::too_many_arguments)] + pub async fn deposit_sol_with_slippage( + &self, + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + pool_account: &Pubkey, + lamports_in: u64, + minimum_pool_tokens_out: u64, + ) -> Option { + let mut instructions = vec![instruction::deposit_sol_with_slippage( + &id(), + &self.stake_pool.pubkey(), + &self.withdraw_authority, + &self.reserve_stake.pubkey(), + &payer.pubkey(), + pool_account, + &self.pool_fee_account.pubkey(), + &self.pool_fee_account.pubkey(), + &self.pool_mint.pubkey(), + &self.token_program_id, + lamports_in, + minimum_pool_tokens_out, + )]; + self.maybe_add_compute_budget_instruction(&mut instructions); + let transaction = Transaction::new_signed_with_payer( + &instructions, + Some(&payer.pubkey()), + &[payer], + *recent_blockhash, + ); + banks_client + .process_transaction(transaction) + .await + .map_err(|e| e.into()) + .err() + } + + #[allow(clippy::too_many_arguments)] + pub async fn withdraw_stake_with_slippage( + &self, + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + stake_recipient: &Pubkey, + user_transfer_authority: &Keypair, + pool_account: &Pubkey, + validator_stake_account: &Pubkey, + recipient_new_authority: &Pubkey, + pool_tokens_in: u64, + minimum_lamports_out: u64, + ) -> Option { + let mut instructions = vec![instruction::withdraw_stake_with_slippage( + &id(), + &self.stake_pool.pubkey(), + &self.validator_list.pubkey(), + &self.withdraw_authority, + validator_stake_account, + stake_recipient, + recipient_new_authority, + &user_transfer_authority.pubkey(), + pool_account, + &self.pool_fee_account.pubkey(), + &self.pool_mint.pubkey(), + &self.token_program_id, + pool_tokens_in, + minimum_lamports_out, + )]; + self.maybe_add_compute_budget_instruction(&mut instructions); + let transaction = Transaction::new_signed_with_payer( + &instructions, + Some(&payer.pubkey()), + &[payer, user_transfer_authority], + *recent_blockhash, + ); + banks_client + .process_transaction(transaction) + .await + .map_err(|e| e.into()) + .err() + } + #[allow(clippy::too_many_arguments)] pub async fn withdraw_stake( &self, @@ -1153,6 +1277,45 @@ impl StakePoolAccounts { .err() } + #[allow(clippy::too_many_arguments)] + pub async fn withdraw_sol_with_slippage( + &self, + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + user: &Keypair, + pool_account: &Pubkey, + amount_in: u64, + minimum_lamports_out: u64, + ) -> Option { + let mut instructions = vec![instruction::withdraw_sol_with_slippage( + &id(), + &self.stake_pool.pubkey(), + &self.withdraw_authority, + &user.pubkey(), + pool_account, + &self.reserve_stake.pubkey(), + &user.pubkey(), + &self.pool_fee_account.pubkey(), + &self.pool_mint.pubkey(), + &self.token_program_id, + amount_in, + minimum_lamports_out, + )]; + self.maybe_add_compute_budget_instruction(&mut instructions); + let transaction = Transaction::new_signed_with_payer( + &instructions, + Some(&payer.pubkey()), + &[payer, user], + *recent_blockhash, + ); + banks_client + .process_transaction(transaction) + .await + .map_err(|e| e.into()) + .err() + } + #[allow(clippy::too_many_arguments)] pub async fn withdraw_sol( &self, diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 85c60e71..6ee5bf60 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -760,3 +760,81 @@ async fn fail_with_not_enough_tokens() { ) ); } + +#[test_case(spl_token::id(); "token")] +#[test_case(spl_token_2022::id(); "token-2022")] +#[tokio::test] +async fn success_with_slippage(token_program_id: Pubkey) { + let ( + mut context, + stake_pool_accounts, + validator_stake_account, + deposit_info, + user_transfer_authority, + user_stake_recipient, + tokens_to_withdraw, + ) = setup_for_withdraw(token_program_id).await; + + // Save user token balance + let user_token_balance_before = get_token_balance( + &mut context.banks_client, + &deposit_info.pool_account.pubkey(), + ) + .await; + + // first and only deposit, lamports:pool 1:1 + let tokens_withdrawal_fee = stake_pool_accounts.calculate_withdrawal_fee(tokens_to_withdraw); + let received_lamports = tokens_to_withdraw - tokens_withdrawal_fee; + + let new_authority = Pubkey::new_unique(); + let error = stake_pool_accounts + .withdraw_stake_with_slippage( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user_stake_recipient.pubkey(), + &user_transfer_authority, + &deposit_info.pool_account.pubkey(), + &validator_stake_account.stake_account, + &new_authority, + tokens_to_withdraw, + received_lamports + 1, + ) + .await + .unwrap() + .unwrap(); + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::ExceededSlippage as u32) + ) + ); + + let error = stake_pool_accounts + .withdraw_stake_with_slippage( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user_stake_recipient.pubkey(), + &user_transfer_authority, + &deposit_info.pool_account.pubkey(), + &validator_stake_account.stake_account, + &new_authority, + tokens_to_withdraw, + received_lamports, + ) + .await; + assert!(error.is_none()); + + // Check tokens used + let user_token_balance = get_token_balance( + &mut context.banks_client, + &deposit_info.pool_account.pubkey(), + ) + .await; + assert_eq!( + user_token_balance, + user_token_balance_before - tokens_to_withdraw + ); +} diff --git a/program/tests/withdraw_sol.rs b/program/tests/withdraw_sol.rs index 3e029b56..8370dd92 100644 --- a/program/tests/withdraw_sol.rs +++ b/program/tests/withdraw_sol.rs @@ -323,3 +323,72 @@ async fn fail_without_sol_withdraw_authority_signature() { ) ); } + +#[test_case(spl_token::id(); "token")] +#[test_case(spl_token_2022::id(); "token-2022")] +#[tokio::test] +async fn success_with_slippage(token_program_id: Pubkey) { + let (mut context, stake_pool_accounts, user, pool_token_account, pool_tokens) = + setup(token_program_id).await; + + let amount_received = pool_tokens - stake_pool_accounts.calculate_withdrawal_fee(pool_tokens); + + // Save reserve state before withdrawing + let pre_reserve_lamports = get_account( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + ) + .await + .lamports; + + let error = stake_pool_accounts + .withdraw_sol_with_slippage( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user, + &pool_token_account, + pool_tokens, + amount_received + 1, + ) + .await + .unwrap() + .unwrap(); + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::ExceededSlippage as u32) + ) + ); + + let error = stake_pool_accounts + .withdraw_sol_with_slippage( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &user, + &pool_token_account, + pool_tokens, + amount_received, + ) + .await; + assert!(error.is_none()); + + // Check burned tokens + let user_token_balance = + get_token_balance(&mut context.banks_client, &pool_token_account).await; + assert_eq!(user_token_balance, 0); + + // Check reserve + let post_reserve_lamports = get_account( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + ) + .await + .lamports; + assert_eq!( + post_reserve_lamports, + pre_reserve_lamports - amount_received + ); +} From f8fbd82687f4dd0afeef7b377bd44992c838eb03 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 1 Feb 2023 13:26:51 +0100 Subject: [PATCH 0302/1076] stake-pool: Update to newest token-metadata program (#4012) --- program/Cargo.toml | 2 +- program/src/instruction.rs | 2 -- program/src/processor.rs | 17 ----------------- program/tests/fixtures/mpl_token_metadata.so | Bin 383568 -> 693904 bytes 4 files changed, 1 insertion(+), 20 deletions(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index ef8c7ecc..5cb2eb3e 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -14,7 +14,7 @@ test-sbf = [] [dependencies] arrayref = "0.3.6" borsh = "0.9" -mpl-token-metadata = { version = "1.3.1", features = [ "no-entrypoint" ] } +mpl-token-metadata = { version = "1.7.0", features = [ "no-entrypoint" ] } num-derive = "0.3" num-traits = "0.2" num_enum = "0.5.4" diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 5725eb70..a80c861b 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -377,7 +377,6 @@ pub enum StakePoolInstruction { /// 5. `[w]` Token metadata account /// 6. `[]` Metadata program id /// 7. `[]` System program id - /// 8. `[]` Rent sysvar CreateTokenMetadata { /// Token name name: String, @@ -2266,7 +2265,6 @@ pub fn create_token_metadata( AccountMeta::new(token_metadata, false), AccountMeta::new_readonly(mpl_token_metadata::id(), false), AccountMeta::new_readonly(system_program::id(), false), - AccountMeta::new_readonly(sysvar::rent::id(), false), ]; Instruction { diff --git a/program/src/processor.rs b/program/src/processor.rs index 28842c5c..ba98e546 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -173,20 +173,6 @@ fn check_mpl_metadata_program(program_id: &Pubkey) -> Result<(), ProgramError> { } } -/// Check rent sysvar correctness -fn check_rent_sysvar(sysvar_key: &Pubkey) -> Result<(), ProgramError> { - if *sysvar_key != solana_program::sysvar::rent::id() { - msg!( - "Expected rent sysvar {}, received {}", - solana_program::sysvar::rent::id(), - sysvar_key - ); - Err(ProgramError::InvalidArgument) - } else { - Ok(()) - } -} - /// Check account owner is the given program fn check_account_owner( account_info: &AccountInfo, @@ -3523,7 +3509,6 @@ impl Processor { let metadata_info = next_account_info(account_info_iter)?; let mpl_token_metadata_program_info = next_account_info(account_info_iter)?; let system_program_info = next_account_info(account_info_iter)?; - let rent_sysvar_info = next_account_info(account_info_iter)?; if !payer_info.is_signer { msg!("Payer did not sign metadata creation"); @@ -3531,7 +3516,6 @@ impl Processor { } check_system_program(system_program_info.key)?; - check_rent_sysvar(rent_sysvar_info.key)?; check_account_owner(payer_info, &system_program::id())?; check_account_owner(stake_pool_info, program_id)?; check_mpl_metadata_program(mpl_token_metadata_program_info.key)?; @@ -3590,7 +3574,6 @@ impl Processor { payer_info.clone(), withdraw_authority_info.clone(), system_program_info.clone(), - rent_sysvar_info.clone(), mpl_token_metadata_program_info.clone(), ], &[token_mint_authority_signer_seeds], diff --git a/program/tests/fixtures/mpl_token_metadata.so b/program/tests/fixtures/mpl_token_metadata.so index f7b3c9f1793e7d33ae892d4036d669974ac774c2..399c584c5c130c92e588bd4834bc3fd168a55d2b 100755 GIT binary patch literal 693904 zcmeFa3!Ii!wLiY!fk)8PQSe0^MP|4NPEDbr(sTn&qv--(Mu;*PMg-B4aZGr4ItgBp zV;$5oqB`-;a2ZY)=n9=KFP0TuG`gdvj%7ucQ*@^?{jcx3>}S8v`_AwVBB%5F{GW_H zYhTu0d#$zCUiE9#WP|k~- z^@<`J_Pp*$E@z=TPS7Cx5%mAvub1>}IC7=rvoI_-n3C4+mU7u}f47vg(8|?NH0s;? zZ7G)xw@EQ);ZTJ~H5|`>b>tg3EKZh$+Dj$ePK`%fn$E|+&H={P8V%w2krdslZAAQb zBIFbbM-Fms{U)IW@wXCRwvNbg_zZnRsN5KeFP@K7=OXvpXAl-A;a}(8BY}%2Q$hOT zvxVYh&VJ4ppCuVaHE6m7E*>HI;uAG~QOO3!4)+fv$&n&BZe^P z>sTmscPu)c;rL1pTzr*=3j|+$h2pn60*_iqMA8?Q--mW6y}&d5G3qBOkK#%xXL3Tn1pQ6uu=D}O z*IG01etb^YkBOg*xgLa)GaB+f$nt#+XVkmu{|0=)Y&5{r88bLe& zpT|&CvhH?a})9LRnZpGCX>N_x>(yAPFJ>^P}`8Qr0FF}b9k;pCo) z5>{as(I3p7S8EsJ;i3RZbFcL0;UsAKlIA@Mqt^o7EwGqH=k0>p{iIIqsJ9Q&FJoyI z<=@NY!+x_1{ici2yCF3+W@6wj3SB8(?}(CZ^kO~=FH84_Q-Si>OSPe!Hrn$DAi#M-On%IZ5$@mwMy z>U$`_6Az;Z`e5hqB{n`CCvs`6k#@zyB;D-!b^+a}GvTF>{*RRij31Ne&&1kMFY!i~ zm7A4w4g$&N#&d>z?idG4ozETXNE8&-^7xX^9Y;PG;Nz*!BOJ#5O+Gi=K_dCw32fK% zxjgx4fJZn;CZ9XeJ&(fH+(@=}sF$iF9Arf31C072mj}o&>W!QXP)G+$A}0z57<5Fg zmj0FepeJ(2co-He;#wsg^hHdSz~E%WR0|AxBl;gc;0N6i*D5gRkC*5BZ1ZQ#}HWpeu_vYoCkrQQEoD*GYITF>4I{34E_2 zLT#L}aVV^>jtDpy{LmxdAA11&V-Etq`7fb8z&N@cLZQ$41L}YG->Bag)Sj51vz8L* zOD0PHNOT7zMa3>3<5o>@v~J*PMM@<#{hW*<=Q_W^$*oq!?! zM?pO3sbhR%Ad&vLOgiRCkporI{+=M+>&uw+_2 zr`S9>nKo2mDL0bx&z_z3%Ve4uSkQT2peKhC@7DsnMdh3MZK(HQ;`4S=7WBOKI`LPF z-Ap#G3-nTXKYtUeOIjt6hg zftC51o2U;UyjjPCTXa0QRmX$dbUe6S$AeWm9^9eh!D<~3{$0m|J9RvGr;Z05a=6x=#o_zhWDeK4vpKvX zcMgXOa_D-adAio1@( zuR56ie9hO~^&IYUZ{zUm?gkFO;g)jvO}C80Z@HMm2i$TFA9M+a-*#{3aJTz64!`5x zL1AmncX=GzPJhDyM6MA5&kJA&A~(^)H4LBT;Xw?K^Dyi}dT2!`uDOy-EvY0^m_ z>VxHt+$kQ0)s0-8hhgs`_6Q|Ex#I-WA_#pbFY~AqJbVnN5A!g_ck+)sj2Tqqj`c8^ zNP>^{Fid0Qj`HwuhKG6>_9t>jcsS4SU=PC{MXtufCo;@zWqM(cBKI`?EA*er@KYYH zXZY_P9>ef{507Q|FCKG5iw`!;VF+*Tb-5k$cR;lNtW8hhf(u_ppay$0E1K!_5r; z(8I86k^8=fVb>z}T@SyU;oTmFor~Oq9-hkZw>&(J;cs~OJcf69_S5T!$ldQ@ z*u}_w$-@^iywk(5lac$Pho>|Ac@M)*M()2o{Cb9Wco=pva-Z?=Ool(@Vc5;ceZs@A zn~~e*;Y%6*n1^9UBli&xU&io%d3YAXJszIT@Fow#&PHy7hvzWde?gJivGsEjV47(h;wH}_w@Vy>xWBA=3p3m^z9){hH+!_yG!SK60ynx|5J$xm@ zt33?69=TN>Uc~Ti9)_Kd+$|nn%XN>M;TwE9#)*hW1xde-Vf-sF#*K(a6@jm37_|tDaU|kVNnl`(c+?VjDZ^;Bz{?m0 zmjuQ*6Y;1hFes0B)D#%wPUPm%zXHFV!iYy*fiVt6JSqze&O|(F3%r8hg=9_ZDO{>y zK6e>&6yZvW&*x@2a6F%z?QZ7q4J?s-ZjQT^;Ws)+ET4OmyPdSK`;_&TmGlw~c9v$kPz!(jL?}Iu0bPpfT z@B|N!WO%%XPhxnihfij>!NaF8Jleyf7{F+Zc2Gx@P9ENK>d@jTA79@QN!_V{ZOBp`W!>?v|h=*Gkjy(KYh6j20bqwb` zd@=p?9)_g8m7M<1XAlK?p}&#)hlioZw$FrgSeVHD)u-Re@Si;l{f^upJ$yUEzxVJe zhGm}^`0il%e|$RhKXSkJF#18{e(7QKhsgcH!{`^0`yXa-a4v`gi0$>EX=`f84`c7~aaT?U!J^4j+wd802L3oC;C9atY)9~yfChkoB^?9mDjo2d*)LBTWq&+N zPq;s~p6CM|M}En#O8Y?g;)1NlBz4=Ezj2rB_a%*b?m*8kB+WZHy={Z+7q++T z5_seHrQCYqSNnw%8E_vZ@bs*&q& zE0n9IzF$-**Qxs6A76Sal&hw`hYqsbcMr1MHxIJh{T0ep!6{e6`?9Q1!>fb`!s0Qy6FdgB1f9gcQy8eqE@4uJl!-SZBz+#3$E z+{Fi3?ll7_cR1v8-2mlt)&S@a<@168lsg>lz9eXOUv@2||AY$k_ho+%2mLPz=>Ole zYmNURbet5>(U)98c|J^A5m|qz8a?=4g>rrIKdkRt2U+eb11NVm^zJu*OvmAB`1R2$ z=#R(hyrfy?ckx)Amo)3VWUS0{l4hA7#$zyRp?OQA?&k;dESrb?i0JIkUtCuOT{h1P z<#xe|hl7qQs-Pp}|M-6~KEAdJ`VR*mUlPz!js1BlDj)Cq>c1iX|9p_;ep{hjHFW-> zLb+<_>^;bG4;^H=?^Y;RP5ZuCpnNeMLFHk$=kEG`@(u(r1vq_;wCwG%n8CANA)e@$m%GT`O;XcdYF&d)6w)!-!52I(?w~`P4MahkdzT zipM<=^bDjoe6tc>={JVg%42U9m<^8SYd)Qi#A5^o-aCj@Mz7&9`Yay#E;tH&m;GwH zKa$M{J7@GRrurlIlTPVI#d;i)8y?@HY&m(-G>-U-XwHp6hibuVB zGWGtN;;mlmcX{eZ&}54b>HjR{w|*D$`{s;Xh6i#n`)2(C`bcQlpXw#ew0c5(*Y<-i z%(t2F82>|k+mMMjITt9tlD=I-@kWR7!Ok(@-Y4`F_c0*1rpe>zUy|Qg4)}h=-!&cH zR@3BqP6*SXUnq~B-!xgy8HDLJd7_9dKj?#MpL-bz2$$Y*kPjWho@PMyq zcf_}51U5T-7q!dAnUMc0DZlYE)Su;?U+i`m-^Tdm-g_8-1u-;oe_=Zx#?RyYavlls zpbz^0dB!jPN|+xfuOcVsk-~T?O7VK1U;8)GCn>(yQwV*TNO7iTsAmDiTl-93@-;H< zh-}81=UjU#$Kx{^dcu^^@%~ z+_?OZh}&iDs8xR#_%0#7!4HPU+5I!aUkT4V%2x>w4RwrXQk8ht^nqvg0P*bX1J8^B z;;9eh9P;PFD)4}huOmBdd;z?*54-*;;&qtspQJj*Z?ltGe+Kx55gnBNwYxSBQquvmo>2Yh#Kc6A?usyK;|7xyB?kk3R`%;dV^Mr8~ z{#inFWXF~5XdHd!XSVX~u#|rILsSiqBPWuDEY9QXzCAXtF1zm?=soc)O)M z?EQX<$GNgw(9!fmeZ)eC`+LW2Oyi3%2K0fy5ncU22)dG?Vh_--@K>^ovkizoj2nlN zzTY1+0Q$}rdb9JXc)rAgKWHZ)3T|v_5S~=x2-yRL*xqpf{Yr)903Sa?M-`19VgLUiIg~}x zM|}AqH0h$R*uw$8!_o`9D+LCgJD(oNL) zpVQkVMET99VvH7lq$f)3|xg-o47$(O1mX^-17C6EB}H4K=*r3yIn-Bs&1n zg!1|+>PIAf$plfvWTC(&ucpb;F-D&+@pj(X-&1dp_}cR{y@3>gJ}VD;-=FE9V=29O z31?%yd62F=LVrj-pLyB&@OCMEnxy-8f`a^CrYn|~Kc!3PPw9~IMn|z;@r{r$X_kwK z$sBptD65afjgrs!WBs-WX3~fHAN|WS&y>A~qUVSE+J9)R5jz^|x$$H~J>!e@y`jX; zDeF5*X8&Td^QyllZ<`lbf3tU!K;QGo&YB*S(E}mS*P0W4Lr!1J$m#i%4m|4u`Pln? zp05MIb5}oj+Qu|BHL&(?nv)l;Lpnsz5aJ*Gctd14rS z23PW99?87#aW3VDAF(eOm#}}bEP%o9FNO7v=W1N&Z^K2fdd*)>8g>2M_Azu{%GL{$ zMm^_YeoG(kHh}NHte^*=duGP}`e;b!*+OS*`Y=fJDwU7)Ph0QJ$|F|0VfQy;e{NpJ znUKF2$NHmlNruj~{n9BN8pA#)#P~RqLdfBQaQ(fZo?^*P`g8u`r=;insQ{-dpFRD0 zo~E0V{redG(Vyk>iUHEUjj96uP5&bFFAC^?*7{mdK9Zio|3o{l{7c#&Y@O^X)$^o{=wEKu2gG5kfU!ognc z&h)P%i4SGtp!pLg3f@lLkGAos>^$Lg$ydz!&6)N#O+jl&R!VO;Zu5NP7Qw^&*_rot ze@=ooI_*AKZ1;m~{p;ct{w7+#Kiq&MxdY7;9DT$ZK!2UoIbC2reR zmJi;Q^!K`M=4|{P63T(ElQMk$I^?DM$#zZv{i{IyE~<(bRX(#wIia6;4-sEDUfB9f zU*p=EK%XnovHN+czgdl(##E4#y_Xou1M}jzOXltNzAO4!U;Ow0>#yil+$H+y{dUze zyk`Z8TzxOF$UGY1)haJ<-?H{3kRwLKgOMZ3fq&C8a$M7g9NV5_IcDj2?*Qe98^`7L zQuc4Fkz-%{Xdi$a+wTRIRE}lmq56>{^uWuJSFWgE6c`<^%ksL+-2#XDhjNhPyo?-Y zfo`>n{yt}b&)$vwA*};-=((Ol(I2yPym^3f+*VPJVkqN++$*>DsYCwoySM}3&qS8% zE~<^}pZ4o)|BMSeIo;MFU{COs&CjxO_2a!5zH02yT@~7G<3;4o;d*TxwQ;|5^=76o z=C0 zw|lczKGAU-{`8uFE|VwXCr(WLA@kouyx12uKOXyE5J|FJ{D5S+$TQ5}L-|8La3{eS zm(Hhqq;X+~wBP)R0<;hF2Gt9FpWW!o;xV}bUptlTyn)%^?U32;h2+=4!nf&oZ@*KJ zr};BJTd%xH1_$A3)y+AzL@ z4j5F*KRt-|>yZt>UjB{>@U5Wurs3j`8vgcX+5csj3{%r^P>cN^xnFPRYG+aOD=7X| z6t1AKvrf(jEhQ$=(wBP`g*y@7sQ3s5{~}&3CVsUMKp)z93x%@#N%0LFUH0ya(3cD7 zp~YPKW)V`RgTfUAcQ)$$V;EB9eM3+VdU`1|dX^I1ptG-bU>%BBM0AP3%j;2pFQ^B9 zqMm(0J$5e1_)?BX=mkBXvp;$UQ+n7hVE;qE3wj5;fqWQGc4pQ&R*`<#xl+5oAIjlt zq?yo9e5PNJ&;1qRy?zxWzhCdB{*2G`3FZGnu+0N(ojbXK66mvav@(0F{!`dqUQe%p zf8m4AE&g{O1pTlVEU$6gOjoP>OJ*m)mp9OXEaP*TpFdyt6Su)Tpto!F9NI$F%eYPP zHb`jacWr+M@}U1{oD)309xaFZzd;%7-Bo%=j_u}w>5%o*2}H*v!k?wX_DLXrq@$jr z=-lN%=(?|ju0K>smncS-p3V;8&p_&LqH}mDU*w&g;uOJiVE)M12RT9hS$YyZcYQGO z`a}s|`h6^ad8Is{U*&51d}!ZG2pK{$gU@8;Wc!SE-p0nW*1?bx z*;T`LrqBgE+r9$(k5Qm<`X?yeeovuw5D`ls%55Zy&Hg1fh&&Q;|2+S(UrOw;Z-xDy z0nQ)cvwDHAHfWd05Amad_`cS0wi7x~kRKuw*1q@-d<$s+iF@`7zlUOVi}c4dc@6Mkz_)c8dN-3Zgyness6sig(%zNH>wbynqmBz9AAU{eVNoB; z{Vt{BCJ7P0KTPjqy$gIo3-d!{Jtd?QANd*? z53>3MJvtivQM+UP&i2!h{tD`eo(}0gF1d{o=rjF)HueAVAN|+=qUX5&XAV&R=;yfp zngj5^b|Cei&0=x27f6Wt13sI_H(i2WBQU~QH0&Uzbudl?Q~%fXKpdY!eA8^nU!2X! zG@tDuYUr(en)71Bf}SA^^$PQ1TQ`UPd=LCB$UHc)-!0oD>mkK0z((f ziAVYSfv+Gi#%Z?m^97E(*E2nKpRM?|wA^i!V)m?+&KcqJ>+`ouzesfb6#FOAQqH!* z*5~_M_u58ufxb`Bx>wvK^Z$6G%=`WCpV@xkMU1z+zx)fzYw5F;*E;vDbgT(hDtW#8I?>i0>-v|1j@A?p*tveimkKp^8`oOpNAn~2j2fld+ ziErfpROa7hAwHcSB+ZlP)Ghf>jT1Qx^>8ia57&Vw{!_-2dp}J0H?JqHr?9Y=!&drz zH+*6Fsgyq~-$VE?-@}j%KK_Ol!IR}vxZb!Rbl~^o@L`?-j2QPmlsPwm^+S|j^%T*q z?|j<4#MZ|`I;JSym;Vj-4u}ByY&|cWuRIy9GqrIxe@`H62k@aC^Ryk`qjsQvd{)2R z_sRO5Azj$#GC!F8AaYb}K8*H#jyRjFwtg@37uyf;euCb!59wn+Mg3*qx$tx3Kk@7q z@)CUhJYVMBQQOb9eW2tvX_uduDqo7~w*mjp>AYdsF4T|sZ|x84(`kaIFMEglJ0B_6 z+i;y@P;kG#uX_;_$c@5GvsV2tTdx5AXULEB=ad8bXOTSd_6t65PYVpP{Im1gHI?px zuax|#X93~E`F8Ljy^kd8P_}M?eE6QO0eM%HocKA`nm zfBr(xEqZ1vdhPu#BakHu<#^mnU^=SlnQccv$hK24&i+G!Gx^O!^?w}pb* zWVx(M8b9ZrFZs}piS#GhS5IMCDa6H*HNS~_Y4=aY& zUr5zGzmV8;qUcxLBlNZ}mwmy|zLOdA_l2S7=+fwiGw5DSo_7zaU!XDc**r1ZA59)8 zHy!tBG{5a@r%R`MYFYu`nb zZtb#mw2c+2S_chcxnTSSW$g_TZ~Omf|APC{_NV8Fr5(0@kyI#m70Jo!tF#ZelhT17 zd2Ib5?%K(E-%9tS@!5G6|4zD{-)P*%`E0!-w1d;3A6;CW^}0vv`ToO%uY0EStFGxB zhUHdhzHv0p#)TC^M~(;t9sc~lA}z1=H_j8dyNAQ1dA5XlUm!V6$|vVYzuYd%e598z zWxQzrrhfdmh;Ivr_3xJY4sd=UF02wd^nHCh2V&ODDo{~mlme@NB|-$Hu0{*3&L9_)u?-}U(k?Kx!W z0KHr2?1c4ez)z9?o64~|K8AV(y3n4y@?*?DsNacLef_BCon%jv+td!#K_R|kJqP?-a%a(>*uTUHiy0K++j^dcT2Im@ zaB`8-sqI}#M*BsSR6ADEf#-PobB30;b2D2te=?02OP}34T1xrr35NfKaE9Ws-#PdE zwsHSNDL;X>rN9r|qsM1<6LPzWS+T$A}C z^7nVn{7ZkQdI>*1v+tG8cf2;32SVTJKYu^Z_h++jdTxMzpO5j{xwWu;;0w-~>MG=LDJz@?NYhk%K9L5wB}@Ev2D}0L?4cL2^RqV zR{G2Kshirsb&@N|3-QV7MVvobF5}I3+W$okq$3RZv4raN^J-Nl@OvsbPRZ&u!jHl- z!B@9R;Ux;M;4rku>j_`D4}f{Q^_zuMc|Fy?RKwPs-lOy94u#%C-w*KPlAR~eaW;J4 zjnFxJ-;I995nxICz}L7-_NBBCjPD^81)or9T#?iKw3wU`HGzqm?ev$Boat57<-$D5!dNl~;?EbW!pJ>x{5bUoIDf}y$4+rZ>rf2m(1^h!s{(rfEN{n2*<(bpec$5FcRy^Ib~6KC_iRwy8S zSvo@g9}(a)yWAgr^fb>i@hVaP#mj%tKj352N^Lj&9ga(O-m!gk_4Bix#AlfCF@($7 zo7eX>D#`11(j&~1dEQTQMY+88k5GOu??-;NZyw$&?MvT&K;vFD`nH?$h5Cm6U5Wli zUT-A>f^;yGKJ>GR{m`50+YvmI?N82MCpwIe)%4ddQ~pYHUh}EG^*^*9kbi&lY#$&! zAMb;n1;xJU3Hbwl_D9dg5_%vd$={bf`w->tub;k;_Mv?Llx2#NacQsG<7<9N_FLaW z$kY59pPl=$bt>q=n`ynN8hpF3e^>>+ORL29Se5u%s>FAHmH4n9QcZi;Rf+GM5MRbG zPw!!hy~MbCApiKyf5Z4tdXI4+_b+w?_Z%SKhiE=w^X|Ay{EY0qll;)ZY-d}C%Katw z56EPs_bn!~{)FTHPSUe*-{zxaXFBx$Nv3?W!V`x9xHI#hdLouI+UI5=jl7IGIhrQ#_ zQPAIM6m#x6Ph++@yEp3f`Vi>hF|3EB^QmW}hpVd6L-7w=hoWt`AL{>tUVa+q!u@*T!LKu! zUjAS|$>9d!gY{z@@8hmL?Dr@7`;RtnuysejKCAj_`|6dS+Gn zYWLRkUJ~gizKCDDEY+K=ULHyNvi;f1KT-cPK11(;`u_!cIsXvrY5n?cT z93e*9xOOP@Zz1bnU-t4tGA}N$daxZ?MdOE^FT%Q1cHI66=0m!E9(T!lN%^=fD`ka?Mf1p z9De)j7hAW&`W#hV^1H6vfQJS-ctoIU8NFxa`KIg0wjOvW z^|zMw_t5#Bt66_VZwKUeLO=ZYF6(%q{IYg*EZI@JH*NZA>u})TYx>pKv8)Io{{Jg} z=Vxg|IF#f2Lw_wF-%Y=apLRbF`bhtIIhlS&PJSOcd*13`=0RT|dTib3P>knOs?x^; z`=4lc>VIPQsQ+>Pe?CEWwV!#>UtuTuI6oJ;|GWCR;1KKQt^Mk!__v{cLN2MCe!zD9 zQ0V1i*2_a@Cx1rkJJxu-0|GRp4!Xehf$t3@*ziD=|t#Ci< zS^EfDlIXQ=*R9QJKyHd%`D^mZ9TVeefgm`db~)n^CC?v zLAC5-B0gC+h4W|kH@C|&o=X;QFT!u5B!c@XvZ1^c}@z0_%ER zyhYj{Igvw1PnO@;vt3!iq$1s?z+KTBWD0 zOXzD?dfW8ggPlW5?00y&gwCWv=(2MQNyCZUkhU(Nv%TR|hHbup{z3myJ4GL`pG4%* zK99=3z}b0T2)gb5o7exkHQa8%)C9sKd?=qUi5$x3OS`#z$e(Mu9;qLC&GaqqDa+SO z`NDY)&QTu21IpwG5yY&OhA9rc|=_8qtxJ&v;aynH^pI^s1ok5q{B{^4a z^L5bq`H;?n%Idp=R<>Ri3B zOzty@p8o9lgLt1s?ONP5o6DEkbHA^k{DV;FOXqiTo+#wQBIsMNF0lgs^JcYIg+*MC z&GSO}zYFs3(~s_JT|)X%RxbccKa+aP`yPJ^T9ivtL|6 zPg6hp>@xiO2)~Vwp5On1`(T?{Pj{#u?&dH)!1>@%Pr=7fPrpWT&-&SR-Xrz1<-ASm zXQS7mzexRk`Pm)nXLn}&?9Ou?V_*@sFll>Wi|r@mCSeyrzd?L9C%ABz4` zPZ-f(UQ0iyX6G-qb1ig^Bq#n6(*HvJ($WF{iD2tT{r!&5^Qg)8J3iU|*3lsYmHAU0 zx*=lr$j+she%ZbL_zod3Sts@keknEEWzVsJ&dGnIagh>{Zug;@?gk|B2*ckMAThID zLumMbXYP|^KaP_6;tq!&tMBik z-0P{{jtxv4zQK>3L|I}f=4yqUKwkvE{r+$~OfvX)-t`=0 z(x`s-FkmCT+B@;Xr!XArx!Q%~A0lSPIUMb_&X>^ghxV|S=mVW+(Row52W9!K{l&bL zuN^O;-A7zX?K+F1FpuH$+{%Zo7iqrX5-z1~gB1@e=g)1QsrfER^VQRzI6sbX#@X}_ zeersc%Vzo;3K4gU-r0HYS`mXQ3S0P`IsU{sZ)%#GA>G#5@A_E2+L@F{pZz}2QmU8F zuTy?Bd4|$ei@}(_t%}Ef&tj{|-S{Ks%@r?}{NPVL{b}dp7t-H=XW$?D>^`QQw>LWk z{xIDtx8jA8ANlI(&xO=pgfp(7f9R_{U&5`%&v62KzSIl6lmc!a;pg^Ih|hip0_i34 z%yF_adD=PsV!gy8Klof!z3}%1j1Oo8eYMC$pS@=VeW(Xa?ZF3qt*6lR)!#$S=nwP^ z7JkMV^bdVojXtg4?lS;Cx0C4LcAhQyi;Bg`LVcT#D&gZusE#5PW zt)3t%N9AEhZGY70wQ@F&qdYAqv0s96*?WD!1OIFYrJ?;c|FHc~kM}f`CjC57LX4L) z=}*ij;W4A0GpHhek7uRiv-7muN&k?a={ZjPZgh#npW7C{JGouT^;hpy$`aN)<^c5~ zKkEI3)(gHLsNPuZTYLd!rmr;;`t0{xiyB{>mvr+Vnl2^A(8qojg|i4mOlwZ|)y?jW zuBS-)Yq|M=#roiKfE z8YTuW(e|3%GyY?K*!y~Np7aCX(GuJr8@f4-kH~|=*I)j9!TC1G{`{aZh;laW4I$wIpUG$L*_`Z>izM7kbR*sF58LlsETwjW zU$}SNN*{6~oI6d*jn;mR^t0$gEJ7=9`Ct#hQNv%W{0{9Up>P%tKGxC)de3lJ+SLkrJs*O&Nvqww@Ll>-lz9do7Io&q>S_>&3nYp z)%#gVv(CplrF_!7i_>w8A0?8-`xrKVZUWUmiQ;YivH3&j=V2WyoWJcQ7<4ZFWorM; zAMx#$X8QX@qpuTs&ZYXs(4Q!O2imz(;^Uh@ot(eNU&-n!>FnlW{Chf}%hrj^o}!+Y z9VDHT2sO%IIY2tmzA}DRLFcX10Ixsle;^uLPj@L=E$koP2)5Gw0Dlxu>^1BoBX&F{rF&2cFr&86M2J|7{aMF1% z*V7d5i4t1*Sm*2c9A-mAcZZ~he7KtUfcpa6Zc8WJ_`-I7F=)5p&*vng`7zn?3*!~= z!v6rPLHBhb-6K#7^~;vEY(GN#u$JUy`xr^%NU=xtVgQW)X2($vk>{Go$G`^|Uu(?} zjt}upfgW5e>7eIzbdM!2OcnfHQ#hpiYn&nO(t0OIetU0W2(t@K}9K!)9>=?#WVf zxGV*uO;6^IP4ff8<@&C@@nx3QYrnr4xtDWAA)i)d_=NjDarYXoEACpwVVHjzZSI`@l{3v3B|*Cmqw)d28?HXcw!TOi!@yeItEHML6S9$p^m%dSiYB@`e7%+)E^% z%_EaD1vY*absa2nGR|9k(^{bqFg~+;HqJDymESKx`@y-mTlBQ)3~QGd9|scb4_$M5ueG~_T|W*DAS8QsuzT^#GcIf3(>V@ugF>VS8d-k zpSy|ihx)Y$dVLQ^vps5IeO;pE7fHCOy#Cp$->>BS^ECf#4nzFYHQy_c&+l(d=X{ZS zi_oKX*6f$L&y)P7e@(V8zDf9Cc&wkA9-1C)rcT4{r4a4y7$f+S#!1pn z)BBqx9(3PBbkjR_oSx5(WCqqQOzGhHI^lyJnw;WI!nb^GkKkP*`D>AhKGV0_;R1I| z)=;Kxu2cJO=TwO|I}$m4kKe}S`H~*q_y0H0tNqLDOT1b56Y**j)!!!NY84NDml=e{ zT^zVh9S`FT(heJ+FfZ9p42-)~eri{2J*@L$v8S~D$@&wYDX`6BV$Gk`YfrE8)z%X+ zpP=UOITr9aa$U?%+P@V1-7?n9UHw&YDkvv=JLtvT@tR_DdA$_U$R)nA=6ts4-Oa<+rCn0H+E2a zlRDvZoEfi@<)V-9)4&(A3&zLG+v}Myua6DlC;5Gv2H}&?j?> z70;Ox#={kl^4)&lK2f>bdV!5Uc3(76deZYQg2&ePy}sxw{G=y$Mp#z)f&$R8ez%@^W=@F%o) zlc=o8V<~lm7bE{&f|pc>zs{8sn*WOWxPNtt-pp;#{93MarSzxG6isA3gYE)5mc?5( ze&~Db##i63RDUA(S>_k`LMrdhrI3>Rx~A=mEG2$Zl3y1N<0+|PJm{OD?FjRuC6(eK z&r0$2LHuSS0_}&t8?FzTzYG5ebei8g`V0c-!#YmMdeJb6pR0ChDHTFHY~80;)6Jhl zI**eY4?9z`UKGTK{@9B&9{hveL0>`tjbo+$?SzN^^Ya7m@1KuY$}a)UcOQKkf1=*L z)&YAmzk7riSfQ_|Zz0tS`t5g-N1qAoBxj-vcEo;v)%{=So9sfli`@(28*|6K8Q&Q9L* z11x8MANg+SSBc8O`i*I1D%tloYC*s+0}m8J3Y3pW#dy>e+BdC!+ZiC`t4bm?-!)M znw__C74)$FwMqWl!EE|Wf6Y#se$`Hpbojj_YG?DC&@aO|Qfmk3K+DW8wQw&2^*5>D+%b9{Y49{)xpC|4RImC5oQ{?mtrno=ft>XZvdAxAx^n zFQDJ6Li-~(ip$kr%7L4!b{EeRLLRn{6$gG9_>SBN&Hplg4&yTLdi$j1EZzHiI&TjB zy)k5nfEV`2)}!Z6LX5ocR$`B=y{d=a9%=mCd0foBXo-YNDFDAr-^?$XMf3uN{qCO8 zWA|)qTn~Q_@iuB-+$J3kb_3<@J$H})RTN2|y{~EYncsna2@K&r8s-zWUX1?u;oqd^ zBJCW*EYb%Ul=d5-J?Z#Z_WRGXINAB%101ig*|ARE1}%Btg8jYoG@t4N=$QBm;*Z*e z^d5_i=VlLO+_Z7k?5e%1*s(?Yt@tLzUyu;|+d=JSzu^h$b8OY={O7&kYT7<~=Pd3R zx{u?b4D_|1CiZX^WoN#Okl%l`@xad4db#L$ZSsi6Py^|MUBF+Vo!mu!493yv8UJ?t zZ%O`z-Q=xfywG+Pb}20O)6Q+0Jqz(p(e}Red!_Q93cV^!;qjt1C-)4)cM$P=9_Ghk zUb2nq2j4zVX{a`TM-Oo^$3(9{nw{6F#E;)o|1-U_cG$hrv>%r0o8dbc zecMg)t)y>1BDqk1()OFa?N<1}`nE>pdtyf4*0R2>Vg6OpH}EUex7oxm=*5DJzV$*c zF`1w*)HlmNw-0^$3h~#<0dLnM1JgIu3w^VCF78*~L~mlRZ=ye`zKI^iUf)EYY`rgO zUa$JLR`pHz)}Ou^-#e?+x9;ac-zKVD0{hSlxvIRt_ot|zo1D$RMtsW?(of(L40!yR zuJ!78({Z-K7fA?vjsCZt{*Tb!y9bP~<8}$nkDW!s9p@XI=Y)LjWDf1Tfc4LOlw-fk z{2=&g`!n|Y8nWL-IHmOYa%9jbtLFpC9oM6oD4zA6%E7*Z4jP6zG(Ot9#>jWd6Et4x z`EU%w$lt2JE81E^jum~F7unZBf0*5{-^a<<$h}0+2mY6h?-Qi7jbowx+5`EXC+VQ) z7V<5h_4uv7w`%K^VSPKOKGZXq+U>{h+oXZUUwg+aY&Rrm>-@-v64~)OnX`oZTk+M} z-YFWYUv1|`On)&hjiW4~9{;`vFD?k)d`>2ual7IzNC-T;saS>VK?J3Jxuv~ui)?6%VE;^E`jYHK{I}JkmRB7XeTZ2kbHXY)z0PHIj*Ed>ap=R zdrSJC2{$xB~>8D{79-{Gu>F%X^H%a^RZUJWu@u6#`dMFI(*z_HyFO+x47vTNk zPoVF;(yqcD3A>d)gJc~n?%pTuY+fPh8z{!7d=8RBR2HlgRJ9TLvjDWR@I*?f4^nb3atNi?9*H;X{Tm|e7a zT2@~64z;aoL~JdHj>%$plNQy#$wFV!vWn}EbsZsTQF(ZJMIN1XBKOWlX>Zc}U8VbB zDX;f(le(WMEcMtvRe$o@O7aT%zh3Rfmwyd8$^_KzX&XLUZ}In)3d&Ev@1=a!^+nvX zX8kWPJ9&QudSm_x1qN^`EoRvq~fAs#Y*()0d8-yPG4l)ffCF8(M zf~~yykI9_lgukzna+s$;FKm6$)>Y7+OM7AGbl>?7%}?VM+e7ouu9JA=e?8}ydr@e| zt3UId&m(ov{?ji^^u8&^!Pz^m=|p_p`hR{pX!HaK1{MCcM{6NyYNaBg< z&s(zK44rzgxQwUo<-` zul=Y{ukGy-`gA|o&clUtvVR@4a~|m4AOvB3UC78VV#VU*dO^J$)H2$i}~EK zTre)o*82Br{WBHbr|@)z_bNP9;a(0y`g)b`7m)skdfq`bMee`K@`GOMUq&zZ4-0AU za=@OUhntrt`Bh7-YE3P-S1}D=6&&oI|bJHU%XM?`AFtWk#cn_Bz=y? zw`l%m!PDL-_(MHo`rA;u@VAb~6|rk}ex{PY1^*}9cfy*Jz0YO8N6^;sDaM=Hb6JR{ zbp)ofHFq5MYg;#IRe6^4$KB&%aL_sv%#Y7l_~cD~xNhPGI*9{keQS zN9^~d^j@a7m$q+a=cI%7gWqBO_f!2gZiMSW4*Asnhx6rYj-qv-9%dWwFX8t=&0jS8 z8Rowd`3ssqm#*7=i`rLdUSM*&kqnmk+ew|uMSnjdX;is%&r`muTs8>5?HpWEcfF)H zUZeT0kg(-V9HO7lfAro=A97kLbVD9z(7Q0{x)!Wy={S51!KU|-llQ~Q`=R(lW)J#X zM}!^4csVgMpZoyzH`~`r*AaWAU3L37wEI1fLmf4+X)OIgpY4xy9Dfp;&G*UCl5#pF ze`vpNr+n7FP@el#U+*S)njR%BGF}w1c}1W7-i)ooh2@v;7niH*Z%H{(5dX$dIotoSbD*KVKtICumLr}- zzh2MujJit%5IKD}YUNs{2l|B1-@_P6zw<+|oe#D1BPKuFSBabmGUV4dDi=AiM`8SU zj{i2(5yroi;!Q4*dj~-z=QBBQ@flGSO#EAf@u-J|;X$Dg9T(l1Sq<8JAn_Kt*= z$NnHV;_v+o7yO7P7Et_Nrq||qn`>xahd$7c{YKT7LiH$} z(C2fghFJN~F-Gv`YsPZDDPJYNHMfiT(qDbEGxhDH`cMx{TX{WSWPEnM+S8-@pVA}e zEF<0(l<^64=W9Nr;r=_D=}G&q*vq(Qp3trR%isU2(67c(ziPGLGb=E=x&JK7^q-$l zeXZ^{f_J6l>o~ri|H$X${!M6ip^uUK7UvJ!gMJDA|86h(qu49Jj^qJ(Ltj#PkC5^< zZcDfEzXxf4IPB?QDrfs3z;_(COYDig2b8CA9$$Gq5+BkJjjc4!v)$J9EgR>v^Tdvh z9b8X7_dH(r0)4PhX3wy$^;y7Ya5na@{{ATBVDwsf={M!{5<>bydKVFF{lMr7)32iR z$jLrSJoC7HD4!f9;dc5PT`f6kB*(`y)n7PD!njrag*keTVk1h+x&g{refB%3{v3wM z>qO38VxK2Mzs{3*$ZI_zYSZw1K))$2LT;){EPE?XZ0 zzHd>va2%dQ?YH&4d~OosP3QA^9>CA%UP4c~ z9mCAQ&Y{q{wCH)4^tUE@ixFS=jtEE4KlSu~`rRXzYq~#lztGtw{Sk@@{D@ z^50AOljZ9NtA{crO z&V=g&(?I{TULO#?Rnq4j%BMW*kI2RNAL~2Y;rakZQj0&(`oKa$S5NtuYM37+{y=`v z^SI}eI@(e&-n#kd46pd^|AMhPDpbAH8n`UFxUVyRXpSe(4STu{Q+t znx2_oYV>8#Y0x@9+aIH^xS5Ec59h*pJkjwF{J45g1wZ5_$sg_~{ToH4eo>zFBJ7_$ zt_F6Y2)=g-9<;aA<@K&%K`^^Tl*L>1Dp8V7zK8x^@n>m2=t~~xAKQpCkjp|k z3={H~$9Emi!hG|QuOIoosFHkDPN96K1@cY(OlUjVFVlwtgC*nW^>mIc9j9c!CG0OU zj$(Ek`dRzM{ttLue^AE_8ISY1dY~=YPdP5wPl3H#66`mFul4l)TC4uPcsj06=kfjW zVX`n5@-y@o&5s8E$5Fk&cP9AX!({M&4)?E>0^2+b`PTA!o%BmTu4q1_zlQl(*$zc+ z2e&)q>zk;GO7p^cicjs$$GKdh^Cj$K^ZBniGEXT6^QVdQeyG_Kyf1;R2hf!dz6t$;wJaS6?jSgACkdLq zzU*TgghgL|Fn*l`;juh^<_9;h|Ijvxlj*$WXolmnWn7HUA_mYmYA{NX&v*$&L+TIX zG+xj9Tz-k9+c}zWoSi}W{W|n`Dc2g+FdgxD9nYiRJp&BpPsW-L^I^2CX{NLYcN3E4W!x{UUG}>KVZH0M zUCmEWyVPFV{z6i>NbFEgkKic?eli98dm`Y+StvJO;^R$gB>$GRW%*ZVJx!D!`U_3B z^H=CcpPeN(7?^B*K3TVi@g$3POQ`QEr2g|xjt4$yOnCmL)DPdr`C@;rY`?-0Oa9KgnDD9JAY?t9=#4D;8=)>34peU?e(_v^4;v z5q|TFE9Kvs$&V4w>_Vmd-I@Ft;nDu*{f77$@D2Oerk|;tML$#d%6vWi9qA>(K7#GH zLGOEGsz^WErw_+v@GDuqkM%Y5Gg)8Sq#)=V{STs3?Sbh7;%AY(it{9&>1o?of%Aig ziJS(VAoDDuXXK2qA4|t*yXu1)9%Kg-SOB{n9k&klQ@jWihq%uA^klbEB)Jt}>XNin2Tb4<`EePEhH|L?8&To+aHIyIy3p)=sUVyHO=SSDA zWqir%H5{TGG~~eNMr9ngaVL9TrJQg389(An`6l+DoNr?95MRo-UTJ@qwx2rn3bcQN z!X)Niz-b5u{IPQr<#g}ie26dAyWKwiVEgMl&|N`}j}V>lmU)cd?yrRXd?w1>By^))KS2JT znUa6=Y!1WxQz?JkCGAE2Z&QBA85Ym_AKG`qoN$~KeX#T4*1wa*qF2c}(X&)vL?3{s zR9}_|U3%^!)t9Lp|G%Lx+z&GS-S(l;-_4I+NPMz!?STE9j9!U;tXBOXmX_$px?SAv zkz`y;?9%d`93RT9uYUesq6>V7T{3=x?+=vBSGF;}R6c8^-ZJ^D;rMhOBK9CIhkWP_L`)pD%tq<##ftm)C`C-e}`0&CfW#y;=4b%jpt6BECc( zbvu|Y#FxmUPWXiQ5_!}KA3}Ld%Jf(G!RSv5h;Dm_k^D}k&-97zcS$=6(qCbR>wzb* z!0ThG+p?d==tYV&u4NvGob+V?*&0y=_C3t zzC0-s^fl7`p`z($6?*m#v`h6XpOble`hJMW+s36-AH>ck&8jb|r*tn#^hC#PI&ZCd zBXW)0lWfQ79vjEodkr*y;P%DSxH%5%iJLD<{b_3t+W$}57qsmW#Wj|Ji%bplciT+w$^br2J-~4*S?^ao#EL zH}3v^>3SseIqp)u?38lAzahXMZ;|$;`<-L^r4!|+UQP7`{R;2Lq;h`&mrwV#^<0!c zKc{l`_u{swpg zP4*{I=zlk(c@@Wp?b=7@xOyO3UYS zvav|>NR}VXbN>!}ao13R8+QrZ?F4S#$uO-KaQ$|#ZouW&NqKr#kntpqioZ_k4cpKB zXaiMZmtIc&#r%$H+TDqEZ^*V=`cLF8V7y7o9@_1!j*nOMi|-|hZ+F%B=Jt#448^yr zYJ9Ez;uFP8T6R{A?=}768>RH^s2bn2e(}lqp`>M7)%ecs7vGUeUr*KenkwSM=z)GW zz<$zV{X~9OB57G)kq&zAm*dgTAKQiZF{GURj#gUlW10T>!%Y8tP+-;fq~)v9U$tNP zerEm7({~r!t&YO)r9alKJs_R$BRc6_0M2jrD4!F4r}Xw=Pc~?OZ&7>FtoEQq@I~(5 zm>ybRVmjz|?>&ExC0`-+yH97iWbHuQwa4fGR0%(=-^=~@1GhKDlT>W4;d?^q6}=7V zJ-UQmvA0=z!}H)jzN*v??Wgg8?t2R#yk4lEwL#;jjbuL1x~0hfJQ)}0-5P<_%>P2lPxC-dr}uOAfpVHJC@lAf=pL`adT*$JT(tK|;^FaQqrm3B+I{8l zeYDGnjyBIh>DTi4M%Znih7T)GGAII42l@Rano z7M07!KM6cX0#XZMmn5%6P=`V$jr{!a6BmTQZb;Ft1hZ-aT`qZP|PQdYm{kH{1Du=w3d{NK&|kGs=+->HbdzD#~u z{GY6dU&hA}|5qyFmkCZe|D-(VKZ44o_EG(9|50Z=B8e;|()84Dqu(u46HgKOuG%xCUaJv(VW5$e&~z(1Y0MNSSThw1et>6e!Ei>VnsdH50NiHu)%Zk^Ug zl;5T&(-kh)lS!&4-yuAQUr(keU8X0K6fW13eFxB!S7!92KBFfuU_F`0_~Q-r9ES2L z)st;rzm6`^6I%y2KmE|@Ns`f%8%p%xdDPP?jZ-O|6R(6Gn4J*=7ayi^Alq+k-3a=B z>ErMN{s{6*{2Uo4RX+p!K8f<7+&^fADU{DpUN4sX?7wNgzfeB!$E#fr%N!c<$PiNPW$Z~#^W^K8o^f>s<8OGVYz*D;V!hFPkwnI{a*0Vdu5sNLiz)pzvlYW z@k81%@bP26;*s@Q(rbk$alK)CX0sfmo~#~1?w_FF{|fW>a{DDe(zk5K__0^`wxO59 zFn_6C5Wf@U?jZiBeIfeO=yc?-^M z#9h0%y=c!mq;KYAzK6J;@Yw!Mc#iBn89Yk@{?j>pk8e#TANWY~N8z)M-{{Bls7loT zZ`6-5{(v-kZ>n6*+5G`6cY~HAkjkwpE4LQw$GZLz+Kp?eT*wdDqmWYZMb=?<}JJhsh2nM+yFr z|4jGYLO1eV_#^6?L0#(v-Z47WGR zIia{)=0{2M8pZP|4*h%68$TlOoE1{e=zJFQ@hcxAxdiU=YXj%g6AmbInSp*`cH8&GrNxx)$3g%%?5&pjQN$^JQ(;|;P+LdU(s??sR z9w+;;d7F$Mnh))Idw=?_^AhCSTNQnUe(9@*@4p~AL%uJ1R(x+bAm1OTs$KH_KmDGK zv@fGi{qg+)w5Pyir0a2k9eEt}>%7hHZ*{31p?4ba#a(Jg8nC2c8GM=UDDcWwoZzA?L-Cq>@8~go5vA?!om$az;J>WXm zZ&**l_k(%->*8qsovc4$T)sru$3tUg>B_T#Rs zKLBj#Z(BK}{v!B#8034Zd!Rr1&VJk=@$p#IS0Uf!l^>ncv>fq;iai5=88z5`M7&w_ z)cj-cx%dOfXQ$Zzf|jR3JPrkR{`vjb!`4AfT+rU{wBP-xW?V)4K*#eRC;eI}^#lG0 z(Ph8uW9xafCrP>=SJ$9*mBv+xuk^ku>{~hyxs%JM{@8Zrf82ef+EKHsxe~kDnf1?_ z|Hgh=T#)=po#c-Tg3soakz3C7W%VWWi=U=;_dVWIr=TyTSLr)|{}?&iJfjcx4gCf8 zn)hVx4<7Mb>G#l^kUsPSmdAQJ7o)#>WcD@uouo(ikh}u<{hs`}$jzhLO5=Z<@$;m= z>|p&vJ=3nB_WAWm8OLlKwEHylzJ|y{?>(gJpF2f>ehBuF(7xXLNk6y9xl}v<+M1if6<1S!56WlG<)gpg zv-9vti>#+tgYUt9@o7J4DPNcGt9|$Pi%<4*k``G%t%kn;?iZifzobRhXRE=tts*|% zpFPNP^yzsxJ(phXJ%)99UcK6T2tmJl6ZO0Iu++(}w8*-0S^EROe$4{1V}U-Fp1)Rq z-Txkmo}(O33QJ!yN6$s8Uq-(#$@|0cI3XZu$(+BQW9RPm{I#CTkKE77>@3b9(>k=Q zi#P7)agx`!NTtzV{)cJ`+qHuF5%~|CKg_q6^5usf$@{7FJ43tfW* z|GtcW@QPkqHlS%#SXeLgo#t^|FX;L+`Tb<)*sjrfo`l^Z&-@^>yQ&YyuMK)W z-SbQN)2MpTVtkW)p}e@i1@b?I{OtUo z2u10ACJuPL_bv2i$9V$7j$&ZQ*Br(C?CX8+kY6|-3_hKj8NYU^9sCi`TQ`ecZkF>q zn5PfjB7GV)lRvW$VTgAgmACh|;Af!e&;yi0eP8~ejK6OsIPRLq@`}e0KwoQ(jvobq z;lCK2NAkEOcFyXJ{XUPJHwx*19+KXc(Z_PioI8rU)gHfF>II!&qu-OabMCFV*R#J6 z;t%yLJde{!@32|9bUpV%MqFNA>P3Ca@2hk^`xRy7u#X?EALq#LjSIq;bU$pS^jGb- z^!p?V@8kX((lJ%#y`R>Np?`AT!Li&S@6z)Q`=uZGeI@A!6am$+sH1M9m@7Q@b7B;{%=9#2fe}myxAe7U-Bv9)5a-`Ki)8j z!!SSVh0Zr=e#7Y~cNWRB!{7TknJY-|bA3katiKQUF@gPkxJ?54`%nMLF!?py-t_)c z)(+py^&GBy5RtpG%rdh@Abmui{Dd z{j5yBU4eXQ9m@0nh1q;$=aV|s_b#Ci_GKP%4E3K(98UemiDm7=z7zeP7}LY!la@O{ z%YpGp-Mq4LOSqiqd06fkDi`tt<7LRNQ|?2*mhm^W2hFIaq}(dzx3w#6|FN0&@8Eor z9(SdDKQfbVFUuw6ca%vVN%lYPO4I2lLrUa|{y_WH(qB{_X!jbT8+`sPjZok-KD#F# z@&W6w#)pt!zo2qqKH*o|j+GVph1nXF(|H)`U-mt!_bB04h>!bm;8#6K`DlMq?Mv1V zIF<3zyhZwBUw%NN_D{Q4mhl53C;nMm*QdCDw>Pek@w@vY4AcBW;0+rDZjtdm-uMB5 z=g4?}(D%sNxEU;$V;(7$BkU&l^-K0gYFMx7cQ=_Hy8kb9i95vWGr*KI2)>Z7OVnTZ zD&e7b^?m<*74g^BVPYMJY`xO=!$y%)Q@tpR>CG$x5!0Hxm@5qHlkqjJ=fnNVQSe6Y ztNpgm^s&G8{TH_{wg1oWN6$ik^SxEk_lbV#gTI8YKl<*?@c+a^!hdnV`s066Rr};V zWncPL4gZ%@`?7S{x_oFP`p?67{AI3c8UXGw~PwYa=Y_SV!Z{zc1y+6@@Z0~YIUv0nY9$Ei#@>a9Kqj=+)Z46n2+svm(YoK0BwEdBVQu zbIB7qA)R+N%e*tdk9jBRA<>k`33LG8TgVTj-yfB6qE6@Es)znwzkf$X=ill#(mfHj z^OfG4#`p*Pr+p`+cOKIl>fa)YiQIUOPyJ7w_j~_S>-GMp&ihwO|DfLq75eSoz51d3 z>Bsr3A2Ye$GWp!Z(LC-fYe&D-eyHzI(0-x#ef}Pd^3C6aQTqKo7^VM}g12nl!sxbk z_;rh4l=W9ooc7l#LjM-QJA@{q;Jf(~aaZ}e#&>B#9kv(qP_skq&yb=(ZVzPgvEC|Q z!g=AgU_P1pfijm4>&fap=CR>^qRodN{X;mh^LnSYm^^;0z5xkr#JrseE&41hknQ>8Nc+;`2SDkPNm%sn#KOac%={~1UoqCyq$?x^tgRCqHxhWE8m z;er43U7e2M-8L#b*frvB$MCMpg$KW5%=}lmDh4C)w`NR;y>p?NVz8WuYlf+-@7W|_M^5%a2 zd7Pg3`n(S|Y@oicwp3^TE1}=*^gRQQ2jGMMVKb@s z-CX$4kJk3k7v|58zQT4gix<{~TH8S{xZQVi+ktOk9q=u0>f!uZ?d6}o%YGUBN0JBO zLtg#e{|P_tcT&F~a$)|O_v3iSdoh?K&-)r@irwq4s5~`K&DhD4QLd>x4IPhiFXSoN zKWlK1KM!L#x-VeR;OIJj3cj$MMt_dG6^i@HHRHe4I!A@j%Rf)yH^VcwJ`RIb7!*)3ZY|^Uh19Z1Z;%&pTOt z#QWm|^|uP$ONBQJ-#nh{Nlwf!WISK+Lzy2_azg9xQl@zh_v;(9+-e_rzdOTu4#Qa} z-O+rzR_jBr!{K#O_IOyH=ZSlfmt#MI_Vo+iEPv_qXXitX7SEMySO;ACUWAr`m(hpT z543;Kll>jG%r5;3JarPzSyp;5)7<`f_ zn*J`#iBv8Imy4d5JkBYvka*71aX3Rqp{t`KzgOw|UqSVmpWLCzr|qNQ`GfB>eP8zg z%@-FIw5x z_B8R$=d0h(IJ7>=i<^AzO>p>k@Iw5-bmbqN2MIiNe(a$$yZC3{$0mLV z9SnP;c;xAc`kaPdL;e=HRXDLqzo_X z^_m&*Bf2NP- zx-QTAVCN& z>3db-(7h=4E=N24E=AO<_iI|e3OM~0!1wgd%A4(jyywShy*IwxmdVGMe4cn8&oieB zp%b}*Kj8ag_~sXIJ^oRiSmtjov%GjeV6D?nva3>$;zJD`%}C`_otiJ6oS0+d-B`FK4rfPT?HDrE`^0U-g3G zdf}I+3)9!;OU7e5$*ISCxr6Wh!{h0@mmUu2i~hVFKQ2>mRmP6Lk)N+rx)5oFE*X2` z?fF!)=e}Re3+UI^dquV$jUyW;vYp^5jK}?_@3EbjFZAi5{aoxp`F>2^b|rc9_f0-e zBf8T$i_*TYaRv0EGFPr)6Z=Y|>THw;FO)0gQBWQ_ALZVea_xT#_36}%KG`__p3x^8 z$6M%rpRNxi_OeZ0P3<7lZ{fRqTx^FLpMxFyba9foq#;+lg{j`L~zN!k4N_Hj*B z1gEd@nD~!$4w78M=AY$i>jdH8qbO^hJsd)QIqF@Db{)oz#o!?6&+7-%&HJIplYE;# zvOLzk=pd?>FBj{r$EDzUkL5 zGI*Lko-6hP>$M)fG$g^yft~KL}`FqgoEFQEkOXQCAxn_JfeD8qX)X|RPc>d1fr+Fl;=i$6b?ZuSu`1O8r zsOT4ek9C0*g`WFLJ&ZT31OL4I^O*{F&lKGK1Q7e*_Cx-8subzm1<~*RipouMjg+IR z%FW;nDA!bOhOR-m7jl#2pAF6ykrO(i&p_W| zd;F=4J-z^CwQo`FTq)BzGoVk!?6&G#Y#)9h_zu)pO1)A6^5OBHL6{`_8$iccJ|KQU zc%Go!q6a?CSWEjplkq`Nih-UVIe_*o=QW~(<-a_gv-G-&>V*xAi{3{S{OSEdjAI<^ zZ>aBK(D~a+AEif4?NLSPVRBJ3I-y=M_=?acsz9EivX0;UHi{GZ7fr_1<4fr;@o%mr zxuEl^#4hpp4&m_uz2F5OM?3Z(m?8(aea{#A<>AB5BycYol^#a#pN%@6y!Q`n9GB$y zb)LUhcGUlOM(v;TdAkxFm`*?XL0ZoYkMjtRR)4GA`3}RUNUH70V%q^`&y{DU_u{&$o8%f6na()9ra4 z;$Kms4fZEC1K+ybmV8D#c=zVQgB_yv62XtoiGW@-Y#yGCvg%Q!`y*(7l+;iByfL<) zhxYWo82YWK9WJ9^Pfr<7AI8UYo&Uqc&x>lCIv)QGJbvXv@;w>r7jX=o>!JAAxOH6W z-x@z`{82fBzxu7k0Q=@547^5{9nS$Pi|kXz>GBe$|219?dNEPPYxFuX$f2pI?{gCk%43?x*~`m=LC)#Sh`95f4$G4*b3Z@F-6wWjZ%O z^;z}Y>`iRH&K5lB{RyepUzslRaw0d=P#!e7L0nGnPpI4=elG^d!+UypepnvX$03*g zHO-&#v~Pjl4-)$NdP_3(zz4_)^KT;2F`*kAk*Aw(quJ-X?`6Mt4`IYu=rJcVPR?)S z(c^to&+K0uk2pEnnds=_vBk7MC^>%z`#!xt>-U3reCMkl|Iv(pKVA2iETsGPof%J$ z*HAm(|2*mcf1wW!&$R?+puU!N@zVRVh38>kc-Ee19LMr7nd&jW-y-8zJ!a>Keje}3 zNsqYRd#K-%K;<|BcCDwttNC=F){$9rEYIQF%Y5tNe)DJUUX#dKPvNZsCmb^WMDbDo zzXe`Xs>`}7_?p=NlOOT+@p)p$i@{-lulrTPF~a5iDgT%b(^K&6Ja3I_2NmxlP`@QF zI|25kH7^UkMddq$f6-3g#I^c8Tq{43>(=OCb|D;sU1fZ~pNlUT-B<4tyH+Z^To7)7 zuk#PXIh^8g%h!YrT8=ht1WnV`e|&c+u>q`8PT*#&P0{rT@fkKHc-}^QAwp zw-Md3@0Zy)ZT;b?^5eW-i(d2z8X{N!A$Belz4my~vCf3o`{n*<=g6?VXFk3Ca?)Ry zzuqGGYxRG$KcBz;F6HxmzWE{Yhl{~1*q4C>zm0UiH7@E$y<<^t1Zv>EOEn&Hdl8 z#d$gPr*!;@e`R(A?UVRN>z85gJK_5iw~fYki+=zwFaB#c{y&cj*W#bnIISJLM@EHb z@ek&g?6~QC0MR4X|Jp5idED0chw%s-;5WBBD%H;7pSy&A+nQJHG#{E5{|KFQ{_*db zOrrCSTl3Vd@ejtQ^w<0$k8@&f`_}je>jDXV{_(Z6Uj+E@uft|iZ|7Y2t?>`qD?c56 z+vm1#jek6ScwF_93BO_0TXHkf>nksWelD0OSNcv0;+uukkbZRTD$3`KE@D|Jo*fj<2<^?M{yn<@ljs<V*Lto>gjP0)f=d< z7yEHc0sEjhZ^EhPV(?syzYhBt$45@iUP5%X{3g@ySKsvU5!M;JKf^Peoww)jM|9uT z0sJ^^{p084ANl(;)!+H4_)Q1E4{?42uTOcrejs>Ze?w`<_VJ3)-@!5e<8ZdmI^WrQ z{^1bjBYKZj=FPmgLg2Z01$;>C_17u!oY*sqSFo&u{y z;|O7U5bg$h5l)1i2urXJar{EnNMwRJJ3)S;vc@aDh*zS;4~kqx)!)d~^Dmb!L$HS| zN3W)R@(EoG?~)+a0>_O*=-Y(dXE^U9eQt#Ve`Pc{Y(M<|`f2aYgELO>Y4wX&h&(>o zb;-`>Pt((<$Nw75J}vz|+oz91|4tBc1omEie7+&Xi1&$${kMEZYdnDY!t-Sv`6<5t z8Jb7A>sI#b){B2){&J7LuN~Dek3@?xzjOlcR)&{(AHP)4d2_7i_33-+#Q^g@>9NKG z!d)9~Z*%zit;clIcK{vp;`pZ@R9<2y!A_S~&xU&O;22h10~g-_FW<>Pa1UH-!J z&-*Pm|0&JKSv=osyx{9yPxX@T$3vfa{@>XKxN?ebKnQr_dz=5DuCBf!yZJ z{{qj=|AOa2$PdfQ*J=N=$#J*>dQqbH*moEFx}~D`lXwOW8>kl{jYs2nlhmX4-@qSk zOuwui`S&I~9^PNL!QqpvpF!>oKRfrpzRO-JbW4BR`h9n%!^vmz{EGZQ((fdJ8_%yu zuh4i8k^6SuOnfd$i(OSaR#m&J^F?I#)y~g}&*RuAa-N)nWpcj?b~~1PgLkjgr|&M~ z`Ow`c_b!$4ww{A!_OTccVd(c{^>|zH@OJaF-y{8UcF)eYc#p&<$H@He<&^W5QOqyw zr;7c8DKadVC!7fXux*}jQj7n%I^!3xzs7QO2jwxs704UeK7^hEVF^cJ7a!KO4pS?4Yl< z&o0vaP02ovF}9zV&ih3bg|B+*=T#X`pO8=dfn!KM6F&lRZkFF+1AJpS`Q=S)Z_r<2 zZ;*e@wzGM~=b^q!`^}Q}mM?=n=#S6qQhT81b%le-i$pcezYJktVAPBJOMh9%->dg) zTE7Z7{T0A32H3Zs#nbYD9?x4-cv>9QnlD=<>;1_(+7(|-&mT;0I?qz%G;AjIzL*Pt zPhm_ee#)2g624uT+aB*HWZN4bn14t05`HcZv6k_R`Kf+;oVQW?9Ot`WpTjucrTmEV zUEqhE`x?t(6?P$!^J_KEGrrGO|H$}03+0&aGf|HDj(DgTtVR6f?5pQTUcT$HKc@LJ zh2wYK2jl&pi!=4W$0YwyCORf`%jUbD9=eUD$M?{S7{wrJksr_lc<0gM{X9-54;&|2 z{>Svf)8(ujx_G=ca{RAy8V;)54?%ue{tgg7DQiFAc(H%U8TY)rT{}Dc$m)a-J%uA= z{Na$zL)w3iUnlUI&?kNmnaAzz+`M0TJ5|P0NCPu5Po8sn&M8~)xe z?Mscr>=@o#O3qV3-fW=0QS4Nyu$|;F*?;8UoHFi@W>-$4JfZpd_8x?-Yxj)XL*R_I z4$FGT@^KYSMm`S3IxHNYy!VLqx|`~|IQ3A;tJpkj^C0Y!odciD!y7P9$Ma0uP9^)a z0VkfHo7PVG9Q(&+{}hhp`^|6GbL+gmh#b24xQF!E(|Nh(ZT6>e`TMh#Ui-*+cgXi6 zVa`dP{sKGc==3~l7sm&2J?z(S?{7{K`DmYq>cVqpkF#;1@p%sG?Fx$nLElckvtjMu z!|gM9ti<0u0Pu7OhyS$y#mp^>h`>#6BW#o^}ofW>Z zefi{#dGT`VIxo|W-dl>>U65*Le(N(6=f>|XX2xZHoz1sAzJA%a1bQa^d8^-w@u|Ex zzw+(5?OWG*Iln~jf5r59?VV}A3h*J{VKb?BTrT`pzZdP5pANrca@)7A^KyHm57Xu0 z8EHQ!onOrQy{jPivEQqD5c|D4|Hpo>>cLje^}ka6UXz<`%M0eM^Ll>d`FT_SH_abD zpUdRi`**L%)bnz}bi9q|X!Crju#4E)WS#fvp_`vCg|ANk&m#S&_qzlSZ}+xFj~8af z$$7mzdh9~=lJAw{do?E(uzr`!H=Gs4c{%b2{WFLDw{_WKaDv?Sdz4LfayQ-%Ovla==ZAxerd;@>tB@oaDMSkBa?{ zi66XqtMfnWm0$lHK0OcaIH5^7>?X%X>5a>3sD=zbEnM^TobB zefj0zwD`HxiIT!JNa8*7Gc`_o7W1x4@9};s@`71@`+UUVH{|7ATm4q%gXJ69uKh=)#V)uWwHtiPyKIA)e^TQU|50u5P z)o(?6<)<6p=G^wJek-^4e(NVsO#7|RPQKRsR+F1;&DXZRpXK?H=eIuihctiKzcBgs ze(U|2dR|Ug4^AaI{yXJsCzAdbgLjD{c)i~mJw|w(ZS%E|YfqP3a_HjiYC2!5azB); zQw%)p^PuK$!Lj6gEwB8HC0~0O+izWO=qVg5<4^Ln+JBDUDth7k)@;7^u7^CH&vd?a zZ;Ye9ZTNe?`|8vu|C zpOu#<;gj^hdwWa)|4vN3r|o=rU``Dfta=_`D2 zPm^x~75R^wx9ay~^SZwyhqM*$I7U~_p=A;!=Z^mS zhf96uXu#WSjdkXtVML(}>;(15&#B6UCQ4NN({n zJCo}4Foc(ueSrNSH4{=8kz&n^|-C;RD3g>%Ukk=`vp975-c z3thA0qw~~p-{~#m;qknU@pSW~ACJ$kbW?vkt{bU7$5Fh3RSZ5%{}LXPC(6~n+Y!d+ ziEfep!}vVW%_xJ6^ggWlor{ET^gb-EwYj)fKzGj%;ai_{C;0s3+eBBTALI9bME>ST zg;shfokpR@vtA$@M$n6I*1KBVM^I2KbKIQ^Bvdj1k{yN~i4v4?>83 zPX!*Y9U~sER6Lk2_T3QrzLUr|eYa;b<25qG|K`zG?T_jK({(2TWbs?PZ|rcir|&@j zL*O7R4f=a`mU%Xu)h!iLa>DPMEkrwpJMlW6UuQqgcX|rPik}lLo+P5?DD1KAqzPH2O zysuX06^8fY+ljt)sV3)zF#gfvY0}>4;NzxEx&6OI0EB(hfJb>M`rid`Cz7yj`efoq zale0BMdMltJd^XdFu_J=bfbOWbij3R#(yde=MjRFv_D?zXUAjqllwh~s*GF-ymp{) zeJ+ic=3(J)snCP|`fT3O^A1j-hV-NJ?y>*7U+2fFo(FfTJf^$>-rutG%_BWGCDQW- zBRyxZ7#t}L`WhEXzx@^Mr+L1VqpJ2Z_#u?_eb{j59F%*}PrrUAE$Y?#HLYI-oc;>n zr{+19&jH}e^q9!=oRf!-QyzrrGMlQHUE_N9x%|kpg|~e-p%~!2-2@Nh6T_H(@b|-* ze#pNh^h5lxt@JZIm@b>YMe?I^TnzBugO7if5gqNjHO1hU;(xSzp5>G8=OOOrO6Wx~ z_@=<|`CHLzsb5h(u>}L7(feEAcrL4*p@ff8#TEBz7TesD0FNCwdM;?&-)Y3&r41(qAGM&#Yc~ zeqHP2BH`Oc!7uES3&sCGl|Q2L6rqpj=P>*A4b#sVk0e86vj}`F%lNRHL7Vzlq?7S7JUgIpg|w ze4YDA^ViP5h{}3j&moD*6EI%K{|y8;s%-f?_s8&VW_Sy^#BeuAeTq92|BYH6-vVcy zzzO6&!}%h^(fG)|R~fEc-_mZiwA&o_ze2{dTI$g{ja;Jxbbfl#bipgSOy|3gbxS#{ zgPzfg;1`5-&^vljmp%u+(Tk>N8RLmwG)c>#OY|blKSs~!MKlolF`t+}(Tn(B?DI=~ z?^696uJ;_SXYa?Bkq?UI>H8=vrnHQIn8xqrjo0^?evgw3(m5%h!{BgBJMni;5p)8- z-|T0!UON!`P4AWpVIA}(c@#Q_b?|ARJ|Oejobm&RZ=75(9v-g;G|r?Uikv*g`@o!D zeECkoSM5e(FW!&-<9U6m*w3&JbdAbgS_WN7AGM5ek>0@GI=q&)q1TU@Uc<{luN6yk z>BV&2oUEC(9H6%&x@Wkvtm@7!Ln>=p0f0wR|^nhgG=m)*JnN6%MOBE|hA5=i1Eot(LQ& z)|e{vV7%63o{Jo+zbx|@f#P~s{T6yM>h~i*hJL-Bn@jviB(QOxj7%tt8YPha4yQVH%NJF{-@U`rkkI) ze)LT$t3PA&mZyu^g;ne~)^+^EcAl@8-b?9zQL;*)J8A?0hiZ1-fp0fM=lx~U?u(-T zeqR5iYgY{L9l~%>_2P((pME4E!1c{fKT7r4{Pd&camRkT$5Xxs*+6@qkC|>f-c>{| z`VNFV2%GaoKK#BIk@E#;XZpkKKKTunr|D9k_yv1Yhu%kJ(oH zug(yDvK<$>(enU29ENY_3YxtqITX9XWu}jP4}$rh{=O#se!f4Z?`vk|q9JGore9tz z-v8sYAG(O=U*#Xm<+v}BJ~ftzK85u~a^?Fptdx9hPxJ^^V!jD=y*eD8iFT?Vp?zob zO2vnqDbeFTlo{?rJdZm3m%Dx}Z^HF{y@C24Rybsin9i10ws?x`Wxp%8J~Q9_oZ-0m zP4qf1ext4!-nSn~(~IX%!^_W)U(eK=&-k4Jd@b+ezq5IP=m+dm-gh=l?uIh*X!heD z6c-hPe~F!cHomjjPOtv9j>cVAK9L;TI4*26jt6NRef1z?H{U1#23Ek2rSmJ{=f>+8 zOJV0H6NBhS`le-_r)(aWERX3q=uGDVWZ+=`Y8b;=m4P#?WrMREC^1HQ+@kQnLY8m5?%J0`Q=o6JctYwTdDt}JP7-v+zRLdA=RQ{xvG0v#`Q7LD~ z8#WUE_!D>VJPtb|7Sg_o%*L zKVpAH*T0&(3xA@ju73^gjB*X@U*XX9DEDH0w9|Z7F}O|oi$?k0rs?w=K9RPA!(=~7 z5`8jVW{JG{^U7aE{)V^fZx(xSo%HAL*XTaaJG+wzTRhjlE9BYp!~D^AQvIyoO6L*- zZXN9?%n>`z_VIM8@8Ouf7iGTun9yxR*AL?Ti*PrC@U$)g*u#!L{k*@*er{1#F$wR! z8S=cRfSk3j$7>al!W%h4s)^nH3E`EOf2|N+w!RUS*9l#t+Ir~oTj2*r<<(jaHZw%p zCyVka-CRuNai*&O`q;JX?@SeWHG3YOGBvk;R9PkPn0|k8?d-g>zQ*war@t}@denTA zl%wiIln0MSxi$giq1T|?J6_8DW#AF@>iwG5uL4eg1@L|R!sD>{l<|5U*>T#>DR>qG z{obzT?>)b{T~ryCdN$8-`@3a-2=GY!VSEQYTD%%lT=A1U99!Cj(vi5zVPy<<7rgmNrL8&QtsXoHluRgS_s_*)EadP?vp215de z_Avp^U4&c#)AhrPVH5Zc%iTpOy8aaQ$Js5G*RTP3<@zsvE6G;_@YrAO=I5%%t>0r+ zecYcK(l6>&ecV_5j;iY8et<{s>4`p4zE$;en(A@4>M!)87<>wNw$TIAFTbuZ_cv+1 z;JmN-!M@%csz={30^M@#{$tdR>9FK0ULGlsqo0>AUKcPsTa?)(-Tx%^cU>Iuk+nSE zbSdAa;M$xd*U~u9FKl*8IjU}u`6V2jigInel%opTS>BMo8?5zF&+|?CU%*&H4zB!0 zdS05O`H>Gup5au$shGb4{~_EBe2n95#}BcO8YeKl#;r<^U+mV!=zk(jXOmX$h=Stt zg3LZGi$jMwPgKWz5clikb&BQ-PEPTsb-sKR^-~PKE#vB|UnuMHr2=M9wogTQ{yf3S z^YuM)e+RiA)-lhWRv`T8&Ik3%?O7u1yh-1lQzG;o9FZ@}OBE?PquV5R`S5xQe|v)A zg?;9)FM)j4^~%l)KgTv9f}?t`@*C4j?SQ>+6ZKBmEbWFcf0KSnc_Iyd;&BN-qF$Tl zF~4W$Guto0e7@y+9*50i#{w_S--mJD4DuMpc{7#!IB%x%f3!5GyczT$whNVZc3~a* zn>9(UrSZ#9j_J}~uUTFh|2|qjp!^u@O&R_>t%qnC{(D$gdsK!#*m!B(1AJU4-KP8= zli!D~;qPHBmI^I&)OM^7SD&BIpYdAvAjf@1S6k=&+^BH4-Kyg}KS)67R}ApIQ{O+^ z1BweFS8DIsE>5HR3}^i&(%+TRJmBx-@&0pL$F=;2um3HsU)TE7t=I$AcVF*oRBxa@ zL+D#7U_4%5J}LNKE_C(%i~UmjV)GNjov!%an(3eMHNVu`eXD;%W_+{RJ}Z20r`Paz z*oJjnZ(k+zP2$HLCIraxo5wdNlQ(2O@cnh< zFDG`_?ByhZ6P}I$rL?1nMe2P|rei{H=rhCnc!rKCexEI1MUKzsdMtFY#~p7X&;`1^H_4XE49azvXdX{&k{j#xC&vL)ys6c_b&a{v!P+{<+Q{v45`f zN9>>L{1N--m_MGpe}13hu|~$-Us)vAuz7>hVLr-(*PyKXe#4l%-7TOet!k?Rd@;+ zEc(%T5U@l0NHGZag}#OR5hLgq?vHw*KA%&DeU2(8i9$xbeYn<6$F+)ebn{>O%h(U* z`7C<25dAT~Uok@cwDotN3p}1;f43NX9emiDA6o~WoVQ`UXM7)ceR}?*v^eFPkf<^F z_W7pY-a+-%UU2&-$iFTIpBDM?ba|Nk>~PmTq(j?39`3q}mXSXTcZDxt-*X6e0iSK3 zMR@uwsbAW$SFWMaX5PA`O?bma+X+NZtBR%(+ z_Cunq=grW5NR)fwM-+n>3!(hHb|&2^2EC#${yuxo#o)x2`^)IQ#l6JTa0mFTxE?*~16F12f*J?C@M?+5J#xK5t@ z`!wutFQOW(pKtm#!EttTCdsGCrLT7k)jN&!VG_0bpk7Pk_mO@|;}6C>Hh!wC`2W{?E4p-^TGSB3QhBqxsdA^(EcEnfG3b><3;bpdTocCC3^_y>@e zV(<-_XOr*j%@qEP{d=SEC&SZ)d_if)SA&jqlsSG7`Dj3XnT~&YGttq_SCVgu_35S3 zFj}Va-i9AMpLP*!hW8G(1FpYmydHQl`uFu_P`z-4@>}_3`}i$hV0g!+=ni~5{OowH zta*EIXv_FTj@)>!A$?)IW>HP<@AZtA$&VYy=QQqmt>ANn!1aC+d;CQ?WtQ5<`%0FG zf0Vqhy9nj@eO=uzv5$bGIC!r5Q`ny#Rae8$s=+U%btEYlg9R;q*(C%bY(Vd$T>-Bc zTqO0f^z!@`{%Ag$$KUlcZ^trvG61;Yu9%1DJq3Xu?n({m7gaWE8TOOnN0gyvM4!o0 z&(rNwbSH~<7GK7zKzSPTLlQkv`ZhIB6n~Ff^F+FTB#ghy3;K5YJxWg}Z&w+g|0a7@ z3|=YY3F|*pz9~KG-_f$tqy9B5D?RGBYgzq%wb$Va*snbKJ5$$@cDv2nA)ZxR*ZGP8 z1Sjd``llJ_irqO9&sE*w^DX>D#-)4o11C(OVSfs4|lBks3U~_%I)f!9PV_ zIPb~+Xa9bv$8@|{vr^5&Kz{P5ud@BV5A#!wpU?FvzbW=QOfEU%wZq9}tRA%8?or!DB=u`)uZRF1M();1RemE^3Tip8uzTPjWURZ~G=IwKN ziSEyN;ubFloE>ZRPiP;v@FVe4*(#**kUX*4Tc+>t$nR;NZwDQp>itOGUhGcx!p|Sw zI^KuH4}7c8o$Lj!w(lalAIb4W?4-`WJiY;1fAH`{kJYc>`E_b$KhlROZua##PtR~( z$n#}pzm2aqjqDKD`&NoiI`8mgroUIwwHSO$#zXtq#ZGg6gsT(--c3gQ(EUFnmao}W zZl}g^j`sH%(v8GEyhkeb)vpnMv_$jD_H>8gv&0mGGvvAV-?)Y8ufNanLov8f@C@si zmrf%jC(-?6|I?`gKkVbXJnunoONCRV9KZiEihMJ_m~MY~fa$Ax81KhXeJq$lk}2m-B7 zwX|csjQ6eRJjHfm8r5Vt@5tB_?0Z-(`fmF;eEkzM^)Wuw_x1jp>J8NAioGipcr}Lc zy$JTNyh-ATu>Nr^>pEq9ftGcDVm;LIdem3_^7LhVc^us-c|A<~%a#JWO{l@p9Zo!uh#q$%X9=Gq=ZoJ$Go7xZ6n?!d$s8>5rZO@k@4^rB0e`#oN zi^0Cq-s{K7bf*}=KDF16GetjqyCG>;6TR~HzaaOIX}Q0Q?$bGGGR|UfE|t8WHx>FB z`*~d`$9~=vlw&_{l9W63^X$Azk0@w|U90 z@BiU;)(6yM`5hyd7rcx0eYVgu8Sk}%Xgn{&-3gL;2mRW7z;c}0?^?z_ zSCiNHT(FG%_xIG4?-IA7lSh_3?brH`(txy8oGtw~E1!#m;8s z#pYk{k4~qqnC_Q8l$L+YAI2ZZ2ise#|36%xY&HLQUjy^W_TyQc!*DOl@DuX3R^}zk z!*IQeGxZ>ECYOlsxZWqZUK@YTkE@ID;`;M4T%x2 z-RJ&MWrx5JJ!FEXDkZ=~}$)46vPzIgra;d)MgSRP{foriu#F461z zab@_2yp!n&d!Ep7Z>hlg$*OJfO|nmNuIRzDx8D)*7ULh?ksi14dqNw2zgzMoGX;M? zzhXbk8+2T2#NKWD{=@C0z1trnaL2l@CD|YI>+UJoEN|?>wM9`ycSh-zG%+E^D5>GI&V?R@j0xS z_9IH4aBFZD15Q*0UQtE+DWiW+CmENEqxWX{?i2LM&v=>q(FvX3#&j6W(t#A3e#JoP zTnl7;oxnSGRCqfI+^DuiIdN+ViX}jkNUFiLB$W>*kTl&dOtgDMX-mAkTzr>62!)#rM?v7I+a@9O|w z9eC1tY+42%qH?#E!Drg9j((S+-)J%V^YfL+-vU9K*O#O|`zJi5iM{sY24plC$PNg`!r9ZUHTmj zu)SS^{dh8V=|P6yVwd)o@sC;F)h>6 z{WA7!fEkg zk~}NQ6ya+~AhFuLOLry5qBX%d8 z+^x@-YI&-bmuR_5%Zs!;Ma%QGJW0!QwQTX}Y%NdM=fhf_q2*Oto~h;4Qa*k1G%3GF z^DS&w$(5q~&RTiSWiq9d|Jf9mnbT&E!#ecK;_JjNo88`ueIAtV1KuYg^McvyKHN8Z z&GLJC59{Ab!K1zZh;^Y>{}Jm)USD~Ciua3ne*pJ0mF4jw_>VMBthWv$4h-XcUTUxB zVLd#&Oy9%3yw#6v*U!tipTRWTQei(CIORRWFNpVlG<1K6o(oOy_2GGZJ~YOHkU5r44?; z=g3cu*W>jZkVyC0Mf0$)riH%?0f+m2j6~hjLE`^-|0z0ry7!^^{yiTUzb`Ufo`bx0 zy#LzeOXgBu!|2HVlIP>rERHc%_1U*YerlUpwE?+mFZgH62ItX6q9sr={my1v^ON zoi)DEcivzxCgXXjK(dm=q%MwSZu%6w<`$Lvip*h|{`{7r@KM7nNk@1gnU zuTDJ&e#ySeEh0C`{^ZRl58A#<%&*D5%Z>7UTlZa>onX4}OLFe{$$aDc9G99r6@xEG ze>{IP<>r*P2;DqCMQ)UT+^ zU)SV>`{_QP2l8VKz>`u5-h!RDS{LbNh8P&SG$$jL+Zy8jqg_%kti@ zeD!o<`6WAyc5tJD_&l!{0zRFy_ILiP)!$em_dUF+8GmEZ-@%6p+4yipx6J3X?@+FB zp6ZNA0w=rxenq$ldfy4$y&3Lc8g8io#3>&J|Dill)*r*hbd)O-P;O2`xjJ6TQ4M(6 zcaq24ejeIKRp1j<6n@V4poC6+pl>ly|MraWLWgMa1YBzqJErfyt|U4PXX&8pJ7cB8 z;<1e*tb>0nhu424@n1UO->(_(4FAF_0gvZn{uP4*QQ@hbuWjlW-dA$r>AW&l{>OTN?`TG~jk$QxdWPI*zF&I`(b4%w z-DC$$&vVY(g8uDK4e3Yc`JlWn@Qtdfp9mA^TpiU<)uX7_^j7sO#`n{(V|4*5e!_T~ z2WWqd;Aws$?Z=Ao-f3f+|4YeU(K>UgK98@MsmJ;oHlUyU{4nzWlJR0*3{i6qT}{-PurDK1(5%q57Wc)N3?Dok8=jq;`!nP|#ghVu@*Y|SA1R+JWro9)rhIM;C-r@ZGVC7h<5Ik4 zDx6tbo*`wAr_ghdu^=3`r?{Huzl%|h*ISEtZ)o(+@u`$T#c{;TJ8*o56?INujP+~AbNFQM~NgsyZhCiJ8ECMnZ88Ono4qg+$FF!UOf zdoeybFGb6Gzozx8fJ5hE%5zT#8K0ZCetJ9c&Do8ODt}j#Us(+HZ?P+&5A2_RpKw+# zogPAaveEqGefVAvnJ%?eX}tq{o&R0jdU7uOodj-H-~4#i=y*PLgWqqtv$XU6JxiqJ zOA@~5`$sWfHmMvMUpAr~^JRmSi^1J8?g9P24xd}cKi}U(DwDiJzce3G3|hZ4os}!L z)An9G)9++D--yl~6Fw*MiSur3UliXb6F}oTo6$(k`!g7x>Mg_j_APn#YlhkZ*cn=P zm9nSvG^O)bslCP37H`o0B-p3QETNBY_d(h>O!-u~pV+$@Qf{?()8&4&c&c0zyVn)B zhn>TBzqozc&P~#G({()4v^-7A-CBnIoKyZF%JKK7*K3&wML#-kSIat&mDg%n9@F#H zQugCzelnepA7MI!Z$0|mkg%!qX4~(&AP-FMMT&eyIp2fe{XR_pGL4=4xr6vI0`!9Y z={qbe2ljmzi?6s|<3`LkjJfUC*_+_-@8E^_gXcm1(YYbQ&#;MWkDhCkeBWh};CJx& z|B?DWz7zdlAh+Z9y}17(eMipIX_ojI@W1$ZA@f}HVj*J>2@Yfvzp3dh@3mTRx_RpfEUA^{S?q8@4F^rrN@aWdfcOa$)Ck; z_1pW(%}1piRgt#}2XX#c6ram;Kc4HkJpEndpXF;9gl}>3Mo8&(jN0pXoBIPO{wS7CoeSM6P_Fx=YE~=|rda z+}V{|V7FC2>HMe`y<_^CU(E21B{}tY^S(usWA8V-IddK`=!^bry@KIQ%hX$%vGYgs z^OZ^$GND2j%}d(&y}f@q*?Z4d%p2&}*E=XvkL`=ayXMFG{h^QEB>O{!K6d`S@5kir zxg&%x@q&LmkC=SUB)U_)A?<0Oqg?xS|9jZHOUhAoxm@X7N0e(zQ67T-7WFQX@>8i# z@5tzrjpL6QeX?;JL-+gYOGT~|dx?aqAGh#H?I82{%%gbz)I3EQ@d};OD}E}iHz2;L zYhKdwlySaBaGm?OT$5i@`hP+Sj;2#zW`O z$Te)@y(`N1qC7Y#SNh%t%0pM6+&fpU#lYfhj4OGMN%NTTdr+Fs)c2qgJF`Lf%4G_P zX#IV?lt-gyf&4S0AL+e}BW$YQKMuY|sNaE)^GJhA-#Cw?{HUN^RI_{%>J@{k@&|T| z@X}hqI>}e@pZ$@0>^Y*vXJY#l)+ka2|i7x5S!#BCxLeKqulhaE? zuhd^yAYvi&`ZuUP#XDl(26j169+V375-R<&aD4vmKVQ#u1wHt@B&k0v7g>*Bd<<`& zH?sBF`p?qv+3uz66!DnHdj-`q{`Z$Jd`$YOYd=(n$LI0-D#feq`Tb&P_+L1P|jo-;dhVzku%B`6RSo zM(AgLE4^2ZxHo4VSL~(vsdGT5a1eP9?r-@!c>YoSj^7iyMet%d;&m;{A0+$gzYe@1 z{=rDHjwO1WvyRoG-&-Ch`E`EDB9dpu=X>PK()ky#JM}HnPfvj!(9i2vyY}DY_QUD+ zr2^&=%HOEn*&upB>&GZp)}!1Uk8*XLl%vJyzbM&J){`-|pNIBQ75GFIgZ;>a`8|Az48~m{SyQE(Ve^SSI&da5j(f=nh zZn75wFRD%K817lA@f*Ac6rS=M%OMm;Ovr^x`|9LA>(@WmFg;O^_Ql2b|8||vTT&oP zKaM->cP{-Ash$^uYg+83$gjo?=I3&Me6DR@%s+b%@o)j_^?4oHMZ=%lT|%$!`R5Fu z&LI$dXeGDCMZU5q2zI|5Evn*T2-xQ6Kz^YHH`y9>w;_>{YC{X9&Oh z8oP^L^jEZ>=FZTQSkJacxu*RLJqCU2ML)@VLI!7*^3&i9qdaJEmZKcQSt{lJvg&cK z!mnxlD&X{20KXW#4RY%IES58yZ^>>5Jc-{()|vk2+@GfZ(l&n9S($oks2-j3g?X_K z`f{A+<(A>UnBt=3Jcd?12{$hahkNfK2U#T!o@b&iQBXp-2V7~Bh<}yDtufXu` zr1+Wk0YOd>zEOFul~H#$U#(n9m<1{gQ#}6l+B({e1>*adyalQ{~6z6Fe2>+ z>fh9UL4Q9k8OPZem!BtoNBFneORV2!+lLLgPR4yJ-8^o~*s=+)jN) z=;rfZ?d;SlA{~$WfuE-BR2Ri1J|47s_hssN`ZJs@M|iuT@qO&)J}i7p{Hyy>j_t<1 zD93i=ZYdY(^l;{ISlX(N}1$9+R=Q8c6GotJ*7BFpR3^X%c%1>DT;jRFj zw|{a5**R{XJ+JV)WQXZ}8MQw~j~QB4du4v*0wHh8A7j6S$2W8v!5QV8!fD!n_ME~I z>3@2r|7rRCTVA#fJa}HU{x6mO2@(3`jen~4pFOAWtI~gWs(){17(V5_@Vu(@I8?fc z&nYa8<6SdbKcCRgYagQe#bBJsA=B@}gulhv{jq;NQJ%;ARX%umoUZw?`K!F&eyz0g z{e4*a`-|wq$P~twuWB=NdFFJu2mCvtm!F1?KY7O(4m zlp6MNbOM)h2cz&6`)(*7-Z4GTO3~Bs`=Qzg=r4WGMd0ndE9BAU5q=M$i*8xm)d~Le zP5GFAJ%x4JkI}a~AMcCNuir29`{BOzR~AkM-v>SCd_$zWK-Y zo%M#kyDiVj4#)L|9o!_YZjJY|@E7O8hg^I3SLDKPjrV~cBc;(gE|+3%|UN*wR2{>1UV+Q~THS39ZpEYT;yH2;ch} zc<-gZqWv_FR(orD`WlpL+RxBoDEFctle+}YCgrEW*@*I>!P$Uv3}?NR`^#zvdKG?6 z>sJA%zXCjq!5al{zpl%2VDEv14bacW`yaS3P5<@0{;mA+^#-`!N|jG?lmAThBAsvA z$u0ADPl|(|OuV1ggBd~(hWq)Gyu4YwKV9vm@+-Ep%CC67RDQ*FwlldHZT|ZLEsS_N zOr(9OjOST2{$hZ0&id-$-&o>(j30W+@MeFX{Z{B5?dOBM)Vt+cDr_eVqV-@YC(lhU zHNF{qa(Yw@FhBV5!rp*CUd~n#MvV7?89AFp@dWMr0R9cMV|las`%-<%58%1lbsHDM zJK{_1_u)I?^gglVol1p8GJcO2_ha(R?W)r5OKR7ZehS~WTcq*M!BpSolb-k-JZ-0b zX}tg3&e_|YI-*~=i{&LX&Z}wsSJk+%@)Ge&89x0->(j`CWXJ9GuABUFzYl97mo+}% z@%@nivHyGQP2XF?IE>qJ;2Y?Bw$cyZpRxK(Sp_REfBZ&zFFL+I^>hFI5w8E9?Z5gR z+V2?Of9~veU&r?!`re0LPv_*zeNU%V&R%f;zg|M)9$F2)4X%=_uP^q$!4MIz%w_y_ zU5?v-o#cBUo;Tkr^#wE%$&BZo?tM=#FC}{t%SSAKDrXhonS2)m{aSn+pZBcoDBstD*As9fl{Ev~XSOZ^T{cNupdV*@$(!OdxTWjjy|-Xr*${}#60&%93P z997oiTHXLYWY1+>00khqz<3v^{FkR_8TioqAW9Fwq4#52^n5wn1t&)=@65OUCCsN` zsZaX?zPYZ-Rc^Ns1i?LK=8w}ZU)6kaEYY<=9_f+xKviL0K&N=icwOJSNlqb+W$QG>Jj9g=3OcK{+WKZ&n2Fha`w6KelbsX z;k)g7F@JvhWM26i&FX#i_0nGwuT2L39KU%SjQ179``+XuK?#{L^$=u^HaKgQ(q3cBCAKO26FmoJ7-?=y-Y!1BdE^H;dMos==J zvL2`RXTu)z{q+9q4MGRs&kX4Y^5)lhL_XX+A#%Gw&=5QI(yx)dtfS2KX9?LKuTM98 zmgJ|g6n3G$M6N7X)Llx>Zlw4u-k&{;_$gF52nS(@eLsws#U~8!Ql1x_zqXv=Uj)27 zKH2ZOD}7-f&Q8X434IsG_qQZt$CvPPHy?Pq*gWIy`G+^8>4bR!4CFM+;PXUjDlyb$HuER=`N zN4a;VT%SsPT6t5N{x*)+wHe2!X&jUr6g(1pxr;E=^HKQZ`20cg4~V{^U*?~NP3TQ& z+@8`tY(oE{s^ulrPpoNtq2FmSe?6+HKON_RasE_a19^u2$`<%{&D}x2>SmM&cSgCk z3FV>fQSRL+o`bi@3e_e-0OY zpACI)!vFO1iRitv7aQmX>u(qFkL?*}ifo<9`*AO)=bn$|uO3DBi@{xzU+~XOzNcr} znH)VT?bay$F<;PmVp1O21LI?Sy68`SpKUx{8PDqNga;Ss=lf$j!ru$Zes^Qx^(0?c z!mfrZTJ7#y(Qow2@IS=$>uUuM%9{hfDO04sXyPPX=YlcOENVbM#*@Z8xR>hLI9T2{Q$Msn8~vYz z{#(~AC;o$#OA@kN!N#O8y=jC+L{x#fQ+m#A07DP#| z1P<++5q%-~Lbk6(`^A5uGuPGf{^B?W_a`&k4Zc}*h|2i4>okB;W7viym zuG=Pe+`nPRj3J{X_G&x&80HOMbY0Aap zH@j+fHnum|e@yRXNqiYCm+Y^)f#=f&DD!;JZ@w}AzVo9r{ikrfg{}40 zQ9arRD}1$eBj4X#Zr9ZQ7{2R|`?-nyVfMe$>pRngu6#eezSAAwPp|Jxjqj(|ce>=h zm!t7+9NhoapCtT;CJ24Q!SQnS^|Sib#q@LQJBvxq2Vy-zT#(4&zoh>}4*!aBEQh~G zIhMm;NqK8>==mr3^?|-To=rCpes!fc(U0j*=N!^se4glaGQK(G%P`*hBDu!%ZhgL% zRc`BZwG6psf0(*R`S)MBE#2Q`)L;8`C)KaA$@2!qL;V}o3)W}P;`+V-mhZj>YqCbW|n`r9kjy%vL zv{QO>y|-n)f3t-2oA%oSp9cIOu9y8T(nhJ*rS*V6*E==?Z@uKPrfNO-7hLb?OuhM( zf3o>A)b)6-_g|TMtk3bjg2r@#%k`>UFDq9nKlc8l&qE!Mv6mY~o-l4-Z=X!P2{fLt zfpPnKduHl&OFfL+*PEEBH(TmWlX3WZyJhMvmwKR|ulM|HJ&9*kKF)(ca6ZlA!h7iZ zX!aeap29nG=WV9v6PY{;&qI9wNV;$9Eu-nvCe^3;8GV`|`m|ZbOZ%)~PwShs4Et~M zQmFeGyd0bUTy;fSzE>0fOfSrDDisb80)&I0N3w3Cen7l$OZ|X&-xA=A#!9p2dKYuJrTzBz{P&PoO8u;VP=fcBKyJmp9LCP`zB5(aT>7-8W|Ra>JPQ@|C2QiT;5B#o&MP z{n}CFX--Bycz*EytjW>)GWAT3?j?Hl)!!uZb8;U0EGe76M(HXZJ6TNeV=v(K zZ(t8Uo{@j{CyK#4G=A!qaoYGiotKjwu>QPN=xp-!eQD?Q;=?r3VxaqfonNpuJGNhr zJjMGq)-~3ZrgOB}R^DlM3M2PSw2nVElT6aZ$iPr;|vh*FR&HN-HLd()AJhqW6V$99$EeS zx&BHSmV7^9Ir(Fj-wzw}WBxx(=jVGon4ZSB(D~gDaJ{<1Bc{Ob#(e1WEB9sViJuI4 z^Zqn{x6Z?3KGD8P!7FcF_s-1t*-!T4?ovA4o~Z{v8F+esb#wP&>Z#CIT zFMp;7D{1Qz<^2W!DE=P$YAwS~`tgE(IDenxW0CWm{VcPYAEZ0{3mf2f*aV%}pXPNQ zmX9;(9D~;H9#^ED@7Lz{Pl#QB9E>(E4C}nGE;BD|miDVM;~h?o*X-tK^TLt5jv41c z4itQoJc#o~*L9(&SM!H8m_87lTXWemlFs@-|uQ`4ZuG$c^b2$73z_ ze7TIU){?OCb(zHj{ETlevUuq5`So4Di5!t_+>iP zW4i92u{W?2(0gz1tp46y-_5&XFBV9*WG|rK4EF%Gw{7PG@R957ld;P(zm@^V+xb1Y z9_5z!$LqBspE`egJ3lc4kLg7F@I`L?c)AD<_g~D8pY8m`(oNv)a*(M9I}bd4y?_27 zJ#Vs|w{iG-f6dfe+Q!a5x|ro{x!So6BG+Mksg~ilc)11rwr=OA=h}JD$=mraUBh-B zb|hI}f#2r)HG6PRCf+ywFN-~!FZlO0&V*gk{lQ`LR4LQOYsE_0v#A=;n*FP4qXP2%PK(nAtHOo}UYEyuhRU z_}J)JGdkLNWHUO(bUqrM?<0>n4pcgUF0_9JW!=XY zRg9l2TJW4eco?17?$02QOqW+??EY%f_pkvv`Fe+D>S5d}x1R=n46j7z3HQb0we_D9 zq(YW%Ue6xoew%>Da0ZBut#IC)568u|yIscfgUO}!|AtZ9g~KZM=V2Tp=iu5NkJq%o zTT1xbJk9NvP&{JmMl?T)d>H-1;pI~H^sx5~KThq~ALSX1zSk{$J2VrZ=Zhf+ zCfBqcDe}PWS%NGM zkIZFyIKKSy<3x|4`2s&2oZB*ffv0|smxHg791O(#wEbmf=MI5>#Ph{VQI6+}y-<$r z%nPMV=iK0GcHicK*d8vDf%G*VlY0FX)zjvm(a!XA@KKaaPlp~xxfgm$eu0+teogCF z0f*uod0q@&F7zL$KPcrn<&VkL)6?r4%h!k2<>|+%g16_}BG&uGY9AZQpY2E#D`MxpPX8!ShNs$lD19-d_EKmEluye5QCV#x1yfG8MznS7h9}h^}aFKME`cB63 zwN%gHA$cUFo45O)<$5k2V87S)6^9Mbf%*0su2)At=5NtDD)b@8&p+?`nej1P)hqA6 zpPQ-I&GpVkKfYd=smJd{o4sfJX0x8wXA3@2d06ejEG;jWvd5q4VR^^V@;GZ*o|Jz! z|C*lr_Y7V^=Tr36*NXfn{{3Du5Z^D$1LJ#aCV$QR=lh>0f4ViUKSdQL^8F7;-27!3e_!K%xzc+_at)jJ%GJJ09S+`&a%~vThwehTcez|Ueow;L z1(92a=SMSm8r{on=zdlvj$!-5<9fS{>p{rRfuKWj{?f3>*OQ4)u3k!V`y}F%Cb$3p zKzwo>@#|8MH?{9X?5E?i#dYWNxSzuKWL_>jGT`)kCgYRS8IRa+u=A4DU$%4cV!vS` z^rxwQMLfT2yzvagCzla#%#Sns$a?e3E1%l<S1U1*^Lt^l*`LpePj()m`yIq5J8-=Y;*;&T-WcMO zKdjG;kMUdxynWp9NTy!9_~e(FdfE8o{*UoI`Rv6fUm%{0B|f>4^2MH>7N6`y_y3*a zljnRXjkm=ozaamz82tOhC;$7!G@cfpT+oK@Kh4B57N2}W#-;HI+<{~r1>2WW{`5NX zFGdc9oR1uZE8D$KyqomF>En9wuhxlw*;7EpXqm2;&BHpH*K^4unw~p7nn_(S`~|EZ zPLFxtn&lZR|Hyi0^`neF$@?fSFJSdPkg2zb*BwuxPU*++_{bXWe}L;byR?Mr^{sg9 zA6&1r!=7@2J>?Pq$z|Km(pR6aWvu57)I%*}y>cKvr(XAWTsc+Xjkq}UKpJzBr^mj& zfxao+O;9QvEmzKSjz5`+=eo^9&b43Vc*5wjyR@VCQh-NU$JH=AbzJ)XK7F4L;~F%)w{2XuKF#>Nm&Qfk zc@{kUzP=0SPBHkV;)i^&<;#vCx#98f`-6O?bE>7@Km+k%&vxIE^8STyN?x>w5_w#& zr-1t=SJARrkgvMRSEF0x%-*k{@36{vqYC6cswh3|y;3@yk2?xi>VDW|Yf)aI`(fv; zM!7yk;XjIrHhVqj+AOCHj-({ce*A^nDD$ z?-+v1bmr%LEe0k7zGLgz;WpzZVMWWU^m zs}eiR{r{Eh2<>yzaYDcScx0Yz3@aUhXSnZp>39EeyA<{yO!=Gz`>|++&E=@SFYa8PFyTYt5v|cFVOY-J3q#QP9;;QefGTawYT<-hj z^OLRL=nTc{6wra|fAn^GUPsyVH9m*$O3aI9-?{!rGWFS>*gWd}jxGYp_0Rk+;p5iM`lU2ITv-dHdBFzmMt5 za4u&*SLZ>d1N#XF@9{c;V|LE;qO?P|+%N6$Ut)j!d_rLf;j8kvt5ge&{@l;)8Gm{< z`AvL(CgElIS`Tj#fhY!lk$kzozg+JBQSQ@wN-}=>&aGVOJGXMBc@*WrH7M7XqCAA} zu+n#KrQBbJJ&bzK6uTJJ&cU_%A-VQf&X=qA8`%E&`E|jyX*n`_Kd%kF-y`~Yp%AFA z0r>qDye||s(Ql;Z8HIz2kDhZB4k@0!IESpi3_B6^+B%4>kJ!2i)?GdRjGxESePRvq zc_qr6kMQ=z=*9K^!S$Tpr|g7_JGvC#UuW=TJCSEkevzrSN#4W6JQb=v^!A}aW9qBJ z-Y50}jLPE2c;B4SPo^8+FVTHFf5FCC489@$tj+6YAHsOv++I9J*4xRMc;w|eZniU7 zJk0;(ey1Ov$U}*~8^FJ9jSq^!X9QnwN7ywiN_0eYYHY9iz7BSx`55d*buG$+_tF9!!VxbNEsWKG0$pS%kCp z*Z5Kl@ZGPz2JAt9MdOer>_k*mzk5*aM@{|iA+;;L@TZHxfb?tn&U(at=$u2@JAwWU zO1yEG)bswg=xra@B7IwkE4R1r8efo+Zd=LW0Yty!FjdZXFdHN@Xyu$T1X@jQp- zVc%{#&;LZ1$yAg1-%sPUdAPqkTgF=qej)UY?EGYvKYP!@-n;Pqm_Gl7;vLVIZlZHZ z-pXcu!~E^PV|+aM89pAKCHyU79Li6|^WAix@#Kit5)C zt8yAPKv%Y(WVXb9-u4~XPo_|kZwM3*%SWg@Z!N#m6tV<-Y~mEQH=2L2_$h3R7q}y* zq8{`289hTUbSfqwk{&NQyC`tSWuYj-iV^ZxHF##7;&-{$+dkn216 zf{(#>^FQxMW4tcl`Y|6BzfTK#f!~kJp=D7{6C$~tJW(pxzTYt3M-KT9<9+0qpUrQf z^H*WV^qldis&Zaa`BppW=`G_`{21RmuXcJ1_muM88~(-!jR38n?+EseSnig{{T-;t z7SHSD>@7scBc+Ah%y6ZXMw()j^eo+S06@>(rV)$&p; z6F~aWxsqC*rsersp04F#luv`8hJ7>j{wmx*rAx{l|0y(|Q~p+-Gu}s$O!U>Kh`-xY zI8Xe6Xz_A+o^5Ax#_e9?+9mM{;^b)A+}!rzO3=gLgu_bz^8`(y<9Uk{d=j_|a>qgE zZJ{66KFVz$wrLOg^M2dxIY?*c!kL{5hmV)_?ZXE6mIwE=T)6KRxE$|9nfPlLdcyQ3 z^`(8$;FFhg<|pMTV}5>}=Bu6ncrv_ApX3Yyesn%lOI(BYkR$HrE7E?JG~o8*KehGt zW{0@_P11g5-2TGMcwS6TY&>Bf`UzJ+-bw{BZ1m&2>7|QYzm$11fS;9b+dpsf$g_oq@qziZ^oO$}*P4uO6T?CJ@&|^+!oU-2_haT^v zdUVc@ra5%p zsmMRW`O|1A9tYMK0^ zM|mHI(v{&Ix0d%6!hR&*v7ZM0FY9-v^m_tPMZYuE1RbI(zB3gLnjQL=tald08zI>w zdf1QoPz?5wqQ8HU+}~U7w~WK#dCj5Tzj%q%r+lg6xjXDujOWfM$9Qg!a*QX|d5zE8 zBIjp`oWt+*cyA;&2cl z@SM;2I>^Zl+ZCP~x!;{KdNiNqP3h?C6{%iWe^~S=Djy+q4D0u6`BhrJSIhVwURb|d z%LmGHwu8*#IXXWK)IX|u!f|rn^O-#a%cpsIU69d-18H15j@^i6J;C2v=m+};Kkfgr z_bza9RaLt9sX&DU83{;1C_xe)5=+s5uh`6JbWmf@oiRSzguW;#8Zkyk(?lgF2d_y0 ziSZRsF+{|!>Q2&8)TmsEigujw!T1=NtB&zC#w#k$bu@Q$H0mh-?^};^R-LMDxxxKH+@t^PTpX?=3{SdA)xr z)l+;lej%Jc>%d22q5Er(tI4~C4w#3Uyswmb74|1ud6kvdTY0sWH(GhEl$*ORm2%p$ zc+2E1^26WP_})m|2PLMiL!X%uswU&gpJ5bm)hg0!*%wZLYA5F@$VQ$y03!WVEkPE-o^>y4?6h; zIvxfX_%)3KKu0U9UyE>;n>~7fz)`(%`lRE_rCqvvrQBn?rPl69v?JcfNPnwDen_81 zgCWkZuT(kPpzEvIR<+CSXWhZv_mjB&c2Q%;@_hNnB1C|$-DchN=l{eb%C(T#FvyT5?m7k>25 z1b*S4?wcQVx=rSvs>xnZko&6C9Mt-;E8@{ej^Q^3V?uGY?_pqIg zFaJK|b&6klz2cQxUd_*Uxwr2^a-YwmfHLv=^iKFAI!#=+0UQZ)76!umZFtVR^Nsa) zVyx6BUM|o1cOfs=9|(unq~C=+>h zsJs{7K~#CiK8`N^A>Di*8TU<5qI&HoyOVeZdJDfH%e-7};{J)vs5_nSLUJ6$`w-%8 z@^8xTLgx0&`Yp#10lx*rH^d3+?+0CGOb^!sOd}w|q6e!w=IoEd2OW_%7s~ zh_j+xI$u5xzQpG)pBKWuSCciu2-+u+8~gratWUYYer1Ux+>XUKf%J)SLg#lO)eciG zX7pXivRt%PUO2xJxeaphy$^TJ50X;cF#JZ?o%S5@8)++%JLMI_>X5I?K_~3rQGdHm z`%A~yYk9Mkdwd^~boTWP!hIIxH0B*g*w1y^-t~<22KM3kxQz?;U-Wa6)eH8Z{9U;% zB|HA#2q(}h(#P|mlHUSo_WK0b^T=QN1;;DadrYYw?F{x=s~t1?#B&>d4j$n>57CES z--mR$dl2L<_V04KTITI%Nc-lW(DxxPoJp8NM92P&6H#$~vr@t@B( z;`n`D_u(7kJg6#y(6sM&)GAA)?0V|+7{q1rJi?>AWp(uzX?wr$i+n$73VHMO71o=@ zdV2({z-#_t6tw;F(bU`6c zwaQ$fV<8t7cjn&>_4Rl?mlSz-k)t&KZm7nc)kNu7&{gBMs?4GopB!WJ#Sh3mZ5?Ul zJyzCpNwa#(%6eXDR=-io=b@1fl%uq*_J-sA*$C~F=I>JbzIi%oaqJPO zfUE1fnf6@n)Cc_u0_*U>^=ZK5EIC0?+fqalg}t;pd{?{hY)xb*(?Dejr~5 z8MAc{Uk7REJj3&=S-}Wrt2O)UefztcX!IA&pSRN|=aA#vAL2 zUkT&mx=1>DXRhae{gjvo_V-IbFkBIi)A>fy6F8lK-#yP-tmo)=8}9GAR5kgi*n!x; z+vy!W#z#IqPW;d_q#f~-_fA0nl_mOLzOR^XOz3iHl7FA`BpG(cxMlx@(K)^^`pp-B zK7p=l>1Xf5zLqCKzOt>hZzRMOvae;6;d8y-DVN*uC&&AEw2Ss$@GQkEvHrQNAK=Tr z7KeXH0e`8%e>m$~yq2~NKbwC~T&?wqM-6{glLyIzBEO*fpZ?(cT0%VeBG?7KF9(!5 z)*;V_T=+WV#M2e;i6_|op?06I_jFkG4(H5CUVflLtI@gcLK0?HznWYuzo*wPmV1=f zRqzv8W3j*?oqqWS>Y3*I1}aZi{keYWB<&XE?GA-@#d`dctY3~6<88@J)+ z`R+qqaQNL6w!f6^H&|YMtL7i6ucSP_6Cv{z&O18umP$9AcO!5yzm|Gw>wuLvN;%SD zG4>-*j458+zeKwDIMUrlACHF-wn4Q-uighb4YwA{`c|#d&~devOF64QMAqZd_A)Iu zPSo<~QZ4sAP|IUWwA?>i%9w{)eXr-gYd_JB5bw05{2;xKfn2A%l`p=pw%NW?#yiwd zxasICq>Q|n^plRgRLlL^Pr6grDY8NBZ>X;H%m(dwzt!(kI71DEAMq0UZBlv?uV3wg zzQIl4&)iP%`4?fI`JTyoJ~w;B=O4v$*F)^T?UE0He|Z7_?8Rsw?CWaAU8X-yk91t= zRI3~>4Ga5YbUBOIL9PakF7{qx)@O7%Q+~$#+)5X`_pWpsRJp`HP@|*LE8#q>pSE8q}!fx-Knr=yMP7yp9Ejx_k z4}3Oy=KLK~dKKRxGd@4X_}nl)=iebSK3|~yb@90|b3X3?pR37c9mfp{cQSgV?Sj86 zQI+FcTH>#~Ut;_vU%lS>ls}3dk*|aaSp@V z1z@wK-(#)e`?Q?7J{_Z?gw!fya*y&P{RDj^-sx!J-~K!J=KjU?pzt&399QacZ{r|d z-@h61x8`oax4;jZNLl}eIdZSf{#&JYON!#>G{1FF+7ZsjUO_l_O1YOl@OvPv_g0J{ z-8C-ur+BaVfYK|-{Q|^u(SChnd#BvXIs1XWuOr-+>Zi}^(%sv&pYaj7M|y5Cd^V$9 zw$<#;29-znHNnUIVYbHo-!_3$_`fYyo}T|p+e)u=ROREg;P<`+{uO>t$PJl55)K#r z@$S<8MVe016J)w4HM>;Esp6lG8$UJ)7|8D(%AehflrF>me18}H8Ba(0zq>?#+R?0T z<7sPqycebL$BdumaERwG;OnE_j0E_;zQcN7=lQZ-a%S*0E55A9@1w2U_@ zeTnsUYdiYOL)-^p<4)Vk2iE%>>mdipi*c;zTT{z!|Hba(5$oUf*-m-fCV2_PGuHcH zsos9ZK{k$9@4cmZhgk1&?LXEVFV&*}xLkR>$^0Vi2=QD!!njw`D{}q==Z)1w+-g_c z%KC3E{}3mQcpY28{a0+ z%l2jZ@%Db{zpyv^tUNt?r7?y?K|=3+HHRoLqmP=IQb{d$yMIINQE6 zoyXbwo#~mz+0_J216Q;QF+L-mA6&9K)JxY}9~bMLgYmfkEBxL|6n@~J+AXCY`M}H1 zIbnI0ly!dN_Md!R8}b-9zai)M;?Gh7^z!k$JYhXl=*jk->o^)0Mfp4oxk5fl>c{6| zuOOqmnCIg7Io|hth;n;K@@>99AZ;DCvgL7GiSW($7eu)0(O;yy*w5fk&)o|6?TxAj z_Wf!03v<)q7tSl?10#P}|0xsTm(3f<7hcswC;qYj$oCkx?L~dUnOm}ZLKnlA_R;Gd ziF!p`bp-l?d>zkT5nq9Rl>geSSIFJtwEX;aj~_Ih0{UuPl*bb-jkkOsYr6BW(C0RR z4mmp7&h;78^JykKx82vBBR@zte=m&Vy#-?{=%yP=(mzuC9p}T1o%93e$%qSkKgaBY z&x2L&ig~cgWiby{x&3|2gXaSuk9Q+Im)ZR5hcaKN3x3o?zjosfoOh#mxAc6dfr>I7 zdL(>33;WO61nUZ_2PQ|cpChfG4^Uq$PvG-n$1C0C@%5X#@Syc5=6^pFzZUVN>Q}`o zb>_h!B3z#pynLUn_g_uEEpUqUf;){rC#c`-yF<%k$7s2Kzm|6%spY|aQXZC^R{p@y#e#CbXOGRn(cW030>ki|tQcKfxtWH&s{_($Q_4+Ia|3+ih%SuE{y zKRdQk=gKEm@y-Hy{6T%LE?Y%TfO4-!b)bu#_J6 zW@pm2#Y0yKIJ}3XbYp)nep1Yr{y_4j^p8tXmHU%8Gi1Fta9vubi5>Ce>Ph0QuZ&Qi zI{B0CUakDvvsUhro+~Zh`Xbt~f9i{$hm?-4((%tV4kX7D4UF63``Sttlk|Ayr~6^7n<^bSxxwXm|MUzi51PC^Tgz_W84vR+zMo=# z8@+aXZ>7igRXNUk(=U$WL&&)leq8q>{#W_&YI35`Z#r?-a?pYJe(Ten{9s(@^o{di zum8`iAM!RaZ;-YNd-5+lmpRO@M*!E~SMzwD{ePYH=$vtJzRo;TF<)0d%z9s8y`W#B zFD{SQYx_8F{$y!foUcz@(p~TNQoa4GcX@Zc+e-Clpxqw({*1WK=Zc$q&BOmp07tvw z{^@P-gYh}}z;XX8;vL#6in{xMU;mBuJ^uNu#A`nkKX?D*fjcce_=?{9?OcYwyQDnS z(0zR|9w7f>Jn+9qJICeYy`sl>tI2Q0uEuzXqEW^Fc*W=MlIP#v~WjmO8n@5a}OeBX_)6Y0L2 z>Bh&^_2I)(FW|Wt4+!^y(zry=d+6_zO7%p~d)R}%QoSYg>utkl zR+7-Kv){#6(#|gx`W4@QT4Lo9(T_L|(#8D;^%?&`{<_Z%N>I<|g&wbAU$l%r+Lxap zp6t%^y+9C+{kp!*?V)cR#|vODy8ZO2U2w=R;IDqSUGRTliLaEa!p;}`KZW&zJVkkp z{6C5HCb9F;zZ_qZ6Vlh|<$2M3zuYy-KaThRJc)Eu{tQ&k5W5=b<^0uo?{eW|y368` zOEeCd%wG}yJ@|f8uk{ep1@j1@AM5?P^!+E&Blo*zcUbQ~1fIr0k$z&I5Nq&ay+b8< zq=)-4UpGp}lphlzPd~CW(!=*7eM#&~vwgdaf2grV=`eb$+_S!oS{}Pa%l+%MymL&; zgKOnJU3(Vwi{py^qh9hK&Yxdko>@&!Gdxex{u+m+oR0du_mGzJdGFm?&gZ=crF>t% z{}u79mhg1F+X4NG@#Q6zJ#D906XSP(HM|k6~N0EL!FOcvb ziO@6Mt@D<&rSp~noPWowtG(GvwtMI!@O!X#dja3u*D9w-`(oXH+i&@x*mtx=%lUaa z8?}78G(()eUdmZr=POyC&Qr2}n_o2)&uVhC_G9NTBOk7C+SaaNa7V3upTXUr?ftuN znSBq=`-|fex|#psxWCvg_De)PThH|)(=&-LVYpfUm7nUQ<1)sL(LY(ewWWH}uhHA% zM#6i}$7zQZ|019LM4?0E7yDuTM_tg_zwA2BG2+a(BMitsOSL zyY=2UDEC<3<@D_@0$;-X?rzvWKS$Ezgt)Kz0pOd@|JdJY(%(-MzQvV%ehQxZylBYm zW;OYd)_a(+Cn>(0xJ>xnZBLhX$pPp2kuE-tt0mv-a<1~->$~ogwZD?>$2;2>-*q=V zvhNY3ZPkM;=fCQK^FQ0F{TJVLpJDqA+CJ-3e6ohYuWP??{4$=V(vx&w6zyb7pEFLE zdcppD_FBdj+D~E6PL&2xPNbdN!?zUueBgH4!*cs>{}tO4zrT4n_-~{7C;z#gF5-qeVN--4LDmh_g}dwQj>1LuU3V(tX72>2-)3tI6AB+?eO; zy`lai)+e9X|G!<l# zaWU#0YwI$8K7AYq&aO^4wTdzz zZJAxIn_RTb?wMYvqb3)9>Q}Qhibpj$RmMN#_8YW)9_Ka;zMaP(=^*1VIjhPp|4u!f zY`h=fc*n}); z`R?C!%FlA>8TMIp)%#Yd-YZbg*SpGki~LH??=6S}iuKN_Ff`^@DS^ntO8p`a`#h;v zh8y`vJUxFyK7aWmz2pOvRKnk-@N08@eMt?^RPf#2^iyy4l=bFm3U{V@vtw#K_xA|O zcsV`EH(ng?kDko9N#PAt7VvS>+@*3cwB|_hyJa|C^jjy*1m0`TFW?pW#o3bjU0YWW zKKZ&raqi-Oja*0kspoE2d_GjzG1ITyZkvAPcH8vJ?4i$(un$(_F1KfH-^|{X`}cVX z`SCd<(jvXLo4?ut`L8C;E`3}~`Q2R5|K~T+4y)dTeMPDlrnl)X&G*E97Fa(&Mtl0@ zqW}`$Ws-4p&%+Pu_}1t+vEC_q?s*TkN9cw2D(~I%aFw?rUvNO+rKNd!#ELlr6<>|*)RK9nu4x7HBXR^Y2G2WlYWg4ao^wq z^gG=4@tXaZb*6NX?z~g!IC!(@8Q$a8a^nUq=W_NYE$4FfS}A9PUf<&g^B0rIS#hrD zA6L&v&%Z6nxzqU>BIobwl5^2h^9PZ>&kFXdR?+p&KeYZ<6V0Q#os4qe<5(=?SfS&1 zn99@dGe59#3*>RP@;$YA>rC)HPQf&9RkkRy)+BOhcQ73|{QV@;-eet&A0{>S-W zl(YAK^uFZ>`oa5XPyYY>0Q?K$4?ov;$0s}E#>w&nZ$rJ`XMSMU4O8a_;KHVrA9z3V z41di0z^C5z`^^u$QSuGb&ky|QQt&V2TkkDD@ceh6e#om1OMl(@ftTU=r1^m})SeC> zr+2se%x{u!waP--(aN}^bDx#wIS7|mp8u$8KAF$?6V7Q7yUq67!oK`!vVhHGU&#H1 zyT1dj&Od)2`0nk1tLs|754a-%F247mel5gFvcKY7A&<-hk`Lo-do9Xt7=%*Ei$Ko> zxL;v+&y(=|PdozO9+VL9?*rdEd*Ryxa9qqE6JMSmdN9;uT=KNNIxoV{_iz^v@v6$d zuv_?>Qzsu+{(UGW<8Zlu@9;y6C(pCr|5ESl=jj)r{zXIrp-?|S6%Kke!WS`z+G_XB>|54R7B>GKR34q~> z_3qjad-rxAjEi|ybk)(%VYX|^&q>GnBpwm3Z|zt9HlL5ic5%P&1MoM0C*30+@?G?R z$6~AZ<^90JzUvw5@3VQ#r>_=&Z}dFM_Oor2{Sf8)>8R3~{qL3ezw)70d4#k>UR~fI zuP*bPbo2{S&ib}%dF)eK?%$^6owsXwaEp|YSGTe~@3;DW3I}<0`8~!797k&B))KFy z-qlSPKK~}{WE{^y(4WsWZ>;%=;`@Y#zkO#nYZ(4lDL=7JsQ80+yt019ANsENH}24T z-+sOK>$u8zJO7Etp_?`Tjz2rj3-}c9c0Eel>wEHr`{3gDMhNf94*vN5kJ>l#%I0p=l@~PMO;&((y zrxiWn?NWI5{nWT#viR-X53L)VqumfYWBN?Ek45gi+`sF2%%eTMqyKA5dbC!~%_#K9 zzSo-T(JK8t*CYMTI=+`F_{aX2BY%VMF^hd9e!qArTe2FgdeG0Q%g#Sr_uX65qq`S6jKYKD1H92v;kMD)=+%9?Gd&r3*4?M_Xm;K9oYlR)*Yn?1U!tGn_^Qbf zLLbZ@^YM*bQ^ZA6jqfrU-}kNk-n@Oscd(|Q&kLlzt|uYx%-eT-2WyJ<&y)6Fwf^sv z_LG0tYH~jPwZQp;z+v3~(o$T=l~nTc9$fyuaFi40_o;}%J$|lL&LaE5cbWe%aS!%E zNWK=|dl&qN8n!QM^ixvK`gFdTj_JPEtY7ypr8{k3>!8j%hwAFzvcZc~j`}avd*4gt zKGb-H+@t)^j>P!z@88*}KTenCBzpB;(7l@cPr*OhAMpoff8)Hu^EH=Fbm}khi1P%m zcQNYaaorwahs+nmzQb4YB41yG?@0BE+i0KNkFee)Qm@;ds(mi(?(?PIh{$7<6AF;~ z4Z>R~_0+D!@kjg1de1?<2uJ8+>kH97KDk7febDb-cKOds_3oB>-FEr$sF!V+-{r5l zPUChr_J1zw7kQ24UF}xUuk@HlHPEiPN5B8Wb{B^0Un6_u@~s``1r&>T`^zqr7ip7RmO3Y z?aw5^hvw-#iTL=%KQoM%7rvb-e2IE}k;G-nuWXI+F^{W_&n=CM{X7i9fBLh6zpmT- z*y3`me~KOwU*b7r-xnUL&r!LqAIg6hyzILic<;r2KPPt1WO3dH#*wE(P)Ghoe$q~J9N)gVv)u^z z%;$UYyf*uQ(7Bp?MefbYm;$0hoFiT=*K#^F-_@~l!mXfgWl^_`@fU=k-7 z4C4ZwO)pj9SU<**#N!6kFXCx!n9r+^o4nnd(JnjM=abgY*hcNo=Z$T(3y_OL#0P#) z?>*jE)A>^(zehfa-`>gA;0N$8zd!j#oWF(jKhc+g%3n!7BDQzA-wL_FIYq*ci_IRn zKlF9wb52seW1cPYLiyu$&Pf~OUhEH2ze79m@fC%gh;~clV~^Um+T0b=K5cC`d#8BR zD$lj&W-a8XdcC#=V++Q|cA@VzrM&p3CB(JkO=}G0pQ_YHxoZ`Qj&+ z?4`^1BO%|_DK4J&j0#@WnuL2P#? z>Usa?oaFWBRn@*L#3WgOKdQ;iGA_!`u9DqYdq1pYkH-lA+mK^l|DnB`_nyMO@b|uvV*S+PcF%Xjal1eKM~RbvCUzqJF7!10 zCtSYcihPCH6OZ3qFE!36;$^Ptu)fDF>hJNsiMDU3-%l-nhxbF|x#u0RkJ;*Zf7-5^ z==TMSyypRvXODC4)bdo{VX*w_NiE{HQS3e5hc$U!Z)MfTE_wv{V*Et991oL%JeAQ! z^JfJe82$10RRR}rlib-ZL*CubABz3Vfn$jBatGrD$jMT`VY_vZlOhkSbfi3fvLufu zTYdVOX6pi>i{~F%{~M+HTmc|_)~BCB6`UiZ_)eUQ06GmN~ z`ua|(N9;PEZ%5hn!soO8ow#1{GEFaN$n`jn^Y719toeH0shc?6aVaJ=l=oo z^r7MMrg}pBd1V_^-=aJ* zPaNfm>#8w-@G!_zwsp~O*&g$B!4LBsD=Yq4eZG_<+{M4`gu4oHH{mV<9Ma_>fV*zZ zputhPtgBxr<#iiYcEKypM?8*M(--F>zV7!pqT8|lT(a&^eAr`oBcL z3jX8g_v#nO;418o*{yt@rTmC+eH<@@{7Bpnc^#^&KKeXhoqdN9@6U>!VxB1X)V_Pq z{iq;m$2?~>>=@?(i%RzY{F@o~tu;P6eygpl_<5Y~+bUJrvfAiK6T z4@f)i_H8P^|0TewCcpd*`=fpRNy#5DlTP^b2kDs2H*9@1ZSPe(H9D?#u20Vw$>(wP zspo0P8>$@~)p-v4+4WfJoAP%6cAev>Cc4h?rw~{F^A6H$r}D%6T(J+0St2oboPmz|ADZdYNe1bnK;|-Hvf)xX+QnVdG`BX z>YZ})Ikb)IyLX@-;xX|r1C>`v#cYGchig>cVtg+9otg&M;$8Z&wRlAMPrV)RckAzr z%h$v1di?Eid942=)^AyT$idyLf4P=py}nXC!DDk#ZzbBY|Hq#c`CEAb2+iX8i@+8_m-K}&g)^9bzlKQ!hVSI#_HFQ4EYrjo3 zz%AgtLlDTeTD&wqPw=eGxlEoY^L{rt^dC z-w40u{yg`K`FFw>OZ#-!+AcUN0f+6cL3{dfhz9ZqnxCMacAj5h>ltefh+N{_SAhpT zkuuwJW{fRIqo3>MOaC}OTm6j1L0QA{OK;IULe^(-Gv=nevVP5zVIQy1BWoyq@&3G)`<0Hd zU!hA=+moLs!_G&4dzJXfi=;xc{Vjom_(jHAmcMTLH#W67rU;f{-_}a zzeP@Kv(&$3TUBnm;4|pQ)l2`c=?VYAQs38^({a;>#scZj&)xNPAAWC=SGiwbXJxgm1Nk1BSN zb3nAye!&eSSuO|qd*=RUm)7F+afa`+I1ly8ek=0z zD`-b}&)gRC^iULB5pQN@{G18b@8jr|_Be*Y5ut0wOk zI&nS&)`xux^HtB=s_(T~Pb2swT_`vBLH#|#U5Pk@<9Q@vw6wii>}uLtrT0 z6mjRSc`|R0{8|sV5swp)FJ=6DskQqC+Qs_wfTzc0tmp8*TB_&xo)3Jx@NAR1h{Ygm z0?+V{@IDWCLu(fOC+o%jAMu}^_!9q!@2Al2MUdkKXm^F(J%3Z1T@m?q`|Ek$6t;<1 z>ibkRtV;ZR&7pp!TWb4Pu}@6p)Z)3crFxLtqdtviBHp(`-#l(~drG{RdG>hJ@x(cx znqR5wx|*+_MR;Ytxg5V6Az8DvUgRUUv#sr>4~tX}+uO9=g%&+1KCB-AdX%5Mg5|Gr@XF2-^BN2kk@qAA))VZYo+mB=TF0}3$3j4 zw&w1Oy7X7{C+O2E)88`wuGxJB~3SU=JHTCa0`>91n{qR(T}T=w}(JYoAK*#DnnLBH8jKUmD4 zFOUW?PeQ*w(Ns8W_w*e-`mx_Bhd#bjF}~VSL(;Hz)H6j-Xpf*0$b+vJI!F3kS@Ii{ zL&9^pdl2A7yn2o|;3?<1w-j%ufAkxxq4!Q#&nrw^T8#59>;rYXH&A(!?jH$yA^itG zvk*;5pWl6idaZP%zV}U`*U=tahxWeD)7Ph}$(KdWig|_F*<${wb~erDpK51|`KQu( zy7Nzbzee~H@j4%PVV}F`S&=t?g_MhY{!3La^Zn14YB|s6U!>(cpKtNkpgr%m`h5xq z`=6zLl#h{;e3Sm9_v!Elu^#1~&;K3qPBpnz7&_cqEqdnPZQ{BkL<{SVx*xSxd0=k8 zr2+m~i~m=X_einXeyh->81EaTT&!PQt>t{Y>X&@|qMH1zz;XFsS2uh%$z!n(wDT{5 zyez<@E9_4Bq`sV^pRE8s50M5#Ta~Yf6SUvD_J{ecl@%YX>seXxZMGImd8n@AiTZS~ zq<>;Rn$n%f^);pQu;usN`aAQZ+vrCx(X#6k`EWDNjV|=)0?kjh4k=zIp#m;^7t6}( zpVQVsD=R#1r2iZ*WhzCgDfeL3k zw8yJNP6jGRNPkfe8u-1Myjbda`*n4#@AEN-SIgn4eJ4C#5#BRU&c8Qq`%c%@wSKc@ z^Dw+`Ma)u*M;PCVoZ!9y&#$mM?Ig!>&KVEKzoe)6C9J3LxzF=({;&BPN;m7Nf5W~n zdG2v1&UaOP*(KHF`<3E9f;>F@37v7Y$ipRCKONQl6#0Mtc`<(U^&O=L^?@^^q1?Va zQ2-SBrt`9N)b&m0Yw4Klo6Q4vy1uDhasQGH+Vg&^-=}bf8YcfO8z1l}+ZVSZH@uy8 zMCm$EIa}gP&*OSOX=|m)m+RpwE4v=9wzBq*by_QTAY2}Sp)^&NDA1r0UX> zU+*mPaJNglp~iN(r=z#(xb0lzbnF%_+j+_9&M__L=jH9U@_ozKl3&k++{AHte&jUq zOM1Rjq{n3#nSW<3KWE^fGTdZ>lL1^fKUC=1ea`R!c^>;)3OdGk@J`rg;&sJqp!aXr zI1=+ui7#Nkv<$UWVz`*hPA?7Lt$c7I=DvVK>y-%@|I3ZpyP zp;gjK+{l#^J z2SN@gue?^6{ti@Bj+?{V7#D!&Nl+V@8|b@6x2w$8hU8b;sI z=bC&QeaHTrmivvqJ1@}kpwf4!Zt_29&-<-@pTZex*t|aQxlHGe1vN_=i@ofF%-TR^VS^#r`djl z*n?u;bf(&ee4coUmh*Yj30ltQiDpj*?Rme|?^8HK4TT@|kMwtYPky}savtTI{NVFP zg1*({8o@LEF8nLe%i|(HA1>wzzJu=>7V@C`FZ`T=$hU>)iT(ciwoW@G{RKX9UwY&h z_un}j@1JmfCixqsPhp=1WjtvU6>w!I>pg9%-O5hZdusBSoh;Ql^5N7=!mm*Ng1)Y_ z=f5k(HU8efZ%WVko&e!|hW-!soLAab|20fv;NpCVSGrIU$?E?pa+EGSPM&A=pIceu z+pPX$D_89IyR_U^e>h=q>1P>mrh8N_eO^X6XUljo<8=+K=YHMc zbA6h6wgST-+}fPk1e@D2_w!MYo`K(;?w)U1w^i+4)Mv3jO#vrz^XkWU%8mG~OZ0b~ zD=u^(z2CT)^R2?4bAI*5@;9yr#OvSQMtwU^<^l90GVkjlf9`)i3c0D`E213XpMo9v zD)5i`;CgaXN$y=wZY(`_J>h&Z!f`!m;<@Vy;#8qi_j&kRgwNgazv@+lE8kmbt9&qT z;O|HN^3~9buJ1O1LAa*V{-Qni~yvxS_;V!q%#>F6+FE@yELQVU6os@>u3sQJ#p;*WO4yQoYXY*{I3Y z5o92KAH75M-|a(g&)hzkez+a;?^f7%EUL*jWL%N&j{w|W^9Sxj^6%I9ca3n)fwa%2 z`0m$ygt~G5#B;c(`tH{owxPbQ*O3k*!Wa9lQF#7N&WkNRsV1KjJSLt;s-V59K{BCg z*CGF$SM=Jae$U^aUGT#jQP1Vwb9C3?DzFn z*1WNQM`xSrBmq)%vyotw~-->fEF&&`iiFt}4;Frf8 z_d~AU_RQapTrHZWT%Ga%s9aH=C|A75H%1b@eKX}ea>VAxb7a1TeXRm7y+PxtNGG=QJO%0a<#X63+ zt3mG?hsB*SK6;Pj{j~og-?BjAt(k9h(Ks~5V{7TZH!1x|m)F0xQ@)5_wq}9y$>#I1 z-+(4+2=Gx+Qt3e#Iq&sPLq1kkMF>f%=l2X z_ygZ@7QWn9z7}zu!_o8cux_XP?pv<(&E;d6mUH=7D&_ksA6Up#Qo1tz zEpim*BY$=(_&9FALmkG!N1S^h`1<+u#kpZ7@A@_-!>%Cw5sU|-VzZByjk+-t{L>%GsjWz$XQ~s86f0vDmafH`C<}AZU`PmN8<4|$VD|dMexlU2Na&2 zi|_AK_o5T!hV6fmk)AFe8bJP`i;>j5kizsF&p0-v*^ zcn%$^$OV-O=g_HMN4j4C`XUY%|CenryUnwS61Jy{oDC+S^c2abNiE@Z)fLF*m;I*FXOB4v-W%Se)PE9 z)0WaZ-@jnz<;L-dp0yPZ<|%2vNY`&3&-g?2G(U&Y@;^AwMETk_{cbGQ@~G>x>%Zx{ z>%Y;{^J#8(-QGrhAs*2$)Jpnt!1Ve%H&ZWel>VE$-yrjxI6klU4b-b0b*!uxa6OfD z!+F3m@Mte@mgjn2Q?vDRk<(h`H}_E9B3$Zo+BP{IH9Z(pxhDM{Ap2L<-V9XUt?^e5 z&-cr}O8Os|(~ZZw1dnA(SJ#&ZN%blHg4??XV13HZ!^!#8a``lVwOme(UuGY%4@CRj zto_AtFR=ByH?GHeOEOO+IQ}kn&f4{QKk)KEmm-csP=;$VIHc#`gQNXc#i=IG)pon& zCi~>X|2DOZ?^6o@=vSBF5#emO75(hC`bY*vKjVHc)_(=-2lz5RgCFgs!+#m;w+uee z6nri*d`6cDKEz`q&c|xD)E*UdPzGb)sMNzgK(PZ|@Ql8M^G4*MaGsLtyX8UCQGreF|r&q43Lg0OyCvIItf^6+$wa^qi~Cs%%?7s#-&E?|6de=uo0s)85gbuxWe3DCrMeo0rXGe|Cz|U+e4ktcC~NoclLUOw@@`wH60muNlH>+(MHTIG8AePH%Ft7ra%gT$4` zOK$&7|5J;P=OgUzIQL{w_XT=hB^$JJK6{)GBlc{k_CtL4VJwCGinzm1?pA#Wc5pJe zB4r5Yiy!LL6Z#GKA+c*NCzLO*|5?_L@KN9OFKrio^-DZ&HRNkYSnoQ;KkDJ9kJAwcxktN9db&L&Uf;bA<5Tk^>mF{8Uj@4vpL_i9d6~~$qWD|~ z0JuD_U#l?6ha5T|+ESGLl7~S@_V;S&)j;wl!7IjZJ5bg0BN1P*)0StbCXbbVV>@1E@T`)!MyK?`-$fM^c_fgpLE11tL$?;LZO6EMJ@-u9!&1YlWKYF7A^O$*YeIWEf21hdo_8C zKKK01AHj})u%{jWiOO-bv&@g0JjHlpl&_Q9@dvVggbz6^;1_oM#F8A4 zZ@ujJajZ8DJAMr7&A^WT>VuvBX)-(h^HROZ?D$X1^@9HS`&iMAzaMdXVaHwmo+fe= z_08?*7fbVB@`3z09nYBupon>%uXrEh!?K@bVugrxGVw6GpQ!h&Z(Qs`_kO0mYA;$^ zkNMa6^k2aak6T{q`N&hJGk3%chOb zUrh<`sRnQ9wBbE@N_giRJky71(ChJ2!aLXCEuJ=h=S&Gt?RVC1_J11qoiQamB;9dk z{TiQ6hrcIJ3GYD$Z~nB$d+e0(<{CV;Gt< z)BY`xyyhHfhy1Jb$9Wd7bj+UT`@9m#OBC~0qfb76J*4!?=dVT|8%I7ad!Hq<_bjT( z_qy!g-SAI&emLZFe4S)z$?oohUBdZUzarieXTy|myyv4{v$b9DqJ2RK-ZTFh7~(rx1F)#;e}p>(I(XSRC?-j5j0$Kmha zxm}vAdYs#}-zmRyyY>s?zm6m8|A~~{9{G54dzI_4e%E!lb+U{fc{`zN2i?FQr@xGk z>x>>RAFty|Tic}_^3lql)`*q6_0ZSJo+5CJ4mq4H*3O={wpm&AGvc-0;+iJ_4&y4S zD8BC_bc*#}4!&XjC(l`r8Vx+9Ouha{`2Gm^F3)kkp4bVMz&%z$T?P`S9PiFkjVepPnQAsy2<`GblGRWOA+P0+HXtC9$&Km{g?y0{~4$}MJlADa|HkN zTvWi7o~LlrM@tdw_wxjwtTA8jwtf-$H4pJJ*9|EW?B^WtcS6I3z-Q&hS@57;^W{+^8Iv(K6PCaE9uT6@EM zD9-a={;p0tsoxJxq#xqrC~ zp(l}^UtLAMt(1DT3ZZ~LqjHmdh1?%VdHvDzI{V`e%=r+vy*rEN%x50lU6hH>n@0j( zUGc~rDvx0XvU@|W~F5Aql5Ie$(ovNgWqs#uawISDoM1J8LcySz0 zeJAWoOUv{ht4s03m)F4_wbzP1rmfX-XFJMel((;JgPprd;iP+1KYd?jI<}|_U((m} zzJzxx{Yb!Lx%|FB?SRE+thevxPChApwZCZJKUAu>9(+sNNsj;f`THIlH%J@l;(6$3 z=Wp8EiJ$rl?KjqYd#N7njOUO2z1Nt(S|NI&_GzGUl*}U{9bDdCRgy!O&(DMI)nuX2 zx7q$rv42C2Wl~N@e=g;$Z>g5Yeyrtw+jp|_E-eo(mfwG$`gF&eI{D<|c>W~g_#np7 zwDai-yQ%Xq_(Q?7_`cOK!Z_-MU(drI)nuvEYqs^h80_PeaymMu(~!)@S~-q4j)x`MxfT%OhUPE$&{6dDn1jxybtp(21lPs9>`RuDpGoPhTwc z{JepDoiva8m+9{|e=o0x`uhyopq{HT**dEG+b+HHd1SCl-%306jq;wyPi7A|zuQup z-+c@7+z3DV#kg+tsFHoqctGuq=YMH$8l`&61rMW_?OS5Kvr6^M?kn9wzF|SB9`yp} zgiAe-gQGq9vywegyQ6rb9)9t|bq3`iI`Aa&Ui|5tkda*}-?q#+^{e5cZUb|n3?H%rH$Y@;W zSP8g352{s8HTgF^^zTaM^LC4O^Le|)yOvjRvZmEzcu;?}VPldDAM(>z#-^WV+{o@%v7>4^+SaT+?a)K(-(6Y+t+we@NgV z&+wmwm$vWLazppirK1P6+&3b>XIr)ZB5yy#_B*tF)~ER3y-Dj|`;FrldIbJ`6#U~J z176b^_fN4jpN^Hs4MyUsCcfUYa@u_O{*>@e6}Vad@@d2S=9KV!y=U39;r-K;@DKpw z%KDd18{TJo!lQKnU0XBcd%w$#+F!iy)f11jt@zQteE3B0Iq35N`mvV6$=_Sa&kxwA z@|(XmY4V)EH)-;Gx}cBzv&nPa3OC|KeZjm_`XfGHehvAg^{}3mKVNwDOx9QaTnJX~ zC&tD9=W>q6`QrKiGo>BQAC-PR?~=BbTe*83g7nJc$CmPm^Hs3}9zUWlUPT_ike8Ep zaeh(8L-nW&e~T|kr=wp>Iw}9tw)0=%;(M@SpK7yClYX&IrS>Yfk1jthPi}9ty?;L` zbNOm${bHZ+j|CpiuT=RRy-VTunf#7@OUwNxzdOI8`Cx1Lw;e46S#Fw&RwyYX1+ zg~^k>pVMraT-kp6X6r{n58oHrY}vT#`dysimeQ+fdXIR=M}@POY==PC(B^&W7rG&VI9{{SDP!f3)AJa=hzA-ftGT6E&49 z&VOKnWPP0XT9yB5nfKbPip0yT$Lr$1)cXp|TUm492qfrn`98%{7vcw8Q9ckxBOdvf z_S=%5WnbuW?w8NkOU*vn_sQ{IpU}PV2TIqdC-WJv2meXFay~s$nosXU{EPKl>7V|H zm%o3U!dLKeyItfD%pV=EzjHht`>Jg{nQ=2OxBqe9ndq_G^l7`8pqce$M04+Jm-5Y$8T_vm&yI#BW}X;K<5#$V>X_)`X}OXcB$T-Qcvwm^na(9 z>xmy$IF4_ecOUz{&haHO@7Dffy`xL@7E3+tKh~?3>MaMJ_v4*g&!e-2T8?-g0KLfXpV1F)(%)Hr1;?df zbHcq;yeQB3FF9u$|J5?@EA06|u0N;nafhBi8s%c&%38s<*?y_qi+t{-I*vS_dy$s& zeC~6#oab}Z4$gExy3f}+&SPN*BR!n|W0UazSD;fhSt)pw+eN+j_>}xs`c;!p>UhfU zDI4E1le5^5^XuclBll;4&ooIK*W9heeovpb<2)zDn?@Jc#4@{Ee#Q6I7j{e6L$W?y zuXXu28|W`a(___*Vf}iQ=J#3(k8$f9=xemUTn8pz|9UO(9-F6m>DC;%57>E1S-AbeE1JKksv<c80k4@Wt# z@cw=O?3u#vp@zxL=qbj3*OwEt+;4KT^B64;s@x3u_W=j(dB4@~Q#eBng&*ZN`X}P` ze-Rf%y6rc={7J+?)#PzqdMNGfTo|@L1A1226|;k5Du=~;%Qn7zpOuX--)CjxyFl2{ ztrv~S^x`hXZxVfQeU5UzsiY6%$g{cp#d=qw9`=!{|F3KRshvBGeVD?Bw6(>4SH4C% zE=3$&raR|pcb4X9UxPivd{V}7&dG~}0O`1{3!U>i4aAylT^GW6AJU(%t6;rf%BO8N zx^3MiW#32M9fvQJiV;td-!LzBJA2z}iI>@D+o$e)9;htn2?zPWU-1XZ#ipxBKcidQ z?fl*HJKh%)`qgHgA#k8KD%W}ZWq!otubkf69`k3d-)C~saKE7w-e@nLhaS4^#V+mF z&x;A~2_HiIRM;PEw!;0c z_h9*=64Yp%*+ zUFm@Dp($Oa_|7o-K)N4`E%mNXwTcEB>3@;kEZZfYuMn?C!5<+1FXN~t&r<%4nmy0= zQ7gaGMN@4Cisv_Jg8zoYh|SxK@0}Y=e zuh~(LGsn!1=5eOmVY8q8?pL+mRC4j-*LC7|$kyX;2j11>m!=1uauCNuKg)5>exNg7r2>Ctc zNyQ%;96!f_@UP`}xC7qgyWk#wW#m=Pb6*uD8hZ=dvv}-$XR`)tKD9JE7$+-+3Z|u1S<1ghO1}e1jfP1;tkNEk%zu__X zn{nMARNntr%yXLpAhzfEi5{k70FU+j1<=dk!C@`v^-vvb#2 zuk*bcjnmWCGV!-~-%tHpYpInr4qmtQVxd#P?|ITM%bbB>-XY~ES3<{4Mwd(U&T*Vq zl2hTM=}F}0IjpDQQo{8Ck!O>8#AkVYu;^ao^vwGxr}Iosb$sJpa>{w_r1ER>5aoAv zNq#p{eof9vmzv1$Mxk@9vgaPkYq1}Hy*y9z{rH-XPRD#d{%ZX_-;cja%K3TK_c<>% zA>%I2jo5B@+$wjRyQSs)+=wk&&d-g|@l1Cfh;=M!Pr2e%)>qFX3>{CdP`@=ljPKlw zf1C6?;%D1;37^ybUBPW;_rHpL(CM!2x(?IYCij8LUr0aM28}nO{w-miBG`!$z=8i2 zJjnNz7z6qG*>^)f)>xi+>z(p@wsm=zJT2h-ea9U-j_ajcoR?qt?O~jCkd9k?Yv)t? zxlN~DYktD=96TR|zzNEiLTATF`!f9U@9kzT{4eygZ0Py_$UeXi) z;XAZ4a~*L6`4r`ndPM#*Q^)#E=u3=u=^8T6*R@c<#q}D#pUnDK zgWtD7-g&uy^7xu?DKPoI0EE+0#xvgWok9Go{T;Dt3jB3CF6S@`{!M8H`&8&VLpkE} z4B+o_g#Adu|8&&!`mNe-;)Qx={r7zx_-mSb#`tsGI*uX_@Y!c|j$;A3Vn4n35b<~V zpWB1}SO-=)R;7|^JIMsNj!I!0g#POdP_~L$d zD!zR3AjShZCVkx>Rg=LSukV!P{Y>je=sW|wj+h}{r`)c15fP_zHF>(=)wK06((U6V z{5tf};;8A+;rhSh{OJh-pKz~TK81WuW85xhckL~Z zy<@6z&j7zWXNcc*#81PLF8tgMRb>{U_GWzvPr8U)Pp5$=?KbOwY=(F~;9I~Gbi#j< zcaZzN*vYbfQqS40xkvqBZSGa#Z)$U|7C%#)`%d*QbGN8}nR}A@wYjfX|1$Rt>R;xb zpneTy@h@}VsQzW{b>d&5-(Czq!SS8~zwO_#BfpMjux;J`y zd_jEAE8*Lrm($?;O28l;uACvhr~Vu8RdnwaUw?nBn(UXjDBF5SiRH@U+>;f*NDq%+-%WgRP6JIz6`49-<$7_R{8@|z>pnJLVN{0tVcslpzuEh= zt@Nfn@^gkBO*smD<#|aCKh}FB>NR)kK2My#Eqo&#mlNNk{z~w5es~;OO+F)XGcbp< z5sv2unfDBc0I{s^4aNSM_aNN20B$weruFlD=$oXB@0#WPAC!8p*Lp{A)z}+a%YqMV?_cESU88!3AR0zV^&{c1ljfZ(_oVTm} zjG5f$=T2$ppPv@^$zsf_zcN_Jht?fCV zb9qa!Zvx+|6+YD}3#CHZ+AHO(exl@c()PHP8xPd-=!lm4W@~v&^8#7_?_@%7uXvU4 zhak(z?cK;^7chI>szoFlv9<4&3g#YPr&LfpSwaQ|_vsQVwNMfzB zLC^88yjteF{(W=rH{GT7wpO_oW9IzrMmcArR=FwR6rxtyDfzxyWjvwe*DCLk{UZ|? z6R)#Ti9OaT@00m;t@6BC)QDQ;y9t(iaKAg@3VE&af0JY7ev-VoR;xT7Us~exr&c%x zs8#+(R)lJm3+3F1TIJFTEmgYP@q1~7D|EHWD=VD3)hhp^LRJB9**RCMY^&6zd}HOo za&K2ok^6h(jnG=LTf#kR7X5y$a{R2b zS(wx1@zbP>(BJ%3FSgM6NcWfNLr__#^_OYVwpB^K}W}lCO^h{fNhs5*|^$`MY0#g+JUryZ#VP zAI<~td7InoYI1H)r(a&$Nv9_R4!&nDU2CGAGX7Hi6;fXjn0T>(MZ2Q@r-wSn zdp@e<<1zg{*7N~!ruds|hx+U2cgp%ny&#;cUq-uZ@q?Y8F;G#;PpAErY(L)FzVLs$ zKq2U3OUK2qZZbU95zd~;;AmcVI&jtyj-5Y({n29Qus=!Sgj%Hvi_72FO4-lzOWPV> z`MG}SsK!@*zMtDm%+sVj`S_#~UzquEz6hUn$Vrs**#4|i`pG6>b&B`!_|lwi zU!5l1gg-s}m&3n?J$hHEpNE8gd_Aws-)OJ@{=3ugeA^xgAI!h1#z@2IKr<0XFi`@508|NbGu zdr}UsR>JRLQ{dMN-tPAh-eYrk|JIzs-b@3(E$<_|hv)DXmf$hYceyRgQ!o79|9-+- zn8UlH1dsEFnZWy-FB9HLIlP@EcxTKI-hrVC z=WR0??;Ekfvzq*>f@TsAKD`8Q;SAx8-$r;p&Eef&dH%tzg!la%-u;!AxgQ|BZwkEV z@22ZdK8v}E`w_$`;!k{^Ky%Ns+`s&)wEoz^XZQ?W+y`@S{^cX+&;6_Cvv6+VA+|5i zBi+useV>lMy$l=T=+AkT{Z2Lch|np%a*O%a)Is>@u|1!LvQBAhy@LpVkclr$B zJ^1s4w=svetORf2OyT_l;k`=WMgE^vf;$s?80q{)@XaYSF7`?hRvUR-)CEfCHsWLK5f!+HF>n)tFukbhw&HYU6YV^ z#r$6K$kXA=yGhrsdE^}FaHjJ;tX;d7T!5BzNW zgnt?m#Bu##CGu>=yqj4L@MWPUR{eb4G(X>Iv91&3=Q}OZ^6AnH=Q}NsvhO3t``IdI z{Vs3LryocIyoWEp4>gu3oY70QexLO-c9FHWes(@r%Y)iaH91+}bn&CD_{jQ**@25F zZ+X5!*PV)SGs``5eNM*|j(`8N7>};Ar1^Msoh8l3WBV`j@n{}ssBZc>Xyfd+@%JfR zh8jvQyr(JnPG{VI(J^k#>lfp`Z~B&wDV%DuXWDo?q5}_GH_P>pyXEc+{S{6%*{*m@ zqF0P_R-p#v|4qobN4iPA<8o;(`_#SO>q_;+9-1B!&c1g>y%F;W`+>j?SGs$n$Z70H z+MAtV`@J3QRc{NsXZn!myG$SQe3$9NnCVr2N$=dQyPdan#%gkf;Mav$4}JN?OQOE$ zI`RFN8--I%E}1qS-|xUa#QQMhmF=0LJm)bhe$4^aW~;xf&3>@-SDXFZ zU(b@~r$J`<`?G&7>(H~$koD(CSMFCpp6WM*ZT4xhf4v5L7viUC@~^UvQaj=T!7KLT`&nn>eIK0fEx#9f`@~7>|MY6s@6-Br z?ikJ=n6&m@B)XR50mq4TrFSUfb z7)ZZ^VjtprnXmaDsNdB3Z2uOKH=EbmcZYBufV9K@8=)WgYUL3tt6j!AqLtO3VZWM{ z)z9L5YAf%z_8YCN@mp43Z{-8_yVB9^XCBAzF#2sZdf7ZQe!qqCr&xh6_;`<}d z`0zj7&fbqW{II9_`^tR2a^FkW@p*mZxBoM1+#&7xe91eX{Te=h$&r8m#jK(5`TPNE zU-$t&|K2}c`BeYDL7cx4Ptx^Kt2K|uy0rhi+}`;r?z3f1C>^?Od+8e$1YF;rVRLZ{1J%`7Uo0Y*GJg{lob?ynd}b zsLh!p`>E1lUC_gOkc#i{Ci&gpmrjRMD=R+furegG^XQ!pl!xW08TpNEz(U8z@Laa0 zfXUB~Bz+%!9rnbe%j5_Do#SNW5aF`S`sbj2thcySk7d?dgnG;ea|RRZZwvKVuMWIk za)b5{{Zu}kxE!@;XAW6;rIpQYow!QM>t4Iso*O?;e6f{{-zO@aa(OsW=?Hx`xJu`o zPo{s7evFS9CvcUB`c73N-e;V}eRA5*Kt=7q8;{IUs^7r&Ik?DnD(bW8-!$kJ@)xl^%Q6VK10UYhSSouhQj-r0#ut*m%uxqd6&*@>>- zIlgDm$*nLthW$ezx6DJ5L_x=c7%WspS<=UWiswJMt{K@3u1S23;5R8C{9YBdicw zvgO3n_-~TD2yxZ|+^?|vS+nOz{S|1>$}7;G_eVVk|KOTw7I__*^Ln638C@p{yNK6iNC^=UmZ?=k#{ zFY)km>eku0D5MXs>|DKH0iy9ywovhPzHr{V_qhs_H5nHy#GQHjZDYlA%E!X%RUSa@ zd&+(|+LHtP-T2CO`%xY?JL>)-wewO2j(8xu6@H$E`#BHdXgD5bNwBWNO~tr|*Xe*S zK10jSKeyvPpY`ukdVI6a6C`e{qy;d}-8J=%MrOH=VDT^_ipu=m9GH2g%muL|oWtoM-nNO!#E zJ_X$w)%K$M$?`m>`>@jenG_0K>rT=#>CQOZ^}L$=>Cko2By?S0qU+DD3-Y{3hL?C; z+1#Y%fr{qEI9{+q^n)5izTAWN7yNu>>d`mixf~|9Y={5yIE4O`?cIL4U17Zid~UxJ z{?7t@p07yCM?E`4J==_jxLE)ESJRKET;u#RmDjV0wZbJH+1czJa)y4s9`Ut!gLvVm z4t(js{CvagaSAVcoWjXoMQFu)^KR#AvyPYN!zvbn-;XljOC)gJrnlrpHts9z&UH5C zg{p!D>@@yn6Sr4v$8y=epW6JjjMsm!Rg@0iPc`|4{?5j@+&+k%E6K&)C>NzTEIm)h zPd@Um$PdO*gg0J-cPH|0dE8t#{^aqB@+m*R{RE|JgiHHLd`|}M{Jz`%68znuYnt1k zyJehdOYN4=gQ6WeNVypnGN^xtLyz(HVf;QI-U4(&pPhP+0dm|;Z6EU%tFOfK0Qbtx zg?*cNywzW1cQrE|^rL;e&HN(AyBq&^KSuffn=O#THBLXb$40+=o~q-IJ@;DtZghZ2LdbBetKOa%gf#`}CfxJMllTgZmt|iToA&9BvRe>FNavch1YTY%f&R zj##MWOE3Uj<^DLX=g9iyxWLW7pPuKR_nJIyx8FUFsd)4{Zz+z0@b`kHk*?b@PP`v$ z<9Lwbm+w{D1IWk2^a&u{e`z76fCn*0xG5Z901iYM7g zDsS%phfY$s)#T0cN2J#x;O%)@%I`AN;P^h?>ZI#_=1<$(g>JFlKGbWrjud?5eT@qJ zry78?NobHOh!Y;;y*d7?W!|%f!t-_MA^YB7I;8E=OLYDj@g*OK-!HN5kR7eEGYdd*6+EZ|HlPPFMdv;&AJr z(1qjU2z%}OU_2b<<-3O8dl17QpDyh$Ry3fG#|fNRpWi8sbSU#}A^IgD^!uWo`dt?| z&7tKA_lOfDzD$7=uk=zN#``4tJ#mfvEaM%%iF$Yc^n5D$SqTyh*!ptXTp%3}$lIvE z&+zqiU3||{=J`BsT;^ZA)*7cR*4KB}9q=5o16t z4>4wZghwDogxp@G;h~dIgq$9g77${6mB(PLpt(0`lOj4*Q3J!6`WTIfV|`~FM>CF( zjvt>B6rG?b-}9V^_%-XF+G(04ZZIs7wzwhm*w8|JBh zk5j+jG*{MM#KXR=la_>5(1-C2^rG-yC%)164&&5suMguD=m&bX{4&A;dXHaRzb`#8V>-pC3 ze!%mX-i7W>L3{_i)il3@evqmR)(K@_2%|{7j1t_d0uI>s(p-N7Jns17JW?pvE{Ewo z#RE*Y#Y-k{cbwb;JnHwM7d=!T=(~AX=mHEohP?6oeu|eS0njf#&U4GZV_3=~ALQHT z@HLY<9*-mbGv1!#sp0dtXDOEt_wROaJHxoRP2eCd)_(M8E=K;Th2PtHFnte9;CA(k zO~N;~ex@%k<-vz9z8(Fe#ODj~vxABt|HZ??55O)z-@gxjTKNmKJQZht?sfR-uciv< z=ie-Xv2m&Oht{u}e}~`a>N*xcgnCpA-FR z+Q#r2z5jE~t?+uV=aV^g^=6M_hv37DH#zbopN5~sr>@;U!TV}t-rw6HdTeo##Uqe+ z&&Nam4g9a6{aGH-kDu9rmsWn}Cd7XDHWj?zt+2|&_8H`*yj#yete!JaPp$CX^Qo;j0Ka)uFc1T%Y21+c z>NPsy-=ImL_a`4Im&fD~qv7{oCAnDrwhk2N#j-A`Pxa_1cz zfd05h-y7b}>Ys~TO6s=^@0gUsy0)uVmD=%Dw;i`hIq1vQm>lmQIodpq@!Q(#@@10n zW$TDR^uxH2#1o9GEbayV@fiLm@O?z07e9C0$@FXd4ZeTxdU~(@)#NRjU+KpChiI;I zzIk7>dv9FrWV4pPT2j!pJ4V-A(QbY3jfubT`x>}_^?xWg9V_=1D(Cl!-e*#Jzy7IO z-*K9XIR))8e}Z;=l!rQ6woXHRQwq8&3l1BFm z$!~FA;KxY+@k9P=yiopt2dTWZ(_7NP`3&|~MqzJ>*j@NO3jd}1J?|Kin|HLx_c&_j z(bR&;v$z?lXRnfU@=Qt5-mech?fo5pqKuOoW_U7*M8 z#q7ktMG(dH%=Ez4`zD3la6Ve??>Iu*OnAL@Tz$&s+3owBZojsd^c->;B{`XYaOpf7 zcCG81etjDw4EAf)uT@y>tUgA!&cB*npq|x)FK9YJjJ2v3cD`@@F_++Vf0C>)*fTz;B(=_S9 zXDQ5pMq|GZNCF*C97S{%g+Ay7{H<4-WqY;cXd4@ z4A!-EKNs{JKbr^emT5lyu8?;a5kx<~RqN4pTfbf7y`}t`;yi{N@_&CdOl63y~uY}Hr z{z~Zl^j`^`!+#}ozWc9)&TIcl=*<6>(D|yr5;|Y>S3>8}e@;3zF1PO+`Avh;Ppw3+ z6~;vvr&Gwz-xtYI2Z#RnH0qbLyxTb%mkiN!xBnj0{`;3}DGnZ!`G#8+V6*$k1~K=jQzf6Q>cHoAAC`EOZ34%VW^6B{rE0wXPke!KeU{Gy~@9y zdHWmetO4FNzX!j{^=(&-Up>mNH@^)1%r3@jeDX>nCs*Hgc>CAStatc?cA}|aKXV_~ z=k3&b#^@#eF#p>ZqjNW4r=M9%`OwbK690_8O8t!G`y}Pt|9)ni>7(yYa9T-E!C~kr z_Q`^tzn@1><9tWIiTurHLQkdrwqIwVe&)-x@7CsL7Ne&x+7#-k@!#xpG5QL=Ltl-L z@7gbYm3H|}qF0spN1|r_HBbtEoVZ9o34S8~`5Yfj$MkkaDr zkD)(-_h%m>zHV%0I$Zp;+!gd+w*LYAvvNP8axR@+$gkriZ%pvH`KM#~*?w;jdce2% zd4~sRW2&_e`@692YyGg>F{aL>B2=lF=_k4IGKV{f&o#50{KkB#d5?Jlr?-oB;(EB$0Zn1yAUHq=! zDtHP_g5PZ~G{tSN>Br2QrJZoW=6@~zKzk;sJwbf7A9~$DexQpl=*EZks$RDG6-9q){i-XLsN_w4xo;i9=*J)JTzr2O@x}NE9^?DcKH@>)f z-AjA}pKgrl>00Cu^jh#izbyaTWBJi8cOOVxuP|F5Lipu?^AEfKwz zxh6YTvyfh2wt!w+yk+`h_LeW%zIw51Z{#l3^G4NknSb%y8&uEVBk#NGIW6R*y?(bo zZ`b^-f~U|V_+7a&AC(`F%V{*;F}VSL(*f%9CgNiyecsCYEcYzgIUg^$PjKr#_1WT& zrI5cfE*PTvY+qEM&yN0bf4Y;DkA4S{7+(|9=MH*~_BOLV50vTi9Q0Gi8LmECx#MH{ zIgI>)J_|nRmE~U*&%Y0S&agg9e6f%|$Nd)QaO+)OQJ=>}kMz7=B|m-WBJ??o6C|F_ zmmU1N|3#&_m1r z#aMo{YaxHW{dV+MyO}?s{x5|&N5=Va{RbUxz4uYQ<#EcC%43dGw;dLz+)I9O-*Jk> z6$PCa@J2M=(EY&P=)+Qvo|Eyme@S57KU~mpqu;I1+ckfy;3+f-{)P12^y6z+g>g!t z?~Y#IL+v?`IAtyIvyxtam+ZtVirvyZhTN{Qczgl9w)pD8m|jEg>^`GT{yJh*&!+KS z_oLW86i@e`g!@|th0i(hLwqNM+_fnEe1!2l9pdQg_Mx8_9;kkjAFrgJn?*m_ zuh~7Dq@N0RaBBObDvb}flAgiu{@@AnQ%>B`MfF)cSjq1WQ90M|o(T9>7Aubrd+1N# zUCDm8rOfa0I#dO}Yvpn=KiWg|gnn1>!T(wQ<+1!|*Ft{xcl6!Dd~lB3#)su`blmTP z4!7P+#P3=hJ+x1~{v*v_%;$G4jyC`H7eDvvj3eUhH+{)f((@t-oqia9AZ~^He@FWP z-MHg-)b0cE&%jqn|5vj9539Zh_YEkl_YExIpAkQU&PQYVk8xgJ&pQYD@5CA1&@U$r zzc;4;uOdDG@8>^=xI^N9*S-!#{tEhU~>rm$LlaemFiq0y^A!w^P04amTKG>i^vf=zlmrBJo0@N%|RYMB;A0Rr(okRO9Y; zjl;KV+}+(J{XtIJ=XdM#c8k+3ei!_1d*k|U`tjhEVccQkTazE;{GkKXYs7Jt^!m%x zPlV?vTev+mKcakX7I*=@MqCWK>SJ+73q8;4`d}r!-UhvN^!j1Ij$dz7y}pd~x}NE9 z^|}xFE9kYAyELY!h`U0)7JSez%m2Dqeza>LzkV9)^%T<;k6&Cl$MqU?xb?P2^xFLT z9_9a>wA=A_b5tJuK63%RHotEA6V8wPl<^gG-N+k}c-YQedZQX|>-kG>yT;GmLsCx9 zoB7@Pyj}CR3Z6of;CJQ9d{jRVx_|lBP;P+FI6!^IxV(}+U&Zat~0)2M$cNg@<@!OXGcJ#ST_4!cN=b^GVWeM_E&}S=`iRtHVq9@d6!3Vvv z{7()={W{vUkUswhU1(zc&_eoLN9}Os3p(6-XQ|%MPn$mP+fVNu*q=CMDfb`w(qG7L zJ91_|I{JJg?I$$3L7#s??KqIQV=eKql0GkEeQs0z?c(%6;_gR&Pjvnn;_gq9y#0+5 zC%gFf6?cC$rk_0#eHMJss~)wR?Xmob4;RwsTUejBvfm2zS@g#B&vAVQ9d5mMM)cXn zlj08-n!kSE0{R@r9TG46+3%N8eMP(+Z!h==z5Un~VccQk0avfzbAWoC`a@;C{w(=@ zuUPj77&3ill2fmkQh15L3;1dH9nifurq}gUAI;;jomBGEte1|Tejnl%$4@sCkAU|g z*6X?7gFaWUyU;IG@Y7bVBc`VfL{I3a1t0Xw^0&wGqg@N>^$D!k(!Nly_dT8j9d5m+ zMfBSI^pyIU`QwfkETGpGcbNW!4E_di;JNyEc94sHEpbP$lEZUg8tve>%0(M+DaWDBgC7H~sG2Qcl0q z;CJiucFo@^cnVE|-;H0G{ydY#d~3QE`@sH<@!5X#{K}YIk5##zE9D?p@EiMq=+D%e zbMb#_CxU4*NbBO-!Hi?i^+AF&>xo@^yGv4C8ysoU!D$f`Ynwk zGAX$?+vHTKeMi$8O1Q5~{93pVYF6az#CNmM=e)=b{t^*Dq9eHfp-8o-X>|&Ag95-p(pil0YA5v zpL;LvVAwmUO`kW*^HbOA^A>&HE6?qIm|Tm(!aqOPsBnYk?-1C|vFm*}er}WItJ8d4 z3NuJ?MvuTJcku&PUp7&{PUlVdJ@|Yk1xESerYDfGGkqreD}Unvzjxz-4)pID51`!2 z-srfC@ouS?awgXeLJ#tv?9>zb$(IX#PP`tkXL*HsCf5mG*AK6*i2ucczbN_Pzd)x~ zQvQvpTpc=(bntlN!iSLFGb-Y(ywY=v(jTMC@PJ>uFJ@fnCNU3!Zk1Cu zEp&LB#m?w^QW8h%emK9WN8lT&ApPjO!~)+W_~?6h4AZ^}mb>4yRnpc$N!vvq?7MaO z(p~(#(4_T@+@blkp3(PcIjv{=O#*jIJ%ya$^SkwVyXJ2dJcTB~@7gKkWcp^`RSM~l z@5Xrn9nBoSdI25sT{kbFqk-QaC>^v;$9fI9oJIcF{6t94UzjhOMUI)2#1r$`sm0fB zJp8YBM(wr%;|g7Wck_KGmXGD3b_YJB-tX$;QYPrnt&eg2aOJXu`$<|nqMv(@7WioTTk^^L>)?c{@Z8Xq}ezp;PY#wm8T2vy8{_YiB!rM!gTw z{C9Xy6rx1xf76`s|Bj;n+dauHUiM#O(vO(jfbWiO#G&TL^X$hxm8)AG`$3TZfk^#( zIX-afKbz{eI69Nkd#sCdJWk1`FJ~IPqVzMs*GcATQ@-JBbFe+ifOx76`_ z+7H0#i>Uo`sMo&B>G;1sj2BB>jQ9KY0#-Xf{lCF{Yf;}5o+ZR@Z-@GKM{obwhd5~o z`vX5Ga-{DJDXe^T@T6jL`z@DGY5pZb|IRvw-TG%ACwguWdO+W%*U5MQArr+X>>t7J z)vpW3AGBXx{N}cCPKi#&@8^aU7W&L@n;z2l3Hd$78}Rt_eL{wTzt_1(li~)&GpBf` z6rNRhH^Xi_*nUQpuM{7;e!$z&!R00k@*ek&&_A}T6UjgH7sdZ))6e4!M6dQc|HAs_ zmBerQOYG`N`KSs{jttdCPhx2*k(`EU0Bfn$E zuxpe%;&o&nRXT4#ctNP2Tf*i2rg3hcOZWS!9N7gwhu(`_4KiGASDS=CTLvWEsCu|f z`|YCHmFQn+N1}h_b|iXD-wzS`azl)l=HnFJs<6moL+<@NZ{z8>h`xudFg2XpIis+~ zYq@EK`8Dxj55sQzVTa(`bFPIyGrzx<3wR@SOowOpXPzv0Jxr?5&u^V&e01Niq`4I9 zk&Azp_zQV7P=3^Nb077qIFw31eAgKAv3qOi`{i68@~tO*1OM=|e)K59gWsBU@(21= z{QOptuQwv8eTT}M5C)yUyh-R~dPY_LXV~~a$IE9@M*7+P*WOvG zZ+1T7Y<^ASUR%dnczoctm&Yq5DUb6wrl0@50e*OrUw9+q%>Vi1=*sT_8f)TwFI0}! zUCQ(m{++(ZT=pD%^mD0MREYagp^6k|FznL1iSoJMp=J4RN2yS6F|S2UVLe#;7LKpD zzHmIZQt}r$5j`WkkjKX<9)Uc65YwAR#m90|y9xG@?NB__Xx48>KlUKr$;*4-Kb81% zpnOS!AJ2{O<1vmmsh?&3&^VD(8lQ3MxAq7;`W}JXy9C~Tlfc~_oYMGAVSV1N`CA1K zjT8C3E5|auQ~tk?^e&Q5pZl>m(e(6i?oVmboPO|M^pE_m#9=NT=#9l==I7k_3;N>5 zU%MSUwfGBqG1C~@FXb<5R~^?Q{3x@Rn4P(LQQS=WTSO~lo_`nm+jRm%Z=O$6LUb-$ z`iJ7Kz#md|5&dc=K6yLEuiE{H-dKy2)BfHY75`jDUp}nw*`%kF;{xM;)(+G|G~(yl z`(g0M&UlIKlge_w+av}3&x-l&nV4Tc1n+lBew^Q6yS`Omi^pC6{y%rb_=R}~ZJ(R( z*Rg!?Gsf4++XX-T1-drS`AHh@hR}dZVWc++Hv6_EQAzUczaTcC{*ISJsY+dD`(zdQSHOaGcSZKDi5x#Q1}9nk$%EN|-{ywX;I zn?&v|o#qFge`-{3F%O(gtx$RfxV-y4!Aq!LHa&(PxtjU+oiaWc{twc7w_da77qb7^ z!sVXo_&JmMN2y=!3v^wIdL4U=%Z2A99ecEW1ZSvyk%>`1+cpbE*!&Tl=VmzUm)Gih ziTnLri^2^mhh~MF6>d~m`Z+(>pm3wUuUEKU;Ux-hQdr_loA=yJ1lY%j0^m2Z9-41zRzkXNb{*uUc^ZH-6e4FT~c{(_tRSb zBX5;~eY`$v7yMC2%pZ;8dzR>==x6IJUPvR*qWQ?Yro1{+mC*T#KQZY zm~YFp9F&=U7g35Qoz*8W>>t;_shtD$^*&{-c~qL; zwSL)qJK0&0v$Ox8ZCN}nSWEG@tv`Ar&5YOX9e?&_$sgE{eiz>C#~TqkI;(2A{y3e! z?n4adJ52D|_aqFDze=84{!HqZLPvuO|`+V{mh{m!v{U(O5e z4VvQidZVIGc7M6qk#F~u+r8!Xy^5051AAq9^8$m;AN0Y$l*hHuAG_xykc)(W;l3P& zU3~$5;60V5G(5fkDB#1$G}GT%Eso0O1A~1t2rlU7EfsyWI0pJM zgT^@5C0lg{ds(QNuIp2Y{^kG1LvJN{6PqIP27bsJT@&d31znV6aZ-5BTKbVn@;#B{n?3k=ri1qXvpmqZU*?d7`W@_^7P!+wN1WHS&tmK4S^pqI|m~nX{*?4@LkKC=y|*zcii_Y_9y?Tc-uI&eq!pANzc zKawK?czq;>e<$mq^nbq6ZR03AKjz|_A$*`~3yotksRx*Ut{%bSGbve@1|C=t+SMDY z_r06N4hY?olQj2=pWiO)h4g)Fo~M}}| zcR-IwC-HOVEmzzY?Z;a%A9_Q1zNN8zad|zDXrB!IMpk;fC^CBwx3PelM1< zbk73w0e13g@`K*kFvGYPwv9-!@haXQLH2F^K$#vod;>qcox*RM???G#w_v_d&vR%! z;k@Dd$up3>U(qOX*&uwt_~;nWQB;_6fsfvp*lRF9yrVbsx5S84Ty^_<4< zU3`s@pJPXt(7HUGe`b8P-bk>{t2fB=Vza{aQm;c_J>f(Bow~k{sRNr|hF^^CW0LuJ z+E>MR$geP7uPF79-(VPi6A>ou>tPspqWhJ4tQ@DoylJss;qrM?)<;KfJw!M391;KI zHOwaF;euu!_;+N?A>Gv3H1(GSz_Y7!LvvNbQ~9gyaqY@9&zu`2g@`Y|0J zOs)k0%CPA*#!+m~MZtr(W=7?W=fLaVno3>Xzm+ot=kNN- ziP4X~Gb(cK-=^@C!lFR5??&Nqeg8d$fgR=Bm~UQxhr%5SOGi)hcLEpdI3>MTIHho} z!gGw5`cH+I==%YM>lNOlaD&2woaXyywEiU`r-509y`s=d=M=Quzi2%z3V&JQW`+Ay zZW3=&Jf`p->F7#5w*JiF^Dl67Tq1%Hy3D?CTg2Jm?p=zqa*(Sbs3- z^aI}{hn6qO`Qfl1_%}x6wy%!t!P#gyu659g!r45*%UDJ*^~ z*l*Wg&-@7X+w~IzxSkow-;Y`$ziEXTBzO4)r`FUq}j zy{s3ZX7jhAT zZir#%M|6LT@Db0G+8@LICeLIuA7AqJsQmWgT+_Pn{nyS%KRnBNMd!^p1s|zdfu92W zFyhMFrJOe=e$n>ZFJ@oNy%a~eae4>vZx(#6z3zGkJs*?j@L%As#jm!$1A0D+d_~Pi z{F`OH>I8zhDQYoCSiWY^r~I@y+1(fO z+RNd$npxjF)BjYqAH?kJEi|9*wg-L@bbS$gH$C5>?V;ca@2wwk`7#*e3)Vuhj!WTEc&C;{&x~_g*aIHiG1k-#uKhLWU!H|0mMxl5h?2uGz=c%-1&yJtH%$Pi~wQu?J@y_*#tL$d6#9q0;_Q z#3M=Wt7UtN#ry8Q+VA$lA8cazg>lSEZdZg4q|dPbv&jCTM+@((m3}Z7kH!6j6K}=$ z)qV|ePKEu(i{Z;+_SNo-AD@cwW0$UP%6jJ0VPEYk(z{A>SweDgpPQcEOV2YYiNl^w z`xp<2wZrKBNUR;ZRPP@9JMwGeTiMQn_-@BqhHZaisK0B)F14TXZi82&{SRcn_{-(f z6!j07H=c{l8_yCQbe}EbxBbC%-b7)smxboTC!Br<^WjT&QKzpz*wI&dsb3;Hf=l+s zCK&Gq-M2vN+6)KwQE>llpV<>zUNaj6Yv`s{1MrtiQ5268!ksn_+(irjPa?3Y~|qWcvIoWIXB>dsGhd z%-1;m59YIMeb?eUZ&b!RsP6;McIWGD-x?`6{h)7Hax92Dpgu@C#{aE2#pTl=@yXUn z(2l<)d(Wg!FYk}lA6!lET|G1Z@hsTwJbogRdOPdcxs$H_b`&ZSC+W7CIXw4@Qm>b9ndN-B zS$Uqf^_)3{Z9ON&<-NSlYvg1fq?gzEjoe<%FM4F>_q@w>-oxpK>oA_kqgK)jQV;C! zw0nlouA28p{p65yj=}OH-;?i)<^zAcG2yE_j#@+W=Ej$7x&hUu!t?44Vjsc%3H1U8 z_a`h7_$Dq!a;syQ_M1w4*(C9)-zxJLe!KABl?&*~@K<7~-j(%?i1wEX-eajD^z*y5 z-c>p;(W>`Nh?Ot5HuAV=S{lTlGzHNI%UPYB#QRQ1yJt(UDiz;V5kL(pipWJxU zm8ZLI)I~KxP7lT8G=+23>!e+fr{(+SSiV7$ySGF1*75`2*))y}#@l+22ki@G{dDbR zfXe$#)7(y!dkK|;AHtLe&BwC*5Kl(eFM36;Hcz!t_>6Lp49%worH}bGDttJI=JeRUl`pivi_76$HN9d!-bi}fuk*>-v~1v@bsW{l-$_4L620=9 zekJgT=#}64bAd-iul)8Oso%H!me1acp1XPsdQJY|=YPPmJfEp!mwx)x0s` zKheqU=`S9v^iHu{-12O{CDAwFc?++1i9LBcMeo8mOY9_G-lZ3M=IQxT;QNQ0vCbg) zvgxH7U)#7+?Qz7$m1>W{xKizLyNxS_KL!2XlHaY*+jSh;DtHP_g5RZ!<*f5Bnbh~B zUnr^`ke&%2#82D)aM1rshaVvybRX?J{uSk(cWDJbSyDe)kb05tB^B{wS5LJ3gYd_? zuIt+6-x03xy!oMA&K>ttctHKW>@y0-^Rud_#&?-_3&-;^zV!mW%lt_uwTJoEUzGa> zvuRj~%+v56_?!OopCeEvbx%b;yK+H4*`@I@QkV7x?1W7zK_xP&iLi+=w*BGcJ^`VmhVzK8l(J(qe&&$Zy}}mYPK6+@8faH zT}Sb`?ZXKDTo?1V+|Nmz?{8}nKX64er=g#dxDMr_ey%~}rT2f(I+(&;+z#@O3X6Sj z$XzFJFdx51VPXikXG&qQXIht2m|s(SCm43y3Hty)Urgs+tY7a;pTz|xZJlT z{tM1~UdQA`#ILWG)!zr_;?>^==i=4hpDpDU9rqQrUDTc-vPajynBM-L_M?U8;@67& z=JDTd9Q%F5FEo^=kRau6lX0r6x48e*zI*CE$2^9Ovu*vz-&j80!+fQM1L6kg!PhAMgq#+^Qa-zsqb`L(=`mXC2o`-xz%}0D3iuwEF@ZMQRWd8I^e&Yj=tLYKiy`22M zi;wTy()PLeo*l~vKjW1&?os}@>wn*P6a0m&gH$>fZ+iEum_C}Go<+~;JU817&98Av z=a$v3WdA3vtEgSc{!iL(EAaOFIQ6@?a+;)Ft&Q20wd1?po%Dj9!}zRGwtr~Oq?=OuF5pA}`?8O%2X;~%My#&bFzlXA50Mq$D0 z6?HtQ<6gSYT;Ge`W>T{MCSSTw{oGbgy^(vxkF^d8JUS|H`zC?6-z9MO0H=!`M`cpq z;rc^5#7|N@E^)D)|I_&k+fN?)CGoR>Yf0bjyT5V1yZtuo)5hbF!>V6a8W%i|4T{d$ zFdh9%k7qcW?%*_z-z!Nz;5+#-$W{2+nU?){u7803n;&xLSL|H$hu;&mSN0QbJV$Ls zJs+fe#)m>q?%`aBuH6OrMbiVB_wYu9&TRFO(%uo(FPpC#RsFMhvL-1<=dVRi+f`p% zC7;V@)_0v>0=?h80``6s*AtEx4{V%H_rbBr={n6i9Y0P(QQXSnD0FQfRu#mijLee15y$i`X>F z`6i#E^_iNtsx(7k~rDMcjm((vb9U<_D`GMsEkE)+&Ka}D9onN>1Wm0!*{ZFl5GkmzmyeqbT z`4RN@0e__3*;F6b+rLuuJ)5S<3Hs%W6RdBYbe|2mVY2)0Fid_#^s@M{!m78$FDa~g zTYOMq(OcVR8rNUQsoU!}><${B1JN z=WmpGH@f#w`BEqGL~%gj6vOD}-~q_*@N|EgvhBs`K`98Pa zB{Xia{=clh9}_=mehl({5!qKbk9-m{0QA@|Lw|TB(K~;cJPqQ6qWGIaZdT|kiNB%q zlLC*3zoGHBz@zGK+NT*V=y#s{cAd{})%pA;ozKt7e11~%*o%#O%lM{t2Y&6k9QKwH zy~qnc@ccUXDTQHA=y~z{n%MJZecn&c52}^#&s#ap8(arh9~cdCEXPx+g+m z?RRY+SLjE; z?C?g`iXG0=54&sV}KK?bDF)h0Et=_M0+a;ywpIEp9h`^|$Tke6HyORZgO0 zI~XbK-+b;;@(Ymb!t=SJ-@$xtoG&BL7Fv_1PIiLY>-Ga5M8AK4d`W^In5Q7(@!@a`~m#L0Lia>9!mBV#PgeAu*koQIuGboOdwS0w`(3gX@UM3Z`A5fp^L&ljBiVt?>l9-7 zIG$f8_5wV`pOYUZkkFF1~5tRG+}t=2s(L?%;lj=8HMSbM&XKzdZ?l!_GC0>pX{uf%f~(x2`c5=+{#6 z*KYiRc~ish&aY$#==r#|hx$L(o6Q2d{o@kkbL?b@=flG|=TN+N<~f)zw<;djp6C(U z`}n(}eByNtZJ!$#Jr>J{{x-O;QTgMpYuvZaUDuF%&0M-c7wZ2u@z;HB{<;x-*Eo>Y zg<1cePU{=T#QGU)&;9eX=UHfv_CNHU!7_WYb{`xoZ+N#m<*on9q}GU^Rr&Vsd@q4%6vR;{flC1HAJRkiT z$$ipt>C+3$1CYQ z+T$~S$GM*MB;N*lex0VcPlo;s#&IlYh=zXR2Bsqy+q;ic|7j-96DiluzPUQok#3dx`~9;hTImGQ-5)m^=(7$-6A(zM_4BI zRp}g29q|Qrv^F+Ry&irv_}-Q3X|Yb})^*cmR5|?uzp3jQ;Ojq7eChhZY3c_%^}DX_ zzVc&9@4!cl9BjVE?j?5RXZpLw@r$VEd91f%vJPPL$xtf#;e9pn$*u2j%5U>5nbe1* zUpP+k+x?Sny~Eo7-t_|X)5F|vbf(qLcaE0zPss1aPlM|bmr6PKMf`&ED@7?^$Q{Ob z^2H*jh1?QO$v<;S>si{q358Rf_Um`NH{|Lh|M)nkar#|)u8q(m_UV!oU^t|^QQq&|H{G9TB>m9#QNPCJvT0IW z`q_M=`Ek1+*x#n>j74b|<}oop==uSC2L$%jLs`)72M5WXx3n<+h4}b+S}!S=E4&EF zdtBtWQ2F~K<)vIDInu;90I#@+^aJ@Wt6vcKEx7wcWiFCs^+Kkzk2f3rSaMRL+t$WQ;sZ%#0NIWY}qPy>d0{~?Q1|B4Lmp}II$zF7xmrC{%fz`FU@l5A18F%J`Cg2~BW^ugxgLp2OfKLHSmHN{d}w~2@ww%e zP&wC*%uh~VLv~th5WUI?z0}_+Ec8;pqOi~z#{)XhAAoOjnBP~?+I^99Z!^ABzDC-@f7`&YBxPYeFi45wv!ul&r`y@d6yv+f!D)bB@6aP|9m zE=S`DmIL^_g!H?-y<`;hbNMU!mb6|EmGNzg^;-N!px4xH*6RxT410^~A=>p0*5_H( zSJP*)BeOr+x3y?}{;;DLHXj-G^L>nm=Ho=aa{~$szvwCG zbn1CGx4qNUUa#~?uHWu^_DT;ZEb{eAUr<>1?v)-=c#i4!mdSWBxX)u5ycV^iX%D~8 zFFk@`nimjwO!(1X{Dk1q`;PopX*aDCDqqG0zsB?A&lNVk8&cTxZY#sIpPth~ZnwS{ zI;dY$c#2cohn77UT#ef2IPnGY-bUlcke@mavQhYNeD!vUo&|AOk!ZC&m*`bz-Ln{x-S=O}&1v~fnos3X98g&JV)sSczD?Ti!1|QYeRHn- zCzQUo6MdP~PX&+am7CA{wE@a!e%yUON_bqmvGH0jwE%p)n(W5nn}XgGpD!+9`4?7* z{^W}i{})!^lpFF-G2Q-(!xT=5zN}cK@SMK?8;0pzC%@mY;&}|`iyD`gn)$gmvRm?> zD)CHVH92$o6;{Z8tNvo6mj7FRPW`pkcbdWt3ZKQW#oLIdUqw&c_Jd#W8&}bDwEsMA zzu57H6}!1S`6;HSu;M|52N~Y5;vW^>s_+8}4=H@V!ovzrC_FCuq2KKYzV|XJcHwOo zy)9h0m-GAQd|uL1zbfhKZ%Vr2UpXaztoX!k@*`qT{+-LI#l*LpmvHKhioW{i&_$DY zel2$|slusG0Hp5&JSORiM>q}oi4{jk`J(8pzv38$MX&u8Cor5>e^6L)3d8V=_}M+= zw7$V~X4CB~A6GAX$bW+-r({t&FWAMvXFXeQ@8JzHX5EXk8`h+HCQh(6;<~a3R_Xr%n zr(f^;rgPeoPruV)-|ukslG~S;`p~{}-vqmV20w7;2X1U4`gpd5_@w#WeYTJHfIjq2 zGH!s!5AFf)=f|w~hY;Uw-;3SfJt@PR)Z~jLADzQwJ)V^9^mMO)-G|U2&vm{U^zM2C z=%U3K`uQ8X_`SDT*4={pL~qgi5{iN!{MfbIccOjL7-a=z&9)tA|{>HU} zPv=>K`A~6lL{|^f<+t`q+SFG@XAj}WxEnn(>OYEjW8>aqDb59dY`+feqvZOKFZG6S z{=(+jgZ*S11tuN?k;^@SwoVjtIE>ATs( zMBh`{S9arDgXce*&gzj2)PfbJO(_=@2&eFgs(vyW^O^kzir!#*vR z`*yAW21yYYkmy+cKez<*44asb;W}aiXLR|1c7X0SnjhWwJ~Gi)Tj#a)#WMYN=v)gv zlMUjBdcHw_8((N2`-1$aw0~?tJ`nHmbNO(8gb!cW{bP4AU;dK!`Nj1O?EpWHCw;3V zj};^jPy27vM>ikjkMg@HU%uGDd<^A$r0@amivBC)YPh`?_ioVn1iNRspz}EWMd^1o zTDq@N5nyp&%+cSTl`A6p&y3+*}RhJh3Nxe zRAKYg@C(uN;-U|D9z8EEa&_A^!2V6->$Z#ar=;{yWz5gKz-ZSTHQB|pDHea++(!CV z8f3pp=TJCBIciqK-`qm{uzuFNQSb-x_o(#KZatuj&PfFL))P(c{-zG#zg6(K^WRs} zx{%vG_EXv(w|~D3`HI@^bSl+A_}u<|9o~=Ydx|rdFPpVKwKun)f9*S?d_ufnahjX2 zJ(h2n@_8j`r`^{Aze!yS>(wEbg!9yu&WVFA@ca1Kx*GV0=kH)WoMFAommcJl?hWSD z8@Z2D`W~*pqxTBjJ}B^ZnGdD!;WAv%`(gan@?FV7llb!pU%>}QzaS6L z<;U#Q+OcGwcDxDtqkfp;b*9I)w^Qjo?1jg#I{wV0-ce@X#+TPqewR+G|9_l%%-_@Z zOQpTt9a1mpJbr#_i@>WD*7)7UJ4o%XG+uo#`3w4P5tsMYOL=dH@_nbs!^H#pb@lw6 zR37c6sbumG156+MK=l5$KB0S?`nxN{-=Q3-G?i-$%0fxcIM=9@f8Ry}w8IW&F_>hGGkY6EiThX43!TNgn7mb=fp z9?!3=`Qq2fe+K!V(f6iL;Q4=k^KCD;`B9f&yq|F$a*$nWd<{CjOH+W}_CDeJXs^hx zDEZ)znQlj4XV8vU(!QiG6f--p=Abx(8m`bGzX4@{-n*AE|$>GcVCD^D8!Q<+t1XjLx(4 zN;y}q%nyri6|ejKpxe$X_j`V>QTU+z$9|li*nXT#Xg-*mqO(~bJJLQjf44AXu%mM_gGD7=SZ zSKszfJ;C@PZT)@uK62J4<)>FtKC$LgePiNZT>pRG8{q$Er2ZXkTz?o}9>WcD=>Q)= z|N5AJLw|(l4^o^P_(@q-qWQm*84tCW>+y5XlKS*J*nU&3!1~=>zx7W{hc_zz!*Bnc z@ZbEzsERG&zAze2XVUUA>eU-FZvI7 z2g9NlbUz9s%$J^E`sv;wp?gHWlTGIywH=R0yW6J)-mdE>-Fp}=*t~4FK5y6jt%9e} zB>3I-v78+`?~b+43g7$5QJvTn};knum^1YMbAl^-|-}=lYPp#kj zIFbF)sP5P}rwLZ0e>)+q@=jpdRn%{Kwe!hO|aoXQycKmecx8AbIerq7sZ{33U zbWHse1z)gZvpbuwbo-fyZ(Llz^_5t@Vc@OMZ+#(_FWzt64?TGr^jkj7LmWuIwKeA7 ztl#<>jTfGd{nk(NBqzsDn?L>>(QEn+fBbEXcbxvj+1oV z#BY*#%G2+T`%Mxb**P6LkH>gi|Jeb%C;IRM-S49MJiRyGyH%e5IqSOx^%dusZ#K@O z`@|Gh`il}rEtdXC3^wWK@|E``I^&%g8;}SPN;(hSrr;uZC@BS{4L*DKW z8fO@O0>2Hq&!}L0F3NMnmx$Nhd3@%(`dieqiTNOLerLLq3wk@IMP3e`6ydRbb2i_D z^4XVBd-GBs;3cpZg;9S4y~6Wjp#RSEHhunaYNtKNI#3&xLB9f4qFn04C_g8ZKi{G_ z6YcMzEGTFBPr|viT6#!7cV3J6uvwp9Eh+F<;k#o_Kgax0eYbuN`Tp1!(qE~+dW3jt z?LfPmQNPyX_LIM$e4v|1#(XF9+4f`jSE#*>h&_k*84JDM3q-;ER?$zhJ732kX7A5l zCi!Wfg2-`)z_{lF{42A=yu3#{FNp1{#e9(~@5{SLFGr`?PH2A;rD*FH`EZXo@${hz?|&#pgTE!ZZXBdHhMpQ7WkywGF& zC%nAMRo6+#?zte1$A!=91rN>v4bY!1J#!=<=vN~>2OS?G{qlMNQNDGY@VTjGz(s|r zy$z%Xu3p|j<@)m_&S3j4ZNH$uMdVETiiDn`jwj7uZWMi>^Ct4X(8qYZH}-Pczg{Z# zF7FZevSCg;Yh_?={UXNu)D#-0O9uu0!91s@{g<6D%A~}=dEV^uaNY-g09$mx2Wnmz zN2wf4A88(%?IK&1VLC3Ndgx!O)6S&`xx62;neYJLbI4Cwe{Fd3CFwsptA4?F`b#oj zo2~j8!+yKivEM5C1bX{p^yVn1(d){G{m=-b;eA$+v+Ivu)P4ixnB@lKOIIuKvHGiw%DKrWGxL>3Fo7^7ocS{fa#w6p5 zw*&9bc^T>1xac+H3ybu19l+#m-{qq7G>pgFDfqK>HQY`Y?nDJ}isk{m(OIS^ zTO)cG&+nDwJ@P+6<1fqajfmZ4t3~hQ<=p*$zePFCACxbNA2EH8mq&fSs!*=8_6}}W zwpu1!vvs!#TqBC)&Y$i@d-MD{1^xPgbDjwJoBl)W5%wMKa~8j1{h+(K{wC_XnY5rEhQ)m+WZa)Tj zxc%5CE=51~3odW-1=;E=nO}D9bMhnx*$+fTzA(huENsqr-AcL~0G zr!eBrWvzcCh5U}6-GleqFZkPZUz>Cz9QT|@`TdQup90^zo(BG%LjOTT zXCvaCTLm^cP!GP>=h8n%`!(p^CEiD2`wQ&c{iFtNDE9}tH-h%(bG~qW=@ndoOEp@=Vwtfoqtw4L6 zew^u}viNx=(Ff#PihT3P-QkLN$YFZ~zI@Hm9y%fL>TTz?Ty*C3sBrRP_bV8);rMlag^(7>BnB zAA&f1t-zxehl}40f{q-~7q?eDe`ajn6?TK?htP8yZ%w{PxIZc4 znD-nE${kFm+^^^9FfPKcfBavWez*Q<=#ArtzD4%ojc8n_<+IeU;TN9o+bw)5&2k!? zml>6QnZ|qayj9{szg_UrJ+$&%&w*z6RE3Mz&IuUaFH1cmTCVkT0*@-b_RmD{1^D&* zGQNIS#?=>Yui7X0bonJAfBh}vj4ykT>~A!?_jby2LyM(u2))a47?jrK37|K(>nexfA&bn_$5#=e#Y!h`%L z0iWZK&m#H*f3kumQ|U+R4%}{kMTf$B6$Uj_-l4Ata1l?5USc-*XZ;`7$Mo&t@?J^! z>E<{3a03YPA4#c8-}58%^`RPvzFvimz8;2M`r`AG6EXUZWctjHiak}LZ;CL3J_-RN z^!-hQzCo@(oT}(9<|ye|;wOQv4B(vsnIa z+y%M2@#q=XMez^ez0$$=v&G`WK8%}2hE=bI1i!|Ukkd13o(4&I$8Jd^<01}FI4EZ_fz;z)VRhl8hgK%-qXARx6}NH8|UA8 zeN<2SD8K26o9{ibe8b4MPUvv+-9q_1z3AmN}NM+nzb%BYkIl z7CAz@)pgM=y6;m}!QUqGC>y727yLH9GkJNVB5&~Nt?krq$KH6Hp?=)j1^ue~M5uQt z*FbgxJ*l)FR_S~Z>xI#y{fsvv@<2aA|5(3Hq^=@g$HWT(XAE`LBL=(y`r zq2nK8`U=+KJ!OmN$uPm*4$*&WAM&01a^9EEa>%BSXU5sNn_$1Rp1<*JAAtHHTc`9! z#UJ_Y9gN5PY;f*I=TCf{H*w=u&}HLR&~xh>5T9VwMs$^qV0?w9Hcq{f<$}L;t-zy) z3f$fz@b(&kyPG*J=(@SzJ*xTcm9+IfdEfLPr*V2by>|ihTu<~=;{R2bMxVpZke{}c z2jd#L=Y{cS)6K%y0w;8j*}{77o1T-N(LY+JuzdlG(|4~_&-U)>`{9e!_lB6he}Tqn z^XWV66F-}Gbom4YboV8IKej#`_#sFC|Am6fQ2(FB8sOqHy?+Vu9rS!VruQp}4)C9< zEn64Nq#j~9pq%~C71}&vCMDys|1Etp{m-O6A^JE^9Ao{v@o$o1E&L`gkQD7dWd`TF zuwz4y&nC?Uar^r_bh$ai1FqHFXGTT`V;scCO?(oRov(}>}B-c;sEp8 zwvHRd!{YeEc#aUF+-hJC<0*?Df^o)E;Kw)S;RnVW*3Y^8IFS|K7u-u_@tp8Km~R-FWqH{6G(Rf-qM+-i`Rx)HdBfA3uW*h8y#A>TjNe}^ zeD+r;e`|%mg$vQ!gnYJfXu#(RM)oy3P7TUAfg-{%GumblT@Q|Z2Aq2KPw z8k>-Oi9Gbil|^mCE-JGt#Kem%1bdh`U>Yx4)5&O_KeR9-L-F(vIB z{i(FGeYcdmLip{s-yzRi?~=4h`jtXX`m;*)pN4riZKwO*_vy)S@836iZ3m{rIQpx;5T`Sri;K+-4o)meTxg#`)i`t>ho1DZo6hlZ|wY3*e~s2 zewjbAb62(=jrR48hw+{5)57x!+7DtsTeoxT8|M0E8NVBU@;J`X=iQXg;!yB!?22f- z4SjLru@{~Jeq-^@KG+atH-N!Sv+4M%f@hzLaDV^o#?@MER zl}!(&59hR$hUdzr@8umS+4N_4#xI-RO*ebv`9nNon@xWwjd_i1`bX*Ka=JHt6sNyV zH*oqydL^f|RY!BWqzWpTP3NkP;q;iQV>vysYBi@VRmX99W)(bXHvOt9M8ethg;h8`35aQZ+MOeCBB zQq>DN{g*0Cp=Hz4Rp{cf>7P`!aQa9UEmIQwyDF$*mbOjNF)m6EsXm?4<<&3Y^tsh9 z<+QQ-Wt^T|y_VC{t4WP0|2frXa@tXiP$8S{u0EU7H&(-B>3fFN=Wseu{R&QRsBYu* zJ=L$|^v-Gu8!6v#_1|)OPxY%fy|4P!oPMtQHJnaWzn0T)Rd;au!|HQ6{dx6yoX%FC z&*|^05vtJqUri^c&#JkQ)B2i=I6bI_8Le1+qJ+-Er)3r6UZIGU~*Idl$1vPKr z^pcuOIPI;ul+&wgdN_SsO`g-6YtR*B(_3o_oNlXmBd4P^Z{qahHJ5QZQL~=YFVysM z`f$zVoPMu{%$3T|)L+fcbqQE^l^Gbrk~T*nX5T% z&TQbcHFFK8XJ_8Z>1#6Aa@v)-j?;CS0Zy;VU}`FxzBaRw(@hzl(=C~|ae7DQ?VNr% z^A1kOGuLza$;>8BAIxm#^vjtWINg)Ek<%Y!ZsPQ(nRjyftIW-u&Sh@lw5oQH(?e_D z#p#OLEu1#gzMIpg+V^mJO6_|&eQE9cIBlzaKd0x_Zsqji+FLojtoAle`)Y6JbR+LL zBKxoXdxqavdnczuwIATLR6E4!y|o|Y^fR^FINe?QAxE7Cp zaQf@oVNRc@Epl3WP>Ite2aRx=J7|>CV-DKR>4^vJ;I!qSF-qb0qvLwlk4X$~eFX1w62n^; z!TYSl@Xp=u`d`^_pG1GWH-dLAlT<%H9l`s56T>?d!TXcM@J>YVem^n1;}N_MCx&+@ zg7@=@;T??N{Y+wb2O@Ysni$^R2;Sku@ODM;{(WM2+ah?kB!;&og7^Bw@HR&9UXvK! z`Uu|36T@2fhZ4g(9l`tF#PCi<@ZOLZ-iZj_ z>k`8|9>IH6Vt9ulc=L(j9gN_WjR#4Lvj!q~|28ptdn0()CWf~wg7<}q;cbiHZAuJp zO9byxiQ#RG;9Z^=-uejMgA>DB7s30d>ZJPlxzD)q?{5;ryElS&Z(?|-BY6KkF}za| zyx&R;??eReR}#ZJ9>M!yVt9ulct4RC-oXgo9f{!`h~WKDVt9Kac(*2ow=078or&RX zi{Rau7~Yl$-oHx>Z({`S8xzA@AHn;&#PHTd@V+K7ymOy+{qI?c;oTd-+maaG=?LC6 ziQ%1!;5|Aqyb}?;hbM-2Jc9So#PAM9@X7^INyMpx5xl>vN-BOBh~WJ{iQ(;y;GIbf zZ&w8GcN4?g7Qy>aVt893c;yR&N$5jk1n+%`(OVzEyE8GobrHNDP7LqdeXjq#Ju$p{ zBX|cB!#f?p`}V}}PDSuuofzJU2;TLH;T@0Qy*M$vLlL~^CWdz~g7=)n@D4=qo|YKi z-U#02#PD`S@E)5O-nIzdTw-`zB6y#j7~aMR-kQYl)<^I@PCG!8+22F}(E=ymEm@682UX z!TZw0=$-qd>wjO67~Z`Ryp4(BosQr=GBLbU5xmP1!#fedi<8UA^vB~7yiWjaBK!D< zB6uH74DVnB@6Qv%I}pM9Z;9dUjo{sr7~ZZ3-hWOEZ(9WK1Bu~niQxT*#PBvo@Qx;i zw?2Xwr?!%@i@FG2oH9!W?_A`3){Tkb-5bG+Q+&zLI~~D`Q-{gmor>UHml)oO2wt4( zOora^2wt2*O$P5!1n(J%;T??N#VOxp=pBgQ#i`_E@b*UVHYA33&pmFulT8e7SA^a} z62sf(;HB?Z^SMs<9-BQlhrg1mOS$**A4~^?ai$f&;J(Hc3Ku0sG=h5raGw9f*Wo*M za&JawdNpV0FBZAJ4Y}($&8Cmz=kC1&a?gR>4-uYA-4&caop8>r**yt}hnL{Mxc(~L zXK)?SW%rSPmQGbtk(9qt?xpZI%Dosa9n;`LNf6?GWNX*E$(7K(`b>|X6T0kP8T#G? zKM(GWvwIw3c+jrpgc^MMC>;d%aY&kezTRVE_s<0P;N|5#^7ow|-izSU3;OKd9OPR~ z_hZoaX_Ow3L)N|zqWCO-CiNKSbMJG*JsNKNcLClkbl^TT+#`T`entnq?fwVIzn-4k zy)$mU8OrBhO9kj>axLh+p>`imCMEZSOjgh<=mqNAL3(BPmvp9iI}FJ~&n-LmkfNRp z-v$AB$$ON4hz{HvpFs!xqkDajd;j$NTXg@)|Bw3p{Dk%Uwfm{xUs}$7u??&w`1t(%@O_D#rj$9Kac0<+4PH9kF)6xy$@x*-iPApeJESW7I5D} zk?%us>wCKU+kej|>u>+q1wX`W3;aMPbqham`4ac1Z-c&Re}?;;@yn!eO9kkg(EeaR z{jKz0;eAn4`hHN~OTTO1;jyiFnbcaww-6n*?ElQ48y&c{gXkC+f4@-qLPfhVJmehd z=a#S354e8)SkimY4-A>qUD- zCEETt{imV+GCeq*%O#-)*!ba%XJPQ81c6c9^^RGqp zMd{7b?!ukYPK&oJ&dH?yi~UfgIBU1YS)aKG@s0Sg&h&|l*YNa@e4fj1XdUC!?l;a> zw{pI0^@-9SRX<<)qv~eqkE&0S{;2w7(h2I1s$Vcqe>5X_sonV5I0bQjH2xR*78C!E zQM=0H|Giv~jRRc$taQ&AYPbih@VKhiUiu+kI=U+`wP(aXGaM_?}1o zQK76qI*i+G_e3M#2Ee+ll#Cs^zg zPvt%25`1rf-b0_Qp2BLegTF^+`YkjL>`*;=fEwzJcQJqHJIkEf_ZeM&@5245CBX~* zCUa)}9;QcVe;4$7OZj(?P>gz8`Jz-oa{a(I!4VN$E{=jLz*st&$r{QXd)K-iMrXRL=ZI z|4wO-drvvOH}3KkcPq#E~}#-@Zdf>=*`y& zkAE|6r=z<+^*a{9eZl%Yoeg*1%I|TXIez{*nx1;Sz^i5aaODcz5(hi}PpN-_d5rf` z|N2zsF+PEDOsqdJe`5Sy$Uo1hyzZy(r3dZRdwV<6$8bAr-h{s6%k43Gtv|N!M!0$a zysmz)xfJab{fz6kw{uqTj*Gr7gl9eTD~?Cvn{YmExA5K3%Q!ukMDWPGsp$`-)_=xg>R+HA?@+niNugeOd~^iZ9vL_6D?T~}eryr((Tl0wVSGdZ z3;irU>>t;7#<3sJ>DqJVQs_|!>v0$dbcx;N86Er82dJQH&lX>G()`{+@ztlOocXW( znBetx_C)Xp{@m$*<8jt9@Z-+iOiX)GRhg}H%&HM?7 z!gY=RV0c6B8Gpp{O6wZa#7FvGDc2L!pOf#qmXB)$fBCpZ{GZF$XVCZN%s+?g8WMK| z-{*DYiSJCh{j0UB?^5`KI&MesUH4*2;k}$vf57dd`#~9w<3YP9EM@s`y^#1{Hm;$L zmwx1LrM#mr|JU)KZu>x=tA8s=2Hv>QBXpFlYuv!qgz>b~{!}c!m?aqTzzh|Ee7{C9 z0)4-N+qn=O_fS7zdO-I|bA{HfOiCK&ZIJ${Q@?v{{K5AamtRDa1^Pq%Ir8z9#r0A@ z2ezaNH*<67`Cfj$Va4NkOtA2I!-_eEO`kKVdjdNK0{T8k8Q*6Yuy^PIG=}bLXa2y> z_c(Gf`@-|a#!z0B)-}J+^=SWJWHNa^3;xFCgW36SENu3zrk&JSaK zRsAnYd%)*6Ttsq^$B{UxFBVrpzR3R#8vkWd*9#vP@WaE@F63X=3Hux7{GI6&xZ&aY z$Vd2jHoc0UyZR+^+0E}mKfH_Kaz8Bi%l)v#OD^7zIC2R6@D$_SpY`R*hiluJMO>iXHoiNE1Iw+wtLtw(?0wPAm4^PUUgJ^u}achT$8zhVBl_T4}d zb@h4|(GCC5NY9}chrxfx=0Q!)=LJ&;7~jTQli1^!UrvFZUOlS^q=-b`rxIa^KfDv)sQyU;SJM=QF+cb88tc_iuu~ z+`o-;e%Fq_Pk!3=+l2m2;&XpvOIiM@Se#|;TE+S{{UXoz|c~B?*pkFv{6h16e{_aS53E(R6`zyq67Z3CZ_OPDg1NqK0 z(aZYZKfdpJ?;$$#YDeMx)2zs4%LL;IzA>qH;Dfugg7vjem znE%xJLphLv(9hxy^BbAeN6Xqb{r}ke7C5PnD(~Bn4kSK?KzhJ72{VuklQCl;4?-E5---h=aS);JO-oMA2Q9 z_1jNTqvHBl)EK_=KaaZAw|jbeU<5bc-rvCOs#|sH)T#5TQ+4aIUfd+@l(`zO&zhW> zUlNd<3gZt-#mlm`OOTLAECSN|9zeMX?D;2 zy?jaOTYfLYiMGhZHfqCc5$l^2grjRkN$9$&`9e<9_o<|OvrI_Bl8j5#JdvLpe_-A@ zjdFZD^&F+YtuyQ;yy&}e%qLOvGpPpB!k>gEr=tyr7%q*AmfNpsk^88*Pt&3g3eDR! zEqbiGxuj{)kKN7NG%fTC%SzW?p?7rKRBpF=UE@r_r|m4cH=oP*ba0OFf1UZ+Ua~LX zw|}HKU%Y?dBE|!81YGg{fjbzUjaP=h`hWS`Fu6MX;sG=OL85!L>U z@MpDuBYfqu#?vd{mIQi`YKWb~@b_>li-z?0P^~b_= zVH}b_h7&c5{Mz^9Odd&o`S~i9SBmTKW%1;C^E~6*g%y0;!S$>8_CD7i6v&L6!R0a| z+m&z6KVf`(-!Sp*uD={!zTJO4@oN>|BFY($zt49Q$?r2hj`{joT)rM(-%hM*{AAyC zj{Q7|AH?yjB;O|ZQu)!oGaB~F^Jw}6#>3Xf%&tVoz+ca(;IGRWZZ&`DzA6YeT^ZU( zCHE7r7l&)#)Xl@pUvH_&Ut^h0G5?6(sK-B_BE4vQlS|3GB-T@+zis{2#=W5X>umgO zJ$qXo3yUP_NDs- z+0CNb&FQz_VQYM zDf8ZXdg>+$c+vb(=_rJ<_)ES|{Iq)YAESA$>6Lo^-z~()rmvj;*DQXS^Z%M<-W2

sn*}wGLX;1k1FQK6d`=&BJVX2+(xfCf^ zy8L>{eReYl4(8DtsT}43KlvN*z3>&i$D;G`e`RlyiXJ5zZyw1Z5**9>yaQ||?M|T}yy7}!T>9LymUg!|}g(7eH z(glkDzwtd^I$zTV_#VggBrXugrM7YVD>P2H%Hq9B_j>p|$@^#xpQ$`9VcEt@_zU#E z`7bKtpolXe|4ZyAw{t!7b1dHPw=47HdE5_^FN?1ujd@sdu3Uc>{E$D``tuY| z&-(2r*Pk&iz<)C9(?g7x;p5^$ichRZ1P`Bo00;O(egSU|$!VH;!YWNAO9pDecl^4gJ*Gg8$W}e4j$$H6_uYTo+W&`L+~3#YN$OS z7Z_iEpKG7?FC_WMmxLb++5HSBUlM*TWWO$O^9q;f0*z|(e#qH}70zmc6K&Yd1y_{% zn192v@G;GEB)whm?4J8IF4w)~t9-AH5A}0?)b=RfS2aJz_jK?$_dBV7eY$Q_K3GZm zFJ8YFMH;W)|Id9t{84&^F5X|Ui|G;bcb}$ZJZ(MA=Wo!*=kFg~S8Er>ybk|s8CNhRU89J}))JmR-n)=i`Satkt;BaG7l@N$CT;Ii_~p(5 ze>VDl_!LH??)$UnJWcs48fN}_&k*_RgV)A-vmSpnpCJBvoQ{lXgunJvxrX_xS^29Z zcknIjDdc7g`)!9=9**VwflraWvN$f}oc^lMAE?v*hU0Ai1C6xbfP6i);OVKqn}%7w zE*zqKeW5}5`T+SOCqjR(Xi&ax9*TU`;jgtcKY*P5HS^b6_Dgc9IlNF@EQOrz&R)oV zPbT$B7SK#;CCib;Q8TG^>=DAgz*1&X*YU|GnbdljPo;XuXGH!z{C;C5^-g|6GLw22 z`%jtFd-)B@Olo_89j}?x2Lr4`WKtjF{iT`I$Af2a`r+W&eE)2K8FD7|SU{-L{UEPo zXHq{6#&Y_J05jf9>euYIW>QZEn9*fYf8>>$OzNosD;k;9QMQknRFJ|749! zU+O|me=;?d?_W(#JmH5%*7GhT zf4cg8U-5UNbu!=d@kq{Bj1S*VEEfB7GB1t&Ie`<;R|G%bF9ICjpZm}P*dgtwThIFm z_uR(^^?ZNr;UkC_2>f^+dywn7b?L0c5yG9-{hOMYZ*0yq^A-ej=`t4!*+adUPLO z6YfWjyPuFV(EVZUC-hM|_?W}@R8D`2@dN&&IK79{_3-^=&2f2;gG;VEwX<(fIEQM& zxyQl54&rpsKPa5en)JKV!GV5F2UiXXXL?OI>m3~E=XCHPh68#bLYWTk85HjGYQmLs zi~$FFJ{^=DTEN#hh4Y4*a4vLk5SK~^5^n|nz|NEJS#hF_2lE_G@62k8LTR_FsiAvr^x+L;k9JY};P0&RQ!C?h2E+C1C*|$(-_{!6C#kmd3w}^K zfL9~w$()8XSNbDKxX-T%_m^A`<9ROqqJ2>=4Zq6PgYg{xl{-&^((tqV`DzQ&qF#94 zAk#&Lm)}#LM?D8Uj;w+oqU!|B;1aAOL7P*5m^$%1av3S-7Rq0v_m^!&DSEE!*6HBi zIbDyQTWgN**SH?~1^Wd*%r0`{j=FKy_7)48)c^lDigNYZ`}l8ajo%{-{&@Hac!GZW ziGIKv96<3|hFcGx&(`e!L&uHJ5yj`TiVytjbnx*(@wus{o!Z9rj)y)|2?FTzLB;2J zl&0?{Gu(RgnNm|O-Z5j%-zn=y=|I+_>-Mjv z{l1mq9S^;YAK$3`dp_OHy>EPvq z>Yc8dawYckc*fb}YPQl9^Wk(bV^F%jp(Z|)m9DlfI`ny-*^vtspNkkDSf~1W`HeOC z4&E8;(Xr!Wa&Wfd1CJ%m(UJQ2yrjZTU=~Msly$zF=OpX1v*yKd>fyk1wBm{QMUpR* z{7Cj+_)g=vQHQJpO;NsX0`cjJI`&lY=K->#zCW;w($LRuB?bz22wz*gA(x^Dbop{R zQ2lp*f$VEvW&KPF-Y3TK2;*VXUh6Mt-Eu1+kZ0T`s;N4Yo_26 zb=Z2awCneu`{Rx4N3My-wUK_m8g$#4?Dyzn>-YWEZ^5^b_FszjwHqM#$vD`# zK=J!J(58SVd=xdea5~x|4!HUK(E#&>ba1cWKaBe77gGtJdU+n|k zPNKg0#^=dS45+UpE-@5+^)GedkucIV6n(WF^cfI8(|?WYtNZK1GyT`NzWQL@{+j-4 zTwiUdi=XK~(JPJEk2lnWcf9)Vy`s0~uNFO0;$f|M4vG0QtAK~@bB?lWxt{qonbfi2 z6K)qc>EMZm@wl-9kLAOJhrme(vQMj#ak-`fk0rx|hrme(|I#o$ZUFzfaalA>cnF+y z@X3bpm{Wnrf?>i#;G_ewlZ}kaqpjdmsTVb`WyTKm{qLxGwWfv6QS)+5%lJplOEfKf z88t7`w8%-+yg<_;ztIWy15Dnc=JkrlL8f!myiwDKG`)$_$v9&=I9JAV82yG*Fz(0U zHyoq@#?xV*Gku7D!{^ZNljt{m`H|uE8~(X2yrKII?*n~?(Qo*0UHpdbH{4klzoGjL zZ>kG#=zhcNYr;D=I~}=s)6o5fn}LV3Poh^%kDW-r;k6ilhll9<pTGJ~_56pS$K4;T z3vcN5xm35mL$}ZO)rB{7`~3Er@J_sa-U_-qyLj^K^Bom4*vA2q0Li|(1y#CX$KFX z{b96&->VC6=yve%=Z4n~{;)2*q1(Z|b^AMXJNSvZ@P=*&KUfpqiMNBhLH9ocJNRG) z9w*NZ-dlmk$+Lsc`CmKe&b1hheWNdeyd8%foR0cW13UQKA=<(5==VvC*N&>GCuw6L z#|?%)AN=F<>en zu!B1*@HlyPaBBq~C(jP{(t*_RxSYIr?L8HEoVu zY2Y_pJ7;L~=P~H_N%R}=>h^HXpMOg)s16Ko=zhZ!b>R)&Z+NP|-h6!Me#5Wp!W+8Z z@RPdmhVC~!Qj>ls-f#FQ@c1+E8_E@UoIJl_a|IqJ&u>^?fyc@78(v$1$I0^>)@bQ1Mgk@j1CM5OHwc1=PmuQ`25q~ z&k{e%@kR4io>#kbzM8jjx_X`BDSpqqe;D_>pAI=W4nON0@YU16&w8M1Xnxkw&r-in zqM!Bk^XvIVLyymVu`ax!`&s`6`V6>^GIT%d<8|>Hx}WtAb>R)&&nnf0cN)vHy?@(? zzW!)U`ki<`s|-Ax{W^K;_4pJ6ou9>a=Fj&%rX@Vij$ZD4tV4>otWQ_#b$K7l^t#U< z`;N-_3m>3^p28jb)o$c%dMPVq35)$a^GJRxwh|1*Bh75(sz9f?|A+L?Sg%%KV( zdr111-K+gEy6)q2OxOMTe5#f|#CXNufjO+{E`5GP($0Thr1@hM&H_!3*7Q702bx~3 z>2^&o*K~`fmuPx|rZ;N(pyIJ!(+4!YR@3`Aoi7QW6`CWZOCLWkxc8WMNqP5OSs8Ep z{;%;j&NG4J_;&5kQ)1WVQ9kU>FLBAZs#B>}>b|lBAlGB;Lq;A0J<{!X!zy*3gMDk#G zWcZYGDkoyW&p$LbPWMxJT&Cx1wfjd}AFtQmwWPug{%!#mC{w^!qOj zjOVGI-OZ)M&uqlbE+_tr$5T3D=Zh704(>Pns=`j&xp39|a850L$bOy2)$v1C$Jg=0 z9)2F5izafvLiu6UOp$-b4_m~~C~OcsR!whL{%DcAp5K};NjrsR;gftx@F?i_^`f~V zxHcZ~ckX_~_$1}n%5`Ut%JVWe$LGqDJ95}?XpDOq6l>@Y^aQ${yQM||a8{ZS+_Im`5fA0M_YQL6#I|KZ!?e;H`dR6$T zocaC=EoZYooMnEKam?{o4WLit`_|oA`Tp*S{9fg7eP?&gUtm5X{OZp0EA3)_h>qd= zB&0ohL`j;dhdI@y($L%9TU;D0Zte-_rj1R$oZ}#LdEXnhzIm!3n zj(8rN4t`gY{{inY(gVg53beQ(50yoc8FtL==~x1#z3 z`LgQaHqqbtvg+wJVT@u~__VvNg(+-)pnWGgEUWyr2_JViPvUaMA7=l%w}6|7uk|~q zHV;ecb@1iQG?A~x*HFO~d`RVL`2(x!@U`(X_-twdUXI~Ozth2Qcsy1V=K<|tRrdEH zhn}7JeZtPbvjYAfx&n9^966sWT)TkbWJXWqJI+=8_Cm3R$ng91E2^L4ujI%#I*EOGUzdBzDDo#VgHzYFW0titn2Drb5Kb_pX5JhxIiF`k0U6q0+4pp9Q<)VBm) z4_c|j^A>^&x%?jPq_$Ac^nvLWv~xMj`Ii_D`u&{&`uz>U$F&;>-=zcn-fs=PGOIy8 znK1yLv>hX#JfGYBt>D9oOt?P0P3^ z&p(W^oAkMkM|Pv8_whZ-uIIba1$+t*$&b%0p#DLxLH@vZyB5QbTg3ESwE@x>>$9*t zPvG}TKizu6^d(#_YFp0tbfEF;I&x_9`mfXZWyyGBEQg1+A4Zo$nijf69YRlk9FzXR zqcz~ylEa&bPin0@-00=U{4aEk z%kcB{+o=gUZ&SLp65Z0lV@fBZo5iV3jx0Vbauj99XnB>d>;z3O=X;cG(e!Ffw`*GY z-+h-`xK3d0Ky?rn@w~OVgt@-KXh5)7vyHarHPJ(#>>=<0Y#r=vGVr zjUjsZ`fto)@>f;wg(YpjJVM&-{k_DcxBr*Kfw!z-_=Crr_i_DI%@$wYEBH6x!S&rd zy!lN6@3yUcH~)tCQ`+s7@r(6tpOkOg#`kn^Kf|pxFPK3tYOQ$z{8`_x`a81!wdMtf z=1@7ZAGnh9UGvXC-!z^t?qyBC?*NrEx@3Z% zbNO`e6X|yY_6FZNvh}`P>QY9uk+|cxDSjI34IzYm537;+jMle9oe&lh>M zc|rGF@oOUI=ZJq4mR0YyVRlXNwDNj^*Ve-6Vp+zayRDtmVOjNH+YC*s9&78;@n$s31&X+fFexXg~o%yoxOQB8H|HJZf#e)b$SH8SU%b%}l8OK7~1)Pqy zOx1j$TcPbGn%=MVu90$j4zbB!9A_3g;=*- zlr}%E9-r)2|K*U+*0zxc$A-pHb8g zwB!0kowa_=U_F1B;p9@MbA@6_>{2cza=u%{F36nL%=N0;@%AH(_26YvX@+O>N6_Vu zSCXAGI*$9nbV{nh^sLl_ej3)m)w@A9asMn#zW!sua!h%X*b_1_C3E{;74sLFU?{v3UfvN3e!#Q zq@7rPHpzH2Pvj01b)QOi^At`OHb}o5f7Xce{*-vR5x@V;0pwu?$%BLM#cR){rhRz= zKgIFz|7N^lN9LiN*7M7cCVgafBOUyT%h!`H^B;~9%-DaYmm=tD#DDlHZMCoV-zQ0Z zx8Ls5j7RJ@?%{Oo-^zH#{%s#WkNw+SQoaHI;Wna|^&_4S5QEYcwaWIr3ciLH z%SF^i!pdotuePf=9c@Y2ld{k|YEyes7J5f*6S;g*{o3v}k%#VP@ms@^$&L88w!f>; z+|Kn(kH&WBKc&Al$<`>MZpgYv!}?WcYi|HXVsz~~Bh9u_*4ILZ4jll5OW&#y0f z&i2Fj{B+>*n4gTl!?M_^sI7$?h;;u;v_<5?{AQy|?AL01VT#~YYu(56#~P-K@Ov&r zhoI8ci2isl)5YWjS|0wEFia!!?CY2=$@=FooalbxSEIYhZ6k0O)YNM_Z?Juh_iyBJ zGrdsAo;W@C!V3J1AFB1sEN`CV@NB-8>EraV`|geKwfQ^7Kelfr*2kh>Oh4vTKjnL+ z|IwBU8Gg8ZE7K>M+oEZqS2S1W_1jgS=sqjs!@~6EaruIq-ps2_{#awqAuAl{^Y5R+5cN;KVL2VwPN z6pIgWL%9@96zEE>pWD7cRoH_;iDKe1h>fpW*s=pd}xVn`i)X!2^oN5iXB$fd;RK#|Ik3 z;{nD)^n{NGTJrJu9@FDpipOX)Py3<=$K%}%;_)uVgNz$p@GH=Q;p5|haWegp3Es;1 zq=O#5o1X&z;U`_NZ*P?R8h+7|2KCCFWQuC-U;7@xZ)9H4!}Xb5gpbTCtY6SONqtiO zgFg=$T(3+fec{7P>XV6y=g=rVJs0pkeDNP+xj$!6xnEA><+qD*@!`Ic;KuVQ)$g9( zJD4c{{)+NnlX3IPC;9P=it_);rCYe)p4C24A05e$cwpLX5_g{&&txvlB?m|EFx7_!H^?itBoCx$dliG(~8G8lcQ5D}ggX!ec1$6i4B^O+Q zdBtAtkL};EIEz28xM2qDDRr1Gv|fv0 zMf#ZJ0iLhpcP~CXljTtS6XR3RX(rVhbl>`M;I*FS^A;DXhu`1x{^x4^+8V*Hjyzph zAx|<-kN4Hzt>ZkIsCHuH13mS?6{OEkB?U(p=nMTCkCW()-9%qMzo7f&o&Q(Ezx)9yOw&)kpTv4} zDL2RV{;Zm<<&0dQlhW(eX_3N%TLmtzt)q_IL;{R+r^!-PFAn}dk9}^H?B{U z1-jgRnw^8=@jbG?v0ovCu>Hu<{Y#h*p~hb#J?A0Zsd}`;&2bzw*}orN9qXTZ`uDY- z{tZjZxjm$HBD4i=#} z(Q}c~LG^idfuz-sDT;cf^;*%V{jenZ>?J;{uGKJ#5>3EPUHUlPvXbN zUOc?|>ld^nUd@l9n0$V`tS&za|Hk|%eqpS~Vtyr4Pc+B>!oS3FlvaLIJ{*vLYxwK0 zAyAF@>n-FL)rtq7)6k=^=R??3t91NV!wNvj9cjd-y=N-E8c&# zOP)92moK4tTkP+H>q(Avzm^{t8A;=9_BdXj7kb6(^WtatdMoL7evS5j8vM9j8IZKD zd)oe#NZ0A(xXKajx3zm%`rlFQ=Ox?Sz<%{!E+5lf^g$!@mp4|_*LpSR^u5c7ze-F- zw;zQ489vWU_|x=PyuSln4Z3T8+N1c zwe(^O)%WEzV!0OmZ1M^^hNKrPos45Z?pZ&ozVzW037+|dL)kxcfb;*zy$7!PGP{<`$NQYtbGi|}Ur+H!voH1JY5k?KJVp0+34Hh7 z@w|rHdjsjAm~IPs1jCZlkM5traPm8a4w=(l$+-}UX#5*i0vpT&F}7sh=(#T}!&c4>c>^WFT3(7vmy>lgifQV;xe2;=IF^S3E& z@3Z>(h<8NUc81%(S?Vt%^jqlX8ok?jz+qX+g{@M~t*f+BgLFARL(eM=`=sCLK;+7A zH_3M^sJ`uY&ZVvucoxSiFJS!gtwNZBo!6sy6l|ThhpQ1DqTj+E!%OsAzDM+5A^WJ% z)6QAfeYs(&kMnODD}I)b?>3?n#$yGo1BP0D3XL!1)y_+3QheNdQHrnA!$!Bw=AWn@ zZZ*BEdbo8wcO+jHJPWPoa5^jrA3*=nAN5oDV&@{p8-6>XNpX1D-(YqDcyFNjntM+q z&*0p9Que(Ev%fZuHonM5d!e4A5N;Pa2p^aybad|tE)YE3I@vr<$9~a9E+6|vqDKn) zo=)X2zn$!gTX(22kNiuD$JerNEdiZceNw)G^RTX>^&pe` zdis65r{5cSfBEtXxI$o~Py9ZB`AZ`2PEJqMd04{ECnT=>x5Q`Wk2rto1hzkq__dMv z-Y;pX!{JvauKY)eQ`DQ9(bm}N zIG)TOY#t0f^;sI1VUH`<(5D|F`&CPy!jk*??;mLVYw6RSgl9c{N?oa`PfG-EKz&*R z&y9pgD)7 z8kr~h{tU|de*Y^-Uxr$*I{tEm^?AMeFRiFA`qbhlew^yv7sr0OdoQfv_htkS^N;iA z3VkxCNPC%6bRBGDVjYaqumIt?;tz(CKy~8hR=v-b{K7QOj_F-v+#jGKjqv9}8oyfn znL9@Q{5jdb0r|55zW6!eeJp%2u3}uxj;jBZu0oT-e2z?B46|m zXwOdPfrWp89^k!pa^2~ED#zh59|LCc_5;~TN~4^=-hlG{dIPc4kk(b-PUBuB&ws}F zzMS~25qtdyvL8-A)v?#3m=DBHv~!7#p9fx#yM(Ar<23RD88_XJjCDECAM0`$x1?VB zbKal)>MMuWe!ubZTJ~G#lit39FVHv*Y`-OL74v<(?k0Q>YKvUpmoEpP|A6am1M>GI zfFt>Prpn{9R34u#<4WhN18ycYhT6jYjNnwhkL8`xnbbJ8rbb$wa%+BLEG@{$bO=(yZ zU!Q=&zCM9Q^63b?hq6!OdzUmOpLh83`M={qRF?4@?(z64(YZ>$*U^W6HN&63h@Kl< zAHIa~&y2i8_2H$uKViD+!^=c&M$RDKf_}VQC=zR9$tO=4GJMu&xa;5-TnE{S#|ZP#M_}4#E*#e5M|NW#Ck~dPOOJS z@5FjY^iHgYMDNJ_EY>@*{uaF>{u!PNp96~Uz33gZDrrFS^$_&tK>8f>i-*1$`|n79 zB9Z=hBK_$^`VBN*<}ZZOZH|MjBSN|S@xU&gr!Aysz}WU3VPD=;G=IT70QBsfEP!Ay zaD_$nPj#PCSd={#Z>MJ{-+voQkG^H+b~-B0Cn z`o0q2e3JZ+TIF6a+k?M^!3CL9f6wzs>(5~8SZ+N8gGPO@c^}%{PV#5*Z95mp)`@Ii zX>^y;sVwb-Z+Km#C~3fX5z)-%p|-vs_G+ASgOrQ(yc>J}%FcOk{kTTT^-tG(yVlFf zcb~$AqYoped)=c?;U3-)aN5_i`-q{9&i(I1DdLa$@;xcw`B_RYB=!LTVJAS6&SDGw zPxSZt_b9=MIyNz#?R-?fojo*uQFb&xH+w_-V;L``iIr$wLB0nDemdmw4bhd$A%E+u zgh$c7o$G@937?7i&*D+Y-*g`|ms~C`RgyH~BbyknJ&c!+FTTfx_1bn1F6i;$IWd0$ z?|&sw;CK4Ta`*tjv-OU!N98TcO zvF-^u((%Ldmyv7Lzf;OXt%3h-owNUT$@lfjLG+`%i~Ae4T7N{3gss*eS@($bvFMAi zRp8nDvkEUyP7eYP#nW$pKl-EkiS_|89(X=U`#biA_&MYT`Lutis@$^@6avq(nAHSn=Vc#C%E2V?QBLNTE0^>J+ z3f1@c0&?c_1@xWq1#I_?T;ec3w{NCq21j+M~%;!Uu@quvVDV*dk<6ey6r!6{d1Q=+`8AoesTIz^^4P&2ZdgqUfY{!594Ke z4(**v?b&-~(MstL>}Csf!M@XA?~6tH-G}I|1=3EEZmORkr}P(u+hzRFPCwZ_8{gs? zLLYnoJwxY{Qjfi74zjz?0K|*n&kJtT<>1F7klMmyaeyi;U)9nBwouvUjlh7_~pEI>)|)eD;MMU zr=#1IUVHWMI>#^9rgYW$wE21AQlaBSogZID^kP0KNqN{!tPi^Rmp3l2C&9CILR;U9 z?tqk$9>K;(+!OP6v%eUBysGc`gls!5vv0or*+uQ6{QlFay}n(nhjODK^)mlKOJ+~p zJVxz}*`ajM&gH{fTlj8#iT=@_d+)7tEK-u@JJAFDnHwqj7Iz4DiXFo~KJXXj8@T&; zL+?Y6;R600Os_t%Pqxqd9;MUmQV!+OQZ#cvm$P|O)Uj9eZ=aNd9Xmkq&2IVr5_*dE zzCyC(!=SieUY+i$@uw%^jO8?P#UB7k(+`<3Aecw2NfwS>Qd{;ix0 zE+ep$=%@L$<_`j&9p@1~w+bA$pHA(I?WZ$7vw1Pp2zV5q3fVx9KvX zYvP;&kqJzV+N0^XG=rk2OQV$Lq)H2I^V-FjPGjo*{HL zevCR~JZg>C5polZj>iLMLVFA+8Al5>zGv}~Q0=D4cc}Ky#Y6gZJg6HLa(<=cLr+k1 z%%|5u&U>{y<+Gft+?c-Ye~UcFxZdmY{W!@teQ0*t^bpGLCi*-2KzQjgI^lVNbhkZE z_S=`Y^RLE!3F;7Cetrk%r#L@t&lC8g9enrI*43Q;SjyFy4p;MYA^=^rp3i+*jAy9* zuHuuK1M|t&XU6rdzjg=iZ}AN&Zr!xpHbTSXZO6~ml+}Z zZ89TH;drDy_w^|-O$Sf19rN>FNAhRiyS4E!IR>3bt+HO7eR15r`3XK8#B^m;31K=0hLqAaeJJg=N5AWmg1m#=*{r0AkocQhC zLuo5#bj+zgVfkq1>)eihZ{8c9f6@M8Jbk!d_S>g6a2X!Z*SNx4<&HQAg-v)&==P@0 zizFZcx}&Jc5%4&J=x=H3Z*-gRU6nmb_y>qH5PWNARDVI*U#xOycEsYgHx&d?q;V~y zaRp{MG1wOp0OYV?6v*)(17`1XSr+@leByI8%&6N4Ri%XW| zIpiLGuEi;h&-=9>{a^;V(EfjuU8(jTYwL?yb3_39XG?waL;U`nH!to_OgDiS(@E+Z zo&FU4`o$3Xl}i!9=yLe<3V!}N?T`I<7L6mhTf9y?_2GDYasJT8M7;XdT`@gQ#`^ND z3I4P7&(yB1P&Xel>>6enGX zo53*QH~w4PieK`+8#pWZ9**y4AEA1X!$$FH@AB}1u+n9Iw9QlexHRBfe8>0KUQGJM z@l(RS$LD2z- zZ~q|W54nAPf6czvos7HLJ_tLv()>T0M>WD9=hxs5+ZSYXui|5GoWRGRONs8gg{+Q$ zqgEXs$RS--cIi^dcm7gA(w#RG1JGr5XX0GRxA-yIJF|ta@FO&j-jY}NEtEl*^|K$!nJ$Nqm~CF~lP3bVGfx6W7aq$mkwe=zT39LbAYa~} zq;}1}hP;FC(2qxn29|H}GV`DD{GaK0lCEaQZC<~Oy3<1N*61DZ*HgN4oX9!SxC%1` zFHY0YbdD1`q@)pXyB{EiqNhBzIF!t&=U zt2tj5Bn*Bnd_mb5AFK}1J{SVZc+h=4rMo+x61h_Q0(@xN&iEYU=YkLD06Yik2l@|^ zq=Pf)|61*c%`m%ycF-jHeVFdnZ~r;BN6%~F3w(fQJ$%3qyQv)Rw2uVMFyHO*`~up~ z!}-2m;eAfqQJUtjRGIng0ZH#Bd~kt}4$%YquBhn~f1GZs!Dpz~T_ZoTb6&;^d>cOiKZ#{+H69&J)9wzxCH;M*=E}V;q%j7Yq@86jm**p$#!rvoahSBrv*+rb>b|QLi z>%+N`0w4AMhD?LmCl_xb9~hUThw+cv<7nnS<}2vS43&%4P2hBA@p2wOqYv~pGJN{& zq5j%=`PMG*c!9267)VKAy zWrQ@bSz!Ke(;O*}`6~OTB~23+`=~w8Wi9>A1)t^z;e)b&v1x;pGdwe+bic<^txvS1 zsugqxJfB~0A-IU=!d_Va`qgjG1bW`lgM$CWEdn>(A>$nONq;k^QA2cLJfK-SRnI2< z_M65EUB(WP`Q=(1MvT+esN3n<<>PS&~m&(wN^6w~9yl3qr-2zc85nA`#Nf75Z_|g5!cPcl=M@jy- z{ddv2(bC_gf)CaWmV129azeZqV$q4NP({M@P*|4sP;Y&r-YV1s6QkZJtzQ;7jyhD% zs2f|odQpe^x!qE)X`I}B{FkG@4@iD=e<1kZBWcrnq3T88|2met)m+ZbGY_}#mwF0k zR9f_&=||N2C4uzYT}17MWuX_I&pns=RbIkyI`6?KQhAj>&|{a^uXONUejb(dZMO%M>|q~I4n!QqE;#A<1r8YFH643t?5^O55#L1c)pTgB=x6#N2^M&(|Cci zj6co}#c#FsX0%5jE9e5fW$mNAkI-||@5U#lhjOOhOUeh{d}oG-x9MBcrxS0L{`z$2 z^Z3B_jr5-{<^1u#1mnM>PsU&O8TD_Fa%+f3!JY9`xABE6!vaYd{m#61U~4r(Qn`45;gERl)&R`!UJ@t>U^#%B+kx> zG`=;v5tcV``)Kb7+EaPUoH_>8k7nq7L0p}>K9vq;b2@wr--0l6MDPbQ&=rYz2jP0j zj~3}&ss&L>(rAzEKFJ5#fm#3v!#f@Pg5kohgAY547XZBDU&9lA3+nsh)=p`E-uw7O z^nWVDv$)AJq7TcPj=vj^zIHALe}tNL{5xxc+AGh#pxsdQ*sOa9Aj(rEKOgen;_);1 zWb}(Yzq^;K1?UIMPhQf-cPJ0f#pKBFGX0Xa?@m6ba0rbi^|r;%kMA^v97d zX?emI{weY?f4En&<9L+vKl%}P@logJD_lIE;5`Stv*;W{+(D2283NeF)s+9;`09QL z^Z#JKscQUPD%I;Y?tpt9Jzdw#BnbG&@EZz}~7yJzGX#8Q}KWZOz!+3)Z zHjhV|;VVAo-`RdGi&NWreOkX)hc#PV;Uu~H;}3YC=XdBI%}2O>i`V$&4x(R6r9R4k z1Le0LlJdO=`ChBvb4VXqynG??8w&2GfAo{~U#DCekd6P~XM*Lpot8L1x>4}!Z%1k3 zk7m8!DR;A@wq9m_W&bjH-n3Be6O|ul%{ZSkOmDmONz?mpmh#bj=_l}cKkY-Z_XeBv zdD99h2fhJ4ZJs#mwyXGo`RlW$UCHU_ei>)?9^vJc_50Uqn%EWaY@E#w`u@oy^xWj2 ze~Z+!ad7#{=VqT>zP4lgVeC8Fk&uPfuT);1BX{dx{~gj!_@Iot%}-3vI6p?^&e2u* z$JTxOuTgv#$sP3VCiC{qn*sC z=Q4a>53v4G`2f5(!msKRxy+0fLfHGYxzhw&TaWVL><9go&wPHKN`16_%W00{6WvOT z2HRKGLpADM%=LsHb9DX>F0+%it^#}?@cQrKO{zzX&M0@cSFRqNAQ_oa!iPSdNjkl+ zf=)7VJ{~$f;~44mY>!Sj9|>1II{b}K2h$@ePoPueKd0ZgYVlK}bb9eH)9HsJj*Xvw z%=Lty8llrQJ{@Y%=@tI-VW88TVW!jPj*(7}43SRf`gEv4r)mE4VW88ChM7+9Jw`gc ze~5HCIwRKKwe;9ChnY@4ruclU$B$n>A@+VOdVJjw>GYjJ==3B1x!QB{8+VIaL+gI> zBQxSO(O;gufgXpR`wi$*y(@c0bxc59l(xQl%G%(Ej6tw7>jM z+?JxQhw}1N}?a%uYxBu2b+MjWf+ixFA`LWl zL_jS*fc;+5Q!cjN{Mu0GzhU`+;OpVBOZCT>rV`xp9)2D^uuJZG4!!M@imqe0)%xPk zaJ(iT=Xky27{_bH2^z0^pJwCrtm7On#8r<)zAipN@kklA3?{` ze%4QaN_}|#(`>vxa-8G!K?*n@i+nwLg2wAt7e2l0*Q<_myuNUZ*~ni-@qRbo83H`;zwN`ZcrM`Oj}hLp3Ex`q7W(im z(f$sCC-7K30KC6AMtF}5&|j>VIQk6%zk3G2?{XiW#yO*z;#Wr<;*a{{%<MH`Y&4{%Zu&-rKeH2;_h3zhk;O|K6QzCHBtt)w+3zo-+bG zamDLuzZE~<(Np4tQAf4^&+`?Jo(B}qkAa^0-Lf2=mxRmciu1B@HA0_Xc2?8J&Q-Gb zvQLM{hz=H4&zDqw^?R2EJx9adYfbjs@ns^8;*SIRXK@vtSJK4K-)Gq|mGIT`I<3D0 zo$Fb(zop1zVZOk7<#yhH<3Bf^%75xAa z+gLtrUs9{Uv;DB>ZwqCi{NIrt#(F0%N53{n52R;Nul-rX4?|dworLlYtjB(hoVGCvf=KcSkxzulRVed=Ok*==ZmQ z&rZ=Bp{}P!2&~W*t5HxI-Q zz-!?|!b{&5G5+`a!S+elAN_ItE^W~eedHN@FTSNk?r#-A57%=t2=A0}3N_9f-T`XRxE1BQq)}e>F-4o@yP#3(`#g5t z*Gc{E*)o=Bm)j>iz6bgeSWb^Hy8evoncW(Yt_|pw_pu#Uy{~d$`vO4!iR2eMzOJDM z_7Z+5_eSbMJkH`z$Tjsx`5Amex6GiKkw1@mTP@&zhjA{d;8@1%tdmy@6fbKeLD}@_PM8n7xKWN|F5j$ zm)LhOlkX3NCF{S)b@KaNwofniqc#a%c5Y{%@D2E5QG#9=7u(MOxoD@N!1Ef?SN%J* z9?380W%~BAKE-?S zeI&K#h6nKd%juMlM(9F%9NF8U($VK5;AMUk;5~i;!6*9Rvi6aG7TNn~gFJ|~$a9ke zJMSmdbH}C-9UiTbIsXMlg+Ao5Et zgOlH|>b!YIx9UCIM$0AFuY5T?Nc{zV*HZg=eQ(+32l?`UG9PC~WEcUz-hQpuO!9>RSb>b=P_lnM+%9_D-h-btNAxqs7v)iZp!eY4hHO!W+(jdyY{y+{Q#Hw zy=oqydS3m@bf9`q?ULU=&;|R2`x5&jBjOXYSMEEueTSG%W`~`BGDZ1P?Ys}4k$6Fn@8r6TyM~RZJ~jr%l3sheW3Or9sC>PndAq1e=;*d z90trEK|deg14IwtiG1+OZ>Ws(L)>=`53AlYJt=gt^V5=a^WpCy_~!Qk{w9XMU*Ng< zfxwODdqN+ZADF(e`2o&>ShR?gpI%ljrb{J1n4e+tUCYmhegJ;6_`O`Q$C;7B{Wfni z{|n{rqIf|g@VXm>x4uDmmp2ISwg%x{(IC9nGzc%`B#m1$FGkkLcAw(V@DE{Q#lhTB9A-9G3gT&=nvQzSoZ7d>U~hrq8TkSyox2%fXAw^hP%=cAM) zAN9zLuzY;co0rxr_i3-3%`ea&v~S<<4D&7A0N|s4QM06z<6`fbqdu7f?|Y1-Oz5(4 z1{~;LGWUFrqs6I`^6$>?I}_N@IAla$*g1t0$WK^L7oOqn_-EuKWCi^i2gLjRz`Os& zoE>P|F%ZUF@F zy~N38-5|O+oFnKz~8gMe_V?oj2M(=TY>Df6-q6 z{LvrVhnfy_eyRS4!(a7^@9)Fjn%#%pZ6`Ru_X}5h@_#F3YW^eSml!;h``EAJw9%yz z_@5d8{%1XS^xYfrBW6hZ=1-VEWOy6hfzRKQUsLs-$Y!Y@o!%$#Fy3_e{tbOH)}0fR zJ2k`4Cxdwex2NBOw)ZgncHidFyB1y>@m%|ZcHijfOT=lrs7b&B zpW!+7D;gh!`u?p~`VcU2Uu^K_%RIpM`#>My-9>lX&z}x{!u&9b>hm}N3A#}39_qi7qihS8i{@_? z{wYa0jPq847ukNKcG25*-maaqkMRTO&UyGho4dPfn%fP_ z%lV!TIvG%C@tgvK<@dz!0PV3pSR(n+%0*ny&Ly(^xrL;vu+^A!9~^}w9Cm*j5zk8>2dC=2IA0H0cX^hM$$dtW9jALMo{ zj+INjhXLArXJQX0X?;NCF|xRfTd!Im`0Bb}1NOajb5b<|{w4bf~n4TZd_7#tD!bj0X zau4;K-{>NN7mfop3GPL5H$NdFUcqJagGj$8Ve?q~&b86m?466pDL$rWG9$jn@M?|Q zL>jkr@Ev|`dblai$-vHSTb2rf8I<*?-l0Em-7-$*!~QsIBl?CGzf*pO9Dak!_v_Ru zED3$=JtsV$LU^p9=hzA!mW9vFKWn0PadoTyH~t2H9zlB=H#EP)-h1uV_W*ZLT`G2T z8QqDM-T7Ar*X$1Z)kV*N&-dp758)5!WuRdElMX&9{CN5px!*N`?>-$67X!U7>)HIl%7+i`;e7i}Lby}-J}g!8^+JV{89_mQy8QXWkEk7^ZA^Jk+m>-97@C)%2_r=#sIXkb!!*Y2^_Pt_?kM+mqJP-CNyf3fk?%f#tkrTG zQBLF8b`D26SjmJie9X_bxJ%S3bTTGE_Fk& zo_~$=^Z!C-jakqdVlKNrs))soJ?*v~odJe<1g^zF__x=#ZoO$vCXZ8=m)3 z8|JTs+ZQohn}?YHp@YFOIWW4~_XKwkQ*wXl zj{X)W3A{+x4=kSO`0h!BpldqV&h!iQT#2xE45y7R%)TO?2m0u>KGbu1BD1@yx6IGQ{0-x8-)o(y{eb_9 zcEd9SlHI|-_%5W?x43>dLHZkIHwm8RKd+E{_{lJZ#`mVD0dEZGv02(NIYhi0elc=! zU)(Cs!<*H=SSk9&=B36*Xa_AuGy511)7R(^=n}bgx~=@&|1RG_>Th)aHqJM@7tLSK z>1h5QDPIyipfBM+1OG46J|vT?90Y)_u&i`YJs0Ub!`8vVGeiI)J+IBt^Hzng^!N2A z#slp&Urc+)iU$}U+fRe{_|QLmPoApMxq}AZ6O)KA9`#Nt2JY4oY`FibtpWbUjdGy2hWTMjLQOX3r z-hqd771aM+ruoKSW(TX*%ZLbFR1f|99L1W_!RHxod#~QUGv?v}CA2~|obWk7bb`I@ zqBP_gJq4V9p!Ju5=K;W$o|lY%Et)p^2|vg5k@Ehy@6&NFb%>q?DZ}3VjCWYxCv=}K zyf|K?!gTo58N z^wZc4bBMHD1FRc6r~>cll!mdI{WtKW*UJ0)l$y-Y3-Un8TLxQ z(H;$(_~;G-iuB?hF7CePvxfSQ_R#N&___K46I->s@-^t? z$I%y`FVEKy5PIa!p>NXi#`ky*POyB8Uq$@f;8Q;4MSzO?g_@6fGHt5}>^u_Fr;GKu z#aY5}EvQQRM)li0oDAMhH%Q{*wUP$?(1@M)kqN%6`c(94bdT^&q~l<6V|onoh7!hS zO{#AkUY6c2{A2rr2jjPN@KMGC^Tx{wzQr9a4r%8K+IfOF!x+~nB0k~*i_evGlgdN) zCDISW-<``MW+w>mkn;UHUxHp|x|Adz{bYFs@#wPe{z7icb3td3SF;0lJ}2-2znQ+h z13>9A{c{;bqkZ8?|J3MW-{;s(Fu~8A)*k%^zCK*|+ZLY( z9bbgF(GJn;VV~Gt)5ms>iM3;Xi@*N=$zOthpGB=eZ`Jq5Eso&ktwpZJaZC^q_-wn1 z#^E+0psoKK-ID9%%c!%&I>BXhClTfI?5TT4?fj@UO6QlU{_^vo7i#5$ezo#J$6EQo zv{rtLm%oF60x$53ug{EMAQ#{VMV&_Idu|BH;tHXYoJs2iTVc+`p!J=3j$fmeBfebozdN9u~LKQ}_>E;&&7`X?ljH zH)?vSrq^q_ozuRY9K`y6b|1s_=ezBM7v=%D(Ej_VBVln5r{i{aY1-QD)3mj_P1D-$ zgPi1Z0uld6wrBF^xBCui*WXV&8ufYv4)FTbWO}|+;gazO-sU%&9Q*Lzf`0S~9Ssi6 zgN5$Y-$?`ta6dnX;A%V2yT~`Y4R}^=Z=&2)D0h$Gf!f1_%p);`O6N^EFu5q@zY*y`__@)Jag)QA^(!zS(n)QF!D!# z_{h7E|Ifc)wl~TS9Y53son8Wd;Fcw>!gO4Ur}F%vUxAJ?2e9|)!eW*%fV}KdI>`sG z4ezjcx;{5L%E58Rf+ql_`7J%s2Y+t#J9iNJ-Np2q#Po>y@C6C_U94&2!{=$*=r>u@ z$3D&@|IGRD56`X7hk2r-&!;SJw}K0WPjBbJ?yu`^5DriQv}^ufL!(^ch+}zn@8Z*X+2_)8D7XaUr;2b@QaP&++wyA$ZA^%wSiv@O~RMe`({SJNNug`CadCUP=AxmG&$yYw<=K4?n(1O9`&uww`2h zM4$f-DgV8crl2+t@Sh(5A1#%3LCZDz;`VK0`)1IzxxJ7 zn5UO30omXbbdeDc@6a+_`zkh{k%vMDnau5cggS9 z*}OE=_c8$=9O2VtFSUnu9*6$u+bjJT{X#~_-gC1!mhDdp-z@xf-pG{B>!(Wj+xb=j ze;4RP{Y2ab@&A^D99>I%9ro_wc5VNjkKaMXZyFKC-harYE|T_azNh$fc4IVPpU;u! zhEFRe16#+nI7TitmHnb*e5-Sg!O3t%A0OyL^kYV%A6Ife)LxcF@B8(vA3w+YFM956 z+#d;4#`8{*Pm7;f{2;omh4Ha<9OK(G&yGZoNKeJzvw1(tp+`3Fw0SP_pMiXP&n_>u z;lE;peZ6b=-$RU84ewO0X#Mi_)`x#V{9KCR?$`0WiTKUr1Nzb~@VQ$*&^W1IA94(S z#kprjKifBJab4TD>gboc1z;GY8@mVb{R+-E^;%Sdz~_poi&se?GE-U|>Ch`Kl|) zFCnC8I3t#(`cRKZcMAD`9^861EycCoq^%MT16`nt)r{HFZKw1Gbs_|@b-2t z7{0lM@A;my_+H3f%z8B6BXld+Jga9aKaX^Od$DH*r@M8&RqT;|XHqiWQOChQqCnVl zjn><*>Dijz$LV~}EKV1)*J`^$&q8({r^BA>w7kskiaoF7bhpOwiao+d(aZx3&(`@N z&xhU)4@oY2?;z?}E^u`pknO*-_o||fMe_U%sb}9Sv~hyp{}NCBq2HkI)4>j|5cYKQ zJ<4i3J*zamMEg_Fw6@dpDoroo=N8|B9)+a%_F^?DRvfk*YEEXvb%V`oi7Q$7P24ZbXaO(I#L{s)5TIdr@OO#T7Dj< zXp;k!ciJz8J*EXr=w`dwOolRlSmjk4=CE#n$x*J@hEHOj8mw2Uk91E+oZb#WYd zuh5~)6;_LO>$UfM< zyRanV7wI_$VM)d}()S^v`=mc+2Vs|>fs9}Laeb-_FyD7x&!QodL8QFNKeabZd? z=NHCr<9o3rtd3g45mO zuclhDpKbQW-s7*O7Yhl!h@I;;kMi~Bt%-7zsT|}x`}5eJMS35logGd1pJoRwUY$uj zm*->PTT-3$o$&$u6bEWq%2)VO!w z)p&bj2Wjt3)LurvC+^QHf$vcIl^&#>w^sCv2tt?d_iZ?j(jW@**Yhp*%XB7xgj}4FY7ppDWN$AWaweVHu?z-%XKx^WS_ue30Ox{3pn7i_a;U z!xi#7^_-H^=5ZQ)`2qT6>s+0ir9tRd!cnP!UIf9U!|WkJPRrKDbm7hZ60RFJ}gj+A@k$UdjDea%dIo*45dfq(X z(;wj@`_gkmH5;OjKr z&HF2_Ia<>2&ZHj6lra2NXY%XOknR&$>naQND$0 zc21M}(Ou$)+xu&NKQP{im!mx5%zG2(CtVMI-g#K?>pLR%)j-E#lwT|a>vAm1xb+=BG=ekZC>qo`APsR;$NobOue2D8=+!=Vkp5(8V zp1hUv!3XqLLr)67(Y%b|K|i3Jy$5Og_`;Grw|I-=Lyeo*IV>jsc#e2F{GEZ$2OB-P zQh(e8{LwgF=+CSC{*)vibaCTE`&wf8_z%Y4t3t-rm-K%#sdn~%fhR_ADE=bW z)av=ce?xL&esDSvdu-{U_`eSg($4p(|CvDeCLKJNJ8I)Rl>R(0NIN?!{NFRU9pB%k zAs!O_?i-}N=R$9Y`l=bfo>m^Pu)X#!nzrb6sGyRPGMIRz#qF1eRmhNV_qHl5D z1685-e#MWlb83A&`l!6W?qU6nhy~4GbN=5T=VB(|m^_1i@0mn++$M;d+^2)ZoZ;hx z_I-c#4QE%sXP@S`l7ZhorhAl?b9O=HnwIvWtlAN`ex~-v;jMaF?Unfv#t-RW{-E?( zNOETWxUJ`>gK1nZUbhqb7587-HMzI*Qo}H||M=CpnO+8@%j~|zbN%sJi}89V7jx$% zz;2IDyf=6A&j`<6u^aZDydR(Baqkg0;1|3jYkm>zK@#2$g6HJ9B=w-@;kSk5B|Hv| z;FSkn>bHgE)m$%{B6P6tNr6s~-!#u+D&;uIuh4t(cs!F4vw4ukY0$rCJ`u-XOit?A zz4J+atiHYPm!?zC&_E;O41F8+iM%-fqOD!=6Ml%=S~M;E618F0Mslm?CKsyC*W|}U zmmdnf+aw)o{68G0@Xru9_WqCUC-L8}ArjO3%!dWeSb>8$Jw{?U&K=@$D#vgS5T9Ti z?uS31`$+7ZZhyZI${8Q}dg%vb51^0fG2;x#o#SQxU08QO`jKeQ#?Ozte1`lP(__m> zU!Ov7Y~IqO>x@Phvlr1_hZufzm$c)~x4l#QNAqIp8lC?u-xyg%>`nE99@=5J<#);#Q*SfIR3F!@-x9tg&r7Wx=^l-`t8;|OOg-y zHGKY?&wYXyT`g~@{}4ULdqa>*T<{x>zIdJ`_~ut8*X#WLV;+X`D@YII)z8Pd8n~jB zV;JxJgYV+I>1CU@MY@h=`}l0%r0thvd+nb`s_SZg`&+5~C_6#uvxA#uKXDu7`{kB! zxfUsxmvYO9UM=)M6cPrEG!G%Ft^(VQ0GaNSgWZr}SLY{VG4me}eK6N1*C7kLwqD=s4o}XC@K< zlicA-2QtA5ceG2n2ZfJKJ}_ROwC}G?CAiQ_?UWCAyJyM#PvD`nQJgWS=d+Ye^zBu>7k2;5q6%X5oEg?ipsJl_zw?%b-9ln4JN z$EnvFr(8<*SJ*ka{`eX_%cSq)xQLuTX#4ZPe=qm=&*aAEi+}nFzgd5f z56$7?+v-o5KN#uv3lQ(Z6{-JZ{F3A+;B|$Mmq!ol*ACL}=|IlQswEG5RUTFlKgIJ| z;V0`yu~+A{Gk5Sf8-AIQbf_m?nUNhbza9BJp5OZP#kiQCV(@G{k7r)HgW-xC9?!gX z+xd{^J=`zDE1tjYQ@-xg=X?3?>q*cL{er)N@z~o!`X>y85rw z`}J~1xvT#ld+!2gS5@7QpF81_fYnI?7s9ldJ9!fsobZfMBmo04RTGrUq$rZf5EDQo zHv=Rm$43%G9=-x1M0{nEKtiictPkRIQmZ9YYoY$sSldrym5SB2(OQkRn&0=k9{cWl z?!A*qM9BZ|Z$oC^z0cZfuf5jVYp?w{`<$)tXr7D%1g*5Si9hQ0z?MmqWq3xtUeK-O zogTt@InwRrt^t0AR^^8KU4wL@`3v@5Mkr_Zm8Rye_ecd0e*x)ca8oc>iQ#TXn&UJnjq}kh!}#F!(2kLh#Qza2k+B?p)|LA_ z^1a?(n-|fKdJf<`KgRO|)Kg4!-`DS1NUa>_Q+O=x9`)Q>d8dc{ih=Wq4Tzn7KZi~_ z>A%pw@5Xb#-`weFhG%yRJpVit9&i z7lA&n-{gEWeP4YO+ZWacH>rL+XyedB+8*wE%RIvTr`Rv~Ka~4`!9h5WF}+07=@!M; z?EC8f1-|(@Qt;2r-wgY0-XEbSK<#1e;e216cckE4m9}fR-&ePO*z7$j`WxJTBt4Y> zm&iZ!&)IKcI!_%tLTIkEX-xRrrq%k3>xcXMe11>#yjlH}1K}QEy<4=umqxG`v7I(= zz&I-D=zPNQFw|aObs{Q3pk0D#g@2_~Gfh9k_Xiz5>{ppxkLB(3+=9M7ocGG!Ot{T^ zMIN-L41FDTZfL8f`QF!4@?M$uJF`PE-8?@@f1w*ylAk|#A;zDTRzLW_{20EB^@SMz zyE*vfIrxP+`0wQ4x98y3=HR~p_;mGRKp|eaQRDti5|eME@C*A2at_t`i1&OXjr|*m zOQv^mJ9eTTws*eht(|+_QWp4h>wY;em<}v7Jj+#17>+2a?26I*NkDezIEe=zUiD+;&mErib4ZK*+|{JV);lVNvjlIv&M}VV*Gabcc?>8dS3YJP%2(%~k9V%Ge%}i15-knseKk6AOs~uRCej_X zgL+5!&qnQLn&%{)k4*1Cx@h~j;r$JNpTNH-Hfx&N*-6w+=*j%DrYA@e>ulpB?dMgp zS!*>tf3?Q8&KC1kxvfb+LVJQ--+jgxqQl<`S<7YDOcv-hx}j< zhp;Pqa(3l4)Po`H%7GmGD zU$ZBA4%*jcvimov9k^f5TbD+uUmD}Po%~ua)g|$LL0>>V)eP7whL3q$H%)mT_`Kc8>%(($@OitFm;Wfh zV}0K2j-7))0=q*Ggzft(js(Z;qkb^|Un9OVJ&$SQFVho|ZnQ6>M2=w|G%L|`urCLc z?qFZ`OWOAfvRMn&uFRjO@pRRT*uIF|BKuMxU6Fj8{;%co$w$(CVlJQZVE&j~KIO{% z=j8IKC(M5q@`HWJ%||(p?goEjy7J@A-{Dm&_qz$dI0sMr7Wex{0iQ140I2$Mv>0(c zw3l(YFXrmmn}c7QgZ~`sS+a-KBx&Dc64&gFj&n!iznqDB(#`I_nBTJ1{FtY~f7ytE zHrAu2{!27}692{KPq7`@NPb3kWDnZqcEit?$MAO(KEj)~AJhxK|0$N++gUEs>%1Mw z>&LA*_`Ds->&06DKWzUcXIJBM6YjrUl(Qo{!58+EE6Jaz9n?4GZ;9H?^v9WAC+a44 z={}?z?MrvgzWk2-m&nfDM7kpSy-;5}(IF7S`jmK(&)8u6ybCY^$9xK$6z^Y1Pi3*3Jv* z_XoV+`#l}L?^463^Vu4{{}6dOzDnW8lBT`m_*3&swchYvafjlmeTU~smAjIUdDK2h zJAZtAGw$E};8&2pSHQ0(-E6VbU26whU0av)^`_Xb*h~K<(ucFg)c4C>d~W_C@6}nG zTW?zfx%qjY+J3?=q2Kp`{QcL-ZN+3F=plWR5EI|V9KLZgblgU@2Yubv`M~ya{VUej zJxDYE!Y2ANR69>PL_2rp=(_SS+j*(A^Oe@lJvn^;)7{uk>J4|8;`V;1MSCYTYwrLG zBT!!`SMueT_~-Y0`2JqHWv|GmGU9lF&!+D-d8yo7UM2fZ`eb|$nd_~T8&AYhZu@fW z`EJ}ETL;Q!JtlZDk5~MD|F-Q%_&7*2*DtWei~jy#9uL!KVz4iD|_8wSGkZf}yHnPfEvNp%@{ZsQcmBj6brpGBBIL)kQv6xNL^XBb}i9%Q|Vr!C&BI zPTvekhJ6mVr)j6=`~KUNhKF>shxM5~_j3_`->xbxA!FY5Oy z^IQ$OUy_}vbWq==UhijiZZXzRA3xrKBE-w!{mAvYg6}-jezE&656H&qaW zK)PO!n0RL5s)_3M&xyT?>zPdW%>pj((SIKJS?(e$Hv{Ej_~nFOsqiuW(+SsWc)&c` zw-Pra5n}u-AD5eqa{X_+QQ@NUH|5Ha&X}&}qMXY&*n`@BoX%IndfAhj4)fW4nw}ul zV!dpyq_d92YR~<2mw}bNW_L9Hcl8WWdp6BcPuHSh*bh$qr{?zG_9eXC} z_`{=wj^l?x2j$u~zNXhq??T%9|8Vy0ar`#y+n;|C7UB^6-sy0zBRa3~bsYI(Jt%fC zo5NmIvqN6*q4#~&|CtKAMHNr2U-`ao+<*C;^?hO{;qU`tIQzftxT>tS|NB$vCx@mB z8wUt^diu>?9ZvnNw~9ly;o?Z0~!%$M>a}s>zf2@4$O0 z&ETIixh9u_TGr^&-p&K-`nQ>v-Z9kh(ah8zNqag ze97KFI!(rvWP;Ziw=QYuvBONyn!5;?z8D%>bHER+g2%gw{3!W{{g4^ZwMvY%Nhd=T$w zG5ujVsah%w$UQ$XKk50A51#>_(ti9v@bdx1E;a*7nAi;Z@Q|nUW%@myuIafYFIJ3O`bbllsn~6 zG)ocZbDSU@_k$k7F;uHsFZb0b2lsz^P&w-_jkt?o;Oje0{_hg`v%J#xPI=ype)hOx z(%-zq+D7pOB~Jv zRdrqy&I47I58?a7Cg=P*2<1pf*4INi1_Z6x;Z02E=p@{F(c|r=$D2%#+5774*BGRW z$x9^vsiYUx3%zr4^h!T$LhtK^UYmz+-YN7tzl#ZsD?+tN|D$~=Ca3B1CU$`{9rB|) zlAp_o`CZIkDaA$3dAqP1&k46k=-Xrb)O7==kIyfJ9peM|idWD>D|4Gr_<7viEkSg^ZAM?xjLpnwx-~9}>iz8(I z+^V;a@CD+r@!R)BBwxzudu-uci=8v_ajjzC*K>TVkAdZX4u3y<2Qt?_KL076r&XQz z*7~2$du#oV)&~BQ-S3@N)gK7`Z<{<8xl#}E{mk3N`kn>-a5`O|IIfq0g3o^gQk-vt zmn+`Ec^02%v8plX(RoGO&)IK?=PVc=-0LNJSSh?t#?|cpd8(HKS}wgt&ncu!8qa?? zo_9de{XPMoC;9oibl_3Jhx^tHubvAJ_wNnZceHIjln#8%;1@~k^O^8o<@5uJXY+D} zv-kbd@ZQdo_FT*Rx!wNz%^s{*yP4hs1|XzwrS(O8t3+65(Dxx&FC~n7?6jUMjL!K+ z|14|Q^vC6S%-_{H`8uEen)6EFodCS#|HDZ8QcN1``F5p0*mJeF;hssmFW%2D`uo1| zy+N!m)~^jryIyk;xB7pAfy(!lygyOToW2X7OL4md&)r&{aA=CO<4O$F;rqQ|UTkve zR6d7(V(S{ApL8ld?g!Ov1WebW_xEKkyh^ITG%dNc)kl(z?&?T-&)?Sdh^zi4(bmMifQ&&M$4 z)a=1MY7g$5sr0UyEit~^wV(LXWqO_?U2gW_b!s1ISE*us;k&}Sq+DFzV(Q~&Vo`s{ z>tDkDVB-V*B;xV@-!+xmR+B>ylFX?T)L+f6?QW=NA>~LX7=iL+U^`3H*MUXau8y_Z zF5{=)N0RyXl<#ss%jA0(5FliJ56oR^Km5BY{@v!^reD69{qiBHCgC|(()CO1tGInAv4bHv|I^JXr`kHy@0MQD zv$zGF-v^z`pz~CX%E<9TXS!MSy++>w)sMi>{g!sQKWS+x9`+r>d!K$EP_Rq86h7Fc z-IiV~aoFz*_dq>n&sW&<~8sN zl+O@$`vCTzk7m0)810V_Ww)p0?DpN0o*KJ-QJvk+n)}`4;s$;!UNc- zs`;t!H+wfu=QV4}+TWJh`oeNsU+7i)mvxNR=eEue%Yo|$ey*DKkN)tX*CQ7xzHr~) zLQDI4r1k%>9ywc{`+7v}ULc!~ZPxPH^v4v>W-Xsh-(zVl@8{I|I&__<|Jq#vFPAEO zy)kZItM!r>L7uUl=RDTwYrS6bW)WPBzZ?8(wobAibFOq?rqGA)X=pp_`yLJJB%7z{ z^QXyP`g#K8y@>ttA=SsB)=U2Ne}=O6re9AJ{iOTlq`Qe9{y6AtwD;q3{5@c4AVL`a z`s!*aS6g3Ixz@fXce_2`t@sBPTiW#akn0j0#2!8$bhY-=yVXuTjduIq7Ib!i&PKaEGe_Ui zYPV+}w%z{hSx2YcUPAc{u`cn%ua0iJ{SnYN9J{?DXSd%nq0vu261&~~6xnUA(;vxt z@^{hxr^9aF1Bd%)UdQ+~4!RA;ZoeJ;dM54mlcckW-Chm4jwZYP&n@We1D(H5cKev4 z)NcP7&eZ}ZNz-{b>+3W zb!GDZ>9EV+#X8Z^Y?tQ`(=P9YK0K3l`J5K^?#rO-XtK+EU#Qvmu@iLuKH23<&pbN) z=>s?~72AjWx_1US9nE(6LeMuHe|l5SE|;DnyZqPKfO{(K@?$x>O#VL|cKM8>+%Dfo zJsrk6@MQ4onY7FABAreA<*}gaXtK*`3p#&|gIK>$cKJgyj!wHg_Yih@59D+-+vRtI zzTw#AT{*kFr2N$Q%O^a=cDZ~f4yak+{to&7blBw#>orHSzx;i$WjJ z+2!hJ44Mdz$M2tr`Lc-T4q&@p2{_&x`eY8@5BQz&ZMv@(m)pzp9`>FH?d+5S{p-E5 ze^J4E<_z)ud!HcuX33WKGXIh3b(&_so`j#oGXQ;x>sd~?^^I^Jpx!~o4AqsVOPsDI z7No0P5|`}zK)iPiVop9<*@XKjt_27{lL~ z%UiDVDkOc{*z`(MSd?$b`pSCUsOM?Ev&1b{9^r6kWV>ZjUwbfgUh2R zZ$)z))&03}51ZY;9?tP>c~bb3&Dt$-x^()F6C z-&M!FUg&!me@QCu*@L?hzN7B_Di2oy90SWSI9#*-_ZZ$EV*h&paO{7{Uz$?mC+S%w z{qHfkucr2X;(l#+ct273QF}j8+gp1-(b_!#qzHUZrA&E8{gHfNeb>OBO{*&3aGs?K zVIhR~1*_96?e&x`-B{1;7WKS_^{k#PPnSojGy;{692b>vHH-X!sqJ19*O;Z=>F;2uG)Kb+U_3k5&z@;x92v{v(NbX z0?4mgyYg68g_-O^5!oLeruDESI#)y;c7yCSWE)%ttx@7wHr2N!;K6_4(}ApECR#wBF5M z({y-m^RG1>-rM|wrtQ5={~n-!7bu&ra`5~2iV0qlN2u}h6iYil^~Fo_kD*#szSi!~ zH21FW1N}|JhTh%miFxudyt)UJ8~&cy0z-~F({CK;C+GazBFU zQRwgL1}8lz!wyn9W`y1!b&P&Li~0>zN#z*+1s_2rv3Z521k0RJN`Xex5FG?`Nlq)V}XkDX86vzx#Xu&uPEMu;W^Aedl-l#zphD!KDg7e*8ULQ^qKc^;Mm}h3^)s zTN?D&+a2VyMDeg*_GhLLy`^ic$=&)*+#kN&L|)We2FE*j#2B>~It@uKDQf@gdX);! zzl%F)&)X+!d8e=aa!p^e)bcOZnBQweS4nQL`~^kLzXbKOM+`31bQfQ~LmLGYiUnEXWW_&AbvYJQ-@^=?4( z*{`SFW4cY{&+oGGIm^EYQxDf`zb84n zna~k`rfAyrm-+y*Tpxa`?`fXS`Y9ZQpqI-ueK>pp8|wJ7AO17j#dfClJ--U<7K68! z_0lc`z7%SFIVGlR3ZX#XA^1YPWy0BaJ7d3!{nz_RY#fjp-@BQv)cS1Mu5SH8>>AohIdJ{)_FQ{E1%2}S-M#+?`(Wc%|JzKS8YOu@ zINXc(0;Qu>d%I?`HIS>(8;{TX*l*ve$XPT#3x z)$f~%{?-jRZ%4EHwE3KL%*U3~;oN8aelX1IEhfXgPrF7JP3cf{@j2-_?=b1QyBS>+ zI)eKh>Dz!9;rzam#6Hhn27bYmB4}PW z{3Ojk|7>cz!rzRa0e`Ol<@MM7iorg`!}|V_{NAMgVE%q`pC>uJgwHV420C+kT;T*7 z!N31rl-s4b&OuD*nI^ zO9y+e-M;Sry!Eu(rZ3I-^Uv5aarrvl%*Ov#{yXpaQV9t?Yfn8>+g~!j)7#5-%#Qf! z_?iETC_mianB%wGz0$}(l!{u(oA_?R#Ld5RUK(Zg&*p)Z2MtRK5R`MinG--~`3=+x@bT<;Qa~j=taP`@6m_;pf`&e2(`SXt&AtGE5=q_!jiG zI$-O@wl7f~&~@xe0h3?^AID3h#z?sa{Lwh^u?SzuzRTcp^>t9zyBPOd`913~KGN5| zPO8N{UrI-Rr>1#cv4Ee&M87NR`zhH;aDotO-vdOakhGp>$xgC$Li1}g`~D;SY=(yQ z5Ysc?CyV#X*P%>aAAO%OhC3sM^ZA?2N8|RgACMoD@yyrv-7k&#^_j!O_lJkT_m;!N zH-`9Zo!$FqJm0*#v&I*n53yY{z8Upj^9%FskL^G=^xyG&efjTM1^y3#k8)-Gygz@q z_)^1{nqR|dFT@kp^@(r!AAk?N#E$u|odZsns2`JukN0PLrJTa~xv0&CVkU#^nEd=PrIG){p-)J=|ldzEwNr-#P@>-fE2;^!{T*` zFLHdd@3V$}QB`=#<2SH3&PVdCj7QAB9t-V*1%-PU5q~=0nP%{Egy(wwHsle`^HVi{ zIG+FjguzJ?CGBqKFVgfXt9Nj=rk5cq(H!m!BTy`~x3h-t8>i5Sda`~|M2xa zpRZ9bCSjcN^{r(9M-!4B#3bzoZ6@r266*WGnVnOW8@Y2_EpLO9%zI1w5J_zfrQoKBMFF^J3YZx z<^J-f=zJv0vqy3r^|9Q37(YSHc7m*febfI}*Aq5Nb@E;hx}lttfGHBV@w_)q9|wCK z>_k+K`W}y`Inf4$|t{tT^%^nDX57UW>|&h3(~k7sKR2>qFVuRWrN{+@rgmH7J5 zM=G{X?)|~fY4|y>u>XoqLrFB8Q<$psIUVtMD(g90^tta#vtH)AepL$E;a%_I@?1x9 z|DSwhVEKQ;IiT!LUGJ@}Q>ee44(Pg4v-t@9`*>ZJ>5}ay__}xg{8mg4;aUH2kfWbZ zb9?0anwh`td<^pHRr+ZkX(`gpN`KY~gp#)Tf}OWWH|zec+mY;T0tS1g--+#?u4iQ8 zb08p3^o?>NoqzMIsNWi0zTd^?ABErL<4f%Kd>MG0?({^ZuWJ&uAMl+LC4(1gOguk; z$z{y?r?%Ptq83Zq%L?cC2G6zfX6MN_@`L5yjPkCJ&FJDhIN&jVnR-u>yg%}N2GUU) zY4rALeJ&r?Q|0sIm(ouHzPujWc*1ht@2^EU*OU0XGHY{IZ>$ni=ak?YC zR{?KmcSNuA<<)o|%J(QIXNeLXDCbu8>x z@8^>k?{v^`ICw5-foBZp%j5C$!<>JCgu3~}KHwo;p9G(LeV|gnq=RsgU8G&+cr~2! zm-0SqZu}aE`d_+P{Tv^U+z$)quTB4AyT);fbpA2u99%5q1wHZkN2~U6JWalcfy4sw zd{o+NblCYMZ-1c2<|WPOn0177jLXsSf!~sj(@>uBhG_5|ZvJheM@{&-*Z6rp;9VZx z{&b7l`N{|wUj)CmJ=~LR=h1yUcYEXO8t$L_xty4P952cLv7p<(JM8{lHcQ8obgQnn zW%Ku_pKxwj>9|-8KsE&k5PbY19c+33&5|AT!tIZrPiv+h)N9gH5jkkRzVBFDU&+;{ zY{odJ13uf!9@A&~;{0%X8|;qBA)TrQ$Hxzjx2%D5ybyGhfSDmXR_o<>!It~}qVxBN z>z`nFo7e;A$BUmM7n&Q+@4F|1S0YHT!-i@lf&=j57>A&bYtj9PFEh{pv%yf3;7 zeDZx!+S|2%Rc~*U^Z6b7Gbs%8+Iv(k zpBlY?spTe0B=3_*IXF#>yUyfa;8Ax>-rr(Q<(S>fPTU_Pf9lHhwJJBLb(izJQC}W|ec-wcQB+24mx>2BYW?)nNUGc8t~-o=tFH&Klq+nL z0@?8^gr3y*>up{e)_rVU$@ekZd$pdvPK`tUI!%Xtr|J8&ol`WQdc*^r-VVR_qH77M zLB4gJR`Wx)`*UnJ;8>z^oQ^PVpS+)kc26_B8p-;clq=jL_4#~>c8ID+zWBNT;kw51 zFX(Ep19wY)Y(IqG)-Qwou>M`MOLs}Rbn|NE%OpvLe(ZKFyeDbp)2(Y2ey+ho&q-OO zX!KcsN*_?Y3i(EN`jF|X4an(s)%*5a6`$)(`)W(yr*Zqq8vFU5{#okx_v6wbKFO|l zOyd6Ox)0&&iP`Zg_uBWn)vt2@GWLtaes0!!XxC^TDd+cb9Nw<|lKPBn_)X_YeKmgS zJqCF@pPIdMd)a=b;t%%3?WOUp$N728wE~!KwQ=o%<=W1<>VKtMcUu|+BBWb)S(?%Z zKhA-2Bcxl6-xog!f2Ip6(|NwJz2j`On4V<$`A@_~p?!R7@^8B>cQO z{BsTozqk(mg@=S+T?c>8A>lXF!E=`Zz97`S)w<#KI{4EL3BS7zUKM62{Cn%*@lwVi z=-FQfuN`S9{G;mRHRh1`%XRQNZygH%%sO}-xQ2pX7{RkYu7nTInEi05avP&^MOf2A z@o8rryq!zGSeoDX{ql!2pW`#<@4;WP{!RMs#X7h9SG4QwxxSA;|7=fGAK};XUeI;g zzq6C)Nd@UTJV3}!o-J{@&iePsGc7F@989~caFyC zB&&Ch#_1%hcaFyS{RKAz#O{cwA9DI(}sH)xVhvJKv3}viaN9ZqHKt z&h>AOJDJ}DWBy7ueX+o$ohpy1pl<@o`?_7b`9+z1_ddPUzgxFR%U!Dc$T}8EdT_b6 z)8|X4j=NAY2H&Rn^pA)?eMsp`x9K=iI!^mhx{}nR{&f;bf8;(S`vd8x-%JQ!Kdr9o z6u?TM@w_~HEhiK2S!)gx@AvD&bddqr#EbaNM z>dk=a3+|`c&vLbUKI{9Fe{VkBYRp>d($GyEND6o@{og zL~3gNcW|~O!#p~@%;>EcovMD}{SSYygLFat!n!*B^%H@r&(?{2eaGkhJ`ZBKN>qRC zz6Bd!(SJO^mBhUTFB5xHYCA>V1247xp{!h$+D?^ygHqdgS#c`0b;>;_rM8JO4=A-w zmibeuZK~aWaGKqJ@I2vXsjW+Prb=zkmva-PwiyX;xG1%qm0 z&Bf%jhI|$+%58b|baGx)Ow2!u@KYm-Ng03Z;W--ky;yO*e3PswZ;#f)t9~}hk1Mc6 z(TaL_o>TGjfiZsa-`_ut^C=I%S0K)(W*0@u_4w&|74aWK3{Uy_zH6LM*PeR0mUdz> z5(qy2`utGV;q{T|z0W&+-alybgH;e_8F0&>1dJEhJiKK4u%*H&s?UWE)o0js%D+_j zBh}}^sX}=P_rpFG(tSSf{kLz5POOT_Ie1!o?(4#?$39PY{bic{wwQEZ#CKvU& z>MT7yhqA&zOXvl7t3s&nE5N-tz(Pg zQ9mbMFXj3`wr0Q5(Mu?-)u0?p#rx~@_sG}l&_L2bK6$%*KEUTc_<6KnYvWBUH(!64 z0hU(nTyUw$zTg4M7xnxwmM`Q@&E$LhGo$v>Pu`cCcRaULn@^!2rlr5)tsfrvk@PjUT}3;WZkFRAX6Vv#2XQpR{(cfaUE zO!pEB`T+H36A8BkrXlG0Y(9k^nI8DQp6gq-=1JxAntc{4y=)gV`aA5L$5ufj>(AnU zK459cUFc%v2>u>yqaUPga(b!X_`goSiI?ptBcJV{JgNg)fB#8ZL96}1r%Erpem~dM zpf^)M96~x)^)H*gQTXQj)Y)|PcYR+zn|`}KS2cn@sDB^d<1GB#ta!OTxR!EVr)l!x zO)&Vey`UZN{_g9-gnKLCsAtQcP+Lh1zONhW*-n(t>^-=e{wm!}_{3Xp z-?Sasnwkossnay$9weDl zDNJKBNw1cuZl90#oN{G|?-v?5wT9RCgY)<3)bOhz@$*)s|39D$z77)m?>|KU3+;{g zuorFfb2)yl%=-h^IT(od4!|wL?=t>9V)6BO-;rT(wM1cmk@f=36B!&l_@5WC{5IC3 z;K9#&1nDx0K8$~aUs^DHYmtHA_JVS5wf{9R_0lzkZJJ-BPt(JZ!`g^W;`?+ghe?Vj z@NllLmS)_8By%d5moTvZFx_>Y8Yrjtx{lwdy_{9!-=2uBX8fc7 z9QfBy?AHIuH#;Ze_ZY|a8|*qry(Qh^cSZHE{m+7qT(imOxmnPPJ;9@4_4A!MeD99= z*{%5U@4M&qw0)7n1-`b_)A0g0d_C29NUW!$zg+W|n(;aISDNYRt3^-M|4BEi{}c0@ zaw1-mZcSOR@U{L^lm66LRQvw z&-89dB0WKVTsQhciM>B%9V@gybu71dvBirdPS>kF3Vz?LyENbD1GDb1wADLnou;)q ztW&0jNBe7L_oZiRHc5Ve$7+d55Br&)kN5rE?0EH?W4~t+`}2d^F0OO0W_qioVHc@K z{=J9z9P1bOo{hpL`F8zq|J<;_1^oz zu=W24Z$=Y{2WI$SxIgh+X;u>Yxw;p^7e2{4bi9e%C3b#^mAge_ z;{6LS*5_R{zUewI>153cjXUiD&#(&r__J$+0AT*2`x(CP-#&&=HT&Lmio*H4r3dn4 zPNnS$flId-y=o>B-@m0^60Y_9`Fm16n?C&Z-qWPL{+_Y#Q}{lz?k7a;Uo6#y_Gia8 zuQ!`MQ+Vcn8~J=|(|Xn3dOQ0~j^wZOM@~2pe1F5?t}{5-r)*7G>bq*OfCu_w`Oky? z__^Wi_->^Sa$xXv2GZF_I~4Xg)sLxthr|4tYt_$*@jnjyS;sWR8`;ypr`}$p_4v3( zJtJ4s2bE9hW~HZVELZW-?*|l~&FA`JgTKDJo?Z#LKP=JuC; zeQ%Yu*W2CS@e?WM=U)5oRR5>n-k*s1u{g(X@`vpo!1(FsFb40HW}*GN1nlfb)IeUzAU_&X^AT zgQbA>GxdbPxH`^665t?i5LL!pU%NVh5dHT#6g6vCnGa$H|i{dt*?VV0=NtCV8<)~ruD_?vb zl9}Jof3B9xrr12*)&c!}MBg8(-N&T$26@=}KyR;*gL5hB2b2nvr5}|Fr-^(^g)TeK z(rxEi&VsJ-9Lu?Oo@JJuXL+&Mxl-XmJI^xL&a=$3^DHm3^DGPPJj<)>Jj>O3KC7@? z^t4oXy`5)SA?I2ATn_h*zWI*hlvw;_KhSd*H%MOG5BEWiu7|Wg#b_U#?;BuRCjIA| z-~rdYID%!@n%&+k=w#lB;i(SK-pGy>6CGz_`o0m@gL?HG$g7pUPQ}Z14Cde{iehqk z1KdX=I6p5H*LQ#2bNl{eRL>oC&uPU_cl3N!^ql;pYvtdgjNz`z!BOMN>Dvr&#ikt5m@SyL3VTayN4xu6v(FREK2I|HJk#v+3(+RR%`y9YvDxRBn|;2_?DOl)KBr=z-S6PI zuJZ4e`i9!~Pe8xxEBzIYRK9+~_CL;fovmB*IWfl1{}#`=4o?0$T>KoLLBsrDrO*-6 zM|k4jkM#;KUrfx-_6oT8hiD3Tq3wvvqsvJ7CsE$(C4EB25-m^s{7zf^d>$Uf^nHfy zQ+2|99W2fIUL$c_ZZUG=a(|xV%W^3unuY*p^1LQf|%PO-qc5lZ6k{!-h z&>m6#EO!Uwd&(6#mu zbXA+urSpBtp_BAjKZ@IP6YzTfbiY2PkLP5`x3}l$o0en*{hjmuU=yIYNXk#KGD}w;W)Ebqs(5t&g|7nvsdpjd-b5& zD>4Ov_R9OoYtYVO@~4tdzpj8^*|oWTV&%w}{}uSH0w0f8A}{M#g!>o3rQ39Vnhxl? zLTz2<{aW7mM|xb}=cAn8Z&XZlBH?_F;pPIalIX&W)9rGM=NV@~-j(ECQeQFoU<2J7 zsAmz~Um@L_blt+|+cmmxmGTYsfqn+Idou8qk`0nBCU22A=F_HJeV>>5bUy3rBenWg zX?Y3-A#VR<;nOXWAME{rB;{N&=e=>ecCwyryJYb9}pleA}dcli&MR`F>E^q4)AN*q^B1y;s_y^thkw_lZ-!3|XhP&+i2c-;e0j=RQ8kIrVobPxyrP z?LR?B{QP_0`SzV!s)m>47X8D2unQ*dANci4ydLIvzT?rCG5`GeKY5GS%lu=vedA>2 zpK|(ZF3oau__;pLKh6Y9zuotx>-sDuVYaV(5pE-v;(c8#?%zD0!*(DF=W(cKB(@@d zv2SGefIHoOuF>iB_dcD@+PsKfGUR4_W<87WUN)cO|8Rew^RMAMbW~o#`MD%Imk2(e z%x3BOy1#Gb=ge#G>n>J({1ZR#v|Q4D|EG_`SDwJpU&j;1=@!MCZdG`Hk13mVyOgh< zM<~!SpfUL+{b9YP{k~!UP8rvQ59H?Q{|?ZGbD|MG+6nUOXTa_ASHHjV%CXAVbc@o% z_nZNSenW2!{?kN>6DU(ILY=lA_ymwxN7p&yIpvprU?eJ`v! zNAZ>H{gjyhGJXuf|Ji?C-)}z;RH@wy=l6cb_&Dy7|6f8|(#?BRkGAaA_yN@`=XZ@C z^M$}Je)I{UXyZNaFJg}GfBHQ;e(sv`WB>E^7ZZI?=t?{H@9#5KbvQ{T7cNP-12uRV zYk_=iUBLO%ufssN7pj>2T=jlH;i<1XQJ>49nZB;b@#{VmO&{8+?cc6`)8K82Zx!@O z+85#9MErN_b3cdX`o{jSDTn{<0ByfR;r-t3+J2box%-3O&trLQI7EHBa`n9lRZ(sX zoFAb$-e2Ena^4^@=fMo6k?s22?%_FgE?2E^uEfqw7ZY1IRktK*zeyhBKB={Wr+v1j z?HFKE{S!_1Z?IV1XnD_wBso1rSQSF}y+WCNcObKV73^lO;&Fa+y?S)6y`32H-Oh8| zV}B&vq6p5%UEc@wdv*x-SRI^>yFL%$^C#<`YrpmJJEm(|9o&z#ec}7JWobz5es3L@ zYwx$ALn5RTB*M5YL#lkw_MB*3&N}sZ;E&BKUEX0Guf_d_@jd|89lf1gC!Pk>u`&5YFsae9o1gmfx4$?0rMx=eYgCch~F_NQ_rN(|wwcktS_qzAn z`0w}Cg?WUH8`;GwIB#dTfBHfwB7*yUevWMXg<2om{ZG(eFBkl(VSMj&E>L(m+7I%< z!jRwD{5lrQSTCv#^)mh4DBtzo`@7#yS|Y;{(oU_3<-UoZeh+D8{-uxSZYP}1aGrsk z2BF>jQy(WNf05@c+8Wn~9?P%b9tsA3KQXm?s^fbn>5uz4NVg}X^9kfHv-PO1w<&(V zUuH7yU!*1U`#9tNE`HGxsW#k4H+YYx&yHETF0qyj^E}7=I{EwtNwmMMrR4Z_0R8%@_V9Ux)*`2_*~C& zYX>KV>2~!q{hpW#?rmW3`(c6}4JbWX$4;elV7bKpK5Jaxyj*?Ttv>k^`GsyV0}P(t9ku-_nm+`hdjo`y^{~^vZbLE7giV z`*{4lQ(+&sX+Hg@c-;2&?s)wEC&0HFcims*_?zU$-`P=``cuZdnlZ?%yC2Er$f4HH z)zti1=Yz`2&#$E34~&oQcM$(+z~l2k*CXF=bo~nF-)#OA?%ljs`I5a&`*G0sd77Ws zd#~5uYbW0rNXLuN&h$o2d;dt+YufKM%BJgkN_=mVHO6`*{s)Z!^Q|25mysrZo?~=7 z>hGJSTU1XfBZ@4Rr2POyaQoUd0|pks`QrJ0zlMJwBD8y~fY;IWB-+LLXR>{^A3W6e zSyllq;G3lQ{5w&>j&*8&fU`8$cU~9!duTuXMAp9)v^jjs_wlv)0WL4U#_xCQz?PRQ z>r3~5-zHyQFZFv2!nk;Dt{vxTI`0RSMykJ(&QSvWJWzU}>RqKxpEu}(>4En<(#7#E z$lvzs{TzeqvFnN3**j`l^oIixqfZ+3TU#If%ET(fG=y83G z>E!t8{nFQGO8%W3^PjywzyB&vzstq-H1BuR{NxeRpK9};g3#~&N8a!C?+>uukD%+g zUd8!8?x^MaeN^FmT(6)Py_^KS^z}fW*AXwjV^}fo&DSZsJ#Kdi$M5|FzS_7MKmQq~ zdd{C_D^@@g_aFbn_7$&`eZ_d3 z5xubX(2u<_?$;PU*z?$aeov9>JM0O=IoGo&8fU^esc3x5*ZZ4Xy;O15+jf}s?yaj= z7o3J_?~iiza_Ncn{@0kpYwxbQdM5x&{dk^l@7@;me&6b4&lnD$H`dil>QQf}M6#~% z<+vWmmk@qG+E9G?cw7#805J$(9y?6Ftd8g-UpK(t@ctouM%w+0nC|z*^@DD7AHeBa zLJYSd2S*4$&lJP0$-%J)vHo|XJ>C!9KX?1$_rrLa@N9p8p8_NZ&Fsy+fNN%N?vs4A zdqdfq?_($!%HDiJp6kHp{EY3<$6>Dmon;|2xpFoHiQs;bkCSZId;TbbSMtL5n*95Z zg!@M*5MvA*2Zyq^H@9g2s$sVORI#UUgh_8zqPlY|KR!hJABfvOQOo=NKCwI>hhjUQ zTKOxr^*r?hYU7vU_458*g5b}f4GiON);N~WkHF*f4lokI&w2a3_C9Zp*Ws>$eA=&3 zJlRGq7wXmFpw1uk`DBIlnE&D99_{?NJ=&Luk@9>X8ee_9@%v@{TzP8imA)_M>k!TM zb_v#PnD{^Yei8m&jVu{V4JEYCXff7lHGpxcxr=$W+~e zKDghLbt-=6cdLBT^xw<&if}G?Gx-)_`F zesn-jV!sdWqTElmB9eEkS8s;n?)9+z|3Frr&d2Eqs{foYZ(y@}SKe^-;5pjB z9dkA2^Zunbrc5ol8b8n$2EWI6$3>cUzc1W-JYV%9n{V^!SvJqULg(w$+uoH+rQW5> z(%1WX;|^P2$>#5}dH6<&34ha4U1eN){SEy)W@x=(onexuy?@92-5BxL-*X{<)`36N zKUUD+q3Z+j`iG43rjL{hKt(QVP|nvKLjTFlm;D@1m`^{b>keEun+ZI=zO}&myRXad zu=>28#_}gUr2B=e-@YHXV~Mrf?sXh2X}W!~#=bta3T4hh)-p5#!*sHsQ=jj+)ZomBY0!)O^>^Rj8Ny5-i6iFEF}%U3-V&@$X&ku=WQ2pge=GSCc)Kp8kF1!LsH%p9f7ZC^wzgl)HBf=>!&-MKC9pT5aO41f(~h?>5<=8>-=*2unK&tYxf+b z!|j2W3wmtrqCABjYoG5w?6BuM7AhXsd)EiHql`zPzZm>`6+C>`=wVAw9x+DdZG&?) z;}W!sP49XY|I!b9mc;%%^i#6~?U&2r*rYfdqUJ>seg{*@$XH$K8EuV$LPQ-_pJc5-@fOa z_s4h+0p{$Wf3Mr=<#?WKsQEJ-pSi!Z9s^j%Gn{?47sFpLUox7WX`l*jAiDC?h#_PPEz{i*3gJg*Z!p$cHagCE_9S-u1Yx&Pq) zCi8!a^~->d%5U)N5a;W2dh>L)%6GgTyB>se6Z+{ly8lo5{tR@)ocI= z*O7g^tG)lHaQXUv7k=(TheHS2#SrK^M4IDA8Srjz{2T%Go*^#}_cuB2mGRu|GySi% zNOzqLClJB?vA+5GJ!?rr#r=EQ!46FnaQXh+1^9Uh@UBJNKkL_G7f2T^$|Z<*GvB_C zP5mQ@exEz#`9eug#b3zP@HV597O_SLy%GJcx6}`$Ymx4suJ_;gI7>RXVoN&q$#ZQN z+fVv>5I3WrbmD)|sU4sP(sd4?A1u{tAH$jpEvXmgJ*r8WO>6I&WTM_JYoIjM6GYU z(S5#sAD-pOyMWj2&w!TaIRo;|=k4ShF|phuh|^8FujBg;0gutg{^;;eps6eebO-Z% zY25G7@xF2lr4G3pKU|-P=ZY`$yt@jr+4I-nxy#w-_}i z_w@=NH{$u^d@R&u%K?bs{9rj8GY;cQt8*x&k=n0o`!7mBZU04|=k+?jui)$!JCvK_Um3S& zs@5Ou=L}7^&(YZBP5ol|F1t_1^{vP9E60qN0)GFH?=zAeQcfIJw8Q$>WV|;?JHhwZ zBqk6-sZINTxYua9+8bYQ<2nREo6Y;h@7pS9-XUjEKk%KdAk%g*h){F%QE`L0L4KHz>sE4(cC zr55-;7~zZ0)$BxpP*00-A*OdO@!NWe)7_E}L*OHaNbd^|17B+MXdmweCn=xvIlN`~&Gdq9{6R?VJZV}|#q{}hd!IfZyj){n&j{-QHox3)PCZ;Z`WA!FGgskv z-MqahkCS-4LFVbuGg)s!%;4)1JFK3pSMxKQCwhBVp}TM$%FhkbPo@XA;6jCWec56B z@p+_=tE&KC2B`a=3rt^qKI8h}vELJvO+TRa#pLSeC)?L)y}lpr=ULKav*kf)Bo=EC zn9rW(=f?d!d)LN-JokIDd>nH-L_PUAz9Z)2Ki3@~V!8i%CgL0LoFVOH3Vcv>cyC41 zU3Z)&`RNi>0N%C0kWJCF+e`XE)Cku17tl*TuaKQIo8SR|x`a@AX9HuucVPTRrl1GC z8aqB;2lel>^8T~~!0+w$_j$eDzCYsoZE3I3ZT?YqlBT^MlHL!nAN3kt0Z!8+jqkn= zk#5s<$Q}$&9HG2kKmQ${n|K6#&yJlb4Jw*dY`;z0m)$&Dez>0a`m*a$%l)ItTHgKn zE9a65@a;^^_x{LsZNvVS-&;v|iq_w|^YT5GALtmX_T0~R_6?@A&yIug~wPa{kBTr}#m(4wB8Iany?Lvt6BezR_eu({2_y#$#oj#s+ouGnSg-rgMikO<|ez()<{hjnOWG9s+E@JnO zKVo|6pEw^}uIbhq-3x>->X)RO_e%LiIo$Jr7KXRPoKG?1ZUo-ss!AQzU z_zpZLvK+>t55@RU56?dk?n3mx{JktiIh{d0Qa*dXZuY$*SuZ<`_P2L?aI`dfOI;z`d^d;Cs-Q@>oly&Y_Kyf5kgUbFrD55RHo@ zJr+&^+!UqL=P^D`vED0zuh}_{*Gj%B`cUUMj)6djI>+&K_-+mJ_$5jY>winBMyJ#3 z?H zljoDcMD`Q%lJ&4Bu-tgmQ%Mwmv*#a(@MnuvPT6AXk82e_?a}B*wJpqPb-rO4;L3Qu z%HpNCe}q$srML%=rI!{a2_;Jl=LjDjMjk_{aF4})uissg=5wHeK5vlp(!$6D$JBwR zQ`)%{=MxeSX!7NHzv?oBC3x|n3497pJ4vc}4F%ZQM<@&0+{6o)ccv z%Op*BN}Bfyas($l)5Sy$1>rT_i(h3nHhY+{y`kM&1PcE82Y-rNRqjeY;ecW%nKy?B2rp zfKqsLXTZNy()@lWO>(I)Q*Op1J=5g*OXNB6Yx*Kdm!O~YM|dCOD2WTAzkW{#;i=EX zZyPCmhhTB55M?)hRh>*&UUP%3wDn3OnFXt_8Y%1gK3WA z{@y*)e8V<;KNP=ta=R$AVQoK6oqzw9@YFlM7m#V{mEQ}+G+k8x{w>qgi=s$F@xi1Z z&0eAD5t3%BG);LIg$tTKS<>qG5?@);%+=?Vb5VMyrs+8srPZ2-nMHaG{%V@?^K+fV zH&xPv(&vu!*ndbhjkDE+WPW~Pt)2zwIO{OUqpNBDh8veZ({}^ajzm3?_ zobRx|^ngipESI(&FD+TxHcstco7p{lFS&r{^yAL1P=hp-+CC>gnE$f()bfc}>DndF zm$sSxYb&e$YwH#cmf9AnpNI1Qa94eK{|9RS+Rjk>*H#fdV!bcVl~aB_WaY-G z{loX5Y2Qk1uM~Y_xv$+_tFM^cY4B&L-D|s4?OxkuqJM<{ubdyMdh-D**QIt3<*1*8 zFXi~5a=ACai`{EmAo@%A`*Q72z1|SuDW_7~%SFEle`7>H`K|p<+rjT@Q}0W_k4Hk! zJ(1js$*qF7)bNrBYV&~d=q<;{8PmbT(J{?C&ZI`Q^Yx@)FFNA+0hhN9fudb_?R#)}#)4BF2A18+A zTbn-D@k8XC(@VAYv^t9aJGtlTSCOmwd{mBKTAotT=fBF;ukF(H3f6x|({{5KE&s;c zbH&e5MxVbThhN7hS_yrAQttUov=O=&!pD*;U zrL{x7E7(gAFP2F9d;vdw{POjWaNeg^;d%hX7A-AIka3It6GQynT3P>CC)wdXD((yJ zjO7D<9}5uDbt_ox^C7MeQ6gboVXNZdxh&alGQ3>B_;OEuzXyn{uT1-!T0ZgrDJtT7 zMVv2X*Xnvt{Qb2&-cQAJf^Hdi@Mm5Q?}vfY=U?uZ(ck0v;O8v8U8Li+IJeM)XY>d9 zk2g9VL;`{I3Ez4(?fc&3+v9ON(MYzF_^u=0HY+^OF-SYCJj<<)=4XWOf~xv@F4G&3 zcK>WR^1CwT3y2_Ji09>`<7%S=`N#@<8A?uh`fegWA%6yzTN2lY_OPdUJzVG7m}}ql zQF+q!A57yP!{B0xf_}Sv`mX&d#gWA4vSU8Ra=0d@2koSsg|BS?R>e;}{VM0>E(ZWT z8p{vu0Ep=6t{nXp(8~Tj70>%SexP(kcz-~=5r10gf1a=NBR=qa4##8GBQfYBO19&V za&{#D{C$8W9QzT=_rLC@*Y}O4w9y`<-%#$qiNE{$miGJiBAI`~ilr-=-+SXVH~9M# z*_s2=zVN+q|BheO-nc)s(g#`Z%<=JbwwH}UAiW=r+VAW6rMAyY{l1>b@tH*k|Lfg6 z_ws4w{}e$J*0X%QntnZsz^@;rcChU<0Zhm0xvg{zwH51NCzK`j_r&}h!8?)5@_tUO z)HY4+28dt@(y9ZYRoR_T85_f1~8@ zm-bSwT3*-lnP!&n|ND0tSl{x9?{2UCUZmQ+3u{%*cJD$fd&PF_gd^hb)%p6PugAsb zf2P8LYuT?sR~hv7b=;%v8A9K`06E9&V0nG#`wXND?0E|GeY^6(z9X6)zcKKeqICYo za#4A;mJ9VKmdAl6@}Qg+POFWF;XR)L6h`29dymL}x6niQ-EWNbXqV*2bg91V)cnnc z2aSmBCi!+VyI`MFH9ACytME_?Z*W%Rdw&T9uxVyq!*~6r$5AB`az>) z9cO7_vd+J;4n@DWRCt5fSMT?#@RxX=W9yJJbsk>0PUhip`R7LE zi^*OqcdD&J&a`#NYh)fCm+N?MeZA`MKW^n`+Ir+NTaUa>=H+quy)oZGxB9)0TKV&I zeqOi+ZGpTyC0oYtm*nczb&D^CaxzaZER%V9T<-Fyo#d0wn?4)Lk^iN_Qt=bxa^KFC z)A~Lk8@4D|fxEV^)RFak-!8>Qgyvv~nwKJ@ZEKAL4SK&DE#n?y_?II^Qp>l6iAn z?y{zOf2WnZS?B$QH8Ssy%blL1Q|GO>Sh-Z^|AjZn{68+YC09<@J>DqgVz}8&=liP~ z;O@)e(|Lbm|DM?t-}MdnCgt=*<-NQC?ui_~6|S!V?t!LouWf*<{aX%B`Ldt^?$%tr+Mnh(z}=jK)BZEJ0d8SaKF@A|yCp{-tyi<}+lN&b34P$>|MnBXV$RPp3A({cThEPH2GJlY^rjEy}1;Z#QP<>ecp+ zYryyX9Gvn`*Fj>w%+K*f@o`n8zTOu%h0`%5#`j1LPW6iq@a zonF$xa*XLuGX8Xwb~tYrpR)}QD_H@LKM#Jmx(h;2>_5}*={EeQV`37wcaQ1UhNyk< z{AdH_yH1b4AMEGDozJOVIGWmhedF&^LeKA|^@-$qx8}$AY42*~^|_z-^7C3T{E47H z+$(V(7=w`KOE?cd$?%=6vG>2O3(0+5w_x0ZBy%bS-EZ{wef)gQGLv)HC0cIq5|+ZA zI)uX64c9>=Hak%&sGUle2pHy7I`7J+>v<>I6JiSIa0e8QG8Vbz*DY4+bIOtBs1N5M z_H#@XuWvx@N_by}P7i|1&(A|u+LTb@>A`cx)I&cH&-BtLKk#!Ru|XG&j=;||N!1bX z^E@r*>(kF9KRG@>75wZ1o@V@fVU+LZuzg+J`CA&r-T*r0KmZ7(0!KZh!+mc0yfpF@ z$q)8&y(FdHkA8vQ;egRZD9UUDdS>^Yy1e|oI=|m7oulRbe4*bP&US1Qd{A(~$59=0 z@gOonv-&?M@G4h-|0Q3)pHubq8K-A(t)Q*@jvI6Q9I3zO=laa?bM(DRi@;ewV>>l{ z=0@$W&Ueba>Q zv{&g*m(Z$!&t}K?emX5n=@_Ni?Vi8?J`(1ZCDKJK1v{z56XsK+xSqTpbUL3a$LM!I zN_d~2q0|OrkC2Yhf^Jt>4_WGbrTrqluJvkQ+)lSoKqf+f!*3~P_M&T=3Wj!!p~v!l zJgJOO{mR!@8fE&nPRqIdBtI8`&%STs>u;Wp;doE2^Pl+)*;KXy@yXg=zfUJyvq$w{ zn>?0rUhHyJ)9$~-AMF9jq zU*q_CkbMF2IZUoa+}~mESHpZzvo1lroB3<(eQl(P()Ypry;vWA{kt2nKY9kosqkJd z3M2SE7p>mIEhgs(oYUE?-PF`tyEqy^KS7_g2k}~@``6g}+G>{NeRgVW!~5E3Kik`i zAGCMu0)GCeu^xM0JF162SLV5%l!iy*1lTdv$tt~biJiN z#2G2^KLVHC^L@PJdq@CD(rH>gwf>wRpQy)#Bc4Y;kNVBzSB_(=(Jt%PF|TX)db8=aUT^y-4}%zx6xQ2gyRi@a@p&NO7&7~gD$~>(-w)yV zH#_S8eos`4Z@b`A|C8|h>elald{nAp>zzmxJiQ^*p2?gLJ@H$I-l`=2tO z>Q#8|BY!rwYhXWn8q2>6eIm@qwkkZwE6%@M?>G_XsF}2bDY)(ndY$!#voh9n`$n-4SMX)eg5X@INlzWi}B;LU11y} z{I8;PdLmnk{%`^wFt+!n;(Gowf@k?3M(Mm?!sp+@P~iKYJ}y`AUWwpeq8%^oElZm6 z-4pRKo27c^<9#;E^lg^v72$VA{LN;m|3!GH74Bct`AmL%Bwe3}Zsh6WxmX707v;~9 z-TSwX+bsXNT)SAVR8ac7oqj(9x%!zu_{K`YOrCh|)s8>yEHew=M=?H3QvOp2l|F8|IJ)^j>!4)?l%Q{h~}f}@E+LUtwp{C2YipH z8|hNaw=R4mweU-b(K_Xa#KCffvVY4Hzqf1r4r^k2eHkmtItLU^YA9+$QPO%olW8)!nA|VVOU3uf{zIwwT=_z8kLg8egvvRrYpxS;x%aJ% zpR4egvHC9@*I$8@r`w`&Uf0KI7jOKK4GMtEI`lqu+S^azU)G`DBV~HGJeOfO@$V

qkI>;a7ZCfm<)&$yFGe80a6co&`2evb`LK(9i)_Ou)SC?|+g&R@49Ohw@W0{O~)N8-Hz@ixTNaR2Tz`8?wTHGPQn>iKvU>s49O zt@Y|J@2}yZUQI(i)T=S?ujNxO{u^D8^y2?Wuey;UU7rvhJHPUN@Z`eIga3)WV}DLQ z{^sC#*u{??eD1Ecy8L~T|ECA{Jy^@9zxK$yUmwilec1TYHFj%V{e*w*jOOsPcU@yY z)Br#J#OCnh(Vx1;Zft=6mtu4He}PTv8hf|E2Y%fmY?Ae@PyYCS5BhuctHAFv9`QZk zPyYMyfv;WX+$rV5ItJu16>xQS4{aN107R`>ow(-$tU*)W~f5Zj}SlyW)AmbX^b0rtebzN9Cw7 z+4P;E-1e9+xp~jw=mp4yUZ}id{n!`#iyf*T!_f!!VW0O6ZUAxw_v2_s>-^UFrk~m! zlWe}ukNlor`YEE1^OZ00c}3>#g~Aksj`(I9>VqZw$Xr?1S}l zHU=S{@3KF-{Ns7=?m9hC{fqI&c8C3Wxbt3}FRT1xd^?BWJNZk}`<*YjdyiQE=$Nmz zAI$tZy)!!)*Si<>l8?{-pW3`Ho33^!>)0UuF5E{wYm@fR0df((2=E^%f7jO0tNbOs z+n*QPXYHRcy?MUZ>5YG9DWY$K$iD@@U#ab2`@e2{Ky)zdLvpZ1;CzjtbgT}X={UFV znxC0G(lJ1U5bVmGdxc*`S63$9@@Fk z^1C&z)myA@=ZueAKht*ldcEsuXs7MdbKQ^hx?kRP5mTCG+=C=@Dz@HpzWL4GKm2={ zU0198ipl%5ecn%I5DU(pjM13uMpRPggZD%7m-X~_DqPpa>i7(rzMgtKZ1J(D7OAu;9c4E^+vHF>Y2wY~9r-&o(SIZCIui}SFV$a=)$!I$durG+I22hnd_ zf1PhGSL*rk$JO-R;rv`iEBvkSy8U!M5dUvrD!e~6tYaD9tG#MZxL<-MK;Ak}$!2Yo zc2}2xNQBhn(R-IFqU#my9!+O9-^R%+ZkKYE5zmuyKHn$*Ulh%gN(E#fFn?B*PyXP4 z%#TP7^brX{rgxQ@OwxO%Y5Wo$M_hhRzw1-FMd`037b(1#zuU^&I-;-31U#sWH9NkF z+(sPLpDR!L&&ttHdL5sC&psVc{y2R#{LfeV?7kbn7lh@>2ZtZzAcNrd0hHQKm$c*Q zUo)tBe|K5()AwjQW51dDn9Wx|Bb&8d;IrxK&!l%tu_S$u>O*=D6bK=GukyKfgBp(N z`>5^cuQpHYJN{>ar_cOU`Y)U6{2KFruh^^g<-g-$^Pxun#{8A_QXRhkpz@?X{}>BW z6&ZD5ZwK@_{V@7Pt>nRSPoSKi+i<@2Pf`8u_wUv&R($W(sHS&KaryKgt9o8czOQ`H?vm8_q55Akzw=?J3CsJwZU4Rc zoO;K6zvpUjF%k&QhxBUePs=pFx2o;;edQhqN9?EB+e(|QgWRe1g7SPx)Q-|Ilx7pV zY4p)vk{-W*uf&&f5P}`8mL;9us0~hYcGTA;E6MjvKegYve!4!o-|l)D=KbpgJ?zwX zq`Z#{m1A_@BK7)LTK#5++0F~2b~?Q-FXun?kD-$Mo#1zV`t$z#%?_?C3tZZ-^$gn% zu9RZ<9;?aiMwN4VllITv6=nxl%@n}?H3x)_;o8Bxz4Gt+WQVYi{{EHAA#W#KZY~c$ zPkh97Ld_!1>!}_VlL2XG=pW&Hi1NwLzf=lbeTDys@rnh49biYXG-K}{ZYL{kx*nP? z=Tq7Ry}6~@s}5wTKs8)qq*w9$-}{H_mD|I9TPOB= z30vWFda18-bNb2_I^I(9@4~Md-hcYP?7azK)mN22{(W0Epb5~&Rw&=JETQFPfj|On zZCD#xASn<+*W{7BEG5ZH@)E)`Rzgd)wN+bNE$XjI7lpbNXVfy<8E_me>R9QFT3kk{ zGb)aw;*O5W?{n_C=lkycCJ%~sod5j(b6axXIrrS{+;h)8cl|Q|SZq8!BjpkOE9o}` zXtfabb1OH*`RuQT5X+~0r%2v)^z0_F2j;6}opdGBQ$76l7ik!&hxBtPr<5OS8 z&2MSXi1WPSyC)|;J4f1^Ymyr}g-(=ks#kPLC(UuRYG;uRW^#bhXZB`C$b&K$(dKTOoH6TNdvq+LKK?;XoI zy|;0Fpej_ksD^Y+L;1*_*7c(~^@=Xy z{D}FmjP0Ok{sx7Y`cb{gftio^)RJl80}nImewnIgi;9MN(rFEYZj!6uxGsOo3|@!n z+oRAp7tZyH@8NMl)@RatxE<4bxgDcnwx2~`5lr=ycN|CYb9**^u2vaKy(v9ThtqEd zKAvlJAUVKeY{g2|OH}QEe@7^GbjoSYpzR5atM7^>BJ@_u&f8q#) zll7}39SnQtWVF5|`{bVyBzAOz!wn$oxakD*|C(*ZDgh}c&2K4W_zo@4dObYia6c2d zA1+|IAJ*q2`nHo)a63}{==(KPC0U1`eGi2qoTqK7o)kWOGs|Z*aFYs;26%<<2!qZL z=qWwA=R`i8b0uHmMVw749?6eOcqx}&ABnAqs&Luoko%o7&m%se(eVEzOm_}`J`IWt zKY75&HedJT_DOCxkx!ZTH)?%;q*rC@$)(7xlrtLUcJlCjOfTQ35IrK_z0K9~Np>Z= z_v9Jwr<|;J-YvbK+cSc%st{%09HysxY1FdMYhUzYBK$M8&m{Ug;{24; z)$JCK^Lmwe-+_8k%M`ti6=!)7eJXrS?PUB|@|;He28ZP`{UrN+i_Rl=_i;U* zq^Fdq_@@0K`BA$?^SQw37FW^9I-9h6Mn8W-@m=;Gg^#k&84XZ-PQ*B``KG_SoqqDD zikE(h_XDUOY(P#8&W9MUzjKi;=KTHh-)!>T;P5%nXSIBJ`AU7K>hzxGelPcLX5GgT zy!!g&T5Psr|I%f=kkd?Ix7yr zhD)EP+`<=+-$azOh3Wx+)~VZjW}OY^zvP3ZycVcisOwJ zWUshD4QZeEL%^Rsgr#!pdM##HZ7~#YY@Y3_G--;b0^KeQZDiCtS za^aoR-Ae-q%Ckp#YTTwA8p1q|$@!$=x}q|E_G$el>tOAmqLzAI`w3XYsy`X=h=atxllT{Fz8HTo zt{dSrj#Kz){EIa+KlNM#@$k}d%NWURZ`C|Wg=bWBqd5YF**{pUwZauEko$RV|NV@)VN_#~0 zIXHrqev7MUj+8q#b*4fPOwL=!9$>g|4*SwBecbJpUQ_xL`igw&7e|qStT%M){x9+y$R^L(_$u#fHtKd4{qK!~7rUy0>501k%Xc?d zD74y_LlraQrq7-;--SL-_1AJk{36vw`equo;-wwsT$;Q~LgBAB);Hrt6btdaB1|pc`J! z{hRV7JxlWjDo2A8BhPDxXwEDJi=8R!F~fK4KTC9l+vzXTyW&9w%lt#m2T6TozA1KM zAFFdu4rtv<^=IuTf>*M>n8N9k{y>n^H(eFSX#@*tycheS5kfkf;FU~I=^=_!r^lJO z=-=M~EZ@r^bw=TRQA*XYd-Ob7)~6_6;?I#aip;a8MBmkIVm#erJB^<)ZQpq5>+dEu zA`vQY9Zz2!vUer{rgGDlZR*yMk8upuBb4MX`84E{RWs3R7wNz0_j5Z)`$a=Ppk$ob z(r+kV&Ku8a`8NeeoNp_i@*z%o`RM*Qe8-`)L@-=%So!9D8NE9o`}Hih0i|DV!a?}B z9#<1Nyq=tX@|cPb`BC}FdbgaHPw(e^3W>RJ!}`9AoIjaW^j#HS-ucd?H<{(&30~(; z1bO98@92?b-@YKTcU7;xGDN70`K2td99q)cHV2bB`R|o*nd+V8iDW2$i zSyzn){`D-yOFzZ!5v%S2gnab-Q?b1)XR~V2(cmJ^9mO zw6<^KkN<~CN7i4W0m^rxBX&qT`i%>W%;SboT!Itmhr}nbf5i@<`rS(O)A0u`8j7lR zqj0LJ$UF5T$~Y04!r{zLwcm9o(RuMFsC*7GJ8!m=^c#|c5yTfcOFyws)h|{Y z1D47=SNUS6$oyLJ6F#P&JgMS|UTtue>-gVN_-N>2mOqqV$sfv3zPyVd`jzw-NlYXD zkcE_f@}P>p`*M|>+Be5_byaT~vB|!rofkQeK>VaJyioV+XZ4UH^^FF8sL~^t@*#Zy z@xr_M-?Q+P&M?9w4);f*r}iNHAbhF6v=j7;9iNzuII&`?CE`hZ!lNZ(#p;K`6Gb6U zOOPL*$M^aNo9EvBf_6kxLCwr9m8F4<$e9J2DIp>l0A1eJ54Y59qI8Und zqM?61OX){LlYR2W?fI9Jx35}qk&(9-J^Z=lir25CeG5e%Xb^?-+Yd7C(fDu#?JV&; z`?rU^{`@BCFHFaU(T?sw~}1W2Zg-aTi!F&Br`^N_!@6+$+`DOed&#Oj{6DSDTF*;wlCzye`KSe`4e#?5NlwbBAr2Mk4 z<9+85`h}dQpS|{Dz3h+A>pEz!ILB*8d>21OUyL5Nc-$ksL41?`E_PHj^mEm(MbF7S zoy@qU`?2U_utSYox}4F_zx(`f4hku_V43KJ4(A`Yfovv z(R%o!mOi@h_VerE11h~ydf02f^XcJNyZy8t9@Tzh>)}j0vHqq0|IS~V_off3`VEiq zJ)4uz8)6@def~=Bp}Su~;k5fpy}w5D@){#ws%IJIHRPij%HR86T<>j0{(s4O?=teG z`WE@>ecOL=y&p94|4Y{UkdZId`)3%}q`m#`E66-j)?3VZ@%iMO^ql$5!Z9P?vFf{D z^&1{X>3-d-{m#Ny%zEl`V`68JKK~i=m-TX5*C4$gtDwKo+ic!A4S1i7+!5ZEf_=G; zVV)+bb0Zky)qWDh>8#wd7CkTxU7YTbQzY_9ACr@JWn{b&dpY6!wewb_BlZ%dP2-Qu z$F3=VhN3&N{#a;?TSV8_Orfw7@lVYgw4X`;fU*5h@GVb~7(;X;Q;nBz}rMKjM z`s@*fR&zp1qCtJt2lw@BS=ajWN$dM^X^!UY`^mci4T}31|Iu#fI!;Jnr5X2 zpGFku-Jc&_Ue2G=p_<3;*82;x?odIgBR#!dIIPdji5x|gHNoZJ_+MA!k?fC5L)_wb zavqe9w41aS-RCDeitg>J_68}XBXU9OA*P&}@}cre(O;6=Cgpp4)bb(u`0G7dz8jT% zM4V5l@|$ul<)I9&Dc{8T%u}8ta-L1Tqq*g3T{4>c_Ori46p}w`p+@+Wk-r>sbJucx zeSApZUNySkSwB75?MH!+6iX`#4z6_C+B$l{WW_%E_F^KUNrYI=g07m z?8F~9TA!T_zY)IFhgJY%osv&6k&UWn0_}YSXZ0BpLSdsbLlj^VZiAwcc`ec@F zPu@2In;a4eT9c7-O1ml_1my^e<+f-(MgcMX$uamI#l7JDz`{bs!z1dP=#<&ATYw zXPHdR*XXDB-a9oWoXj_7Yq^qr9N9mXbyU&cBzIJw2CXOMy%Kr%UGy%sx2lh>MMRSt@_+iylnm{+#niy~#yz`knmrP4pN1dk6bN2q%&Q zC_j~B2tM(@u9L%??qk1j9sB7mTp>A^`%|1MhKLD zEvI*(`P2Cx7g2AE^19~{-Hwf@H}PHGEu2l0UO3{f!WT1Ks0RqipWgR5t26}rOJvTyF$iKxd>3P(A}$va1l$nW=nhi|s?k48=?d6IL>g*U2bnfP-V zjyQUL&LH-2=BZzq{=|fG?nvxa(gRdaI^RP++0|x0NV_T-?|Yb@900B45WbSbW~OUm zv2zOR8P0_sq4uHvr}{hUNlwliM4Vr!`cb}S`^tA>n+5Ioh+lD^A$RbHiWbUW*C zqA$n4!WyQNcQd_nKvYizQTeDI4LBc8PV{e|)=U2LSJeJQnF#-y`#muYF5>8WCzH9~ zMnlsTzHc%F9xk=~8LlVjt$B;y-;?=2)u+UK4{^p}ZvV$sGHPAv8I)J%N9j2wDj;3# zD&M>}afs;jdt|ikLvHwrlPW!e3FW>2cLmEC&G++O;4%}v=wW)V&n`EY>(wX+@pG(l zoH6HvR~%nqkW3)IMXI{qJac$?E%Rwc4f}U&W51wY`LVeyr?ENnRl2b?96#dlfM>Rc zl3TrQCi5A2e~@6RitM`%&$w5mPyMFXklW!IBMNV(Td(>J%RkYN^ligEo|eDI zRq<6ntXBA=UjA19n8E9lvc6%Kqg=&1G^%_fz*GM_WYmM&>CEeEcJk7>j=;M!wnk$9x#gKh_`Kc@~3D%)e}WVm)H=r}sSk*=CfJ`0|*+pJ;^d z*~K=o{Lb3M`q=w!ptiFMH!C(eeT&(r@z3nH)L)OH9Np!9em66}bw9gi?rfES*a0-o zVH+y5PJ~cOA-0**p>)Z~yFuPQY(3+t7Zc?*HQZt49Sa!`slL6)K;%K}^TM?pU)BTU z{K)JUjYm9kGA`5jPxYhyByv=4fM@#{RAV~9v|p?EqW$i~Z&m%}9JqJhV$njC&aBJ1 zp7NcYS(jg?@ZP>;RDsSBp01DDpG@FAFIA37oK7Q}@mfSVvW4R{f-S^xvD@15n~GfL z;t$+htiOE+egqsQNBce$-dDu((1_oZULAv;eM|ME`LWDv>zV<;Jq!G4__3`wDA-GH zA{YkOh+?Yrw4E~Q{L)HA=B3*ZB*a8zXZ_mz?gGj~_x03wEqwC*TXS5}c1d9+r`xxh zeZQTO2p?DWiR_z_yvzb)MQ&Pd?m9~`NuLs@hnKS+k#-uMu}g)U{qlTzg~o-k^vX%2 zKH2rkX_en-y>dq3hsSu&wFdQ(@tooneTe%y)oUz0&Uz)Izj}Xe(zCuc>)WN$f8~0s zS1l0CK*2)}$E<-#4FfNBV5OIE8}> zboz?fCwravFiWqyM;!hRYOH>lB8c5{wen?tC*Nn1a?v^kn&YgT$7)1&RKUJk70p{O zxNREOm-GddNbE|l+)r`+(t1BXQx7hG#QDCeH|0whdFMA8;PT3O3&G1hXrZThGQBJ! z_M5!(Hk-{Qht@+}r2D+~yC42{mEQrK->iAe_ag});Jo`btqjY!(vHF@{jUA)$;4go ze=E~Pu8)Cyd~Y}O7U}KXh);ToOZLh)=P44 zg8Cb|)C}f}=q2yFPmgmr?H8RSIeS9Gs2t6INxvWT@o6IV5&Pu+fqu6^)_+&^RjVH>rBkCKqXz1fH`N{8&{a`>?T>s^8=Oy13teBMZ%2u{Ao zW7-$0K6-p5eKDfw^!WNdiiPqPvrpxsq)30Pd(_ZZC_jQ!d7s7pwe*+&3H*KM1@gBF z_5APT@BL%&H?GI8jQsKh^Frm9#zhzP6FDA&JSlh!kZ^yF9Cy7UKI?POo*e&xx{=pk z{*rQh`~OfrUweUkW_kYa<8#Frd`?HH)uG>@Y*-&d5yD-lJezV1(RSvB&!>NR-Nw|v zQIns#A7t0V{LWNH53@Y~cj)1q|Bv(a-|-<&&yKzTzOuaj_wn_cu#;tclXdI(A{vFE zr{*Y6-5Vo`ZGgOyYsBE_!l(Ct$jLgO+$WN8mH6?f3SXn>2v2UbeZuQp*~8D%UtE=} z57IlkBn8T)0n3h=&@UBh&Z@N9eKKa^gle!}g^_Dk0O z?Q%L7US8ebvzB+Xz4fRmmo=R4=<;W=w{$+|9jAQd8J^*@x3oPba&azu>%Lb}9=-Q6 zArApmo#c@uF`~cQAo4a^KQB;>${v1^3jb5vm+TPM->+2u*dP-7JG;K-a~c^rWc~f; zm-BpbH+r0@HRbLC^dZS+1Yb2K28*5kmz2L{hWwEpn2&N0Ka21q7ImpunR5bqT(5#~ zQMl|I%*Xs&!S#yVncd93%=gv&95t*0T`Pj*eTn%{uLRHT)$|A0r}ee3(>(1uhG|`$ z`XCw~_{0}#`B;=vr*`A@Mxs;t_k9Yj*2z@)*Jv2z<@lM>{PVs8 ztl>taOY3x1@QEL?K1g{JJe#vq?<%T#;g6~p!mN6szmuc#sPD`^u3^xt@~mLElRak# z@Z@A2OxDfXfu|t)PPvu7F7J8MZ&1lPJM{XRIbSu)A$pVSM5^oT6&%l-=f00&vA@*5 zhPmH?dXghOcM|I*Z)eckzaDFRei9Akr;E$Jiyr624tO5vUyC%K7kn{iAm`DZ(d9j$ z$KN6NL{H^;$5{E$A`+a83q<$O7<6Ol@dpgLbg@gxjQJh!e&4zkn$TOf^6EWLMR(Fu z+3)LPzac=Ysz^8PlINtim#}ZV|Nm85RMw8x2dD{TT}<9_IoCSr$IlV}m9DFiet^h0 z7qVV@+<1qY_`c&8SYOlk>EvD3XkezQnXIeJI^_S~)=Nom5`R5;(Q;4gv6J`N?GKca z_g%&~lGgj<>4{pN{Cd&z4GaETwXp}Ul9E!qg?X64;fF>eY%{o z&(O!^CH@cj`Zu+P@RRf?IoVh6`jh@1;_w~3A9dsa(@{U7`={pjT-5nGtq&-_5nq0I z?naFZ&A$G0+t1IQrTrIbaW9{zbUsiL{&es6rAzgo@#dIsUt<%}?R%W}Px_wV{Rw&h zBpPHp@ma*Bs(ar@((miWi_2938WBi(O5T?}m;U^(_&yT#Ck*f2KDnIRkoJ=Li2R5h zPWshFJh=zdj!F>!$qpgB?B~(B3#z~O?vFl~GW&8M;pDteM13`x_gRU)P>0L+7~6rP z{!I4LBS!nkJ&1TS0^x{`%0a%1e{#N->@E~y;p9f9HRmh(?dTArvsWZdc9u@*`J{FuYoCOzNt zryFbKfv~QU=}1qJi-s`(z==FIF&WNz=BRS`)9EhO^G(Dd{>>_80hRZ}N6}AWxu^V? zp8isQV_(YA4xEdB&ud@w4~W7)~pr6d)^qRDM%XfsEmgsVV zKI4i;QXLL2;1Lv!#F`&bkc=ln7i)fq@s~4kOutJi{nUeX{iwfY%30{WW7gEl z@uglv09E_Ir}h#3=5M#my6+;D0O`*f{ECL@v>oEDQJ(jXyS$Gh@0ZDasv*QflQ?7H z(F|ka$(|aEo;1iOa@MjTD=P74zB5FQ=M55J* z@N3~Gw-6TmkFwvCV86l9?F2cf0V*2N?WE5m4e4=6)>-77rmR;{II{Nc<(hcaPR$5} zGx4gOnibl@t9BX#?}AkFJ%HaNuOzotJE0xOdF|BBu&kGjYA3`e=iO_mRAFJZxZ z9e$))f!_O*f+sz1wUeeNywy$`Pkd7CgmBeP&G-RFbTMP2;ak*? zBbtuvAo@w&f&4mZJUG&$1j~6~(t{ZXdqBTSDDQ(s)axveZ;Ir(Jnx*E=!=N6SB26z zK%{eXzjv1SCHK$Ys6x3s3crmJNfI_ViPwK^c!-*$B4uC zOGlMc_os-uRg3;dLJvoJk6bj|t$d0{d?x^AlXspvc5%51mwHlvrV`4$yzWL7?Dbm; zSN&}aJY_u=z3Ojc(5wD72HrK&IiSluN-yg69s(_ux2Ya~;AH)k`hlevMek_7ko>6r zMv>tPb-1jrQaIH|@Wel>ziE2HTm4PriBHtu=o}`^r$sL|0#^M@^kEH%;OusFMm#$c z`Msc)N8w)YUMa#sP9>Kcz0{w~xGWK zK3*N<_X%Wti=uW^B=0+YC=Zoa&eckN{r!K|5~8Abqy-)4nMul1>lyru{+`)w$8$!+ z4wj*5Rnb!43DapNsgEo}4$1ZQ*j?S;6Vc`{DB4E8&y$tG)(KC#CxXrAI~Tp3LiC z@;xJY&x+`)h?CHcyk?z z>OuXL%2l|M!>e>Y=vNev<}1nvUnt*1;CE+<&##of(*K`@p0MNx z1A&nM35$UcrIKU!~i@}tKQ;uF=YdzHw~ z_f`M8@P0EjOTV$@g7i6MkZm0B`WIKj+fSALG~CDmUOxgz<&SB-aAyUt3Hkd`O1HDL zd-vr3)Ov)ZMbBg5pSRyEQRLqH2(phqy1&d~elWSZCq;4~auHjq^@)}TkKgk-LR$9= z`JVG__c5WYLsNfHdPKKhYz^N#YX?jG5Bi<`^&7W(9*uZ{7u zwz8bf*7FRJTUn=-dbM27?>n07?zHbLdMLi1!`qRpi+|5+U-S~uQF{t3=lrGrKBLEP znqL`ir0H^oe!oyeidl*ms zko3dc$Xw?Si1Vyol9YD~GU3H4oW^ZxdD|{=M(Si-#k?Zpu>R4?kh#x{rxR*&z-ix;De`a?y#0lBy!|t8ONjx*Eo_sH6c8bI2 z;=KiGN2)jRo#dNf=?8Ulm@YZMKCS1w_(|Io&yGOoPBlk!Bc44f7 z1zha5%sn-9BseM;aiXwaf#3&0D7VO^t3Xdb%<|ra;*K|pZxOZ^NAazg(|IP&ex`l+ zoeGibXyoTgMx!CUKev?WrJvjKR^-HPL_y(V@g>TSIQ)*&vw&*wFYCJ6Dn;(pZDwEQ zCqrNhr8pKIs(ws7RMePw>VjjX;~Mw_Xm65_QS--g5Wx-MAGL@#e*`@_qPOOcnqKHg zj;J28?;!V7huV2%^!_&RUoxF6-jkFGTuk4u zi#Qup`%=HJ0X~ZFN01YJN#&yY%05h8g$lOxqiUZq@Tz^rz^nEd17C!s$4cKd@CQ&B z)jlYfwVuZ6&s(RJb?VtSa(PF!j~+**J;?r7?W5@nb-3&UQn+d#jVHOc+Q-0K?W6I; zM{1wh%eXvbUsDfhgs<8~>yupFemH-o+C}Ul%HIXO-H*%Hh<;@}agbd3XK6hAd+2v> z-xg}eMTp&B%U5~h1JWlab^^u!B;voF(N5Va{vqqQh1|Wpd+XFMT>O*wwyC}f*7~AM zkL!gA5W$h1=E5J+zU&JK9gV{(T>E8nKny46MJ2z&W`(xaWnG{opR&t2yd56ly?Et} zm;F#$*QRh;*B-u+q%^Y+?k}&bUknEnnWv8#!a0rpma^7FS$DFvv_A!8d|)8a-8gDl0!X7H_!w7!t1H=}ksIQ>R*`9h$Ghr=dJ_E_)zFg~ z?CnkV49Vb<)T(&{KHll`fVbx8$D!d#xs$SkE%C=G$@6Fuz% z9lmnt#F0>ca%gS5v&$|oB9Bl8IrFtyLV z`$vA1UQ*KeS91oMZu*xaZ<@F53zNUqv8Q<6l9?aL{q+0ZXT@*mfq-rL=s+YL&LG&&Xhf;S%YinmuyW2n5l}MGA zmWr%)rcl-PO^Lq2&VF=+&i0=8z+ivElkOHsD&(x5*|pB=Pe$?95_4>MpkBBoncUos zUg{;KilhaG2>B9o?MmB99dui?(5_C979L1I&!+~G{qgpMo9d0XBvvO<1Dy~& zG@??Z^@;v&63k@J>O@axqE(4gx;L?*Gu0g*Xz5s`wAH#+sOBV6qyIYx(rynFp&B_B zfbHm}sV?*%$b2(ozaLt1#ZEL%e0x`-la;pH2L0O;?@qKN(eSKHNec|_M(A9TXqcLD3T!qF7A`efQu1g415SKe6RJej~U3vhKt{N3xYQv`3^Y89#b+5jLivd=a zERZgltw$OiQAjr>Qji;e=k0Nu(b;vMZSZ;nsb7q$q?9{*dIzBXi2sv zwxe6$fZtT@fFp%v=8P(Csk;T^OIv3@4arE}8=T8sXoLz zt5FnKL_1JGWem_DLc+hLvpdmRH#k6Z1#;2{Ay&#zXw~s3c~8Jd+7yDVDnQbOUAHTa zUe`a6A{|EqVozeo1$W4tSV1-!`ZxD#9)X@B6eo1F6#HHflx*x6EAUP6EtCLPWHE&N#J)&B9%(^myz(PKTVn+ zO+9TSH|L{fs;$c6qGm~v*@>ci1}79m_t=RDhhXuurq7z45Wwu(3G3z@bm-G0Q>{o- zem3a_5f(LRc_Oh*D1&$G;&E7+*icOv(6eUT)}KhcHc`f&*OIN0)%oJVkRG~#SW=U+ z7B#dXbuM@edd+t#1#=1N%cn3`o+ zs<%NEM-BZfLYw1VFcA2+n!kw}6%lg#VPcKl;9e!A$x%yBlWnbNC6iyxs}z%Uhigv^ zD9!10HFp5EhsxTObR-eg5W;Aev=z(~aFNpMY;#j6yDQ~vO<+JpOHx>>1%^j|C#G3? zVn;~Qq+_w9zCXDuy+N051+)wOQyNB}pN)`?10_KVDKAn`KaL80~ryxHHj2 znl3JxWfgf9h5PY^#26gtq#142WO>QJm=}zih_a447e#~8+~=Z@mOK{?%VgqQBn>?@ z_@0YmlTvi&qL2nV7mYT3Gvfr9qOEHeqr6+!rl?=UfytX?54| zY}19AV?|#%xE&@U=4dWtmFCr0V;D8%w_;HE7Nw>(Yc*vBb2Yuy3|YTOxjPqIbd(IV zoXe76tPfaJqe9)Si!1_FIe(=#CA!fETvZfkSCvR7h9c-DEAkeodRN-6Rf=kntW|@_ zd5Bm*j5@ep&$SX;!JYH`ggU_nH2t|#%1(ihvIg#_++0>kM)7s)VrEyu-4IXFdXg3x zD^~WlwHt-|?pQKl)74{g?NM1dkqzu_gjN-~RpXFdG_l9 z1ubA?p$b=zVT>mWYN2VN%c4)yTT~voTXjEAY{gJjmGh)Si%ny2l1Vd5;ZoTlNGN-)?Nu~jPgrwvHH{K>Sqy~1z0dQ z7IL$7saFs6xn6^*B5ZHU*} zM`z9k&PJLRdUGoniCCnfwO*{Mmb$CrJ+!LT+0)Xm)(cHinwOQXf>!8JYmH<<8VU8r z`>|T!iUs^ia%oLu%f&1^nQf`Eb246&WEhX;$2QoQj`kYQ=|<;mHd>RixzX^Av>2?m zm4@^$Z5EZfn|E~f_7Z!@l;st0ntFF)Qjf8`o-Gz70$^ZITW7nQ*aaPv%8QK7o7)UZ zMd?de^RPd}Ko%^|88i5`u=!IRm_w&@G(UmVU-4*!p^aGZ?uWV2RkxEj$JE-l9>_>* zuTHc;KXs)xcO(b9T304+#;%REQ-sx0THANIsbr@>=2=ST%j^*w8vS|;K+PnvkQi$l z>}l_WRhL@Vqc;KcHJZm$p%8b1hBF zTeRntXjP+;p3%zI6osflna$2qt(2XzJ&}}YqSriXvLrED^^8(Y9+gU_;tVP)KGEtS z$f!@W)(>vSQZnsDx~)kp`%#xv3(*i1UZv-y97ESC8gGM9mEROJtp8x!MDbTwMT!fJ zs5W>q;v*qekyVO9E0xk!eXWvfE$EtSLbADjy>3Qd05^`Fx!3hzNr4vktO=~!f~J)` zvBZwma~Er)B-T>KR2pVqx655{E%p?#m*itb%OG}?dIq}Evgzc;_3jQ6q7%dH=*$dT z*gff_`E7=tR~yemE}B`9DRt^$WWAodxs=_KFIEJDSQ&we5aykqVyqU>Je6!-0ST)W zT}!pH11all<3&VsX-CrJ#zV(c3qGnB_0WzqS){q@Dbh z4pOChZjPVSd~q;?Mkk%`O16^nl9NOZ2KA5BUF z7xf9KLb4_{Qun}C6?S$>C$grZ)pP9Zx@`$;*T+*xTJ5u?N>L3Z3qzf~2}86=qv1GE z=~mraT&3fHF*1YAjv_#ym{^UUx*YM=JD}E3fMib#aTBHm40bR5Qf#I1I89Y#Zc8^* zikXwaD!*6-sw%2g&^-O6vdHTXB51P}>B0gsQn4 zZ=+Q@6i4qngB^Bc;tOO6ClJP>RnmeuG|eQEOc7KFbJ`APm4qc*Wa>2>W*<^UP^T6W zue$ZHPZ3~|lfE&HLeki+nWZvxk~nl&VrOS^kR~&{SVl|3h=;>MlmqoegMk^P;Avy& zYDPxuQtk$ItV3xL$P=CK0K2*{r)2%nhDjLq1{4=*o2ms%Mr@7{U+F}GK30Yeo{UWf zjj!w^8hyybYv~pyw>TR^`U=Pk!L6NA& z@l5PEbP)QuR6QHL>U?NZn_B6}G%Ep`XwVTZYFyH5zP44W!DwvFvv!*LC;=IRZDTU5 z7}E!30YYPwYT_(0lBiR$WcZ8KfD+Ks3g*8?zN5;~1rg^J5j|vWPtdk}VgP~;tz<++ z&j%?_M`5&KMHG_Xlc2r=a-K68@kZHKl4m)Tz8&)xp;pncEO7wMw8UJj2&3 zwz9f(#MHVr)Rp=w%xLBiW>&D)uPlhg1*ILp%GHPiILlR3!!3`R+SjE%Hfy97E zqlAOheOI!lT@|lQudG0dyyX=4;O7)=V{W8u#zDS!={2r<`)H=to^2G61b?#X5_V~$SpyF9$PVvT!8J7_* zp2YD02^rHGE>i-YKH1guWkprf3esy`O4g{yD@?^MFBQTYYP}#b%a}W(ijfg~TVJb! zcnPQ)zw)@NF%5xvqt+<3eQp)ZZkzKZZZWcWi`u7Gh8s`KP+c-Cq^wj|97oaZ&S~q# zX;+V$=!i7)k{FsZV-u~&m@;1fSBdKGL`#lzz*6xGM|d!3@@mm28B=|h+P%NCy#p2{ zTAP?+vmJU^O>BB;C!v-5uIMO_R@3N-l2}?wVKH}90igw%L2KkxzUtnp7>Qlj>4NP- zl~C;6KwU?r;Gd)E%6faF+S1oei1l(&8nk4OjST9;$eJoDl06^#h+75Zq$y#e;?Om( z11gmS)uEPhQ7RZ}4V%^>3Dz*1)7{%~npVJ#ahQ+-s6uB_mL(H^4X7v?Dr0&{Mu3!F zm6w>1p`?;ZA!Xu5>*2bPyuh@=tC(p|>uBJE)?dPkQS+p+c&-}^Y@Jh8Hgp+jU`9}>;uxiYrPu@IBLHG#*?=ntZs&6f(LuXBrpzNJFtXm=r_pvLidr2&VLj0X4or|I=IwAjDMNA&Yl4sR())#d3>B zlK0G+M?Ukr_M=mlm;b!-$!jXxPcMJGb!x@!A3J>U{J(wo`+s}^J)KIf#y_w8vir^c z`TCE|2YM&r)ph#1_^XyEziRucC8ypDdG%7``?+dIAClzc{L8Ojekt+z!(ad6%WGfw zQTjtOKX%WLn{KIkX!!%by65$0ou`rUx!Q-yWrUA?zQe;Gu z;zkso{2)kokfzR_wj{VlC=9%ri#dd_#Z+Hdq=4SR?JzMAZL?YrGmW7XSz7vn6K2=g z!BeyiJv6N&3$G0WFVHxPMhLM&^g0FB4RE)Y>=nv}OaWasjI4ZjxJfhy5nzcD!?{^b zx;=qwrFv8yb(4A>wnyX&^{BhkIuexECS=T)rqv#wzAdd++cxpFZ4IeYQpl0~_110a zRapB?cI!luj(1ra8LaW&lC}=L=s4nyx|giC^5rbSW?01Pkb<{ZhBY8Mz`U+?o&Sof zPLq}rx9GdAx*|r1#vrm>pC)>t(+3@1N&n3`@YSi)hF@%3@{O;A8~*V3M?XF1b8ju) zI{3bCe)5Y=bR(bIFoDglRysgmv1oDSlBHGE%T}yhwR+9k>uRsRVf}`U^*3(Xyrp4l zP(hdXA2JBN0qU(1)mF5s^d2!_IuoZLJeC%<6a_z4#k z7M-0qY4XLKmh5w1;CT47W zCDk13FJKf}sV?M7GqSjC#&ilCO>BVh)#C62i{xgkCaP4ty#=VO6roDM66l)#)3=YAF_L`GE;2T%_8Aqhs_-DQ2SO z+uyY2F+dkE=_P?qeOI*=3PFA=*3r%eN`#tWAVyJo5(9JxU2y^H$33ms$;@Qml}z?h zH82+7%0BPE^DaP1qO`pfdr#e}rbM>@%Z#ltwS{7&fXH(F8b#|I?B;~f63Qf0Tb{7} zaP~)K06bZW2AF9Ny*;6h$?+v@8LoMKd3(QFJL<*Wxzwr^%Z)N*sdVL5wji;%j)i0j z!nPFM%TC}ft#?5?zFj@pA*mU+vJImCL>sL|V;c(FJ+!TbtwOp;zJ|oG8~X^jdR~`u zOOiM?LnwEF3R#Zz6B0pum1d^r ztVy=5%ZRZ&ZLl8e!q7+SvBayj$6B;GNh+`#u+O)i1bP(-G&YZvM5i#$Y8fWlm5^Y} zVUz^ZZ^BWEB);^U#rH;%UU`*-w3wFK&3qw$?O<0|BfVU3GelPx#2CTW(WPq~g6T?Z zWFe)5Yn6y*vRDtv!${v+hrQAacC`o-GF?N*KG&sIn79nks1CG}OzD-6HR?F-N+nD6 z5G9@WYDm%wY|^ajX-FlI>M9Wz{R8d3f~7@AXvkdQuf>&q1I)w#2eI_-$=fEDB*&?Z zr?3I1`gcnl3nld60IdzsyET?#E^PtBlQ6*A(W3N71QcUCUbz|EUW&s{v5G`X%hE;5 zmbGqQmT0M7w73kb@g3+ULp`zb(uzf;nwPuoaKXZY zh49=v-8)MPN){H}a$ET>Z1+@@FDhSLURl1Rd}(=Ad3E`+it>tzibWNRD=I6NR4lEi zs;I75wy1nj#iB)v7B8w?v}DoJMOBNc7cE;{zPMuXB0OYPxp>LqrHiW;S1(>xSzcLD zxu|k+Wo6}(%B7W6mDQEYmXt54Sh8rz;w6lB!z%|cAA908}Bg*^hZ8C$9hV_|BisfiuWjN`?RKigB z1FmWr48jV~gCSGu;l5;ne_764fwxKNY!*Fqg6;3YfwovRziN=uW)@!x))JtHMkezp zU{ztny$d6V@uz;nvetbOZ;{F^{DKbPH6>QCVZ-pJpIpFLeWJN3d2RANs}h$PYFy7PYX;B&B(nZFf%xN ziW|Bz6dP9>C=XQx7X=OkpALQ?{K3561^+Yhhu|MWXY)V2D}Dc)pD1tKcK-tp&it2) z3U65dpT93HyY|-Gn!daD&2M?=ZBKvnlb`zR=RW_1Z~xo(&N|_VlNMA|RxQ8knswLT zw)ZUv{MaWy^|>#+@a2E|o)eyMkqTXY)ta^IuD`uCvG<{OKlb?-zC2;#0-)A4-g4{h zxUv7{hn_~1&wl~>hQ?kzk2TPj(qi{(?7fWp8KDA|KAt`5WJ? z-S@X&`rHd&UbnHX@uu6G?t9ByKl+Jhk9_)b&%ZQr%G6tK{q=ADcy^?_@7v$GXm(F> z=B%bWU;mM3c7N)*DN`?Vo7)GEeg621 zC%*mzd?M9ty6mp+gzs9NcS$&B;+_v(H1fg7?EF2Kgr?^O!e!ygaBe7&o0B`SpuTWY zZbNP;JhLD_lo!ek1tDnT!;#RqoWMoV$j01DavO7lIa4OohgXI0nre7rPT~0F;aPK= z-0tulb4QLv?m85jk#pA{LO113$)A>g@%W3!-;q<0Gb87w+$$q%3l@gQhXbLCaSOvU za>j*5K7^pMiVdNWr}C~26^5?Pto5O*tQYYW&o2#pB^U-J`x#uf6<;_0xR4y3F%?;+|HRsHz#mM zct`M=&~w2r2VV?+W&Bt3zZQHc_>I8H$jiYWgii&3;+_tl2|`c<^S4V*PI}{gZ+VX=i6n>{ z>sk}He&X3nX6EJCM}J`TMi) zdUt8r{E~*p_CNmQQwI)y_><55L(aJI(OJu{U32665B%eo_UBHYaoOD0T>FFn`03ft zelF}@K6hTp;_BtK*RQYN+_05|uDK=Awj;Ic&fRZ%>I2UlI(qyg&-5f8zWuV{NGKc& zwS@v@r6YIE3RM)&4A05GG;(ERb@-wyMm~@;Cp;%yl2VZr$}7lOmRqoA z>GY9j1BHtw-2Lvh!Eq!1@TT=G6ZV$9^~Jlcd;D+iT9$i7_|}|x1#1gRB9rerbW7rf z@Uq;AH6#O%p2^$$wJY+U_`#mVvCzbD-kt~U3-5?b2<7J%y{-AW{DG@SeqE5t>y54* zdDq3`8}p}+ym8NUp?g*qM)%gw9(no7k*~%=Gs3|=HM1u!j|BFf9QnEK-env2Y#AR7MMAmxvqIw{IRynddC;mOUz}U8Hz%t$)>^rVCYn&lTl&*vnPJYM zj4ustCUZd{)F01oQy1g#z)I6VGC_7+69#^|ymxolbsmZ|JGV{V?@XHN&K~bJ&;IGc z{a0R5?k-He|K!5p!RFYd|JhvX{Lx+dp0mwM{}6b2X`rCEYR-h0t3G&9d|BDF$Cs7Q zeEGUxTw1*T^c^qP)g_DTAA9ccdgsgW8xt=+exvh^;!V!Ump7Nc9B=r@cOTz+{M5@^ zU8kq5!CyNU|!%S#I}GFaEgkG@QiHW zyMedkgCD46xFi$~ybtL+!FP_U2oDFA7A`<73qlo0F*k5cXig-M_nN@?U}Zi!O`s`6 zjLZq_4}|ifimQRZl)y!~p~z?Qs3KE|qi83h3Iu0zirYR^0Qh99-G626JX_Qp}^}z7t1g;I= zNWV*iQ}OUH)@HA*r{C-wJ%O&cwu1 zQ;mgB0MB34a2%8VZs4ViCVp=g{5@IlF99#*EN#qp_^SXw!rcIP3;$H#WgaWPpCMf0 ze-rexH9dL1^TE@%<$JWhK=@=$YvO+c+$4=JhrEo{UWcz?f(Kt` z+fBfWe46;%fWM5BvFMwDllCy_sVkLg`bUvIw>%^E1D5_t7&BfB@CGJxf;Z(mbM$Y@ zgT5<3&W|TqAr}L^l!adTuTWUW*$BLpo$5z@y7IvrJh=`^XV3-oUjk1p)-@Brwq&@`Wc zze4|h5%?1Q`;dYEE%4WAd<}g4^tiM3mV9TS#=j;Do_H;?ZqieGOFNkO-YoQQGVuM# zm)<}pw;KOM{yqTwQiXM#RR;bf@KUd5fR}dLbZfrHtB+;De-n7=dnP^MC*U8sTF9rV z_r8d9FXkZrdt0V|5@I6Y@kaPpFg{3sB=jtV%UD40Wq@UzBe)8%wBK65(yvYYw}BVF zoA|pSPwOZVI1}FsytMJ;+wJ_Def67$aI^e(0A9>VD%lYEHu2PtL}xq(di_kjYA2yL z@#_uxFN1!rPM_*4^uGjN^up69zm&m`FV=BQ{87*g4^8~v121~l#D4~OX@kFR%k<|> zNL$Ka;%@<7`e&d$-y!`%j`9?JG81^w3pB20!@CG0cP;2euWSS?>HG0Qb1Uej?wz1_ z@sHe{z~}N$^>;5|NsAEeH|Be^q)%N!!ujzs&Nyh4W<_D!2QCaaavj=#Q2QrVG5(D9 z4{H2r?eAL2;d!rN|CFZ7Tg~uk9e!$!1wrqLWi4t7)1WUV-vp@qNG`?Jof8@+` zf`JVF>u7JWYm=Z8`F(pwMjk2sYbX&o6aOK=qDxKuFMt;vXyShjyvV+Z51>3^Yn%8e z@N*D{oQb~{cp78KnfMyuMgN)jj{$!blUwv3&qDu6;6g8vz?ry~G=AFz~} z!v6qR>P&EKM@F9$ybkab`k`GDU^Bk~z@n>(Az#^-Jeh#qo4T8@A=C836 z1Uc%;*nI?70v7#Da3kR9^h3K|z-D>w0W3Bok$l1z{zbrIOHlZ~12*eFqdQ-JMU_HP zf50N!1m6PKVMh!6e*V6*&R_rbphY?e3HWAl3zU^9FGu=GvJZy#WhM}iLl zmN_`VF97DR01<@mU;;Mzm%GW9w@FF6{YwFx?Y|nZ$?xlY@_G}(&HVNP7Q2}8|9~(2 ztANe&{sOR>Uw*Hh-=%=f@JhfYe;WaduA}_=0h{%`AFwHpe+^i43(?G6CGUI6$%^Toe(r!9~3>uvd8jc^%rDVaTh z&GLU3u&J+}2V8IDH+3jqe-)6CO@Ph*`ygPkor&UEz?+Qt`MdJHxgeph2fV}x-woL0 z*E4`87~#(Wo@l^d0$gUmzxTmcrtSW^6|gB!9e~aLekb4!MtWZWZ1&$%fX)1W3;0HZ z{`%M2`ZEr=)(C$Zuvx#a12+51)M2}SF9K|~cOJ$wQ$AjYa5MfV0h{{idw^?<{O7*T zme1>ba1yX75AOzS_WyqZZ1yMT&U|mKPT4F2Z0f@%z~=a|2e8@S-UoPvQNHi{!V6w+ z*VhGX>cdrl+l}}i0NiN6f!#Jg76PXEow$C$*9rjtqkv6*|0iH`Jg*wD?TzaJuQTF5 z4A_*9OVM7YK6(n_%MAK|0c`4v;2vAQUJ2Oj|4o3+{`6767aQr#-(>gq&m!F9_YVP^ z_SNLO@|_kV{!YNAKD`UDY41D)*zAw*0bFCm|2AM#zg%*6X1#>SZUk)BcPHS@M*PnM zHu--I_-E!fd9Tg?d4NrMzY(y>?_R*gM*0r{Huc-VM{~S6MV>*o?{0>E4SLhQ%)iIh zAC~}z`RuuwfSWuB-x4?IuLC}!!%RGlhcbrNe-K><74S$nfi< zm^z4^eTRWJ*Zn^Re4Q?Xx$Yl&W4^Oq<3AhB%*Xxsn5HrD$Fk59UfQM>^%7_D%iBLd zxYSpCqL+54d1mbRvcCT<@LA-f7V)GHnt0-~$byM)&4Nz=FKL?edx4ianD~1P{IlSv z=!F}?nR&X2r|1fL<}dp}Cyjh*9xXP2i68(o@PCDLq--vfhoo=f=KwEtG4Ul?@C&ox7iGaO z$%3!Wg1dKIX^ze`$cI26}&CpV4e53i0))4Tlg*=E_7#}XGu79n@&Z`-!$!)X!_$i z`~>ilpZLVo<82HzYkx%hmpqv7Y|~sP*%G-suG6O=vt7iFK8$!GyZ0D09j`lgy|ab; z>wWqdm!wG7?-bHiPQy}f2|tGNn64T0Qf~1ny!v6y2ZT$XG5ORnoC$|{qn!8z9M<94 z>akCk(_fw)4`=i|rLz;TSuQHCltX-?t2fFcc=0LR)#3ZzZm(B=4DhW)0N0FvCG-Ps z-(zFvQ~n-Kbw9$%9o2p|`n>eK z&MUk$={Er{YvS4DcGr32x)$eJWerC7Ec3VKf8tgV{Z;-17f$AYGXDJT>{(*9^KtGH z9)I>7=lJ6|n%7T-Cx>6;aG4uCuIZ$%8hphb$*+{jj6^f)vG9Z&3s1UxEIhT%B=nLK z*XtT+MYLGsM>a6NNOz=~Ea{NFI#&8ES@0uS@U#v!RyvNlnC_&KT}@rd_9pcMm&NJz zCHdXbn{IM4FU2@5>Xnlwb)VIv>F#BEybyq^^G)hmyH-5Rlp0VZxKZ3h&%iY4*I%0S zt$7uQFPGwrz&!&^{J4vxNe^Fp%f`)`Pg-o8T|T%(vsuDxe6XuKqJ&rb;8R+#B)nWJ zN`dQraIX)3&<7v%!AE`Y2_JmM2T#+AP4chy!Sz14!w28%gAe-PqdxeA4?g3Arxikg z;Jotq;Cp@WA*~pMK2IwKfsg8ePhi==61e1YJHKhmZMfbCclhA?t8DsHK6u+YJG|Ei zpYg#(*W2{_eehu)d|Xd7r9P*8aBsbx-ZWCsa6;eggAe-PqRlpahYud{!4LXicZ(gr z+6N!=!6$w2y$yE!{XV#Ms~z6#gHP%WNvUs*o|p-I$_LlnWT&^^2k*Pt4nO0Ai*B*Q zT_0TQgAe-PW-^fAqzrzndWQQO1!H3^whadOBrysV%Yag-U`nTI~ zhY#NW4m(cm<`wZ;NJJx;m3UN z@%P%{r+jeU<92wn58kHjSLr{!KKS&LcKq6>Z1~Ut8$RZPk3MaOPy2um{-6z)``}$4 zvcr%2;G-Y5!%z6&`oFQmJACkn58mg4w|&Wu-|K^`U$Dccecgud{iY3{__hrfeaD7R zf8U17e_+GSKepiqe`3SOd~oeA?eN1s_|zZm@MgLY1Sj&~7T9pF53U_&hZl{v;Tj*@ z>x1|EU}u6If0_?I=z~xB;G&D{_#-~}s1H8ngLmOtuUY@YKKP^$E}v-Aclh9v$#!@V z9YBW@{%-TZ$EVogXMFI<>2~;uOKjMkX~WH~4WFP5LL+~7u?;)4QD}tM`rtFPVQ7Rm zFSB8{)`n~9ZTJK(>6-D6(FIyK;YZOH8-8$y4WIVG$C7qDBt+Z9e!+pG|)z zWy3`SHeB<94d45c4IlTxC%x0X$ zx9Q8*+i$i5_rb@9Z2IGA8$RWO z>v!AXCw%b95j(v60UJK$gGb(KhfjOhh7Ues!$;p`!!-wNc*FWW&yX*l^7+Z20IeZFtui8_v@^KcXKG zg+dnpPx;_`BX;2Osyrr+je9Qak;9KKO(WcB*XpUDY5gHQP2jtw?_&5bsE%m*Le zY==8rZ1`BC4Hw;P!_BwY@O~eB*ax5S!9};)@#}r?w%hIS<|Z57?}N|8?eJ~eZTPqk z&TFy5OImGsmk(~CeEbtO{fWaieA)-^|64me@9%7Q+m~$kkPmiW zu)~ji(}qXBXTt}5@R=Xl;m&{9@KGOp?~m>9Z9lQ$(?0mYpW5N4eDJ-e?eOxS+3>EP z+i=M*Z206aZFt`q8$RrV^ZwHgcYp7L|6s#4KDgNjpYp-Af3)Lw_~64n_=FG6J8Q?U z_QA*XPP>fPMFHLs7WkkKJ{h#b4~1-a8XfpH?5$oOeB1|@L~Qz9KKPgqo|a?NclhAL zJ~%Jerr+j+5BlIUKDai|j=#?b*W}yb)BbOJ_Z~DmUEgs$ikEOvRp zwYAfrR93vqs$3!n1P~hJav~fxVAb^=6*YK`+Rj7~T?%Tb2swBm0%EubD~=eoGu=8< z&9q)tt(u}}pFNwL=X~D(b^7n~%)svJe7?VLe)*l}wtIGe*-IV56>RN|dbos#`=B0n z9h~7ua`PDUd#Sp3nR;}bIyzpRpP+6}R9ml5XD6xalhvbB)Wxal=rncit0!lu z<1^LPS!(ZWwH2tnbJXpt)y=u;^nCUF0(Bay=dV$R7pZ64)$Z%m(d*TNi`C;x)Xf{z z)*IFC>J42RAN}WJ3J>3+`RuLg79L)zc?5?a(7dEC)7<``+Jz@@`ys7wKcXIdRK5J9 zdYY-L&#KLtx_}2)X&%B2yvViQzDC_%r*^Ja4|k{?xcUn6ud2te2TyL)dg~_j6gF7xfmp@mV zzfh;YR$ISON556)aPT|i_o?kaz<*S`aCX1u)}PeIpVdQnY_4BW)_?!0VS7)_+kMpj z!_*NR!}h*f@9wAe;C6q_{R7k~93H573+Io~eE3-P1hy^Bb9mXkK(AlF;4rNp9KLw{ulW+59;12lBDK@K zp0uB@4_EL4u3xVGhR3NLID})kf)}uLy!Ic#5uCttxPk2xw7&~a;S{dnCG4E2{l{<& zXYc}U;gP5PCvXDK;088cq5WLggHt$%m#}$~_8-GOoWTX$!h@5w{{#-;8C=4~E4AMc z_TUiC;R-fS(f$_f!x3D-b9iv7_P5~xp28(u!^6|GzXOMG3|H_1wtVeBf+IMA=Wqkt zr)z%~p28_y!%NsXL;H{67|!4Y+`^+Xwf_W8;2GS&#;dfS3wv-1=kO9X&(i*5*oQN? zfLnNQw)UUE0X&0C*!X+xH-tSngmbup%|QEGun$LY0ng#VIojWb19%FTa19S%t^FN1 zgk!jZ7qE4%_8-9!oWOIqf$j6OzY9;{6t3YV?3}Ot$8Zd1@B(h((FNLn0w?ecZeU}Z z_H$tmPT?G0!e*%b$FL7)Z~?dQ;5FKR0tfI6E@9(B?KgxyID~V!g3XJxzXkhn1Q+le z9&FeCHXOiHxP)tX_*(7nz#$yN6}*70*J=L|9Ki`Zha1>_z4mwEDV)MJyo8-d`;Xxm z&fo>y!lR3|{{&9p8Qj3eCECx0JvfDPcnOt z8C<|EJb0J(pTGe;gG<8~^YCxf)0e7K zIDe()6>OiP`2^148Xldh<9)b<8+d%0jt^n$bj=sAb%y34?4PN51Se-}K7-A3G`C>) zT+IWxJYRF?0`+{Gx}jgAxpAR7+OAGuH`d&PjYRVyJo$*`0lY{xZ(-+?nvY>0j^F|| zGVPaKt}fsOTwbg7@pbA9&SCd@t@q#@uHbQ@<9&DuPj+a%bAvj7b9nF-t*^eW9^a~V zZ&OEb4#&4^y>W-Sfc-l)Z{YYY%_n!OLpc90&F4Q;C%;v-L83zdtvR zUhOor`FbY*aq0;64%K{UtFtGogTvI#k?Mh?E}pI)JVR|iTRnm2M`><7S3Nu$K1S`p z^$Rq&k5z~8;DwqmUZP$euQpFm+b64CI5|u6`~tPHO`XCGT!dQhT%=AeRnOq@2Q~L$ z<3pN{KBk_)_CIOv!i!I9-ooij^BnfB)ZF=kdJHe&>PuR`fa7a5_jjlxxPr%D)B5Zd z_40PLd57A+TV2l8H5`0L^9l~{K@QvB)x7+Mh^ z5;h;OPWs$}NALs=;3=HKIb6XDxP=D~)cM-53wv+~$8ZK0@EmSnV-KC*5O&}(?88$y zg>$%qM-S5Z#1B@_9$iHEcW$$Aiak04Hz(H?Z?`JzfAOZ~-si%+-GNbJgC_>iF-}4eUK%^YJn2 z5KiF&UcjTV_G{rmxA*$G$}lWAoap!j&fw-{T3?=^HcwQK;3=HLEo^(*FN71gf(PAR z@9Qob*UpARIE81g)Z>p%QP1GC+f%(iUUZh$CvbVO<}Ez9L~{!s!zCQQNypc3Q!ioX z?V1O02G3#R9Xj5DeK>&&cmWUIsr_9zgfn;!FX6$vw7&yS;1G`C8C<~)Y{q(g3wB{2 zp28_yz%|^$!*}a^Mz9A*a0(and$hm#UbO}La0D-5`%>)}!8u&P4Q##-{oov~VDtSt z-hx|r@BytKCh8a-eo%7<_Td%|KcwRexP_e$YkdgM-~~MVh>oAYFWc89cmB^9h{8=Ji@XDAYDw zzzrPi(D74vc!TB+?8EVmT5o+znyhU^Oo9YO5Z`Is`?Qdz`!fB=X z^fq-3XSXB2Lml3!u3-P$n&)?`?R((wsVmrOGoa%`oBL?}7#{4axed3lJf#Xf z=m~1$iRuwNI8^fxHf+tUjcd2;{_l-bxP(Vf*7`YYb=Qhne-# zM`*tk4vy5^aMT%G!Ol~)zJ=|lXYEyz#$yL2|R;KxQ3Uod4-WtjfI~Qj6L<#aa0Sod1~xvc=R1TQcnte+1SfC?7w{Zjz)RTtoX+2ZN3aWz zVIPj*1fIbqJck!>3lC;`J~r&a9vs3`IDuzy3D@uvHm}tATJQ*-zyUmkQ#gk!cmcQY z;GcEAHtfP49KusLfipOVOLz`1;1(WSh4X=3cmn%y2*+>+7w{ZzVB>0??+|w2G3>(; zoWL`}a)1fIbqT*FJ){GzUx1&`nf9KcgJg>$%q7jO#?a-FXYyRZlQa0Dmt z3@+gsUc%-zI$sMO!DHBi12}?XIE80$0atJhH*gD^|DxwRgl%{Pk6{lE;0TW46rRBa zT){Qmz%6Wk3Fi;n@CY8m9vr|C9K$I*gA2HVYq)`1*t{0!58Lnv9>X3Sz!4n7DLjJ< zxPoiAfm_)8GR_~i;SoHBJve|PIEGVr1{ZJz*Kh;3uz4NMAGYBUJcd0ufFn4DQ+Ng! za0SF`U9PxPU9Th8wtr%^Pt3unmvkG3>zs9KkW1!ZWyl zE4YRmxP{HH;QV159>HVSg9A8%V>pFpZ~<5F0&d_IHouDVhi%w}Jvf9TcnZgG1{d%g zZeZhUI3L)7$M6IW;1G`C1fIbqT*FJ){JNfx1&`nf9KcgJg>$%q7jO$3H|l&%*n&s! z1oq(wp28`d!xg-MTX<0F`Pi@vdvFNHa0VCf9ByFa8#=!s?7$;<0()=>M{o>hZ~@QZ z1~zWO`M?f5hJ84K6L$%q7jO%kw_v{T2%f+JJcUy@ zhbwpixA5SbI$s-hVGj=B7|!4Vp2Ib~gj;xUE9MWoum^{53}$%o=Wq=#;T9fLIDgoIN3aWz;R)=)J{-Uy9K#8m!Wmq^bGU|=uz8!V z*8sL*2OhyLJccK*2m5dUM{okCa1Iyn9IoLd+`{JVx_(30hFy3J`)~k9a01WZ94_Dz zuHgmT!p0qX{sY*CU3dcfa0th60?*(aF5x-6fS0gwC(akPVFz~M3GBlWJcScDgA2HX zD|ik!@Det^jrD+sumwA?3wv+?M{ojXa1K{+4L5KLn|JB?4`CY~!DHBiLwE`&a0cga z1ux(wY}~EqH-IhJfyb~9M{okq;1aIj1)QueS8nXJ@uI-hU2na;)Gklf+n4Ne*1gcL zukT*Iyel89mt)g=?|ix8F1wFcCofPt$ExSB@nX%>iMoPEFVlPqSFrPPt)Ib@<1}yK z;&{!Y6V#)V)y666>Qr@jj(YrRwGRj9Y97<)X`a*PYhJ^Cu6Y1w*Jy5Br_Oh%<8Q0& zhp#^&_uBa5o%i-txA17Jc^InmAFJc>`g+rS|MBb8L3h3DKCip$Rrelt*FWy*| z{E_B^e^tBptCMa&s{Z_w6W9B{^!B>_l6uFdYCeO9-F`@Yz0vK5)O!w(FVcSQ#p?PJ zb=mEg)c1?J{gHYH-Tp_ty>7pw-h<1vU)Akr)aQP;KT+?t+mEPs((NzQJHJ)?)v(>| zC)C%+-F`y73wYV>C)DTFz1lzgzPhZ{HT?t4jUTGbAE|A4+3h#f&&T+LVX_X zvHpdkcQsHC9;vSPR~HAU8`wQi^W-4)u-o6HKfd>P&CA2o#S!Wf_K(qg^aAztShf8k zwF?*BeiQxtnv=ACc9yzkKUv8)Ay^x%hb#6 z{nvdzt9yTSZwEHI_q+DF2@l{QT*Agb>U^f%`)B+932b)15cjzSd!N#NA?#kR`2_ai z5MF*p$JbY=t?vD`{rtw=`)7N5-TP&G2XF+(Z~|v=0atJfn^)`n^X~nz{rr;aHLqa5 zdp~Ml@9xn0oW4PG=WA-KR8QgAFEuZIrEY$wp8sCGfUEBPj{W>=xa{8F*ypqRwBO8J zKLG3VWKXrbx7y!FJ$abg-B%sM!$)Y|?x!9gl7^&B5x?W7Wyy)b=6j z>@U@YqaHj>?ZVlZDyx685T&T{rtG&C_)^3kiR{g^N(A;R$?J=8= zUsm_V$ExcWsf*XDo7bzOOVrb^st32JlY7rqFm^s)uu77L zsLg%U$w)nWt~wa2{THgIFIIamRW~nJ506vZC#myu)$um<>{@kmoqD=MJ^Y!vhO?h* z9{xgY{!%@Ijiu%pJpPsD$*hr^XfVza+ z2WnpJp>`gmj^PG&AFTBWynvmDX#EtP!`4H!K7>nnU~0V&=dib@);oKtV|W3N_C`Hi z!_GdahrKszp2JReJ@?hmv(?{seVNt|KCI5V>!tVgWp{n?-iz+~;=O|#b$s1jzq`-v z?t0w4i|+c{yZjR!-!|&ByB>C5KiKX0meu*V`))qpvU0PZdU}}JIb5B<%iW&8S@p|~ z*821qb@&o>^NG#hCw7iMWTVN($7=qouf*hen?D~{4&St@TIZ`X_uS2V<#xAzt7j5| zCv83+T-_^AQ!kF*9KSQ)b8|kcd)01_2UnHRQJeW{j>S=%<99ywe8l#%qV2{Jue$hx zi?(05aeMmq(~r3Dtn-ezaGSC7b|YA)7oWfL_Vn}5Iny}eqF|$X`{`$F)NES~+35WL z`&j+dUj4UzHf3Yq!S#>vUAMCrujkz#Wqnq?Ha<@_?yiPBviqa?OV;)M?L)igox9i= z^mn@3)vqn9@$2uV8(&A4ugCYdgTr+IkN=d7cs2KaeAE3qLVw#m4ZQ38`tkidp0F`? z_4l#h)K{=JEUaKXW7Q&wX9F{(rK4^;x&^d)Jz~{?Fs@3byWSt-#g_ zY^}i73T&;w)(UK`z}5Oi7m+(?X-^47||GlaqBt!Sgcx7NXGEBdxOYD{%e(5`#QB&QKP)y?{7Khxf={i zmij**nCJeU_4oX?=l3kv5-d>)47+L5&B4lP$7cHOS!JoIwx z4cps)yOygDcWAN5!w!Q-rs$7&x`rjA)q5>HK3j9<$Nlyoqh_O_vk~UU{YKzN$45e= zH>2MZk|@eW2PEFhk4)8y;$98w>o50e{iU|w9z<19yj%$wmo+|i{K{JXoe0?1xZlz* zaQs*r@s=-szScv$e!dp*y$U~y!qbqCc(WwaN0FY3{$22Pe9KQEzTZ0xzK=D*xA!T; zclTlN{Y-#wJjMA%DF z$$h|0+WU~?pQq_*{;rn!w=;k5B1@PhLMcrQnB{>qQb z>T&tq6x8GL8>e)#`cgV+eTTy9T|$RqO+Vs8&}~D|ey{0keq3AhEY#rqi>H90c-)S} zCmA2x8tup%QJ>q9c*=Y$=X5dtv>m=5uMhAVOFiUtGy2|9Q;(n%EgLsk`j;PGSbO3-URt7jlfs0jBXqj= zPT3^&lJ2C~1Sprw&3g|XJeZ4qEq3p4@|WS+D1QqA`lRw_cHQmw1QbJa2NNQPr!;PY zgx+qJu5wXAKlspI7a0cjx*P4eJwG1x ~bxl+H%+3~2q9{;nY{`qJX{V;vW`Y+K( zM4x*6r#{L2=y-zp@pw#rKXLpRmHOuk;hzY8{6Okoaop-JqNY$E_DcP$j$8fp^7IAN z@Al-$(C<%5e`w8~82$K&)c?fE(?e4K{3i_m%~JmpCr|H^`ky#?S}*nMxO6=9tq4ko z`f!)jzvT&||81y0)rZ;AOyqh|zD(h3FwSzM%(tB^Vfp;}_(>8!0fREKMiVf;F&we- zBNu3X_N$1W^oJkW5=G1LoABKh<|7?P^Bmam z1?hd3p7!fnDH`CM2z5j+cG5+@UPk%8f>`vpKxoX*m8UN2;dBasnVVA^@R2ZZF$~^cDBUOVz)Lno{ zkN3S9_F>yR$sa#7zoFb5mU}?UG5`I{zkQD8AMR?%KMncgs`i)p-;Vr`8hw(&u;gdI zA3B>Jo<2!oi^M1QZPIY_Mh$PMf9nK3z%sz#5owcQruKDOjDM&f==X(6e?8_@8x;*@0!RJtP zSbh)XrJfEtFN!PHZTc<_MIr8+8MSl>=7|Ax0kQQ7*P zGyMqp_#)zEcE|N3PU-#utN(KnCY_rM{*=MSm+Hq2-XLMW=|@~qIGL*Siz}KxnX2>N zxT5tXQR}E-9DI{s`=QTaGdk}VgExp zZdFgJ|4X#qkxMMJewL^2l!y}6C&22Oad;76*AuTNwsDs8zmFq*WV#fOeB284@sSTS z>SHPTPoeWjSZa_*d`j)gC8{bPDo~ibtlp81M@l3TF`P>Nt`#9nG z9z|WmeC{H}KQ3ziKgy{=n5NNeGI|OAC)4F;>M!^;>@n?u$fe~=*JCcydVL-H zjCS@qieB|H_4nd)6z?-G)O@dcnWm?59pG^t%H^W}EA$BQd#S`L|9zeRj2pb2UrPR5 zr0GfL0)dmlBCQ9_*7$$-seDX>I@kCioA+pbpk3pKtlh2gSl+7fLvB<19NMoXl*cN2 z4}TE-a{q7fy`Ue^CFR|2QGO28_*FZk9p)pYl7iY9=BxF;HcGzCe;GD-iG-P-r*fBU z9@Y4@`!&2x^&!N2MIGK72@kOs=m(H?|A}%yJ^QZ>lEmT*h5VTuZIOB@AEPyLr1VbQzhA3#PHt0vWq!NzE0ecXX??ZwwnF<+ znJ-~d*kSNIgNG#y@fEuq=mF)6{G^2)K_B?A{|}2Cjaof>tls?w?>2a!!MhCJYw%79 z%i9iE{2UFZX#F8RJFWeqwY%>x8|5kU!@H!OvHRhg|FC|zjk_b~D1MVJ)X?R4?&T_% zg!wE+$e*P)N;Bld)~QF#Pgo8+#q_z?XaSeonGj6ck4KTtFyChD^0xrMt#nHY zM*mKwyN`E{M^e!Eke+)$&(J=IA82yy^^?EfM|-i&6X<6U)3~bqER9pVnD6#?s63$B zgFb#IcMS%GQ^NH&LH^ zfp)?PI~c1^lL2i?Kn#MhUJc)zNQzg>`oK={&7Qqa%O9;hdsM4Q>7Viq z#O*@WpbFr-lrF>L&Vm#9ytd~{0oy$+Gvv0?GzD2#Sl>Ew1 zpU>6z!^cx!$MJrR3`n(6@(k?<`_0GK9g@3%5FTHDaD9kpSii?BUMyEYKDQ(6$F;y~ z#OPO=@LZ{-hf%guQ2)s5@qG!>jU-BZ9_RB?M6S5eoC~Jgz69q5TmDmJiwz|O zwToeU+oV197sB{q#5bGAUIls)uW6`{^d?0}@6$o=Ql#UBpC@6y*Td%Dekyb8`qGNx z>t4g(#g(sJm7J>lC7#P}E#ATSWv^X+XL732nenC9F2f2;6s=m;hj{*K-u^SCeeG*A z{ALAwW;*31nXK(6leN8Ml~iBj&kcYM>?bvA1aiP<8k*VPm(iR3|F5^vjtq#r#MKQF zrt8{MwSKmXf03^<<|3V_`1-EnssdfIrd*jH=uve=fC9{l0EA0ez)M~^Q2VY zuF>=nHFL5q!Scy9idTNT&M!*iPe|M4k7SyrV|_^CXSQFY>sclTA^v|~gTFSIi+&{d zJc{9o{7Y`zsrXf-IytAr`H#oS@aWIp^-6|)hA8|$JBS{lEl==M_^kk#R;R>lY zuCCJh=V*n_r(}hogK_U;@`HZQZ_uCKbMXU@+Xt?%Q4153)8xK6QeS@JUr0Xoo5o}0 z&jgI--mm4!N5;>5hVExMUq`H6pGS?X({iDFyiw?Ol_WGv|MNhu+5VGd|85t&bO3uQ z?C&e2{nqyPt~$Dm)&6pQZ7lZfDv_%tCRaU83Yo+9iV$F|0L!6rkpAHC&2s?5AXK~H?Qz;epWhL|K91^@4muM zrCey5?qVatN?Qd-RNPfN~-nK={ZQrD!?GummXnU`k_IZg9`7CyPy{5AtTYro3 zaf`}HJgjn)i#{#oD93!BRp00Q$-hYIQJHvw0ML|1+fDr8ZTB6o12)FeR^j8$GMt|i%gFGMU{Nm%_3+YCQAivmC(&ydaYbly39epasw>L@qt;e^` zfjqgqxgX_z{ISe0R&Jnt3H^0aU^_YLBQ;q^z&Hcb^v@Je@{V8hnlY+eCy%$DU;h53tpUu z{F39vg^I85_i=q_BKdKFWW)J2wZr5qb2{H$4sy|Dl9BL}H9zSm6R)xQ=c~rZ?@tN8SDBq!BcY$uI+FIry590P(%zx%BHP8kbiK2| z&W*v}c^Guf{GE$axvKYf{xP8M(fd2P;$E`#XO92=kh8vSn~QoSI7Vyt#|(HQKm z>xG~5&qX?~JeF}`ta|&0W6;~a)Spp%)?4|E*b|OBeEQ5E@0+UWN2Ay0*XZ>nQm^wP z^k4os;MdXXwa;UCI#T79q3d(Tj}As-{CK5=&Gh>h%Q&w7{_FQSE%f`>t2xd-b^85d zX}|S2n+xQ{<;mv<$77!IwYMDJuX1^E`AXL-o`m_zF2V26dNhBh>FN!ydU`^hD23vVBPyA3P<@Pxv&$>-{zOUn=?jJI_x( z2s*Q$_2cz`=#w%$7wLM^v5Z4w9Vc%egC6;QT`u|~p+Dy*zk{DuZZbdN(B$)z{;PGM z5;;bhjPE+}W&D#hFL}Ap_o=g&S4#V>?d8pZ{<$8E#a@neUh-VwbM3sOe*J{);$OON z>~`r$@ENQB^Xw+}vHrf9v7Em+t;RlNa#cSsd453OqxWCN3w=s$&lEi%UHIf8IZ{xw zPvG;ADfe=J;P>B8nbg9r{R_?rJ(YgS*QNc|dN&F=^l|S<z)s_fxX-8hSwC zSnU5;_3*C*zeD>enf=%GCZC7&P0fk?_g3_Mx4x-r@6&xcdq22r=dk-bcj&svpsx4F zLwf{HuGVv6$;DjVg8i8_UBYDQX%dQ_LDzizaJ!WHL1S3Ico1@s`9ZDyjlT}$;ppvz zt;@FQIXJ-|q;dQYwQkXc0|@_ruorIwok^E^Kj`MC*j`+B7<+MBARkYJy}0zK?8TF} zZZY$S?1kFhve^e;x9FcGY7IX_2hdcXXKQ?_*Q<3MpfpbHg3~*kx13g^*O#UCqG9|G z_!jH5Bl7zv`V0DAEzkMDtv#6VU=ALxw-duemql<6-1R!xKdRB|6;iH#y&^m>@W`)2 z{non_%fo6v4^?jBJkM)oZ;2-tzaQk3? zDfn&B@xQA6Mm>J+XSh9BS@{Rae|up_!qm^O`$fu?&q{p1`5BqtF)Hzy-*G_Tcu@U~ zcu4(^dOsssxLxuk-Fi=hpNEaBJ0!k$Xp4j^w<Hbxkxv%IX{0Ke2LGMPr`a$QPcnHq`_RI=c4@lnZM^hVs@T-w-Pi6?F--2^!FCRd@p@B z^=PN?rPMY{=-~TB>3uZzzFg9|Lh>d4-mBeflia6znAp7>ejeBP?&o*?{v5`W-hPgE zWSi1)0{9_#Rt<)pZ6V%9?`dG$qFZyCh`;P-AI?99{iOW}$DiMVzNP3@QYJm8VdrmL z-u+yETv2)V_sEH7y}x!Y_))U+7QU~Z+@<5AzgLmGMH%n?&qaT1?W-R8I)|_4`}(l+ zq1id$CFmFBB9EF5wf{bec4u3U@F^Z%qM_Nx^!`(`o6YV&orL~5{@$Nlbb;W{{ybUh zSC8YIVM(kk_43KzSO1B$Ppi?~Z=cXaZ=J8s&t~V678oB7H-3EM9_r-+$Pvq#_^FkT5oE< z*QuP(#Cr?0sFaU-KlIa}V`jhg9Bs3F--X<|zmVGV_1a$V3=RDpJN;I2CNX^S<6kcs zlG{}7S$_#JBf4!L%{?Cxcz7P2@kzJZtA=yxDaP+JC#3I2|9Rs69{Z z@sy&}liKSkDtLT-kL^1CK29x1Bum_FVLYt(##NO&e_uWqJzwf=cJ6vN`t9R2V zum^U&&(ACSIGt~Mw%`$0l}_<=8;|ULwRk!zz~kduY<`!I%kgwcM*6VO)$d_S&r_eK z_vnOt;d)!@cbJ|L&j(>}M*6hAc#HBg-md)3MS3oq@<@HEKfmSoJo&uM?OJ+Hp{n|w ztY>MpH>e8!nSj`b(SF8Nm9ISRXXfMgOy%3uuj6^_F2v`@*?JX>m+SZQpjSCLb;fdv zckJz^a-sDnsoZEk-A`oy_&8o}m*YjzDC6^Xk58#x&;8K8&_hg&4u%04tOWzl`NQy^1zsUxZr3{A4MRbeo)x zS3V})%GVhA`6S&-EdP9imEQ4qML6j;xf;)2G5-e3KgZw!gNp{QG1&B?dzHb9EPdGE zB?j*>xX0j~0HTm?_cVc%Zsk{U zoAN7JsPYkx-$m-#5KAlH=?9K%RhaUz`EttZ-%5KUx?LQNoUG~b^_jd8j}p$$@=4`w zhJXU|S1#(4h@^AiH~ay*YFOAPVSGOt#FO1;uKPkEzV2^q3GU5ddn`$RV{hPJ(BGJ| z1b^&de|p}M`2q0_MxV|#+Wrkjr_NOZyB{(EdcgYG4#MN? z%yBPk13$qOkq@25LjU&umhs8jJraiVqFtEahV|}YJ2o$3{T--?^?wlchxqKo`nu1D z!hBna$Nfg1s`8uZMYPX)euVVp_)Yk33-k7#KzKfpB8PMHDko-#a}kUvo)8bgceO-E z{(d~$x$RA@>49}VrAJ}c<186hjXs^b6&~ED>D_x29@?+)!o3P_HN39UekK>8K|G1w z@0R2Rlyv~|f%3!9@6jd92jhqIZ?UEOz4U%>G4K25!~Xo$e`faD-+PSztV_~Eetv>{ zG5(F*BFSPOidN5~pg+eEnCb>Tl%f|&0Ut-p4=fQlKkg4D9El}J`xRGBf2V7Fa-Z_s z-#^ZGoT=q1nohZ-K2RQ3Ad3CE8TgbdD}}E4w(BG#+s8ln4W^d`)z{QdTWj_#sCRdr zeu&-$_D$r~?3?=$Z2v3R>h7)V7XFsnuGICnhYVlnKNo;TdKG5=wcvxp-v6*aSD`<6 zPgeL^p04HcZ8{#s({&#%InDHA`bm-@ISm!#iKnaMnw;kONd?eBi@{G*d*%13E=Dp9 zbiVC!87~%tt}Nkt!}pN*_@EBt!4fbB>%j+{9P^cw=;ibk)=N%<5gT;V&!!_&)$>Mdu&7e z9{&^4=j~E1q|Xb0ztb_JllpnR)gOqw^mUp&82nD1z4)5h3$rI%zo76^vo~ARe)JWe zjaI;iF3#E!&R4%NS)}yuQ?aPAca&?=^<2oI>q9R3qTug((_dI2{T~VBSmeJ~ni0NS zd3CKF9fsY&dbh|e*TXgi@4K_Tcj9P9ynTnH$AiNXhIV)p?T*P1q+I92{C_^5c63H%az>{_7_%Z`nH`KZr>r{q43yRgGaC8v3Ze{ zOV%!tFvI6P20K0*1JF1_A@J*@q2`<&cYoNRXgUj5d% z5=nZw@<9plUa-nXMeE1?L;{C$GL7>;>p$tX>{o!dDgK<-cQL(=PR#c++WkO&WgZ#S z^FmDA!t^zD?R*vO#FaUw7bbs|qQOS*$~1$u-(h{bpf6Zo(*D>yfO0qos1v`FAEdmf z{l`53%D?nG0;2}6u=)=etn>J!p!&=DD8anHaU4TTEh%{;+wlhv*X#BJkMgkUz1#m% zn@+%-uI|t0BArObRmGnE%kZ z+hFr6I`;_N`+)iz@LLof)c%);J|*?^Zq;!nS-L~$nJnC?VfQWxp zzxp4PC#9>W`}!@@KQ8HOq&?n8NPYDC<9mk(B;NP)Lpk&D{ktfii}W4|`ing^-|N^d z_|gvWfu1RU3M$vkza#LgAh((y?mmko_o=)$Yxm4`z;kG_(qroq4Yw@Pu)0OUWY#8W z7k-z)8wKvWOXm~4Rr4PP*J%2Ur%QVB43)>ei&cL5W=*nsR#-hV1TI%s3EV&HJb`(PA|KS$#GW<5{Ss{>a56#|#58?636wse)h{#m;W zR=Mn(^$CO3uJzCQTZ7fE_0RfW2JaQQ=%4j*gVjFv&)RA5eo0Se?J#(b;WKP-m%&>M zE*iYS-~|Q`7~Em-8iVH>yvpEt2Cp!9)Y|Vcc$%dz5jeSek;SXNC9}R|unjFt z61h!gea_&G27k(6)!)8Z`wiY<=|3@8^)H$AbAfwpU%qdaOe46SPVtQT-XdZu>j#8= zob&TCeotgBDoXvK9MkSo|E?ANdA6p{W-YLzwoVo1-^+300!?Q*E*AN@lziJMs<+$K z-o(TEq`vr`4k?fyPiu|*&>23y-okqBd{6DXXD8dSaU)zm>beExt4bHYpSach#pfy6 z`;Y2x_;&^TUXILus@;nR4euedn}_|*2p1%Pm)$es>k#bMAN(oe@0a9k{mcUxG(cMdpChV;J@ z^iS-b)8uVhj_r**HCP`5+zy!ba(=L`n~N@&0=~}5dWkXne`&LNk&b^g>u$uSzTS}; zQf+h%`;B(vt;&zmxC;gU`hG3L_ZZl&+xdJ>`9hfSes5+T-+f^FjAzy1{ilpiHfuZm zg@Yo$+_z-;k>&VQ;4boj3aurIkuVLy-K>qTdoe8BIJ z_IzK-_bo|J;e)Lk5hfo(`Dah5=cJ?WXEo6C9Buz@WTJ#|Jt5@da=;Xw>n^l>=qB?m zMtiJ(vKE_`+Lt)m(a?36Mb(d*;?0$&Z3-4Dd_t$7X-*58!2xA);Q~7s#qg_5D zD>XdpQVspPE%oxh9C#OzZqJJnK(#zl5^zUoA{<*%h{uQVn^AEMJz1Ge; z#e?!hl=9vVU^LahZ?{jWKDIqq^07Rh*xm!mbHg4_9sIu3Z@`rL-BhM($mKFn_rt*A>w#)iNo-O}%7ifIyzg?zqGF|cZaV1&1SNI%P z)E@hN&0LpfP9Hz!a=^kvI!k<2K>6NKE4n_8vD)dHmOn^hr}23 zryQjC0&Xe?htLlcX<|1&D|px2MfVd@c>sNChA!^ukTyN$p89n@U(3E`jHx#Mk@ z%1!JNP)PmZ&@O!+^c%BXs_Q5AHKc=wvP)k_{VnYhkRo2GT>?NpwDRjxyEN_^wM*u= zQeN>dO6L&-@VI|_DErdNpZy<{E7VbAUjQG8T=}^t+5y@Zx1Xi9vjl(o14Na2TSVAQ zZzX;m67huo_FIpK+@sFsa(|rth55w(5PrLjyQw|_sTzF(Tw`BBG_kL!v#EV$r|_iq z)$(6=zQ(71`{fF^@)z7r#aFBSeboE~-k*vpGyhhTvw4&I5zDpyvo5iAFVk?u=EsxF zzc0_!_2kMuw{H-XHjw^OQ zyVt{hvB}h52TT(3d{f8=pU+*x&coh%`@YUx8h>i7TpOKQ>8Ib1>+7WPp!zSw_dMcj z^TkQ$O7}ASt^et{7Nh@JZuhKzi-Y#5$0c1(lJQOath)aBx>92NPRHAYJ7hsB=^oaw zbBl!jou~MEKQE%|ZhlS;_cP17TDZO>=ijQ@AL{=++rM44g!Jsvaoz6Ejcq?7-}Zcw zx3Hci+^-AkfgvLwccW_3Z#-y}+@|Za$$h$B7*`a(eA_z(0rG_|kjo3p{Rnd*Kfhag zhAL9Cd~I*ic4$AD-g_(Gk46P}XuofX?_9>;{l(SG{9G*KU;4T`i;VBRA_Ux`6eG&5|K(Z%*C$AfBfqpTKVE=a)8e-(J^?`wB%_m+h^5 zTf)A=3<+^=TSDv$8LaE7IHzQ=u16<@$pV+{oLPTin!vpkTfZ(GkbbPJJR4ng_g3B`a9`ou25&T2&!vmO-6J&wNLofymRd&c$Tb9`f&n_)R&X{3V;`h~6Z(6(tPmFZ+jq zo{%3Q{r?j5$N6xQh{qta4l!ko=Gvf%^-pPqc%4a1KuMbq=WhRoe~jF<9Ipe2;sLz~$-z#iMhB z!3E2|!r;>kUL|n0pYj@scfR{LAD(0UgSFXrV3u`UC|`nF*0Dj(|K~eCEpHxBuD&^| zR<0JKA31xEaaqTu(V2jk;bU~qMwsu|CEsObx%Zw^TW${0UGE*QL&^UnINtuf-(?;1 z@SF92Qv8&p^T_Rnw|^?+llV=VQ;XjV1N@lo4|f**yF{TLP_Nma5B^{3={JPl%R0`L zn=JDke09l^bx5)-|-<`uj%-RoF``ecg(Kk!vfTwi}XV- z`Hn}$zo1;v^=AHkb@ z{{F*Q9S%0*YC{d=^IzqH#&!iR5*owziu@40n)OFHGEg7lE|{JT2-%s9gK z4i;J8d1-qusgq-#M?Vt$&xh}h`F2|0^)qVi4w^fn`qtyf3*HAz>w8|EoL_bX^@aY| zc{pN-?=q(K9xI+pVA$}z=d`{r)$xsZ=AwVbU$p~|)TJNkcyc4=WVz_)zw`QXb#mw9 zF#Z3r*p)ZHvB*U~PU}0?@#r2HkX)qx9p&`j1N=h05Ai$}y`KoZ&*mu`gbzMn=r8EK zC)vE^ZIYhNTi#*$ecrOsV4t^aGT7%WI<95&mSL;!fcS@fg%1k6vZC|H+Y5hf91)pcBzuQ-Mx$qU|fvmjG%XVA) zJ`dX?u+PKdiu${5FXM{(!%0EkXAJ$caGn;%AML!1pRCG7n^Ji^DX?=-g#3K!UB7?w z(>M;QJUtQP;3^oRTy#rQe$mgW(eqv3_E_B}Q`P|vq|{vHp# zd!6v{+?0>!AH(<^j<*-UG08<|ruBZg&d+!e+I2sJS#QkjSA4zek-pEF$(g>-n#q~IKTUq2`GfvF z^SI1aA>g~ZC}Gl>u2+k_4#&Iwb^Cq0ZU5;L=n(c{C4W3Ts$u#bir#-0)+6^8RHZpN z2SkKuCk`NrbbbTm%IQbDME*Fw_&%-J;p9GDUk~5&-BEX+!!GW7^=dn;-|ur+h5AE$ z`2MfIzZ>Seop?NCeC<^_`F;`e6%F5qk&oN#gzvU6Z~NilILobetP`u;*tsv?$B(zE z9Oa^yAXhDZ(vS5L9fj-ObJ18UI$>Wz=~UPu^NqM_bnD!y@SyHLB;C6d9@71dWTDPi z;;n|~;qG~Wy(fPhf42wujt9lw<|2D9ePx$)ARH$iCf(OrzaG#qr0Y7+mGwlKj1OxlwQs>+ zz8}3r_*829ONkHVit9&-$y0Wpf%32AeFo0A>H(ooc8}qx!m{cL`a{l%2lZ0EmsFiB zcx3rI6mF7#bQ$|Mr!If7W&R&Ce`UUG)PrnD$KU)R4j8v)G@l3cDQ&&sn_^3(eR+7d%UCFK)P}W0ZOn;FZHT6`sqGepovD zzXDCM|6fM`Lpljw4;fxqg(h;?vsbXV-4C3@z_ATZqatb_m=+T-K8T3{}$vA z`85x8A^leW7<|!gG_hl=q<(zQS;Ek6yny|#8;^1kgbhz`^$Q|zeVw|#7!Q6%;G}!6 zj_*UCPV;J`PTI9&=rS6+N+5J5d`MM^MuS`x_%hhE^C|56NAy=~lxynV| zB0v4zYA^kqXlO6Rj+q{jfA9OFT6q=w>3SQSqyHZK$KKRmoFsOm*Ul64b*i5d59&FE zq+9)%cu3dflZEQ%#9MzNa+xf(a~MY`e^@t>{?U)1-EzHXcJB)9Z7%v#Y0vNf^Yv1n zSLWOG{Wq=)P%caD5Kug0w_hlN!Gc`<>n%yd*K|JaEAxqUiPCC`jC7tRYCnwlBniJGNCcQ|v^!}=f z#$(?>{HM5T)@hjkZ_i5lg3WH5Q zD@GqXC*}07r&EXr=QV8a^M3;U5U$c+I7d1f@}KvcW%HTF{_s2{`YrurKZdOze}jI6 z_f+hlpJeBD<7#96|H=G;Ty`*jFfZ|Xhim8)DSu;=Bhz2M7d4bqn7Lz`_sbD(#7pm*fYu3v!ug9n7)K5n@_($7PaX#ZrQ zQ$s)UjpdiT9`a;#X|OYP{~Yeo75^cw+Pu{CE*`XbX}9WEJhV^ewF~#Czj3wNljLHh zzkj#H&-Lb__lXS+`?(i*;XP{Ai=e+GT+*G%#R2q(_}@l;x5Qub`@J%m-sm_L${*#l zUanmp$xmOOcx9a&irfZr==l~CFI&F}{pzCO{pU!ppEu`IJ$oi{fnOAAJoN8{|LYWH zzpsEDj>~H#qFMd#Y+C=Bl0WpfxbETnh^vwCE%Re+{@G;yIOkThU!7K$-{zl9@}DjF zyXx}KQMgI|XET3gfu-LdauQb;S$SOt&*qyiRsR5dqP&wnr=UE}wMu-syhQr#>wWR+ zE`dY2E5e?T&qXW0tSS94@xl|*?>xY{=$qO;8s~aQcHhF+74OP?u|xT`B2sJhFrpm` zqTWvPwgDu`QYPzrSmOp_kgwYtbe7S)TaC#JfQ9MYI)-Ep*w*` zi~4hsuDAL9)0rQ7X#dmwi}E^`U+c%ZX^M9suala{NnTDt*2*jO9s6Z1&@{TFE2|}PdOf@6dL%HyKjKBL|92a$6Al~kN zm-phg8F#x+xH+hyx)xF>&MYj^b4V1Y9CMgT?0KuZq`dPLbnNG zAM54gxso9}$8Yv9JumO`Uz4vPJKuj;`^ZtERxf7*_Ho$nX$kG*oFEoj3YA zD)IUEe(Ir+ExY%~#+zKUTj?-Q)1Qd(;3d$LdcAl$j|XpB`^1h1ryr;B;3L9UFc?px zeYN?~QQqJFM2rXj_%_O6D}0aNc<^zw6Y6QJ@!%2Sa~#KmQPg)N;{o~BKZfz(Dy)0> zI!fj*{Qiswt8PL6j$k~vP4bU@Jh&D4k7Yb~CCVSmc<{$d*uN)lJh<;ihaL~k8_Rfb z38fQy#KE4SolncRKVRT{`vo#y=G)JgeU*HBm#q8d+n*=%oP7IpK{L?3eXhR$)czcq zkLKIYll}MXyvZDyzhv*Bcjep40&Z6XFyiJS}n4fsE zp7rNae;ps6?-nF~Jf!W#m+3qsT_3s}1@R=E=I333g%`qp&+L@~Mt=WnE?OuN^fOOj zKI50q+p_OcnV&e*>R)R0�^aoZ9-+b?6(d+{KpvYR#96ex`oJc7^E=hxCPh3tj1F zK^?@;Y6smydeyIAdA@@iYV&O(AJ%I-r0>=Amu(#d?;S`xI43V5{4EK?b~d0q%e@HY zNH2Q8xIaVWg?{b_g7?z!p1H*1{%8sD-mBHG>)b3)O5py=wEW)S`#V_2uyPx%ocWWL z4F)&*l|r{6?H|u+io9EY{k}rKUzz=Q*+o2`p!-?b_;8|BfN{gl_k2nG=WN~d9~B-{ z{wLj^RCvhF115>cB6PXWV+r_uI#gQ!^V8HT>jp2yt)TaEuS8)YyW?v zeb>8s`j(;db<;5+BlI05pL<|B4AA9oE#@jS>1)#uuFX zH+>wHa&cwA;QbBttT6lWD9VTR-z@t}x=!rp2J5=E+pYe>&06m`o$s=KO0?U{q*K>NVq4e4{o7jq zItZ-f+hTBs!J7;g5cOoiRXub(eLXfOUQVrk5<~w!PACstCuY4% zekl9eGCuk|4eP|pcmIyz9BL8dae9#f=%RAr^a|@;638*u6{Q~L%X59O(j$DI*_M-W zP56twY(J01d?zEHe;?bw;~m~F$ozNz!Yho?_~Jj?nm%oE4+xielQ z8S-s&C5+dTODz9~3a?Z7&9`+6?CU={`8qG?IB4=`-?jAmlNnmi-G*O(VW037_Zuod z3wsTAz1|~m$iF>YX9m6n)IolnfwfBKhttLNaVCZ*_S?^;x}9UW6QNhk&&S8FvrsRe zx$E@@`^5*}J5>G+YFM)Si~ZhMzu#(Zhqx;kw_Lxi+{s!G$6+=(bNsmy5)abd!?Mw} z)HX>pB~I7xwLTx8d_C%&sEe4!{g!@#@x{J};`!p|E8W@72Yb+8ThAgLsX6Q?OEUc- zrmq8lhv`LzL3*_Z?V0}h_gSfz>__%p(KTYna4(M9v+97tohuX`+@NsxDh)4I{q^sa z_&rjw*+I7_Zih2_5{rD4?>rY+!f#qVM?&v6*2hJzyj*g=B&X{rZa?FbG~VsY%yhr~ zf2%wWsy+5|#(uuo<=*u&mNR$yZ*rM)Q{!NeDk%=~OOC1@OlWHog@02%Id@ z`s3I4X!+|EZlv3g&@KH=A#$?-?IIu7yYlL_T2KE94ewkfVShpIsd0Vwb1PmB_g!iI z3ny#Xt>;3MrMCZhpUy`xZ&bW(9^(E&e?i|5$9{mM_ZR-v<{3)w{`5O8N{8&ckI|vv z^BI#1JLi$gnayY5Z&~{~k4gJeM~D7`-qXYJ_cy`45|ocKK`*xtF>D>5@H~Occh+e< z<WKzi(C8?Wx?? ziYVg$cX%Pw&n>%s=6vfEq~m+i!grkKl6g;lobJ#2eQ0@mZz$V;Fg-!LEXevN_0TTq zd@Vcop!4-+=X@t3Kk0p1Cn=;4=}ilASb7Kj-pKPN>$E(}-3HtGbfWva4oUZU$4vKq zHy;_@A4C37jwm;z+s1zZ9V<#l+7po{lXs?9p$OT%UpimU&dd4vIn_)59u@ow(d%?w zD3~X+ea}J39Zidk)icaZ`1Cb-Bz%7fSt^p6L2S*bnN7+YjdBX*hIlaF`e|OmFX7u#; zmu&sV^}zKx-=VtVcFw{S?(g}Ph8$D z`Q1*$4gQmlYu^<5mskI*;UR4&qaPT9$Nikv^xJCmQ@_N^XY|tXID>V3ZKR*Z zXY|`Ccs0^T<6HYj+FtznC93B)NH;_e7%>y$FvDE*E~Q()`A6k7n*UDoj}{IXor+RH zvT%dJ<{vHGC~z`Ul0k3tk1ki3dRN=tfV7vKqv`2+qA3bHecZ0p`%O-l^qyOjyYiZ~ zf_EB^@sUrw#{8>Q=3jMQEB*lPW05d9VZMg<&C}4|Utc;$V65k8{|ZHem9Fl$z+Ota z`)#m~2CJWjdmpU4`fG8;=v7d^&HXa?9ag`|pRFrnUE0d)db0afnIE^$+H*f{kHNlP zyv54vcz}CQ4IZl>x5M(QAJ^Z#Q1A@xnD|3gr8oI4b~o@7Xm{xkktMWq@4@47QDY!gSU=>{(bdke%+UlzZw1R1^w{e)p6-hv-&@H zjQn}Drk|%8p6ypUcC}{HTZkF?*RKDbi;Xg@$>MWg2J8V z4-M{Cx(?a<7>7LvwnFO}*8H)R5Aj>Tb;rOyaNa;XPh3p;Es%cuy1-&saT=KHoYQq; zSp0i)KHv8DD9dHuGR6GoNxraM+7F!XmipP=xHCe!EPk8?Tg@lKeMj!}u>9-aT&rJV z_ts0Zx=v*IRw1ABudi^c(C1KiO|IeBJQ*+JL(p?x9X*K$@w@8fr02ZD&{H?)ThTMb z^MKX+)_(>aZ9al~piNHo9t@njHrVcssVF_tdCXRYeLrsGL4}EL-|S}lY&vk0ey1R7 zw%&ER(6P7r9g)xMy}hrg{HE{ieL>;$y}i#UZ13&$&3d*VkX+2#;n!XL2O9D+K0H}_ zC#qZzE>e2-O0vko37A*5q949ztmTfop4qy<;QR)B4saiPo#I!oAItzAihW9S2e_Ml=u}IzXkvvzNfMaVYn|nO874P!7~A!EP@~-s|-d! zPdVw{&`|#X;};HS{GFB`MBBmgHb3M%Y@d|hC;5_vdo^6D<4JPDZiR2#rQznC8s4`< z!gx^e$9EeH)_&q#wZTe{qvK{d<@HP@kn=!8*~WVcKfOS@NZ#{Af7eG2P~Gh55pt*!HKA z?s*EIL+z#fb}4+efSBLU5jZ{H;qS%S_e7FenlBgqtKCuC%qeq zHGFy`I;0!luL|q^z!>Z02%3u?mU{CYjqP3~=}PbX#K!ciC0+MPvUN(6!*tv|IV1nTXD__F?kiMZG{4dnQ26=El*!W)jrTzfUfy(%fbD$jGc@Feh2$Q8tgg!h6I!WR?<-9<=dQ>Ey z^n?khu_GHnZ+;(lSMXhU+KIQn0{vgTOUhw=Mg2qjE=s(8qrlDT8?gHJ*44KT^(C7Z zNxAp|wVU~I&$jwESpD-gy<+)J000lg z$4mC8Z0owLhZ+34r86<?Jl@2Y^aqqS2-;~p& zeA21<98Xa~C!LBA2uLa&;C*G!4q;nBXhw{9l4&Qu$Z|KJlfH!IXP5JE}`GA8doX?cUk&& zgXbx{dJ8nQw*6J0GuwNJbX~oV&ES2ORc4>osNE@aNf_eYW92>|a-`|Fr(E0HyhuXw zh1SLIbEQ9WU$C!_bB&5uWrek~!r&f*dlbI25pU8hr0;yd^k48#?9i1Q*W3;jHdwu? zKS^Q0VAUV2=Nhc^P71384*OfIYj2gcSG4xxdz$%SAS|BH54#dD?$x&Tc1V~M^j@eq z^*a`8`k>+4eVxMYe=NL4%b9&m&kJ4LA?+n}s_@`@rIN2~`#AYFdTXFd`GE2{Ho86_ z(Xwt;#81k@%}x6w#Za&I3;UB2;c^@LkBbjkUh#~}n+y-mJ|UM)@OWv{der|3>B{*L z&fQ6WDR&b9XX`f?NqoppvFAM9xasBwx7JXXUh4SG^)6I^RPhu+kC7dfEVRQ18DdaQ#4(UKU72;8B zf=6CX$2IT&Y^gs=>CSdZ7d{;KM(g~e3$fNg`9iZb=NzcdEH?|~a?vkD|H(%_VSOES z_Pz5k_0bQ`MS5RXy}b|l!SN=f!@>2<^trVh%#n8fN$q4H2VIEAJ=YEKJrX~sA%3I8 z7aQVtN&Ga857x6r5g)EU6+yF+V10?}H1+E_J};tQOU?6hko2?m5ROqP9=?Y`gPLqU zApFI-Jq9u=P7mT{q1&`-~^#zRX4k4G^WQKTq;cV9@k_=v_Mk{UyK9jKG9@2w8x zHC?Z|LK;Xq2Y$mJN%tBFpN#vMe;(jN{h%KCeZ{^$b}aWyY{b2m@%H^fmw0%ehBgn+ zw>93c-0U6)>d^tvg>+uDp5qOE;K}Bx3gdk!SszdC)BU}0eW>ZZ4eO+un*Eh4QGaO9 z_OqEcrwH zr;4epVF~=kHSOy6<)Yk;8yQpJKoLab$$=Q z9hlgK_{)6-kU>7;CvaV5o4%JC58J%~6-_600~V zT!+Lb_l=4iV!b)lS9%bBo{Z&c-)Grta_jGd>-dEEz3Qu-rwIGS`@=#!d7lR5ffhfu z`;^(=U)`>Fqekq~|(#5~~NdAWFQ236g z&?h^W8Y%4O!$EJBC!IdFlJlseet~C? z^ZTFwhrqbEQ~Nu(QRFCGM|&IOqSZRuk@Wk0N7(QCkFeiwuj%(dUBBO0*Y7t7Og(VE z+=KGDNY@ib76>__bbat#gMFOrc%DS$@%>|#&v(ofe>C6m99= zX6H${a(RQ6Z_|o>d}}sO_}sc?_L{8{U$xtDd9T3D%75yRpEc3hx&@fONk{D6?Z+r3D>qe8o97wZjjf0z66Q0U4L#_t1LNZyHtjK>@M9 zWcKc`^V%OOzJcA@#rljNVL$fsTy0^e>T5t(_Y3|IbPeCbw0y>RKywRf~#l$aDI@$Q$gifcj|JyA;#BLwXgZRA%aaGGv zUY%YiHKA9{_{wqTJz8Hpr1~;)t-)IrKhpK>-{*bJI{s76IG*6Vxny+t{qLc@Nc*MtV8q+ZPqF(?!}7c9#%ana>)DMXQE_#*%J+1we=(4t zf{IJRlmpC*J*ZO(7xNr!Z~rg$azlIj z^c-(Zjsrc@am4IVlX2vwplhg?I^JsjaQwKoE}xFK8UH^I`egRg_c@;||3ekGalEyD z2YNgj9i3ltF8kkdylwPPW;CH!>+#m`OvhUtf2mjRud(Ak-eM5|PwVlPtF}l#hVk}U zLA#~4nKB+_(sy6{ER-u5*Q2|0(lJ@@?OK%E#GUi*a_GjI+A06^^ru zz>@lL_VDA{bA*w3%ojN><}qIc>k*!7^T;{k=VbH8b0zQE7P;Bw{ZMgqj)x%FaGq9_51j>SIRfT??+9`KY8QV)TjCQwGos%n)%{gplfJn zTFn>Bb@}S&i$8;@dFsY52p^ts{OSRm(jyqZc1iq^&lj&}|67hGA8PEQk6#y}7r@8nU*UX_JIT%Fi=&7?lKJArLA!^aFY0+`jt6|kGGF{6?Zt7J zFOI`iS5Jre;^cr{Plx&9bG}>aKlps{T*N;e=Zk;40(=bgl%nM8?oY@0VjlXv95@#7 z|85JjbNZ(vhW%+ho}GBe@~y_(%-?&om-V-vFSZ@BejjhSx&=ED%xj8(>G%EWjm`S^ z=Qqxybl<1hcuP&n$yW}5?=j357X2%on;9};2d|-|);kgzJSm@ab~X6F|MsV~?QMY^;r-o)d_P3K-pYXOJNSD7I{t-pEdl>rG(+e_KeO36 z{_H+yJ6AFj0~sEC*HY@w?q%Ge@Hvuq|-8vP6%zeD=G5cz!_B5ZHJ?W_Fw z+mzSGL|(J+73n%ydEEw-hFrCsFQI=InD1|PAtvnSF2d_2o7jgU``zhskbcKm`hjyW zqs$rNLpkt!$ijHi#lL&${z%fT^oWNtIeiVLKDb}Qm9V!Rypqr4tGo_vE{F2=l?e{Bn+I`W3df!0Ot@lO8LpufE zWZ_@e%2~_z?LI4fqMVb{*}nE?Bp%<}mHPV9@BDp6>+d!>ANqu~XL7#v5rvnkoR4)M zDi`T@!pfBoYkAZ6kd7O{Pv;lu_UJ93`+7A%tBphLp!yiz1^SkHjT>4&5|xySMY zR{p@R72aU*sK86lg>!`5tjSx?B4f;rkVT$D4k~K|EX+qaACwf7s+Jy?^+Am9N(K51X7^0K($&`Wx>bo~H7d>Z$H? zf%LjOivHOfS}@KY(=Czt;B;>v>tfS23>IIoi%WV*j9b z65>8T4KG&xP2VR<-_KNfXZH{5_>hgWcK_hL=K@Qd<6A#RLcSBl$G>wM8{ho?;CP+V zHM3`$KjV+@>)QMDgJy5k-Hk>r)BL0x`H1smBCi>&^4oY{p2qvRRv-WTJH3thwZG+c zozh@qy0#m?Z70!);`d6n*7pzJ`z^^=UcXoKuj4HswD-H!9<3`91iZ&!<4a+$>Z86M z8pQ*L;o683jb)bVnLWKaDC z*FVyaPk(2J%8{M>OP1<6pX3BRFOzJxb2Jt0C;SHSFWf)qFFaErXT*{rkSa%5QqlRb`*jv7mmj+woGn(L)2w_fL@iaNIoPeZ=dv|Ka+} z7TA+ie<7c4C;tNnjo2Rd9h%)otn$`Ew(Fl@~$=(24Szv$i4UUGxxADM6AMH+IvA_7jQQcloG{T6?(vn08YPt`Ii4?HFr z(|FXwCmt~W=56NREWK3P@3;F^lFeO;&k1uh?DY3irwNR8GVNbsvcXDM_ZP6v)7CPqJ z&S~J!4&l%AUDa5(4elT<2@VE@58^R@LgFi9Z@$z?g3Z?OX}ab3-MfH>&SP0o9q8eq(6(1 zmxj00Hed03Py*mTS<>Bqi7V3-ws9z~%u)Cx&F^+RS*rUYZs(Jw(?*$N8ti;e_?^wA zzMrD^iiUVn?tQ<6^!zLOV@A(XTbJOQ?Ng}!W^`5kh8+5Ir!tHI`H2KJ5ikACWn zm)l?jd^vve&Bkd^+XJ^|@$AQ@#TiWeetBEAE){RrcH?2=<2}0W7q2H3n(Oz=Ktt~z z=X2yoE_#XNkB4;sG5cPu&d1{Pd$H>G##d-N>3yPCN^$y4YR?Y)o?clBlq)w0UwxgR zZq)uj-70StjpsTB#|zvKB<1S&S!tISAuH*0<=Wc*cSt$)cX8jdlxM#6*VpFb z{4m{rtg2ix-=Egy)A@?(sr&uRx27)NeC&((ek9ZHWcqgN&qSMt->)#<2UdEZA6?du z^XmG+dleji_Sf^xs>?T7+Ex6*eADal@qWj+YV>@M;=%EkBM9-W-oo)$$FpGmFB$9g zi1{ypeGlWwFUGIf%W>s3YWD_B&dx^yp7;U@qS)@QOS)|w?Nt5odzkz_kYuf<`+je~ z-P6Q*A|wQ#RJ9$hcZ(l#kHW<7%4>i}b%Dy&bd9IIBEsx9>5+?Yco`4d zIR#<1&Z+UeReg`GuXCS{H-q*bo2{e9L-roqLR)9us`t+%OLt5DvF;~^^!0JOqXpeB z6}rz7J&FexY5#hq8^Yg@_MzV7%k7AtAt2@A z(B~<7q`vGP-6aaA_vkKC_-w5`>0BUidY+=?J-YgRZ2!)y?;nt#Mf}G-aLRwsl220T zYM__U-RMO+J@`tF6PE7*El2tk@ssJ_1AVZyBkV znVqM=I4^kBzpoL>OBd=3`?rzsYHf{ry$e5ajz;Q9I(^)qrf`#U6y(3JpN4WF^w_HP zy1$jZm#p$e{Qn3D^``RZ=P2@0u%SM~ljWwqiu7G1dY_HM&z5r7=ahKdkEilbU8QiR z$;aRlf#abbjX&&tAL?&XKFOiXZhcYgac}hwsi&{gOk{bBDUi16=U-4FzNAmq9tech__-^kf zR*cVu*BIYT4mw}0@SxGF`$mQB{;Fi*O9f8tM9cFq|19{Ihp!j@`F#t`{CCPf@jVg$ z|je)w@;e z@3;G5Q~&Tr-u?@|UCmLM`ls^UH&qQ>Z$;bfo61od`E36(7kyg!r{+36f5rQ7={NX( z`-qzPi1B|Pq%Kg-GJK>C@yD>{JH9%b_#v(F}Hl-rv5 zOYpr(;?rz@C$v}O+X)bCw=bo(sSz=aQ~BC2bja+?K7(B!_ZqDH@_XCD{i8kb>yBg| zv!iYv^Xip4j-VQ;hyCJn6aMF-cS`%AUU586$E~Vlm34ah1GEQ=5XFA~1D0sRaynm7 zzQ7L`{bs)LC=ljjf6{TXs{CQT-{BsGFy9XPA64Zi(|^tMVZ#SPBz#z>u-{We{JIRk z57*&0AoVF;VZMj!^8vrOs&>TB*@f$5b9<==146e_+ePA^hIqR^#~5$Jc+!>q`1v;w zUsk*cfAJOQ7nK4}m|yxAjAN(0GLy4>+cc9im8018{cNp={o|8dpke(wb28oHO<#z| zCy0l-715-(YC6X;{EOzU;$QX087{W?QkyDLJ>DVT#?|2M^I%0Z(~ILZ{$4123CE-7 z1K(WKCGox0zmTx6)7BFP9~9WnI!FvEJh@r^!;BB-h};}cZUjQ zzGH&OLB8V|I`6>uHz{KIj&_-MEJOS=1Re)kGrmpW^!qVrznQbgmfWYu|F*IAYI2p|MC4pf#a&iv;RfZ$Mlz= z|I6{4@X^de*4R4b^F-d&KlOc@^8GteE93y*9pvNlN%p6U@BbAR56#Iz0Sb%7M$9&qJn3dOdv|Z zc3b;HHXm7N?Qeat=v}f@<#p`ylTWDJRuq5oS@m?6$zP+MJ_?}=={pbeN$ej<{!mXp zf_%M|X{tX3O)s@g5PL;EJ+Ik%Fyv@=o!|6Z2s`;k`-%Co)HnCk8GSlPSbiT63DqS$|vqcll;W%1){Gm zhwl`-7gyYm+#>nhFU5Vm3ZG>5ysaP=$M^3BR**}R_fX%z3_3RI`{`0Hw0An+<7iWB z2lYIP&JR<&qS>GaN*_ND8n(NuX}egAudDwSz`ov*6N^;aKHTy&J+2x(lwIjLy~Oaz zMXzJ^HS(qORyz<6D&6BD!+WdR8}i{DSobRj_J9QS?|o$cjm;~o=J$8nywcVel5U+> z#zQ(^OBP-&@|BZOo8KY0R`sl4c-Ve*e6sS>{enY@u0Rla=w6(>nHsw=A3)J=6C;UvBmrMkiGs;FI4_NB=}>Tl`!N_v2LB5 z^P+fgli*Fh-3;4~dChN#k)M-wI%MnQ|0oEDwhaX2;n6hn5~f zZqoH6wfk|^*H3I*uyqH&_xo`Bogp3rwqDu!b^67>6uFPL)vjlR`6t)Wk>djK|N2#= zpYAKQrk^^zt={9u_bY^srM7nno&6jM>CYz@y-mV=$0cI7N45zV@%wy2PqXvxPZ6)_ zxc?#Cmm=Stf9`iO-?N!-*y@9DbA0smkhr=hm6KDMuVVRt)*2Zn)c;{UCnKHXJu$|3 zBlHaO??8SZr)Y<}kdNg)cULywgB~`N8)dom+HP3x?@=zSpX&m?Zp?Z=T;%w?Mf4%x z)+-jSx2pa?pMM8v@DbIU?u`=0L;8I)eD7T0t#+<@>43nwNC_Pe>V9K*FYsG>AP2?= z`WZrpQx)%Av_s0z27TG@Ny<*xOVyt zBEb*eiIH;IxhD1R`q%1xQJK7~N$ckdU{Y8i@L1&hGuY}503dE;>m%M*M5%>8}*|WIX53x#;_XA7MT|pZE2oY(Kvw<-+mkCgjgW-<9(5 z;2a%SdZilC_vt-Me@xP!taXxHG+*#c@2{St_@wI(cprdWEw#fi;c+^+-}hdLg?_a^ zeh@=4!rvTZ&V2i?50anx_FrKPVR+!6tWUK6Qq~*X9{E02C|A?WZ~E&KA#YU_#>0F? z+SST5p%2bK30|RmPo{k~`KCSe^@U=cJYdPA#@>3q(~&Q|e`US48~VksLVBY=u7Z%0 z(Fgbj`?BnZ<3l~000F@JQ&J$b_eC_t^y{0}Pid_6t2tsi{X@DfvT^tMU*ov_1>tM9 z{-N`yY(G}#J8`-ntMj$^Y-tYjq{(7u(tVbe`?0!?klj-brr{} zq*|H32!B^AO#WRC{+3hu^z{X$2hMMZ+$M$Rs@<=4Dcm_r;lViycb}>7P*LH9Q)~Iq za$Vt*f?v6Env~18{Xh2J1-#CqIv3uOvtz|vd`WiVY*Mmq$FU+}kP}E01BsH5L=l%L z35peSiDUtG(hJ^J5_|lWVmUw@|K%Jz0b<+(Xm81}+(W5bpfMCGw?7xtQtF-pbve+- z<7rQM|Yx!C<8e>m&v%-B{NUnD})(RzB8`$Erv0y;Y;T z-|!qUxKH4if2|xxs#0CiN3N%y2m3CJwW{3h>1Zq`#&=&QB_HzWYxVMi7YNV1ygVu8 z#B#n0Px86@mHx847CGm>N9;!uzPNl174`dTvA*l7;g9gk^fBuzc1Fa%TbMq2KMwmL z467e6{r=Ig@+0wmo#}bjUCQrarPIGxiFvj>hrdPWg+IpN9R_PXNYAhLfhN?Af$+-) zVtZTVi*m#yUjIUF3zI{S_e)ODrFc)_96IHOe1E#<(7*on%rEBlH2f<`D~XSt3<2k!B#zgQkE4A#KW7rmBelKk zp7yXrlH>fyHs#-Cis(e=&X-2zdAs<$|4E}`#^=t5wS1?S_65j|&Yizf5)}Nq8(YB` zghF$N#D4y!&~%l+9LJjQD=%Mx1^-4(E>3#x{GiIGea9Z>DzqJoIxmX#&wkPeIys`U zovynlXdd_^Sz91fkUYu8F@Ois`zifF68Wh3L zfqTF3_5JMp(aWTKmP@{RT(|j)AZ-cH<@1PH@VjNL}L3m z!>G=aeO=S{Wz?T5S3TqN2KZ&A{oS64+n@TC^qu<`(3=$yi@^R*JAM-==b3pI)Dr%WXnm{d?56c_66;J5U z`2J3bhl=IYj^Ts!{Fc1sJ#4yvDCu4&>5|=Qzxa2-lkMuqhW}gX_V0O{9W_+ELGr=B zChv!e*Bh+-9xA%srF_WjF5`pQUAS+_@~PZnU#7t-XV_mZuIo9M>?I2_8o~|WYpRl<%#{j zM`72elz-|g_Q#{xcj5cBTu)~H26bp-f4kWC+4(JyIkl$BJ&p91_pLL4-{`u=L&QzpX()l9! z^{M|cRe#scBVP_d#`>xB3(5-#$M=4e{)(RO!n(T76DyZVI`lJxR~T&b`*hy9Ox~9( z+CPWRSGurYPo5{|3wp?p;z`a|L%`Qr6WebXDvHPb0{Praq(5c-M)gKqZ}uD4A56y( z&(qjnTyIc5r=E9LKJfX}^X^CL`tczt=WyL~(GyiEcFMf%hXat?apT)Q<7ZX*7SBt7 z_NfB)+b|T)(SGLd(|!+qz^bu*C(!O;NRnfIy+eM4u|o~%O4|BF|1#ey_M`GHN$>ii z-mY?a_`0-ndBbNUz583RKC1fu-dq4>pEW4kK6jZT>h-kSN~qibGtB|XPNzx*_qA{{f=#UgV{Z0vwQAWK43qO@Fm>8 zU-{A9W$?JcJqnMFOyyrd!ytrczYE(ryB}aw`x~8d2pNCY37!nrakQRa`aI)TzvQdu zhd!U)4$|_%17-)^q4aQGBlN;-XN>)(DmO!B2bIkZy1&HNu;W^l5BHY{0&X|h?4a%r zfs>{3Iv4IYJLm?5>&tt$^5+tLpWbJ>Kw;;P>yKLd!1>bKBIJp^&Ya~c~_iH)3`wXwinSB@A?-#-Pk-gtyc->ChX0Y37+J7=Tt;@>ku>3s+ zw;MceaI3-l4K5knXYfLShgMc4uGQnQ|4a00WEXH8i}&dscvHRo)95@q^HKlJ!nk-k z%4BD@^yoi zuct%zk6#JPkGCO zdM*8qyxS?-&yzN@Uq-DTk7@rt*?y0F?qAhj+-v&4^2hWYpnov3n`p<8&VTNtydDsJ z;q&-as5d(V?Nv&!?>lzCgU^rs`wZk0SGMxG?N*tg6pdXX==SZ~f&vA)4 zc#i!@%{lhgKD8Bzi1m2!pvJT#S?@;su=$+tlM9s&|9)(Ev_v#mkJEW8_7RKTiQDN2 z*BPUBItDx}_sQ>|zm6W${!=~b{Yc^h&P|}mDSG56_i4B3xDeyxJ`;&p?AT#t?DKRnGk?pl-=*IVTCQF6!pcc>8QT0^?* zI~TEiUP3y)AH(~TuH&j%nB#s3;qNd@(fn`dCH^A|#)O~yv+xH((L z-HZ;G&;5Q~dy_w`$BWoMOm6G>e^}>r>37tRD4c#r{iwn#5C4qxgt21^cOMZrx!LSJ zU-!Kfj6lfe#)Y12y|*OKPjqgzA1TuLjG~>=j-QLxAt+zO$ojprAs@Ng%X&+c`my7D z>l)M+OU7O${K)5~yLbDG!l$^sp$3rt59``f z|0W}?XMNK{+_J-rov;|@00GYY5Sh^ zz6$e`R{qM$M}r{5_2>iaauDu6$k$WaQ|dD+kL5nKxS#s>E?Cb=*c14ka9U3t4=z`H zWzElY7lI#tuWsCKwS0R!`(=vH&u7)>zr~7|?agrV^I577Nkt^M1ye`7zd@DKf0<=~{} zqc@2B4OI1h2Hf9Za`R7`f2Hb)F!p_gyRDo(-&T0F(lPUM25+nD2UntI`CPv|hg~gr zgO5+vKFL<8e%<|S$s&DzB01=qA_sr@6q_XMwQ?%Pulb6H<2VE5VF6;c2gl**><+ds z<=Az7k=6sh@5r4m z+5G@7k^Gt7)dJG<;*ZK}sYeMvS&uKH4^2PLy+|^gXg?Cy(5BC?j+nR|#7?m9&$Ik{ z-w3|jIEiy2sr}&eee#6(P0yD**nH{vqgYS>_lEgteNWX_9B1>=OVQ52Hl6*&60>&w znYL?%*mRvu_S;5!`diQiu^n?9c9Qqk%x`OYd#8=3b}w*tPyTW3e~+nR!F`Gfe?ZGk zx@}xOsowrur58M5pgk~&IQ^bsRF7k{^NMD_M{+|K3)^iaaK!D(eLHUNlmDLX6*cL| zA8%*k`8`zWKaU?p;X_;xt+&lH8r1tmHT5|PJIw17*ZX{=bH8rf{eL|=5y~s(}xBgwI-ll6suLc`eeLtnc zalNGcM43s zf`2prK2|OL*566@>%}foyDp1=zn8g0=nH#g znvVS`YDdI;mHj}G{IK7Xp8s|o@Yuec>F4{4g^-z#o1-Fc1J&nCJlK{~J784rmBM!^ zR1c2*%~oVgwHK`AG;W8VRa^SPb!9QPMXjQO>eTb-wHo0V()3S-K@ zllxa5R=oDT?f5*z+pzy}IzHudTO?n49{f3EPkerTBRxi`Cm&C4Pkj1>`KPld4vXDD zIlSji^6iL}hx0de_Qbvu;y<}PQE8a}*|R4OgT#0|d2ZSh%J*1r=(u`F+9TfA?sh^u z_!_5IdqUI4wg1P#pG=?mJn7l8ucosnrmy$>n);|cQD5)pBi*Uk6R$)1 zwde&U{NHGCL9E(SvnO8qwZ`_uOYrR7xnK&tz6HmwM)znthGZTJnZlBzV|nLJ8P$m zkC<2>)X%Tg-}vm=3A=Utwe|e^dmzsfItyo=EA~|3tOd5NFyGb{=IOe^&V!Q9zv~d6 z*P93bg6~fyU*B^F_1ZzPJKTPY?e(wWXncKtuRj-aElNDuJlD$!kB$g^v0f%!q~{xO zY{vfhh4hD1)E;7cam3H(Oz$r8d2OHCZ%cpxAz9g@aC*L|OJOw=v7XT>u2O0m5Zc4y-m*({!Bcc(c6!oZtul><#{&$&PUwdJ7!q^n}FBvdBgcwk)QHT zbW(&u(=8HD*t~+@w`|7~-{;T$Gdl=J{Z{1C=EV~x|4H|L!At)BIobsG??`)O{r1&b zPK4(O`My;iOS>ePha|gq2_C zbg(@>Hs#zaQMD znSA}-Ujg6uY5iwo`ZPj3=7(~9%yg4CA>Cd}H`~sgTlI8dtcR!jFw&v_YrjePe!yVkdxVF4cX^<^ z;2-2grH=J-(GzF&9Cad16nRwf7bbSW>+1P zdWF>gV(TQS|K*6jPyH{41)gbtZba`*)6jbm^v3Dg&smR8)jVf^=kwpe^L*}mLXVGI z&xYOh`r9cV+P`D@DVdx-4*6M&--I_>T#!|rsq?gJ@$O96Z6AFhehdQe)T9&Zb@S zu|Iik+HEhKhTca&Z`?j^x4o<8x!Y}<@jSKLZiNwq;Pc>#Wd_?hwZb{CmIsA%UL|&Q z;ha~h-|d{0>UTTm8r?s0P6uqMsd6Irb~IlYg)b!5FUP^}Y+d0>_1{Etrt2FEe?kIq zFOI~VC;0ltd9`vW_larxINe;NE1WY+{1;{WuKcPdeE%JIdz-E!`kc=L=$~mPY;(XEpLd*y9s?k1>ZD>F8^FRKW z{YLLODi71ENq-+_5mV*kAYgo7`^WOU!oMmv?ZD&hM0~Tw|EzM9-oH?3H#wS={5Z#C z@Uc34C8O)-m=9%kp879Xuc`hy^J`5KOwIcpg6D|g zQN6)*pQ=gMFX>Fqs!9*j{dP?{@*Ddw44=|RebNt-nEoBVq;f`n=SpZttskzrW`F)|&UqXKh!fhxOh8x>>Jl zrtoV^9lv%=!>=nE@+*^{U%a3Zzid5nSlA}zuf7fKG)MUr^I!U7G@d_!blLdr>r)pA zqBFm*=LLcn-@lW7J=k{qXM7Mwf2RF*<)p%6dcF$dj>3EXN#CzND)7_sn^AwUUG5b9 z|0-z@+|#CURrQD8-^X@jIQjneOnxp0A17dEFu=boay55>!qhX;-^|`vULvIZknt*e z-`j*m8id;Risf|ul=k`)-Jd;8J#e3_&~fs5WP17B6Ua@dX6f#kLdR!MNXOIRXY(21 zr`~&WB7WXHr5=?N)?=pptS!&&P|Dw%rzc9uiq;S{FJ;xi^_G3SH`mlukO3a+Vd>TVe0(}_4{{PK_B@(^p!?_ zgR_P3!3QzTuS1aA=ea7cJPaYJ`nUf<63g?_7?d<1h;`Y3!L3=h@zoGn|bp2)n8V14dlPh4K z2t&MXdmR0q{o?7KGv0}X1=lldU+R(cK1koEW9NIr;*ymAbj}rDj_(Ief3Dc|x2`Y7 za^>e%zW@`#&%Zf8GPyE7RSv7YbjHuG>b=Ome~9I_gA;yVXiTr3haQ)CVchSKr~!PQ8lT_Tf#>1=ejy;ncLejXSWXrHE}={GJnT_F$JvYfGP%w?P}whbZlOu_ zRIKkoMq2)~-$=3N&G{n@!WG_aKS&!UH7I>f(V{zZKMS<)rj4+!0i7}qYw{!B-*^SSL*V?#=u-Vlyzx4Gj5mk&CO>~47g^-gaJ zKR3EZZtzCRxqbgLO|RdPY?S^jlD?w`f4j*C3>pN=DO-y5U&Zv59(%t^_zVk5G6%8SAs>{d9Iy3W`$pr# zZ$Oai?Hk1x%bAW3|El%y`=rwQCeHjgaCmitalr3ouycr~bFaiN;kz)?>;IPsUt|5+ zPrlmy(XqUrs(xJteouej!AbP$K5bC$N1|Sh_4#!7OYKdN}bzIy$7F6p!P zalYF71>V?DZd4J)azjhemF09g=Q3J~2H5`Sq2>F~9WQoPmm-`yVX+lIY($JXOuld1>u9csuOGjQ{?f z6}1b=_mho--}*Ag!8d5VQ-8uyu?w?%FKqvCdhdnGdr0rSIHY#uNzYFolyaWwdlB-v z-_`bLRlfPWB(LeBdH+IWiPLevA=AC8CS7|?I=>I-YNYe_zIUq*jN#!P zA*3+-Mv0TQF6H;ueu3li`Z=Fy>y!76hxfffY;v((wgU4ezkfVb)=BzaoEu>9d)oJ+ zv-63sQ>+3&*zY}Ly?$v`HjX9tbt+x^`X%Q4jUnAvx>Z1t#6bse2R3NB+7+A zEeH5PRFLugY*o;EgWivytofnTFM0IuG~TM;IT^Y`lI4b)pOWXCxBNBmvs}`_@0~I3 zon`jh6UMKqwdbhPnYaCig{Gehp7H}FLHs2C0%fi@e@vbeX7G76_ERW5>3w+GU$Xo1 z4%qwk5@R2|!P^WzV(<=wj~cwoU@aH-d>TAy@5c>3Zt#ACwFPy}?=! z+^cV}@;g+Nj^zB3B*6X9_P*6%r6W1N-C(67IlseTr6W1N)8IbK-!E`-exJry^+^1S zmv%|)cBS|G!YsvKRxuGj`hOs$f7iQr)_l2_g!*y;p8IzU{rik@|2ztLm}1ueWYLdvqActwQ~ovUe7x4sr8*xnG_9 zp=E~ecpKl3NF2){>l@4A5y0f%8?L5(q4Jl>-6Fw{b#=jmalHNhrUnm!&W@meb}xi)b9`~ipS;IT&?XsWb!QAF`Q@K8a^VG-jJ&g3;r*S*aklwTPLgA<1%fR+n2>!-$OFtj&oa1;-{;XPues26o z+t27tY&=iir*h-^#Pv+x&S%HvF{RsgKCfXpCCItUjpv`PTyN*J-DaSV*dI?tA9dE~ zqc1dSw>o|Fden}3kzB>R?iBP9J!NiR*6X99;OlL^FjqvIQ6Dk(@zB3h6YC?^H*QzB z*F+z6t>n09<6%|x8Samh{+H>eB~o6DZ`|_#BlbJt{Dz4Cdw{Yx-RWr>YpAwqCVcW7W!qg(YIae z6YqaN$n}vZzwoK7_=u<9@cdWcsnh=(>eFpUy6N=2%emL{ROJ5$s~U{+t)>TtHEv|T z9s)m3WxQBlBmX~-%1z~ep_RL}Bn&7t>plm+hs))EDeO;l8L>ZqgqZ!Canj~`?|{fn z+@7R2ZjS?i*^X;O-yf0mxIai^o7ZM?UoRiqEdTNo%DL*bP|^N`?@3uXruW+V6&|(z zy0TB7xX#a%Ru=~t~YwlE6Iz(S$9et&NKVzH3H_66`HPa z)&)7RIJFZO&er$*dma84@ZDz4Ueoe7Q<$t0t#rZ-%416UDGo$(mX}tT%EwwfPWR_)@U-8Z`8(44 zSRT~*%uL3ck%$iR<$_4w!;*_gF63AF9hRs)fv`(m%qIV!!rX>j0zu@DG09<0413->d13 z{M*3_bqftAD4|U)z@a$84%za1kc+T$1*ySy(IU@B7gGV)fo8k#?S9-%bBt{7LDj$*^7H^TqxunO&nNBOe zUGXF(#mjQZUzRH|=tFZn)!StFoo<_dWbJSLb%n}P+V5AWJf-Ja*_a=+Aj;!=4Hzw5Zd0}6AzWeei|9_7!yUGl>3ZG82uFBX{l z3K{Sn6N$ZjmmxnX2y0Xhe4lmd&s?DO#6C{JpYG#wzAR`FeCc?t=yS=2k~~lByPsU| zMp3!sLrUNBU4%%Ft)El`6o2ng@Sk$p0{=r8=#&?4x$y6`e&!eReV|PDP8eFj>YdMh zU(zjq#PKU%eSIgbZ`Jsz)N#2QT>&B?IpL5xNGKs9d^zGidWZd{5vTy4XME)Jviw!UN(1bV3ujgOz z0kFiN=SuuoW$$}u>AIG$lQ?~i=sE_v!d|U+p+(o@_+1V(&r{1E(GKQv=Jn^eI3A5> ztlv#{W#g>tffKd&UbOczltcc^eORiI>c>Xyeqlqo%G#G2DpalAt-t2&-sN=OaDnnW zxu7Hk=5xojy|1?NmsqT9NYBfXA8hGxMW-Z4zbCpv+duxEDC<*bMuQ-*eUMe!fBahH zH+`G<{LK5?LZ;$-iE_z8jVZURm;1M!ufhD(?!PX~s<)?)qy0{0UU{&lJ+F+~ll7oH zxPN@W_>{ES_)}Cp`u16Q*-!HJSuG-`-tP*tQ~~+;?(1Q1pEX-nObfGK2%V|pKU4#L z&ld(1@SdD3%zA!mkF&-7e!K$8ql6Y_%@IBmKSz4^`w?b-O{Msm-q)-7p5?lKg)piL z7(WmQvt@>gDktH=5+A4Q@4aVRI&D6zKWoFqb~f9=$0a|1%>EM4@16v%X0WEJnOUdOfexJt4+LHW89yk0dUb$6>$*)55`NDVh%g*R~NfX*VavKqo#Dz#7zh4WO z5`5bwfx(VJa;mUf79hS*{pVp zuba{?C&?VwONb}d;Sa*{wHcpFfE)4iwuql;dZcZ{&#+g^JsDqno4@gt(1UuCg0#H> zGfb@2_~NTIp4g@FTrvm2>lGHY3S4MKTKkeyr);FKCa~_NIxsUg8xvUS%eJ#rMd+1MEF6br6J|3iUYwgB) zek@O(8nRSAD7brLUSf1}IaX-%T1sPxYzD}?83Hsaw#&U+3zu$RVrr+EjNPS8?%NL!5-)jV2 z&hNudmX+i|%4hH+mNS>DTK?C`8S2U4dNVwse8~9SFT7g@IbzS5NbSXf3;3y`k8d;H}bx=Ji*hq@BW}twQfJQLkSEDYxyol z9)`4^-BJ=bxq4dp`T1E)pVmtW!o3$#-?U!ZU2+pL0HNKT4)j;4cU6kX#*+?(eZOMd zKdz1HwLBPqkev0o*zASr#@V^+6t9o-wf!NIA6d7X&c0%Q)cKIw<%8*b$kqerY5S&j z*rKU$n5TTo-cN;nd%w2g77(Ae)bDR-wf@{`bpD^W zF8mGj`7^OD{8iv_Khtc;kM!pa(yY?%{rE|J^kt-bCf0=)NAmlBgP(o?HZl7l{yi-} z{YPLclHcsdr{bsowO66HuXg<$mKgqL$ZwzC`@2l(b^T9%kzVRWvXcD27478T z@$7Bk=&SNln{F^_C;#4TcvSfk9#cMr4`{u@2TOt{>`;CVwXjv-m+31>oOD_JJB+`r z#$SDm@4s|Py3}u1?ohZ%>7zfF^u>NVug?n9$K^e_piA;47j$a;u;Sr+N>HtzE@{*G z1@3`Tdjn~RH>{BCSl>`PBw49`H23QjX50F~gPM->5z^;+Eavx%Kwq!S9vZ*DD&li8 zN9_UkGq_(kT|XFAdM2*Wa(&%|_B6vUEGbCru&>k6Z^M>J_rYJH^$tt5-l1gmYt{0D z$x*mW%Nu&EBzT90v|W>jtUYI0d){g7d7~tg^J(M<%WY>2`p8%6ch0YRo2E_IH0*a=}zN!1q?Az1{9g?N3`*Dm1J9qTG@GLh~&A1^;Y63GETq znEmN*P=4CaZNGgO#0!Ko;rE@avA6EOGtN6t5d(P-PitqtH0OxyABmi->)kP zzv+LXob~c@00duu4EL(M#{QAN1K-l|X-JYwdwzBe@}c>~@9TH~bAB*4Xu69xX`H;T zBtMc58U8!;x%)4s_4~r+U^r#JFX*7)*7<#{-0A(k+RrGj_rDHuJfQN){zy(G=PR7b zvF#6I|D^_|{w%TFhw%qt`7m=Se@loP@o{IwN6(+;dz$?0ZT_bC8JwZD)9rZT@`Sly9M|!@eT$1O>fVQ{GiR*oSAC!U5 zDKEADu3CSP`^9SgVBra^-$W!&tZ5&ftqt6E1t z9NZ8`ot0HqCGC;Psnp?R)X#n&0V49xTZN-;e#Y>s{Ag?kC=s$}0;>{luV;H4P(& zwLM#O9INvaw=NR;LUV`2>Hg2{ns0Es-mgGDvfUc-QJzP9{MTvtSUi(_M1Oo*e&C3Y zG;N$enSbT2!Y`UBi}`+B<;mAAxgN~tr`qmb4u%o2>*M}MI#NIIDeCXqexJ|XB=i?@ zR|6~b?;LGM_S+KRwEZ?@{Xm|(+;2r9gjoK+H;~DHs&C7d|7rGv+WPl4AC>+~zZ^05 zasWXf%;5XuIc}5)JH3zbt?JXS4PS3PWVhl7-kq?Z|q(6{D{7n3TOJ9U^ z;0t4XM@{(d=OE*KOssEg7w!T~`gg)s@O?L7e80B0onOlK%L6$=jIWFMw#wu5z7FEM z>9r^F2X-0$extKR;cB14Z8?SQ96P=bt^VaP&6jlRJX!@p(aVGZZ2M+XMg7 z^S{&i(;A%<>8s(>LBMQ>PT*tx?i>K#%{@x*cBL!cFJF7lpYW-S%m~EOgP3@_fyebW z<(rhp`%^vLO-MH#{j4X$O!n>8o^u|F=HqF{*B>lwwMbn+j z$j+HeDqi0Yo1Qy4X!IVl_pV2d8mx5To*97$i@MGi_nTj>;qw^bsNYz~?h z#NOM0mk4ZkPxsgT=r_a2fWZF6uHyUMyx(}eef;p}lnVyhGqwHZnn->pUask`1`)^c zbD6~#->A=N|FYbPc7<0V68XeX!si8?Ms}D*?)CTPM=Io=FX?=~FY_>@$;;{dT<&EL z0zi0Kuf}T;mGIyFo*SW51m1#&2pjQV=wU*Hr7g{}&+KJySJ>|j@%*chpXupmV_azY zk+k2$U7lY3TN}YA{L9U~LZ6pyzbn7x&aetEnbG;$JB!!=gFg)BZp#f_ug|?bPRd{8 zWsZqg5DUryUxlB>_d@=H6c+y4`$FFMYV{%=e4p~QpV+|H*J!*J`AYaX!3IRwh(bz; z{a(e5crSF&ct%(X!;t)Vnbj}ltL0yX{7nBO{xdGjHokTOK*;A#%vay%Hgts+K)#CK zcai2#`FFL#seWIi{b6a-*|`#4xnE#uQ-ZuTOuOq<=!vh1MR43oQo}UeYh|(peut zUhr?$#{>?y&zs~Aw|~Oz{=F2_Pj}?xy|0%q1AU8;KHXUy_xF6yNH@5>M#xlyiI7_i4KSVD1t@ zkMAz49(KJp@rXS)e`r2u=ci0R|H6fK-f^d<^ZPfbFH3ktz4~kYkVm77`-{kzwfJAc z|BV*+HfSff{m}-hsQp|_K9|u4HU3m>z5E`Ki*3F%myL~ZHRxfvUjFiP&F{HS+asU* zf%0islBfI5e7}2n!6JF#`x;iEKFr|nosLy#H$G?muSEQo1xSeC`>fuw;BJAFl}Dw# zP|^Ct_E`xj$hTGf$fwzJYZ3GLMvEywd`0_!A(bZ^*E4>Rih6#tJ(#ms{$}mt`^)cH zB-yaup>mYryIfu*t9K~<`}Rv*I7jzmCfm2^b2}IAenr36%KdANgD9$48NA+^8{ai@b#SX&Yw%V^5T-v>-8u!Q|qAL?NR#uo}_&4B7Ht?c!ve7mxK8w zO=o;@JcT9*HUj3S`rhytpbr^heMQxo&*{Y8>GE?Kg{H4-{p|j$+e~lxy%NjMeXqQC zKaKBG^?i~qk7cJbr9=4^(}C$3=ukxzKfgqtLy!^T=Su-kHy?0&$H(Krt91Ox=YC@K zQN8B%S!MFuo7eLF+-PqTI!;Zwmjd>FU)%pE|8JA`nvZfV%0-pf=j30=HD?hgE7y;#FR zyWcFHH;f>EcAm9Q`MqSGUW}84?IqobFOMmD3#pKO1sNIb%DrKCJhO>!-@8)T5&PrjeZPp!^M6djijX!*c=T zA(m6#U+nT0%c-ZIkM!Qo`x(4Fe4kFb z|HIC^rR%mut5@nb(t5@BTO36>9B1#kLC17b#`)t*5OY27cyw-SA(CvXY1iu`J>&Oc zWpa_vEg?SOzl8W87b7+KJ7c-ndq~>b+pBEzA73XZK+ec_;sYw|Yns~rZqJ;I-(|D! zxo*Oc eNUVw@t^fv#C&{3YxQUEvUe4OPn`2BnNoIZDaz0G!yUy4WVnDPR{)2!`5 zIpFva?7Vj>_Y2VB5Rx|IgY_?8_jJDa`SVyF$%$BRyZn6ZM&%btce=eE`P^SgJx?Tm zbDm@Jcc4aoeuOR7)Kd^+++%W3;pf{C)O%jz7;G{kQNbp$lc%R{?(+rRqROL?~Csrt6f4j&?=jN)Cf)iSv&8a| zpKJ$we_8N39LBWXy{0EzPFO#tcmEDy2KWKx-uv?HZ36qf>aOqc-Cd=(O}|?jx{MzW zN%DvvPOp7$_y(*0^;Z9zH9hvDNqOO}k~~Q6vwQgO(s?A#bISW+5`(IX@0)`I`?aU#@q)5F7Am_35uQI`>N)T2987&#HaUY`Z|)Y z1Eu`1@~4%LwoO{@>VApKO*Q;r=SIMKp{CouO=5i4Smoxv9R_Rv3l;5u>HheontwLB zqR@|frj`B=D8F_ZzjhhFKA`Et*(Ldr%;{77aw{+Bn6qB#;NXoAK4|@`M`2c1%E4bP z=V9fOse&i%ecDenTdurQ>y7*Rv^@Vl&WB5qVrb6aYd`e-zQ57(56wBI{Mda|wuN<-G+8$WXFj(bv zsJPwW15%%%;v)vDTn`nu8N5sRS=?f<$zgGm!P>q_alOGuE&V!!4;kEVaEru4#nlE+ zTKRVye9YiJgAZH&9)ph<+-2}_gF6k*Nt_frB&Hr?JBR8zNten!A0iAD|3ULr=V`vS z9SV;fRJ`5o3RhY+R<|$Y{fNj-JpbZ+E-C8zk(Z0_oKCWwq+7>@Ot0EHQiX3Zu7I8` z$Um`1;V`~X%A0tP!W>_kuR%TR9^UXoN#1AkyAhRRJBQ(ZR(u~?o~QTwrt`aPmj3kT zcU?7h#Cvg`&&R`feZHObt7?6)yqViZxU4YsG`lGC{qW6dU-U1wPKoD9QTdhePx%@1 ze;)CT8h+qwr+>!ynXbD)Ur}YTobpZFe=$$^(A#vW*cqYPA#i%WrqZtP49?el@fDOa z^}`m@@11p7ejRXqJYxA=bEX}#s>TkX#!vZIBOjrva>)0$p?(7<5A=@%74*L9%k-Y0 zqLv@3yMzw+1Bdi}QLS%C?-$kjrhb!YzlZvOFnXYRx!@gaYmqpNUZUl!%qcu}k;2`_ zwg2onPvO;*0?+jO)~C}hk4|Zqw+h{%;_U)qLx|hu*O5M-)AhT7%6o*~jK4Mx)#w9! z2S)ToFnc>x`W2op=pnzRFUAz+crE&(+t-^j{lIoi^@hoPEa$PFi1ov-!8UOH(A#u@ z>b>-y+2h(C{{50?K`->z=!ND;FHr7x)W|(e8GHv;81!`X#=2)oZ~Vh+V!g5OwDrcd zQ{W|XAS=rA)o6F>dEr}yMHT|AL>P>d)x0n_0$Jh7{dPv{rJKu zeA0FNj8ESa`OfFwCvkc|h;Cb$vhS4RPGa{glMl`R20zfa>c_BmhxL*YD^e}=G6^ZEHlzh`U}33}|EHPOwxs0PW;zvLTWBY!W<4;Tu{k}K$Uk~j}e_@M&wduoFP33kH<%}93 zY}NGXdCP~iTu(=Sd=d)P`*&O(x)Iu?Q|n=V&$L`0zigjq*xRG^9yfi|tl!7Qcqh*b zP5&q{_ZzVug=W78)Z`28PD)8n1@!p-o3OKlr)bXyCCbgE^98}@q3OM6tSrJR#AI1- zvrh1R9}ewEbQ4+Ul6EvdJ;!r~Rfr|uEcJILmzCtX`+a>}c7I`de`xwWjYCuFAKud= z`Qv^naylxH#UFAA^f=#K-q>!`>;si;g0Hu!MaPZztZ$6Z^hy}*m-Myy3z&yfzYkP( zAMBvrClspxP12|9RaKow`~I&`{dIe<^6qjlXma4|bjbqSKV$dJBnwy?`@^K>UvQDY z1GYbGaKR-4*UC{oH&>p=^2eP@UT$*A@~3lxOy0DiT^`x)E^l{2-cH_senaY$&pj@2 z810bQ_xJgIPpMp5dPeT>1^Z@Ujl{nK^an*Azy(SlR` z(3C4LFXgxC71x8c`zs2wv|>z833q!bZ{v~g|Li?WZ_*5X#`hNW!!KWm0TE$B)j#x` z4zLb$pPTcAaeA)Tua=L3MiL2q-N zijVcKU$+3G5rVC&7VP`Nv0s7hLb_)9oxX!L{2ajfCblQgJjMRWII(@zVL?gCUy6Gb zE<_n@mm>bNU5?b?xhHNHUl-nr#0XA5`NAiTKcB0L{17iCfp|C7;9VNg=j$ncUwO8k zqTh9Qy%aVy@W)`DfpwRkksj9f7Li}|vlTG@k*-itKUcQ?KTq^`Oy777eVuW=Z65CX zq(fExb?JWUQNur`{<8EO%e3Zg7{ulLmJhe8k`mgAW_r zZtwwvTMa&FaLM392AkioZJzKiY*0Tz7*hR{tjx)C*Jq)s_4D=qFkj^W`^6RCBGy9v zj3RH=Z(=)U9{pt-G#%UPllVS2{9`}olLGu>#F%Vu(Q@}{I^OFu0)(+&?>you>wAvJ zv&YE5wyrgq2@Q|M%3G-=Pf1sRvY>J<{ zQ~C@1uYxxz+PXnS%S~+knRqy2!_Oz_iRZ{7wQX53tRpxcqqD={T?VUM#dOy8L-rf; z`7Gd@xSv>+-)Fyu{5T-;hxv}--EZ(AgU1a%=yVu-z+lzuKK{mZ9I$drR^BTcv~PC* zna$@aq)zqIwn#6K?;Y2XUhV&0UZ`xF+MauN2prR~$=a9lg-Bk z59Gz#Z&Ki_y^aZ7-(E*8-xi6nZZ7!X4>C9>a7>@*+p5(Ya(5K;dV7U2m1EZb@Qtj$ z>$48SYkH&DZm{W%VynR_Kae+p%X?K`LM5kkHqiei+b>!INi6rQhVAw|A(-{|KugQ* zC_jfa_#mZD`OetwYM%G#0_=Vqmh;^wGe2Y)v+;FQ$5prE_?;>i*~pFqd!q7nzXa@F zYd;+?F<&vbv7O@UM4_s3O}aKijlwdw1^8{H||zK5B5Mw&%{>26q{(f|C?`3?8@lcNt9V)FX!s?lD-`Q^U?a zgOBL@$~K9yUTE+ZgO3@!$>5^~?=bkd!MhC3xxO&CMc{#*N3A^5zmHD}94bmLzRO~G z-eCC-7<{wA`wdq6D)ZB*eU*7+m$wHmDY&c~6=E>OMVc0sazMD$$jhpg?V zhq#}6Sjd-kBX7q(w4=+#FBbcZ55H;j`+E298ob8df7amp3|2n)dOG{d0TdPMjZKhC zAFrq{7U4bRs0-yMoA(QzWb?SaN*QMOKu<|S5ay$7-O21xThI3O*O(6K z`C7Zl`;psq@%q$vF}%S}kn-7YIN#38F3YL)TUVq1H(lF6|L0346{{*uKYgvh`$qPeS+-k6)~DHh#TC-Vap2ZglKYK8}9X z=-8p~*cXfr_2-5?pEEkP$orGg;o~8`b13QEUzgthV&6vzyGp`u^65)xr&yl5qJHA% ze3|Z##J=kh`C8hf9x3VHOCh(gGZ>ieAn~yiAf)FE%`Tu{>Nwhi`(-HK`JCPl8>(G` zH!P8C*gvRtO0auMdvOku{A^U-??&ahzHxiO*QLtl2U%a(gs)$PM>W0UP3(T~jYijyt*0g1*Qq>I zln+UY+a<+KLeKKqdSQa&4f8caFn@HmueDXmXSwW;9+!<@y-jmG$j=j^ z2f`k;v&(P1OkR}lXq7nhXu4#M*(sozA>65aa6fJRe#k#nI_}i;el9#&t@=HKRStX4 zQUUS%F_Lb5?)yNKZncYg{rg@fPdG;+_EM-C{fkxK*Qe8RaX+M{UuNxW^UV7FsGnB8 zj%)hz7URo%jW1iZUbug1O8McklDtTEo87qB{K;)O8chyv0s(J^AEMH({W&TzsB49 zH16)vcypJ;p{n)7ek_BPpF?dc4c7J=YP-f@ZI_|84uh2+Nn5+Y#*emEfg!gVn|}f8 zox)f5E4cnm>#x~!W)*hw&v#D8+awqLk9j|>qLuQv= zCmiv660-e(BO*ufck&hkU!(iB|KE1VQ}v*xPxk{Ju>7P#^&1N!J)cK<^8Lb^eLd_U zGv@m!v0@Aa-#f_Ks z!K*3hJ7AB|&pKJ-XYIh&gHY*EyUEtOsh1{^Kc9QI)^l&CzE^dl_7mO@84Ulf<;O#W zn9f$4@BGE9C~xhOuF(9lrV`SzzcD6Vr8j5&nf1EuwoI;EANaoM7(e?}QdB*|bPTZ{ zlad_!F?%9^xa%9r^}?U(SgHBdZjQ^@B;{CttT2`O14k&wRfAEOx67~Ig!UMh>SgzpkC_W$kVDQP^wa;s&K7jHz7}(@#2aubSvt;`#3N zz?06;RG-(|TRuMhx$5yTEvH<2erAv6Pt;t+c_9>lkgT+E_)4WKv*R4^mkh6_t3N-a zecZ$Pn$)xYypTS3ze{<(*$+*W5|u~B>AHgRd7jx1kW+^Gdi<8v zL))c}Kad56Wc4PsANE*#tt#pB&0F+&uXdU+O$&F3l3 z7w2Oy=w=`+F+e`)b$d%+<9;8jPp`?DzgKaCelY$#pzR(umIU8W@xwyT(8^s(*XA7> zuimEd?kyU3Z;}}P8?A48&PDm}_L9r{P*LqeoWGFtLq)X*u}{+St6dl>#y|5DCfm(E zoMZN3MdcWN94mjn;WPWt?75+$*@w1XF=Xdnun*kIGyAZz&0w_;v5&-HwG%@+e_d$h z?XdUr1RiSJEpe>xI4;C`S@iU%uvhvo^)&4*HX-%lE3c~`?|Yjr7e8Q(*Y*4RKFxLC zakHOvKZl=dn2G)M7{}ez{_=Xd{qlk&6kGdfSq&ewFv z`+C*?G@sM^wBcVcdrkFD(yEHj?Z>2bzBG`p*C(y# zD6Efh&!{T6r@xLhPs_J;G+$Sv-2B^5XwOb}JR%iJ_ZK{}OW^R{evO9@*!yjke!s!}3U3*=blS0eKSLN^Z|OQU-9zgv zU8g$nvjZnt!3U<6;ka{nOC&1$~)$ZNR|R?^+KOP(k9jYv#8pan0;7siR5 zJB3}X>2~XQmTcZ6aN(R63Bp)U?clg$i14oFBCkK%kNDGd7YVJ@qdfT>0K0j}euH)N0Fx?+yeiT1v z;rvMbI4jqQ{F5*E2fo<3vDLayEUy1LnMY|q#Xhk~QWn2o&vAPXpW?amX-MJ3&byKy zAH4$aqkhf#8SECJqtJA>(BXXX`$M^2xrKNiR($jab>S!X!7k+Uiakdq77CrpZ;rz~ zc*SymyLW23L*f@|RsL7&)9*uizdtLzw>6!2?NGg8eh~l8rTeMfP*wRz+LTW?4=QvgZ8~2J)jorDo}1}6)n7QLZ0}9KRo5H5 zU(2z5TIqh;B$QLE|wGDx0Ze<8A9%M zUCXs-FXJ!U@3v3TZaXY=WPY@(kD*i>3PPT8m@;SY)u2tdmzPggaizPYshb~lj zkK#=VhUXP356Mj?H%m1=&fzM3*x$>r7S&-5({+)GwiD~eoaE<9@}ttP^>aOeeCR&d zH%u%%7lV$5;PyniZna3u@3rr;Q7@K|F2?^-;kWWF7`}A<#LDZndrw2v(<$C8ot0zl z>w1CZwbqnZlKON$WA!;t@OPat{I&GA2!8F?z8@{)H!6#8I_>eZ% zf8815PYLyn<>~vx|AgwTFhFjoKSJcy?6BS@FcBdPsNAG-Wb10ZcF%~9tBvI7FHufD zryVO)4@iBobNBldZZK~;jC^KZ3k|f)T`wdi?@H~9Yq59Nh9GCNY+C9(Cn zbX|0FpQJD3bbc1wC+lK6a;=s(@ga+^(Kwl-``@Uie*^0Tem}Q=Z))OROaGw8VXu}4 z|FM)ialJmz>_+XEIG-%Nxd>6>1-ckwLbj-(r5Ob+S!>s*stUJ zu;NRKeG1$C(KEI;Q+rYU1tGO34=TQ$ARHmJHwU!5utw$Hzmpoqx~yHhG~bx^kEFZD zV3n_=+w9M=4oh$L=a}|8|GrBY({}OsbFllv65n4nru{kTHv4nT? z*{QGjB<<93DJQd2M--lcojRNPxO&j?oBmDrH$nj+P%a^YQhpQCW4+n%Z!-JzT{ZUU zJb9nlr|%Lx*?r0_%IDNR%_*GPr^h9KSS;CKpH3>gNAaHAK3%W$O>3WOJH_MP-{OEt z>Q8cggzC$9zewpg9ee0og1@BoI0N`wK~hZr*93p-8N*+y!T(2szx|BiuciO@1i$w4 zGhr{*(*K)+zw;TR|D%Fm_1ZH*|D%Gx=Opx-ztQ|MnLV%ix3^grg53_y&NJ^2yqVp( zP2mQ1=P>Aq?asGBPJ-V%W^x^DzVF}FuALvI_HZ;md=Pk3yH2+^)}0%V_2&_e>o=fq zgo!&XR`n%%YU``npC?ss7fsLmJpg|0*Uo=q-?Qo;JD2SKl=8Uh{jkCCS2X5$d;sOM z|CR8FdihDvK=X?5MvMJBF+=Y|1_au142{lz&;wX|?%VItPWfW<4*yB6~&XXW@$_#~XG zc#@SP25Ub^R_;>R@+HL`0>|U9QDSwyXIq6%3_KfM@ zkM)tb-96n!YLO;&EXnR(^V6e4!<#PsGdsjYX zu(mhlpIs9Dy^il}f9Es#`_HdHJ@y{g_A0BK#r!P+57S-MpdJOBOkjxh<~4w^ej?9t zp2zgmSH=SLME>-pji@Wb?C*tI6m~FTtDB$@{VIn!+cle$H&RN z{X%~jUsqR;9^>1OkS~+deknJu?>lk69rHPPo^0>bcyouu8UNY^uIFE?Jcpl7%Evi8 zgL@3_GFa<3RD7qwrjJd3#`>ZK^u+!8>vz>gg|A?0s6kKS*v^=Ci#y;F)szZlW?`*d85&!heq=&SgA)Cvsb ze!e2?RXtG1{hA;Ok3&EaeEq5ZywvmLeY`LEDD)%S@9CbG`l}mMUvhrM{(^s4S2j8} zX}g6`l5*L9t^@tC+;_5nZI#zkzKi}!q{DrBBEKg(H*^j0aj-)0@0ahnd7+ku=Y{;95z_w>miL&J=jFN_r00i>o*ADXGC6R%-QH*an~kEDFX1Qy zd9-oU&jS^jVH_g3|EAFNa)FtT?U2u{5ZKQfIo@QMw$DZ+qC^hax%*`Mp`SAY_FYOG zx6?t$3FjMo@t=ISnf?nE=k%P=Qrt7ma{YWu*r)m>mglP=&*T?_w|jbi$nJ~r^H=_z zdf%6a`_Y812cZoT*JIxg8d2R`IE8aV z-^A8Gw>QWy_5ijASw%Yj2j5$J^L?r2{nzl``!D+w=}-HU_4l;@r~ByEtNy6&kQnQ` z3Xkqmc;yz2uh#zP?Vntr4LJC)+7Z}Srgp^zAPOO$Q@>vM17^QH+A7b(;}Yc(6|Y=) z%=n15WvD+dWcT62reb&!|Ji_kPN)~>=^5N#?dO8h`>~Zg_>+~s@}po9Li%1H$n6}R zcObunHyGZll{F>t1S&|3X4`Q(KwM)~5 zON<{kD9nDx8fNEz^nR6O^LojjT%zeH4@{Syg8|Hdb3jU$p9Avqm>(|5`=Pd5#r{e2 z*X%nTYSVV~dq0!S9cnLiw`;t;RbuQHPmRD4J%=Ktme-#Vpr*0{aHE=~?ndW;#(6GwRLkW)Zn10kDD3(#J_j^;jqD%z z8B?U=dwM?oSA-*2UzGVm<|o$s2xhVm^#S4>T9V=80DcrzbdKJ=>?Vebd_j#wt?-wF{Jnm9n$geN_Hs)_N_8sYD$ma${ zQ&0}4j2AY)4I4_54(BOFj{Sas+Hzw1pW{8tz3Fo(cU}cqi8AbK>p)JMf`$Q1q4G`{ezdd}r`|aJYBF z^jiHoru6@)U+kd$>-xa^k&ROxF%Oj_Ol?pXztWCmF%?kHWMF#ie{Hrw%B{sx0#)-dKUM<89ueo;Wsqc#`%iMq3d1jceVGb zZ-?483w^PEsvVz2UyW+JxZN9{zxsbVGCQ{yn-M5dF+SJBfB6ZHYfs?M zC^R1zJ)YUU|1PliXX@AQAYVTBFY+AgN>YD}>oR^|o+$HaoI^2K=iRUm4Ayz~!1%`n zJ{|hM8quHnH&0-%e+lUu@$px|$9(R`XQV!j@K>XDO6M)OhnxX?lX7P=Kl#Lz`hHLH zW$pAg0>|w%F75Q!XQW=I(@u|1q5IEVFIc_xzLb3KkL&u4*s*T+JtXWBJK@1=z&G31 z<$BfaWXPS>SM3?MOOiH~&oHXa=Qxhl%qxHMx3YO=Z11l_7WV50ZlgRNkp4VWyj}ZeMb{CN;+W8Z z^OUx3@^OPl4E~hC;|70D>Au(K!8pGIKWqDk)4_99BbTeK$Q-2SMf)4s_b(QN!Rik` zlhT>))7xgS@*Da|VBg=#b1$rKEgjfjCiNyA2O>KBToLK{2KsUReB=2-PmGWE+IhX$ z9~W7DZWaFSl5*CfeM@-0(c(hWLa~q7?hIJ>5W3xOKTv(X^pC+dlhe_&1kU96XKGJ$ zo1E|YSA|zwKNvY8qTuf_N*<&nN$LAv;TJLZ*P?=gAr_?fOBO9ZepOn!A-5BoX zYwZu}56UI^AKy289CnAd-%#-m;cK~aNaCU5of2cek?_sW$I^cb)=lB>Jn)D8sHf(f ziJizy5j1aV9!bA~la z_)O@$|7p>=4W*!*wVNb95uJySf^@!+>DO$L^pqp!oC$sXF@5$OhLn$X{s-sYm5;V> z?}Jhb_;R!U@b8o3zBo-++$HhF59)ir=P%j4U*GROAhGKqzwftjHV8-X^*#Cv1V%r{ zKiTg^_$}LB&j|8;i^RU(THwHskje}4GavbLJ?iP}wY`4tkm(ioOEBG=UZv?pzJ~=J z$1kDR_pvkG>)rtUz4@@#XY(PAw;z-kc7~>}Xnyuf?(=m1`1(2VEC&yR?bqbGEa^@8 zoqj*|sN%Qtu2a@ifS2RXbl*o<`1Y*-F2v7uHTwDwug&Tkp3rizPfE%woHJW05X;}e zs6WT`_$dAJ<5vH@%9pt+zUg|f`;+5*OTfpuzMg9Q3{{n%#O?{j{737bp3~NHk_FyA zDp#R0qIBE&%0_y;8FG-yZ`3~Hs2AJg80%5d_6z$|PJLg(T$`s1ZMAlVxUszwljm38 z`w1yO*u7V8x$L;W`P~0j`d8cd-L2zY(q?wY1y+w0s#n~u2`l>LMY?ZvMUTOUbbMaX zWw6;XD>@DC)Nx`(hru=;r~6mcF3R?=>UfgvN40Tg#X`$}*vbQg5O6Nn@V6MO<9xQy zRqd8=RiC^M_ewNnT|(wJ!}^?j|5iKtr_Xnczts07B;or@ASY|_oA5@9dvn+07y8RS z<448nU9tLBl;7ANC-f%w9ngB1{fBh`8&8cNHm;`gJhy|){}U?OZf=*s52koG9~8Xt zysWl0hc+tbCs3ia{LIRk zPqqS&wX@*~Pnf)}k=Il9y-uDGpXw3cALe=>Zr@`K^Q%6me)Dh*eqg>Y{PzCu`;Ovt zP;2S^9^T)>hrnRwAJDkaRKFi=J?v)UdAjz|1(81G_y)D|RN~|6fc7W1Ba^mWKPNqy zze*hIS&^SA-$EvuF|P()l#fqh!~XQ^k-pBQ19gn=a5P_y@29>MzI^9LYCk%?mBTV0 zzRJ3_IqhZk1D+Ku)ZHVrf~NWh4)!I-D-N|8s&R(ndyxSwSIn2PfRbrzY)*B zYS&TU40)N3?qs{sxm)Rv`^!Q4OCr7sUxt+q%A>EN_5goO&jHQ{x7Me7E$Q(7wm|C_ z=VLpv-TwWbryWAn@1gE!9_X|GyZh^5O*oJyjhK%8Od1fI`z-BzC^VbR30z z#CoZ>VR>pF#pS(5%3G~??H8Lou`QL?~2-k>90n5 z>Njfkllnonx2XMdUru7?qa^zJ3i;UB|1qNDYjL6E%lwk_6nkP!Vej=kG1iqV zU%Nby>ml+zCTz`dADrk}<3q6dHTU7sYGyre`7!qqXurz(>0&_uJ6-i%@e|UIL)G+Q zo83D;YI-f>C^5HDO}r6r#biF=V%MfbFEyhU!my*Q(($1SSfVxS;{)-`04HB z=biF7ooB`Ji>yfBEcoK*B|P!(F~oe#nLq5?ze)eZxx(l2zOM*B+}uu~~ z5!m^JeQg4h4^#bm$E|)^KF)I(tn{H@3Y^Kews*aJo1U(0vHDFKo=pa;Tn+7hO6fwg zka5Jz829~Zy0((mW7x-wE|sfcFi_IjInngKh7Nl#uYspsVLQ)3zK^^Nd}AR9gm3K7 zatVWfQf?ua5JdZ^|24S1V0P6^_T8^HJL~E0yZ?t*DSfoB>g<-a%8#(FBy_SKJ*Y=4 z59=a%iS41+A)TM!InloRZsMczL&%F467T|rSE0Qc@4H_o{0lbzX8Z1^|4zrNqjJ3c z-QM+m;xpc7Usn2@PTG~^AN2;SQn%0E=HKZ)`?A^()9$lhqjKkX6Z<~HM#vL$4i)=F z-V(oue|L|-al74>ANAn?c@6V9oAm=?H4#%rsaiZ2oORjNhG>K z$_EvU^SO%h4|FkjzfAWfS^2)tul!!y&$UI%OZOe!r~8B4kDQ)+uzpFHVW_)H%iG?m zvF#Va_cj#veL}YWn56snm9N?UeQnQd|Gu_cwtrvw;`{gE$5Xzvnf+?}_}y+zcI*7j z^>SK&GKqB0bl<-Dr+hy_eDB{5=)<%hNAsZTpch##S>0&gKJ8rCC(=J-{W{Zq`y8LA z_?Zdsk!q!SmF+_jpuYL>mE6y?UdnU(g!VGm=kmG3!V&m&<$byiT-l-U4DNS%?In=M z>VC_wf&o9R_wApI@1t5@E&E>{=7UwE2Vx}m68N}@c1JZtzF&x`c!pABJgLxhoxnI(DRH@?`=SbVA7wmm1S{(Nv>D#3YVf|?@Lno$t$f7(I`Tc{*DJuU z`u#fH!r0V)Grt_iQLuQ5T=roez1&fK_#!|G5_r18VZn!(&pp12T+b6q+GYCZHnPmZLdB_~JT_ zp!VQ8J~*Cs9kdkfAzCTfitEe)aLJ= z$8g7+q@F?d-E0=WGJ7A8?VFFuHsgUGfp*NK>mLz@fsDr_XX7i$uYPy?DO_Cq*unh^ zd5``b%A@tK+`hs4CFDJgSMvAj_t@;@?+(Ai-UCz+yjZ{NGVO<4s{N45xmh>|Q_5BR z#fuC4A-Snr-k-1ikc-!G+}#7Tln6ynta3jXf8)9SgyyjDr1+D5Pa5y%atGs2-lzE6 zAn9y<7LZDhI}b_y#p?KzdfoatTNg~eIvzVuekS#Ag#Nk?U;BNf7R8^=Q^as4=&^k< z@h0uZT~Lts%U5Oaw_5Pm!JmUz$6w;>B|doH_g)@9Ocu*`yC2%dhfMF-`Wm;cQ^Y3S z&tv=7i4XD6IhG7Z>3r$;x&7^m&v>(Zk1yB$V0(e{b+zg~ln2&Gzi#pT$M zH!6CnN9>y2j~DCtpQQiw`#RAljV&A&dv4XZ(Dj+LpZ!VKej)@tL-k)@L+!6bhZ#hN zFnE*V@0qoyQu!A>LponkM(5iVPV1-N%5l@npko`;xy0{_z0$AiXcaodebTQ>=64Hy zHc7wE&Q*>#OTW&}o3?rHTK%ik5B!v@S8#sdCpaDkpO$)`MZS4n89x6(^pKOAPjNh? zQyjrh155FjLh`*hoFrkqQ1mSDUZ7XN`<)jJo=0!j^WBo0R&}q8aeMT zzC-tQZ~aD5akhR7H{9$K@C6%KiBp1 zrYbxS7m$qB>5dK1)qx)Z{oJAFmH6Xte+B&ZA~pFDl&%eN?H}R1nI#l=>qj0Idi(MX z`hfn(0(ipHh)*)*Q9qygs6980_35DcGxZrhi{wk=DZWy|c&3EOaUPi^f&NDV7q(6EJJLU+yCP&Gg%Y<*5v>kTuT$93Y_mVV8yQse`a=B%R$YGD<1N<8@c6pW3VLc@Q z9X`8+?3Ui2MC%GUKkau?y`%m|qw2#R^-FX-$?%`WlTY_G+8_H2xng#%Oc=~&0Dby* zQ@YshQ+izCr@`f2SXWY%IQXYu;r<}O?eAA>LAr+|o!@V>^p7LGhnH?|J(^!`52Yh~ zF#i4Wv-;)j#J@x7mmg9&D+!ze{cr0<)AfyALa!dxZ>m>(_%;xHzP|ish4ScL4TdwS zu%6<4sy7T?!}XvXJn+B3akP(0>sS3$q5d_Q`k$&$znyRE>p`p#34?32{OtmttrO`L zzJ~rdh0^)$&DQt#73(90=JNkj+C@?Li|M)&@xy(13Y`A0IK9pDSihL=WfD4zcn1Es zEYsT?C%6Lien|D&EmSByK7BS;fVVxkm($UFKGzek6nV9MrCB?0DD?lg=2g)DlNF9z z3JhQU^uMeRN^VlVzD4on$z9eCpo`|~0oaw)4xC(@9ngKchujVr-kg75qyC>Fct~0V z@5!<;jQ5TukVfKPq7j}jIFG})i395QtNj{I@Art_PZ~v@eYqM=|BoWRje8^?ov)^P ze}s0x+b7NTQt{-&VRisl`J{HBnH%cUpY4G2ceOn=*n^*6NPOgtTeCe-`K@FR{tf9p zzGQpg$#p+L2K)FUO6TE6^o3VXR!@AL+83K%xApH{xdkn^v4Xycc(z974H+@?2mWUw z?Bn*04A$o#5`FuyPhafovUTD3{sP!3-Om-}PT~S> zKULhnN9d{NX-1=j?sncL>cN9@`ap*si37fMs7LwOU$1s8_3>yNN$}7l>6cP^yh!Jp zBK~0e>0NuLN_yK@f_8t`+ZPXbUP?)<-9G+1>Am&0+`V7!o`RjyPTQY3=-z@I`d#p0 z_Y}~13j$}~dTCFOzz29~+XK%lyzq2tulkwUb`*QGAFTYilHe~;5qD^aedX|1Y@Ms| zUl_>zOR@KxTyIC~Hi55C_$$5N_9=ev?&sP3q{NqRkbKQ2GQi1P)I#`Ktn)fosGZUN zxb;s5s`6`r^AE+Zgbq3vRruBC6XwS=I6Kqr2docwGknj4A1|$uAD>faemplLhesMe zK0W7u5kHmOd3_bdUlEYH1>1o zk2myFJelvU+Hslb)jDqdj-D?7Qz3K9BNhznuLa&FSF}5o<6$ZkY!A zqjq2SE4S0S5IoV?(>UEw@EjNto^cs?Y=4O9|6{lwAD$HqkHIbc+@2G-qp>zmDfY|9 zBU+H+@pvxR|9&%nmvU{t7me?;ywLeJA~${C=a9~~k@zODzwUm!&1!#_i+<>67QRX5 zs-0b|cJ>OfvmJU~0qiC)YU2`SZ_S>jaQ}(x_2EXo^!tAPp0(3HeatV}cPjW!+7abW z6n(f=_=e`KqV`%hg=>w6h~ykEBc)m?bsxbe>)xBJHNe%^a7y9@7cKI*eywR;rt z{+QLBAHn+{fBp3r7+!pS$&Lr?QM$hz{f7Px(*NJOkwZVua^2R}DZU9^AL z!CSsxX&t|(b3Y|~U=@eR2TId;h09mI|4#Ug&ckOoXgr$J#XT|(P2&_UUpd~y&JM<# z(0?%Agg*x3Z9A9mx1af-7nqg#56H{FCXJJNf*gYG^ppAHd$bRP_8o9JbU&BC-#cF7 ztpX42_mlX1;mDp><<|KV|6na?TzMv`GjZ#QH?bA3$U1!TbG$$7HO+NAo0jSE=5Ym%%5Fb{PCS z*Nb&u`>32)=k4rXFwA=b6N#9OAQ>}{ViaE@03moJcLP2aZhYm3dfF8To@^IFFBG)f+hkCQ{o#pX|(J>hhDiGduy9Htls_qx9&$qG^l|!V?CHEO3gv^0iWpG#WdP^#;=K$fQRPAq>vd^k)UosL|N@0aym5Sk~6%=XYeQZ7Dos9pI3l)b+RyLfzHa$GewB=sR70iOc;^oelGYizr=Z!*bS`QA3bBPxA4IAnJ!E4FlQd5B(+a8?^qj zgHF!BjBmD$8vYbq%lZEttl%)m@5A7JSAUV-)4ChYKQDMb#XB3WU{5Y;*w6EaQNw=) zWR|)8@bJQ5t;;X*D>Q#Q^KaDfJF!y@zZZQ^aD#Kg;7*rM;+JT?%Xz*oYWQ{V60YYr z!8uyrOF3Vc%O~+An(vjta!&UjJiZb&?BkIb;0f=;;MFdl#20G5%lLfMsNoku6X*YB z0KJ2JGdN$T%O~;qn(xv8_C0F&8T$!Q!_V16Lq4(lf=AFr;xE*EZNXo0zMljabNJH$ z78LpLp6s=&PvXzhe3$S^P*KB=132wb!@sd-fqbhtUz^J(aoL~ONr&-~dq?T_1TWz5 zY3Zj?KD-Zui(Ed5pRDy=OFlgE{UAVB3H2aO>q}gEi9>UPPp%RB-0)r2i%36#)1Twg zOI#-SI~%U%lTV|DZv~4f9nxRO>CbZMC4Q`ye^t=I>AoIZr|A)=eVi`6#AV}sXTy~| zKN2;3HK1W8F8_I){xp|f;_Sw;oE^>SzQ}$a;6dE>If9N7|8IJW_P#1uKw;GIIrdPH z9&y^A>&ln-Z|N=4FAJ`sFlzY6;7Sg291nx3E8a}}*Cy-wJi|4rX68~3C-yYC0ja2@}1I$ApJ>ntn5r$S5E2F!&>X2R7z}_}^-} zck#$H(sgpWZ@F|5f4`>Nz$;*p?)jWf@Cdw0e6yx|hx98b-LahR%lsbcB)(D8JAyPer;$ zPWOaMC-FCHx_kMgIi!Q%5C$K0=_G!irn@J&nSLSNt2y0=Tsn#0t?9ahGd10dI9 zC-J{_aY7Z*`j>j$z|0Lv*PLZ2SIewe_4!uz2A zIF6%LQvP`yhZIWue2%YlaoG8gxktXQ;5f9S#9KICbn#O;j$HD6G{>)Y@dl1x>EbWp z_^VtT_SyQG;HzaEZ+G93GGwny%5UO0uq5&69KXcHPvAJTl6;Ri{xTQ8nB$Nd`HnB{ z9Br!q2995V&)iP~W^7#~;Clhb7veL2pTqHUUHo#6qgC>KJjY+`;)^+cwu@iKad3g8 zKaJzyB8iXXIJBL_QIp;440wRqkfDE%yDq7#HVq5s*7L2aX=~GCvqHAllT&j zLmNu`dX7(UakSJQCp?DZ&vD-uavX0ZKRDCQ(*V5CGi0~$ndu40Li*3*;4GW3M*5pM zPCw{D9D1Ou@qGs@j?nslKqqp-qzNI(l(?=zYCm)amWo`Jy=iD?Zr{=iNu0we_Hy< zw4agN?cVFT?{54fFZ+|z^$5rPh3h4z0zQy$HL(Vb1Mqvm_fTdWLiE>Y`3`2(2S06J zIp7bv8}a?qcw^^W%@(&by?y(!0D3zKEfBCYnvp* ze9sv9$#OD#A^;(LYC8M|Ja$g=0F(he?~uTS1H$e+&ZD0=pRKo<0;Sq5U$}kZHo0}4 zwmx;*LP_(41nyq;*+prPotKC6s_?Xvox@}6obE&6^jr%gMGxpv*1qD=?mhpYKis~e z#AYwj@=lSs!8HIQMvu_}bU%L)#aHlahX*GgJ@OvlVcx@^m%|que@W$PFY{s2xRXP` zy~CS_qw|~H`|j^*Be@(IzwqS=@@Mnh{(G#)^5qoc`Dn*Eb1=>&24*W_UVqud>N=+Ao8yYV`|-knC-cM+~B^jT}{T+`(MY$w@E!X?T{E9l&+kLfP z@B6jh)iSP?`-qHdM}6bV zQvvZGW~a<*7trHU(9_ne*@R|R381NdbDqR8U4=I`nJlrWbQM0^v9yy zSMp?r>r!8Lnf#rm_5G8KXXd_?NB^!K?OITV$CI_5ugN%QZfBlci@Ma)UB(|1w4SfZ z_-XF*`Negrr%)!>M`=A@k#X1DQ~B%aRL_bse)t1BbDg;_%XlsE!)bM@XIB{?{9Nn# z5|86XxgB}*%j>}h`^xC^1Fh$a!2&8j%6&S2Zk_5`Uq+u@TF*`yS0?>%Wu5BTRYsrB zYCT`z@#l#2!zp#DXF-{s{d=wF^D>T|+n&dWLOtj+zKlLwwVuz(_;>E_^B7O5M?Krh z^ufEeo~LBooa_b0Y3fnWKCfRy=L=~)pOx`;vKMF6sh$;O@^d%W6Xia_H=?@j7vqNcQ77Rk9zi$$d}ru8J}IE<$pOpu}Re|9>uzan*XjzpV`af7Ee| zr}E8pD!))BU;m-ye>RVC-+I8mudMtZYx$qaV;s32<*zT3-|uMo|CqV<@#Av!J+&N`>@~FC%TPQ2{zjF1Gw_Rm? z_N%&;yQ8e!AJ?ti@nw2)ciqYj%F6v}-OBAQn3lbISB&ciqY@l$Cp1-OAlq=11LBw{q8)m3wX7%55v7 z+vRmDcYPWE%6i{=`0I1Z^yEwH2Jh-Jevoz3^?-Lz8Qogy25(Si-%hGqxf{#yE9<7~ zf`>Bv$^w#ll-pLO*Z%~yUYGu6p^Sh3vu@??D3iCJ)UDj048Py2Te+*t_;**`%3V>$ zzn`mHxou_TezI=m24#5o+q#vzuT0)H)verZWpeS(x|O@JtlYQOt=u_fa&b@H%3WP1 z$7||V?)Wmgy{2yEww1~8b#*IuM;ZSvty{T!%JBPFbt|{K48IHOR_=~6{K|sGdf1^k zWpaVpzundSy0mTzg>+hc^#?S$Ex?#+PzHf9wsafpa=H`;fd%z0X*%rixlwq>q=Lly|?gZ zhI8p?T2I<9=Lp1GWgjk`=gaj*xkosE+#~Bv>7F}&@6PpTT&D3|9MXDNUN>#$x6!>X z`d#-kH;&i1tXrjX4>T_8yXjs!jc?$P=%wYY*Z6*ouhY2P&lC4_YkaqU7dYvjJ$`TJ zdC@(593KiFZ|cK+kgGUddj8j)j4<1$9QO*o?7r)nu#Ue3n%en4J8kGGPXqW&rL z333im!~5$A5AEDav~L_|L^?jdW-?NXJ}*1JM$ZceoMq?NOcnvg`?B+Eu(*VtO7&mP z^-EhTeSe*&U+^9JXVCdEtGW0xJyD=`qn%hkIMn$uFQtX3aes^O>DB^=h6g*x$m+B6 zPwdOd=ZtkU$~j-f zo*OxTN8>&zFV!m?zp+R7@@6}KuSfNO-urC&q0;@(S-pEtMLmPng^+vU?}ODdcFtOC zay|BGhCkAC7>3e2$3m_(pDQP;hc=5IibAo|@n+RWq2QbD;}bpHE9rbagpKFJl|K?a z^m}5^te%W=pOyCJKf__Fhjwt>hv!$6KMdrar;^g2?vv$oNpqXfqgU)m(!7M@MLnmh zqge!}*em?g(JTf$?%l)fPnz%2{ChQihsMQDCe5ofE_NbmUZL^vT0d4NQ~P?yXncXj zMPDb)^EAFo%b%lh!F$r&qH&=|(p=E^ZcQ)xDJw6rovYM*AE&>ucMsQpbMu27@0#=w zhmb2gVeoeTo;}AnzFYWVC_m{*!hh-~y^G5;J>~mT-zGVSz9qGAAeL^P=O@kL`kkND zBK0~yNzmlZHNw6mXv`=l{&stA^&mf~h3fIozx@@NnRu(}nO@N|c7G79uNM8%I)(9S z@@x0R#!gQNoz1_ZdyF*w3ZZY~9E~s2`2IfwA#qQe##{8e@~68;Px-Sk(C^)veu>6K zZ;?O5abM5ketO^Dt%u$vzX6;Ce81<#sQ)P~Pxvdh1KTQ=H&4qG{u_z@#gV{S_@W$E55f;@=P=d3;ureu zdnx4)c~_VCH*BZ1pW)L_{6gV-(>rz#7~ zwsBYwzi>s3_5VB9ze?+0!C~?U5saRsS?mMa&HOe=+L`)=&ttvN(fB85$Iusqo9Tqx#KA#Ub4Qte$)q-BG#XdZ_!5rWes0YAt)e%+p8|gYd^LyO zLl3W;kN%v>tNO1Uw{MVg`vksZ?h1`Bk$UDX)3~%hnY%#a!jH*ZaUA15@xzk2sEznv z?Qb$y9}Yj@kcY?ihaG(Y#H>m` z9A?|;kDq?)-S8vVbGp=zd>-S+#vS7=ZCdUs4Xs^PpTV&~zV{0Ll2Zwx^w_z^&R!}0 z-TwYDs&ChF^1wew5%vvqnZWY8OyF#g^f*TykG03w)5jovufZvBN4%Q`{U&%@8s*3c(-ZM(dOCNPvQ6jsDg55g|L2MD1Dp7La=*w&w!MkoD;x$Va=KE_ zLyE6;944o>@%y;9TjNVO-Zgc#yf?c%b(O{i|H;%98W;GJsj3%xr2Wa%1^Qj^kW5v* zp!fGCQ|IV+p>r~|MdO0+WNJaUZPf8#OL)(ftD&-z|Da$GgnWNyphmPpAFbotj?p=f>?7U)tZJ``5L6 z(MRdL!amOL%h`U?@4mjrxi#PyP!#<9rL)WR5Aa}ojPKX6Tnaq~%jGVCcZK2;v-DVOghzNho7xgI)qllf#Qx!i#Cy#}YiJ(OHN%;jr4dZk@9?h)l_ zaG0J{E`@J>xqN`-awezq`4n<*d}@3g1_e%6+Hxt=nfyed_tZ9i@BHSepd!&vhLQLb zzg39$@@pP<2mO6|znSRW6>sANHoln3t+X$dTft8%w}PisZiRnSxfMQ07==i{Ce zm0RJTRBi?De!GT~+gDbS+v@~RklTNM7wlk94k@*a5Szrq?F7aek-Q zCaYd6@#~uO+JBNOk*wUIbFp7k)}6FVnc-DVe-LtQ}o>Ag2qMu6P?F2e)IVe3F%%;ew@Fe<0-M;<2*B0{hpL3 z3E%1XKTZ*n@ifd+mW}_DE`@#|Gk*a6L7Xoa&*0=ie5QoSM3EDW`{P$~hQ8N(wje)v z=v;gb5kFk>wC|&Kw(}^kv~LPQ;Exx6(rX{!s&$@rAK{^v@wofRgp*u|UGCj4_Mn*% zN>8=*3xnu6L-5;9_uk+!IDINN;nxMcnE7pr=*`}O=#?t`M(1BLT{?49^_;mg_}-UtaJ^7Um`o5n|7L>XLp^Rv+{a5Pn(Lz%yt<3meWPakMCjdagIm1 zYvjCsD!+l=pnPZyn$PF&mGJbuGXCgybVI(BKelpy%ws`MN4ceP?lYASy&MLjR{)R1 z`!xOKdLG_&a;`k3Co!b-AK>qm;CV|KAIW+n}(Q;P?P4p|ub;z9a zk8~1$gQmNiPvAwmlR4d6_&w4|{4S1HYX5D29*S?A|T=)GlhZgg~>PUWR^1~*mCKekLiOmz7n-&y!Wwvv_0c}p1_V_i8X zpd4oxWj$9V{&-_qe#6fK%1!xu)L+v3KEoh?0Pn$fCs8<1M2zkOBK#F7^v8MNN5OB} zLGQsgmk|Aud%?XF-VQ2K=&j@9xZ>aWr#+mE%ZERlG!~?Os*ls_x?`UI_xAbNdSkrb zy&IZRo=WRQ&m}l*T>#b(q3Gn!7Op3`Q`+z2ExV4?{F4jVFWM{l+E~3@WWlQon0XMZYV#UD_E2-{E@v@~io^+b9dlf3C_`6UDRD{f0l1qDcFJ=P-cgm-_vSi0}tEsM!Zb-f!5#aCPPySYLPM zjukn8Fwp~lLPFzjSYhI0`VM-Bd}=8C#$(j)csad8z8uHxeleu?^>dWFnC)?tdl}nd zq!)XE+)}>8ML%P_Ui_Jh*q=duLUEbDD|{||13cle{S7I9DxclCliNL*|980e!}0$X zmMiH$`ux&Q?|pgRL2=M$?^}97y=K89IL6&4K=si-ii2C^ zJG7X)Pk=s(Um&{8=s^7^mmYj&{A2ZXGz)%AztXr7!)thOdWAz!|APG@OQV~6wXbi-aX2P|M6b3^HuL97JHiBODuBY!;f-oycm4( z|4?49j-&L6eA&8o$hGJRc*i77!p2hEicT#z7yiNI}Zx7Q2_eB8ykZ)C^@=jHHYrB$D zrF^^RIPUG|d~wf4$v?zA{0W4Qk1S+i~7(?kzF96T1xAlH!*q5?> zE>lDy;COVHk-1qV-A~xB1cJ)Mec8HMkamvsJAqRY3`Et9q`w4CL zN3}gmv^{Ooo*MM~8Y(Z<@1ht@zI{9JFzIab+sr;EtqZuG>iT`2z*B>M&+^F|HbB2C zpXmOWxNkR?m+JS$((YmPyW&IV6^Fv_GS(Bd)8jIx$Gu9AH!3~4IXs;D`&@!!DE++dzfcW!-{*r#gi>*C(p=`wSKbeYCeI$;4F6Da|7%|Nqc7FX6 zsibK19L38E6fd$)sn{d;Gj}w8gYi)8`7VbYjk|=d>TlWoOE>oH=l3`3JxwOBNn?wq z7kgp*M*Q|><$W^ybAmTok0AL6$vb8PhWF?EdJL~$86jT3LwFhqUcb(Gt=-T2GNm^^ zFYfE-_L@H&_X!^+^EW6Slt0yfkNfuV`{E{{Q^!SJjF;jjp;O02t2rKTn#bvGzNk&( zqOX&SmT0_9>b+=z#+PV(p2nAHT=*s4v`XXRpvRk5XuP25S8H74!Pc#rJ&reRWbAT@zv?;(FA~4&#!Wk=oXtBV-_(ur z{nQPb{yq+GzUV=TpWV+P^dX+qKa%}-c8{8^vuLM&5+2i^zI}X<=$VeM$-c)*>9&%d zG&>5rNn)SQ%b&-^)BSQ|_y?9N0yLYKH#ocI%QzeA#}kdZK*NQcJ{q-%`%%6e9O>g( zZza5-ec&9l3m5>Nt|z><^KBsL&r#zDDGO7OkTqbI&YLk+U4B93MK z+3p(c>Pwr@FX|S)?p-H*of)@5z4R}z@uiTlD0swse>@5-W9e)h%H}l=$2im}+@AH? z9?@^v{hu}tW%_X>a(Hr?9LoHX(Z!e7c^=(tom1&WgdBS8p2@8I4Pfw*9=wO#CW}N) zyOxVQM&a}M`~M`ln?`u3#Mi&0E?7Hr75HZnx9f25$DRWCeQ5qj=U2oY%%t;KFb-RZ z&flkYq9uU zOcx>=JKgUoy9?kC@iXlFj*wTsr1Y<)zFPI~Te-g4 z^sk*uJ|&l7>AJg75ZHdtu*xLj$8l?dL``??s;iJO65C{@AK~y|#?6Pv?RS z-@cxEmq!m9->~u7kZAJ9(7 z(I9zLIjm*AJSyW?=_echeEE8Thu?#rFCWeDqFg*t?jj9sJXG~9eMh^(Km;?&Eo47G z$}Qq~@Bc}D$9TdU@R{}Ze?qFEJ($hye>Uvfx4Hi6_U%6l2WQ`EwKqGaL7r-}H|EEO zyc&Y=N&Ep8^8I~sWjw!y(HfZFZ+7Z%_;s7PT|@hI=J$tz&Oe_e@FuMy=f&w7Z`{jr z-$~~gfKr|LF(N+@4tgTKEl}Dm@)Gg;PP%0m>qa8F9gR#E<3-ky$U2mWz5{;|m1lTE z`KHhC9eyUh!%~5NF(TmB3s79}k5uv<<+$|%^c`P9E?vH(97iwu4!F7+|G@2w*N8pD z{qFRM=3nub@&Rai;#fj|eF*$nw-2jBzQfO0e}>ct)I?Se6?YWH$K5FDrmd1Nxlig% z9@X+EO1P97C-^&o@jiv(3$6#m@(f@RI6Zezqfx>XLZ1J9CB^5_`%BJ4DoRKBk!~r$ zfd*T@3+eFw676rfam9u7k{*yl65S7z^0n|yJVD#jxS#O~y5Y^hy__wW zy_R0k1HAJ4UU?6{1pZAWeBR*U6LN=qv+ve&C^$I0+PWn<@2M)?b$k@?!4s+k-(>`! z(RE<0v}amTLfg-0^nHTxUB(v_2mHVj{S3?xTuP*7`iEcSb2SFh-{@-er~GB~r#RE! z_(btGuu$L%gHJPk+56#shp~{0RI+ zKY9G?s4{pdLXYn^L*7dj{ATDS^P9VlK)?BC)D?d=&u{uJ*AMO%yl4H8-%d;EZ*-}r z-~3rxxPLhP=8toI2kAGT#b^qOGbFTix=E|r;ZbUbM`i5rC{iNy0Ds`;kas_jy{7Zj zSdWaVVu$HFi2#jjSFywNo$WAvhu%f`hsF*cV10Bjc9_JnqTP5OsT{ytrf(^JaQ5Qp zy4vB8dtU?}5eM`d z#^o1##qW0WQZlU=l+NVO?i>L0bHN{WK6;n#|FwPv>c{hJ>;pb|7`=YBhX=z`EqcAy z@rf}b(6iQmGk?|2u}E~?WO2IS@!)F`OgSuPbNFLUDM4W=O-=q4Ln&tbo1DekIGgbRNi=<^5vQ zuh?f$pe(MRa-ZUlh{^9O=-+R6?VfGvDO)A`QhU3tU-AtGAnuiUJHUAg!FMole)^EY z`Dupp31L6>r_q%J-{C{NN#Kt!SVl4Fr@~%yg#N@^gdVdm5CM#PH2s7noFvh6)sp2h zAKS59_!#B0UA$LH^81zizE|D@Z`JtrT^?T04?w=*`jyq_n6+n9GJI=%xRUBYzwAN^ z;j!5~=TfR1dL!N}?Tn5xK6p3d*YV{WIT{RHL5b0oo`luhvB6+uD#y)BdOq;{F`rk z?FL^{!)yFonz)VQw%-?W3rx4?@mKT?LhHx0kJk6-?9fw{p4zVl9ZtK7q^5 zC78BW;tqaYXO-L{?@fPa+n?1-5#b&D?$)Du{g98+dw>2L>uch^jqK9{&)<9x#dV#H zUoH})<@Pc_hOgqpk8#{D7vlhaxxbW`S<$CaLr#F7NSa0E%`!a@iC&OR8 z-1URX-IFPId#2nE(f$RS@2y_05YX@tAJ6O(6esTI`h2+iQNFJ02A=0o`JgB06mRMm z_%GmW0p^eJ!t`uJhZ=J_UGF}yNYdRwb^$DB=i9HO^5#+e66FN^S?{U7uP z@jhvle%3gZ>uI7sDV^|fVtU)`qRLOarJM2GK;{3C=;6~9_8j9qz_YzK{ATe5_!-Y< zP-1$r-@`!8e^2g|`l5#AT(9f@uabPTK`?rtX9^UW{F6q@5Oz)IGwFyi2HVM+~7BUv+;Vmr%=8tT=kzxl z5#sNVT<`}_>aXvp&$#D)!RtY+@2IvO;d0QCr>5t35Z5dG6SV~ z`=->MABy!ItsXwX2dLSN=N&X&O@4KK2bDub58uCfJ6cVCmElY0;o>GzIP^rhqq!W@ zvrj0#1}@^y>~Fu2+LNpl{0(0B(aH(YzY@7`;dtCMg+sb;QRMX@DG%iXZom9lRKC^k z>LDG1hxw91*KY&A(*c(*G#Z^vH!MgkH3dI!XKp+jrS2@&!22 z;(=B4haT5YqL=)>SKdQUvRvIGap>`%(-K5m7vtz}{WZnYxceo&*(cZTN9Fy&wh#D1 z)BJTeAV3s8!uD+7JSpGZ3ph*SL#;FalcSmzgqIzRYhq!7~i#fU2cKC<(W zU!x<|fH!hK4ix*-c|_nfHb3Q5fz#F>0q>wgV(|CK_Xa8-{=0wQz~$J#sq&tl1JlA8 z2G3^}_&wk}T>CN}Bs>kZ|N8wNehh#0oOg_gAl47D{j;^Mi_YTD?y*cJsr>8xIvw|d zT4EOwhQaSeFBttM;VtotN5|bnNASf>%zwK%eMINb5@~{3`0x4}`R{K${1*FVA2ayq zVEGSl`}}tl^Pj#~ji_Hesw-?!btFR-&2|YHYy&Z-&Z^TiG4{Lbsn@w@R>Aj5dO;WlTVk~#G<7hqs!M0fUnYh>~c?S zx{rN_z~}a{Z{v7L_px_1ZrASyPq)Smo^>40^0yDqbIag)vK*dCFJt^UcqT33xXB;g z@1B82{OVZoVfRlJa!EF1dmRW9W%D3tp2e3K|!@y8Sd6`R-UO z>p?o^3V)aS6fc_uUrF;)E+?6EiG+*K<*;imEHw0xv?G~xEyqiGu20vbl^h5E;i+Z4 zr|FM>{T=L=(OJ&vs};hO*Zm^XOu9tHoY#t5ILxGZk{8a@A{c1u768NZ&$4l4g$5J|8PM?#<+*V-mb|*d5W=9g{@C8UNdO zh}~0|s2`Qg75}PhQi1b#EuJo6a}$RqCtd1Sg*3W{4|spL$G=7Tf zFZReeydBPO5PqloZ1{Ug?RJ-*D`e-}*}9N;i`bK);Q07@^m_~rJ8w<+EYb7UoV{&a zBY5dy_Th6Wv+bJm4k}N_>tZ`E#g%VzDtbNf?sWl2o4!tT|E=viv-)G*|5?p$S$@-F z)?cynpp%P5za;bbaXajO`xA6;i{#vsDW`1GPynw%V=y~47UgcBs-<+SQcKmj=<8#%HH>(}* z75+_{)sCxu>S|UyzIX-KlT2F1q3y>{CJDgq{9v>Q?4$`09l$ai0Ppl*ULpj6s%WkI%W1atq zd)F%;fx95j!f&V-Br^H5{)~<1Mfv+VUzA(N;Vh~bl#TND3O$Kmtv#!$sbO%Byr)88 zfd{o`HNB+AZ_kDr+jAASX9Jh-=EbUEE~gfMY6aPt z)Src~tdt9?mCxruyS0+z{gvU+-Px@ln>l3WE;L7u$Ktx_>afP4E(5 zD&atzgiu$2EK$8RupoWUdaps@rr81{sRYmLGPq^jknZDQd_#Y--fNR`k_#ooc@jh# zcg}>JXI9)S{g7lX8D)G|J=Jl=F&ytuJ7wp)Ce73MeW`aR*VolNi{pu&dzVaV;W*&N zV|-%k3h@4L=_gz*{A})n+fTAPR6po=kFSi*waD|v8s+(4iKKQOuF13Qw;oA-wf4Kd z$@Oh#zKGSXW&0mh`(45|70+|Ae%Duj3D_c`!4khO)uE}9r4yG{kXeDE}$nnsUK&4TBPTM$L?I&L5k#o1stDA>$Z^6_OB$5 z1(MG0Em?)sbT1~Ux#<+zerz9K_puz#47zOSNVG z7W7ZtEBp(-dL^Yx^-mMm7xxNYicQ1>^tf|jn>b4GT?}X3JBPz!leDv=@eA@^)7g2k z#U6Rz(J1Y+el6XnE9tlFm2mSO344UT11qGytEb30>^@yLP&-VI+Wr%?=bzt1?>i-5 zyixce?ic=W_v$F$K%VFy>o4SpHy5~m+pioOTsrP$b}GsXVr`vV#JdCh`)`F&FrSO^ z0oSqgJAQmTm+$Uh((#}$C`!9~rQKGprH{9ak?&gr2^G$Gqv)ezpV*0x`8V_TVqZ6h z9rIU7`o7g1Ci9nZSn6BDVV9nR-f_Diq}ZqVH%Y$a3hggGk{S1%EBsyRTOs9dl5!L6 zmnM@I0G&aycm{`EbG83?ZyU$so+$#4_8ZMV13mDB!2IkL$TVMaYo&0k= zfGca~b`gnFJ6GL5|2c`a>2I^c>9~CdmtW04FIDi*fuc(OIf=u8ME&!2Ud>Y(?oX7# zJ=i~|W9bf*+Jq3ke-4hebKuQJuk}HWu525I4a5q zywfOj>%DBf7PX(>>-sgnowLzS%8Yhe{@Ip~-t+p&VcLs)sNY|&g?9gMKCfcmfBNgm z^xRUnp6pn@mlk-*+RLBQyVPEaUr{L?@SfUBk>6Oy!NcH8!Y<9XdFNF;4ZAm47(FiW z=fL<2Al|DmMm7kUdN*b zpF=AC4%&6N?9>3&HPkrHzmQ%vd>X!Mu@mSgpr1B(+W8`h$0C+o9{34wDY$F)nPWMDfA8yl`hfe>9$H9) z()vISfETQP+wPrv2)_I^eK7unzM-sv?W?qN31O!|(Lr>`z!%Xz1U!}C+1OML4^Rkr zc4y$(`cAg4sFgc+c(Bag2d2k`D5=o$9mwCfG;RmVvLG zRKM*HGkal z?X>kK)6{P`rzp6$b`3nN`8y;;J&)c`<0>w{ydP(N$K8X|pF}Fa&dW+3m3p)Co0U(i zKRf<2lg^2{i>ipPQ}}fs_0a6jqi2MD7axJ2y0<|wrXG2sl)!2J@gB=wG>qp{*=y8hQ9`JP<7 zpJ75f-hg~k4c~)}6t)k~@|jg>=~3RDR43{IC)@f*Td$DZEBS_k zZviFo;k%OJmEg;!yKNZwkRI^epzxuk!@+0kx(6Po#Pl?f@b7|sEJ_^hoi&v<-^|~M0qCjp{el@OeGM-t7yI6f?ub9~ZwC(e@egO>AIii}BtEzF;6FSar%Sk$ z_zeoEqedp?r{IxM%( zs&tDWrmGbL-Q^47wujYz<-HyuL@uaOFFL8<<*Dr0KdJ|Bu789C$Q6~$=7Gl zd!YMRLIm*fJo=vcA%Z9KV{AQXymdF*!*d>z_J+YVl#B8eIS8EJ@-~U1{Ew1MkJ}(| zvuB}le3ZL}B{IqtS#p6t!0GSvhKFKuYxo`tf8ZC}mx1!Y7e0Ofxy@Tw!YA-&=|i54 zP3h*-349Xoh_o3hdznQ;KOFO_X1_#<9cvy()h>r>!+Iro%M4c*nY?Pi5AoI=Tu^ zW`FE_Sm)P!e2=p2d`^?AFwpxpRgQgrf@N~&I8^u!iS*kGIkEPdU8o0NfTDgq)%apt z6~4G@NWR!6`0U><_*^T#l;P9#mHEZcA3r38p7I$1N6$FrGuQ9GN8Tg-DbP3fN!;f3 z?YxvIpJ)9I{ulX0>%?w|+?U4ME(J)lS2{1ptx4zQSLcxSF-)CO5*^( zL_4dD1DIdXb-I+B?RSO28T`J(rB7@h#f?&*^=}OC@aNI~ zt|s{oUPs*U9j`TgB>g8h4yp5hwrc-~E7F+#Po=hMi+&>tg)$y=176kD9~&GU~T=kj6KAL=W2Y3vxK(9)SbrI^c2rsUD8pFgK_?t!fKyO>eXXBi{e*riF7t*2pn`V++DIFcYdWF9aCw{&O{Paruu09o1F6VFH z1@Nu_K6(WoSv(m3KNEZ`A$$NopipG^{VT>D;UBCcR^NrHx*p-9I{odyrCbpjvkG5xDxj~8%#W(O+SS%wi zAbe!)ZZultc_r!AGW$bz0-R|4elY&fk_z>~uCe_Yt@g*pVGg7H*~a|Z&Ga3K{h42Z z9;y8iy`J*V{tW-@)40gD>rXbZ`XPURk9_Z0!=c;XPvcix=ReJK00nCcyDf6n59;vOkCxpTbW>!vA!zk4(N#EOf9=%_8@*(>8Aa{_+kD`-$ifPI78eg`IGs(rJO#=pUmH- z@g*E4^LJ`o@+b3maJ-}SNe=B?DQ6edAMy1>wf^nbX=9tMPs2D19< z^ud|FJ)OsJW&5{gCkOX)NrBJ$ezh>y`EnWna62pE}ytn+P9=)4pC+p}r%* zzCOj{o!w0Dk=WN)RG>#{U&m+oXMaZS_G$dtwy#qdj*-~c8IYqY{X4U#^%#!@zYMmg zbO~{e7AiE=Ws?vDu zKGIFlPw1x)ZwLS9jK|Jrd0)bK8;O0|HOjY7lE0q%c>DCh`q=tihtqyfVtXX*8)`iE z!@$QO9FKj3@ZtKyN6>ieUr1!q@oMqge1FyY!w&#Ib+p&FR^X3AIUajMh5C+!@z}2c z|Ju(SiM?J{fgY*77Qa1}vm@1BOTT6$_IfttsEWOYet({)=j&;|ucvwk+wWGfU&GC( zR+&fj<;=!scW1_D8|q}AKR4s>+UFnB{n#V1&wrw+*Z+<7c`?iP$nEp@^Qm4q6!WD| z(b!kEzw~U_=jmnk2cr??<0WQ)J_&prLi^lH_&5^n^U-DascxSi0e( zw^XR_NU+cULPL}XW1p|DK#%_m_W5kcQI5s9;(X~mPtVuWKCh;F4~Knj@zz_xUL6lR zcZ;+a^QYvNm5ukdQGe6cbJ)0IrTNpZPd~i&`9J<^WcGQCN4Nh?{pZVAzDI7K_Y#kr zUN{u?c~{}cu+Q^>pBmOPeIEEYg!cKvgpVW9K2IvcPj&m;3;fj4KEJsFe;i8t{5KWq zI}+^kPiPF#way?SGSfzJ}#{B(`U>>; zzhIv)g&YlGpWA5twzJQ6J_OCZ;<5W?P5;kcBn4S{ODT#s?KwHe&Gvr{=sx%-G!IX1zm}f2nDu+?dp4h2 zFGpkNcv}@H@37kaW7f`6N${JlQ;~b8OC=gOrKdgjb1vWTSGomI)BF5S z`F%&Dtj`_j=huAB{@WqHy&9)to8TFUETu+w|yJiM(Yd;m}D2?T3T7<`@c z+4;n!lB`#=bF-q{3z)yc;O{tHsq_M_Af@l0^!*%u-=6z#DUaHNr*wt5LaX8Uux?A-iE1Rs9A^E35sr*csqEFI`_9F=EsVfV-zzT0#E#O*7U z49~`2ir<{@7w`yGlAZ&ypYx^XfQTJR&jH!1-zgJ4wok&BBetI&AMGKy&94F6i>VC* zU6McLtIr6$6JE_9o}j;A31?3wxjXNul78GoX;9u~3Vr?9ozai4k5c`ZwtH8m-8(fd z^6K^%Dt}el-`;|DdhG_i(B2kmZ(N$kElBLX4W*0Qr&wyy@2ZbW1&wcKIDGuFo~lsK zb5YNl1)Q%`TEbzf_h%2I_f3!8NPVbBUNDf->U!?GX%CN7d_b=x7V7>n` zd7st$J^Y&W*Q+!5hu-()ub*6vQmp(%)e^db+3q}|0vA*&y@tamH(mKJukT;0?}bjr zw^{ve_s*0`(!Tbb=*v>c+GTR7?NPn&>-E2)no_;qFMR0q`bLc_U)HeyH!F|pl`p?V zO|y1{!MC_v+c#tPXW6;fVIcBQDhVFib7sF@$9QSa{ebhAN~<;gJt>cn3<}4$ir|&O5E}F+c_Qv zlCD&`TkAn9z^8H!WvO%z$J=wFAAv_arCZ*>VU$0S!<4V39OLUW|6Z=IRFZt{xu0+x zdijl1LaLt*jb2XX@A(S=wSIlFd^g9Tw;m$?h&M~z{OGt((i`7c`sCtWoX^UuWUs+@ zzJ6rCtb)CMA<3z42iF6>TL2~TEAffh>E}~Ax9_ZRFV`RI{v;Z2(D*#YC!Ketaq%Y- z-M3`tR=E9Wdj3b!IG*#_IU;ucN4mefz~6m1+Xz0teb7ffyi+pmf&}~N_tJSHNWXyI z1OF4beS-gF(mHyJ_9~tyb!%Mc(J^Ta$GaYp4o`CL5{?^RhQTEaFZTD%fAjCaTEX8O z2)5dJ<#>PM$KLo$yubF!vmQ!x{}kST_sdT&#`~}Rd;CE=2OIB4|KRseNB@G^Gw2W%dZK)e z z6uX_mKZgsb1pgO3_)~b~9OD$8KQbLc+I5S9(sUYkaQ|M@{YKIee()H6;tAj$8W)7_|6N^VtJtN(PP8;+k0`b71T8coluXDN6;@h zUEqk1M`;At91iH5ba|h`t?3RS+}kp6pXI?Fk1sG_hZCNi8F*&;@JtYR%-=P;hd3Sw z=XAx}3<*Im-0y@mOz-o^V9*nvQs5AD#bfdn9R(^$9AVe#61Q^&u}%pk8@-Sp9Axrt zeu16amBOWbsBpF0x%Zx&p!-zZQ_#_-%5A!nIJsLj~8fg&#Mrs_p;3FfVW+(YKay>lRv1YkF-Y~n;FL@am9C=@0ms7hWe7n#6LdRacmpM1-zs-Yoh0`sP2QI zr=RcH9MAsrZ)+RR{s&GcdcT(O?7!pmLRjmE9jftclZT{rhxjkkiFow*;~2Zh9@sp9 zorel}!BdG}UsuMjySdz|{7Ps6KboHge)xdT7yY|9e{xedhtU{P0`%B8vB?key_xV9 z_enbpiW>@db`2UE;?j_YeZ; zvHJt<9tU^dt+?Ysu}A#cj^j_`^ras0O}dU3xL{Agc}c721H(tG_e;Va<2$BffCp=* z-Jd#pp;R<*Iu{?Kn_66zOy<6sYinuVp;(NSR+Sfh`v6PR;P39<#0|}qH@n5xD z={dz48IJf4rE`yrqg*}lef-|nGkf57-nmZRFO~9>o7PKwvBZJ*21++@y~N|k_4{oa z-y->Ay|3K(Eesywa*|eQ&%h&+e%xFMOGObtn^!9pMQ{^6Z=(_m9|6qFUu!!pYZJyR4ai> z^Z)ou@bF)1$I)8O#gcBILq5RYN4t{w!asJdW1{E0+4*mFevav>ajJJP@3sv2rx@P} zzLF^gu3(%Tqs4mcTB>L%=`&ikc_6DFOm7*!?LOhFCyG5E#J|f0U*Lz2QpYdeEOCR+ z_%W;hjb8@{k9bUfbX_j;WqQ2p1kn$s=etzz#XZ`-6AGN)=$o7%?N8nybV_a&#z<6t zvihFRZ)Z92`Dq7bF?|QSj~bHGwVWodF75x$(E3hSyla2c`jK}3pyiLJOa4Lq#5$E@ z7s zqWm%Jao`?Sa7Y-)yeZ;@I{pq4hk?wSB0aGly_az;$RFw(cpLqp2Xe50LK{Cry{B;e zIQlDceHF(=F!5c=7e5K*LFM~?J?1U^@|RIORy{b5)+FFDc}0Fa(P%1|9@9(KzXxAj zP5LGZu?)mWj4H#Rhu@4Va5C0^c+nwZ!1o3KPf6>3uE*{-oYo}i<41(Q!SDDr zTm2)u54SV_LZ$all-^@XC}n}hp!*@Qv2*X%0>OaUk-X=qu|5tm-698{Z--a z+sE)vn?Z@_F}P=+E(*@{m7T+!6eS(x9_5lo0^aVxkO<|mB1xpt`BB{yaGN%0+TXyJ@FzrIp?>>O9)H?-^1s9)=Kbky>awE~B; zi&g7gzzO3==Zv`i57(jobJnWf=uvocx<2$eiTmRQ8;7XR`gwl(9}|m@yI0Dw@f5c& zUh!e)n`iOY^^n3t;1NiH(arqxfmpsrV}2bJ=%Y|MQXZh5p zE9wDV@A2Ac^Nz-!rXNPar!mT_qCYxT2)vN@q4k~cr}5wH<8!RZ9NwCwoUHz+u0M_6 zk=8vXY|U*(5!MQLYA z{cuO$Ch1RAY6r?eJC=Cu2!mg-UN*Q7hORFig0AMLJN-k-4sc}YeDHXATix(7v(9*V z?l5?P#yM!btQGnLkHDw#SIRG|E8|7|$&v6&zRq~rPZOop^Z@t;cIVLH<>ht5%a70w zXU|oRVC?BJc^Zj+{FaZG3U(ZRkKrYGYzND&(=)_OtT&xK5eM1nsUm|#_l!$ue3G>% z?X(HMKuL^0rfI&oSL%yr!3(GF)0c2KGuK<$PY^X7_;v-Tf&SS}?X-2V<~M|a7%J;0 z+x=~W^jq=&al5nn&95h?^?U&MR6K^k4@J+hwHTRy)$7wm>FxWyz`M~UtJmVbom_9M z{m@v)593YRZ?Jx`jt3;xFYc56U#$Jp%MBjWx98|ShA{X5 z!yEVOIK*0x2Il|Sx@WZW3bO6vZkO*?{2Kk#xr{U~l zH0FW>1>np4aHYp!J5|{auVkmb?X@SQTXKQPLG3zd{&@|GqkYH2^UraIn14Qja|RV( z29MD(%Ri2O#H5wzXMA(;bUe21bbL=Obkz1|`7!HnowGK_bPI!Xg?<@*QfZvw+te4V zG|mA0nLappeEsAv1uCbWe1As;d}Z~J^+)}2$koV~8Ak|%rGEyZ2Icq0-)=-c=db@) z#q@Shy2+`pUyGFA`K_wAjeo=7Wh}SZ`iClS>5%2!U%5QBZ~pkwE6^_I=YCT16@d*I z9|b4DKD?U-G!fG9?txhSyJVplfLQ0V6J4(s>wI>y5Za&g$8-*8U7duW3(Dq-4}r^#}?_XC5r^d!sWUXX#!5=XlMufdmGEcP&&zn$@A^QVd4 zH);1N#h2;*BCXw=F1}3aNm|!%Jj%VCD~Nly$@f`OALiMCGLzGB6Xm__SGW5*Z9d-J zpRD(YVqS1J<{9*!(lB^27tlTit-yHrSsca>w{YmsV-)BO+WQ#k1B?@5T@38t9D2W! z{>S$_G;9xk$8eX5P4ou)qm&=izExijY;au6`D}g`^CMKXn-5K9@aMqpSBYoftE>+O zAL2I!cg;T2%DWJ+0)IWQl((MKqJISlfggl+-(=Fdj=zV2`kxv2ZQi&&-;Cme0i_4Z zFMRw7t^Lvh}Eg;B3|YUZeI0RiB?USr~Re{Wk2=0N=#@ z`?)>lABKVYZ#~LqI^XT)Yc~l$#+!vtP0rhSRDkpV;R~3Fd;7WE4sCzPwbA@T|1V45^Vp`wEVd~q!-);R= znoszpI-J5U*Xnws3yE(rPm-L$O>ugnsCdG>Df+3MG!Od!*?SZCx{B+5{Ju?_ZDboB zHU^_BjImi{%lpD+V{B{!wpoM-2}sYEvH7m@^Ka{K^F|iU>YFh92o^H~e%`V(EusNMm1g!$Jw5L z`}pLOJ>T)uDNlA@-cKjL>^>7eoubP73)qg?<;r^`Yz2JN$05-w#w<{O?YxJbPcgf`2Y4Y6yD&(Mw=KaRgd(03ieBLTInj&MtN_9=za~Lv&9Z)f6Q+*y@~ur=P&wxznl+o-}_^G4ECNjVJ6wVEB3xN=h4I7 z`AvI2T;|t1bWF4!^$Yy=o`l|-pJ;v{{Uh?te;@D=@F-97P#x)z{^_s;1J18#!S~6@ zsq$k_%e-p$HmhA2|P(dO*%| z{8^Iu-$s7K=XFR#Fn(9~_@ep)j=v*wUU0Db55!|aX^y@Z?ceuAKiJj-)ez$6JbP#F z_uKhq)4LYYD*8v(?jhxi`9X6WpB^?koPXx-kFs^ez{5&U-rXm|agD8CoS$Fm=S#7E zG9CXzZnPbiukqfmGx_r6g8k)tm9srO_Uk$rNb8?H*Rgw6>>TCDIXZ5(t{FMUjkELT z?0xRisUfJUtgCFi=>Lu)-Q-|#BeAsIK1{(TSH8db37CX28gB%XW72s8(`ghCY+uOo zZGV7x`+?U5oDlz>adD4ZFOBU*0)mwzU%(#W@zJB--@x*nY==xnuzBtoz#-tL@Q?UK z*j)y@k0+AXRgxS;>wTwJ_Pr{O-&sKM?f+XL@4kPY%zq5J5slM6XQ!rXT;8YSGcsM{ z@;)7(k?C%n_9;Chnl1WH(r=p{N=8M_`kkEZa&fzhZBWJ^Gp7?+^6+N>)Qw1c)Ux;NzNye@7qH` z99ieav03p(LK`<%Pc&|n2IxsNuIdj}#(k;FH@Q%MU&d9&`7+5r(QzKRV^qe8_-T|Z z&2i&4$Bmn_Pru4>dpI#}uky$3m(Zui#JDB(=^}sJena|1{&K`4{yM&o{2KLRD8c75 zJw8)-O?YdZW;rleMA3DL_Ez*aQQD zP=JkR=-7mc5e7~nwHS|0p~U4Gvm_ol)#=qrr=M;hmg1pRjJJ#b#$75439 zC1H1Ozr8=f^kQeYo9V^gt|5Dmg6S>2#l1}LFLofEzm$KZfczr`=-=6Rro&c^rr?7o=^AkqgJ!EVb{|6;E z|0U(5P|$XZDZLk=2!E3!Q*`&77g zO4ciW`EOqyFR$x^|KZBdck9V5vYzzIwIN)6*e=gAVUOsi1TZe8Ex%B%zGeJM)3HO9J`Zv1u=oVRz`sHr$=>`21 zom{Y4${nkp|KOKHKj}KMpBdLr%9TC$I#xfQ_4>*39jM6oN%#<8+i&;je%WsybZdW? zDBa$;b|?6v@^Ha8yhkUjZ^1ac-$~S`{5oqK-rEy+D!+K?6~XVv^NDuz$j`~@EROf7 z1RmuoC%X!9yh{`9(oWfancwa?2|OH=1|D}Y;`P00!ge{jalG9Lywj1-@p~LqnjNB@ zW3YQ_?0yQnFCsa=Q7;cC=nPSw_4Z=Glk0^&DV>ivf8wX?Pa%rlBQrYe`G&o>W&3#s zv;I$bbdR0GT3~M2tl7e&%OAa_&k@)&tObQH_X-1k$&wL>tQG% zonfS1e;7UX+{x%FtGbN$XXa`7iN@nO*cGcU8b5dMj6ZH~@Wzev6)9;2&2+H&Jb-q+ zn4T??Uc`PnCApYhA@ag`x4*G6U**$(f?TZOk^b(@m2}ptcI4xdUrbla&9}vLD4JVL zHwSs-qU^XY8??F#V^C+b&wb6a7x5|9R{!(>WZ+i@HpToOG^nmW7s>-?6ygVo`n7+34!>3B`SeX;=XJyxFpKIJ5j&N zxvuxwul-)X%}-(aoJ74aOQ?5QRPXdeKFk~P7f1Q`Cg@hW&X4leqa>qWParu=6~ z$@SpTZ^!4+Wd0nKv3az#U+2q_QJqh1ofth20WL&$-1nSpKCj%b*PwonJ7+O469p0c z_2ww%ZMJ&`Vy=H@zaGqR!R|Hi@%8z}L!3Ti^*qG+f84(LVZkFm*s`6giS3(rRpv9> zH!nYYuavWUc+2j4*>;bDzkZPC2n8jW{V0HC<}c^dGi6?|dkV{qidQ~M`C6VAN`m=c zZwExa=EO@tT{Dyy9dq>FP(DAT-DH0xh9ALxvE4tD@ud};IREb)9@uoWa=)LWgUX6v z_ZYCg{{;gP?Z3B6b|imnzqE6BcZb_==D78SrD0-qbQDXrzrggq{^B6h3q##~w*NeG z$3f-q9S1b7)A3}z=u$LJwNsD$Kk8o>2scA$;Fvqwehq3i1s_5{({t3epvgTPw9QMoEOlvjO$x4t~orN zVt?PwKM2S2H~$C5&G0ymv{Q^Z?(EO+`*se@UgYxGOXA`4WulM7CrrLtd5it}4ewZS zh2FTlvA&%Ndg)Om+cCQ~b~Z8*{{L{l+#2-rMDCY+E%1zA(YdPImCts6w2hbL6W=cv z@pm4%i+v#{f7C0=VblKyzdOVE`9%2J47^{4zka#sd6T+B(etMNjPI8OupcM#{gR{q zLOk_XPUOC~p9nssgY#9D#J{fl-e|Xep0Hb-vbevw*|YN;r&qzI*?2ML?C!(g0^L4* zv$Jz%zxq7b{F!KfLe&cA92QD{%LR$>T`J8m`_u(vN_(2m!nh$kC4XVJ^ZKJ2M6pEq zMuqELy-Wwma(^iI;m1Zbza{JLW69`5oyWN^2AjwET`C5)!x5q0GH@S-^)=na)gs!z zOQN9uER7>PfKtxsebYj%fb$STt4p`%*)198XCTjSFJGhmwf8#MKJ&@%C%|`0x91iH z`*@%A_|J5Pkp=7p;#tb55f#&5($5e>Fpj&I+}rNa%lEB z`P~WIU$gTEd(d8p`sd@k+?|NaJCrYWe&XhtAPm9Z_q!Z)R`4V{nDm|j_goA2DG8$S zzXLDLF+pGqLDNiKH%&&LmP-MTqfZ@F`D?}aTnhLK#G{Bycf2h1+WG4};0Yz`3dDz* z@7iU*Dec!9U+6}@(2aOh@U-9T7yCOIo$MDx3HR{D$GKr25)m#QP}#HbHvRVH z_XXb56P4F;_CB@mui|ySqkg%qU_t#}#UFX2wr_IE=Y(88Qhw+7`=C0^ft_E*KH_kh})hWoVK#RbQ2N7vZ>n(nWgK1_Z`pfD?IX` zwrlf+@!Q`|9zp*n%eV7`V~=Tle7@(ePklQ$6YUoiVAe&wBQCWbN~+&q$|y zjjVk^;H3Q~T|8o*q>JZi8LU5?S11W4k2bHcd~c#(ESFEcr0wH3Ysv+B-#&Hb?AI>; z2%_NX|21o?)n9H5nS}SM93R~KSe%z`^7z2<XI`GDS^8KICkrsEZ-_n!wWMv*|WwSbep=XtO zsY}v1kDqys>NXSby^bS{$%jA0KYXtvf)7c)nESxak6Qa2ue$A(dN^L^0iXWBEnYh5 ze+TR)>&O4mcLZC4djM7B>7`0DHgrQ#CeqCH&HrBiPF0u*CAlehm1+T z1@>aw0)_ncs0S0(i!M!=9(w7IgIL-Nw$p-uEQ#&>&K{?)ZS$BD1Px0xrhYF&AjH_{ zXpjAXA1^szM>au%IsUKXQn;*vZzPhy{ zSH65MMxHO9p}>>N=WSP4>Y;qn;!r;S*h{B;uANXmn}u-PL!kC_!1V)d9zNOtyLa&D z;m6XEovcRsGq_+XDZkW9@}+5}_S^KQ75FbpJ->7G%%|h^+_GfidT7s@X8u-;9=6+X z%Eb5$u-8p99~g)K&D_NJ-vqmwX1;wK{>Q%a^9lR)vG3La|4o8VdBFeC_vpI7?+`HM zoUwiPXntnj(eLBzQuLiqj0aUOCMT#UpSxM=we#0@j;+J_UFPq+8)X^BIN>0a&j~eN z;O3Vh%`m@_`uIDEd4hha%@gL&wFLV7&CZ?XQ+%pQ`Flv{qMW{jURbd6?!KR)`=z@7 z>8BrnJ{@cS9wefj7ov6+?(*Al^F91Wkbv(3yd-$Z`QG|#@8MF;PsUiZxb;p>W;O8Z z&DsMyZ)@L6Gk=qOAwBHxk3aFucZhxFhkp3_o2TN7^;b-AlBr8b;33^>}n&wX>fr$N9nDr)IhKlsA6ox#t0MUb$Rg_#hWL z-oAXi;QNE_yND+u51$8ZwhkHFul+K8qMeNSrB|x|NqfyOa^;JvpI170M7qeMyQkeh zzs~)g=)H4yzn{s!uNQ}aXYZp>Ugx46#z;Ooatyw4p0ejzv_lN`9uZ-5Gtwt}&P93N z9Mh{ORgWH);_{xgucySH{WEX;qj69^`29F2^eDgl^e2(-_YYNi{j+gB66t+Sj6Q9L zbi~HRy$|HKLw=BN|A2|R!avnhyC-|(N+*Zz{_bS?UxuH%V)QCMNpJJZt9Yb2)3@wSLt)@vb(q3-uH^WuP_4@Aw+ujmKS7v z?ETgH2PHdbaO-WWx21}s>#bWJ*73FP8MLJCm3;ao47Sdqyt2in#%4`-en<3PDvc5X zzwtV5Gv($D z*h?_I;d?9$W8E6((;E~{jEmVt+xM>DsQ3ddu3YXMSua|B_MHx^ckX5My6Fe&z2k-# zY`wN)>t>Ui zh!5K}-{^7d!v3;;LD2d?cfI=8IXsPJiF&Iy**|6b_~&)*{tT1*R***uTim|J#VawG z2oXPb2pBXh)!6vkA)dIYw^^eajKiSyz5 zS4i)bM<=4!_&wHHq4)U&y>IjAwf$3jj?DF)$OR9>AaEa>a7*eYfd>k;5|^F*DBQ0G zs}j= zerWkV9nbRpQf*LvK;@wPE(kh8`Q1w2z_HjkGStE z*g9k)zghh!=WpI6&EPv(I*!z{!`P>95pMx{`LO15o@BYn#)0L&f^vEBMk@R)oul$x za?csY+O@uSYgCc9guJkwPbJ2i<7DG)<7MO0;=T`^3;tZk$DLEN@1pw8a}J>&CMP!j zEx|v#a&F#t-&wJHd`QnT33`0_tH_PxtJ`-NDCoH6ExkH8B`c(mLHs_eEo01eIN`YYgO(^-~aLG%V$ZQ+Jl(hyY{K?q+@KepapsN{&!>t z213aw4^3(~LU2WDUN zX~cbp?nL#te7CkYUY=EdjnDR;i`~aiex>rPYKwC~I^UGuqy42FAgk>?#-u*mJU5Vd z{%+4vTHM}7D;Pk9h3Nr*h@6LCWcL*31+&akg zC7*KZHJ4v*3YN5@S2vZ-zfexM6_wS8lYp9Bj+pk$*G^&3VJU^eODl6y`}Tq zIRxkb?m;^DKbe16@|C_lpqHL=D`F{+c$E2T-8lrn_#gf(cWEl;0oYISIXa&(PqHVi zhwZZ+wton*ohx8HNJ2d-7vuZk&L?>NnCa>{;?-mOE!NKXdffR0v`0Q1tG^hU*u64* zF2Z^8$M{Zw$@eRHE`8~=_1_%WL1#$v=kwCvS1N zH97e2EN_oZFy603?v6mveLwJca!0)|xuZRzXqDFM{K$P`3n6}ttZx=@WQorEBaKYO zJV0eesJwTo@VI)fbpCO&-YbuY9kqKzqx0~bco9bKcwY1GI3#g-H57*F?w-?@8okG> zyi)1PSKTK0b}v(Tb|^6IJVO_Z5=r1aqWC{3t2vFnt6F}5SeWOc`!Q+7famT@istA0 zwLj)}+Wgbv-it5qbNP2m@tA#~Ut5{~cL@T|XVAWqF7}Z3n@Wu4xxbgM+AerG9ERnO z@*4Fo^0ik>y7iCcn~|~r7$1?GZeVs=3q`R-d8E_({U`{qkehb`HN<+2w=zgeHwqyA_Y0FI~a zhuZfW%Nsem@T>9f#Wz=k?&ch&9CGXGDX$k0=TJ2^eH&Tp6Uz6zAbihfE9F^& zu+l?qs?@8yVS4Y9yJrfH`Zh8ev^N{9r7*jz9VmPQjYFncJfB2NAUFhGxOJt|MVN4MLy|c zdoAw$%3QFL#b7s8P9pp4?5y3hozE(tEx-Jz>hGAc1^rdN)elN_vdh4BxW5Z=INFj` zU#5PC=G%EWtEc?9wx0{WCGz2pAqHJ&mh$zCi;ezb%@1WCPsfM+cJ{akBe+Oo=HI+YNlJC@D+xKqR#a!fTcjX)_^GDwDtm=Deh2-Z` zON7t%oMaF1g&!b>@g5gjxtzR}gm#?W^~dc#wik_?%2~M(A{F{%=Lk(7-1oT4A5gnW zy%l?+#e!B>k3Aspx6x;Gl?Ie=l(P|(vwa(T-^9vO zuU{EobzJRUoP6ry6XdIw%ennWvnOV+ZCp(5Ie(HaqqoA3m(*U(UWi=epBhSR{bo7J zcfQum`*&-;ox8Amf-3e?-)qa^X&o!Fddlv3K|b{tNS_hWQGP_nqjJx+_KSSpit;VN zrxrbdniT;*9r1EX&LFSerz-;F@{k3@_@A^xa z{Icf-*8ir{elJD`?pIKlgMtw4cfMKS|Ge?ib5@g&*SkR{#_N~nzn-%)dt&lePV)a@ z9rwBSLEsRM%XcTw5#ODh+Hb*F5yT$R@8ebV75a~b>My-k5)vIju=_NwjKC`Fz_DrbFG}E zcOj3iNh^_XGsZTpCPs()H=Oup$oov}Z-X1?`Zur~=qr6y0>(m24nLj8~({O`Qg7O$DUREDYXL^Kcx3H zn7o-h4&*5vI=@IP^i$qvsy}nRWTPE7?l&l$lq>qpY`0kTJ@vN~4drxyvz!klr94CB z+t#~d*C?XtpUExdgY_l%mmA)!_^qImBQf$`^=tE4UH|2?^;+&h#oGhD5q>y3Xa1Fy zv-dg8pDsV9dRl&5$0?t?P%3J=K^G#jzls#I8*_`RBtIuwrh3AJ=)3fe4x8T!vvmN= zGnEhaJ<{@Nq140gVG6yVTl@tUM6h|kd~ztT&9DA*Rq~@HP(Q%VVOV|kye6OGd-e1i zRQ{rIp!0|j$!EeZYzh8K^osQf-s8%5o1f=)shmai9*53q*U!8=zd~5%`-0YQbT`fV z(^$K?;1dFy{jR^(;XAn^qE$%y1TKU-is_d@yRl;F%2{6nV)vqHr?D3R>bJWo3JDNMO+ z#!vcjcVcV8_-*GWY~98D_j&t#h3PD%_7qw29UHR9+V}HAm+#Xz=K5*#lC3w&`{Md* z^Q-Nf+k0}R&!sB14t;o|MA3Sk_L!W`+jAcsj-Ygo+HHHjWb}@sV^t^>mTlkAz87P1 zH{jYsy=UR4omV4W)Dv4@v;?bUz|HT^*PJ7;`Q;;TIVj_6?*-azGS=P*Vsl)=h0!#leX`$&GZlH zN08pMVwNCA_45!pg3YJf)(9Akn=iL$I>mu zy`<+yy}J+>gB0AnQLNJa$npnt-1AlXyvx30)!@dxd_dc&SN1?Y72lql&z=5FX(t!x z{#d2HlT{Azv0c(xOzRg=Oy2To@(Fr{_u$z-rgMaC-z5)xHpzVQnfVwx{Nvw>Uf8}A z^NAnrhXH0en81Uom!b%NM&7t?Ogj`z$|$Hd-$Yg%!Yl$(2GD!qW*M2e?p{~zpw{%5H3O=NvYlU zY4aWX_gdoX^a1~`UdE64?1G&?qdu`C#mscg*XdXM^w-78S4%rqPcGPmT#QH5{^bHk z^Sawdu=Z`fv2(CyKU>`WXt_Y;G@m&|FoRgM5kf`k>BZ^ry&g+J{l* zJ9}sMH#Ie0fK>ALY>ADJ!&=~ZDA@UPd+@kk=t$$-16pwoKDbG(feJVGGf)MS8 z&QmygZVWmW0K?vwH#=zik}bgvQoeAPM6u`P^c%!qKnL0W3cP?ZeqM3&(ql(t{0awO z)Hs@7)IZSkyzqmtEF`~dU0#9JanEOT{PeP| z|12Fgx#4q|5GgjkA3vT^AqN62HFAkH=p{Fv^U;fxclwgyhXm~{G`tTj2}$r{A6||7w|cN z!pIVSvfS~;&E|>Z^Bo&U8<)w()5fndPw4ZnT<}q)=a(M8e@=|w<5FKf^Y@e3d-Xpi zxA(v5@%v(o-xYiR`B=ZlkCX17B+rBU>x;v%6ZZU3<^hc3iM*HikY|_8KlST9DD|pc zc_r^99*}ZwpXXr^gTVeiiF8}H(w=<}_RRd1Uq}C*{tfrg`l<5v%H>q$`}lJDTYf*?c_Z@=DAzxLT-*Mxy}#A81Q`hS zJf;Qrw=mfIbooqC;rS8;)o@=hHOqbqnmgLy(oLWF9wgsGBsOE(QHES_vBY-Xq2A3K z1MQL=28ezDcL18Ylur8&v-$P*{xHjvjmdRBiJVJBx7fn%|drER-my->)&tQGVPqTfRFd?IMk_ zwNu1B`D17|7koep8ogZW9rp0@@c$10&IOO+uhPYy9=~7jkM)c5=K+*!s?~EOx!}Ek zD)qG@pD(2veJ!=`3AnR#{C4ge*Ull7YpVUS%nvy^QI2{-BqG$0N)!yBJqCNPz6-y7 zKJ}y;B|o2=EA@|U7cgiT)tG$ZP_(%B1ux#L6(-v$SE<02wOFvNU4OLoYaG273pAMa zpy?iczx3kO`ur$a-(=(3gYR20*mKFIyI+$2+w*~uC9EC&b^Bo>^OP>rlU$$#Rmy+G z@lWZQjk5pvDkz%^CT~Vh9$$~hA}^2kL1>3eo}%%D*D3ze1aeJzA|6B21Expn-$(u5 zulZK5wVNC_Yp;k?7%JaaNI{lk7#o#H#?Ei|;^xhgF}Xd+%YJLV_VnP#z%)9jmmDd| zFBxX-&#%2i`g?r&T{DUNs)KFc!9E`SO_`l;ycSD8BKiPvWGSycebmQhq&3y5+}Qhf zR_^$8pB1Bfeh>!lM12#{DdXTG4>`WyFR|%U`2(tdrITj~fw!HUm$;*2 zhQuZJL70)dD|*OwMx1`y`g*{fqs(XYfb+n~I$ou>@0CHBvo(hs%g+4Q#=?71spCfV~1@Dj!`RSrp$LJSXI8nb2oKU|GM|_C)>qXZu?VnGN_RHyq*WcC0 z?60o-C$cZi((gX$cb*@?Lugt`Yk}ud?)%))cfcSQ47SfYshx(LQjdDvJuVfwX_tQG z-M!G2b{0v!c0ahSC+vLKz~z!H&q+lOz;wpNY*yz12p5_=%I7!?xj^5iFgc$)?<`4= z_J3VJ>^suQec)nR=TG|%Nh{cKDQYl%iJmWSl4?ai(dA&4Bq6GAhAMI^x-IqDz8(0(pQKaH zUtK1}qIz4>tB^25?jP4j5lY-1mQd zc|D%~u=R=b=kN*X&k><#yj^%n(nlt^|48+xqIWfK5hk%)pkutg(JuJ*=b_K~_^MZa ze|HQ1iQAoa!GBWd_3If$x;-c3IDEhx2jhRot!_LpZlj>TX@@(Pgu$Vti64NescDCM z{(^K$jHF`(n|3@CjVF7RbLXPR)SU^+*XVtwc8<7wgL~g2a~`m%ohrH(Vl!^=?S*-f5#NI(L1a)<->K1p}KE z=D9*raPw^KZ!3NiHoqjI`%#s*vU`qE=?AgN_kYxJz;CA5dE9zAsmTvDKkxt^v z`UW+ay|edz#&nq$G;9G9LKpm+5b-lE?s-6;4?m7H)-(5uSmpaGBaeVQlVv|D!~o#$dGCj$ko zf7>Yl5V+67akckeqUT@NO19ji)tspRRy^loJ5Z~mcFxk?iy}Qqd|XEw;TvBET>I2N z&XhU1&n;xZJ)iT{@OfQ+Rom9ZnPuqZxm4W#mKNRJ-!j_L4WaoFdz3ObKUCi z$BhDh3Yq&5H=QyCe^rl15tIHJZ$FX!#I>do{bTEZgh2UZz1+WRM%{N)jvYya= zAv@nRALrUSkWV{Bm!Ec-^Fh-oH{&nnEf_oeFZS+7p1rGg`$yeN1TDC2&Ie__WIgkd zlnZW>jLGevu9GIuSNdP6zM7u4LQf~2k8;PEj~a#U9Cnx)Cbxg?yaU=%dH5IU|F53j z|M>iQ!3oLte~tMwC(;VOJO5-A$P70o?`KL zoIcSXpoWzkJ(Kwj<}Yx*S>VwZ`5PZ}?KEoa`w_AIJ@l7>enis=>ACK^wSq4p%2o7y z8LJV!COvjv0rh)25}Hm4nH~Ar5x+q{^X>l91(0un*9m&iuw7$Yr-+_G@>cTIV;a-n75=VNnCH&XWWfFIn0=uWhtNH&@ohKElOIgxjXzz8r5wt~$^mBR zZqfL*8|KRo`m0cbqw}-hJbLu-PjZCO&7hdtruGkfq222_g|*UtwMiWLxsM7c?_V8D zK61ehK{UH&?-^G75bjD;_&z>gpC|mXc4QCwkFEss@xJ}B{q9Dg!~A~p+b6eoy8rqV z>Q{TG`>+3TI*(`HxQhgS!MPqqJkk1K|IfVj!S%$39IlgSf^~vBM~r?@mh8T-|7`y$ z=kBvJy=%pwQLZCZZO7Cs!HJ*%)Ux(d%83?hYJGrW7ClQ`-G4-Byns!I#t&JhG-M$~{+bE#ujXzJZ zjKH>Ugn5TytX(3}ebG07olLLR^aY3sH{7o9*y9>=|4jI|K;bS#AU)u9BQgEpCJ#dQ zs6@eS)$`;B_sK%xTez!&_N9n>o3;HkfR?f{^jvw=JKT-$s$rqWoHnLXA zqwXiNob1nhP?BZ;OX$~XWgZj1W~1iY{e8yIR@5u}K`i`n^FF&T{K;xLvs+vzPuQ<@ zibs0HUOehx;0rxxD;)J3=?pd>;k_=kM@X0YK~Ictj{f7;Z~lOrAD%*e>`Q}d-@a?b zeL|m4BRA9v?3>-$f((Ztnrw_}P19Z0FLSRQ#iezQjF` zK3$*o=(6*kcK)n9kdW_zPzWUdQ`g1y6_1i5eWg4LzvVCZPXNKbmt^M%Ms9U-{kY~+ z-uYgjzn@6Cw*Io+xScde@3V<| zccI>a1FF9jy-=gWo0W+9*z{GeTHNuk3C$FhshdCv`K7r_G9Mpc+& zmHS+x9EZT{Bjuh8gUQAz`TnT+>1;nlIrFEvZXy4fMrYhZk zvwLplwi`W~o}_<%dZWBgV)sjRp}#^G>-Fg3`s2@#kxyq8|2iNb*nJj-wLBcF+WQC#$e~u?YyO(TWy87kkXcF-RI=Egn*ltYC&5+Svu!~{R#O!iWholC)i#W z@}(cF$LojPBTzU8l_Q89J=ze|Z&$dWk?>Xe!AcMwN6dO{A0nUC{hrkVJGK>L8E zf~HRW?o@p{Q^(H>{`m!tFZ;1K!PhT%eD(1|)JOdG1pende3>6Wh|NQ^9}KqNL%Np( zZbf_)GC)1#i=R#NRDTFF^qj2rhUGa9^KmcTC6G0?Pnb9uo#?yAOs|CL!8YedvA$&} z*ECP%mHPvKg?(aaAGP!~YAL%9#q_#W+QFF}S5MN8%tkSzgEi2;8jSc(d+(*q=?(S1 z5{}&2)WI6Sm$Nms?Rt%q^)_{?qqvPsLoj~k-E&>jyEf-f7V%y<=}6Yo)5uk`mZzM| zZ3OcX>|E72{F%xxwx{^~OMH!u4zp9wATPu}8~0>=|BpX${!mZIN#mFK_jZrW6K*`| zCwO7BZJt7Qzh9iM_0e}D+nl|y`OV~Oj01+S2g5IVh?sh4_ay9rlOgGdCH)PG&;2mU z)%@K2;1|HR_X+HKf0g`3$)}wXe@4YcE5W0iZK~EX4_YF2vVv`$3i<1TBWTa;f!S5^ z?YB^O{hJiuzPDL^#Q9&2KW!bFZ|4gu&qL=*2I(Vdrl)(L@0SAJwp7d6a{yVlVB@uX zK%a{jt5d?7q<1aK6YlrXjl1o~O3Cfv28S0_;NW6ah^R z+8)r{rsy1aUJ~N%)&$#hdW!b7ZCywD(=q!0`6%fpUrBmTNhug-SB($Ar95m~pmf-C z`M6x7{YK3p5Me+KB(Ka`KKQXSK`hHhKN!zC%5aK7t zlkxn_EE!kwf#X2GgX3&^vCY}vz9A$cn7y}inRhxq*g7LxR}3n?-D4V`e}d7bC2H{P zeXz=TT__TQ`9F3~y4h9EPvnr5Gy5<%8h?88m~Z5-{Q=){|1L5%j&I7&;E96bR>nu) zCos9r=YA;V^BG+q+xKxz&*SnoJ!rZHgd#K*R!E!+_DOlp3+wPNpFLmFZ69?Hx-I?M zAj!eD>ohjMmHDi3qIAwg6Qy%KG*LQLaH90kOMe{lL3yD4Y(YSl#OAN>0Ze+^wlfFM z2Y}B&{ACFI&Dih_k8;O;*t~D&Wyf53=CePRPPwT^V110+n)yrpoD>3oGhXb{N!M!p zhxk$#Oa%}ITn*I8B5_4;1+>y~K!_I*^_x3%?Ty&E6<&T;AbN`0)S=VYCy^|mk2 zQP6x_#~GdP*5v4(n-k~DtV#GXO=>hcThT8vp5q%EM@N6eKck~de;B_;sAvcgpYU7w zlvO+Yx+SWZNj{a%mSR#)`SCLue_MaZx&$c4|EuC zg7UsJ<%H{dhNhKHUK||Bp_7mDUd6NT)!yvBiDUawoL5;NpSMZ>H~yRShx;j{>vhXj zF>JgI?{&*n5UsuXP1=r)PxAZJ13NW;?hPu34L3Oac8zVn#`@K9rQYl4@4xZ+xyf1K zfaY^pL;QQj#U^)ge+Yit*+4*Ob9{~bI5!UVUJTd~*)2ZjW|^Z$zkg>_^Sk&nI*(*{ zP0jad`aFrCXXGOAoIQ!)M$P9sl6H|0*T1G0ZJnBL^E=g$V9MvVQsu9hcZ80tNDI9L}5aFnI9&=m-%6W^w6v4aWqCgjGMm~X!~5> zkdtjrPa6g`o#zW<^Y?sBZyR>yP%rz@=J1pIFXSKlW9js_V)KKmkLfYH;?l_{nZJ=Q z^SA3K?JPy974fBr`>w|ygh& zf2IrLN4po_?->oYIXttAHvcv_KG=A*RO@pqTMyg$l3dUv?bol9Naij5C4W=)9&g(z znwrnvB0p>&pMDMHg6hE7)~UAM$OShFetaE+_2>#cUt#yN=7QHN9xI6g)_<;D^Y?SX znGrpby{dvW+dubXdJP5Rh4Eb!2#4Ja7CV=I9WY3#UX_kEJ zKlL1_k^i>M`J1NC%ojbJAYJruf^^Zt3DQLmCrA&`zO@_q(`YxQhb)XheIdPV+X=yc zC4ev+|6=yi@u|)6g>of&=4V6oIkKagGPY19td_c+WSpg%)- zXhke??D*2RQHqP7#gcZfnE59Sjhf$zOqRRTjl;Hen*J1-is0+7*cI0v^JMN zUu!w?Y<{-=Eb2YFkF%;XWjt(t&ZBo6pXj@~pojF@`?%KMq+OW1f>xgrjGbNJs zvHs%Um+p+03r5X9nY)y|VR?J)hV$-wj8O>eucEy5Yw-pxv3S15^(!0TF%bNTYL5GF5T77`HsFEQWzrIBmY zkXyMVy(a%7DXqu&)Y})9hWZ8zUB$4}U+5?ndxyG*%3*KcP`I;ixVQ7%aL=w{Z&=#h z-O=6K6}ETu_4XD!hPwND!@**yI8@j@SS)mw!ySEtgME97oxA!y%0tCc*n^^-1^h$l-F+Rmg$UR6^%RFo#li5Ri^CnmgS}h( zdW&0nZ!hfb?nM24yU}7l8|@t`kbt$JWp3+t1jVx#h1c&YhC90lK@wXHdxrU|7&eD} zgW(ckME_u4*I=P%acQt)aVM+qC=3-l+mPH*ES35O7Y&xcqK>}ZyIrq4L3sD>l5(f6 z*xAjdEBS4O;h|l9gW#cGvtQko-qO(Eu&{7#cwKQQyuR-?aQM2RLT_hbuyaGDsjV1< zO&o*}+`if|Y$NzQxHeqh(Se+y^~(M&y&wa8x}(@Ru6nP+>wpl;Z|S|gIM}_j99EF- zpLM~f25&yJ{@?!gZP#4eo;@dc-~&_ArLX<_(EYQ1{;o&XZQ0$uW3Vt-Ufj_)SQM^N zG>VIRiai~>$Sob_zTu&;Zzo0#)R)$VLl}qM=wx>(yt=TryJxs3bet=N{e#`TV0q{y zX|27~b`}3VXuKi@S?mlrSSThO%j}SiGZn9HeWD zw?kmO5ewIw$i*sK-w&xHVHJUz7|~VOQYs#&rpYmov$$obn*ylf9HV3$UvF5Z?83+u zN<&cijjBemQZ4z)R&Zv6K+h@ec|PitqBVys>+f@OBOX>5ccmb7BCPngW+Uc zI=2pOp8x~BCWN@{R5TiKp`dg@sFF*|tgXlTew@<6H>v12^<3B8RWV+ZwczylS{V1i z+eLN4tGY`=$En&QkqZ6_OFQ|3`RRc@3rmIF#qf3r!w}8!WQ4x5Q9g0{&5*^^VSMpP z#O7Sggx;hwndY2WX(PqWH)g0xw^K<}l_^9ePB#9;*gaJ2@#nk}X6Ygfwx2c(8$ly} zJ=}uQPAGo3yU^3$H#k(HMsb$tg}N4OZi8b$6CjQWCfq^6u-sCKlEpGE#j5Dr(@O$f zyO0bK`W_mCXmYmHooaET^iAEp-KAaVSjiPjB3yS{cYi;tPiDZc=qONahjw9>lh$@Y zvwPvgL{s)q_wB_S`i6>b^4_q!uVk5+7F}xTa=1mDsWG*LPh{VfXHM zM?HjihNna<9nV}p*frckZmR#)(tBGk1kJ6o)Tj3U!aYBB*gCmaxhULF=%okV-PGQSlaSz%Ha3`3%A;U1)efZMyFJBv23I$6%Z zaW4)+FJUiq1~iX5gs)y)B=y6$qmN477bf5;vM0bpkGgkugHP~*cfh7$GN)B4^`lFY zUKySVN}oU>NW%iGTj+ci!UGE5}QTxzY6#o9UCtIIkW*`#$p2J&!k z5?S1Wu!Ghu+$jd)7(Oc|k}g;@vK`{Cs&4B#xRrxWMnbrOf{g(2e04Tof&DI{UD4CU#F@sAHE%*|=#4!$;}k1SBFok^2u<37m%GM}lO1 zt%3=DSC#;iAsws2%Sj-IWaD1AZ(8ZG@ZIuN(M!NDf^Xyas7^Rn046#by0eU$xhVP z-@}O1%$w1-VC!LcNVrAS?d#o*O)Ic!H~cxZ9Xm1oV0%P3NLQ-^i-I!rx<^vD@nmb0 zUb;$@22=oRPy2@oQ5goMqklNu-Q9yu!%&p^dP}eF8xDsCIX|F4cQ0z8Bx6rZ*StuD zR26z5Q@ud&CNwNdZVRyp-Uj6ByL(io)w87A2l|bzG=$o?ELcm}dWaT#;)xy~-%PH! zmj?9pWB-mD8SDeNMnNp~bH7K-u@Fl|r#yQ6X{17Vu;`~_ICKRr3OB1je_?mu5bWk< z#d048*Fi9+ohV#Vwn7%Xni}bs$$Skyl*9@etty|+@wnC-tWtj;mKPPFEQyC^0XSZmuvQi{h<|uJrV%c*%Yii$f`(O+ptc7e8bN zYIKIX$L)i;p;3`>u0xM51D%9K9S5^MP8VPL#wUr7zlB1Z#*M?&%)d<)dS^ny7p<%}Yg-G-7j@Hr9CEE>4>| ztYQ{)oR>5=t6^|nOJQ)ZP?lCJ9tdr!iK*H&*zHa!=GMh`h!GIe5JtqA4^nUwGZ^h0 z^DZoNX@DyGDw9}T?1Q6}+VyVJpUXUl&5RE0tPG_LAo|qYEPY5Qqs$`|EO~Mv7?IN( zk-e(`kIOv1EjuxFQdi+ZD~GV8Ad4;t%P@InUumwLq(x{PX-q*@%22@#PFHH;yD>Ku zhawyi4x0PjeZ5^m-cC54SnAS#bPQva+dBlS*x6m;G}TFW$aXAr1ay=lKFb0K=sU5K z!bP8$1r>6t%CK&rMtd7FqN+o(>FUf2aq;o zrDI{Vvafh_<;Gp>cFXe6&6-d|IvZBPab{wq^_8`Gr2kT>Q>Sj&$lLI^Nch!Rq#L1I zzvBj8be7{j*xj`Y-lVK;I2ZVG48tmmn*KtG=1UaPY*d8naNHuvTre?M${isPf~pMK zs6HC@^XSbB8O6PY4r(boA?&>x)Pzz)(l)xzMh_>Pm+yuUOA#{~-1@>Yj5>^_MZn$e z>jKy#9TlL{Qo={Y6I)#}i%Ej%7~*a!sDh)`a_tsWp%&)4a?cJtG&OK*0WPEgLUg5O z+b&7=fTUEgyrm_b0Ha>$B@-%`q|}JCMVm*Y8m9G8$9#X<6$2lf{W2vVw?>+X=Wf8j zHY$)O10}fZwBfH=VD&A)!xr6A47)oo2z$Yv3&I6XBo^H4Hc?RO>dIKW(n=`-m6~ih z>1~BxrQ6@wrPy8I=E064wlW~ey+ch!*|vo=z`vmN)vZu{@2+z0=F47Kcx6(Jn zl!piY>g`q@{1?K@yRkMXz-;y4Ar^NnRhtKknBuVNlhpz@PjNiJDA`?J+=2yBY4PAN zjui|p-qSaD+u|MlJDVVs~K;#pNa|pl_j0mix-n_4N8HFE?2U9VvYx zRQ0z%{l=Gz4?pmgzxc+c&wac6duRN?8@}82npO9$ecMmo@cN^{hluOufVS@5oqZTv zCPAVG%d(N@68eXCKp_FN^vb#(^12fu%}vs7NihAk73GfMo_=^_#m@CGmg67A;Hk%Y zb#KN!gYh4}jC<xh@*QoMZ@;v1fOWI~yk%xqLW{>53R zUGUm#8sGNWt1iCs2Y251H{YxI?T3GH`QLx_D{o;r>`Fsuy6Bd`gkTG}Z%|jG`csdY zU=O`-uv{@Ka^48WekUGIVSC!1kwx1XFnn0$4i5Lj7#19nx^%PoktI1JL=z@6WS3@l zckgYbj={cCsi_k?RIu4h;dUIXHcG&3ces5fRsyS8D#L=qucmniAgR(0nl2J@yG#Sa zSd?S&s89VMrl_?S#*)88oQbOjnLgMMJU2{fc%U%tD{O%?)7yz%)k^cb`}+FX4QLRa!|AgC-IZ8aT-3D)dtp7&Q{tV=IiN|lbi5i+ z*v^uHwC>>^tq4P-`?=hHg}YL~l7$T*or^UOtPGIbF5$^As1#46nE>f}cgLXkvi;b{ zw_bH(`D2PM_1f;JC1SCUg)Ot(A+}yd{}sm;#zQB+rBmoN9r!9L*7XEy6|-i>lR*cu2BVtT@R7*kXP?;4+v}Ci`D&- z=B3TcnwK}PXkOX8s(E$unkCIkmMmGiWZ9DCOI9pdxn$Ln)l1eaZC<)$>C&akmM&kq zV(H4ItCp@_x@KAPvL(xw;$ZdiWh<7gT()Z2>Sb$|H!okZeChIK%a<=-v3%w7Rm)c| zU$dfl#gY|ES1enxe8q|tD_5*qv3kXtmCY-ctX#Ts*~;ZBSFBvQa@ES!E7z=QUbSS^ z(pAe=Enl@_)yh??R;^yOW_9!GC99XNUbcGq>J_V3u3oiz_3AZiK;jxSzXnyWL9sPR zny{1VVCktyXeIW7l~X1an!}A`IafzPfhEFIcn2%Cl!PV?DZ_ERQUGUVw4^Jx@Z6+R z?=Q9DsC)oN=M663@X*et)p}~Ogyl(*&Z!)qas%sZj-o{vpjOJ@cqETnDegEvz++o1 zPn|?Bcpii&)PIwKGtGZ2q>mXgiI8RR8hp*7MT>5hBdSgspg6H3l$3+^9mOu#FdUBM zaoUCYFhm|yWA9IoTH+wng?!$E;#eQ>Y3aFAa@-JLr?;c8vxo=vm^9aRM*a^J7daeQ|C;Ze$ur1?DWjcnJ3qtnwpiJojNTur~35N8R>>o!_4`arYVb3 z&6y?XrK!i$A4-2X`@1#&p8i?x7wMNXM{ED*-tt@D{z!A{jc4rKnp zAN}!X{`_;#ed`~B?6i|4ckP86H*LA{md@fm_x<+!KKr@nrp-7PNn2W9^V(b5I*V_= z??Wi^>Cb-sTmNum+Ki1`I*X(C{Qf8YbnJ^?KJtUR-|*H)AN$j>Pe1dy=l==KmNq2v(9YTbj8+fH{SHxTV8+X$3FdqFMjRF4}LOOdgsvad(K(3`0*#6 z8hhrsFMs{L>mGcl`JD}a{e{mR-Ma0j*HqWkPhYV3d*AQvTXpfJmu=jC-*sKX&wlp# z&%f}Mf5NrXVcS`EeLZ{E@W z{mkl?>P+^Gy4p-lraF^`G)>LsGE=HjC*^Znt52_Ptxi{+I&FJ)Lk9O*WM@>>PhFdx zJHIXL$=*7D^x529PiE#+-SvyitE*3~on3p%)KjM3T2)syr|Q+!=jS%nU67rcO=Xr$ zxga~IYD#AG_mH)C$<>+BM{6$1)MqZLUR`s3?yjRVX4fp9(UfVdZ>%4ETlTI8Pn(jz z_g%TgxeKe)C(W)M{nN9CrjCAT&eYuK(cI|Qr~dGLnN_v>UVF;u(>0@ik*k}1VWzHX zbE2a-)w;-}jU1 zRCrz$a^IdE{nO0pnfhr#RVszfrE}HQ>6)6_bX{&r`lRgi)Qt4Z+{rUeN#)bC(x**3 zBR99^?9{E<+tN>DK9PPd{rU74rhc*ZOX)AC|0Z=f_l@*FWnWBxFFcZcDGfnQO^ZoDtosqXb@SaD0|Bv4I(W>g&l^0)f!;hZ-eD;*tD_7mndgq5f^2DF4I6U)B zZ+^%7BT1wnZr#>deC;1Tb^00AHFZ-?nYD7w+Jhf@;VZSP_TP7~y6(bDc6Pt>{=T-c z?|uKK9Y6m0(f9uLqQwgqw!H7a!ykC`@q_>Kk3R9Kswq?RbJt$F@tVgT|I5ERP<`5* zv*urN=|6qv`$s?hnQS<3{y7VmtzNtN%B!|t*Kz}euDzqU^S097*WLM+M?d_;lZT%F z$P>MN58QIrNG_AbH={GD#fwJonwwcte@6D~+B0+K=Pu8lbl&KPtIp1zon2V7e9G1h z`&QMST30js!i{S(9W}Mhr{)?nr{_}ZR%c(8Tb!+{uB~1dF33);U71;%n^T>gTD^VC zs%6ubRWGWk+jq{jTNl=xcj}yT&NyXO?N&5!`Lxrj>#8=_ET|oxa_Rc>sxHjcRb5k+ z%1zJYM&G*Q%*{1*qmSKk*2XDyRntyhTUEF6g6yo(k6+Yz-PFysb(=PxzPaYQXpP{xnj$z%tCbN(eeWq#TWe1nebc@xGH@czq{5oTvmaj5e8xAf_|ch-R~@+Tidv zu512Aq2(jreE5dvU;M@mVbI%pBz3eEA0@BG$Kg_`H2zC%p3#;qQO$X?Q{gHU$kxE>RM(~Frq;4}wgxD5={c!%dJVKZn}(H3 zote(0rV!2nA$3anRM-Guqwbnib*3(TX6izeor;nRQ9Wt}$5Ywr^c1O;B%#qX;WN@} zK%ccTH?=vHO`-BsP3oFdx_WBOj#RpKO4XI=(@|e4wd$l4TFgyJon4#SnN3xJsPt*+ zY-W0P8h%!#>Qmr*W^VdS{I@Qhs;)_;r_`okdsD;dvr@Nbvgz7XRpzT;0;sKKjp>@I zx^$|!VM(?ba4xm5c4|6ACsUc#$V9=++M0Cwp-gI8s+tXE(w|uur2eci$h}xQ{POz8!w5Wm)V7xZ0dukKS=-9lqK1b)XMsE(aXBb64Y3o zx;S%oE>&|$YHE6UEz}~_mLVgnQU_9*n!Io|l{z(bQgtTxXEp4|EOHd%M66W$+n}oo z@#*Q78m8PzULd!a!GPj2*Hro^7C7T98y7kN``S}M2x_^b z3JrkYkTf=xLO(D81*uE3*YNkE^ens_p2_BFYSPtbX5W>;XA73rq)tkmnoHHArWsNT zuVzbKoDHgbs)P2?Bc2;}mfc>iX>$QLc-a>v;C8_CT>fsv?rM_YZls^#mHQ*WeBYCS z?{A%>KLbDg5YqWRCWD{Oy9C`Uy0P?UCQ1KGr0bha@p}FW>C3eGSUsOZy1tPa$A4~; z^dBL8B6>RE&gzYm@p?WqN&452zF-1+HsO6Z+spL%@H#L3Bj?(!ph580s3Y&{@zWvc zQGfmPE0I1C{u?Jre+20lOi=%`NDn7Tcdxt#HK4iO;TX>d9{L&zBh>t@#?3B1azx?j zKXCb9*Lb^&gKsIk%V38Wy7)<#e+Zk^+ogrdSP|UyV=e!ri(hc@^H~fkg2jh^>e~NT zjckRPPJ;iVN$`I@ z3H~pTJ_G+4{Q7xq^+fd8JvvGJt-v=u^Xs_<>88hi`U^-m8TQk^iu8&4`;SPUB~-@g ztikwPHbHtV(kJ5cKBQkb0sdV`cds7D`0ysAPn`gN6Z|9_bD#cyM7r5+KmF%OUpqlP zuZP_-IeJ}FPVTI5Xu(G+=Ckgnwfc^f@S(=Mv ziv^ki^Id)moq(@20P#lv`{ln1*ye1a{Q%<`@`nqlWw}Tum~;tXpZ;3`>un!e;2ywc zpPBLnz?(Ho{+_Ws-u@QAHdhj%AMmvv{wD#i_u$NmxO}Vz?DK0E;AtNIFkrJOOnxI^ zUmiY|fWHOUY&h}jSH|V35wPh2^H&1Cnm=5)8?fmHlO6`_xBvTquQ6oAnN@Zxs3y(< z?DJ~}V84I&1NQahdBA3)Si`pg`{Vr#^ww+-^H;2nmoEYK`}=;t>xk&W-vRdJGqWZR zF9ht%!}WkySz*L)1?=n7#{rv7BH9lD`|>w?Z7w*=E58=7uWz>i_T}Ms68V1y*zfOG z0MGO4`#E6VBVeK9!kpZ1WAGmV_WAJ-fHzqt;`1-c$=w^4bSq$=-+uu3BFjX41hDx` zOwL@K3$}RqR{{3r<8LuuzF&Sb@_l~22e3aLe+<~Suipaf>;LRa;`($e;8VQzKR++7 z@2^L`&+kV7pXcHKCEyMZUVLfXo?ZyJ-pjudu&K`Tuk9&u{N9k?-^W>wx|7ty>@G_ql)@z51^N?Ay0az&2icfVafq?#G;J z>mc(bnDzW1CRK#V@?UcKhWBiT&ZkfR6)I#o7az3P;amPN=<)r#$=Z4Td982n=QUpa zWsMJ`{HvrT+~Wf$!u+GXDVK=I`xzYhh4yE%{MBzgcK%+M-;ZvFt_h!C3wKw_PoE%v ze@gko_N|=7L_gsAwfP0@-!2zFyP+bdoNr7f{Pfp*=|2X(;arCF)9{bMPp8}&j-Sr? z%hI3SsPwWdL-pkq`Pq&>nC+gAbdx3G%?508{0G1bnTXJTUiO%BHd%gB&YE{BT`zVk zzYn?i1s5N5a%TCv(5~^>V$!pEK+8{-zst)fJ_EWF1(TOxQ=Csp__577xf|RHeiX1@ z&tbr(2UTg_5u{<=mdgG_3(^f|JDpt@{CZ5jnQ#5HnCMU5tL1Kdv&MT}%u(eaRr@BOgS z^~YCM>M5fk^Tqu1QKXxXaG%$Y*PvaKn=hfBh<2pE2>2|-77jJ$qCEhnCG+cE7576z zz^2c{ZvyQ5k(UAX=OunG%9ocO7#&sdjAaYJT`=ICMvQy>)Thw_2{R7 zjTglI--&joUY(2P1m^!3{Z>vB3WCuDACl#h?ae`bzQ6Z8%KP%L4*6ADwfs%iw+Z?4 zU49*6(`P@Od@5)fcGo1Etsy0U(HE7FVye)_dYk9_S(BOA~pJO%?(%t?qYJrZp4s%{+db6`^vz-FapPi_lb(5suJW2Y{Bi zj|xhCyW4j6b+yS4oM6K1Ep0*NU}n%ECmGx1Sdig#^zV`bOpZ%Wc7S*E!RJhZ67+=X_ZHY^V4JuXajc@VyCm^+I$U!Sc5! z;Dc@fVfmY#p)vSHXP6AO1)sssy9J=Z3*7?S;DZVHAr7cV&yxwb#wo9rKaha?-NOXS zzc&Hj=oUu4Z6{QizOd~X7NC;`84 zYaBnIVL`C=n-g$*IiCM?00Z)G*p1&>uA4tHn-xbI2Prwf);3Elm^Sk5a zA4pmFIzcB&tO2GGiG>(5D0Y905SAQ&yzdZrBC*WP5h~tkY z;Qa}B?CG#Nn5g#o_78o;| zouiIcI;T#w{x~om54b4g6k>yb4NA3!N_W5a^Z9=7>-lf@obTEDxUcu;Ju`dvd+*(Q zXWpy%j->muQ7Igqm;pR52cW+nw zcc?qq`LO05TzyP)=T3F^DYf%ywFmc~)!ePs133AD<~6*6J2<#U*U#Y+uHmrJ^)Z~n zqc3ZH2G8LF9^H@i@Ek7S;RCuphZk@O59~Qad;iyOoo56u;L*dny_Gpv$bP--VdoL8 zUv5t5*zxtHgM&vkpTfbnki+F;nlIt`L(P|P`i$l|oS5G{+x^MlYU|Xw4!HwFifAe5}@I z@C+Uvr}e|*)xnAC2u|Q7T)q_Rcd1i2hYQ#_Mb~%mrysVjK+E1Jjf_}4Vg;PlrupTP?__${rkU!~4Af4JN6_#T|C&fqy*?biCi zrRvp{>cLg&>DB7u?dlqC;P9PVzucV2x8r!i>(nvq-KhB-?lv!OyrbXn1L_u@-=cX5 z*KoYh`V5}I)g4;jz%AT=MC*qiRo8c_-MiHOU#rJ(0K1>i`s|bH;_uY6&!`J{`8my7 zxQCbbq8{$y>OQS6?^jPAfWM}m!ZBRH*@L=%4i|6-C;zVN3poFV=1aJT{YSOFfrpQ2 zp27vZg5Ae;{TPnnIXrwq*9UM6=Wqcp;SP4ct=k*I0UX1VAL#lST)-7P`k}5*&EM>r{10yu|DxQ7Qn zqWz|D2G?*04}Vnqh42in;5F?3nD&d{9A3gbJbJeF3*i}D!aeMH=m#fo2{*9!9PKxP z6LpFpa07Sn@CDj`0%!0XUco&)GB0pwzdri&oD3@+dfc8=116L<>G z;S%m)_b0S}07viwuHZH79j*OCIED+jhMgB_zX3dj6S#zzu=`@|@52$C!WG=W-Z9#L z2*+>+*YFA+_}YI2CvXlg;THCf)&65Rg=cUBcku8y?LUDtcn+`N9v&U9{R23M7jO%& z;qgnfe+bXu0`6ev1noD0r|=vu;U0E>Qu_yR1TWwUUc=r`Y5x$8;R3EW?pSjlPJdqWHSC_Ld3u)GpQ^{Oe=c%( zcAnZetJL1x z)Far-ki+9Y(!7A@*J@tD?K?Gh{#fn(iQ4@$^$;$v*Sv;jf3EogUcF264z6aJFJb3B zntN~y_wf9Ey1szh8#G_T`TI4W!;24SUc=4Jn)mdrntKa%c$+$cN4IM}f%7{wcMJ9S zPIXkO7avzApHNRetuEo{Gn%*mtPby1PnPNko_$X95_Z3+d3uk!huwQM&)_*cZcq=; z;Q~&-qU+0*x_wx^cueg*uJ*s9PQIre9k6}ngnhnL!i}qWc$hlz)IHq12>Eep=Opz2 z9>Nvez%3k{to{dtc_yWyScmc28sP)mC)C+h8dzWZ^0MFnR>|Uzt zCvXba@EZ0n(|!S*z;n2UJJ?IK{}_(o9B$$83hfue1>C}eJ-R-CQ@DUvu={51H-e{d z4p(po4}M?!2XGAMZ~-sj4tCz6+wvOn;>l?Jbhokpvp2FUZnh)VA zyu3;4=eMYbA5^d4_%Afi;K{9;PZsJWJo-z`YdE@1^AsN6u6Ym7KBW2L4)q$Inroo# zp_K(tHGm_i5g()b0c79A3cQSG7KZ zD>(R?*3V$~LCwc-0=KaDkgkv5{Og+gtvZBrxPm+SVeRL9Lmk00IDACw*Kqw!&Ex-2 zk2`e>myc>b{g%3eXOC+>enLHiC*RgQ_)m2PCr@hbe@C6cEu4N=>l=9Tl;%C`{I}*~ z*!v&N6L_%Jyo3GkX}*T1|EqZq*H3G{hMVteKKg-r3A9(f@Yr0l zZ@*qv2OKQ@M+d3{IENRoe~_-9!oz22Uc=GBn&)s2SBGeQ2ghe?p29gihfBDIS8xxz zuh#AR@E8u^7|!51T*6DZh1ak*)%_j96L<;7zkPTNhj0WZa1Jlv3U1&IcFxuP z9l#?vfFn4CXK(@6@Cxo>_dMNSA0ERY9K#trhYPrd8@Ppg*m;fazX$v92%f+p9Ki{k z!83RPmv9X?a0~aa^Sd~H*oQ~(1PEhhgd;eC zGk69s;1aIk25#XVb|M@rm!zEn74ZMPTcny0O z>is!@NAMU9;VB%!F`U73xP+H*3-_>VW|i8<*8sM&Ol=+@58)V2;1tf_9G<~*cmWr1 z4KLvq?qKI4{rtP|03O0)IDjKKg=g>_F5wEU;U&C+J9rJdvECm(JcP$^08il5#wX_{`z(AYqo4$ z`RX1X9H)5*H^*!4zC^t^LA`?0%^=dPH@kn4nU87RpQ!orWOchsot&z!PgAF-tL=-z z*zHAUXrBL~dOT6bzpNhos(NnbN80}DKy%N`gS5GSrsfkf|Iy~_Q1kRv>c!dWshQts z*H6yXynxr|XHnt6Y=e|CrFOEYiH=Bb&dW?lTf)>r?iF3r3$Tih0dSvD^S+DQb_0hkmb2E?0);nL+ zJTmi^Y`%hLX1ay1S7ZB4%)A=w#LTO)PT~AS?Z4Qio|<_vc75@3 z&3iaFL-P*KU!nQP%zLr@D>HA!I`~bk58;uSpJMA9Ge5<;GxJTXvum_p4zF&}yt-9g znE4^L-`dOvv5w6A4(sl3bbSxIpV!=N)R~!gVf)qegIe!Aq;?-sSKm~xI(1{_C)n*( z=K34!!71D4J6pG>sz>H}nSJ>yHLrg|U7o2Pou%&1Q3vMw7~9{EGY=&5#rCh>ta~SEF5%i-UtsgmeY(8@4(`{ygTt?Co;{+D&GiU& zd)^b8cTcL_r_^)Uds_3gvwi-F?Oz_Kp1bPsaP`zUUZ8efs2;=7QJT-;!O@zB zaQ7n3-Q(4hlhkWCKUwp^&!|JVdzt3`scPpmbqp^~*Sv#!cy@-?m%pu!UaPJyP)8T4 z*RNNXv3h#3dSsxdFt<7t5zOD7boL_65e@WLD=KNKgmtWU>{BP=kIp5RPr*Hws=KN1vzcS~4 zT8EwXUz+nfZC;r3H?8w0wLU#~`}bcqZw^sAhpOG{_dcE2`+REilUZWs{cqOq{YmZJ znlE72%qy5icH;)hZ zW$OHA)$2>uQKC+-P)~L|U)=OxzI5-SaNpz88L1;PAJgvN%FM^K_Fk>^v6(k%^VZCp z+~@1G-Z%3QZ9X^i5Uu^sYJFqo5!!rd<`G&?%{)Tu%*>y&?shyM+H`gg*#Gm>#_f*p zPa9Wf?Z5vvmGQOe`s3;jo<4v7*MrUaen6Mr4z1@Au8!m8m zT@i0p@7aC+R?TIbC7VwFueZ&;u=%$+hRvJ5eYfnpo%q}Py`Ao#cWgb`dS|obx#k1W zvD@|b_Mp>DU~cT+TkS`mz4gv!{q|>b>+@vJ1Gcx>k+yRCmg_gaM&InaUEi6%8`#^@ zEVsvJ*L&vUCv4pwvGs5J(Yp0{Gp~bnBhvSGHFKJ3qMfKDYmWuR)ya From 7edb0fd5ebf00a234e5fee66a5ea45766095cecd Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 1 Feb 2023 15:39:44 +0100 Subject: [PATCH 0303/1076] stake-pool: Use `Pubkey::as_ref()` instead of `to_bytes()` (#4014) --- program/src/processor.rs | 50 +++++++++++++++--------------------- program/src/state.rs | 8 ++---- program/tests/helpers/mod.rs | 4 +-- program/tests/huge_pool.rs | 2 +- 4 files changed, 26 insertions(+), 38 deletions(-) diff --git a/program/src/processor.rs b/program/src/processor.rs index ba98e546..d63d7e44 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -372,8 +372,7 @@ impl Processor { authority_type: &[u8], bump_seed: u8, ) -> Result<(), ProgramError> { - let authority_signature_seeds = - [&stake_pool.to_bytes()[..32], authority_type, &[bump_seed]]; + let authority_signature_seeds = [stake_pool.as_ref(), authority_type, &[bump_seed]]; let signers = &[&authority_signature_seeds[..]]; let ix = stake::instruction::delegate_stake( @@ -405,8 +404,7 @@ impl Processor { authority_type: &[u8], bump_seed: u8, ) -> Result<(), ProgramError> { - let authority_signature_seeds = - [&stake_pool.to_bytes()[..32], authority_type, &[bump_seed]]; + let authority_signature_seeds = [stake_pool.as_ref(), authority_type, &[bump_seed]]; let signers = &[&authority_signature_seeds[..]]; let ix = stake::instruction::deactivate_stake(stake_info.key, authority_info.key); @@ -424,8 +422,7 @@ impl Processor { amount: u64, split_stake: AccountInfo<'a>, ) -> Result<(), ProgramError> { - let me_bytes = stake_pool.to_bytes(); - let authority_signature_seeds = [&me_bytes[..32], authority_type, &[bump_seed]]; + let authority_signature_seeds = [stake_pool.as_ref(), authority_type, &[bump_seed]]; let signers = &[&authority_signature_seeds[..]]; let split_instruction = @@ -453,8 +450,7 @@ impl Processor { stake_history: AccountInfo<'a>, stake_program_info: AccountInfo<'a>, ) -> Result<(), ProgramError> { - let me_bytes = stake_pool.to_bytes(); - let authority_signature_seeds = [&me_bytes[..32], authority_type, &[bump_seed]]; + let authority_signature_seeds = [stake_pool.as_ref(), authority_type, &[bump_seed]]; let signers = &[&authority_signature_seeds[..]]; let merge_instruction = @@ -526,8 +522,7 @@ impl Processor { clock: AccountInfo<'a>, stake_program_info: AccountInfo<'a>, ) -> Result<(), ProgramError> { - let me_bytes = stake_pool.to_bytes(); - let authority_signature_seeds = [&me_bytes[..32], authority_type, &[bump_seed]]; + let authority_signature_seeds = [stake_pool.as_ref(), authority_type, &[bump_seed]]; let signers = &[&authority_signature_seeds[..]]; let authorize_instruction = stake::instruction::authorize( @@ -577,8 +572,7 @@ impl Processor { stake_program_info: AccountInfo<'a>, lamports: u64, ) -> Result<(), ProgramError> { - let me_bytes = stake_pool.to_bytes(); - let authority_signature_seeds = [&me_bytes[..32], authority_type, &[bump_seed]]; + let authority_signature_seeds = [stake_pool.as_ref(), authority_type, &[bump_seed]]; let signers = &[&authority_signature_seeds[..]]; let custodian_pubkey = None; @@ -616,8 +610,7 @@ impl Processor { vote_account: AccountInfo<'a>, stake_config: AccountInfo<'a>, ) -> Result<(), ProgramError> { - let me_bytes = stake_pool.to_bytes(); - let authority_signature_seeds = [&me_bytes[..32], authority_type, &[bump_seed]]; + let authority_signature_seeds = [stake_pool.as_ref(), authority_type, &[bump_seed]]; let signers = &[&authority_signature_seeds[..]]; let redelegate_instruction = &stake::instruction::redelegate( @@ -673,8 +666,7 @@ impl Processor { bump_seed: u8, amount: u64, ) -> Result<(), ProgramError> { - let me_bytes = stake_pool.to_bytes(); - let authority_signature_seeds = [&me_bytes[..32], authority_type, &[bump_seed]]; + let authority_signature_seeds = [stake_pool.as_ref(), authority_type, &[bump_seed]]; let signers = &[&authority_signature_seeds[..]]; let ix = spl_token_2022::instruction::mint_to( @@ -1389,7 +1381,7 @@ impl Processor { )?; let ephemeral_stake_account_signer_seeds: &[&[_]] = &[ EPHEMERAL_STAKE_SEED_PREFIX, - &stake_pool_info.key.to_bytes(), + stake_pool_info.key.as_ref(), &ephemeral_stake_seed.to_le_bytes(), &[ephemeral_stake_bump_seed], ]; @@ -1452,8 +1444,8 @@ impl Processor { } else { let transient_stake_account_signer_seeds: &[&[_]] = &[ TRANSIENT_STAKE_SEED_PREFIX, - &vote_account_address.to_bytes(), - &stake_pool_info.key.to_bytes(), + vote_account_address.as_ref(), + stake_pool_info.key.as_ref(), &transient_stake_seed.to_le_bytes(), &[transient_stake_bump_seed], ]; @@ -1664,7 +1656,7 @@ impl Processor { )?; let ephemeral_stake_account_signer_seeds: &[&[_]] = &[ EPHEMERAL_STAKE_SEED_PREFIX, - &stake_pool_info.key.to_bytes(), + stake_pool_info.key.as_ref(), &ephemeral_stake_seed.to_le_bytes(), &[ephemeral_stake_bump_seed], ]; @@ -1730,8 +1722,8 @@ impl Processor { // no transient stake, split let transient_stake_account_signer_seeds: &[&[_]] = &[ TRANSIENT_STAKE_SEED_PREFIX, - &vote_account_address.to_bytes(), - &stake_pool_info.key.to_bytes(), + vote_account_address.as_ref(), + stake_pool_info.key.as_ref(), &transient_stake_seed.to_le_bytes(), &[transient_stake_bump_seed], ]; @@ -1940,8 +1932,8 @@ impl Processor { )?; let source_transient_stake_account_signer_seeds: &[&[_]] = &[ TRANSIENT_STAKE_SEED_PREFIX, - &vote_account_address.to_bytes(), - &stake_pool_info.key.to_bytes(), + vote_account_address.as_ref(), + stake_pool_info.key.as_ref(), &source_transient_stake_seed.to_le_bytes(), &[source_transient_stake_bump_seed], ]; @@ -1973,7 +1965,7 @@ impl Processor { )?; let ephemeral_stake_account_signer_seeds: &[&[_]] = &[ EPHEMERAL_STAKE_SEED_PREFIX, - &stake_pool_info.key.to_bytes(), + stake_pool_info.key.as_ref(), &ephemeral_stake_seed.to_le_bytes(), &[ephemeral_stake_bump_seed], ]; @@ -2076,8 +2068,8 @@ impl Processor { )?; let destination_transient_stake_account_signer_seeds: &[&[_]] = &[ TRANSIENT_STAKE_SEED_PREFIX, - &vote_account_address.to_bytes(), - &stake_pool_info.key.to_bytes(), + vote_account_address.as_ref(), + stake_pool_info.key.as_ref(), &destination_transient_stake_seed.to_le_bytes(), &[destination_transient_stake_bump_seed], ]; @@ -3560,7 +3552,7 @@ impl Processor { crate::find_withdraw_authority_program_address(program_id, stake_pool_info.key); let token_mint_authority_signer_seeds: &[&[_]] = &[ - &stake_pool_info.key.to_bytes()[..32], + stake_pool_info.key.as_ref(), AUTHORITY_WITHDRAW, &[stake_withdraw_bump_seed], ]; @@ -3640,7 +3632,7 @@ impl Processor { crate::find_withdraw_authority_program_address(program_id, stake_pool_info.key); let token_mint_authority_signer_seeds: &[&[_]] = &[ - &stake_pool_info.key.to_bytes()[..32], + stake_pool_info.key.as_ref(), AUTHORITY_WITHDRAW, &[stake_withdraw_bump_seed], ]; diff --git a/program/src/state.rs b/program/src/state.rs index cede91c1..e9d8b61f 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -62,7 +62,7 @@ pub struct StakePool { /// signed by this authority. If no deposit authority is specified, /// then the stake pool will default to the result of: /// `Pubkey::find_program_address( - /// &[&stake_pool_address.to_bytes()[..32], b"deposit"], + /// &[&stake_pool_address.as_ref(), b"deposit"], /// program_id, /// )` pub stake_deposit_authority: Pubkey, @@ -273,11 +273,7 @@ impl StakePool { bump_seed: u8, ) -> Result<(), ProgramError> { let expected_address = Pubkey::create_program_address( - &[ - &stake_pool_address.to_bytes()[..32], - authority_seed, - &[bump_seed], - ], + &[stake_pool_address.as_ref(), authority_seed, &[bump_seed]], program_id, )?; diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 498cd961..a543e39f 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -2429,8 +2429,8 @@ pub fn add_stake_pool_account( ) { let mut stake_pool_bytes = stake_pool.try_to_vec().unwrap(); // more room for optionals - stake_pool_bytes.extend_from_slice(&Pubkey::default().to_bytes()); - stake_pool_bytes.extend_from_slice(&Pubkey::default().to_bytes()); + stake_pool_bytes.extend_from_slice(Pubkey::default().as_ref()); + stake_pool_bytes.extend_from_slice(Pubkey::default().as_ref()); let stake_pool_account = SolanaAccount::create( ACCOUNT_RENT_EXEMPTION, stake_pool_bytes, diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index ad1ac200..5a151786 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -25,7 +25,7 @@ use { // the test require so many helper accounts. // 20k is also a very safe number for the current upper bound of the network. const MAX_POOL_SIZE_WITH_REQUESTED_COMPUTE_UNITS: u32 = 20_000; -const MAX_POOL_SIZE: u32 = 3_000; +const MAX_POOL_SIZE: u32 = 3_200; const STAKE_AMOUNT: u64 = 200_000_000_000; async fn setup( From ef4d615a216c18acf222e2d4d224e4e43afbd7bd Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 1 Feb 2023 16:34:25 +0100 Subject: [PATCH 0304/1076] stake-pool: Revert huge pool number to 3k (#4015) --- program/tests/huge_pool.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index 5a151786..ad1ac200 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -25,7 +25,7 @@ use { // the test require so many helper accounts. // 20k is also a very safe number for the current upper bound of the network. const MAX_POOL_SIZE_WITH_REQUESTED_COMPUTE_UNITS: u32 = 20_000; -const MAX_POOL_SIZE: u32 = 3_200; +const MAX_POOL_SIZE: u32 = 3_000; const STAKE_AMOUNT: u64 = 200_000_000_000; async fn setup( From 431b224e10a55e9f54a06626964225b60f271993 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 1 Feb 2023 18:10:35 +0100 Subject: [PATCH 0305/1076] stake-pool: Specify the space used for new stake accounts (OS-SSP-SUG-00) (#4000) --- program/src/processor.rs | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/program/src/processor.rs b/program/src/processor.rs index d63d7e44..b68d5616 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -340,12 +340,10 @@ fn create_stake_account<'a>( stake_account_info: AccountInfo<'a>, stake_account_signer_seeds: &[&[u8]], system_program_info: AccountInfo<'a>, + stake_space: usize, ) -> Result<(), ProgramError> { invoke_signed( - &system_instruction::allocate( - stake_account_info.key, - std::mem::size_of::() as u64, - ), + &system_instruction::allocate(stake_account_info.key, stake_space as u64), &[stake_account_info.clone(), system_program_info.clone()], &[stake_account_signer_seeds], )?; @@ -1036,10 +1034,10 @@ impl Processor { ]; // Fund the stake account with the minimum + rent-exempt balance - let space = std::mem::size_of::(); + let stake_space = std::mem::size_of::(); let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; let required_lamports = minimum_delegation(stake_minimum_delegation) - .saturating_add(rent.minimum_balance(space)); + .saturating_add(rent.minimum_balance(stake_space)); // Check that we're not draining the reserve totally let reserve_stake = try_from_slice_unchecked::( @@ -1064,6 +1062,7 @@ impl Processor { stake_info.clone(), stake_account_signer_seeds, system_program_info.clone(), + stake_space, )?; // split into validator stake account Self::stake_split( @@ -1342,8 +1341,9 @@ impl Processor { )?; } + let stake_space = std::mem::size_of::(); let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(stake_space); let current_minimum_lamports = stake_rent.saturating_add(minimum_delegation(stake_minimum_delegation)); if lamports < current_minimum_lamports { @@ -1389,6 +1389,7 @@ impl Processor { ephemeral_stake_account_info.clone(), ephemeral_stake_account_signer_seeds, system_program_info.clone(), + stake_space, )?; // split into ephemeral stake account @@ -1454,6 +1455,7 @@ impl Processor { transient_stake_account_info.clone(), transient_stake_account_signer_seeds, system_program_info.clone(), + stake_space, )?; // split into transient stake account @@ -1609,7 +1611,8 @@ impl Processor { return Err(StakePoolError::ValidatorNotFound.into()); } - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_space = std::mem::size_of::(); + let stake_rent = rent.minimum_balance(stake_space); let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; let current_minimum_delegation = minimum_delegation(stake_minimum_delegation); if lamports < current_minimum_delegation { @@ -1664,6 +1667,7 @@ impl Processor { ephemeral_stake_account_info.clone(), ephemeral_stake_account_signer_seeds, system_program_info.clone(), + stake_space, )?; // split into ephemeral stake account @@ -1732,6 +1736,7 @@ impl Processor { transient_stake_account_info.clone(), transient_stake_account_signer_seeds, system_program_info.clone(), + stake_space, )?; // split into transient stake account @@ -1839,7 +1844,8 @@ impl Processor { } let rent = Rent::get()?; - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_space = std::mem::size_of::(); + let stake_rent = rent.minimum_balance(stake_space); let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; let current_minimum_delegation = minimum_delegation(stake_minimum_delegation); @@ -1942,6 +1948,7 @@ impl Processor { source_transient_stake_account_info.clone(), source_transient_stake_account_signer_seeds, system_program_info.clone(), + stake_space, )?; Self::stake_split( @@ -1973,6 +1980,7 @@ impl Processor { ephemeral_stake_account_info.clone(), ephemeral_stake_account_signer_seeds, system_program_info.clone(), + stake_space, )?; Self::stake_redelegate( stake_pool_info.key, @@ -2077,6 +2085,7 @@ impl Processor { destination_transient_stake_account_info.clone(), destination_transient_stake_account_signer_seeds, system_program_info.clone(), + stake_space, )?; Self::stake_split( stake_pool_info.key, From 320fdd7a0b8b573c8bd6853e4d3a74dd9a73ffa6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 Feb 2023 16:12:15 +0100 Subject: [PATCH 0306/1076] build(deps): bump num_enum from 0.5.7 to 0.5.9 (#4020) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 5cb2eb3e..21d21518 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,7 +17,7 @@ borsh = "0.9" mpl-token-metadata = { version = "1.7.0", features = [ "no-entrypoint" ] } num-derive = "0.3" num-traits = "0.2" -num_enum = "0.5.4" +num_enum = "0.5.9" serde = "1.0.130" serde_derive = "1.0.103" solana-program = "1.14.12" From cef38b9284c23f78d91d57d08087b02e1aada604 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 3 Feb 2023 00:42:21 +0100 Subject: [PATCH 0307/1076] token-2022: Fix non-transferable extension for unchecked transfers (#4005) --- program/tests/helpers/mod.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index a543e39f..4fa7327a 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -246,7 +246,8 @@ pub async fn create_token_account( ), ExtensionType::TransferFeeAmount | ExtensionType::MemoTransfer - | ExtensionType::CpiGuard => (), + | ExtensionType::CpiGuard + | ExtensionType::NonTransferableAccount => (), _ => unimplemented!(), }; } @@ -288,7 +289,9 @@ pub async fn create_token_account( .unwrap(), ) } - ExtensionType::ImmutableOwner | ExtensionType::TransferFeeAmount => (), + ExtensionType::ImmutableOwner + | ExtensionType::TransferFeeAmount + | ExtensionType::NonTransferableAccount => (), _ => unimplemented!(), } } From a4d947c3584aa9348d54f1f4e5692690a714fe3f Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 8 Feb 2023 15:56:23 +0100 Subject: [PATCH 0308/1076] stake-pool: Refresh blockhash more often to please CI (#4041) --- program/tests/withdraw_edge_cases.rs | 38 +++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/program/tests/withdraw_edge_cases.rs b/program/tests/withdraw_edge_cases.rs index ef14e250..27e25d9b 100644 --- a/program/tests/withdraw_edge_cases.rs +++ b/program/tests/withdraw_edge_cases.rs @@ -582,11 +582,17 @@ async fn fail_withdraw_from_transient() { tokens_to_withdraw, ) = setup_for_withdraw(spl_token::id()).await; + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&context.last_blockhash) + .await + .unwrap(); + // add a preferred withdraw validator, keep it empty, to be sure that this works let preferred_validator = simple_add_validator_to_pool( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &stake_pool_accounts, None, ) @@ -596,12 +602,18 @@ async fn fail_withdraw_from_transient() { .set_preferred_validator( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, instruction::PreferredValidatorType::Withdraw, Some(preferred_validator.vote.pubkey()), ) .await; + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&last_blockhash) + .await + .unwrap(); + let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); @@ -610,7 +622,7 @@ async fn fail_withdraw_from_transient() { .decrease_validator_stake( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &validator_stake_account.stake_account, &validator_stake_account.transient_stake_account, deposit_info.stake_lamports + stake_rent - 2, @@ -625,7 +637,7 @@ async fn fail_withdraw_from_transient() { .withdraw_stake( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &user_stake_recipient.pubkey(), &user_transfer_authority, &deposit_info.pool_account.pubkey(), @@ -657,11 +669,17 @@ async fn success_withdraw_from_transient() { tokens_to_withdraw, ) = setup_for_withdraw(spl_token::id()).await; + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&context.last_blockhash) + .await + .unwrap(); + // add a preferred withdraw validator, keep it empty, to be sure that this works let preferred_validator = simple_add_validator_to_pool( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &stake_pool_accounts, None, ) @@ -680,12 +698,18 @@ async fn success_withdraw_from_transient() { let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&last_blockhash) + .await + .unwrap(); + // decrease all of stake let error = stake_pool_accounts .decrease_validator_stake( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &validator_stake_account.stake_account, &validator_stake_account.transient_stake_account, deposit_info.stake_lamports + stake_rent, @@ -701,7 +725,7 @@ async fn success_withdraw_from_transient() { .withdraw_stake( &mut context.banks_client, &context.payer, - &context.last_blockhash, + &last_blockhash, &user_stake_recipient.pubkey(), &user_transfer_authority, &deposit_info.pool_account.pubkey(), From 77b9cb9bcff67d7ea47baa3ca1f109bfe3e8e2e2 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 9 Feb 2023 00:27:05 +0100 Subject: [PATCH 0309/1076] token-2022: Bump program, cli, and client for release (#4039) --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 21d21518..d28326fe 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -22,7 +22,7 @@ serde = "1.0.130" serde_derive = "1.0.103" solana-program = "1.14.12" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } -spl-token-2022 = { version = "0.5", path = "../../token/program-2022", features = [ "no-entrypoint" ] } +spl-token-2022 = { version = "0.6", path = "../../token/program-2022", features = [ "no-entrypoint" ] } thiserror = "1.0" bincode = "1.3.1" From a40480835f6805a2984da9add9bf446e1cd631dd Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Mon, 13 Feb 2023 23:05:49 +0100 Subject: [PATCH 0310/1076] docs: Clarify audit status of all programs, no S word (#4046) --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 179033a2..c8df8f6b 100644 --- a/README.md +++ b/README.md @@ -7,3 +7,8 @@ The command-line interface tool is available in the `./cli` directory. Javascript bindings are available in the `./js` directory. Python bindings are available in the `./py` directory. + +## Audit + +The repository [README](https://github.com/solana-labs/solana-program-library#audits) +contains information about program audits. From 61f231a6ef77236fa70e465a1a9ee5381a5e4b33 Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Wed, 8 Mar 2023 17:09:32 +0900 Subject: [PATCH 0311/1076] Bump ATA to v1.1.3 (#4073) --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index c1498f28..d86ad3df 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -23,7 +23,7 @@ solana-logger = "=1.14.12" solana-program = "=1.14.12" solana-remote-wallet = "=1.14.12" solana-sdk = "=1.14.12" -spl-associated-token-account = { version = "=1.1.2", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } +spl-associated-token-account = { version = "=1.1.3", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "=0.7.0", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "=3.5.0", path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" From 0c2c068c9de7067730cad71b8725f9a2c104526e Mon Sep 17 00:00:00 2001 From: Giovanni Napoli Date: Tue, 14 Mar 2023 21:22:50 +0100 Subject: [PATCH 0312/1076] Support `create` and `update` token metadata in stake-pool python bindings (#3978) --- clients/py/stake_pool/actions.py | 66 ++++++++- clients/py/stake_pool/constants.py | 19 +++ clients/py/stake_pool/instructions.py | 126 +++++++++++++++++- clients/py/tests/conftest.py | 2 + .../test_create_update_token_metadata.py | 67 ++++++++++ 5 files changed, 278 insertions(+), 2 deletions(-) create mode 100644 clients/py/tests/test_create_update_token_metadata.py diff --git a/clients/py/stake_pool/actions.py b/clients/py/stake_pool/actions.py index 18176f45..6e681a31 100644 --- a/clients/py/stake_pool/actions.py +++ b/clients/py/stake_pool/actions.py @@ -18,9 +18,11 @@ MAX_VALIDATORS_TO_UPDATE, \ MINIMUM_RESERVE_LAMPORTS, \ STAKE_POOL_PROGRAM_ID, \ + METADATA_PROGRAM_ID, \ find_stake_program_address, \ find_transient_stake_program_address, \ - find_withdraw_authority_program_address + find_withdraw_authority_program_address, \ + find_metadata_account from stake_pool.state import STAKE_POOL_LAYOUT, ValidatorList, Fee, StakePool import stake_pool.instructions as sp @@ -589,3 +591,65 @@ async def decrease_validator_stake( signers = [payer, staker] if payer != staker else [payer] await client.send_transaction( txn, *signers, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + + +async def create_token_metadata(client: AsyncClient, payer: Keypair, stake_pool_address: PublicKey, + name: str, symbol: str, uri: str): + resp = await client.get_account_info(stake_pool_address, commitment=Confirmed) + data = resp['result']['value']['data'] + stake_pool = StakePool.decode(data[0], data[1]) + + (withdraw_authority, _seed) = find_withdraw_authority_program_address(STAKE_POOL_PROGRAM_ID, stake_pool_address) + (token_metadata, _seed) = find_metadata_account(stake_pool.pool_mint) + + txn = Transaction() + txn.add( + sp.create_token_metadata( + sp.CreateTokenMetadataParams( + program_id=STAKE_POOL_PROGRAM_ID, + stake_pool=stake_pool_address, + manager=stake_pool.manager, + pool_mint=stake_pool.pool_mint, + payer=payer.public_key, + name=name, + symbol=symbol, + uri=uri, + withdraw_authority=withdraw_authority, + token_metadata=token_metadata, + metadata_program_id=METADATA_PROGRAM_ID, + system_program_id=sys.SYS_PROGRAM_ID, + ) + ) + ) + + await client.send_transaction(txn, payer, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + + +async def update_token_metadata(client: AsyncClient, payer: Keypair, stake_pool_address: PublicKey, + name: str, symbol: str, uri: str): + resp = await client.get_account_info(stake_pool_address, commitment=Confirmed) + data = resp['result']['value']['data'] + stake_pool = StakePool.decode(data[0], data[1]) + + (withdraw_authority, _seed) = find_withdraw_authority_program_address(STAKE_POOL_PROGRAM_ID, stake_pool_address) + (token_metadata, _seed) = find_metadata_account(stake_pool.pool_mint) + + txn = Transaction() + txn.add( + sp.update_token_metadata( + sp.UpdateTokenMetadataParams( + program_id=STAKE_POOL_PROGRAM_ID, + stake_pool=stake_pool_address, + manager=stake_pool.manager, + pool_mint=stake_pool.pool_mint, + name=name, + symbol=symbol, + uri=uri, + withdraw_authority=withdraw_authority, + token_metadata=token_metadata, + metadata_program_id=METADATA_PROGRAM_ID, + ) + ) + ) + + await client.send_transaction(txn, payer, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) diff --git a/clients/py/stake_pool/constants.py b/clients/py/stake_pool/constants.py index 7e0be876..766a0d2d 100644 --- a/clients/py/stake_pool/constants.py +++ b/clients/py/stake_pool/constants.py @@ -17,6 +17,9 @@ MINIMUM_ACTIVE_STAKE: int = MINIMUM_DELEGATION """Minimum active delegated staked required in a stake account""" +METADATA_PROGRAM_ID: PublicKey = PublicKey("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s") +"""Public key that identifies the Metaplex Token Metadata program.""" + def find_deposit_authority_program_address( program_id: PublicKey, @@ -75,9 +78,25 @@ def find_transient_stake_program_address( ) +def find_metadata_account( + mint_key: PublicKey +) -> Tuple[PublicKey, int]: + """Generates the metadata account program address""" + return PublicKey.find_program_address( + [ + METADATA_SEED_PREFIX, + bytes(METADATA_PROGRAM_ID), + bytes(mint_key) + ], + METADATA_PROGRAM_ID + ) + + AUTHORITY_DEPOSIT = b"deposit" """Seed used to derive the default stake pool deposit authority.""" AUTHORITY_WITHDRAW = b"withdraw" """Seed used to derive the stake pool withdraw authority.""" TRANSIENT_STAKE_SEED_PREFIX = b"transient" """Seed used to derive transient stake accounts.""" +METADATA_SEED_PREFIX = b"metadata" +"""Seed used to avoid certain collision attacks.""" diff --git a/clients/py/stake_pool/instructions.py b/clients/py/stake_pool/instructions.py index 0ecfea60..cb52bd7f 100644 --- a/clients/py/stake_pool/instructions.py +++ b/clients/py/stake_pool/instructions.py @@ -2,7 +2,7 @@ from enum import IntEnum from typing import List, NamedTuple, Optional -from construct import Struct, Switch, Int8ul, Int32ul, Int64ul, Pass # type: ignore +from construct import Prefixed, GreedyString, Struct, Switch, Int8ul, Int32ul, Int64ul, Pass # type: ignore from solana.publickey import PublicKey from solana.transaction import AccountMeta, TransactionInstruction @@ -448,6 +448,65 @@ class WithdrawSolParams(NamedTuple): """`[s]` (Optional) Stake pool sol withdraw authority.""" +class CreateTokenMetadataParams(NamedTuple): + """Create token metadata for the stake-pool token in the metaplex-token program.""" + + # Accounts + program_id: PublicKey + """SPL Stake Pool program account.""" + stake_pool: PublicKey + """`[]` Stake pool.""" + manager: PublicKey + """`[s]` Manager.""" + withdraw_authority: PublicKey + """`[]` Stake pool withdraw authority.""" + pool_mint: PublicKey + """`[]` Pool token mint account.""" + payer: PublicKey + """`[s, w]` Payer for creation of token metadata account.""" + token_metadata: PublicKey + """`[w]` Token metadata program account.""" + metadata_program_id: PublicKey + """`[]` Metadata program id""" + system_program_id: PublicKey + """`[]` System program id""" + + # Params + name: str + """Token name.""" + symbol: str + """Token symbol e.g. stkSOL.""" + uri: str + """URI of the uploaded metadata of the spl-token.""" + + +class UpdateTokenMetadataParams(NamedTuple): + """Update token metadata for the stake-pool token in the metaplex-token program.""" + # Accounts + program_id: PublicKey + """SPL Stake Pool program account.""" + stake_pool: PublicKey + """`[]` Stake pool.""" + manager: PublicKey + """`[s]` Manager.""" + withdraw_authority: PublicKey + """`[]` Stake pool withdraw authority.""" + pool_mint: PublicKey + """`[]` Pool token mint account.""" + token_metadata: PublicKey + """`[w]` Token metadata program account.""" + metadata_program_id: PublicKey + """`[]` Metadata program id""" + + # Params + name: str + """Token name.""" + symbol: str + """Token symbol e.g. stkSOL.""" + uri: str + """URI of the uploaded metadata of the spl-token.""" + + class InstructionType(IntEnum): """Stake Pool Instruction Types.""" @@ -468,6 +527,8 @@ class InstructionType(IntEnum): DEPOSIT_SOL = 14 SET_FUNDING_AUTHORITY = 15 WITHDRAW_SOL = 16 + CREATE_TOKEN_METADATA = 17 + UPDATE_TOKEN_METADATA = 18 INITIALIZE_LAYOUT = Struct( @@ -496,6 +557,12 @@ class InstructionType(IntEnum): "seed" / Int32ul ) +TOKEN_METADATA_LAYOUT = Struct( + "name" / Prefixed(Int32ul, GreedyString("utf8")), + "symbol" / Prefixed(Int32ul, GreedyString("utf8")), + "uri" / Prefixed(Int32ul, GreedyString("utf8")) +) + INSTRUCTIONS_LAYOUT = Struct( "instruction_type" / Int8ul, "args" @@ -519,6 +586,8 @@ class InstructionType(IntEnum): InstructionType.DEPOSIT_SOL: AMOUNT_LAYOUT, InstructionType.SET_FUNDING_AUTHORITY: Pass, # TODO InstructionType.WITHDRAW_SOL: AMOUNT_LAYOUT, + InstructionType.CREATE_TOKEN_METADATA: TOKEN_METADATA_LAYOUT, + InstructionType.UPDATE_TOKEN_METADATA: TOKEN_METADATA_LAYOUT, }, ), ) @@ -917,3 +986,58 @@ def decrease_validator_stake(params: DecreaseValidatorStakeParams) -> Transactio ) ) ) + + +def create_token_metadata(params: CreateTokenMetadataParams) -> TransactionInstruction: + """Creates an instruction to create metadata using the mpl token metadata program for the pool token.""" + + keys = [ + AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.manager, is_signer=True, is_writable=False), + AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.pool_mint, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.payer, is_signer=True, is_writable=True), + AccountMeta(pubkey=params.token_metadata, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.metadata_program_id, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.system_program_id, is_signer=False, is_writable=False), + ] + return TransactionInstruction( + keys=keys, + program_id=params.program_id, + data=INSTRUCTIONS_LAYOUT.build( + dict( + instruction_type=InstructionType.CREATE_TOKEN_METADATA, + args={ + 'name': params.name, + 'symbol': params.symbol, + 'uri': params.uri + } + ) + ) + ) + + +def update_token_metadata(params: UpdateTokenMetadataParams) -> TransactionInstruction: + """Creates an instruction to update metadata in the mpl token metadata program account for the pool token.""" + + keys = [ + AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.manager, is_signer=True, is_writable=False), + AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.token_metadata, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.metadata_program_id, is_signer=False, is_writable=False) + ] + return TransactionInstruction( + keys=keys, + program_id=params.program_id, + data=INSTRUCTIONS_LAYOUT.build( + dict( + instruction_type=InstructionType.UPDATE_TOKEN_METADATA, + args={ + "name": params.name, + "symbol": params.symbol, + "uri": params.uri + } + ) + ) + ) diff --git a/clients/py/tests/conftest.py b/clients/py/tests/conftest.py index df80f807..24212678 100644 --- a/clients/py/tests/conftest.py +++ b/clients/py/tests/conftest.py @@ -33,6 +33,8 @@ def solana_test_validator(): "--reset", "--quiet", "--bpf-program", "SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy", f"{old_cwd}/../../target/deploy/spl_stake_pool.so", + "--bpf-program", "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s", + f"{old_cwd}/../program/tests/fixtures/mpl_token_metadata.so", "--slots-per-epoch", str(NUM_SLOTS_PER_EPOCH), ],) yield diff --git a/clients/py/tests/test_create_update_token_metadata.py b/clients/py/tests/test_create_update_token_metadata.py new file mode 100644 index 00000000..10ae24f6 --- /dev/null +++ b/clients/py/tests/test_create_update_token_metadata.py @@ -0,0 +1,67 @@ +import pytest +from stake_pool.actions import create_all, create_token_metadata, update_token_metadata +from stake_pool.state import Fee, StakePool +from solana.rpc.commitment import Confirmed +from solana.rpc.async_api import AsyncClient +from solana.keypair import Keypair +from stake_pool.constants import find_metadata_account +from solana.utils.helpers import decode_byte_string + + +@pytest.mark.asyncio +async def test_create_metadata_success(async_client: AsyncClient, payer: Keypair): + fee = Fee(numerator=1, denominator=1000) + referral_fee = 20 + (stake_pool_address, _validator_list_address, _) = await create_all(async_client, payer, fee, referral_fee) + resp = await async_client.get_account_info(stake_pool_address, commitment=Confirmed) + data = resp['result']['value']['data'] + stake_pool = StakePool.decode(data[0], data[1]) + + name = "test_name" + symbol = "SYM" + uri = "test_uri" + await create_token_metadata(async_client, payer, stake_pool_address, name, symbol, uri) + + (metadata_program_address, _seed) = find_metadata_account(stake_pool.pool_mint) + resp = await async_client.get_account_info(metadata_program_address, commitment=Confirmed) + data = resp['result']['value']['data'] + raw_data = decode_byte_string(data[0], data[1]) + assert name == str(raw_data[69:101], "utf-8")[:len(name)] + assert symbol == str(raw_data[105:115], "utf-8")[:len(symbol)] + assert uri == str(raw_data[119:319], "utf-8")[:len(uri)] + + +@pytest.mark.asyncio +async def test_update_metadata_success(async_client: AsyncClient, payer: Keypair): + fee = Fee(numerator=1, denominator=1000) + referral_fee = 20 + (stake_pool_address, _validator_list_address, _) = await create_all(async_client, payer, fee, referral_fee) + resp = await async_client.get_account_info(stake_pool_address, commitment=Confirmed) + data = resp['result']['value']['data'] + stake_pool = StakePool.decode(data[0], data[1]) + + name = "test_name" + symbol = "SYM" + uri = "test_uri" + await create_token_metadata(async_client, payer, stake_pool_address, name, symbol, uri) + + (metadata_program_address, _seed) = find_metadata_account(stake_pool.pool_mint) + resp = await async_client.get_account_info(metadata_program_address, commitment=Confirmed) + data = resp['result']['value']['data'] + raw_data = decode_byte_string(data[0], data[1]) + assert name == str(raw_data[69:101], "utf-8")[:len(name)] + assert symbol == str(raw_data[105:115], "utf-8")[:len(symbol)] + assert uri == str(raw_data[119:319], "utf-8")[:len(uri)] + + updated_name = "updated_name" + updated_symbol = "USM" + updated_uri = "updated_uri" + await update_token_metadata(async_client, payer, stake_pool_address, updated_name, updated_symbol, updated_uri) + + (metadata_program_address, _seed) = find_metadata_account(stake_pool.pool_mint) + resp = await async_client.get_account_info(metadata_program_address, commitment=Confirmed) + data = resp['result']['value']['data'] + raw_data = decode_byte_string(data[0], data[1]) + assert updated_name == str(raw_data[69:101], "utf-8")[:len(updated_name)] + assert updated_symbol == str(raw_data[105:115], "utf-8")[:len(updated_symbol)] + assert updated_uri == str(raw_data[119:319], "utf-8")[:len(updated_uri)] From a060a9b878404f4238c47b7131ff22942c0ad372 Mon Sep 17 00:00:00 2001 From: hana <81144685+2501babe@users.noreply.github.com> Date: Fri, 17 Mar 2023 01:07:38 -0700 Subject: [PATCH 0313/1076] stake pool: dont pass unnecessary program infos (#4090) --- program/src/processor.rs | 63 +++++++--------------------------------- 1 file changed, 10 insertions(+), 53 deletions(-) diff --git a/program/src/processor.rs b/program/src/processor.rs index b68d5616..db28f118 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -339,17 +339,16 @@ fn check_transient_stake_account( fn create_stake_account<'a>( stake_account_info: AccountInfo<'a>, stake_account_signer_seeds: &[&[u8]], - system_program_info: AccountInfo<'a>, stake_space: usize, ) -> Result<(), ProgramError> { invoke_signed( &system_instruction::allocate(stake_account_info.key, stake_space as u64), - &[stake_account_info.clone(), system_program_info.clone()], + &[stake_account_info.clone()], &[stake_account_signer_seeds], )?; invoke_signed( &system_instruction::assign(stake_account_info.key, &stake::program::id()), - &[stake_account_info, system_program_info], + &[stake_account_info], &[stake_account_signer_seeds], ) } @@ -446,7 +445,6 @@ impl Processor { destination_account: AccountInfo<'a>, clock: AccountInfo<'a>, stake_history: AccountInfo<'a>, - stake_program_info: AccountInfo<'a>, ) -> Result<(), ProgramError> { let authority_signature_seeds = [stake_pool.as_ref(), authority_type, &[bump_seed]]; let signers = &[&authority_signature_seeds[..]]; @@ -462,7 +460,6 @@ impl Processor { clock, stake_history, authority, - stake_program_info, ], signers, ) @@ -474,7 +471,6 @@ impl Processor { stake_authority: AccountInfo<'a>, new_stake_authority: &Pubkey, clock: AccountInfo<'a>, - stake_program_info: AccountInfo<'a>, ) -> Result<(), ProgramError> { let authorize_instruction = stake::instruction::authorize( stake_account.key, @@ -490,7 +486,6 @@ impl Processor { stake_account.clone(), clock.clone(), stake_authority.clone(), - stake_program_info.clone(), ], )?; @@ -504,7 +499,7 @@ impl Processor { invoke( &authorize_instruction, - &[stake_account, clock, stake_authority, stake_program_info], + &[stake_account, clock, stake_authority], ) } @@ -518,7 +513,6 @@ impl Processor { bump_seed: u8, new_stake_authority: &Pubkey, clock: AccountInfo<'a>, - stake_program_info: AccountInfo<'a>, ) -> Result<(), ProgramError> { let authority_signature_seeds = [stake_pool.as_ref(), authority_type, &[bump_seed]]; let signers = &[&authority_signature_seeds[..]]; @@ -537,7 +531,6 @@ impl Processor { stake_account.clone(), clock.clone(), stake_authority.clone(), - stake_program_info.clone(), ], signers, )?; @@ -551,7 +544,7 @@ impl Processor { ); invoke_signed( &authorize_instruction, - &[stake_account, clock, stake_authority, stake_program_info], + &[stake_account, clock, stake_authority], signers, ) } @@ -567,7 +560,6 @@ impl Processor { destination_account: AccountInfo<'a>, clock: AccountInfo<'a>, stake_history: AccountInfo<'a>, - stake_program_info: AccountInfo<'a>, lamports: u64, ) -> Result<(), ProgramError> { let authority_signature_seeds = [stake_pool.as_ref(), authority_type, &[bump_seed]]; @@ -590,7 +582,6 @@ impl Processor { clock, stake_history, authority, - stake_program_info, ], signers, ) @@ -649,7 +640,7 @@ impl Processor { amount, )?; - invoke(&ix, &[burn_account, mint, authority, token_program]) + invoke(&ix, &[burn_account, mint, authority]) } /// Issue a spl_token `MintTo` instruction. @@ -676,7 +667,7 @@ impl Processor { amount, )?; - invoke_signed(&ix, &[mint, destination, authority, token_program], signers) + invoke_signed(&ix, &[mint, destination, authority], signers) } /// Issue a spl_token `Transfer` instruction. @@ -700,17 +691,16 @@ impl Processor { amount, decimals, )?; - invoke(&ix, &[source, mint, destination, authority, token_program]) + invoke(&ix, &[source, mint, destination, authority]) } fn sol_transfer<'a>( source: AccountInfo<'a>, destination: AccountInfo<'a>, - system_program: AccountInfo<'a>, amount: u64, ) -> Result<(), ProgramError> { let ix = solana_program::system_instruction::transfer(source.key, destination.key, amount); - invoke(&ix, &[source, destination, system_program]) + invoke(&ix, &[source, destination]) } /// Processes `Initialize` instruction. @@ -1058,12 +1048,7 @@ impl Processor { } // Create new stake account - create_stake_account( - stake_info.clone(), - stake_account_signer_seeds, - system_program_info.clone(), - stake_space, - )?; + create_stake_account(stake_info.clone(), stake_account_signer_seeds, stake_space)?; // split into validator stake account Self::stake_split( stake_pool_info.key, @@ -1388,7 +1373,6 @@ impl Processor { create_stake_account( ephemeral_stake_account_info.clone(), ephemeral_stake_account_signer_seeds, - system_program_info.clone(), stake_space, )?; @@ -1440,7 +1424,6 @@ impl Processor { transient_stake_account_info.clone(), clock_info.clone(), stake_history_info.clone(), - stake_program_info.clone(), )?; } else { let transient_stake_account_signer_seeds: &[&[_]] = &[ @@ -1454,7 +1437,6 @@ impl Processor { create_stake_account( transient_stake_account_info.clone(), transient_stake_account_signer_seeds, - system_program_info.clone(), stake_space, )?; @@ -1666,7 +1648,6 @@ impl Processor { create_stake_account( ephemeral_stake_account_info.clone(), ephemeral_stake_account_signer_seeds, - system_program_info.clone(), stake_space, )?; @@ -1720,7 +1701,6 @@ impl Processor { transient_stake_account_info.clone(), clock_info.clone(), stake_history_info.clone(), - stake_program_info.clone(), )?; } else { // no transient stake, split @@ -1735,7 +1715,6 @@ impl Processor { create_stake_account( transient_stake_account_info.clone(), transient_stake_account_signer_seeds, - system_program_info.clone(), stake_space, )?; @@ -1947,7 +1926,6 @@ impl Processor { create_stake_account( source_transient_stake_account_info.clone(), source_transient_stake_account_signer_seeds, - system_program_info.clone(), stake_space, )?; @@ -1979,7 +1957,6 @@ impl Processor { create_stake_account( ephemeral_stake_account_info.clone(), ephemeral_stake_account_signer_seeds, - system_program_info.clone(), stake_space, )?; Self::stake_redelegate( @@ -2063,7 +2040,6 @@ impl Processor { destination_transient_stake_account_info.clone(), clock_info.clone(), stake_history_info.clone(), - stake_program_info.clone(), )?; } else { // otherwise, create the new account and split into it @@ -2084,7 +2060,6 @@ impl Processor { create_stake_account( destination_transient_stake_account_info.clone(), destination_transient_stake_account_signer_seeds, - system_program_info.clone(), stake_space, )?; Self::stake_split( @@ -2292,7 +2267,6 @@ impl Processor { reserve_stake_info.clone(), clock_info.clone(), stake_history_info.clone(), - stake_program_info.clone(), )?; validator_stake_record.status.remove_transient_stake(); } @@ -2317,7 +2291,6 @@ impl Processor { reserve_stake_info.clone(), clock_info.clone(), stake_history_info.clone(), - stake_program_info.clone(), )?; validator_stake_record.status.remove_transient_stake(); } else if stake.delegation.activation_epoch < clock.epoch { @@ -2334,7 +2307,6 @@ impl Processor { validator_stake_info.clone(), clock_info.clone(), stake_history_info.clone(), - stake_program_info.clone(), )?; } else { msg!("Stake activating or just active, not ready to merge"); @@ -2385,7 +2357,6 @@ impl Processor { reserve_stake_info.clone(), clock_info.clone(), stake_history_info.clone(), - stake_program_info.clone(), additional_lamports, )?; } @@ -2413,7 +2384,6 @@ impl Processor { reserve_stake_info.clone(), clock_info.clone(), stake_history_info.clone(), - stake_program_info.clone(), )?; validator_stake_record.status.remove_validator_stake(); } @@ -2443,7 +2413,6 @@ impl Processor { reserve_stake_info.clone(), clock_info.clone(), stake_history_info.clone(), - stake_program_info.clone(), )?; validator_stake_record.status.remove_validator_stake(); } @@ -2726,7 +2695,6 @@ impl Processor { deposit_bump_seed, withdraw_authority_info.key, clock_info.clone(), - stake_program_info.clone(), )?; } else { Self::stake_authorize( @@ -2734,7 +2702,6 @@ impl Processor { stake_deposit_authority_info.clone(), withdraw_authority_info.key, clock_info.clone(), - stake_program_info.clone(), )?; } @@ -2747,7 +2714,6 @@ impl Processor { validator_stake_account_info.clone(), clock_info.clone(), stake_history_info.clone(), - stake_program_info.clone(), )?; let (_, post_validator_stake) = get_stake_state(validator_stake_account_info)?; @@ -2862,7 +2828,6 @@ impl Processor { reserve_stake_account_info.clone(), clock_info.clone(), stake_history_info.clone(), - stake_program_info.clone(), sol_deposit_lamports, )?; } @@ -2979,7 +2944,6 @@ impl Processor { Self::sol_transfer( from_user_lamports_info.clone(), reserve_stake_account_info.clone(), - system_program_info.clone(), deposit_lamports, )?; @@ -3286,7 +3250,6 @@ impl Processor { stake_pool.stake_withdraw_bump_seed, user_stake_authority_info.key, clock_info.clone(), - stake_program_info.clone(), )?; if pool_tokens_fee > 0 { @@ -3476,7 +3439,6 @@ impl Processor { destination_lamports_info.clone(), clock_info.clone(), stake_history_info.clone(), - stake_program_info.clone(), withdraw_lamports, )?; @@ -3575,7 +3537,6 @@ impl Processor { payer_info.clone(), withdraw_authority_info.clone(), system_program_info.clone(), - mpl_token_metadata_program_info.clone(), ], &[token_mint_authority_signer_seeds], )?; @@ -3648,11 +3609,7 @@ impl Processor { invoke_signed( &update_metadata_accounts_instruction, - &[ - metadata_info.clone(), - withdraw_authority_info.clone(), - mpl_token_metadata_program_info.clone(), - ], + &[metadata_info.clone(), withdraw_authority_info.clone()], &[token_mint_authority_signer_seeds], )?; From 5f92980c1dcabef0bb56d5eca1231d94b48565f6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 May 2023 14:05:48 +0200 Subject: [PATCH 0314/1076] build(deps): bump terser from 5.10.0 to 5.17.1 in /stake-pool/js (#4153) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 147 +++++++++++++++++----------- 1 file changed, 92 insertions(+), 55 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 25ae2a8e..f837a703 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1041,29 +1041,62 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.4.tgz", - "integrity": "sha512-cz8HFjOFfUBtvN+NXYSFMHYRdxZMaEl0XypVrhzxBgadKIXhIkRd8aMeHhmF56Sl7SuS8OnUpQ73/k9LE4VnLg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", "dev": true, "engines": { "node": ">=6.0.0" } }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.3.tgz", + "integrity": "sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.10", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.10.tgz", - "integrity": "sha512-Ht8wIW5v165atIX1p+JvKR5ONzUyF4Ac8DZIQ5kZs9zrb6M8SJNXpx1zn04rn65VjBMygRoMXcyYwNK0fT7bEg==", + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", - "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", + "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, "node_modules/@nodelib/fs.scandir": { @@ -5732,13 +5765,14 @@ } }, "node_modules/terser": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.10.0.tgz", - "integrity": "sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA==", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.1.tgz", + "integrity": "sha512-hVl35zClmpisy6oaoKALOpS0rDYLxRFLHhRuDlEGTKey9qHjS1w9GMORjuwIMt70Wan4lwsLYyWDVnWgF+KUEw==", "dev": true, "dependencies": { + "@jridgewell/source-map": "^0.3.2", + "acorn": "^8.5.0", "commander": "^2.20.0", - "source-map": "~0.7.2", "source-map-support": "~0.5.20" }, "bin": { @@ -5746,23 +5780,6 @@ }, "engines": { "node": ">=10" - }, - "peerDependencies": { - "acorn": "^8.5.0" - }, - "peerDependenciesMeta": { - "acorn": { - "optional": true - } - } - }, - "node_modules/terser/node_modules/source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true, - "engines": { - "node": ">= 8" } }, "node_modules/test-exclude": { @@ -7016,26 +7033,53 @@ "chalk": "^4.0.0" } }, + "@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, "@jridgewell/resolve-uri": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.4.tgz", - "integrity": "sha512-cz8HFjOFfUBtvN+NXYSFMHYRdxZMaEl0XypVrhzxBgadKIXhIkRd8aMeHhmF56Sl7SuS8OnUpQ73/k9LE4VnLg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", "dev": true }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true + }, + "@jridgewell/source-map": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.3.tgz", + "integrity": "sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, "@jridgewell/sourcemap-codec": { - "version": "1.4.10", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.10.tgz", - "integrity": "sha512-Ht8wIW5v165atIX1p+JvKR5ONzUyF4Ac8DZIQ5kZs9zrb6M8SJNXpx1zn04rn65VjBMygRoMXcyYwNK0fT7bEg==", + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", "dev": true }, "@jridgewell/trace-mapping": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", - "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", + "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", "dev": true, "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, "@nodelib/fs.scandir": { @@ -10546,22 +10590,15 @@ } }, "terser": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.10.0.tgz", - "integrity": "sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA==", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.1.tgz", + "integrity": "sha512-hVl35zClmpisy6oaoKALOpS0rDYLxRFLHhRuDlEGTKey9qHjS1w9GMORjuwIMt70Wan4lwsLYyWDVnWgF+KUEw==", "dev": true, "requires": { + "@jridgewell/source-map": "^0.3.2", + "acorn": "^8.5.0", "commander": "^2.20.0", - "source-map": "~0.7.2", "source-map-support": "~0.5.20" - }, - "dependencies": { - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true - } } }, "test-exclude": { From 5ce104df5dfb4e7b3fdce98d9e5c54fe9ecc9757 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 May 2023 13:31:57 +0200 Subject: [PATCH 0315/1076] build(deps): bump num_enum from 0.5.9 to 0.6.1 (#4156) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index d28326fe..56176146 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,7 +17,7 @@ borsh = "0.9" mpl-token-metadata = { version = "1.7.0", features = [ "no-entrypoint" ] } num-derive = "0.3" num-traits = "0.2" -num_enum = "0.5.9" +num_enum = "0.6.1" serde = "1.0.130" serde_derive = "1.0.103" solana-program = "1.14.12" From ff393704fc0d51f369d102f886953dc58ba71aab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 May 2023 22:45:12 +0200 Subject: [PATCH 0316/1076] build(deps-dev): bump prettier from 2.5.1 to 2.8.8 in /stake-pool/js (#4172) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index f837a703..1581c97c 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -5092,15 +5092,18 @@ } }, "node_modules/prettier": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz", - "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==", + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true, "bin": { "prettier": "bin-prettier.js" }, "engines": { "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" } }, "node_modules/prettier-linter-helpers": { @@ -10109,9 +10112,9 @@ "dev": true }, "prettier": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz", - "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==", + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true }, "prettier-linter-helpers": { From 494038cc78f244e978763a6528f65318063c3673 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 May 2023 22:46:20 +0200 Subject: [PATCH 0317/1076] build(deps-dev): bump @rollup/plugin-node-resolve from 13.1.3 to 15.0.2 in /stake-pool/js (#4175) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 184 +++++++++++++++++++--------- clients/js-legacy/package.json | 2 +- 2 files changed, 128 insertions(+), 58 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 1581c97c..de9ce9bb 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -21,7 +21,7 @@ "@rollup/plugin-commonjs": "^21.0.1", "@rollup/plugin-json": "^4.1.0", "@rollup/plugin-multi-entry": "^4.1.0", - "@rollup/plugin-node-resolve": "^13.1.3", + "@rollup/plugin-node-resolve": "^15.0.2", "@rollup/plugin-typescript": "^8.3.0", "@types/bn.js": "^5.1.0", "@types/jest": "^27.4.0", @@ -1214,25 +1214,58 @@ } }, "node_modules/@rollup/plugin-node-resolve": { - "version": "13.1.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.1.3.tgz", - "integrity": "sha512-BdxNk+LtmElRo5d06MGY4zoepyrXX1tkzX2hrnPEZ53k78GuOMWLqmJDGIIOPwVRIFZrLQOo+Yr6KtCuLIA0AQ==", + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.0.2.tgz", + "integrity": "sha512-Y35fRGUjC3FaurG722uhUuG8YHOJRJQbI6/CkbRkdPotSpDj9NtIN85z1zrcyDcCQIW4qp5mgG72U+gJ0TAFEg==", "dev": true, "dependencies": { - "@rollup/pluginutils": "^3.1.0", - "@types/resolve": "1.17.1", - "builtin-modules": "^3.1.0", + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", "deepmerge": "^4.2.2", + "is-builtin-module": "^3.2.1", "is-module": "^1.0.0", - "resolve": "^1.19.0" + "resolve": "^1.22.1" }, "engines": { - "node": ">= 10.0.0" + "node": ">=14.0.0" }, "peerDependencies": { - "rollup": "^2.42.0" + "rollup": "^2.78.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-node-resolve/node_modules/@rollup/pluginutils": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", + "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } } }, + "node_modules/@rollup/plugin-node-resolve/node_modules/@types/estree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", + "dev": true + }, "node_modules/@rollup/plugin-typescript": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-8.3.0.tgz", @@ -1568,13 +1601,10 @@ "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, "node_modules/@types/resolve": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", - "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", - "dev": true, - "dependencies": { - "@types/node": "*" - } + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "dev": true }, "node_modules/@types/stack-utils": { "version": "2.0.1", @@ -2245,9 +2275,9 @@ } }, "node_modules/builtin-modules": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", - "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", "dev": true, "engines": { "node": ">=6" @@ -3589,10 +3619,25 @@ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, + "node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "dependencies": { + "builtin-modules": "^3.3.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-core-module": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", - "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.0.tgz", + "integrity": "sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==", "dev": true, "dependencies": { "has": "^1.0.3" @@ -5234,12 +5279,12 @@ } }, "node_modules/resolve": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", - "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", + "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", "dev": true, "dependencies": { - "is-core-module": "^2.8.1", + "is-core-module": "^2.11.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -5315,9 +5360,9 @@ } }, "node_modules/rollup": { - "version": "2.67.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.67.2.tgz", - "integrity": "sha512-hoEiBWwZtf1QdK3jZIq59L0FJj4Fiv4RplCO4pvCRC86qsoFurWB4hKQIjoRf3WvJmk5UZ9b0y5ton+62fC7Tw==", + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", "dev": true, "bin": { "rollup": "dist/bin/rollup" @@ -7164,17 +7209,36 @@ } }, "@rollup/plugin-node-resolve": { - "version": "13.1.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.1.3.tgz", - "integrity": "sha512-BdxNk+LtmElRo5d06MGY4zoepyrXX1tkzX2hrnPEZ53k78GuOMWLqmJDGIIOPwVRIFZrLQOo+Yr6KtCuLIA0AQ==", + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.0.2.tgz", + "integrity": "sha512-Y35fRGUjC3FaurG722uhUuG8YHOJRJQbI6/CkbRkdPotSpDj9NtIN85z1zrcyDcCQIW4qp5mgG72U+gJ0TAFEg==", "dev": true, "requires": { - "@rollup/pluginutils": "^3.1.0", - "@types/resolve": "1.17.1", - "builtin-modules": "^3.1.0", + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", "deepmerge": "^4.2.2", + "is-builtin-module": "^3.2.1", "is-module": "^1.0.0", - "resolve": "^1.19.0" + "resolve": "^1.22.1" + }, + "dependencies": { + "@rollup/pluginutils": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", + "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", + "dev": true, + "requires": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + } + }, + "@types/estree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", + "dev": true + } } }, "@rollup/plugin-typescript": { @@ -7459,13 +7523,10 @@ "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, "@types/resolve": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", - "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", - "dev": true, - "requires": { - "@types/node": "*" - } + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "dev": true }, "@types/stack-utils": { "version": "2.0.1", @@ -7930,9 +7991,9 @@ } }, "builtin-modules": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", - "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", "dev": true }, "callsites": { @@ -8947,10 +9008,19 @@ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, + "is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "requires": { + "builtin-modules": "^3.3.0" + } + }, "is-core-module": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", - "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.0.tgz", + "integrity": "sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==", "dev": true, "requires": { "has": "^1.0.3" @@ -10206,12 +10276,12 @@ "dev": true }, "resolve": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", - "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", + "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", "dev": true, "requires": { - "is-core-module": "^2.8.1", + "is-core-module": "^2.11.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" } @@ -10261,9 +10331,9 @@ } }, "rollup": { - "version": "2.67.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.67.2.tgz", - "integrity": "sha512-hoEiBWwZtf1QdK3jZIq59L0FJj4Fiv4RplCO4pvCRC86qsoFurWB4hKQIjoRf3WvJmk5UZ9b0y5ton+62fC7Tw==", + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", "dev": true, "requires": { "fsevents": "~2.3.2" diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 418c854d..2eb6471d 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -56,7 +56,7 @@ "@rollup/plugin-commonjs": "^21.0.1", "@rollup/plugin-json": "^4.1.0", "@rollup/plugin-multi-entry": "^4.1.0", - "@rollup/plugin-node-resolve": "^13.1.3", + "@rollup/plugin-node-resolve": "^15.0.2", "@rollup/plugin-typescript": "^8.3.0", "@types/bn.js": "^5.1.0", "@types/jest": "^27.4.0", From 1497ec04980ec755ac153eb3bc22dbb2296c5a99 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 May 2023 22:53:48 +0200 Subject: [PATCH 0318/1076] build(deps): bump serde_json from 1.0.81 to 1.0.96 (#4186) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index d86ad3df..5f54dbac 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ borsh = "0.9" clap = "2.33.3" serde = "1.0.130" serde_derive = "1.0.130" -serde_json = "1.0.68" +serde_json = "1.0.96" solana-account-decoder = "=1.14.12" solana-clap-utils = "=1.14.12" solana-cli-config = "=1.14.12" From 3233790e9efa59e8e1e7aee382c626b38aa9e949 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 May 2023 22:53:57 +0200 Subject: [PATCH 0319/1076] build(deps): bump proptest from 1.0.0 to 1.1.0 (#4184) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 56176146..5080ec96 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -27,7 +27,7 @@ thiserror = "1.0" bincode = "1.3.1" [dev-dependencies] -proptest = "1.0" +proptest = "1.1" solana-program-test = "1.14.12" solana-sdk = "1.14.12" solana-vote-program = "1.14.12" From 59cf76d5f0776750336b930767ce6924c558d6e7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 6 May 2023 00:30:35 +0200 Subject: [PATCH 0320/1076] build(deps-dev): bump eslint from 8.8.0 to 8.40.0 in /stake-pool/js (#4188) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 491 ++++++++++++++++++++-------- 1 file changed, 358 insertions(+), 133 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index de9ce9bb..2f427457 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -643,33 +643,60 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", + "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, "node_modules/@eslint/eslintrc": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz", - "integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", + "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.2.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", + "espree": "^9.5.2", + "globals": "^13.19.0", + "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/eslintrc/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "node_modules/@eslint/js": { + "version": "8.40.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz", + "integrity": "sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==", "dev": true, "engines": { - "node": ">= 4" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@ethersproject/bytes": { @@ -726,19 +753,32 @@ } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.3.tgz", - "integrity": "sha512-3xSMlXHh03hCcCmFc0rbKp3Ivt2PFEJnQUJDDMTJQ2wkECZWdq4GePs2ctc5H8zV+cHPaq8k2vU8mrQjA6iHdQ==", + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", - "minimatch": "^3.0.4" + "minimatch": "^3.0.5" }, "engines": { "node": ">=10.10.0" } }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", @@ -1826,9 +1866,9 @@ "dev": true }, "node_modules/acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -2828,46 +2868,51 @@ } }, "node_modules/eslint": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.8.0.tgz", - "integrity": "sha512-H3KXAzQGBH1plhYS3okDix2ZthuYJlQQEGE5k0IKuEqUSiyu4AmxxlJ2MtTYeJ3xB4jDhcYCwGOg2TXYdnDXlQ==", - "dev": true, - "dependencies": { - "@eslint/eslintrc": "^1.0.5", - "@humanwhocodes/config-array": "^0.9.2", + "version": "8.40.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.40.0.tgz", + "integrity": "sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.0.3", + "@eslint/js": "8.40.0", + "@humanwhocodes/config-array": "^0.11.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.0", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.2.0", - "espree": "^9.3.0", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.0", + "eslint-visitor-keys": "^3.4.1", + "espree": "^9.5.2", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.6.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" @@ -2953,18 +2998,21 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.2.0.tgz", - "integrity": "sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", + "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.0.tgz", - "integrity": "sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", + "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", @@ -2972,6 +3020,9 @@ }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/estraverse": { @@ -2983,18 +3034,82 @@ "node": ">=4.0" } }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/espree": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.0.tgz", - "integrity": "sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ==", + "version": "9.5.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", + "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", "dev": true, "dependencies": { - "acorn": "^8.7.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^3.1.0" + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/esprima": { @@ -3011,9 +3126,9 @@ } }, "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -3380,9 +3495,9 @@ } }, "node_modules/globals": { - "version": "13.12.1", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz", - "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==", + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -3420,6 +3535,12 @@ "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", "dev": true }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -3700,6 +3821,15 @@ "node": ">=0.12.0" } }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-potential-custom-element-name": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", @@ -4468,6 +4598,16 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/js-sdsl": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz", + "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, "node_modules/js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", @@ -4818,9 +4958,9 @@ "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" }, "node_modules/minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "dependencies": { "brace-expansion": "^1.1.7" @@ -6090,12 +6230,6 @@ "uuid": "dist/bin/uuid" } }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, "node_modules/v8-to-istanbul": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", @@ -6319,6 +6453,18 @@ "engines": { "node": ">=10" } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } }, "dependencies": { @@ -6779,31 +6925,44 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^3.3.0" + } + }, + "@eslint-community/regexpp": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", + "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", + "dev": true + }, "@eslint/eslintrc": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz", - "integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", + "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.2.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", + "espree": "^9.5.2", + "globals": "^13.19.0", + "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - } } }, + "@eslint/js": { + "version": "8.40.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz", + "integrity": "sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==", + "dev": true + }, "@ethersproject/bytes": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.5.0.tgz", @@ -6828,16 +6987,22 @@ } }, "@humanwhocodes/config-array": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.3.tgz", - "integrity": "sha512-3xSMlXHh03hCcCmFc0rbKp3Ivt2PFEJnQUJDDMTJQ2wkECZWdq4GePs2ctc5H8zV+cHPaq8k2vU8mrQjA6iHdQ==", + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", - "minimatch": "^3.0.4" + "minimatch": "^3.0.5" } }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, "@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", @@ -7659,9 +7824,9 @@ "dev": true }, "acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", "dev": true }, "acorn-globals": { @@ -8420,52 +8585,57 @@ } }, "eslint": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.8.0.tgz", - "integrity": "sha512-H3KXAzQGBH1plhYS3okDix2ZthuYJlQQEGE5k0IKuEqUSiyu4AmxxlJ2MtTYeJ3xB4jDhcYCwGOg2TXYdnDXlQ==", - "dev": true, - "requires": { - "@eslint/eslintrc": "^1.0.5", - "@humanwhocodes/config-array": "^0.9.2", + "version": "8.40.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.40.0.tgz", + "integrity": "sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.0.3", + "@eslint/js": "8.40.0", + "@humanwhocodes/config-array": "^0.11.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.0", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.2.0", - "espree": "^9.3.0", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.0", + "eslint-visitor-keys": "^3.4.1", + "espree": "^9.5.2", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.6.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "dependencies": { "eslint-scope": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.0.tgz", - "integrity": "sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", + "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", "dev": true, "requires": { "esrecurse": "^4.3.0", @@ -8477,6 +8647,43 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } } } }, @@ -8524,20 +8731,20 @@ } }, "eslint-visitor-keys": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.2.0.tgz", - "integrity": "sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", + "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", "dev": true }, "espree": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.0.tgz", - "integrity": "sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ==", + "version": "9.5.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", + "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", "dev": true, "requires": { - "acorn": "^8.7.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^3.1.0" + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" } }, "esprima": { @@ -8547,9 +8754,9 @@ "dev": true }, "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "requires": { "estraverse": "^5.1.0" @@ -8837,9 +9044,9 @@ } }, "globals": { - "version": "13.12.1", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz", - "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==", + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -8865,6 +9072,12 @@ "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", "dev": true }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -9065,6 +9278,12 @@ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, "is-potential-custom-element-name": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", @@ -9671,6 +9890,12 @@ } } }, + "js-sdsl": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz", + "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==", + "dev": true + }, "js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", @@ -9943,9 +10168,9 @@ "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" }, "minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -10858,12 +11083,6 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, "v8-to-istanbul": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", @@ -11036,6 +11255,12 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true } } } From b966a579e27598c667c0cb30df74b647bff7c083 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 May 2023 17:04:55 +0200 Subject: [PATCH 0321/1076] build(deps): bump @solana/buffer-layout from 4.0.0 to 4.0.1 in /stake-pool/js (#4198) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 2f427457..2bbaaa82 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1375,9 +1375,9 @@ } }, "node_modules/@solana/buffer-layout": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.0.tgz", - "integrity": "sha512-lR0EMP2HC3+Mxwd4YcnZb0smnaDw7Bl2IQWZiTevRH5ZZBZn6VRWn3/92E3qdU4SSImJkA6IDHawOHAnx/qUvQ==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz", + "integrity": "sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==", "dependencies": { "buffer": "~6.0.3" }, @@ -7461,9 +7461,9 @@ } }, "@solana/buffer-layout": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.0.tgz", - "integrity": "sha512-lR0EMP2HC3+Mxwd4YcnZb0smnaDw7Bl2IQWZiTevRH5ZZBZn6VRWn3/92E3qdU4SSImJkA6IDHawOHAnx/qUvQ==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz", + "integrity": "sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==", "requires": { "buffer": "~6.0.3" } From fbb067ba6fa1c05e7ec4852d179410b2af78ef03 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 May 2023 17:05:20 +0200 Subject: [PATCH 0322/1076] build(deps-dev): bump rollup-plugin-dts from 4.1.0 to 4.2.3 in /stake-pool/js (#4199) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 103 +++++++++++++++++----------- 1 file changed, 63 insertions(+), 40 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 2bbaaa82..dae36420 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -55,12 +55,12 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", + "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", "dev": true, "dependencies": { - "@babel/highlight": "^7.16.7" + "@babel/highlight": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -279,9 +279,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", "dev": true, "engines": { "node": ">=6.9.0" @@ -311,12 +311,12 @@ } }, "node_modules/@babel/highlight": { - "version": "7.16.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", - "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.16.7", + "@babel/helper-validator-identifier": "^7.18.6", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -362,13 +362,13 @@ "node_modules/@babel/highlight/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, "engines": { "node": ">=0.8.0" @@ -377,7 +377,7 @@ "node_modules/@babel/highlight/node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, "engines": { "node": ">=4" @@ -5515,25 +5515,37 @@ } }, "node_modules/rollup-plugin-dts": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-4.1.0.tgz", - "integrity": "sha512-rriXIm3jdUiYeiAAd1Fv+x2AxK6Kq6IybB2Z/IdoAW95fb4uRUurYsEYKa8L1seedezDeJhy8cfo8FEL9aZzqg==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-4.2.3.tgz", + "integrity": "sha512-jlcpItqM2efqfIiKzDB/IKOS9E9fDvbkJSGw5GtK/PqPGS9eC3R3JKyw2VvpTktZA+TNgJRMu1NTv244aTUzzQ==", "dev": true, "dependencies": { - "magic-string": "^0.25.7" + "magic-string": "^0.26.6" }, "engines": { - "node": ">=v12.22.7" + "node": ">=v12.22.12" }, "funding": { "url": "https://github.com/sponsors/Swatinem" }, "optionalDependencies": { - "@babel/code-frame": "^7.16.0" + "@babel/code-frame": "^7.18.6" }, "peerDependencies": { "rollup": "^2.55", - "typescript": "~4.1 || ~4.2 || ~4.3 || ~4.4 || ~4.5" + "typescript": "^4.1" + } + }, + "node_modules/rollup-plugin-dts/node_modules/magic-string": { + "version": "0.26.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.7.tgz", + "integrity": "sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow==", + "dev": true, + "dependencies": { + "sourcemap-codec": "^1.4.8" + }, + "engines": { + "node": ">=12" } }, "node_modules/rollup-plugin-inject": { @@ -6478,12 +6490,12 @@ } }, "@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", + "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", "dev": true, "requires": { - "@babel/highlight": "^7.16.7" + "@babel/highlight": "^7.18.6" } }, "@babel/compat-data": { @@ -6650,9 +6662,9 @@ } }, "@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", "dev": true }, "@babel/helper-validator-option": { @@ -6673,12 +6685,12 @@ } }, "@babel/highlight": { - "version": "7.16.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", - "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.16.7", + "@babel/helper-validator-identifier": "^7.18.6", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -6715,19 +6727,19 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true }, "supports-color": { @@ -10565,13 +10577,24 @@ } }, "rollup-plugin-dts": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-4.1.0.tgz", - "integrity": "sha512-rriXIm3jdUiYeiAAd1Fv+x2AxK6Kq6IybB2Z/IdoAW95fb4uRUurYsEYKa8L1seedezDeJhy8cfo8FEL9aZzqg==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-4.2.3.tgz", + "integrity": "sha512-jlcpItqM2efqfIiKzDB/IKOS9E9fDvbkJSGw5GtK/PqPGS9eC3R3JKyw2VvpTktZA+TNgJRMu1NTv244aTUzzQ==", "dev": true, "requires": { - "@babel/code-frame": "^7.16.0", - "magic-string": "^0.25.7" + "@babel/code-frame": "^7.18.6", + "magic-string": "^0.26.6" + }, + "dependencies": { + "magic-string": { + "version": "0.26.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.7.tgz", + "integrity": "sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow==", + "dev": true, + "requires": { + "sourcemap-codec": "^1.4.8" + } + } } }, "rollup-plugin-inject": { From ed8e122721f45ea416d3818426f91b1adf10ec86 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 May 2023 17:50:24 +0200 Subject: [PATCH 0323/1076] build(deps-dev): bump @rollup/plugin-alias from 3.1.9 to 5.0.0 in /stake-pool/js (#4200) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 47 ++++++++++++++++++++++------- clients/js-legacy/package.json | 2 +- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index dae36420..4c4b4c03 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -17,7 +17,7 @@ "buffer": "^6.0.3" }, "devDependencies": { - "@rollup/plugin-alias": "^3.1.9", + "@rollup/plugin-alias": "^5.0.0", "@rollup/plugin-commonjs": "^21.0.1", "@rollup/plugin-json": "^4.1.0", "@rollup/plugin-multi-entry": "^4.1.0", @@ -1190,18 +1190,35 @@ } }, "node_modules/@rollup/plugin-alias": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-3.1.9.tgz", - "integrity": "sha512-QI5fsEvm9bDzt32k39wpOwZhVzRcL5ydcffUHMyLVaVaLeC70I8TJZ17F1z1eMoLu4E/UOcH9BWVkKpIKdrfiw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.0.0.tgz", + "integrity": "sha512-l9hY5chSCjuFRPsnRm16twWBiSApl2uYFLsepQYwtBuAxNMQ/1dJqADld40P0Jkqm65GRTLy/AC6hnpVebtLsA==", "dev": true, "dependencies": { - "slash": "^3.0.0" + "slash": "^4.0.0" }, "engines": { - "node": ">=8.0.0" + "node": ">=14.0.0" }, "peerDependencies": { - "rollup": "^1.20.0||^2.0.0" + "rollup": "^1.20.0||^2.0.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-alias/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@rollup/plugin-commonjs": { @@ -7343,12 +7360,20 @@ } }, "@rollup/plugin-alias": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-3.1.9.tgz", - "integrity": "sha512-QI5fsEvm9bDzt32k39wpOwZhVzRcL5ydcffUHMyLVaVaLeC70I8TJZ17F1z1eMoLu4E/UOcH9BWVkKpIKdrfiw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.0.0.tgz", + "integrity": "sha512-l9hY5chSCjuFRPsnRm16twWBiSApl2uYFLsepQYwtBuAxNMQ/1dJqADld40P0Jkqm65GRTLy/AC6hnpVebtLsA==", "dev": true, "requires": { - "slash": "^3.0.0" + "slash": "^4.0.0" + }, + "dependencies": { + "slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true + } } }, "@rollup/plugin-commonjs": { diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 2eb6471d..a824245b 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -52,7 +52,7 @@ "buffer": "^6.0.3" }, "devDependencies": { - "@rollup/plugin-alias": "^3.1.9", + "@rollup/plugin-alias": "^5.0.0", "@rollup/plugin-commonjs": "^21.0.1", "@rollup/plugin-json": "^4.1.0", "@rollup/plugin-multi-entry": "^4.1.0", From bf0a518424d1252972741fcf5f106923a78155c9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 May 2023 12:59:45 +0200 Subject: [PATCH 0324/1076] build(deps): bump serde from 1.0.152 to 1.0.162 (#4207) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 5f54dbac..a7ee9fc9 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "0.7.0" [dependencies] borsh = "0.9" clap = "2.33.3" -serde = "1.0.130" +serde = "1.0.162" serde_derive = "1.0.130" serde_json = "1.0.96" solana-account-decoder = "=1.14.12" diff --git a/program/Cargo.toml b/program/Cargo.toml index 5080ec96..05c909a1 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,7 +18,7 @@ mpl-token-metadata = { version = "1.7.0", features = [ "no-entrypoint" ] } num-derive = "0.3" num-traits = "0.2" num_enum = "0.6.1" -serde = "1.0.130" +serde = "1.0.162" serde_derive = "1.0.103" solana-program = "1.14.12" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } From a7b2b42463064f4e276179ffcbd93a58c0faba6f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 May 2023 15:53:59 +0200 Subject: [PATCH 0325/1076] build(deps-dev): bump @rollup/plugin-typescript from 8.3.0 to 11.1.0 in /stake-pool/js (#4218) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 83 ++++++++++++++++++++++++----- clients/js-legacy/package.json | 2 +- 2 files changed, 71 insertions(+), 14 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 4c4b4c03..f2cace6e 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -22,7 +22,7 @@ "@rollup/plugin-json": "^4.1.0", "@rollup/plugin-multi-entry": "^4.1.0", "@rollup/plugin-node-resolve": "^15.0.2", - "@rollup/plugin-typescript": "^8.3.0", + "@rollup/plugin-typescript": "^11.1.0", "@types/bn.js": "^5.1.0", "@types/jest": "^27.4.0", "@typescript-eslint/eslint-plugin": "^5.11.0", @@ -1324,23 +1324,59 @@ "dev": true }, "node_modules/@rollup/plugin-typescript": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-8.3.0.tgz", - "integrity": "sha512-I5FpSvLbtAdwJ+naznv+B4sjXZUcIvLLceYpITAn7wAP8W0wqc5noLdGIp9HGVntNhRWXctwPYrSSFQxtl0FPA==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.0.tgz", + "integrity": "sha512-86flrfE+bSHB69znnTV6kVjkncs2LBMhcTCyxWgRxLyfXfQrxg4UwlAqENnjrrxnSNS/XKCDJCl8EkdFJVHOxw==", "dev": true, "dependencies": { - "@rollup/pluginutils": "^3.1.0", - "resolve": "^1.17.0" + "@rollup/pluginutils": "^5.0.1", + "resolve": "^1.22.1" }, "engines": { - "node": ">=8.0.0" + "node": ">=14.0.0" }, "peerDependencies": { - "rollup": "^2.14.0", + "rollup": "^2.14.0||^3.0.0", "tslib": "*", "typescript": ">=3.7.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + }, + "tslib": { + "optional": true + } } }, + "node_modules/@rollup/plugin-typescript/node_modules/@rollup/pluginutils": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", + "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-typescript/node_modules/@types/estree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", + "dev": true + }, "node_modules/@rollup/plugin-virtual": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@rollup/plugin-virtual/-/plugin-virtual-2.0.3.tgz", @@ -6137,6 +6173,7 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", "dev": true, + "optional": true, "peer": true }, "node_modules/tsutils": { @@ -7444,13 +7481,32 @@ } }, "@rollup/plugin-typescript": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-8.3.0.tgz", - "integrity": "sha512-I5FpSvLbtAdwJ+naznv+B4sjXZUcIvLLceYpITAn7wAP8W0wqc5noLdGIp9HGVntNhRWXctwPYrSSFQxtl0FPA==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.0.tgz", + "integrity": "sha512-86flrfE+bSHB69znnTV6kVjkncs2LBMhcTCyxWgRxLyfXfQrxg4UwlAqENnjrrxnSNS/XKCDJCl8EkdFJVHOxw==", "dev": true, "requires": { - "@rollup/pluginutils": "^3.1.0", - "resolve": "^1.17.0" + "@rollup/pluginutils": "^5.0.1", + "resolve": "^1.22.1" + }, + "dependencies": { + "@rollup/pluginutils": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", + "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", + "dev": true, + "requires": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + } + }, + "@types/estree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", + "dev": true + } } }, "@rollup/plugin-virtual": { @@ -11042,6 +11098,7 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", "dev": true, + "optional": true, "peer": true }, "tsutils": { diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index a824245b..eff37c51 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -57,7 +57,7 @@ "@rollup/plugin-json": "^4.1.0", "@rollup/plugin-multi-entry": "^4.1.0", "@rollup/plugin-node-resolve": "^15.0.2", - "@rollup/plugin-typescript": "^8.3.0", + "@rollup/plugin-typescript": "^11.1.0", "@types/bn.js": "^5.1.0", "@types/jest": "^27.4.0", "@typescript-eslint/eslint-plugin": "^5.11.0", From b3f264579e713fb7caec7f90d9df2c1d2340d810 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 May 2023 15:54:28 +0200 Subject: [PATCH 0326/1076] build(deps-dev): bump eslint-plugin-prettier from 4.0.0 to 4.2.1 in /stake-pool/js (#4219) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index f2cace6e..c8ed530e 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -2990,15 +2990,15 @@ } }, "node_modules/eslint-plugin-prettier": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.0.0.tgz", - "integrity": "sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", + "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", "dev": true, "dependencies": { "prettier-linter-helpers": "^1.0.0" }, "engines": { - "node": ">=6.0.0" + "node": ">=12.0.0" }, "peerDependencies": { "eslint": ">=7.28.0", @@ -8788,9 +8788,9 @@ "requires": {} }, "eslint-plugin-prettier": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.0.0.tgz", - "integrity": "sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", + "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", "dev": true, "requires": { "prettier-linter-helpers": "^1.0.0" From 6d9351e6c99b80f0ec045039cda2fe40c9adfa2c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 May 2023 15:54:29 +0200 Subject: [PATCH 0327/1076] build(deps-dev): bump @rollup/plugin-json from 4.1.0 to 6.0.0 in /stake-pool/js (#4220) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 75 +++++++++++++++++++++++++---- clients/js-legacy/package.json | 2 +- 2 files changed, 66 insertions(+), 11 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index c8ed530e..917da7ee 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -19,7 +19,7 @@ "devDependencies": { "@rollup/plugin-alias": "^5.0.0", "@rollup/plugin-commonjs": "^21.0.1", - "@rollup/plugin-json": "^4.1.0", + "@rollup/plugin-json": "^6.0.0", "@rollup/plugin-multi-entry": "^4.1.0", "@rollup/plugin-node-resolve": "^15.0.2", "@rollup/plugin-typescript": "^11.1.0", @@ -1243,17 +1243,53 @@ } }, "node_modules/@rollup/plugin-json": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-4.1.0.tgz", - "integrity": "sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.0.0.tgz", + "integrity": "sha512-i/4C5Jrdr1XUarRhVu27EEwjt4GObltD7c+MkCIpO2QIbojw8MUs+CCTqOphQi3Qtg1FLmYt+l+6YeoIf51J7w==", "dev": true, "dependencies": { - "@rollup/pluginutils": "^3.0.8" + "@rollup/pluginutils": "^5.0.1" + }, + "engines": { + "node": ">=14.0.0" }, "peerDependencies": { - "rollup": "^1.20.0 || ^2.0.0" + "rollup": "^1.20.0||^2.0.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } } }, + "node_modules/@rollup/plugin-json/node_modules/@rollup/pluginutils": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", + "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-json/node_modules/@types/estree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", + "dev": true + }, "node_modules/@rollup/plugin-multi-entry": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-multi-entry/-/plugin-multi-entry-4.1.0.tgz", @@ -7429,12 +7465,31 @@ } }, "@rollup/plugin-json": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-4.1.0.tgz", - "integrity": "sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.0.0.tgz", + "integrity": "sha512-i/4C5Jrdr1XUarRhVu27EEwjt4GObltD7c+MkCIpO2QIbojw8MUs+CCTqOphQi3Qtg1FLmYt+l+6YeoIf51J7w==", "dev": true, "requires": { - "@rollup/pluginutils": "^3.0.8" + "@rollup/pluginutils": "^5.0.1" + }, + "dependencies": { + "@rollup/pluginutils": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", + "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", + "dev": true, + "requires": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + } + }, + "@types/estree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", + "dev": true + } } }, "@rollup/plugin-multi-entry": { diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index eff37c51..bafac374 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -54,7 +54,7 @@ "devDependencies": { "@rollup/plugin-alias": "^5.0.0", "@rollup/plugin-commonjs": "^21.0.1", - "@rollup/plugin-json": "^4.1.0", + "@rollup/plugin-json": "^6.0.0", "@rollup/plugin-multi-entry": "^4.1.0", "@rollup/plugin-node-resolve": "^15.0.2", "@rollup/plugin-typescript": "^11.1.0", From e90b011c7b9e90b9f5fafcbf608b218eab7b9c91 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 9 May 2023 19:26:08 +0200 Subject: [PATCH 0328/1076] borsh: Use `to_writer` API to serialize (#4228) --- program/src/big_vec.rs | 8 ++++---- program/src/processor.rs | 32 +++++++++++++++++--------------- program/src/state.rs | 8 ++++---- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/program/src/big_vec.rs b/program/src/big_vec.rs index 97d141bc..903bb966 100644 --- a/program/src/big_vec.rs +++ b/program/src/big_vec.rs @@ -3,7 +3,7 @@ use { arrayref::array_ref, - borsh::{BorshDeserialize, BorshSerialize}, + borsh::BorshDeserialize, solana_program::{ program_error::ProgramError, program_memory::sol_memmove, program_pack::Pack, }, @@ -79,7 +79,7 @@ impl<'data> BigVec<'data> { } let mut vec_len_ref = &mut self.data[0..VEC_SIZE_BYTES]; - vec_len.serialize(&mut vec_len_ref)?; + borsh::to_writer(&mut vec_len_ref, &vec_len)?; Ok(()) } @@ -116,7 +116,7 @@ impl<'data> BigVec<'data> { let end_index = start_index + T::LEN; vec_len += 1; - vec_len.serialize(&mut vec_len_ref)?; + borsh::to_writer(&mut vec_len_ref, &vec_len)?; if self.data.len() < end_index { return Err(ProgramError::AccountDataTooSmall); @@ -252,7 +252,7 @@ mod tests { const LEN: usize = 8; fn pack_into_slice(&self, data: &mut [u8]) { let mut data = data; - self.value.serialize(&mut data).unwrap(); + borsh::to_writer(&mut data, &self.value).unwrap(); } fn unpack_from_slice(src: &[u8]) -> Result { Ok(TestStruct { diff --git a/program/src/processor.rs b/program/src/processor.rs index db28f118..acc8164f 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -14,7 +14,7 @@ use { AUTHORITY_DEPOSIT, AUTHORITY_WITHDRAW, EPHEMERAL_STAKE_SEED_PREFIX, TRANSIENT_STAKE_SEED_PREFIX, }, - borsh::{BorshDeserialize, BorshSerialize}, + borsh::BorshDeserialize, mpl_token_metadata::{ instruction::{create_metadata_accounts_v3, update_metadata_accounts_v2}, pda::find_metadata_account, @@ -901,7 +901,10 @@ impl Processor { )?; } - validator_list.serialize(&mut *validator_list_info.data.borrow_mut())?; + borsh::to_writer( + &mut validator_list_info.data.borrow_mut()[..], + &validator_list, + )?; stake_pool.account_type = AccountType::StakePool; stake_pool.manager = *manager_info.key; @@ -932,8 +935,7 @@ impl Processor { stake_pool.last_epoch_pool_token_supply = 0; stake_pool.last_epoch_total_lamports = 0; - stake_pool - .serialize(&mut *stake_pool_info.data.borrow_mut()) + borsh::to_writer(&mut stake_pool_info.data.borrow_mut()[..], &stake_pool) .map_err(|e| e.into()) } @@ -1216,7 +1218,7 @@ impl Processor { if stake_pool.preferred_withdraw_validator_vote_address == Some(vote_account_address) { stake_pool.preferred_withdraw_validator_vote_address = None; } - stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; + borsh::to_writer(&mut stake_pool_info.data.borrow_mut()[..], &stake_pool)?; Ok(()) } @@ -2136,7 +2138,7 @@ impl Processor { stake_pool.preferred_withdraw_validator_vote_address = vote_account_address } }; - stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; + borsh::to_writer(&mut stake_pool_info.data.borrow_mut()[..], &stake_pool)?; Ok(()) } @@ -2549,7 +2551,7 @@ impl Processor { let pool_mint = StateWithExtensions::::unpack(&pool_mint_data)?; stake_pool.pool_token_supply = pool_mint.base.supply; - stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; + borsh::to_writer(&mut stake_pool_info.data.borrow_mut()[..], &stake_pool)?; Ok(()) } @@ -2842,7 +2844,7 @@ impl Processor { .total_lamports .checked_add(total_deposit_lamports) .ok_or(StakePoolError::CalculationFailure)?; - stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; + borsh::to_writer(&mut stake_pool_info.data.borrow_mut()[..], &stake_pool)?; validator_stake_info.active_stake_lamports = validator_stake_account_info.lamports(); @@ -2992,7 +2994,7 @@ impl Processor { .total_lamports .checked_add(deposit_lamports) .ok_or(StakePoolError::CalculationFailure)?; - stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; + borsh::to_writer(&mut stake_pool_info.data.borrow_mut()[..], &stake_pool)?; Ok(()) } @@ -3272,7 +3274,7 @@ impl Processor { .total_lamports .checked_sub(withdraw_lamports) .ok_or(StakePoolError::CalculationFailure)?; - stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; + borsh::to_writer(&mut stake_pool_info.data.borrow_mut()[..], &stake_pool)?; if let Some((validator_list_item, withdraw_source)) = validator_list_item_info { match withdraw_source { @@ -3450,7 +3452,7 @@ impl Processor { .total_lamports .checked_sub(withdraw_lamports) .ok_or(StakePoolError::CalculationFailure)?; - stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; + borsh::to_writer(&mut stake_pool_info.data.borrow_mut()[..], &stake_pool)?; Ok(()) } @@ -3642,7 +3644,7 @@ impl Processor { stake_pool.manager = *new_manager_info.key; stake_pool.manager_fee_account = *new_manager_fee_info.key; - stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; + borsh::to_writer(&mut stake_pool_info.data.borrow_mut()[..], &stake_pool)?; Ok(()) } @@ -3671,7 +3673,7 @@ impl Processor { fee.check_too_high()?; stake_pool.update_fee(&fee)?; - stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; + borsh::to_writer(&mut stake_pool_info.data.borrow_mut()[..], &stake_pool)?; Ok(()) } @@ -3695,7 +3697,7 @@ impl Processor { return Err(StakePoolError::SignatureMissing.into()); } stake_pool.staker = *new_staker_info.key; - stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; + borsh::to_writer(&mut stake_pool_info.data.borrow_mut()[..], &stake_pool)?; Ok(()) } @@ -3729,7 +3731,7 @@ impl Processor { FundingType::SolDeposit => stake_pool.sol_deposit_authority = new_authority, FundingType::SolWithdraw => stake_pool.sol_withdraw_authority = new_authority, } - stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; + borsh::to_writer(&mut stake_pool_info.data.borrow_mut()[..], &stake_pool)?; Ok(()) } diff --git a/program/src/state.rs b/program/src/state.rs index e9d8b61f..4751a978 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -701,7 +701,7 @@ impl Pack for ValidatorStakeInfo { let mut data = data; // Removing this unwrap would require changing from `Pack` to some other // trait or `bytemuck`, so it stays in for now - self.serialize(&mut data).unwrap(); + borsh::to_writer(&mut data, self).unwrap(); } fn unpack_from_slice(src: &[u8]) -> Result { let unpacked = Self::try_from_slice(src)?; @@ -1043,7 +1043,7 @@ mod test { let stake_list = uninitialized_validator_list(); let mut byte_vec = vec![0u8; size]; let mut bytes = byte_vec.as_mut_slice(); - stake_list.serialize(&mut bytes).unwrap(); + borsh::to_writer(&mut bytes, &stake_list).unwrap(); let stake_list_unpacked = try_from_slice_unchecked::(&byte_vec).unwrap(); assert_eq!(stake_list_unpacked, stake_list); @@ -1057,7 +1057,7 @@ mod test { }; let mut byte_vec = vec![0u8; size]; let mut bytes = byte_vec.as_mut_slice(); - stake_list.serialize(&mut bytes).unwrap(); + borsh::to_writer(&mut bytes, &stake_list).unwrap(); let stake_list_unpacked = try_from_slice_unchecked::(&byte_vec).unwrap(); assert_eq!(stake_list_unpacked, stake_list); @@ -1065,7 +1065,7 @@ mod test { let stake_list = test_validator_list(max_validators); let mut byte_vec = vec![0u8; size]; let mut bytes = byte_vec.as_mut_slice(); - stake_list.serialize(&mut bytes).unwrap(); + borsh::to_writer(&mut bytes, &stake_list).unwrap(); let stake_list_unpacked = try_from_slice_unchecked::(&byte_vec).unwrap(); assert_eq!(stake_list_unpacked, stake_list); } From dee102ac03401659a29b2755df1d0d66ed925b82 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 May 2023 13:53:18 +0200 Subject: [PATCH 0329/1076] build(deps): bump arrayref from 0.3.6 to 0.3.7 (#4233) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 05c909a1..a6d30500 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -12,7 +12,7 @@ no-entrypoint = [] test-sbf = [] [dependencies] -arrayref = "0.3.6" +arrayref = "0.3.7" borsh = "0.9" mpl-token-metadata = { version = "1.7.0", features = [ "no-entrypoint" ] } num-derive = "0.3" From 8b7188280690aecddec53c920d56a96f670057ea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 May 2023 15:52:51 +0200 Subject: [PATCH 0330/1076] build(deps-dev): bump @typescript-eslint/parser from 5.11.0 to 5.59.5 in /stake-pool/js (#4242) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 169 +++++++++++++++++++++++----- 1 file changed, 143 insertions(+), 26 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 917da7ee..b81ae45f 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1798,15 +1798,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.11.0.tgz", - "integrity": "sha512-x0DCjetHZYBRovJdr3U0zG9OOdNXUaFLJ82ehr1AlkArljJuwEsgnud+Q7umlGDFLFrs8tU8ybQDFocp/eX8mQ==", + "version": "5.59.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.5.tgz", + "integrity": "sha512-NJXQC4MRnF9N9yWqQE2/KLRSOLvrrlZb48NGVfBa+RuPMN6B7ZcK5jZOvhuygv4D64fRKnZI4L4p8+M+rfeQuw==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.11.0", - "@typescript-eslint/types": "5.11.0", - "@typescript-eslint/typescript-estree": "5.11.0", - "debug": "^4.3.2" + "@typescript-eslint/scope-manager": "5.59.5", + "@typescript-eslint/types": "5.59.5", + "@typescript-eslint/typescript-estree": "5.59.5", + "debug": "^4.3.4" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1824,6 +1824,80 @@ } } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "5.59.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.5.tgz", + "integrity": "sha512-jVecWwnkX6ZgutF+DovbBJirZcAxgxC0EOHYt/niMROf8p4PwxxG32Qdhj/iIQQIuOflLjNkxoXyArkcIP7C3A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.5", + "@typescript-eslint/visitor-keys": "5.59.5" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "5.59.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.5.tgz", + "integrity": "sha512-xkfRPHbqSH4Ggx4eHRIO/eGL8XL4Ysb4woL8c87YuAo8Md7AUjyWKa9YMwTL519SyDPrfEgKdewjkxNCVeJW7w==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.59.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.5.tgz", + "integrity": "sha512-+XXdLN2CZLZcD/mO7mQtJMvCkzRfmODbeSKuMY/yXbGkzvA9rJyDY5qDYNoiz2kP/dmyAxXquL2BvLQLJFPQIg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.5", + "@typescript-eslint/visitor-keys": "5.59.5", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.59.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.5.tgz", + "integrity": "sha512-qL+Oz+dbeBRTeyJTIy0eniD3uvqU7x+y1QceBismZ41hd4aBSRh8UAw4pZP0+XzLuPZmx4raNMq/I+59W2lXKA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.5", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "5.11.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.11.0.tgz", @@ -2654,9 +2728,9 @@ } }, "node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -5803,9 +5877,9 @@ } }, "node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", + "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -7888,15 +7962,58 @@ } }, "@typescript-eslint/parser": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.11.0.tgz", - "integrity": "sha512-x0DCjetHZYBRovJdr3U0zG9OOdNXUaFLJ82ehr1AlkArljJuwEsgnud+Q7umlGDFLFrs8tU8ybQDFocp/eX8mQ==", + "version": "5.59.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.5.tgz", + "integrity": "sha512-NJXQC4MRnF9N9yWqQE2/KLRSOLvrrlZb48NGVfBa+RuPMN6B7ZcK5jZOvhuygv4D64fRKnZI4L4p8+M+rfeQuw==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.11.0", - "@typescript-eslint/types": "5.11.0", - "@typescript-eslint/typescript-estree": "5.11.0", - "debug": "^4.3.2" + "@typescript-eslint/scope-manager": "5.59.5", + "@typescript-eslint/types": "5.59.5", + "@typescript-eslint/typescript-estree": "5.59.5", + "debug": "^4.3.4" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "5.59.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.5.tgz", + "integrity": "sha512-jVecWwnkX6ZgutF+DovbBJirZcAxgxC0EOHYt/niMROf8p4PwxxG32Qdhj/iIQQIuOflLjNkxoXyArkcIP7C3A==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.5", + "@typescript-eslint/visitor-keys": "5.59.5" + } + }, + "@typescript-eslint/types": { + "version": "5.59.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.5.tgz", + "integrity": "sha512-xkfRPHbqSH4Ggx4eHRIO/eGL8XL4Ysb4woL8c87YuAo8Md7AUjyWKa9YMwTL519SyDPrfEgKdewjkxNCVeJW7w==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.59.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.5.tgz", + "integrity": "sha512-+XXdLN2CZLZcD/mO7mQtJMvCkzRfmODbeSKuMY/yXbGkzvA9rJyDY5qDYNoiz2kP/dmyAxXquL2BvLQLJFPQIg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.5", + "@typescript-eslint/visitor-keys": "5.59.5", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.59.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.5.tgz", + "integrity": "sha512-qL+Oz+dbeBRTeyJTIy0eniD3uvqU7x+y1QceBismZ41hd4aBSRh8UAw4pZP0+XzLuPZmx4raNMq/I+59W2lXKA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.5", + "eslint-visitor-keys": "^3.3.0" + } + } } }, "@typescript-eslint/scope-manager": { @@ -8504,9 +8621,9 @@ } }, "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -10857,9 +10974,9 @@ } }, "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", + "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", "dev": true, "requires": { "lru-cache": "^6.0.0" From e43ce30dae82f07766ea742f11854e582616bce5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 May 2023 15:53:33 +0200 Subject: [PATCH 0331/1076] build(deps-dev): bump eslint-config-prettier from 8.3.0 to 8.8.0 in /stake-pool/js (#4243) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index b81ae45f..8a2b10d6 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -3088,9 +3088,9 @@ } }, "node_modules/eslint-config-prettier": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz", - "integrity": "sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz", + "integrity": "sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==", "dev": true, "bin": { "eslint-config-prettier": "bin/cli.js" @@ -8953,9 +8953,9 @@ } }, "eslint-config-prettier": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz", - "integrity": "sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz", + "integrity": "sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==", "dev": true, "requires": {} }, From b9573d02f4ea359afe75b5783a089333bc574d4a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 May 2023 13:24:13 +0200 Subject: [PATCH 0332/1076] build(deps): bump serde from 1.0.162 to 1.0.163 (#4254) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index a7ee9fc9..50b0cff7 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "0.7.0" [dependencies] borsh = "0.9" clap = "2.33.3" -serde = "1.0.162" +serde = "1.0.163" serde_derive = "1.0.130" serde_json = "1.0.96" solana-account-decoder = "=1.14.12" diff --git a/program/Cargo.toml b/program/Cargo.toml index a6d30500..28e7f9a0 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,7 +18,7 @@ mpl-token-metadata = { version = "1.7.0", features = [ "no-entrypoint" ] } num-derive = "0.3" num-traits = "0.2" num_enum = "0.6.1" -serde = "1.0.162" +serde = "1.0.163" serde_derive = "1.0.103" solana-program = "1.14.12" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } From 04306c1147ee6a683d70528d5b9453c42c17eec7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 May 2023 17:49:48 +0200 Subject: [PATCH 0333/1076] build(deps-dev): bump @rollup/plugin-multi-entry from 4.1.0 to 6.0.0 in /stake-pool/js (#4263) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 53 ++++++++++++++++++----------- clients/js-legacy/package.json | 2 +- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 8a2b10d6..b7037bc4 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -20,7 +20,7 @@ "@rollup/plugin-alias": "^5.0.0", "@rollup/plugin-commonjs": "^21.0.1", "@rollup/plugin-json": "^6.0.0", - "@rollup/plugin-multi-entry": "^4.1.0", + "@rollup/plugin-multi-entry": "^6.0.0", "@rollup/plugin-node-resolve": "^15.0.2", "@rollup/plugin-typescript": "^11.1.0", "@types/bn.js": "^5.1.0", @@ -1291,19 +1291,24 @@ "dev": true }, "node_modules/@rollup/plugin-multi-entry": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-multi-entry/-/plugin-multi-entry-4.1.0.tgz", - "integrity": "sha512-nellK5pr50W0JA2+bDJbG8F79GBP802J40YRoC0wyfpTAeAn5mJ4eaFiB/MN+YoX9hgb/6RJoZl9leDjZnUFKw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-multi-entry/-/plugin-multi-entry-6.0.0.tgz", + "integrity": "sha512-msBgVncGQwh/ahxeP/rc8MXVZNBOjoVCsBuDk6uqyFzDv/SZN7jksfAsu6DJ2w4r5PaBX3/OXOjVPeCxya2waA==", "dev": true, "dependencies": { - "@rollup/plugin-virtual": "^2.0.3", - "matched": "^5.0.0" + "@rollup/plugin-virtual": "^3.0.0", + "matched": "^5.0.1" }, "engines": { - "node": ">=10.0.0" + "node": ">=14.0.0" }, "peerDependencies": { - "rollup": "^1.20.0 || ^2.0.0" + "rollup": "^1.20.0||^2.0.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } } }, "node_modules/@rollup/plugin-node-resolve": { @@ -1414,12 +1419,20 @@ "dev": true }, "node_modules/@rollup/plugin-virtual": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-virtual/-/plugin-virtual-2.0.3.tgz", - "integrity": "sha512-pw6ziJcyjZtntQ//bkad9qXaBx665SgEL8C8KI5wO8G5iU5MPxvdWrQyVaAvjojGm9tJoS8M9Z/EEepbqieYmw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-virtual/-/plugin-virtual-3.0.1.tgz", + "integrity": "sha512-fK8O0IL5+q+GrsMLuACVNk2x21g3yaw+sG2qn16SnUd3IlBsQyvWxLMGHmCmXRMecPjGRSZ/1LmZB4rjQm68og==", "dev": true, + "engines": { + "node": ">=14.0.0" + }, "peerDependencies": { - "rollup": "^1.20.0||^2.0.0" + "rollup": "^1.20.0||^2.0.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } } }, "node_modules/@rollup/pluginutils": { @@ -7567,13 +7580,13 @@ } }, "@rollup/plugin-multi-entry": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-multi-entry/-/plugin-multi-entry-4.1.0.tgz", - "integrity": "sha512-nellK5pr50W0JA2+bDJbG8F79GBP802J40YRoC0wyfpTAeAn5mJ4eaFiB/MN+YoX9hgb/6RJoZl9leDjZnUFKw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-multi-entry/-/plugin-multi-entry-6.0.0.tgz", + "integrity": "sha512-msBgVncGQwh/ahxeP/rc8MXVZNBOjoVCsBuDk6uqyFzDv/SZN7jksfAsu6DJ2w4r5PaBX3/OXOjVPeCxya2waA==", "dev": true, "requires": { - "@rollup/plugin-virtual": "^2.0.3", - "matched": "^5.0.0" + "@rollup/plugin-virtual": "^3.0.0", + "matched": "^5.0.1" } }, "@rollup/plugin-node-resolve": { @@ -7639,9 +7652,9 @@ } }, "@rollup/plugin-virtual": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-virtual/-/plugin-virtual-2.0.3.tgz", - "integrity": "sha512-pw6ziJcyjZtntQ//bkad9qXaBx665SgEL8C8KI5wO8G5iU5MPxvdWrQyVaAvjojGm9tJoS8M9Z/EEepbqieYmw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-virtual/-/plugin-virtual-3.0.1.tgz", + "integrity": "sha512-fK8O0IL5+q+GrsMLuACVNk2x21g3yaw+sG2qn16SnUd3IlBsQyvWxLMGHmCmXRMecPjGRSZ/1LmZB4rjQm68og==", "dev": true, "requires": {} }, diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index bafac374..926061bc 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -55,7 +55,7 @@ "@rollup/plugin-alias": "^5.0.0", "@rollup/plugin-commonjs": "^21.0.1", "@rollup/plugin-json": "^6.0.0", - "@rollup/plugin-multi-entry": "^4.1.0", + "@rollup/plugin-multi-entry": "^6.0.0", "@rollup/plugin-node-resolve": "^15.0.2", "@rollup/plugin-typescript": "^11.1.0", "@types/bn.js": "^5.1.0", From b4ac3ee2e0be8da6b2df5fdfcce53aa468350d9e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 May 2023 19:42:57 +0200 Subject: [PATCH 0334/1076] build(deps-dev): bump typescript from 4.5.5 to 4.9.5 in /stake-pool/js (#4264) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/js-legacy/package-lock.json | 442 +++++++++------------------- clients/js-legacy/package.json | 17 +- 2 files changed, 151 insertions(+), 308 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index b7037bc4..50a2edc0 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -10,7 +10,7 @@ "license": "ISC", "dependencies": { "@project-serum/borsh": "^0.2.2", - "@solana/buffer-layout": "^4.0.0", + "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "^0.1.8", "@solana/web3.js": "^1.30.2", "bn.js": "^5.2.0", @@ -25,17 +25,18 @@ "@rollup/plugin-typescript": "^11.1.0", "@types/bn.js": "^5.1.0", "@types/jest": "^27.4.0", - "@typescript-eslint/eslint-plugin": "^5.11.0", - "@typescript-eslint/parser": "^5.11.0", + "@types/node": "^20.1.2", + "@typescript-eslint/eslint-plugin": "^5.59.5", + "@typescript-eslint/parser": "^5.59.5", "cross-env": "^7.0.3", - "eslint": "^8.8.0", - "eslint-config-prettier": "^8.3.0", - "eslint-plugin-prettier": "^4.0.0", + "eslint": "^8.40.0", + "eslint-config-prettier": "^8.8.0", + "eslint-plugin-prettier": "^4.2.1", "jest": "^27.5.1", - "prettier": "^2.5.1", + "prettier": "^2.8.8", "rimraf": "^3.0.2", "rollup": "^2.66.1", - "rollup-plugin-dts": "^4.1.0", + "rollup-plugin-dts": "^4.2.3", "rollup-plugin-node-polyfills": "^0.2.1", "rollup-plugin-terser": "^7.0.2", "ts-jest": "^27.1.3", @@ -1711,9 +1712,9 @@ } }, "node_modules/@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, "node_modules/@types/lodash": { @@ -1722,9 +1723,9 @@ "integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==" }, "node_modules/@types/node": { - "version": "17.0.17", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.17.tgz", - "integrity": "sha512-e8PUNQy1HgJGV3iU/Bp2+D/DXh3PYeyli8LgIwsQcs1Ar1LoaWHSIT6Rw+H2rNJmiq6SNWiDytfx8+gYj7wDHw==" + "version": "20.1.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.2.tgz", + "integrity": "sha512-CTO/wa8x+rZU626cL2BlbCDzydgnFNgc19h4YvizpTO88MFQxab8wqisxaofQJ/9bLGugRdWIuX/TbIs6VVF6g==" }, "node_modules/@types/prettier": { "version": "2.4.4", @@ -1748,6 +1749,12 @@ "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", "dev": true }, + "node_modules/@types/semver": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", + "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", + "dev": true + }, "node_modules/@types/stack-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", @@ -1778,19 +1785,20 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.11.0.tgz", - "integrity": "sha512-HJh33bgzXe6jGRocOj4FmefD7hRY4itgjzOrSs3JPrTNXsX7j5+nQPciAUj/1nZtwo2kAc3C75jZO+T23gzSGw==", + "version": "5.59.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.5.tgz", + "integrity": "sha512-feA9xbVRWJZor+AnLNAr7A8JRWeZqHUf4T9tlP+TN04b05pFVhO5eN7/O93Y/1OUlLMHKbnJisgDURs/qvtqdg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.11.0", - "@typescript-eslint/type-utils": "5.11.0", - "@typescript-eslint/utils": "5.11.0", - "debug": "^4.3.2", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", - "regexpp": "^3.2.0", - "semver": "^7.3.5", + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.59.5", + "@typescript-eslint/type-utils": "5.59.5", + "@typescript-eslint/utils": "5.59.5", + "debug": "^4.3.4", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "semver": "^7.3.7", "tsutils": "^3.21.0" }, "engines": { @@ -1837,7 +1845,7 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "node_modules/@typescript-eslint/scope-manager": { "version": "5.59.5", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.5.tgz", "integrity": "sha512-jVecWwnkX6ZgutF+DovbBJirZcAxgxC0EOHYt/niMROf8p4PwxxG32Qdhj/iIQQIuOflLjNkxoXyArkcIP7C3A==", @@ -1854,88 +1862,15 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.5.tgz", - "integrity": "sha512-xkfRPHbqSH4Ggx4eHRIO/eGL8XL4Ysb4woL8c87YuAo8Md7AUjyWKa9YMwTL519SyDPrfEgKdewjkxNCVeJW7w==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "node_modules/@typescript-eslint/type-utils": { "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.5.tgz", - "integrity": "sha512-+XXdLN2CZLZcD/mO7mQtJMvCkzRfmODbeSKuMY/yXbGkzvA9rJyDY5qDYNoiz2kP/dmyAxXquL2BvLQLJFPQIg==", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.5.tgz", + "integrity": "sha512-4eyhS7oGym67/pSxA2mmNq7X164oqDYNnZCUayBwJZIRVvKpBCMBzFnFxjeoDeShjtO6RQBHBuwybuX3POnDqg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.5", - "@typescript-eslint/visitor-keys": "5.59.5", + "@typescript-eslint/typescript-estree": "5.59.5", + "@typescript-eslint/utils": "5.59.5", "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.5.tgz", - "integrity": "sha512-qL+Oz+dbeBRTeyJTIy0eniD3uvqU7x+y1QceBismZ41hd4aBSRh8UAw4pZP0+XzLuPZmx4raNMq/I+59W2lXKA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.5", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.11.0.tgz", - "integrity": "sha512-z+K4LlahDFVMww20t/0zcA7gq/NgOawaLuxgqGRVKS0PiZlCTIUtX0EJbC0BK1JtR4CelmkPK67zuCgpdlF4EA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.11.0", - "@typescript-eslint/visitor-keys": "5.11.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.11.0.tgz", - "integrity": "sha512-wDqdsYO6ofLaD4DsGZ0jGwxp4HrzD2YKulpEZXmgN3xo4BHJwf7kq49JTRpV0Gx6bxkSUmc9s0EIK1xPbFFpIA==", - "dev": true, - "dependencies": { - "@typescript-eslint/utils": "5.11.0", - "debug": "^4.3.2", "tsutils": "^3.21.0" }, "engines": { @@ -1955,9 +1890,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.11.0.tgz", - "integrity": "sha512-cxgBFGSRCoBEhvSVLkKw39+kMzUKHlJGVwwMbPcTZX3qEhuXhrjwaZXWMxVfxDgyMm+b5Q5b29Llo2yow8Y7xQ==", + "version": "5.59.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.5.tgz", + "integrity": "sha512-xkfRPHbqSH4Ggx4eHRIO/eGL8XL4Ysb4woL8c87YuAo8Md7AUjyWKa9YMwTL519SyDPrfEgKdewjkxNCVeJW7w==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1968,17 +1903,17 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.11.0.tgz", - "integrity": "sha512-yVH9hKIv3ZN3lw8m/Jy5I4oXO4ZBMqijcXCdA4mY8ull6TPTAoQnKKrcZ0HDXg7Bsl0Unwwx7jcXMuNZc0m4lg==", + "version": "5.59.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.5.tgz", + "integrity": "sha512-+XXdLN2CZLZcD/mO7mQtJMvCkzRfmODbeSKuMY/yXbGkzvA9rJyDY5qDYNoiz2kP/dmyAxXquL2BvLQLJFPQIg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.11.0", - "@typescript-eslint/visitor-keys": "5.11.0", - "debug": "^4.3.2", - "globby": "^11.0.4", + "@typescript-eslint/types": "5.59.5", + "@typescript-eslint/visitor-keys": "5.59.5", + "debug": "^4.3.4", + "globby": "^11.1.0", "is-glob": "^4.0.3", - "semver": "^7.3.5", + "semver": "^7.3.7", "tsutils": "^3.21.0" }, "engines": { @@ -1995,17 +1930,19 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.11.0.tgz", - "integrity": "sha512-g2I480tFE1iYRDyMhxPAtLQ9HAn0jjBtipgTCZmd9I9s11OV8CTsG+YfFciuNDcHqm4csbAgC2aVZCHzLxMSUw==", + "version": "5.59.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.5.tgz", + "integrity": "sha512-sCEHOiw+RbyTii9c3/qN74hYDPNORb8yWCoPLmB7BIflhplJ65u2PBpdRla12e3SSTJ2erRkPjz7ngLHhUegxA==", "dev": true, "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.11.0", - "@typescript-eslint/types": "5.11.0", - "@typescript-eslint/typescript-estree": "5.11.0", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.59.5", + "@typescript-eslint/types": "5.59.5", + "@typescript-eslint/typescript-estree": "5.59.5", "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" + "semver": "^7.3.7" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2019,13 +1956,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.11.0.tgz", - "integrity": "sha512-E8w/vJReMGuloGxJDkpPlGwhxocxOpSVgSvjiLO5IxZPmxZF30weOeJYyPSEACwM+X4NziYS9q+WkN/2DHYQwA==", + "version": "5.59.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.5.tgz", + "integrity": "sha512-qL+Oz+dbeBRTeyJTIy0eniD3uvqU7x+y1QceBismZ41hd4aBSRh8UAw4pZP0+XzLuPZmx4raNMq/I+59W2lXKA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.11.0", - "eslint-visitor-keys": "^3.0.0" + "@typescript-eslint/types": "5.59.5", + "eslint-visitor-keys": "^3.3.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3146,33 +3083,6 @@ "node": ">=8.0.0" } }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/eslint-visitor-keys": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", @@ -3593,12 +3503,6 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -5157,6 +5061,12 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true + }, "node_modules/node-addon-api": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", @@ -5573,18 +5483,6 @@ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -6368,9 +6266,9 @@ } }, "node_modules/typescript": { - "version": "4.5.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz", - "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -7891,9 +7789,9 @@ } }, "@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, "@types/lodash": { @@ -7902,9 +7800,9 @@ "integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==" }, "@types/node": { - "version": "17.0.17", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.17.tgz", - "integrity": "sha512-e8PUNQy1HgJGV3iU/Bp2+D/DXh3PYeyli8LgIwsQcs1Ar1LoaWHSIT6Rw+H2rNJmiq6SNWiDytfx8+gYj7wDHw==" + "version": "20.1.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.2.tgz", + "integrity": "sha512-CTO/wa8x+rZU626cL2BlbCDzydgnFNgc19h4YvizpTO88MFQxab8wqisxaofQJ/9bLGugRdWIuX/TbIs6VVF6g==" }, "@types/prettier": { "version": "2.4.4", @@ -7928,6 +7826,12 @@ "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", "dev": true }, + "@types/semver": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", + "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", + "dev": true + }, "@types/stack-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", @@ -7958,19 +7862,20 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.11.0.tgz", - "integrity": "sha512-HJh33bgzXe6jGRocOj4FmefD7hRY4itgjzOrSs3JPrTNXsX7j5+nQPciAUj/1nZtwo2kAc3C75jZO+T23gzSGw==", + "version": "5.59.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.5.tgz", + "integrity": "sha512-feA9xbVRWJZor+AnLNAr7A8JRWeZqHUf4T9tlP+TN04b05pFVhO5eN7/O93Y/1OUlLMHKbnJisgDURs/qvtqdg==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.11.0", - "@typescript-eslint/type-utils": "5.11.0", - "@typescript-eslint/utils": "5.11.0", - "debug": "^4.3.2", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", - "regexpp": "^3.2.0", - "semver": "^7.3.5", + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.59.5", + "@typescript-eslint/type-utils": "5.59.5", + "@typescript-eslint/utils": "5.59.5", + "debug": "^4.3.4", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "semver": "^7.3.7", "tsutils": "^3.21.0" } }, @@ -7984,115 +7889,75 @@ "@typescript-eslint/types": "5.59.5", "@typescript-eslint/typescript-estree": "5.59.5", "debug": "^4.3.4" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.5.tgz", - "integrity": "sha512-jVecWwnkX6ZgutF+DovbBJirZcAxgxC0EOHYt/niMROf8p4PwxxG32Qdhj/iIQQIuOflLjNkxoXyArkcIP7C3A==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.5", - "@typescript-eslint/visitor-keys": "5.59.5" - } - }, - "@typescript-eslint/types": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.5.tgz", - "integrity": "sha512-xkfRPHbqSH4Ggx4eHRIO/eGL8XL4Ysb4woL8c87YuAo8Md7AUjyWKa9YMwTL519SyDPrfEgKdewjkxNCVeJW7w==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.5.tgz", - "integrity": "sha512-+XXdLN2CZLZcD/mO7mQtJMvCkzRfmODbeSKuMY/yXbGkzvA9rJyDY5qDYNoiz2kP/dmyAxXquL2BvLQLJFPQIg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.5", - "@typescript-eslint/visitor-keys": "5.59.5", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.5.tgz", - "integrity": "sha512-qL+Oz+dbeBRTeyJTIy0eniD3uvqU7x+y1QceBismZ41hd4aBSRh8UAw4pZP0+XzLuPZmx4raNMq/I+59W2lXKA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.5", - "eslint-visitor-keys": "^3.3.0" - } - } } }, "@typescript-eslint/scope-manager": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.11.0.tgz", - "integrity": "sha512-z+K4LlahDFVMww20t/0zcA7gq/NgOawaLuxgqGRVKS0PiZlCTIUtX0EJbC0BK1JtR4CelmkPK67zuCgpdlF4EA==", + "version": "5.59.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.5.tgz", + "integrity": "sha512-jVecWwnkX6ZgutF+DovbBJirZcAxgxC0EOHYt/niMROf8p4PwxxG32Qdhj/iIQQIuOflLjNkxoXyArkcIP7C3A==", "dev": true, "requires": { - "@typescript-eslint/types": "5.11.0", - "@typescript-eslint/visitor-keys": "5.11.0" + "@typescript-eslint/types": "5.59.5", + "@typescript-eslint/visitor-keys": "5.59.5" } }, "@typescript-eslint/type-utils": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.11.0.tgz", - "integrity": "sha512-wDqdsYO6ofLaD4DsGZ0jGwxp4HrzD2YKulpEZXmgN3xo4BHJwf7kq49JTRpV0Gx6bxkSUmc9s0EIK1xPbFFpIA==", + "version": "5.59.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.5.tgz", + "integrity": "sha512-4eyhS7oGym67/pSxA2mmNq7X164oqDYNnZCUayBwJZIRVvKpBCMBzFnFxjeoDeShjtO6RQBHBuwybuX3POnDqg==", "dev": true, "requires": { - "@typescript-eslint/utils": "5.11.0", - "debug": "^4.3.2", + "@typescript-eslint/typescript-estree": "5.59.5", + "@typescript-eslint/utils": "5.59.5", + "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.11.0.tgz", - "integrity": "sha512-cxgBFGSRCoBEhvSVLkKw39+kMzUKHlJGVwwMbPcTZX3qEhuXhrjwaZXWMxVfxDgyMm+b5Q5b29Llo2yow8Y7xQ==", + "version": "5.59.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.5.tgz", + "integrity": "sha512-xkfRPHbqSH4Ggx4eHRIO/eGL8XL4Ysb4woL8c87YuAo8Md7AUjyWKa9YMwTL519SyDPrfEgKdewjkxNCVeJW7w==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.11.0.tgz", - "integrity": "sha512-yVH9hKIv3ZN3lw8m/Jy5I4oXO4ZBMqijcXCdA4mY8ull6TPTAoQnKKrcZ0HDXg7Bsl0Unwwx7jcXMuNZc0m4lg==", + "version": "5.59.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.5.tgz", + "integrity": "sha512-+XXdLN2CZLZcD/mO7mQtJMvCkzRfmODbeSKuMY/yXbGkzvA9rJyDY5qDYNoiz2kP/dmyAxXquL2BvLQLJFPQIg==", "dev": true, "requires": { - "@typescript-eslint/types": "5.11.0", - "@typescript-eslint/visitor-keys": "5.11.0", - "debug": "^4.3.2", - "globby": "^11.0.4", + "@typescript-eslint/types": "5.59.5", + "@typescript-eslint/visitor-keys": "5.59.5", + "debug": "^4.3.4", + "globby": "^11.1.0", "is-glob": "^4.0.3", - "semver": "^7.3.5", + "semver": "^7.3.7", "tsutils": "^3.21.0" } }, "@typescript-eslint/utils": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.11.0.tgz", - "integrity": "sha512-g2I480tFE1iYRDyMhxPAtLQ9HAn0jjBtipgTCZmd9I9s11OV8CTsG+YfFciuNDcHqm4csbAgC2aVZCHzLxMSUw==", + "version": "5.59.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.5.tgz", + "integrity": "sha512-sCEHOiw+RbyTii9c3/qN74hYDPNORb8yWCoPLmB7BIflhplJ65u2PBpdRla12e3SSTJ2erRkPjz7ngLHhUegxA==", "dev": true, "requires": { + "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.11.0", - "@typescript-eslint/types": "5.11.0", - "@typescript-eslint/typescript-estree": "5.11.0", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.59.5", + "@typescript-eslint/types": "5.59.5", + "@typescript-eslint/typescript-estree": "5.59.5", "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" + "semver": "^7.3.7" } }, "@typescript-eslint/visitor-keys": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.11.0.tgz", - "integrity": "sha512-E8w/vJReMGuloGxJDkpPlGwhxocxOpSVgSvjiLO5IxZPmxZF30weOeJYyPSEACwM+X4NziYS9q+WkN/2DHYQwA==", + "version": "5.59.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.5.tgz", + "integrity": "sha512-qL+Oz+dbeBRTeyJTIy0eniD3uvqU7x+y1QceBismZ41hd4aBSRh8UAw4pZP0+XzLuPZmx4raNMq/I+59W2lXKA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.11.0", - "eslint-visitor-keys": "^3.0.0" + "@typescript-eslint/types": "5.59.5", + "eslint-visitor-keys": "^3.3.0" } }, "abab": { @@ -8991,23 +8856,6 @@ "estraverse": "^4.1.1" } }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - } - } - }, "eslint-visitor-keys": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", @@ -9268,12 +9116,6 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -10466,6 +10308,12 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, + "natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true + }, "node-addon-api": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", @@ -10766,12 +10614,6 @@ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -11339,9 +11181,9 @@ } }, "typescript": { - "version": "4.5.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz", - "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true }, "universalify": { diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 926061bc..389d1e46 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -45,7 +45,7 @@ "license": "ISC", "dependencies": { "@project-serum/borsh": "^0.2.2", - "@solana/buffer-layout": "^4.0.0", + "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "^0.1.8", "@solana/web3.js": "^1.30.2", "bn.js": "^5.2.0", @@ -60,17 +60,18 @@ "@rollup/plugin-typescript": "^11.1.0", "@types/bn.js": "^5.1.0", "@types/jest": "^27.4.0", - "@typescript-eslint/eslint-plugin": "^5.11.0", - "@typescript-eslint/parser": "^5.11.0", + "@types/node": "^20.1.2", + "@typescript-eslint/eslint-plugin": "^5.59.5", + "@typescript-eslint/parser": "^5.59.5", "cross-env": "^7.0.3", - "eslint": "^8.8.0", - "eslint-config-prettier": "^8.3.0", - "eslint-plugin-prettier": "^4.0.0", + "eslint": "^8.40.0", + "eslint-config-prettier": "^8.8.0", + "eslint-plugin-prettier": "^4.2.1", "jest": "^27.5.1", - "prettier": "^2.5.1", + "prettier": "^2.8.8", "rimraf": "^3.0.2", "rollup": "^2.66.1", - "rollup-plugin-dts": "^4.1.0", + "rollup-plugin-dts": "^4.2.3", "rollup-plugin-node-polyfills": "^0.2.1", "rollup-plugin-terser": "^7.0.2", "ts-jest": "^27.1.3", From eb9d2eeb04b6cd5571ba4f58b41527c807dcdb00 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 12 May 2023 12:42:07 +0200 Subject: [PATCH 0335/1076] build(deps): bump test-case from 2.2.2 to 3.1.0 (#4271) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 28e7f9a0..81be0aa1 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -32,7 +32,7 @@ solana-program-test = "1.14.12" solana-sdk = "1.14.12" solana-vote-program = "1.14.12" spl-token = { version = "3.5", path = "../../token/program", features = [ "no-entrypoint" ] } -test-case = "2.2" +test-case = "3.1" [lib] crate-type = ["cdylib", "lib"] From a5481097e939671fd1f4c071275961c148cfbd9d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 12 May 2023 15:35:32 +0200 Subject: [PATCH 0336/1076] build(deps-dev): bump @types/node from 20.1.2 to 20.1.3 in /stake-pool/js (#4281) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 50a2edc0..8d3bb8a3 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1723,9 +1723,9 @@ "integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==" }, "node_modules/@types/node": { - "version": "20.1.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.2.tgz", - "integrity": "sha512-CTO/wa8x+rZU626cL2BlbCDzydgnFNgc19h4YvizpTO88MFQxab8wqisxaofQJ/9bLGugRdWIuX/TbIs6VVF6g==" + "version": "20.1.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.3.tgz", + "integrity": "sha512-NP2yfZpgmf2eDRPmgGq+fjGjSwFgYbihA8/gK+ey23qT9RkxsgNTZvGOEpXgzIGqesTYkElELLgtKoMQTys5vA==" }, "node_modules/@types/prettier": { "version": "2.4.4", @@ -7800,9 +7800,9 @@ "integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==" }, "@types/node": { - "version": "20.1.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.2.tgz", - "integrity": "sha512-CTO/wa8x+rZU626cL2BlbCDzydgnFNgc19h4YvizpTO88MFQxab8wqisxaofQJ/9bLGugRdWIuX/TbIs6VVF6g==" + "version": "20.1.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.3.tgz", + "integrity": "sha512-NP2yfZpgmf2eDRPmgGq+fjGjSwFgYbihA8/gK+ey23qT9RkxsgNTZvGOEpXgzIGqesTYkElELLgtKoMQTys5vA==" }, "@types/prettier": { "version": "2.4.4", From 1688035894c9ec9cfedf9cc6aa5126c6f3f24b05 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Mon, 15 May 2023 12:20:12 +0200 Subject: [PATCH 0337/1076] stake-pool-js: Bump web3.js and borsh (#4293) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 772 ++++++++------------ clients/js-legacy/package.json | 5 +- clients/js-legacy/rollup.config.js | 4 +- clients/js-legacy/src/layouts.ts | 2 +- clients/js-legacy/test/instructions.test.ts | 57 +- clients/js-legacy/tsconfig.json | 3 +- 6 files changed, 336 insertions(+), 507 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 8d3bb8a3..54c9d161 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -9,10 +9,10 @@ "version": "0.6.5", "license": "ISC", "dependencies": { - "@project-serum/borsh": "^0.2.2", + "@coral-xyz/borsh": "^0.27.0", "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "^0.1.8", - "@solana/web3.js": "^1.30.2", + "@solana/web3.js": "^1.76.0", "bn.js": "^5.2.0", "buffer": "^6.0.3" }, @@ -26,6 +26,7 @@ "@types/bn.js": "^5.1.0", "@types/jest": "^27.4.0", "@types/node": "^20.1.2", + "@types/node-fetch": "^2.6.3", "@typescript-eslint/eslint-plugin": "^5.59.5", "@typescript-eslint/parser": "^5.59.5", "cross-env": "^7.0.3", @@ -644,6 +645,21 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "node_modules/@coral-xyz/borsh": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.27.0.tgz", + "integrity": "sha512-tJKzhLukghTWPLy+n8K8iJKgBq1yLT/AxaNd10yJrX8mI56ao5+OFAKAqW/h0i79KCvb4BK0VGO5ECmmolFz9A==", + "dependencies": { + "bn.js": "^5.1.2", + "buffer-layout": "^1.2.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@solana/web3.js": "^1.68.0" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -700,59 +716,6 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/@ethersproject/bytes": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.5.0.tgz", - "integrity": "sha512-ABvc7BHWhZU9PNM/tANm/Qx4ostPGadAuQzWTr3doklZOhDlmcBqclrQe/ZXUIj3K8wC28oYeuRa+A37tX9kog==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/logger": "^5.5.0" - } - }, - "node_modules/@ethersproject/logger": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.5.0.tgz", - "integrity": "sha512-rIY/6WPm7T8n3qS2vuHTUBPdXHl+rGxWxW5okDfo9J4Z0+gRRZT0msvUdIJkE4/HS29GUMziwGaaKO2bWONBrg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ] - }, - "node_modules/@ethersproject/sha2": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.5.0.tgz", - "integrity": "sha512-B5UBoglbCiHamRVPLA110J+2uqsifpZaTmid2/7W5rbtYVz6gus6/hSDieIU/6gaKIDcOj12WnOdiymEUHIAOA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "hash.js": "1.1.7" - } - }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.8", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", @@ -1140,6 +1103,31 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, + "node_modules/@noble/curves": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.0.0.tgz", + "integrity": "sha512-2upgEu0iLiDVDZkNLeFV2+ht0BAVgQnEmCk6JsOch9Rp8xfkMCbvbAZlA2pBHQc73dbl+vFOXfqkf4uemdn0bw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "1.3.0" + } + }, + "node_modules/@noble/hashes": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.0.tgz", + "integrity": "sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1175,21 +1163,6 @@ "node": ">= 8" } }, - "node_modules/@project-serum/borsh": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@project-serum/borsh/-/borsh-0.2.4.tgz", - "integrity": "sha512-tQPc1ktAp1Jtn9D72DmObAfhAic9ivfYBOS5b+T4H7MvkQ84uML88LY1LfvGep30mCy+ua5rf+X9ocPfg6u9MA==", - "dependencies": { - "bn.js": "^5.1.2", - "buffer-layout": "^1.2.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@solana/web3.js": "^1.2.0" - } - }, "node_modules/@rollup/plugin-alias": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.0.0.tgz", @@ -1505,84 +1478,25 @@ } }, "node_modules/@solana/web3.js": { - "version": "1.34.0", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.34.0.tgz", - "integrity": "sha512-6QvqN2DqEELvuV+5yUQM8P9fRiSG+6SzQ58HjumJqODu14r7eu5HXVWEymvKAvMLGME+0TmAdJHjw9xD5NgUWA==", + "version": "1.76.0", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.76.0.tgz", + "integrity": "sha512-aJtF/nTs+9St+KtTK/wgVJ+SinfjYzn+3w1ygYIPw8ST6LH+qHBn8XkodgDTwlv/xzNkaVz1kkUDOZ8BPXyZWA==", "dependencies": { "@babel/runtime": "^7.12.5", - "@ethersproject/sha2": "^5.5.0", - "@solana/buffer-layout": "^3.0.0", + "@noble/curves": "^1.0.0", + "@noble/hashes": "^1.3.0", + "@solana/buffer-layout": "^4.0.0", + "agentkeepalive": "^4.2.1", + "bigint-buffer": "^1.1.5", "bn.js": "^5.0.0", - "borsh": "^0.4.0", + "borsh": "^0.7.0", "bs58": "^4.0.1", - "buffer": "6.0.1", - "cross-fetch": "^3.1.4", + "buffer": "6.0.3", + "fast-stable-stringify": "^1.0.0", "jayson": "^3.4.4", - "js-sha3": "^0.8.0", - "rpc-websockets": "^7.4.2", - "secp256k1": "^4.0.2", - "superstruct": "^0.14.2", - "tweetnacl": "^1.0.0" - }, - "engines": { - "node": ">=12.20.0" - } - }, - "node_modules/@solana/web3.js/node_modules/@solana/buffer-layout": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-3.0.0.tgz", - "integrity": "sha512-MVdgAKKL39tEs0l8je0hKaXLQFb7Rdfb0Xg2LjFZd8Lfdazkg6xiS98uAZrEKvaoF3i4M95ei9RydkGIDMeo3w==", - "dependencies": { - "buffer": "~6.0.3" - }, - "engines": { - "node": ">=5.10" - } - }, - "node_modules/@solana/web3.js/node_modules/@solana/buffer-layout/node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/@solana/web3.js/node_modules/buffer": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.1.tgz", - "integrity": "sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" + "node-fetch": "^2.6.7", + "rpc-websockets": "^7.5.1", + "superstruct": "^0.14.2" } }, "node_modules/@tootallnate/once": { @@ -1727,6 +1641,16 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.3.tgz", "integrity": "sha512-NP2yfZpgmf2eDRPmgGq+fjGjSwFgYbihA8/gK+ey23qT9RkxsgNTZvGOEpXgzIGqesTYkElELLgtKoMQTys5vA==" }, + "node_modules/@types/node-fetch": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.3.tgz", + "integrity": "sha512-ETTL1mOEdq/sxUtgtOhKjyB2Irra4cjxksvcMUR5Zr4n+PxVhsCD9WS46oPbHL3et9Zde7CNRr+WUNlcHvsX+w==", + "dev": true, + "dependencies": { + "@types/node": "*", + "form-data": "^3.0.0" + } + }, "node_modules/@types/prettier": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.4.tgz", @@ -2042,6 +1966,19 @@ "node": ">= 6.0.0" } }, + "node_modules/agentkeepalive": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.3.0.tgz", + "integrity": "sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg==", + "dependencies": { + "debug": "^4.1.0", + "depd": "^2.0.0", + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -2268,30 +2205,41 @@ } ] }, + "node_modules/bigint-buffer": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bigint-buffer/-/bigint-buffer-1.1.5.tgz", + "integrity": "sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==", + "hasInstallScript": true, + "dependencies": { + "bindings": "^1.3.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, "node_modules/bn.js": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" }, "node_modules/borsh": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/borsh/-/borsh-0.4.0.tgz", - "integrity": "sha512-aX6qtLya3K0AkT66CmYWCCDr77qsE9arV05OmdFpmat9qu8Pg9J5tBUPDztAW5fNh/d/MyVG/OYziP52Ndzx1g==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/borsh/-/borsh-0.7.0.tgz", + "integrity": "sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==", "dependencies": { - "@types/bn.js": "^4.11.5", - "bn.js": "^5.0.0", + "bn.js": "^5.2.0", "bs58": "^4.0.0", "text-encoding-utf-8": "^1.0.2" } }, - "node_modules/borsh/node_modules/@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -2314,11 +2262,6 @@ "node": ">=8" } }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" - }, "node_modules/browser-process-hrtime": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", @@ -2498,12 +2441,6 @@ "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", "dev": true }, - "node_modules/circular-json": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.9.tgz", - "integrity": "sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ==", - "deprecated": "CircularJSON is in maintenance only, flatted is its successor." - }, "node_modules/cjs-module-lexer": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", @@ -2617,14 +2554,6 @@ "yarn": ">=1" } }, - "node_modules/cross-fetch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", - "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", - "dependencies": { - "node-fetch": "2.6.7" - } - }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -2681,7 +2610,6 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -2741,6 +2669,14 @@ "node": ">=0.4.0" } }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -2818,25 +2754,6 @@ "integrity": "sha512-cId+QwWrV8R1UawO6b9BR1hnkJ4EJPCPAr4h315vliHUtVUJDk39Sg1PMNnaWKfj5x+93ssjeJ9LKL6r8LaMiA==", "dev": true }, - "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, "node_modules/emittery": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", @@ -3389,6 +3306,11 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "node_modules/fast-stable-stringify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz", + "integrity": "sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==" + }, "node_modules/fastq": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", @@ -3419,6 +3341,11 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -3642,25 +3569,6 @@ "node": ">=8" } }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, "node_modules/html-encoding-sniffer": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", @@ -3715,6 +3623,14 @@ "node": ">=10.17.0" } }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "dependencies": { + "ms": "^2.0.0" + } + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -3812,7 +3728,8 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, "node_modules/is-arrayish": { "version": "0.2.1", @@ -4688,11 +4605,6 @@ "url": "https://opencollective.com/js-sdsl" } }, - "node_modules/js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -5027,16 +4939,6 @@ "node": ">=6" } }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -5052,8 +4954,7 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/natural-compare": { "version": "1.4.0", @@ -5067,15 +4968,10 @@ "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", "dev": true }, - "node_modules/node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" - }, "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz", + "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -5094,17 +4990,17 @@ "node_modules/node-fetch/node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "node_modules/node-fetch/node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "node_modules/node-fetch/node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -5114,6 +5010,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==", + "optional": true, "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", @@ -5694,15 +5591,14 @@ "dev": true }, "node_modules/rpc-websockets": { - "version": "7.4.17", - "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.4.17.tgz", - "integrity": "sha512-eolVi/qlXS13viIUH9aqrde902wzSLAai0IjmOZSRefp5I3CSG/vCnD0c0fDSYCWuEyUoRL1BHQA8K1baEUyow==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.5.1.tgz", + "integrity": "sha512-kGFkeTsmd37pHPMaHIgN1LVKXMi0JD782v4Ds9ZKtLlwdTKjn+CxM9A9/gLT2LaOuEcEFGL98h1QWQtlOIdW0w==", "dependencies": { - "@babel/runtime": "^7.11.2", - "circular-json": "^0.5.9", + "@babel/runtime": "^7.17.2", "eventemitter3": "^4.0.7", - "uuid": "^8.3.0", - "ws": "^7.4.5" + "uuid": "^8.3.2", + "ws": "^8.5.0" }, "funding": { "type": "paypal", @@ -5713,6 +5609,26 @@ "utf-8-validate": "^5.0.2" } }, + "node_modules/rpc-websockets/node_modules/ws": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -5773,20 +5689,6 @@ "node": ">=10" } }, - "node_modules/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", - "hasInstallScript": true, - "dependencies": { - "elliptic": "^6.5.4", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/semver": { "version": "7.5.0", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", @@ -6190,9 +6092,9 @@ } }, "node_modules/tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", "dev": true, "optional": true, "peer": true @@ -6218,11 +6120,6 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -7012,6 +6909,15 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "@coral-xyz/borsh": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.27.0.tgz", + "integrity": "sha512-tJKzhLukghTWPLy+n8K8iJKgBq1yLT/AxaNd10yJrX8mI56ao5+OFAKAqW/h0i79KCvb4BK0VGO5ECmmolFz9A==", + "requires": { + "bn.js": "^5.1.2", + "buffer-layout": "^1.2.0" + } + }, "@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -7050,29 +6956,6 @@ "integrity": "sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==", "dev": true }, - "@ethersproject/bytes": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.5.0.tgz", - "integrity": "sha512-ABvc7BHWhZU9PNM/tANm/Qx4ostPGadAuQzWTr3doklZOhDlmcBqclrQe/ZXUIj3K8wC28oYeuRa+A37tX9kog==", - "requires": { - "@ethersproject/logger": "^5.5.0" - } - }, - "@ethersproject/logger": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.5.0.tgz", - "integrity": "sha512-rIY/6WPm7T8n3qS2vuHTUBPdXHl+rGxWxW5okDfo9J4Z0+gRRZT0msvUdIJkE4/HS29GUMziwGaaKO2bWONBrg==" - }, - "@ethersproject/sha2": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.5.0.tgz", - "integrity": "sha512-B5UBoglbCiHamRVPLA110J+2uqsifpZaTmid2/7W5rbtYVz6gus6/hSDieIU/6gaKIDcOj12WnOdiymEUHIAOA==", - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "hash.js": "1.1.7" - } - }, "@humanwhocodes/config-array": { "version": "0.11.8", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", @@ -7382,6 +7265,19 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, + "@noble/curves": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.0.0.tgz", + "integrity": "sha512-2upgEu0iLiDVDZkNLeFV2+ht0BAVgQnEmCk6JsOch9Rp8xfkMCbvbAZlA2pBHQc73dbl+vFOXfqkf4uemdn0bw==", + "requires": { + "@noble/hashes": "1.3.0" + } + }, + "@noble/hashes": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.0.tgz", + "integrity": "sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg==" + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -7408,15 +7304,6 @@ "fastq": "^1.6.0" } }, - "@project-serum/borsh": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@project-serum/borsh/-/borsh-0.2.4.tgz", - "integrity": "sha512-tQPc1ktAp1Jtn9D72DmObAfhAic9ivfYBOS5b+T4H7MvkQ84uML88LY1LfvGep30mCy+ua5rf+X9ocPfg6u9MA==", - "requires": { - "bn.js": "^5.1.2", - "buffer-layout": "^1.2.0" - } - }, "@rollup/plugin-alias": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.0.0.tgz", @@ -7615,54 +7502,25 @@ } }, "@solana/web3.js": { - "version": "1.34.0", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.34.0.tgz", - "integrity": "sha512-6QvqN2DqEELvuV+5yUQM8P9fRiSG+6SzQ58HjumJqODu14r7eu5HXVWEymvKAvMLGME+0TmAdJHjw9xD5NgUWA==", + "version": "1.76.0", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.76.0.tgz", + "integrity": "sha512-aJtF/nTs+9St+KtTK/wgVJ+SinfjYzn+3w1ygYIPw8ST6LH+qHBn8XkodgDTwlv/xzNkaVz1kkUDOZ8BPXyZWA==", "requires": { "@babel/runtime": "^7.12.5", - "@ethersproject/sha2": "^5.5.0", - "@solana/buffer-layout": "^3.0.0", + "@noble/curves": "^1.0.0", + "@noble/hashes": "^1.3.0", + "@solana/buffer-layout": "^4.0.0", + "agentkeepalive": "^4.2.1", + "bigint-buffer": "^1.1.5", "bn.js": "^5.0.0", - "borsh": "^0.4.0", + "borsh": "^0.7.0", "bs58": "^4.0.1", - "buffer": "6.0.1", - "cross-fetch": "^3.1.4", + "buffer": "6.0.3", + "fast-stable-stringify": "^1.0.0", "jayson": "^3.4.4", - "js-sha3": "^0.8.0", - "rpc-websockets": "^7.4.2", - "secp256k1": "^4.0.2", - "superstruct": "^0.14.2", - "tweetnacl": "^1.0.0" - }, - "dependencies": { - "@solana/buffer-layout": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-3.0.0.tgz", - "integrity": "sha512-MVdgAKKL39tEs0l8je0hKaXLQFb7Rdfb0Xg2LjFZd8Lfdazkg6xiS98uAZrEKvaoF3i4M95ei9RydkGIDMeo3w==", - "requires": { - "buffer": "~6.0.3" - }, - "dependencies": { - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - } - } - }, - "buffer": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.1.tgz", - "integrity": "sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - } + "node-fetch": "^2.6.7", + "rpc-websockets": "^7.5.1", + "superstruct": "^0.14.2" } }, "@tootallnate/once": { @@ -7804,6 +7662,16 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.3.tgz", "integrity": "sha512-NP2yfZpgmf2eDRPmgGq+fjGjSwFgYbihA8/gK+ey23qT9RkxsgNTZvGOEpXgzIGqesTYkElELLgtKoMQTys5vA==" }, + "@types/node-fetch": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.3.tgz", + "integrity": "sha512-ETTL1mOEdq/sxUtgtOhKjyB2Irra4cjxksvcMUR5Zr4n+PxVhsCD9WS46oPbHL3et9Zde7CNRr+WUNlcHvsX+w==", + "dev": true, + "requires": { + "@types/node": "*", + "form-data": "^3.0.0" + } + }, "@types/prettier": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.4.tgz", @@ -8012,6 +7880,16 @@ "debug": "4" } }, + "agentkeepalive": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.3.0.tgz", + "integrity": "sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg==", + "requires": { + "debug": "^4.1.0", + "depd": "^2.0.0", + "humanize-ms": "^1.2.1" + } + }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -8174,30 +8052,35 @@ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, + "bigint-buffer": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bigint-buffer/-/bigint-buffer-1.1.5.tgz", + "integrity": "sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==", + "requires": { + "bindings": "^1.3.0" + } + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "requires": { + "file-uri-to-path": "1.0.0" + } + }, "bn.js": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" }, "borsh": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/borsh/-/borsh-0.4.0.tgz", - "integrity": "sha512-aX6qtLya3K0AkT66CmYWCCDr77qsE9arV05OmdFpmat9qu8Pg9J5tBUPDztAW5fNh/d/MyVG/OYziP52Ndzx1g==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/borsh/-/borsh-0.7.0.tgz", + "integrity": "sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==", "requires": { - "@types/bn.js": "^4.11.5", - "bn.js": "^5.0.0", + "bn.js": "^5.2.0", "bs58": "^4.0.0", "text-encoding-utf-8": "^1.0.2" - }, - "dependencies": { - "@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "requires": { - "@types/node": "*" - } - } } }, "brace-expansion": { @@ -8219,11 +8102,6 @@ "fill-range": "^7.0.1" } }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" - }, "browser-process-hrtime": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", @@ -8344,11 +8222,6 @@ "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", "dev": true }, - "circular-json": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.9.tgz", - "integrity": "sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ==" - }, "cjs-module-lexer": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", @@ -8445,14 +8318,6 @@ "cross-spawn": "^7.0.1" } }, - "cross-fetch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", - "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", - "requires": { - "node-fetch": "2.6.7" - } - }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -8502,7 +8367,6 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, "requires": { "ms": "2.1.2" } @@ -8542,6 +8406,11 @@ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, "detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -8600,27 +8469,6 @@ "integrity": "sha512-cId+QwWrV8R1UawO6b9BR1hnkJ4EJPCPAr4h315vliHUtVUJDk39Sg1PMNnaWKfj5x+93ssjeJ9LKL6r8LaMiA==", "dev": true }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - } - } - }, "emittery": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", @@ -9024,6 +8872,11 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "fast-stable-stringify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz", + "integrity": "sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==" + }, "fastq": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", @@ -9051,6 +8904,11 @@ "flat-cache": "^3.0.4" } }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -9213,25 +9071,6 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, "html-encoding-sniffer": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", @@ -9274,6 +9113,14 @@ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true }, + "humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "requires": { + "ms": "^2.0.0" + } + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -9333,7 +9180,8 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, "is-arrayish": { "version": "0.2.1", @@ -10016,11 +9864,6 @@ "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==", "dev": true }, - "js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" - }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -10277,16 +10120,6 @@ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -10299,8 +10132,7 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "natural-compare": { "version": "1.4.0", @@ -10314,15 +10146,10 @@ "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", "dev": true }, - "node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" - }, "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz", + "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==", "requires": { "whatwg-url": "^5.0.0" }, @@ -10330,17 +10157,17 @@ "tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "requires": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -10351,7 +10178,8 @@ "node-gyp-build": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", - "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==" + "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==", + "optional": true }, "node-int64": { "version": "0.4.0", @@ -10776,17 +10604,24 @@ } }, "rpc-websockets": { - "version": "7.4.17", - "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.4.17.tgz", - "integrity": "sha512-eolVi/qlXS13viIUH9aqrde902wzSLAai0IjmOZSRefp5I3CSG/vCnD0c0fDSYCWuEyUoRL1BHQA8K1baEUyow==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.5.1.tgz", + "integrity": "sha512-kGFkeTsmd37pHPMaHIgN1LVKXMi0JD782v4Ds9ZKtLlwdTKjn+CxM9A9/gLT2LaOuEcEFGL98h1QWQtlOIdW0w==", "requires": { - "@babel/runtime": "^7.11.2", + "@babel/runtime": "^7.17.2", "bufferutil": "^4.0.1", - "circular-json": "^0.5.9", "eventemitter3": "^4.0.7", "utf-8-validate": "^5.0.2", - "uuid": "^8.3.0", - "ws": "^7.4.5" + "uuid": "^8.3.2", + "ws": "^8.5.0" + }, + "dependencies": { + "ws": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "requires": {} + } } }, "run-parallel": { @@ -10818,16 +10653,6 @@ "xmlchars": "^2.2.0" } }, - "secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", - "requires": { - "elliptic": "^6.5.4", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - }, "semver": { "version": "7.5.0", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", @@ -11121,9 +10946,9 @@ } }, "tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", "dev": true, "optional": true, "peer": true @@ -11145,11 +10970,6 @@ } } }, - "tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" - }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 389d1e46..e0450ff9 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -44,10 +44,10 @@ ], "license": "ISC", "dependencies": { - "@project-serum/borsh": "^0.2.2", + "@coral-xyz/borsh": "^0.27.0", "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "^0.1.8", - "@solana/web3.js": "^1.30.2", + "@solana/web3.js": "^1.76.0", "bn.js": "^5.2.0", "buffer": "^6.0.3" }, @@ -61,6 +61,7 @@ "@types/bn.js": "^5.1.0", "@types/jest": "^27.4.0", "@types/node": "^20.1.2", + "@types/node-fetch": "^2.6.3", "@typescript-eslint/eslint-plugin": "^5.59.5", "@typescript-eslint/parser": "^5.59.5", "cross-env": "^7.0.3", diff --git a/clients/js-legacy/rollup.config.js b/clients/js-legacy/rollup.config.js index f926a9de..eb4aaccb 100644 --- a/clients/js-legacy/rollup.config.js +++ b/clients/js-legacy/rollup.config.js @@ -66,7 +66,7 @@ function generateConfig(configType, format) { // Prevent dependencies from being bundled config.external = [ - '@project-serum/borsh', + '@coral-xyz/borsh', '@solana/buffer-layout', '@solana/spl-token', '@solana/web3.js', @@ -94,7 +94,7 @@ function generateConfig(configType, format) { // Prevent dependencies from being bundled config.external = [ - '@project-serum/borsh', + '@coral-xyz/borsh', '@solana/buffer-layout', '@solana/spl-token', '@solana/web3.js', diff --git a/clients/js-legacy/src/layouts.ts b/clients/js-legacy/src/layouts.ts index e7cd77b6..5027cc9b 100644 --- a/clients/js-legacy/src/layouts.ts +++ b/clients/js-legacy/src/layouts.ts @@ -1,4 +1,4 @@ -import { publicKey, struct, u32, u64, u8, option, vec } from '@project-serum/borsh'; +import { publicKey, struct, u32, u64, u8, option, vec } from '@coral-xyz/borsh'; import { Lockup, PublicKey } from '@solana/web3.js'; import { AccountInfo } from '@solana/spl-token'; import BN from 'bn.js'; diff --git a/clients/js-legacy/test/instructions.test.ts b/clients/js-legacy/test/instructions.test.ts index 204d85d5..510dd5fa 100644 --- a/clients/js-legacy/test/instructions.test.ts +++ b/clients/js-legacy/test/instructions.test.ts @@ -1,3 +1,12 @@ +// Very important! We need to do this polyfill before any of the imports because +// some web3.js dependencies store `crypto` elsewhere. +import { randomBytes } from 'crypto'; +Object.defineProperty(globalThis, 'crypto', { + value: { + getRandomValues: (arr: any) => randomBytes(arr.length), + }, +}); + import { PublicKey, Connection, @@ -6,10 +15,10 @@ import { AccountInfo, LAMPORTS_PER_SOL, } from '@solana/web3.js'; +import { TOKEN_PROGRAM_ID } from '@solana/spl-token'; import { StakePoolLayout } from '../src/layouts'; import { STAKE_POOL_INSTRUCTION_LAYOUTS, - STAKE_POOL_PROGRAM_ID, DepositSolParams, StakePoolInstruction, depositSol, @@ -65,16 +74,14 @@ describe('StakePoolProgram', () => { const instruction = StakePoolInstruction.depositSol(payload); expect(instruction.keys).toHaveLength(10); - expect(instruction.keys[0].pubkey.toBase58()).toEqual(payload.stakePool.toBase58()); - expect(instruction.keys[1].pubkey.toBase58()).toEqual(payload.withdrawAuthority.toBase58()); - expect(instruction.keys[3].pubkey.toBase58()).toEqual(payload.fundingAccount.toBase58()); - expect(instruction.keys[4].pubkey.toBase58()).toEqual( - payload.destinationPoolAccount.toBase58(), - ); - expect(instruction.keys[5].pubkey.toBase58()).toEqual(payload.managerFeeAccount.toBase58()); - expect(instruction.keys[6].pubkey.toBase58()).toEqual(payload.referralPoolAccount.toBase58()); - expect(instruction.keys[8].pubkey.toBase58()).toEqual(SystemProgram.programId.toBase58()); - expect(instruction.keys[9].pubkey.toBase58()).toEqual(STAKE_POOL_PROGRAM_ID.toBase58()); + expect(instruction.keys[0].pubkey).toEqual(payload.stakePool); + expect(instruction.keys[1].pubkey).toEqual(payload.withdrawAuthority); + expect(instruction.keys[3].pubkey).toEqual(payload.fundingAccount); + expect(instruction.keys[4].pubkey).toEqual(payload.destinationPoolAccount); + expect(instruction.keys[5].pubkey).toEqual(payload.managerFeeAccount); + expect(instruction.keys[6].pubkey).toEqual(payload.referralPoolAccount); + expect(instruction.keys[8].pubkey).toEqual(SystemProgram.programId); + expect(instruction.keys[9].pubkey).toEqual(TOKEN_PROGRAM_ID); const decodedData = decodeData(STAKE_POOL_INSTRUCTION_LAYOUTS.DepositSol, instruction.data); @@ -86,7 +93,7 @@ describe('StakePoolProgram', () => { const instruction2 = StakePoolInstruction.depositSol(payload); expect(instruction2.keys).toHaveLength(11); - expect(instruction2.keys[10].pubkey.toBase58()).toEqual(payload.depositAuthority.toBase58()); + expect(instruction2.keys[10].pubkey).toEqual(payload.depositAuthority); }); describe('depositSol', () => { @@ -107,20 +114,20 @@ describe('StakePoolProgram', () => { }; }); - it.only('should throw an error with invalid balance', async () => { + it('should throw an error with invalid balance', async () => { await expect(depositSol(connection, stakePoolAddress, from, balance + 1)).rejects.toThrow( Error('Not enough SOL to deposit into pool. Maximum deposit amount is 0.00001 SOL.'), ); }); - it.only('should throw an error with invalid account', async () => { + it('should throw an error with invalid account', async () => { connection.getAccountInfo = jest.fn(async () => null); await expect(depositSol(connection, stakePoolAddress, from, balance)).rejects.toThrow( Error('Invalid stake pool account'), ); }); - it.only('should call successfully', async () => { + it('should call successfully', async () => { connection.getAccountInfo = jest.fn(async (pubKey) => { if (pubKey == stakePoolAddress) { return stakePoolAccount; @@ -145,14 +152,14 @@ describe('StakePoolProgram', () => { const tokenOwner = new PublicKey(0); const solReceiver = new PublicKey(1); - it.only('should throw an error with invalid stake pool account', async () => { + it('should throw an error with invalid stake pool account', async () => { connection.getAccountInfo = jest.fn(async () => null); await expect( withdrawSol(connection, stakePoolAddress, tokenOwner, solReceiver, 1), ).rejects.toThrowError('Invalid stake pool account'); }); - it.only('should throw an error with invalid token account', async () => { + it('should throw an error with invalid token account', async () => { connection.getAccountInfo = jest.fn(async (pubKey: PublicKey) => { if (pubKey == stakePoolAddress) { return stakePoolAccount; @@ -168,7 +175,7 @@ describe('StakePoolProgram', () => { ).rejects.toThrow(Error('Invalid token account')); }); - it.only('should throw an error with invalid token account balance', async () => { + it('should throw an error with invalid token account balance', async () => { connection.getAccountInfo = jest.fn(async (pubKey: PublicKey) => { if (pubKey == stakePoolAddress) { return stakePoolAccount; @@ -188,7 +195,7 @@ describe('StakePoolProgram', () => { ); }); - it.only('should call successfully', async () => { + it('should call successfully', async () => { connection.getAccountInfo = jest.fn(async (pubKey: PublicKey) => { if (pubKey == stakePoolAddress) { return stakePoolAccount; @@ -209,7 +216,7 @@ describe('StakePoolProgram', () => { describe('withdrawStake', () => { const tokenOwner = new PublicKey(0); - it.only('should throw an error with invalid token account', async () => { + it('should throw an error with invalid token account', async () => { connection.getAccountInfo = jest.fn(async (pubKey: PublicKey) => { if (pubKey == stakePoolAddress) { return stakePoolAccount; @@ -222,7 +229,7 @@ describe('StakePoolProgram', () => { ); }); - it.only('should throw an error with invalid token account balance', async () => { + it('should throw an error with invalid token account balance', async () => { connection.getAccountInfo = jest.fn(async (pubKey: PublicKey) => { if (pubKey == stakePoolAddress) { return stakePoolAccount; @@ -241,7 +248,7 @@ describe('StakePoolProgram', () => { ); }); - it.only('should call successfully', async () => { + it('should call successfully', async () => { connection.getAccountInfo = jest.fn(async (pubKey: PublicKey) => { if (pubKey == stakePoolAddress) { return stakePoolAccount; @@ -263,7 +270,7 @@ describe('StakePoolProgram', () => { expect(res.totalRentFreeBalances).toEqual(10000); }); - it.only('withdraw to a stake account provided', async () => { + it('withdraw to a stake account provided', async () => { const stakeReceiver = new PublicKey(20); connection.getAccountInfo = jest.fn(async (pubKey: PublicKey) => { if (pubKey == stakePoolAddress) { @@ -305,7 +312,7 @@ describe('StakePoolProgram', () => { }); }); describe('getStakeAccount', () => { - it.only('returns an uninitialized parsed stake account', async () => { + it('returns an uninitialized parsed stake account', async () => { const stakeAccount = new PublicKey(20); connection.getParsedAccountInfo = jest.fn(async (pubKey: PublicKey) => { if (pubKey.equals(stakeAccount)) { @@ -320,7 +327,7 @@ describe('StakePoolProgram', () => { }); describe('redelegation', () => { - it.only('should call successfully', async () => { + it('should call successfully', async () => { const data = { connection, stakePoolAddress, diff --git a/clients/js-legacy/tsconfig.json b/clients/js-legacy/tsconfig.json index 9e8b3120..2ae40abe 100644 --- a/clients/js-legacy/tsconfig.json +++ b/clients/js-legacy/tsconfig.json @@ -15,7 +15,8 @@ "resolveJsonModule": true, "isolatedModules": true, "noFallthroughCasesInSwitch": true, - "noImplicitReturns": true + "noImplicitReturns": true, + "skipLibCheck": true // needed to avoid re-export errors from borsh }, "include": ["src/**/*.ts"] } From 280819689d1db32743faa854a2421366ef348bb8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 May 2023 16:09:19 +0200 Subject: [PATCH 0338/1076] build(deps-dev): bump rimraf from 3.0.2 to 5.0.0 in /stake-pool/js (#4302) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 553 +++++++++++++++++++++++++++- clients/js-legacy/package.json | 2 +- 2 files changed, 544 insertions(+), 11 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 54c9d161..73e29837 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -35,7 +35,7 @@ "eslint-plugin-prettier": "^4.2.1", "jest": "^27.5.1", "prettier": "^2.8.8", - "rimraf": "^3.0.2", + "rimraf": "^5.0.0", "rollup": "^2.66.1", "rollup-plugin-dts": "^4.2.3", "rollup-plugin-node-polyfills": "^0.2.1", @@ -749,6 +749,102 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "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" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", + "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -869,6 +965,21 @@ } } }, + "node_modules/@jest/core/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@jest/environment": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", @@ -1163,6 +1274,16 @@ "node": ">= 8" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@rollup/plugin-alias": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.0.0.tgz", @@ -2748,6 +2869,12 @@ "node": ">=10" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, "node_modules/electron-to-chromium": { "version": "1.4.68", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.68.tgz", @@ -3384,12 +3511,55 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/flatted": { "version": "3.2.5", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", "dev": true }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz", + "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/form-data": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", @@ -3949,6 +4119,24 @@ "node": ">=8" } }, + "node_modules/jackspeak": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.0.tgz", + "integrity": "sha512-r5XBrqIJfwRIjRt/Xr5fv9Wh09qyhHfKnYddDlpM+ibRR20qrYActpCAgU6U+d53EOEjzkvxPMVHSlgR7leXrQ==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/jayson": { "version": "3.6.6", "resolved": "https://registry.npmjs.org/jayson/-/jayson-3.6.6.tgz", @@ -4951,6 +5139,15 @@ "node": "*" } }, + "node_modules/minipass": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-6.0.0.tgz", + "integrity": "sha512-mvD5U4pUen1aWcjTxUgdoMg6PB98dcV0obc/OiPzls79++IpgNoO+MCbOHRlKfWIOvjIjmjUygjZmSStP7B0Og==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -5202,6 +5399,31 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "node_modules/path-scurry": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.9.1.tgz", + "integrity": "sha512-UgmoiySyjFxP6tscZDgWGEAgsW5ok8W3F5CJDnnH2pozwSTGE6eH7vwTotMwATWA2r5xqdkKdxYPkwlJjAI/3g==", + "dev": true, + "dependencies": { + "lru-cache": "^9.1.1", + "minipass": "^5.0.0 || ^6.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.1.tgz", + "integrity": "sha512-65/Jky17UwSb0BuB9V+MyDpsOtXKmYwzhyl+cOa9XUiI4uV2Ouy/2voFP3+al0BjZbJgMBD8FojMpAf+Z+qn4A==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -5456,15 +5678,64 @@ } }, "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.0.tgz", + "integrity": "sha512-Jf9llaP+RvaEVS5nPShYFhtXIrb3LRKP281ib3So0KkeZKo2wIKyq0Re7TOSwanasA423PSr6CCIL4bP6T040g==", "dev": true, "dependencies": { - "glob": "^7.1.3" + "glob": "^10.0.0" }, "bin": { - "rimraf": "bin.js" + "rimraf": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.2.4.tgz", + "integrity": "sha512-fDboBse/sl1oXSLhIp0FcCJgzW9KmhC/q8ULTKC82zc+DL3TL7FNb8qlt5qqXN53MsKEUSIcb+7DLmEygOE5Yw==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.0.3", + "minimatch": "^9.0.0", + "minipass": "^5.0.0 || ^6.0.0", + "path-scurry": "^1.7.0" + }, + "bin": { + "glob": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz", + "integrity": "sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -5834,6 +6105,21 @@ "node": ">=8" } }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -5846,6 +6132,19 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", @@ -6346,6 +6645,24 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -6979,6 +7296,71 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true + }, + "ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true + }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + }, + "strip-ansi": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", + "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + }, + "wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "requires": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + } + } + } + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -7073,6 +7455,17 @@ "rimraf": "^3.0.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" + }, + "dependencies": { + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } } }, "@jest/environment": { @@ -7304,6 +7697,13 @@ "fastq": "^1.6.0" } }, + "@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true + }, "@rollup/plugin-alias": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.0.0.tgz", @@ -8463,6 +8863,12 @@ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" }, + "eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, "electron-to-chromium": { "version": "1.4.68", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.68.tgz", @@ -8936,6 +9342,17 @@ "requires": { "flatted": "^3.1.0", "rimraf": "^3.0.2" + }, + "dependencies": { + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } } }, "flatted": { @@ -8944,6 +9361,24 @@ "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", "dev": true }, + "foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "dependencies": { + "signal-exit": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz", + "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==", + "dev": true + } + } + }, "form-data": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", @@ -9350,6 +9785,16 @@ "istanbul-lib-report": "^3.0.0" } }, + "jackspeak": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.0.tgz", + "integrity": "sha512-r5XBrqIJfwRIjRt/Xr5fv9Wh09qyhHfKnYddDlpM+ibRR20qrYActpCAgU6U+d53EOEjzkvxPMVHSlgR7leXrQ==", + "dev": true, + "requires": { + "@isaacs/cliui": "^8.0.2", + "@pkgjs/parseargs": "^0.11.0" + } + }, "jayson": { "version": "3.6.6", "resolved": "https://registry.npmjs.org/jayson/-/jayson-3.6.6.tgz", @@ -10129,6 +10574,12 @@ "brace-expansion": "^1.1.7" } }, + "minipass": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-6.0.0.tgz", + "integrity": "sha512-mvD5U4pUen1aWcjTxUgdoMg6PB98dcV0obc/OiPzls79++IpgNoO+MCbOHRlKfWIOvjIjmjUygjZmSStP7B0Og==", + "dev": true + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -10321,6 +10772,24 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "path-scurry": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.9.1.tgz", + "integrity": "sha512-UgmoiySyjFxP6tscZDgWGEAgsW5ok8W3F5CJDnnH2pozwSTGE6eH7vwTotMwATWA2r5xqdkKdxYPkwlJjAI/3g==", + "dev": true, + "requires": { + "lru-cache": "^9.1.1", + "minipass": "^5.0.0 || ^6.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.1.tgz", + "integrity": "sha512-65/Jky17UwSb0BuB9V+MyDpsOtXKmYwzhyl+cOa9XUiI4uV2Ouy/2voFP3+al0BjZbJgMBD8FojMpAf+Z+qn4A==", + "dev": true + } + } + }, "path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -10495,12 +10964,45 @@ "dev": true }, "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.0.tgz", + "integrity": "sha512-Jf9llaP+RvaEVS5nPShYFhtXIrb3LRKP281ib3So0KkeZKo2wIKyq0Re7TOSwanasA423PSr6CCIL4bP6T040g==", "dev": true, "requires": { - "glob": "^7.1.3" + "glob": "^10.0.0" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "glob": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.2.4.tgz", + "integrity": "sha512-fDboBse/sl1oXSLhIp0FcCJgzW9KmhC/q8ULTKC82zc+DL3TL7FNb8qlt5qqXN53MsKEUSIcb+7DLmEygOE5Yw==", + "dev": true, + "requires": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.0.3", + "minimatch": "^9.0.0", + "minipass": "^5.0.0 || ^6.0.0", + "path-scurry": "^1.7.0" + } + }, + "minimatch": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz", + "integrity": "sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } } }, "rollup": { @@ -10770,6 +11272,17 @@ "strip-ansi": "^6.0.1" } }, + "string-width-cjs": { + "version": "npm:string-width@4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -10779,6 +11292,15 @@ "ansi-regex": "^5.0.1" } }, + "strip-ansi-cjs": { + "version": "npm:strip-ansi@6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, "strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", @@ -11139,6 +11661,17 @@ "strip-ansi": "^6.0.0" } }, + "wrap-ansi-cjs": { + "version": "npm:wrap-ansi@7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index e0450ff9..321ec9d5 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -70,7 +70,7 @@ "eslint-plugin-prettier": "^4.2.1", "jest": "^27.5.1", "prettier": "^2.8.8", - "rimraf": "^3.0.2", + "rimraf": "^5.0.0", "rollup": "^2.66.1", "rollup-plugin-dts": "^4.2.3", "rollup-plugin-node-polyfills": "^0.2.1", From e015a4e6b5da812c09af3b2e90bf8ed27b938a94 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 May 2023 16:09:29 +0200 Subject: [PATCH 0339/1076] build(deps-dev): bump @rollup/plugin-commonjs from 21.0.1 to 25.0.0 in /stake-pool/js (#4303) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 333 ++++++++++++---------------- clients/js-legacy/package.json | 2 +- 2 files changed, 141 insertions(+), 194 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 73e29837..5e2be30b 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -18,7 +18,7 @@ }, "devDependencies": { "@rollup/plugin-alias": "^5.0.0", - "@rollup/plugin-commonjs": "^21.0.1", + "@rollup/plugin-commonjs": "^25.0.0", "@rollup/plugin-json": "^6.0.0", "@rollup/plugin-multi-entry": "^6.0.0", "@rollup/plugin-node-resolve": "^15.0.2", @@ -1317,55 +1317,89 @@ } }, "node_modules/@rollup/plugin-commonjs": { - "version": "21.0.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-21.0.1.tgz", - "integrity": "sha512-EA+g22lbNJ8p5kuZJUYyhhDK7WgJckW5g4pNN7n4mAFUM96VuwUnNT3xr2Db2iCZPI1pJPbGyfT5mS9T1dHfMg==", + "version": "25.0.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.0.tgz", + "integrity": "sha512-hoho2Kay9TZrLu0bnDsTTCaj4Npa+THk9snajP/XDNb9a9mmjTjh52EQM9sKl3HD1LsnihX7js+eA2sd2uKAhw==", "dev": true, "dependencies": { - "@rollup/pluginutils": "^3.1.0", + "@rollup/pluginutils": "^5.0.1", "commondir": "^1.0.1", - "estree-walker": "^2.0.1", - "glob": "^7.1.6", - "is-reference": "^1.2.1", - "magic-string": "^0.25.7", - "resolve": "^1.17.0" + "estree-walker": "^2.0.2", + "glob": "^8.0.3", + "is-reference": "1.2.1", + "magic-string": "^0.27.0" }, "engines": { - "node": ">= 8.0.0" + "node": ">=14.0.0" }, "peerDependencies": { - "rollup": "^2.38.3" + "rollup": "^2.68.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } } }, - "node_modules/@rollup/plugin-json": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.0.0.tgz", - "integrity": "sha512-i/4C5Jrdr1XUarRhVu27EEwjt4GObltD7c+MkCIpO2QIbojw8MUs+CCTqOphQi3Qtg1FLmYt+l+6YeoIf51J7w==", + "node_modules/@rollup/plugin-commonjs/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "dependencies": { - "@rollup/pluginutils": "^5.0.1" + "balanced-match": "^1.0.0" + } + }, + "node_modules/@rollup/plugin-commonjs/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" }, "engines": { - "node": ">=14.0.0" + "node": ">=12" }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0" + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@rollup/plugin-commonjs/node_modules/magic-string": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", + "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.13" }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } + "engines": { + "node": ">=12" } }, - "node_modules/@rollup/plugin-json/node_modules/@rollup/pluginutils": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", - "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", + "node_modules/@rollup/plugin-commonjs/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@rollup/plugin-json": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.0.0.tgz", + "integrity": "sha512-i/4C5Jrdr1XUarRhVu27EEwjt4GObltD7c+MkCIpO2QIbojw8MUs+CCTqOphQi3Qtg1FLmYt+l+6YeoIf51J7w==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^5.0.1" }, "engines": { "node": ">=14.0.0" @@ -1379,12 +1413,6 @@ } } }, - "node_modules/@rollup/plugin-json/node_modules/@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", - "dev": true - }, "node_modules/@rollup/plugin-multi-entry": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-multi-entry/-/plugin-multi-entry-6.0.0.tgz", @@ -1431,34 +1459,6 @@ } } }, - "node_modules/@rollup/plugin-node-resolve/node_modules/@rollup/pluginutils": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", - "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", - "dev": true, - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-node-resolve/node_modules/@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", - "dev": true - }, "node_modules/@rollup/plugin-typescript": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.0.tgz", @@ -1485,34 +1485,6 @@ } } }, - "node_modules/@rollup/plugin-typescript/node_modules/@rollup/pluginutils": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", - "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", - "dev": true, - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-typescript/node_modules/@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", - "dev": true - }, "node_modules/@rollup/plugin-virtual": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-virtual/-/plugin-virtual-3.0.1.tgz", @@ -1531,28 +1503,27 @@ } }, "node_modules/@rollup/pluginutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", - "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", + "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", "dev": true, "dependencies": { - "@types/estree": "0.0.39", - "estree-walker": "^1.0.1", - "picomatch": "^2.2.2" + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" }, "engines": { - "node": ">= 8.0.0" + "node": ">=14.0.0" }, "peerDependencies": { - "rollup": "^1.20.0||^2.0.0" + "rollup": "^1.20.0||^2.0.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } } }, - "node_modules/@rollup/pluginutils/node_modules/estree-walker": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", - "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", - "dev": true - }, "node_modules/@sinonjs/commons": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", @@ -1688,9 +1659,9 @@ } }, "node_modules/@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", "dev": true }, "node_modules/@types/express-serve-static-core": { @@ -7722,18 +7693,59 @@ } }, "@rollup/plugin-commonjs": { - "version": "21.0.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-21.0.1.tgz", - "integrity": "sha512-EA+g22lbNJ8p5kuZJUYyhhDK7WgJckW5g4pNN7n4mAFUM96VuwUnNT3xr2Db2iCZPI1pJPbGyfT5mS9T1dHfMg==", + "version": "25.0.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.0.tgz", + "integrity": "sha512-hoho2Kay9TZrLu0bnDsTTCaj4Npa+THk9snajP/XDNb9a9mmjTjh52EQM9sKl3HD1LsnihX7js+eA2sd2uKAhw==", "dev": true, "requires": { - "@rollup/pluginutils": "^3.1.0", + "@rollup/pluginutils": "^5.0.1", "commondir": "^1.0.1", - "estree-walker": "^2.0.1", - "glob": "^7.1.6", - "is-reference": "^1.2.1", - "magic-string": "^0.25.7", - "resolve": "^1.17.0" + "estree-walker": "^2.0.2", + "glob": "^8.0.3", + "is-reference": "1.2.1", + "magic-string": "^0.27.0" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + } + }, + "magic-string": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", + "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", + "dev": true, + "requires": { + "@jridgewell/sourcemap-codec": "^1.4.13" + } + }, + "minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } } }, "@rollup/plugin-json": { @@ -7743,25 +7755,6 @@ "dev": true, "requires": { "@rollup/pluginutils": "^5.0.1" - }, - "dependencies": { - "@rollup/pluginutils": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", - "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", - "dev": true, - "requires": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" - } - }, - "@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", - "dev": true - } } }, "@rollup/plugin-multi-entry": { @@ -7786,25 +7779,6 @@ "is-builtin-module": "^3.2.1", "is-module": "^1.0.0", "resolve": "^1.22.1" - }, - "dependencies": { - "@rollup/pluginutils": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", - "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", - "dev": true, - "requires": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" - } - }, - "@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", - "dev": true - } } }, "@rollup/plugin-typescript": { @@ -7815,25 +7789,6 @@ "requires": { "@rollup/pluginutils": "^5.0.1", "resolve": "^1.22.1" - }, - "dependencies": { - "@rollup/pluginutils": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", - "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", - "dev": true, - "requires": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" - } - }, - "@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", - "dev": true - } } }, "@rollup/plugin-virtual": { @@ -7844,22 +7799,14 @@ "requires": {} }, "@rollup/pluginutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", - "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", + "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", "dev": true, "requires": { - "@types/estree": "0.0.39", - "estree-walker": "^1.0.1", - "picomatch": "^2.2.2" - }, - "dependencies": { - "estree-walker": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", - "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", - "dev": true - } + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" } }, "@sinonjs/commons": { @@ -7988,9 +7935,9 @@ } }, "@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", "dev": true }, "@types/express-serve-static-core": { diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 321ec9d5..f6b2e054 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -53,7 +53,7 @@ }, "devDependencies": { "@rollup/plugin-alias": "^5.0.0", - "@rollup/plugin-commonjs": "^21.0.1", + "@rollup/plugin-commonjs": "^25.0.0", "@rollup/plugin-json": "^6.0.0", "@rollup/plugin-multi-entry": "^6.0.0", "@rollup/plugin-node-resolve": "^15.0.2", From 28f27975178fa3dd201e331bc5e29d6ac50784b3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 May 2023 16:50:03 +0200 Subject: [PATCH 0340/1076] build(deps-dev): bump @rollup/plugin-typescript from 11.1.0 to 11.1.1 in /stake-pool/js (#4317) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 5e2be30b..30fae6e7 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1460,9 +1460,9 @@ } }, "node_modules/@rollup/plugin-typescript": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.0.tgz", - "integrity": "sha512-86flrfE+bSHB69znnTV6kVjkncs2LBMhcTCyxWgRxLyfXfQrxg4UwlAqENnjrrxnSNS/XKCDJCl8EkdFJVHOxw==", + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.1.tgz", + "integrity": "sha512-Ioir+x5Bejv72Lx2Zbz3/qGg7tvGbxQZALCLoJaGrkNXak/19+vKgKYJYM3i/fJxvsb23I9FuFQ8CUBEfsmBRg==", "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1", @@ -7782,9 +7782,9 @@ } }, "@rollup/plugin-typescript": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.0.tgz", - "integrity": "sha512-86flrfE+bSHB69znnTV6kVjkncs2LBMhcTCyxWgRxLyfXfQrxg4UwlAqENnjrrxnSNS/XKCDJCl8EkdFJVHOxw==", + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.1.tgz", + "integrity": "sha512-Ioir+x5Bejv72Lx2Zbz3/qGg7tvGbxQZALCLoJaGrkNXak/19+vKgKYJYM3i/fJxvsb23I9FuFQ8CUBEfsmBRg==", "dev": true, "requires": { "@rollup/pluginutils": "^5.0.1", From fe92f971c62417ea27af5a35fe348d48e3711226 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 May 2023 16:50:23 +0200 Subject: [PATCH 0341/1076] build(deps-dev): bump @typescript-eslint/parser from 5.59.5 to 5.59.6 in /stake-pool/js (#4318) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 141 +++++++++++++++++++++++++--- 1 file changed, 129 insertions(+), 12 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 30fae6e7..81c8648f 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1835,14 +1835,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.5.tgz", - "integrity": "sha512-NJXQC4MRnF9N9yWqQE2/KLRSOLvrrlZb48NGVfBa+RuPMN6B7ZcK5jZOvhuygv4D64fRKnZI4L4p8+M+rfeQuw==", + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.6.tgz", + "integrity": "sha512-7pCa6al03Pv1yf/dUg/s1pXz/yGMUBAw5EeWqNTFiSueKvRNonze3hma3lhdsOrQcaOXhbk5gKu2Fludiho9VA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.59.5", - "@typescript-eslint/types": "5.59.5", - "@typescript-eslint/typescript-estree": "5.59.5", + "@typescript-eslint/scope-manager": "5.59.6", + "@typescript-eslint/types": "5.59.6", + "@typescript-eslint/typescript-estree": "5.59.6", "debug": "^4.3.4" }, "engines": { @@ -1861,6 +1861,80 @@ } } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.6.tgz", + "integrity": "sha512-gLbY3Le9Dxcb8KdpF0+SJr6EQ+hFGYFl6tVY8VxLPFDfUZC7BHFw+Vq7bM5lE9DwWPfx4vMWWTLGXgpc0mAYyQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.6", + "@typescript-eslint/visitor-keys": "5.59.6" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.6.tgz", + "integrity": "sha512-tH5lBXZI7T2MOUgOWFdVNUILsI02shyQvfzG9EJkoONWugCG77NDDa1EeDGw7oJ5IvsTAAGVV8I3Tk2PNu9QfA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.6.tgz", + "integrity": "sha512-vW6JP3lMAs/Tq4KjdI/RiHaaJSO7IUsbkz17it/Rl9Q+WkQ77EOuOnlbaU8kKfVIOJxMhnRiBG+olE7f3M16DA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.6", + "@typescript-eslint/visitor-keys": "5.59.6", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.6.tgz", + "integrity": "sha512-zEfbFLzB9ETcEJ4HZEEsCR9HHeNku5/Qw1jSS5McYJv5BR+ftYXwFFAH5Al+xkGaZEqowMwl7uoJjQb1YSPF8Q==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.6", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "5.59.5", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.5.tgz", @@ -8095,15 +8169,58 @@ } }, "@typescript-eslint/parser": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.5.tgz", - "integrity": "sha512-NJXQC4MRnF9N9yWqQE2/KLRSOLvrrlZb48NGVfBa+RuPMN6B7ZcK5jZOvhuygv4D64fRKnZI4L4p8+M+rfeQuw==", + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.6.tgz", + "integrity": "sha512-7pCa6al03Pv1yf/dUg/s1pXz/yGMUBAw5EeWqNTFiSueKvRNonze3hma3lhdsOrQcaOXhbk5gKu2Fludiho9VA==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.59.5", - "@typescript-eslint/types": "5.59.5", - "@typescript-eslint/typescript-estree": "5.59.5", + "@typescript-eslint/scope-manager": "5.59.6", + "@typescript-eslint/types": "5.59.6", + "@typescript-eslint/typescript-estree": "5.59.6", "debug": "^4.3.4" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.6.tgz", + "integrity": "sha512-gLbY3Le9Dxcb8KdpF0+SJr6EQ+hFGYFl6tVY8VxLPFDfUZC7BHFw+Vq7bM5lE9DwWPfx4vMWWTLGXgpc0mAYyQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.6", + "@typescript-eslint/visitor-keys": "5.59.6" + } + }, + "@typescript-eslint/types": { + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.6.tgz", + "integrity": "sha512-tH5lBXZI7T2MOUgOWFdVNUILsI02shyQvfzG9EJkoONWugCG77NDDa1EeDGw7oJ5IvsTAAGVV8I3Tk2PNu9QfA==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.6.tgz", + "integrity": "sha512-vW6JP3lMAs/Tq4KjdI/RiHaaJSO7IUsbkz17it/Rl9Q+WkQ77EOuOnlbaU8kKfVIOJxMhnRiBG+olE7f3M16DA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.6", + "@typescript-eslint/visitor-keys": "5.59.6", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.6.tgz", + "integrity": "sha512-zEfbFLzB9ETcEJ4HZEEsCR9HHeNku5/Qw1jSS5McYJv5BR+ftYXwFFAH5Al+xkGaZEqowMwl7uoJjQb1YSPF8Q==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.6", + "eslint-visitor-keys": "^3.3.0" + } + } } }, "@typescript-eslint/scope-manager": { From c99d3cbe515ff1c04f7b7758f4a1a48ec743580e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 May 2023 15:26:21 +0200 Subject: [PATCH 0342/1076] build(deps-dev): bump @types/node from 20.1.3 to 20.1.7 in /stake-pool/js (#4332) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 81c8648f..8ebff709 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1729,9 +1729,9 @@ "integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==" }, "node_modules/@types/node": { - "version": "20.1.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.3.tgz", - "integrity": "sha512-NP2yfZpgmf2eDRPmgGq+fjGjSwFgYbihA8/gK+ey23qT9RkxsgNTZvGOEpXgzIGqesTYkElELLgtKoMQTys5vA==" + "version": "20.1.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.7.tgz", + "integrity": "sha512-WCuw/o4GSwDGMoonES8rcvwsig77dGCMbZDrZr2x4ZZiNW4P/gcoZXe/0twgtobcTkmg9TuKflxYL/DuwDyJzg==" }, "node_modules/@types/node-fetch": { "version": "2.6.3", @@ -8079,9 +8079,9 @@ "integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==" }, "@types/node": { - "version": "20.1.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.3.tgz", - "integrity": "sha512-NP2yfZpgmf2eDRPmgGq+fjGjSwFgYbihA8/gK+ey23qT9RkxsgNTZvGOEpXgzIGqesTYkElELLgtKoMQTys5vA==" + "version": "20.1.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.7.tgz", + "integrity": "sha512-WCuw/o4GSwDGMoonES8rcvwsig77dGCMbZDrZr2x4ZZiNW4P/gcoZXe/0twgtobcTkmg9TuKflxYL/DuwDyJzg==" }, "@types/node-fetch": { "version": "2.6.3", From 61ee084354e77ca392b74736db6fe859a7bd0f14 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 May 2023 15:53:38 +0200 Subject: [PATCH 0343/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 5.59.5 to 5.59.6 in /stake-pool/js (#4333) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 245 ++++++++-------------------- 1 file changed, 64 insertions(+), 181 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 8ebff709..339bd402 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1801,15 +1801,15 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.5.tgz", - "integrity": "sha512-feA9xbVRWJZor+AnLNAr7A8JRWeZqHUf4T9tlP+TN04b05pFVhO5eN7/O93Y/1OUlLMHKbnJisgDURs/qvtqdg==", + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.6.tgz", + "integrity": "sha512-sXtOgJNEuRU5RLwPUb1jxtToZbgvq3M6FPpY4QENxoOggK+UpTxUBpj6tD8+Qh2g46Pi9We87E+eHnUw8YcGsw==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.5", - "@typescript-eslint/type-utils": "5.59.5", - "@typescript-eslint/utils": "5.59.5", + "@typescript-eslint/scope-manager": "5.59.6", + "@typescript-eslint/type-utils": "5.59.6", + "@typescript-eslint/utils": "5.59.6", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", @@ -1861,7 +1861,7 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "node_modules/@typescript-eslint/scope-manager": { "version": "5.59.6", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.6.tgz", "integrity": "sha512-gLbY3Le9Dxcb8KdpF0+SJr6EQ+hFGYFl6tVY8VxLPFDfUZC7BHFw+Vq7bM5lE9DwWPfx4vMWWTLGXgpc0mAYyQ==", @@ -1878,88 +1878,14 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "5.59.6", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.6.tgz", - "integrity": "sha512-tH5lBXZI7T2MOUgOWFdVNUILsI02shyQvfzG9EJkoONWugCG77NDDa1EeDGw7oJ5IvsTAAGVV8I3Tk2PNu9QfA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.59.6", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.6.tgz", - "integrity": "sha512-vW6JP3lMAs/Tq4KjdI/RiHaaJSO7IUsbkz17it/Rl9Q+WkQ77EOuOnlbaU8kKfVIOJxMhnRiBG+olE7f3M16DA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.6", - "@typescript-eslint/visitor-keys": "5.59.6", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.59.6", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.6.tgz", - "integrity": "sha512-zEfbFLzB9ETcEJ4HZEEsCR9HHeNku5/Qw1jSS5McYJv5BR+ftYXwFFAH5Al+xkGaZEqowMwl7uoJjQb1YSPF8Q==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.6", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.5.tgz", - "integrity": "sha512-jVecWwnkX6ZgutF+DovbBJirZcAxgxC0EOHYt/niMROf8p4PwxxG32Qdhj/iIQQIuOflLjNkxoXyArkcIP7C3A==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.5", - "@typescript-eslint/visitor-keys": "5.59.5" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.5.tgz", - "integrity": "sha512-4eyhS7oGym67/pSxA2mmNq7X164oqDYNnZCUayBwJZIRVvKpBCMBzFnFxjeoDeShjtO6RQBHBuwybuX3POnDqg==", + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.6.tgz", + "integrity": "sha512-A4tms2Mp5yNvLDlySF+kAThV9VTBPCvGf0Rp8nl/eoDX9Okun8byTKoj3fJ52IJitjWOk0fKPNQhXEB++eNozQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.59.5", - "@typescript-eslint/utils": "5.59.5", + "@typescript-eslint/typescript-estree": "5.59.6", + "@typescript-eslint/utils": "5.59.6", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -1980,9 +1906,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.5.tgz", - "integrity": "sha512-xkfRPHbqSH4Ggx4eHRIO/eGL8XL4Ysb4woL8c87YuAo8Md7AUjyWKa9YMwTL519SyDPrfEgKdewjkxNCVeJW7w==", + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.6.tgz", + "integrity": "sha512-tH5lBXZI7T2MOUgOWFdVNUILsI02shyQvfzG9EJkoONWugCG77NDDa1EeDGw7oJ5IvsTAAGVV8I3Tk2PNu9QfA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1993,13 +1919,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.5.tgz", - "integrity": "sha512-+XXdLN2CZLZcD/mO7mQtJMvCkzRfmODbeSKuMY/yXbGkzvA9rJyDY5qDYNoiz2kP/dmyAxXquL2BvLQLJFPQIg==", + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.6.tgz", + "integrity": "sha512-vW6JP3lMAs/Tq4KjdI/RiHaaJSO7IUsbkz17it/Rl9Q+WkQ77EOuOnlbaU8kKfVIOJxMhnRiBG+olE7f3M16DA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.5", - "@typescript-eslint/visitor-keys": "5.59.5", + "@typescript-eslint/types": "5.59.6", + "@typescript-eslint/visitor-keys": "5.59.6", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2020,17 +1946,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.5.tgz", - "integrity": "sha512-sCEHOiw+RbyTii9c3/qN74hYDPNORb8yWCoPLmB7BIflhplJ65u2PBpdRla12e3SSTJ2erRkPjz7ngLHhUegxA==", + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.6.tgz", + "integrity": "sha512-vzaaD6EXbTS29cVH0JjXBdzMt6VBlv+hE31XktDRMX1j3462wZCJa7VzO2AxXEXcIl8GQqZPcOPuW/Z1tZVogg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.5", - "@typescript-eslint/types": "5.59.5", - "@typescript-eslint/typescript-estree": "5.59.5", + "@typescript-eslint/scope-manager": "5.59.6", + "@typescript-eslint/types": "5.59.6", + "@typescript-eslint/typescript-estree": "5.59.6", "eslint-scope": "^5.1.1", "semver": "^7.3.7" }, @@ -2046,12 +1972,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.5.tgz", - "integrity": "sha512-qL+Oz+dbeBRTeyJTIy0eniD3uvqU7x+y1QceBismZ41hd4aBSRh8UAw4pZP0+XzLuPZmx4raNMq/I+59W2lXKA==", + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.6.tgz", + "integrity": "sha512-zEfbFLzB9ETcEJ4HZEEsCR9HHeNku5/Qw1jSS5McYJv5BR+ftYXwFFAH5Al+xkGaZEqowMwl7uoJjQb1YSPF8Q==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.5", + "@typescript-eslint/types": "5.59.6", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -8151,15 +8077,15 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.5.tgz", - "integrity": "sha512-feA9xbVRWJZor+AnLNAr7A8JRWeZqHUf4T9tlP+TN04b05pFVhO5eN7/O93Y/1OUlLMHKbnJisgDURs/qvtqdg==", + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.6.tgz", + "integrity": "sha512-sXtOgJNEuRU5RLwPUb1jxtToZbgvq3M6FPpY4QENxoOggK+UpTxUBpj6tD8+Qh2g46Pi9We87E+eHnUw8YcGsw==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.5", - "@typescript-eslint/type-utils": "5.59.5", - "@typescript-eslint/utils": "5.59.5", + "@typescript-eslint/scope-manager": "5.59.6", + "@typescript-eslint/type-utils": "5.59.6", + "@typescript-eslint/utils": "5.59.6", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", @@ -8178,87 +8104,44 @@ "@typescript-eslint/types": "5.59.6", "@typescript-eslint/typescript-estree": "5.59.6", "debug": "^4.3.4" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "5.59.6", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.6.tgz", - "integrity": "sha512-gLbY3Le9Dxcb8KdpF0+SJr6EQ+hFGYFl6tVY8VxLPFDfUZC7BHFw+Vq7bM5lE9DwWPfx4vMWWTLGXgpc0mAYyQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.6", - "@typescript-eslint/visitor-keys": "5.59.6" - } - }, - "@typescript-eslint/types": { - "version": "5.59.6", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.6.tgz", - "integrity": "sha512-tH5lBXZI7T2MOUgOWFdVNUILsI02shyQvfzG9EJkoONWugCG77NDDa1EeDGw7oJ5IvsTAAGVV8I3Tk2PNu9QfA==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.59.6", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.6.tgz", - "integrity": "sha512-vW6JP3lMAs/Tq4KjdI/RiHaaJSO7IUsbkz17it/Rl9Q+WkQ77EOuOnlbaU8kKfVIOJxMhnRiBG+olE7f3M16DA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.6", - "@typescript-eslint/visitor-keys": "5.59.6", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.59.6", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.6.tgz", - "integrity": "sha512-zEfbFLzB9ETcEJ4HZEEsCR9HHeNku5/Qw1jSS5McYJv5BR+ftYXwFFAH5Al+xkGaZEqowMwl7uoJjQb1YSPF8Q==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.6", - "eslint-visitor-keys": "^3.3.0" - } - } } }, "@typescript-eslint/scope-manager": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.5.tgz", - "integrity": "sha512-jVecWwnkX6ZgutF+DovbBJirZcAxgxC0EOHYt/niMROf8p4PwxxG32Qdhj/iIQQIuOflLjNkxoXyArkcIP7C3A==", + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.6.tgz", + "integrity": "sha512-gLbY3Le9Dxcb8KdpF0+SJr6EQ+hFGYFl6tVY8VxLPFDfUZC7BHFw+Vq7bM5lE9DwWPfx4vMWWTLGXgpc0mAYyQ==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.5", - "@typescript-eslint/visitor-keys": "5.59.5" + "@typescript-eslint/types": "5.59.6", + "@typescript-eslint/visitor-keys": "5.59.6" } }, "@typescript-eslint/type-utils": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.5.tgz", - "integrity": "sha512-4eyhS7oGym67/pSxA2mmNq7X164oqDYNnZCUayBwJZIRVvKpBCMBzFnFxjeoDeShjtO6RQBHBuwybuX3POnDqg==", + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.6.tgz", + "integrity": "sha512-A4tms2Mp5yNvLDlySF+kAThV9VTBPCvGf0Rp8nl/eoDX9Okun8byTKoj3fJ52IJitjWOk0fKPNQhXEB++eNozQ==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.59.5", - "@typescript-eslint/utils": "5.59.5", + "@typescript-eslint/typescript-estree": "5.59.6", + "@typescript-eslint/utils": "5.59.6", "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.5.tgz", - "integrity": "sha512-xkfRPHbqSH4Ggx4eHRIO/eGL8XL4Ysb4woL8c87YuAo8Md7AUjyWKa9YMwTL519SyDPrfEgKdewjkxNCVeJW7w==", + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.6.tgz", + "integrity": "sha512-tH5lBXZI7T2MOUgOWFdVNUILsI02shyQvfzG9EJkoONWugCG77NDDa1EeDGw7oJ5IvsTAAGVV8I3Tk2PNu9QfA==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.5.tgz", - "integrity": "sha512-+XXdLN2CZLZcD/mO7mQtJMvCkzRfmODbeSKuMY/yXbGkzvA9rJyDY5qDYNoiz2kP/dmyAxXquL2BvLQLJFPQIg==", + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.6.tgz", + "integrity": "sha512-vW6JP3lMAs/Tq4KjdI/RiHaaJSO7IUsbkz17it/Rl9Q+WkQ77EOuOnlbaU8kKfVIOJxMhnRiBG+olE7f3M16DA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.5", - "@typescript-eslint/visitor-keys": "5.59.5", + "@typescript-eslint/types": "5.59.6", + "@typescript-eslint/visitor-keys": "5.59.6", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -8267,28 +8150,28 @@ } }, "@typescript-eslint/utils": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.5.tgz", - "integrity": "sha512-sCEHOiw+RbyTii9c3/qN74hYDPNORb8yWCoPLmB7BIflhplJ65u2PBpdRla12e3SSTJ2erRkPjz7ngLHhUegxA==", + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.6.tgz", + "integrity": "sha512-vzaaD6EXbTS29cVH0JjXBdzMt6VBlv+hE31XktDRMX1j3462wZCJa7VzO2AxXEXcIl8GQqZPcOPuW/Z1tZVogg==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.5", - "@typescript-eslint/types": "5.59.5", - "@typescript-eslint/typescript-estree": "5.59.5", + "@typescript-eslint/scope-manager": "5.59.6", + "@typescript-eslint/types": "5.59.6", + "@typescript-eslint/typescript-estree": "5.59.6", "eslint-scope": "^5.1.1", "semver": "^7.3.7" } }, "@typescript-eslint/visitor-keys": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.5.tgz", - "integrity": "sha512-qL+Oz+dbeBRTeyJTIy0eniD3uvqU7x+y1QceBismZ41hd4aBSRh8UAw4pZP0+XzLuPZmx4raNMq/I+59W2lXKA==", + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.6.tgz", + "integrity": "sha512-zEfbFLzB9ETcEJ4HZEEsCR9HHeNku5/Qw1jSS5McYJv5BR+ftYXwFFAH5Al+xkGaZEqowMwl7uoJjQb1YSPF8Q==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.5", + "@typescript-eslint/types": "5.59.6", "eslint-visitor-keys": "^3.3.0" } }, From 2dac7ce6327b1db2d0c16ac4d99a8a3c8aedb197 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 May 2023 14:35:48 +0200 Subject: [PATCH 0344/1076] build(deps): bump @solana/spl-token from 0.1.8 to 0.3.7 in /stake-pool/js (#4301) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/js-legacy/package-lock.json | 88 ++++++++++------- clients/js-legacy/package.json | 2 +- clients/js-legacy/src/index.ts | 89 ++++++----------- clients/js-legacy/src/layouts.ts | 18 ---- clients/js-legacy/src/utils/index.ts | 1 - clients/js-legacy/src/utils/math.ts | 5 +- clients/js-legacy/src/utils/token.ts | 102 -------------------- clients/js-legacy/test/instructions.test.ts | 14 +-- clients/js-legacy/test/mocks.ts | 30 +++--- 9 files changed, 113 insertions(+), 236 deletions(-) delete mode 100644 clients/js-legacy/src/utils/token.ts diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 339bd402..0d34d931 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@coral-xyz/borsh": "^0.27.0", "@solana/buffer-layout": "^4.0.1", - "@solana/spl-token": "^0.1.8", + "@solana/spl-token": "^0.3.7", "@solana/web3.js": "^1.76.0", "bn.js": "^5.2.0", "buffer": "^6.0.3" @@ -1553,22 +1553,36 @@ "node": ">=5.10" } }, - "node_modules/@solana/spl-token": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.1.8.tgz", - "integrity": "sha512-LZmYCKcPQDtJgecvWOgT/cnoIQPWjdH+QVyzPcFvyDUiT0DiRjZaam4aqNUyvchLFhzgunv3d9xOoyE34ofdoQ==", + "node_modules/@solana/buffer-layout-utils": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@solana/buffer-layout-utils/-/buffer-layout-utils-0.2.0.tgz", + "integrity": "sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==", "dependencies": { - "@babel/runtime": "^7.10.5", - "@solana/web3.js": "^1.21.0", - "bn.js": "^5.1.0", - "buffer": "6.0.3", - "buffer-layout": "^1.2.0", - "dotenv": "10.0.0" + "@solana/buffer-layout": "^4.0.0", + "@solana/web3.js": "^1.32.0", + "bigint-buffer": "^1.1.5", + "bignumber.js": "^9.0.1" }, "engines": { "node": ">= 10" } }, + "node_modules/@solana/spl-token": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.3.7.tgz", + "integrity": "sha512-bKGxWTtIw6VDdCBngjtsGlKGLSmiu/8ghSt/IOYJV24BsymRbgq7r12GToeetpxmPaZYLddKwAz7+EwprLfkfg==", + "dependencies": { + "@solana/buffer-layout": "^4.0.0", + "@solana/buffer-layout-utils": "^0.2.0", + "buffer": "^6.0.3" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "@solana/web3.js": "^1.47.4" + } + }, "node_modules/@solana/web3.js": { "version": "1.76.0", "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.76.0.tgz", @@ -2309,6 +2323,14 @@ "node": ">= 10.0.0" } }, + "node_modules/bignumber.js": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.1.tgz", + "integrity": "sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig==", + "engines": { + "node": "*" + } + }, "node_modules/bindings": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", @@ -2832,14 +2854,6 @@ "node": ">=8" } }, - "node_modules/dotenv": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", - "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", - "engines": { - "node": ">=10" - } - }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -7835,17 +7849,25 @@ "buffer": "~6.0.3" } }, + "@solana/buffer-layout-utils": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@solana/buffer-layout-utils/-/buffer-layout-utils-0.2.0.tgz", + "integrity": "sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==", + "requires": { + "@solana/buffer-layout": "^4.0.0", + "@solana/web3.js": "^1.32.0", + "bigint-buffer": "^1.1.5", + "bignumber.js": "^9.0.1" + } + }, "@solana/spl-token": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.1.8.tgz", - "integrity": "sha512-LZmYCKcPQDtJgecvWOgT/cnoIQPWjdH+QVyzPcFvyDUiT0DiRjZaam4aqNUyvchLFhzgunv3d9xOoyE34ofdoQ==", + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.3.7.tgz", + "integrity": "sha512-bKGxWTtIw6VDdCBngjtsGlKGLSmiu/8ghSt/IOYJV24BsymRbgq7r12GToeetpxmPaZYLddKwAz7+EwprLfkfg==", "requires": { - "@babel/runtime": "^7.10.5", - "@solana/web3.js": "^1.21.0", - "bn.js": "^5.1.0", - "buffer": "6.0.3", - "buffer-layout": "^1.2.0", - "dotenv": "10.0.0" + "@solana/buffer-layout": "^4.0.0", + "@solana/buffer-layout-utils": "^0.2.0", + "buffer": "^6.0.3" } }, "@solana/web3.js": { @@ -8407,6 +8429,11 @@ "bindings": "^1.3.0" } }, + "bignumber.js": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.1.tgz", + "integrity": "sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig==" + }, "bindings": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", @@ -8805,11 +8832,6 @@ } } }, - "dotenv": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", - "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" - }, "eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index f6b2e054..89981e48 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -46,7 +46,7 @@ "dependencies": { "@coral-xyz/borsh": "^0.27.0", "@solana/buffer-layout": "^4.0.1", - "@solana/spl-token": "^0.1.8", + "@solana/spl-token": "^0.3.7", "@solana/web3.js": "^1.76.0", "bn.js": "^5.2.0", "buffer": "^6.0.3" diff --git a/clients/js-legacy/src/index.ts b/clients/js-legacy/src/index.ts index d18495f4..9b77e2a3 100644 --- a/clients/js-legacy/src/index.ts +++ b/clients/js-legacy/src/index.ts @@ -9,16 +9,19 @@ import { SystemProgram, TransactionInstruction, } from '@solana/web3.js'; -import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID, Token } from '@solana/spl-token'; +import { + createApproveInstruction, + createAssociatedTokenAccountIdempotentInstruction, + getAccount, + getAssociatedTokenAddressSync, +} from '@solana/spl-token'; import { ValidatorAccount, - addAssociatedTokenAccount, arrayChunk, calcLamportsWithdrawAmount, findStakeProgramAddress, findTransientStakeProgramAddress, findWithdrawAuthorityProgramAddress, - getTokenAccount, getValidatorListAccount, newStakeAccount, prepareWithdrawAccounts, @@ -203,18 +206,18 @@ export async function depositStake( const poolMint = stakePool.account.data.poolMint; - let rentFee = 0; - // Create token account if not specified if (!poolTokenReceiverAccount) { - const { associatedAddress, rentFee: fee } = await addAssociatedTokenAccount( - connection, - authorizedPubkey, - poolMint, - instructions, + const associatedAddress = getAssociatedTokenAddressSync(poolMint, authorizedPubkey); + instructions.push( + createAssociatedTokenAccountIdempotentInstruction( + authorizedPubkey, + associatedAddress, + authorizedPubkey, + poolMint, + ), ); poolTokenReceiverAccount = associatedAddress; - rentFee += fee; } instructions.push( @@ -254,7 +257,6 @@ export async function depositStake( return { instructions, signers, - rentFee, }; } @@ -287,8 +289,6 @@ export async function depositSol( const signers: Signer[] = [userSolTransfer]; const instructions: TransactionInstruction[] = []; - let rentFee = 0; - // Create the ephemeral SOL account instructions.push( SystemProgram.transfer({ @@ -300,14 +300,16 @@ export async function depositSol( // Create token account if not specified if (!destinationTokenAccount) { - const { associatedAddress, rentFee: fee } = await addAssociatedTokenAccount( - connection, - from, - stakePool.poolMint, - instructions, + const associatedAddress = getAssociatedTokenAddressSync(stakePool.poolMint, from); + instructions.push( + createAssociatedTokenAccountIdempotentInstruction( + from, + associatedAddress, + from, + stakePool.poolMint, + ), ); destinationTokenAccount = associatedAddress; - rentFee += fee; } const withdrawAuthority = await findWithdrawAuthorityProgramAddress( @@ -333,7 +335,6 @@ export async function depositSol( return { instructions, signers, - rentFee, }; } @@ -355,29 +356,16 @@ export async function withdrawStake( const poolAmount = solToLamports(amount); if (!poolTokenAccount) { - poolTokenAccount = await Token.getAssociatedTokenAddress( - ASSOCIATED_TOKEN_PROGRAM_ID, - TOKEN_PROGRAM_ID, - stakePool.account.data.poolMint, - tokenOwner, - ); + poolTokenAccount = getAssociatedTokenAddressSync(stakePool.account.data.poolMint, tokenOwner); } - const tokenAccount = await getTokenAccount( - connection, - poolTokenAccount, - stakePool.account.data.poolMint, - ); - - if (!tokenAccount) { - throw new Error('Invalid token account'); - } + const tokenAccount = await getAccount(connection, poolTokenAccount); // Check withdrawFrom balance - if (tokenAccount.amount.toNumber() < poolAmount) { + if (tokenAccount.amount < poolAmount) { throw new Error( `Not enough token balance to withdraw ${lamportsToSol(poolAmount)} pool tokens. - Maximum withdraw amount is ${lamportsToSol(tokenAccount.amount.toNumber())} pool tokens.`, + Maximum withdraw amount is ${lamportsToSol(tokenAccount.amount)} pool tokens.`, ); } @@ -499,12 +487,10 @@ export async function withdrawStake( const signers: Signer[] = [userTransferAuthority]; instructions.push( - Token.createApproveInstruction( - TOKEN_PROGRAM_ID, + createApproveInstruction( poolTokenAccount, userTransferAuthority.publicKey, tokenOwner, - [], poolAmount, ), ); @@ -595,27 +581,18 @@ export async function withdrawSol( const stakePool = await getStakePoolAccount(connection, stakePoolAddress); const poolAmount = solToLamports(amount); - const poolTokenAccount = await Token.getAssociatedTokenAddress( - ASSOCIATED_TOKEN_PROGRAM_ID, - TOKEN_PROGRAM_ID, + const poolTokenAccount = getAssociatedTokenAddressSync( stakePool.account.data.poolMint, tokenOwner, ); - const tokenAccount = await getTokenAccount( - connection, - poolTokenAccount, - stakePool.account.data.poolMint, - ); - if (!tokenAccount) { - throw new Error('Invalid token account'); - } + const tokenAccount = await getAccount(connection, poolTokenAccount); // Check withdrawFrom balance - if (tokenAccount.amount.toNumber() < poolAmount) { + if (tokenAccount.amount < poolAmount) { throw new Error( `Not enough token balance to withdraw ${lamportsToSol(poolAmount)} pool tokens. - Maximum withdraw amount is ${lamportsToSol(tokenAccount.amount.toNumber())} pool tokens.`, + Maximum withdraw amount is ${lamportsToSol(tokenAccount.amount)} pool tokens.`, ); } @@ -625,12 +602,10 @@ export async function withdrawSol( const signers: Signer[] = [userTransferAuthority]; instructions.push( - Token.createApproveInstruction( - TOKEN_PROGRAM_ID, + createApproveInstruction( poolTokenAccount, userTransferAuthority.publicKey, tokenOwner, - [], poolAmount, ), ); diff --git a/clients/js-legacy/src/layouts.ts b/clients/js-legacy/src/layouts.ts index 5027cc9b..020a8c37 100644 --- a/clients/js-legacy/src/layouts.ts +++ b/clients/js-legacy/src/layouts.ts @@ -1,6 +1,5 @@ import { publicKey, struct, u32, u64, u8, option, vec } from '@coral-xyz/borsh'; import { Lockup, PublicKey } from '@solana/web3.js'; -import { AccountInfo } from '@solana/spl-token'; import BN from 'bn.js'; import { Infer, @@ -21,23 +20,6 @@ export interface Fee { const feeFields = [u64('denominator'), u64('numerator')]; -/** - * AccountLayout.encode from "@solana/spl-token" doesn't work - */ -export const AccountLayout = struct([ - publicKey('mint'), - publicKey('owner'), - u64('amount'), - u32('delegateOption'), - publicKey('delegate'), - u8('state'), - u32('isNativeOption'), - u64('isNative'), - u64('delegatedAmount'), - u32('closeAuthorityOption'), - publicKey('closeAuthority'), -]); - export enum AccountType { Uninitialized, StakePool, diff --git a/clients/js-legacy/src/utils/index.ts b/clients/js-legacy/src/utils/index.ts index 1091d0ec..e93c2cde 100644 --- a/clients/js-legacy/src/utils/index.ts +++ b/clients/js-legacy/src/utils/index.ts @@ -1,7 +1,6 @@ export * from './math'; export * from './program-address'; export * from './stake'; -export * from './token'; export * from './instruction'; export function arrayChunk(array: any[], size: number): any[] { diff --git a/clients/js-legacy/src/utils/math.ts b/clients/js-legacy/src/utils/math.ts index ab64724e..5f939bc8 100644 --- a/clients/js-legacy/src/utils/math.ts +++ b/clients/js-legacy/src/utils/math.ts @@ -6,10 +6,13 @@ export function solToLamports(amount: number): number { return Number(amount * LAMPORTS_PER_SOL); } -export function lamportsToSol(lamports: number | BN): number { +export function lamportsToSol(lamports: number | BN | bigint): number { if (typeof lamports === 'number') { return Math.abs(lamports) / LAMPORTS_PER_SOL; } + if (typeof lamports === 'bigint') { + return Math.abs(Number(lamports)) / LAMPORTS_PER_SOL; + } let signMultiplier = 1; if (lamports.isNeg()) { diff --git a/clients/js-legacy/src/utils/token.ts b/clients/js-legacy/src/utils/token.ts deleted file mode 100644 index ee20463f..00000000 --- a/clients/js-legacy/src/utils/token.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { Connection, PublicKey, TransactionInstruction } from '@solana/web3.js'; -import { - AccountInfo, - ASSOCIATED_TOKEN_PROGRAM_ID, - MintInfo, - Token, - TOKEN_PROGRAM_ID, -} from '@solana/spl-token'; -import { AccountLayout } from '../layouts'; - -const FAILED_TO_FIND_ACCOUNT = 'Failed to find account'; -const INVALID_ACCOUNT_OWNER = 'Invalid account owner'; - -export async function getTokenMint( - connection: Connection, - tokenMintPubkey: PublicKey, -): Promise { - // @ts-ignore - const token = new Token(connection, tokenMintPubkey, TOKEN_PROGRAM_ID, null); - return token.getMintInfo(); -} - -/** - * Retrieve the associated account or create one if not found. - * This account may then be used as a `transfer()` or `approve()` destination - */ -export async function addAssociatedTokenAccount( - connection: Connection, - owner: PublicKey, - mint: PublicKey, - instructions: TransactionInstruction[], -) { - const associatedAddress = await Token.getAssociatedTokenAddress( - ASSOCIATED_TOKEN_PROGRAM_ID, - TOKEN_PROGRAM_ID, - mint, - owner, - ); - - let rentFee = 0; - - // This is the optimum logic, considering TX fee, client-side computation, - // RPC roundtrips and guaranteed idempotent. - // Sadly we can't do this atomically; - try { - const account = await connection.getAccountInfo(associatedAddress); - if (!account) { - // noinspection ExceptionCaughtLocallyJS - throw new Error(FAILED_TO_FIND_ACCOUNT); - } - } catch (err: any) { - // INVALID_ACCOUNT_OWNER can be possible if the associatedAddress has - // already been received some lamports (= became system accounts). - // Assuming program derived addressing is safe, this is the only case - // for the INVALID_ACCOUNT_OWNER in this code-path - if (err.message === FAILED_TO_FIND_ACCOUNT || err.message === INVALID_ACCOUNT_OWNER) { - instructions.push( - Token.createAssociatedTokenAccountInstruction( - ASSOCIATED_TOKEN_PROGRAM_ID, - TOKEN_PROGRAM_ID, - mint, - associatedAddress, - owner, - owner, - ), - ); - rentFee = await connection.getMinimumBalanceForRentExemption(AccountLayout.span); - } else { - throw err; - } - console.warn(err); - } - - return { - associatedAddress, - rentFee, - }; -} - -export async function getTokenAccount( - connection: Connection, - tokenAccountAddress: PublicKey, - expectedTokenMint: PublicKey, -): Promise { - try { - const account = await connection.getAccountInfo(tokenAccountAddress); - if (!account) { - // noinspection ExceptionCaughtLocallyJS - throw new Error(`Invalid account ${tokenAccountAddress.toBase58()}`); - } - const tokenAccount = AccountLayout.decode(account.data) as AccountInfo; - if (tokenAccount.mint?.toBase58() != expectedTokenMint.toBase58()) { - // noinspection ExceptionCaughtLocallyJS - throw new Error( - `Invalid token mint for ${tokenAccountAddress}, expected mint is ${expectedTokenMint}`, - ); - } - return tokenAccount; - } catch (error) { - console.log(error); - } -} diff --git a/clients/js-legacy/test/instructions.test.ts b/clients/js-legacy/test/instructions.test.ts index 510dd5fa..6552d0c3 100644 --- a/clients/js-legacy/test/instructions.test.ts +++ b/clients/js-legacy/test/instructions.test.ts @@ -15,7 +15,7 @@ import { AccountInfo, LAMPORTS_PER_SOL, } from '@solana/web3.js'; -import { TOKEN_PROGRAM_ID } from '@solana/spl-token'; +import { TOKEN_PROGRAM_ID, TokenAccountNotFoundError } from '@solana/spl-token'; import { StakePoolLayout } from '../src/layouts'; import { STAKE_POOL_INSTRUCTION_LAYOUTS, @@ -129,7 +129,7 @@ describe('StakePoolProgram', () => { it('should call successfully', async () => { connection.getAccountInfo = jest.fn(async (pubKey) => { - if (pubKey == stakePoolAddress) { + if (pubKey === stakePoolAddress) { return stakePoolAccount; } return >{ @@ -142,8 +142,8 @@ describe('StakePoolProgram', () => { const res = await depositSol(connection, stakePoolAddress, from, balance); - expect((connection.getAccountInfo as jest.Mock).mock.calls.length).toBe(2); - expect(res.instructions).toHaveLength(2); + expect((connection.getAccountInfo as jest.Mock).mock.calls.length).toBe(1); + expect(res.instructions).toHaveLength(3); expect(res.signers).toHaveLength(1); }); }); @@ -172,12 +172,12 @@ describe('StakePoolProgram', () => { await expect( withdrawSol(connection, stakePoolAddress, tokenOwner, solReceiver, 1), - ).rejects.toThrow(Error('Invalid token account')); + ).rejects.toThrow(TokenAccountNotFoundError); }); it('should throw an error with invalid token account balance', async () => { connection.getAccountInfo = jest.fn(async (pubKey: PublicKey) => { - if (pubKey == stakePoolAddress) { + if (pubKey === stakePoolAddress) { return stakePoolAccount; } if (pubKey.equals(CONSTANTS.poolTokenAccount)) { @@ -225,7 +225,7 @@ describe('StakePoolProgram', () => { }); await expect(withdrawStake(connection, stakePoolAddress, tokenOwner, 1)).rejects.toThrow( - Error('Invalid token account'), + TokenAccountNotFoundError, ); }); diff --git a/clients/js-legacy/test/mocks.ts b/clients/js-legacy/test/mocks.ts index dd123dc4..c9c10839 100644 --- a/clients/js-legacy/test/mocks.ts +++ b/clients/js-legacy/test/mocks.ts @@ -1,12 +1,11 @@ import { AccountInfo, LAMPORTS_PER_SOL, PublicKey, StakeProgram } from '@solana/web3.js'; import BN from 'bn.js'; import { ValidatorStakeInfo } from '../src'; -import { AccountLayout, ValidatorListLayout, ValidatorStakeInfoStatus } from '../src/layouts'; +import { AccountLayout, TOKEN_PROGRAM_ID } from '@solana/spl-token'; +import { ValidatorListLayout, ValidatorStakeInfoStatus } from '../src/layouts'; export const CONSTANTS = { - poolTokenAccount: new PublicKey( - new BN('e4f53a3a11521b9171c942ff91183ec8db4e6f347bb9aa7d4a814b7874bfd15c', 'hex'), - ), + poolTokenAccount: new PublicKey('GQkqTamwqjaNDfsbNm7r3aXPJ4oTSqKC3d5t2PF9Smqd'), validatorStakeAccountAddress: new PublicKey( new BN('69184b7f1bc836271c4ac0e29e53eb38a38ea0e7bcde693c45b30d1592a5a678', 'hex'), ), @@ -114,28 +113,27 @@ export const validatorListMock = { }; export function mockTokenAccount(amount = 0) { - const data = Buffer.alloc(1024); + const data = Buffer.alloc(165); AccountLayout.encode( { - state: 0, mint: stakePoolMock.poolMint, owner: new PublicKey(0), - amount: new BN(amount), - // address: new PublicKey(0), - // delegate: null, - // delegatedAmount: new BN(0), - // isInitialized: true, - // isFrozen: false, - // isNative: false, - // rentExemptReserve: null, - // closeAuthority: null, + amount: BigInt(amount), + delegateOption: 0, + delegate: new PublicKey(0), + delegatedAmount: BigInt(0), + state: 1, + isNativeOption: 0, + isNative: BigInt(0), + closeAuthorityOption: 0, + closeAuthority: new PublicKey(0), }, data, ); return >{ executable: true, - owner: new PublicKey(0), + owner: TOKEN_PROGRAM_ID, lamports: amount, data, }; From 520ab8da77dd83a9e1001137fa1951769fff833b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 May 2023 15:37:44 +0200 Subject: [PATCH 0345/1076] build(deps-dev): bump @types/node from 20.1.7 to 20.2.0 in /stake-pool/js (#4342) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 0d34d931..ced1b930 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1743,9 +1743,9 @@ "integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==" }, "node_modules/@types/node": { - "version": "20.1.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.7.tgz", - "integrity": "sha512-WCuw/o4GSwDGMoonES8rcvwsig77dGCMbZDrZr2x4ZZiNW4P/gcoZXe/0twgtobcTkmg9TuKflxYL/DuwDyJzg==" + "version": "20.2.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.0.tgz", + "integrity": "sha512-3iD2jaCCziTx04uudpJKwe39QxXgSUnpxXSvRQjRvHPxFQfmfP4NXIm/NURVeNlTCc+ru4WqjYGTmpXrW9uMlw==" }, "node_modules/@types/node-fetch": { "version": "2.6.3", @@ -8027,9 +8027,9 @@ "integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==" }, "@types/node": { - "version": "20.1.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.7.tgz", - "integrity": "sha512-WCuw/o4GSwDGMoonES8rcvwsig77dGCMbZDrZr2x4ZZiNW4P/gcoZXe/0twgtobcTkmg9TuKflxYL/DuwDyJzg==" + "version": "20.2.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.0.tgz", + "integrity": "sha512-3iD2jaCCziTx04uudpJKwe39QxXgSUnpxXSvRQjRvHPxFQfmfP4NXIm/NURVeNlTCc+ru4WqjYGTmpXrW9uMlw==" }, "@types/node-fetch": { "version": "2.6.3", From 6a3a0c9f29be99a4c32740385b5213073398ed61 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 May 2023 15:37:48 +0200 Subject: [PATCH 0346/1076] build(deps-dev): bump @types/node-fetch from 2.6.3 to 2.6.4 in /stake-pool/js (#4343) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index ced1b930..141b2b01 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1748,9 +1748,9 @@ "integrity": "sha512-3iD2jaCCziTx04uudpJKwe39QxXgSUnpxXSvRQjRvHPxFQfmfP4NXIm/NURVeNlTCc+ru4WqjYGTmpXrW9uMlw==" }, "node_modules/@types/node-fetch": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.3.tgz", - "integrity": "sha512-ETTL1mOEdq/sxUtgtOhKjyB2Irra4cjxksvcMUR5Zr4n+PxVhsCD9WS46oPbHL3et9Zde7CNRr+WUNlcHvsX+w==", + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.4.tgz", + "integrity": "sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==", "dev": true, "dependencies": { "@types/node": "*", @@ -8032,9 +8032,9 @@ "integrity": "sha512-3iD2jaCCziTx04uudpJKwe39QxXgSUnpxXSvRQjRvHPxFQfmfP4NXIm/NURVeNlTCc+ru4WqjYGTmpXrW9uMlw==" }, "@types/node-fetch": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.3.tgz", - "integrity": "sha512-ETTL1mOEdq/sxUtgtOhKjyB2Irra4cjxksvcMUR5Zr4n+PxVhsCD9WS46oPbHL3et9Zde7CNRr+WUNlcHvsX+w==", + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.4.tgz", + "integrity": "sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==", "dev": true, "requires": { "@types/node": "*", From 199d5a995286f492817b072e20733d0a815b9b34 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 May 2023 15:37:52 +0200 Subject: [PATCH 0347/1076] build(deps): bump bn.js from 5.2.0 to 5.2.1 in /stake-pool/js (#4344) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 141b2b01..297b57af 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1656,9 +1656,9 @@ } }, "node_modules/@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.1.tgz", + "integrity": "sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==", "dev": true, "dependencies": { "@types/node": "*" @@ -2340,9 +2340,9 @@ } }, "node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" }, "node_modules/borsh": { "version": "0.7.0", @@ -7940,9 +7940,9 @@ } }, "@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.1.tgz", + "integrity": "sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==", "dev": true, "requires": { "@types/node": "*" @@ -8443,9 +8443,9 @@ } }, "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" }, "borsh": { "version": "0.7.0", From a40fe68b48dc9e07cee80b2bc137ce01443b9242 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 May 2023 18:12:56 +0200 Subject: [PATCH 0348/1076] build(deps-dev): bump rimraf from 5.0.0 to 5.0.1 in /stake-pool/js (#4353) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 60 ++++++++++++++--------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 297b57af..f8ccfae3 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -5125,9 +5125,9 @@ } }, "node_modules/minipass": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-6.0.0.tgz", - "integrity": "sha512-mvD5U4pUen1aWcjTxUgdoMg6PB98dcV0obc/OiPzls79++IpgNoO+MCbOHRlKfWIOvjIjmjUygjZmSStP7B0Og==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz", + "integrity": "sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==", "dev": true, "engines": { "node": ">=16 || 14 >=14.17" @@ -5385,13 +5385,13 @@ "dev": true }, "node_modules/path-scurry": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.9.1.tgz", - "integrity": "sha512-UgmoiySyjFxP6tscZDgWGEAgsW5ok8W3F5CJDnnH2pozwSTGE6eH7vwTotMwATWA2r5xqdkKdxYPkwlJjAI/3g==", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.9.2.tgz", + "integrity": "sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg==", "dev": true, "dependencies": { "lru-cache": "^9.1.1", - "minipass": "^5.0.0 || ^6.0.0" + "minipass": "^5.0.0 || ^6.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -5663,12 +5663,12 @@ } }, "node_modules/rimraf": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.0.tgz", - "integrity": "sha512-Jf9llaP+RvaEVS5nPShYFhtXIrb3LRKP281ib3So0KkeZKo2wIKyq0Re7TOSwanasA423PSr6CCIL4bP6T040g==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.1.tgz", + "integrity": "sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg==", "dev": true, "dependencies": { - "glob": "^10.0.0" + "glob": "^10.2.5" }, "bin": { "rimraf": "dist/cjs/src/bin.js" @@ -5690,15 +5690,15 @@ } }, "node_modules/rimraf/node_modules/glob": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.2.4.tgz", - "integrity": "sha512-fDboBse/sl1oXSLhIp0FcCJgzW9KmhC/q8ULTKC82zc+DL3TL7FNb8qlt5qqXN53MsKEUSIcb+7DLmEygOE5Yw==", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.2.5.tgz", + "integrity": "sha512-Gj+dFYPZ5hc5dazjXzB0iHg2jKWJZYMjITXYPBRQ/xc2Buw7H0BINknRTwURJ6IC6MEFpYbLvtgVb3qD+DwyuA==", "dev": true, "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^2.0.3", "minimatch": "^9.0.0", - "minipass": "^5.0.0 || ^6.0.0", + "minipass": "^5.0.0 || ^6.0.2", "path-scurry": "^1.7.0" }, "bin": { @@ -10544,9 +10544,9 @@ } }, "minipass": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-6.0.0.tgz", - "integrity": "sha512-mvD5U4pUen1aWcjTxUgdoMg6PB98dcV0obc/OiPzls79++IpgNoO+MCbOHRlKfWIOvjIjmjUygjZmSStP7B0Og==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz", + "integrity": "sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==", "dev": true }, "ms": { @@ -10742,13 +10742,13 @@ "dev": true }, "path-scurry": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.9.1.tgz", - "integrity": "sha512-UgmoiySyjFxP6tscZDgWGEAgsW5ok8W3F5CJDnnH2pozwSTGE6eH7vwTotMwATWA2r5xqdkKdxYPkwlJjAI/3g==", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.9.2.tgz", + "integrity": "sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg==", "dev": true, "requires": { "lru-cache": "^9.1.1", - "minipass": "^5.0.0 || ^6.0.0" + "minipass": "^5.0.0 || ^6.0.2" }, "dependencies": { "lru-cache": { @@ -10933,12 +10933,12 @@ "dev": true }, "rimraf": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.0.tgz", - "integrity": "sha512-Jf9llaP+RvaEVS5nPShYFhtXIrb3LRKP281ib3So0KkeZKo2wIKyq0Re7TOSwanasA423PSr6CCIL4bP6T040g==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.1.tgz", + "integrity": "sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg==", "dev": true, "requires": { - "glob": "^10.0.0" + "glob": "^10.2.5" }, "dependencies": { "brace-expansion": { @@ -10951,15 +10951,15 @@ } }, "glob": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.2.4.tgz", - "integrity": "sha512-fDboBse/sl1oXSLhIp0FcCJgzW9KmhC/q8ULTKC82zc+DL3TL7FNb8qlt5qqXN53MsKEUSIcb+7DLmEygOE5Yw==", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.2.5.tgz", + "integrity": "sha512-Gj+dFYPZ5hc5dazjXzB0iHg2jKWJZYMjITXYPBRQ/xc2Buw7H0BINknRTwURJ6IC6MEFpYbLvtgVb3qD+DwyuA==", "dev": true, "requires": { "foreground-child": "^3.1.0", "jackspeak": "^2.0.3", "minimatch": "^9.0.0", - "minipass": "^5.0.0 || ^6.0.0", + "minipass": "^5.0.0 || ^6.0.2", "path-scurry": "^1.7.0" } }, From e384dfcc67c43097fa7b2982d1bf03787ed0c6c1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 May 2023 18:13:03 +0200 Subject: [PATCH 0349/1076] build(deps-dev): bump @types/node from 20.2.0 to 20.2.1 in /stake-pool/js (#4354) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index f8ccfae3..f4bf0b52 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1743,9 +1743,9 @@ "integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==" }, "node_modules/@types/node": { - "version": "20.2.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.0.tgz", - "integrity": "sha512-3iD2jaCCziTx04uudpJKwe39QxXgSUnpxXSvRQjRvHPxFQfmfP4NXIm/NURVeNlTCc+ru4WqjYGTmpXrW9uMlw==" + "version": "20.2.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.1.tgz", + "integrity": "sha512-DqJociPbZP1lbZ5SQPk4oag6W7AyaGMO6gSfRwq3PWl4PXTwJpRQJhDq4W0kzrg3w6tJ1SwlvGZ5uKFHY13LIg==" }, "node_modules/@types/node-fetch": { "version": "2.6.4", @@ -8027,9 +8027,9 @@ "integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==" }, "@types/node": { - "version": "20.2.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.0.tgz", - "integrity": "sha512-3iD2jaCCziTx04uudpJKwe39QxXgSUnpxXSvRQjRvHPxFQfmfP4NXIm/NURVeNlTCc+ru4WqjYGTmpXrW9uMlw==" + "version": "20.2.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.1.tgz", + "integrity": "sha512-DqJociPbZP1lbZ5SQPk4oag6W7AyaGMO6gSfRwq3PWl4PXTwJpRQJhDq4W0kzrg3w6tJ1SwlvGZ5uKFHY13LIg==" }, "@types/node-fetch": { "version": "2.6.4", From f5adfcac15981260dd4bf75579c740a73409a1d9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 May 2023 23:10:53 +0200 Subject: [PATCH 0350/1076] build(deps): bump proptest from 1.1.0 to 1.2.0 (#4378) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 81be0aa1..f8416574 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -27,7 +27,7 @@ thiserror = "1.0" bincode = "1.3.1" [dev-dependencies] -proptest = "1.1" +proptest = "1.2" solana-program-test = "1.14.12" solana-sdk = "1.14.12" solana-vote-program = "1.14.12" From 1cce2430b21ddd31423e87b9b1cabe247e973c41 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 May 2023 23:21:21 +0200 Subject: [PATCH 0351/1076] build(deps): bump requests from 2.28.1 to 2.31.0 in /stake-pool/py (#4370) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/py/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/py/requirements.txt b/clients/py/requirements.txt index 7cd54097..6469d765 100644 --- a/clients/py/requirements.txt +++ b/clients/py/requirements.txt @@ -11,7 +11,7 @@ httpx==0.23.0 idna==3.3 pycparser==2.21 PyNaCl==1.5.0 -requests==2.28.1 +requests==2.31.0 rfc3986==1.5.0 sniffio==1.2.0 solana==0.18.1 From f48bc0a8a216b2d5e794dcee41c1082a93ab1ec4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 May 2023 23:33:39 +0200 Subject: [PATCH 0352/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 5.59.6 to 5.59.7 in /stake-pool/js (#4374) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 350 +++++++++++++++++++++++++--- 1 file changed, 316 insertions(+), 34 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index f4bf0b52..9ee1de11 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1815,15 +1815,15 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.59.6", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.6.tgz", - "integrity": "sha512-sXtOgJNEuRU5RLwPUb1jxtToZbgvq3M6FPpY4QENxoOggK+UpTxUBpj6tD8+Qh2g46Pi9We87E+eHnUw8YcGsw==", + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.7.tgz", + "integrity": "sha512-BL+jYxUFIbuYwy+4fF86k5vdT9lT0CNJ6HtwrIvGh0PhH8s0yy5rjaKH2fDCrz5ITHy07WCzVGNvAmjJh4IJFA==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.6", - "@typescript-eslint/type-utils": "5.59.6", - "@typescript-eslint/utils": "5.59.6", + "@typescript-eslint/scope-manager": "5.59.7", + "@typescript-eslint/type-utils": "5.59.7", + "@typescript-eslint/utils": "5.59.7", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", @@ -1848,6 +1848,53 @@ } } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.7.tgz", + "integrity": "sha512-FL6hkYWK9zBGdxT2wWEd2W8ocXMu3K94i3gvMrjXpx+koFYdYV7KprKfirpgY34vTGzEPPuKoERpP8kD5h7vZQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.7", + "@typescript-eslint/visitor-keys": "5.59.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.7.tgz", + "integrity": "sha512-UnVS2MRRg6p7xOSATscWkKjlf/NDKuqo5TdbWck6rIRZbmKpVNTLALzNvcjIfHBE7736kZOFc/4Z3VcZwuOM/A==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.7.tgz", + "integrity": "sha512-tyN+X2jvMslUszIiYbF0ZleP+RqQsFVpGrKI6e0Eet1w8WmhsAtmzaqm8oM8WJQ1ysLwhnsK/4hYHJjOgJVfQQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.7", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/parser": { "version": "5.59.6", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.6.tgz", @@ -1893,13 +1940,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.59.6", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.6.tgz", - "integrity": "sha512-A4tms2Mp5yNvLDlySF+kAThV9VTBPCvGf0Rp8nl/eoDX9Okun8byTKoj3fJ52IJitjWOk0fKPNQhXEB++eNozQ==", + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.7.tgz", + "integrity": "sha512-ozuz/GILuYG7osdY5O5yg0QxXUAEoI4Go3Do5xeu+ERH9PorHBPSdvD3Tjp2NN2bNLh1NJQSsQu2TPu/Ly+HaQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.59.6", - "@typescript-eslint/utils": "5.59.6", + "@typescript-eslint/typescript-estree": "5.59.7", + "@typescript-eslint/utils": "5.59.7", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -1919,6 +1966,63 @@ } } }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.7.tgz", + "integrity": "sha512-UnVS2MRRg6p7xOSATscWkKjlf/NDKuqo5TdbWck6rIRZbmKpVNTLALzNvcjIfHBE7736kZOFc/4Z3VcZwuOM/A==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.7.tgz", + "integrity": "sha512-4A1NtZ1I3wMN2UGDkU9HMBL+TIQfbrh4uS0WDMMpf3xMRursDbqEf1ahh6vAAe3mObt8k3ZATnezwG4pdtWuUQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.7", + "@typescript-eslint/visitor-keys": "5.59.7", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.7.tgz", + "integrity": "sha512-tyN+X2jvMslUszIiYbF0ZleP+RqQsFVpGrKI6e0Eet1w8WmhsAtmzaqm8oM8WJQ1ysLwhnsK/4hYHJjOgJVfQQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.7", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/types": { "version": "5.59.6", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.6.tgz", @@ -1960,17 +2064,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.59.6", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.6.tgz", - "integrity": "sha512-vzaaD6EXbTS29cVH0JjXBdzMt6VBlv+hE31XktDRMX1j3462wZCJa7VzO2AxXEXcIl8GQqZPcOPuW/Z1tZVogg==", + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.7.tgz", + "integrity": "sha512-yCX9WpdQKaLufz5luG4aJbOpdXf/fjwGMcLFXZVPUz3QqLirG5QcwwnIHNf8cjLjxK4qtzTO8udUtMQSAToQnQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.6", - "@typescript-eslint/types": "5.59.6", - "@typescript-eslint/typescript-estree": "5.59.6", + "@typescript-eslint/scope-manager": "5.59.7", + "@typescript-eslint/types": "5.59.7", + "@typescript-eslint/typescript-estree": "5.59.7", "eslint-scope": "^5.1.1", "semver": "^7.3.7" }, @@ -1985,6 +2089,80 @@ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.7.tgz", + "integrity": "sha512-FL6hkYWK9zBGdxT2wWEd2W8ocXMu3K94i3gvMrjXpx+koFYdYV7KprKfirpgY34vTGzEPPuKoERpP8kD5h7vZQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.7", + "@typescript-eslint/visitor-keys": "5.59.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.7.tgz", + "integrity": "sha512-UnVS2MRRg6p7xOSATscWkKjlf/NDKuqo5TdbWck6rIRZbmKpVNTLALzNvcjIfHBE7736kZOFc/4Z3VcZwuOM/A==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.7.tgz", + "integrity": "sha512-4A1NtZ1I3wMN2UGDkU9HMBL+TIQfbrh4uS0WDMMpf3xMRursDbqEf1ahh6vAAe3mObt8k3ZATnezwG4pdtWuUQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.7", + "@typescript-eslint/visitor-keys": "5.59.7", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.7.tgz", + "integrity": "sha512-tyN+X2jvMslUszIiYbF0ZleP+RqQsFVpGrKI6e0Eet1w8WmhsAtmzaqm8oM8WJQ1ysLwhnsK/4hYHJjOgJVfQQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.7", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/visitor-keys": { "version": "5.59.6", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.6.tgz", @@ -8099,21 +8277,49 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.59.6", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.6.tgz", - "integrity": "sha512-sXtOgJNEuRU5RLwPUb1jxtToZbgvq3M6FPpY4QENxoOggK+UpTxUBpj6tD8+Qh2g46Pi9We87E+eHnUw8YcGsw==", + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.7.tgz", + "integrity": "sha512-BL+jYxUFIbuYwy+4fF86k5vdT9lT0CNJ6HtwrIvGh0PhH8s0yy5rjaKH2fDCrz5ITHy07WCzVGNvAmjJh4IJFA==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.6", - "@typescript-eslint/type-utils": "5.59.6", - "@typescript-eslint/utils": "5.59.6", + "@typescript-eslint/scope-manager": "5.59.7", + "@typescript-eslint/type-utils": "5.59.7", + "@typescript-eslint/utils": "5.59.7", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", "semver": "^7.3.7", "tsutils": "^3.21.0" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.7.tgz", + "integrity": "sha512-FL6hkYWK9zBGdxT2wWEd2W8ocXMu3K94i3gvMrjXpx+koFYdYV7KprKfirpgY34vTGzEPPuKoERpP8kD5h7vZQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.7", + "@typescript-eslint/visitor-keys": "5.59.7" + } + }, + "@typescript-eslint/types": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.7.tgz", + "integrity": "sha512-UnVS2MRRg6p7xOSATscWkKjlf/NDKuqo5TdbWck6rIRZbmKpVNTLALzNvcjIfHBE7736kZOFc/4Z3VcZwuOM/A==", + "dev": true + }, + "@typescript-eslint/visitor-keys": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.7.tgz", + "integrity": "sha512-tyN+X2jvMslUszIiYbF0ZleP+RqQsFVpGrKI6e0Eet1w8WmhsAtmzaqm8oM8WJQ1ysLwhnsK/4hYHJjOgJVfQQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.7", + "eslint-visitor-keys": "^3.3.0" + } + } } }, "@typescript-eslint/parser": { @@ -8139,15 +8345,48 @@ } }, "@typescript-eslint/type-utils": { - "version": "5.59.6", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.6.tgz", - "integrity": "sha512-A4tms2Mp5yNvLDlySF+kAThV9VTBPCvGf0Rp8nl/eoDX9Okun8byTKoj3fJ52IJitjWOk0fKPNQhXEB++eNozQ==", + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.7.tgz", + "integrity": "sha512-ozuz/GILuYG7osdY5O5yg0QxXUAEoI4Go3Do5xeu+ERH9PorHBPSdvD3Tjp2NN2bNLh1NJQSsQu2TPu/Ly+HaQ==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.59.6", - "@typescript-eslint/utils": "5.59.6", + "@typescript-eslint/typescript-estree": "5.59.7", + "@typescript-eslint/utils": "5.59.7", "debug": "^4.3.4", "tsutils": "^3.21.0" + }, + "dependencies": { + "@typescript-eslint/types": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.7.tgz", + "integrity": "sha512-UnVS2MRRg6p7xOSATscWkKjlf/NDKuqo5TdbWck6rIRZbmKpVNTLALzNvcjIfHBE7736kZOFc/4Z3VcZwuOM/A==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.7.tgz", + "integrity": "sha512-4A1NtZ1I3wMN2UGDkU9HMBL+TIQfbrh4uS0WDMMpf3xMRursDbqEf1ahh6vAAe3mObt8k3ZATnezwG4pdtWuUQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.7", + "@typescript-eslint/visitor-keys": "5.59.7", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.7.tgz", + "integrity": "sha512-tyN+X2jvMslUszIiYbF0ZleP+RqQsFVpGrKI6e0Eet1w8WmhsAtmzaqm8oM8WJQ1ysLwhnsK/4hYHJjOgJVfQQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.7", + "eslint-visitor-keys": "^3.3.0" + } + } } }, "@typescript-eslint/types": { @@ -8172,19 +8411,62 @@ } }, "@typescript-eslint/utils": { - "version": "5.59.6", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.6.tgz", - "integrity": "sha512-vzaaD6EXbTS29cVH0JjXBdzMt6VBlv+hE31XktDRMX1j3462wZCJa7VzO2AxXEXcIl8GQqZPcOPuW/Z1tZVogg==", + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.7.tgz", + "integrity": "sha512-yCX9WpdQKaLufz5luG4aJbOpdXf/fjwGMcLFXZVPUz3QqLirG5QcwwnIHNf8cjLjxK4qtzTO8udUtMQSAToQnQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.6", - "@typescript-eslint/types": "5.59.6", - "@typescript-eslint/typescript-estree": "5.59.6", + "@typescript-eslint/scope-manager": "5.59.7", + "@typescript-eslint/types": "5.59.7", + "@typescript-eslint/typescript-estree": "5.59.7", "eslint-scope": "^5.1.1", "semver": "^7.3.7" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.7.tgz", + "integrity": "sha512-FL6hkYWK9zBGdxT2wWEd2W8ocXMu3K94i3gvMrjXpx+koFYdYV7KprKfirpgY34vTGzEPPuKoERpP8kD5h7vZQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.7", + "@typescript-eslint/visitor-keys": "5.59.7" + } + }, + "@typescript-eslint/types": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.7.tgz", + "integrity": "sha512-UnVS2MRRg6p7xOSATscWkKjlf/NDKuqo5TdbWck6rIRZbmKpVNTLALzNvcjIfHBE7736kZOFc/4Z3VcZwuOM/A==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.7.tgz", + "integrity": "sha512-4A1NtZ1I3wMN2UGDkU9HMBL+TIQfbrh4uS0WDMMpf3xMRursDbqEf1ahh6vAAe3mObt8k3ZATnezwG4pdtWuUQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.7", + "@typescript-eslint/visitor-keys": "5.59.7", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.7.tgz", + "integrity": "sha512-tyN+X2jvMslUszIiYbF0ZleP+RqQsFVpGrKI6e0Eet1w8WmhsAtmzaqm8oM8WJQ1ysLwhnsK/4hYHJjOgJVfQQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.7", + "eslint-visitor-keys": "^3.3.0" + } + } } }, "@typescript-eslint/visitor-keys": { From 3154927de73d52196c093287bb9502d7b3659d26 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 May 2023 00:14:34 +0200 Subject: [PATCH 0353/1076] build(deps-dev): bump eslint from 8.40.0 to 8.41.0 in /stake-pool/js (#4364) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 62 +++++++++++++---------------- 1 file changed, 28 insertions(+), 34 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 9ee1de11..5a41f46d 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -708,9 +708,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.40.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz", - "integrity": "sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==", + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.41.0.tgz", + "integrity": "sha512-LxcyMGxwmTh2lY9FwHPGWOHmYFCZvbrFCBZL4FzSSsxsRPuhrYUg/49/0KDfW8tnIEaEHtfmn6+NPN+1DqaNmA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3188,15 +3188,15 @@ } }, "node_modules/eslint": { - "version": "8.40.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.40.0.tgz", - "integrity": "sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==", + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.41.0.tgz", + "integrity": "sha512-WQDQpzGBOP5IrXPo4Hc0814r4/v2rrIsB0rhT7jtunIalgg6gYXWhRMOejVO8yH21T/FGaxjmFjBMNqcIlmH1Q==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.4.0", "@eslint/eslintrc": "^2.0.3", - "@eslint/js": "8.40.0", + "@eslint/js": "8.41.0", "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -3216,13 +3216,12 @@ "find-up": "^5.0.0", "glob-parent": "^6.0.2", "globals": "^13.19.0", - "grapheme-splitter": "^1.0.4", + "graphemer": "^1.4.0", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", @@ -3881,6 +3880,12 @@ "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", "dev": true }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -4946,16 +4951,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/js-sdsl": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz", - "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" - } - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -7431,9 +7426,9 @@ } }, "@eslint/js": { - "version": "8.40.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz", - "integrity": "sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==", + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.41.0.tgz", + "integrity": "sha512-LxcyMGxwmTh2lY9FwHPGWOHmYFCZvbrFCBZL4FzSSsxsRPuhrYUg/49/0KDfW8tnIEaEHtfmn6+NPN+1DqaNmA==", "dev": true }, "@humanwhocodes/config-array": { @@ -9233,15 +9228,15 @@ } }, "eslint": { - "version": "8.40.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.40.0.tgz", - "integrity": "sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==", + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.41.0.tgz", + "integrity": "sha512-WQDQpzGBOP5IrXPo4Hc0814r4/v2rrIsB0rhT7jtunIalgg6gYXWhRMOejVO8yH21T/FGaxjmFjBMNqcIlmH1Q==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.4.0", "@eslint/eslintrc": "^2.0.3", - "@eslint/js": "8.40.0", + "@eslint/js": "8.41.0", "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -9261,13 +9256,12 @@ "find-up": "^5.0.0", "glob-parent": "^6.0.2", "globals": "^13.19.0", - "grapheme-splitter": "^1.0.4", + "graphemer": "^1.4.0", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", @@ -9742,6 +9736,12 @@ "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", "dev": true }, + "graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -10554,12 +10554,6 @@ } } }, - "js-sdsl": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz", - "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==", - "dev": true - }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", From dbd33163000c1715acff049a5b413761e761375d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 May 2023 00:49:51 +0200 Subject: [PATCH 0354/1076] build(deps-dev): bump @types/node from 20.2.1 to 20.2.3 in /stake-pool/js (#4365) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 5a41f46d..78c5653b 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1743,9 +1743,9 @@ "integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==" }, "node_modules/@types/node": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.1.tgz", - "integrity": "sha512-DqJociPbZP1lbZ5SQPk4oag6W7AyaGMO6gSfRwq3PWl4PXTwJpRQJhDq4W0kzrg3w6tJ1SwlvGZ5uKFHY13LIg==" + "version": "20.2.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.3.tgz", + "integrity": "sha512-pg9d0yC4rVNWQzX8U7xb4olIOFuuVL9za3bzMT2pu2SU0SNEi66i2qrvhE2qt0HvkhuCaWJu7pLNOt/Pj8BIrw==" }, "node_modules/@types/node-fetch": { "version": "2.6.4", @@ -8200,9 +8200,9 @@ "integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==" }, "@types/node": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.1.tgz", - "integrity": "sha512-DqJociPbZP1lbZ5SQPk4oag6W7AyaGMO6gSfRwq3PWl4PXTwJpRQJhDq4W0kzrg3w6tJ1SwlvGZ5uKFHY13LIg==" + "version": "20.2.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.3.tgz", + "integrity": "sha512-pg9d0yC4rVNWQzX8U7xb4olIOFuuVL9za3bzMT2pu2SU0SNEi66i2qrvhE2qt0HvkhuCaWJu7pLNOt/Pj8BIrw==" }, "@types/node-fetch": { "version": "2.6.4", From 983c2b08be92838c2a6c8417b34cc1b14d215f0b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 May 2023 20:45:00 +0200 Subject: [PATCH 0355/1076] build(deps-dev): bump @typescript-eslint/parser from 5.59.6 to 5.59.7 in /stake-pool/js (#4385) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 354 +++------------------------- 1 file changed, 36 insertions(+), 318 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 78c5653b..7c3f6f76 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1848,62 +1848,15 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.7.tgz", - "integrity": "sha512-FL6hkYWK9zBGdxT2wWEd2W8ocXMu3K94i3gvMrjXpx+koFYdYV7KprKfirpgY34vTGzEPPuKoERpP8kD5h7vZQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.7", - "@typescript-eslint/visitor-keys": "5.59.7" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.7.tgz", - "integrity": "sha512-UnVS2MRRg6p7xOSATscWkKjlf/NDKuqo5TdbWck6rIRZbmKpVNTLALzNvcjIfHBE7736kZOFc/4Z3VcZwuOM/A==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "node_modules/@typescript-eslint/parser": { "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.7.tgz", - "integrity": "sha512-tyN+X2jvMslUszIiYbF0ZleP+RqQsFVpGrKI6e0Eet1w8WmhsAtmzaqm8oM8WJQ1ysLwhnsK/4hYHJjOgJVfQQ==", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.7.tgz", + "integrity": "sha512-VhpsIEuq/8i5SF+mPg9jSdIwgMBBp0z9XqjiEay+81PYLJuroN+ET1hM5IhkiYMJd9MkTz8iJLt7aaGAgzWUbQ==", "dev": true, "dependencies": { + "@typescript-eslint/scope-manager": "5.59.7", "@typescript-eslint/types": "5.59.7", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "5.59.6", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.6.tgz", - "integrity": "sha512-7pCa6al03Pv1yf/dUg/s1pXz/yGMUBAw5EeWqNTFiSueKvRNonze3hma3lhdsOrQcaOXhbk5gKu2Fludiho9VA==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "5.59.6", - "@typescript-eslint/types": "5.59.6", - "@typescript-eslint/typescript-estree": "5.59.6", + "@typescript-eslint/typescript-estree": "5.59.7", "debug": "^4.3.4" }, "engines": { @@ -1923,13 +1876,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.59.6", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.6.tgz", - "integrity": "sha512-gLbY3Le9Dxcb8KdpF0+SJr6EQ+hFGYFl6tVY8VxLPFDfUZC7BHFw+Vq7bM5lE9DwWPfx4vMWWTLGXgpc0mAYyQ==", + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.7.tgz", + "integrity": "sha512-FL6hkYWK9zBGdxT2wWEd2W8ocXMu3K94i3gvMrjXpx+koFYdYV7KprKfirpgY34vTGzEPPuKoERpP8kD5h7vZQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.6", - "@typescript-eslint/visitor-keys": "5.59.6" + "@typescript-eslint/types": "5.59.7", + "@typescript-eslint/visitor-keys": "5.59.7" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1966,7 +1919,7 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "node_modules/@typescript-eslint/types": { "version": "5.59.7", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.7.tgz", "integrity": "sha512-UnVS2MRRg6p7xOSATscWkKjlf/NDKuqo5TdbWck6rIRZbmKpVNTLALzNvcjIfHBE7736kZOFc/4Z3VcZwuOM/A==", @@ -1979,7 +1932,7 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "node_modules/@typescript-eslint/typescript-estree": { "version": "5.59.7", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.7.tgz", "integrity": "sha512-4A1NtZ1I3wMN2UGDkU9HMBL+TIQfbrh4uS0WDMMpf3xMRursDbqEf1ahh6vAAe3mObt8k3ZATnezwG4pdtWuUQ==", @@ -2006,63 +1959,6 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.7.tgz", - "integrity": "sha512-tyN+X2jvMslUszIiYbF0ZleP+RqQsFVpGrKI6e0Eet1w8WmhsAtmzaqm8oM8WJQ1ysLwhnsK/4hYHJjOgJVfQQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.7", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "5.59.6", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.6.tgz", - "integrity": "sha512-tH5lBXZI7T2MOUgOWFdVNUILsI02shyQvfzG9EJkoONWugCG77NDDa1EeDGw7oJ5IvsTAAGVV8I3Tk2PNu9QfA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.59.6", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.6.tgz", - "integrity": "sha512-vW6JP3lMAs/Tq4KjdI/RiHaaJSO7IUsbkz17it/Rl9Q+WkQ77EOuOnlbaU8kKfVIOJxMhnRiBG+olE7f3M16DA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.6", - "@typescript-eslint/visitor-keys": "5.59.6", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, "node_modules/@typescript-eslint/utils": { "version": "5.59.7", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.7.tgz", @@ -2089,64 +1985,7 @@ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.7.tgz", - "integrity": "sha512-FL6hkYWK9zBGdxT2wWEd2W8ocXMu3K94i3gvMrjXpx+koFYdYV7KprKfirpgY34vTGzEPPuKoERpP8kD5h7vZQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.7", - "@typescript-eslint/visitor-keys": "5.59.7" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.7.tgz", - "integrity": "sha512-UnVS2MRRg6p7xOSATscWkKjlf/NDKuqo5TdbWck6rIRZbmKpVNTLALzNvcjIfHBE7736kZOFc/4Z3VcZwuOM/A==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.7.tgz", - "integrity": "sha512-4A1NtZ1I3wMN2UGDkU9HMBL+TIQfbrh4uS0WDMMpf3xMRursDbqEf1ahh6vAAe3mObt8k3ZATnezwG4pdtWuUQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.7", - "@typescript-eslint/visitor-keys": "5.59.7", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "node_modules/@typescript-eslint/visitor-keys": { "version": "5.59.7", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.7.tgz", "integrity": "sha512-tyN+X2jvMslUszIiYbF0ZleP+RqQsFVpGrKI6e0Eet1w8WmhsAtmzaqm8oM8WJQ1ysLwhnsK/4hYHJjOgJVfQQ==", @@ -2163,23 +2002,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.59.6", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.6.tgz", - "integrity": "sha512-zEfbFLzB9ETcEJ4HZEEsCR9HHeNku5/Qw1jSS5McYJv5BR+ftYXwFFAH5Al+xkGaZEqowMwl7uoJjQb1YSPF8Q==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.6", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/abab": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", @@ -8287,56 +8109,28 @@ "natural-compare-lite": "^1.4.0", "semver": "^7.3.7", "tsutils": "^3.21.0" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.7.tgz", - "integrity": "sha512-FL6hkYWK9zBGdxT2wWEd2W8ocXMu3K94i3gvMrjXpx+koFYdYV7KprKfirpgY34vTGzEPPuKoERpP8kD5h7vZQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.7", - "@typescript-eslint/visitor-keys": "5.59.7" - } - }, - "@typescript-eslint/types": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.7.tgz", - "integrity": "sha512-UnVS2MRRg6p7xOSATscWkKjlf/NDKuqo5TdbWck6rIRZbmKpVNTLALzNvcjIfHBE7736kZOFc/4Z3VcZwuOM/A==", - "dev": true - }, - "@typescript-eslint/visitor-keys": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.7.tgz", - "integrity": "sha512-tyN+X2jvMslUszIiYbF0ZleP+RqQsFVpGrKI6e0Eet1w8WmhsAtmzaqm8oM8WJQ1ysLwhnsK/4hYHJjOgJVfQQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.7", - "eslint-visitor-keys": "^3.3.0" - } - } } }, "@typescript-eslint/parser": { - "version": "5.59.6", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.6.tgz", - "integrity": "sha512-7pCa6al03Pv1yf/dUg/s1pXz/yGMUBAw5EeWqNTFiSueKvRNonze3hma3lhdsOrQcaOXhbk5gKu2Fludiho9VA==", + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.7.tgz", + "integrity": "sha512-VhpsIEuq/8i5SF+mPg9jSdIwgMBBp0z9XqjiEay+81PYLJuroN+ET1hM5IhkiYMJd9MkTz8iJLt7aaGAgzWUbQ==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.59.6", - "@typescript-eslint/types": "5.59.6", - "@typescript-eslint/typescript-estree": "5.59.6", + "@typescript-eslint/scope-manager": "5.59.7", + "@typescript-eslint/types": "5.59.7", + "@typescript-eslint/typescript-estree": "5.59.7", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.59.6", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.6.tgz", - "integrity": "sha512-gLbY3Le9Dxcb8KdpF0+SJr6EQ+hFGYFl6tVY8VxLPFDfUZC7BHFw+Vq7bM5lE9DwWPfx4vMWWTLGXgpc0mAYyQ==", + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.7.tgz", + "integrity": "sha512-FL6hkYWK9zBGdxT2wWEd2W8ocXMu3K94i3gvMrjXpx+koFYdYV7KprKfirpgY34vTGzEPPuKoERpP8kD5h7vZQ==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.6", - "@typescript-eslint/visitor-keys": "5.59.6" + "@typescript-eslint/types": "5.59.7", + "@typescript-eslint/visitor-keys": "5.59.7" } }, "@typescript-eslint/type-utils": { @@ -8349,55 +8143,22 @@ "@typescript-eslint/utils": "5.59.7", "debug": "^4.3.4", "tsutils": "^3.21.0" - }, - "dependencies": { - "@typescript-eslint/types": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.7.tgz", - "integrity": "sha512-UnVS2MRRg6p7xOSATscWkKjlf/NDKuqo5TdbWck6rIRZbmKpVNTLALzNvcjIfHBE7736kZOFc/4Z3VcZwuOM/A==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.7.tgz", - "integrity": "sha512-4A1NtZ1I3wMN2UGDkU9HMBL+TIQfbrh4uS0WDMMpf3xMRursDbqEf1ahh6vAAe3mObt8k3ZATnezwG4pdtWuUQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.7", - "@typescript-eslint/visitor-keys": "5.59.7", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.7.tgz", - "integrity": "sha512-tyN+X2jvMslUszIiYbF0ZleP+RqQsFVpGrKI6e0Eet1w8WmhsAtmzaqm8oM8WJQ1ysLwhnsK/4hYHJjOgJVfQQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.7", - "eslint-visitor-keys": "^3.3.0" - } - } } }, "@typescript-eslint/types": { - "version": "5.59.6", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.6.tgz", - "integrity": "sha512-tH5lBXZI7T2MOUgOWFdVNUILsI02shyQvfzG9EJkoONWugCG77NDDa1EeDGw7oJ5IvsTAAGVV8I3Tk2PNu9QfA==", + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.7.tgz", + "integrity": "sha512-UnVS2MRRg6p7xOSATscWkKjlf/NDKuqo5TdbWck6rIRZbmKpVNTLALzNvcjIfHBE7736kZOFc/4Z3VcZwuOM/A==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.59.6", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.6.tgz", - "integrity": "sha512-vW6JP3lMAs/Tq4KjdI/RiHaaJSO7IUsbkz17it/Rl9Q+WkQ77EOuOnlbaU8kKfVIOJxMhnRiBG+olE7f3M16DA==", + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.7.tgz", + "integrity": "sha512-4A1NtZ1I3wMN2UGDkU9HMBL+TIQfbrh4uS0WDMMpf3xMRursDbqEf1ahh6vAAe3mObt8k3ZATnezwG4pdtWuUQ==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.6", - "@typescript-eslint/visitor-keys": "5.59.6", + "@typescript-eslint/types": "5.59.7", + "@typescript-eslint/visitor-keys": "5.59.7", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -8419,58 +8180,15 @@ "@typescript-eslint/typescript-estree": "5.59.7", "eslint-scope": "^5.1.1", "semver": "^7.3.7" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.7.tgz", - "integrity": "sha512-FL6hkYWK9zBGdxT2wWEd2W8ocXMu3K94i3gvMrjXpx+koFYdYV7KprKfirpgY34vTGzEPPuKoERpP8kD5h7vZQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.7", - "@typescript-eslint/visitor-keys": "5.59.7" - } - }, - "@typescript-eslint/types": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.7.tgz", - "integrity": "sha512-UnVS2MRRg6p7xOSATscWkKjlf/NDKuqo5TdbWck6rIRZbmKpVNTLALzNvcjIfHBE7736kZOFc/4Z3VcZwuOM/A==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.7.tgz", - "integrity": "sha512-4A1NtZ1I3wMN2UGDkU9HMBL+TIQfbrh4uS0WDMMpf3xMRursDbqEf1ahh6vAAe3mObt8k3ZATnezwG4pdtWuUQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.7", - "@typescript-eslint/visitor-keys": "5.59.7", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.7.tgz", - "integrity": "sha512-tyN+X2jvMslUszIiYbF0ZleP+RqQsFVpGrKI6e0Eet1w8WmhsAtmzaqm8oM8WJQ1ysLwhnsK/4hYHJjOgJVfQQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.7", - "eslint-visitor-keys": "^3.3.0" - } - } } }, "@typescript-eslint/visitor-keys": { - "version": "5.59.6", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.6.tgz", - "integrity": "sha512-zEfbFLzB9ETcEJ4HZEEsCR9HHeNku5/Qw1jSS5McYJv5BR+ftYXwFFAH5Al+xkGaZEqowMwl7uoJjQb1YSPF8Q==", + "version": "5.59.7", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.7.tgz", + "integrity": "sha512-tyN+X2jvMslUszIiYbF0ZleP+RqQsFVpGrKI6e0Eet1w8WmhsAtmzaqm8oM8WJQ1ysLwhnsK/4hYHJjOgJVfQQ==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.6", + "@typescript-eslint/types": "5.59.7", "eslint-visitor-keys": "^3.3.0" } }, From b7e80d009911377a51f56f59fc41e50d83c74f86 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 May 2023 22:39:03 +0200 Subject: [PATCH 0356/1076] build(deps): bump @solana/web3.js from 1.76.0 to 1.77.1 in /stake-pool/js (#4392) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/js-legacy/package-lock.json | 12 ++++++------ clients/js-legacy/src/index.ts | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 7c3f6f76..7a5d871e 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1584,9 +1584,9 @@ } }, "node_modules/@solana/web3.js": { - "version": "1.76.0", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.76.0.tgz", - "integrity": "sha512-aJtF/nTs+9St+KtTK/wgVJ+SinfjYzn+3w1ygYIPw8ST6LH+qHBn8XkodgDTwlv/xzNkaVz1kkUDOZ8BPXyZWA==", + "version": "1.77.1", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.77.1.tgz", + "integrity": "sha512-YWahzcQtQ3inR2+ZSqWsoJnXBppfd//7mbSFVFpyJWyE+vTtSfljdKVOosCY0ynu6AZaBLV1HYErc2wZOXUdeA==", "dependencies": { "@babel/runtime": "^7.12.5", "@noble/curves": "^1.0.0", @@ -7866,9 +7866,9 @@ } }, "@solana/web3.js": { - "version": "1.76.0", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.76.0.tgz", - "integrity": "sha512-aJtF/nTs+9St+KtTK/wgVJ+SinfjYzn+3w1ygYIPw8ST6LH+qHBn8XkodgDTwlv/xzNkaVz1kkUDOZ8BPXyZWA==", + "version": "1.77.1", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.77.1.tgz", + "integrity": "sha512-YWahzcQtQ3inR2+ZSqWsoJnXBppfd//7mbSFVFpyJWyE+vTtSfljdKVOosCY0ynu6AZaBLV1HYErc2wZOXUdeA==", "requires": { "@babel/runtime": "^7.12.5", "@noble/curves": "^1.0.0", diff --git a/clients/js-legacy/src/index.ts b/clients/js-legacy/src/index.ts index 9b77e2a3..7043b90c 100644 --- a/clients/js-legacy/src/index.ts +++ b/clients/js-legacy/src/index.ts @@ -141,7 +141,7 @@ export async function getStakePoolAccounts( ): Promise<(StakePoolAccount | ValidatorListAccount)[] | undefined> { const response = await connection.getProgramAccounts(stakePoolProgramAddress); - return response.map((a) => { + return response.value.map((a) => { let decodedData; if (a.account.data.readUInt8() === 1) { From 8580642c23abe0332ada3486695840512e9bcc93 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 May 2023 00:54:44 +0200 Subject: [PATCH 0357/1076] build(deps-dev): bump @types/node from 20.2.3 to 20.2.5 in /stake-pool/js (#4404) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 7a5d871e..9ffb8862 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1743,9 +1743,9 @@ "integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==" }, "node_modules/@types/node": { - "version": "20.2.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.3.tgz", - "integrity": "sha512-pg9d0yC4rVNWQzX8U7xb4olIOFuuVL9za3bzMT2pu2SU0SNEi66i2qrvhE2qt0HvkhuCaWJu7pLNOt/Pj8BIrw==" + "version": "20.2.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.5.tgz", + "integrity": "sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==" }, "node_modules/@types/node-fetch": { "version": "2.6.4", @@ -8022,9 +8022,9 @@ "integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==" }, "@types/node": { - "version": "20.2.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.3.tgz", - "integrity": "sha512-pg9d0yC4rVNWQzX8U7xb4olIOFuuVL9za3bzMT2pu2SU0SNEi66i2qrvhE2qt0HvkhuCaWJu7pLNOt/Pj8BIrw==" + "version": "20.2.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.5.tgz", + "integrity": "sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==" }, "@types/node-fetch": { "version": "2.6.4", From 22bd804fb3dd8244b6a5e507c2e97abe2676b1ad Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 May 2023 16:21:39 +0200 Subject: [PATCH 0358/1076] build(deps): bump @solana/web3.js from 1.77.1 to 1.77.2 in /stake-pool/js (#4413) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 9ffb8862..7bb636e3 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1584,9 +1584,9 @@ } }, "node_modules/@solana/web3.js": { - "version": "1.77.1", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.77.1.tgz", - "integrity": "sha512-YWahzcQtQ3inR2+ZSqWsoJnXBppfd//7mbSFVFpyJWyE+vTtSfljdKVOosCY0ynu6AZaBLV1HYErc2wZOXUdeA==", + "version": "1.77.2", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.77.2.tgz", + "integrity": "sha512-pKu9S21NGAi6Nsayz2KEdhqOlPUJIr3L911bgQvPg2Dbk/U4gJsk41XGdxyfsfnwKPEI/KbitcByterst4VQ3g==", "dependencies": { "@babel/runtime": "^7.12.5", "@noble/curves": "^1.0.0", @@ -7866,9 +7866,9 @@ } }, "@solana/web3.js": { - "version": "1.77.1", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.77.1.tgz", - "integrity": "sha512-YWahzcQtQ3inR2+ZSqWsoJnXBppfd//7mbSFVFpyJWyE+vTtSfljdKVOosCY0ynu6AZaBLV1HYErc2wZOXUdeA==", + "version": "1.77.2", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.77.2.tgz", + "integrity": "sha512-pKu9S21NGAi6Nsayz2KEdhqOlPUJIr3L911bgQvPg2Dbk/U4gJsk41XGdxyfsfnwKPEI/KbitcByterst4VQ3g==", "requires": { "@babel/runtime": "^7.12.5", "@noble/curves": "^1.0.0", From 52257f01d9a4111a3d534f7d75db7e5e648f8380 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 May 2023 18:59:47 +0200 Subject: [PATCH 0359/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 5.59.7 to 5.59.8 in /stake-pool/js (#4423) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 362 +++++++++++++++++++++++++--- 1 file changed, 322 insertions(+), 40 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 7bb636e3..e7e768c5 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1732,9 +1732,9 @@ } }, "node_modules/@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", + "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", "dev": true }, "node_modules/@types/lodash": { @@ -1815,15 +1815,15 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.7.tgz", - "integrity": "sha512-BL+jYxUFIbuYwy+4fF86k5vdT9lT0CNJ6HtwrIvGh0PhH8s0yy5rjaKH2fDCrz5ITHy07WCzVGNvAmjJh4IJFA==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.8.tgz", + "integrity": "sha512-JDMOmhXteJ4WVKOiHXGCoB96ADWg9q7efPWHRViT/f09bA8XOMLAVHHju3l0MkZnG1izaWXYmgvQcUjTRcpShQ==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.7", - "@typescript-eslint/type-utils": "5.59.7", - "@typescript-eslint/utils": "5.59.7", + "@typescript-eslint/scope-manager": "5.59.8", + "@typescript-eslint/type-utils": "5.59.8", + "@typescript-eslint/utils": "5.59.8", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", @@ -1848,6 +1848,53 @@ } } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.8.tgz", + "integrity": "sha512-/w08ndCYI8gxGf+9zKf1vtx/16y8MHrZs5/tnjHhMLNSixuNcJavSX4wAiPf4aS5x41Es9YPCn44MIe4cxIlig==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/visitor-keys": "5.59.8" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.8.tgz", + "integrity": "sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.8.tgz", + "integrity": "sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.8", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/parser": { "version": "5.59.7", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.7.tgz", @@ -1893,13 +1940,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.7.tgz", - "integrity": "sha512-ozuz/GILuYG7osdY5O5yg0QxXUAEoI4Go3Do5xeu+ERH9PorHBPSdvD3Tjp2NN2bNLh1NJQSsQu2TPu/Ly+HaQ==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.8.tgz", + "integrity": "sha512-+5M518uEIHFBy3FnyqZUF3BMP+AXnYn4oyH8RF012+e7/msMY98FhGL5SrN29NQ9xDgvqCgYnsOiKp1VjZ/fpA==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.59.7", - "@typescript-eslint/utils": "5.59.7", + "@typescript-eslint/typescript-estree": "5.59.8", + "@typescript-eslint/utils": "5.59.8", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -1919,6 +1966,63 @@ } } }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.8.tgz", + "integrity": "sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.8.tgz", + "integrity": "sha512-Jy/lPSDJGNow14vYu6IrW790p7HIf/SOV1Bb6lZ7NUkLc2iB2Z9elESmsaUtLw8kVqogSbtLH9tut5GCX1RLDg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/visitor-keys": "5.59.8", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.8.tgz", + "integrity": "sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.8", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/types": { "version": "5.59.7", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.7.tgz", @@ -1960,17 +2064,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.7.tgz", - "integrity": "sha512-yCX9WpdQKaLufz5luG4aJbOpdXf/fjwGMcLFXZVPUz3QqLirG5QcwwnIHNf8cjLjxK4qtzTO8udUtMQSAToQnQ==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.8.tgz", + "integrity": "sha512-Tr65630KysnNn9f9G7ROF3w1b5/7f6QVCJ+WK9nhIocWmx9F+TmCAcglF26Vm7z8KCTwoKcNEBZrhlklla3CKg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.7", - "@typescript-eslint/types": "5.59.7", - "@typescript-eslint/typescript-estree": "5.59.7", + "@typescript-eslint/scope-manager": "5.59.8", + "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/typescript-estree": "5.59.8", "eslint-scope": "^5.1.1", "semver": "^7.3.7" }, @@ -1985,6 +2089,80 @@ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.8.tgz", + "integrity": "sha512-/w08ndCYI8gxGf+9zKf1vtx/16y8MHrZs5/tnjHhMLNSixuNcJavSX4wAiPf4aS5x41Es9YPCn44MIe4cxIlig==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/visitor-keys": "5.59.8" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.8.tgz", + "integrity": "sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.8.tgz", + "integrity": "sha512-Jy/lPSDJGNow14vYu6IrW790p7HIf/SOV1Bb6lZ7NUkLc2iB2Z9elESmsaUtLw8kVqogSbtLH9tut5GCX1RLDg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/visitor-keys": "5.59.8", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.8.tgz", + "integrity": "sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.8", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/visitor-keys": { "version": "5.59.7", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.7.tgz", @@ -8011,9 +8189,9 @@ } }, "@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", + "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", "dev": true }, "@types/lodash": { @@ -8094,21 +8272,49 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.7.tgz", - "integrity": "sha512-BL+jYxUFIbuYwy+4fF86k5vdT9lT0CNJ6HtwrIvGh0PhH8s0yy5rjaKH2fDCrz5ITHy07WCzVGNvAmjJh4IJFA==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.8.tgz", + "integrity": "sha512-JDMOmhXteJ4WVKOiHXGCoB96ADWg9q7efPWHRViT/f09bA8XOMLAVHHju3l0MkZnG1izaWXYmgvQcUjTRcpShQ==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.7", - "@typescript-eslint/type-utils": "5.59.7", - "@typescript-eslint/utils": "5.59.7", + "@typescript-eslint/scope-manager": "5.59.8", + "@typescript-eslint/type-utils": "5.59.8", + "@typescript-eslint/utils": "5.59.8", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", "semver": "^7.3.7", "tsutils": "^3.21.0" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.8.tgz", + "integrity": "sha512-/w08ndCYI8gxGf+9zKf1vtx/16y8MHrZs5/tnjHhMLNSixuNcJavSX4wAiPf4aS5x41Es9YPCn44MIe4cxIlig==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/visitor-keys": "5.59.8" + } + }, + "@typescript-eslint/types": { + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.8.tgz", + "integrity": "sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w==", + "dev": true + }, + "@typescript-eslint/visitor-keys": { + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.8.tgz", + "integrity": "sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.8", + "eslint-visitor-keys": "^3.3.0" + } + } } }, "@typescript-eslint/parser": { @@ -8134,15 +8340,48 @@ } }, "@typescript-eslint/type-utils": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.7.tgz", - "integrity": "sha512-ozuz/GILuYG7osdY5O5yg0QxXUAEoI4Go3Do5xeu+ERH9PorHBPSdvD3Tjp2NN2bNLh1NJQSsQu2TPu/Ly+HaQ==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.8.tgz", + "integrity": "sha512-+5M518uEIHFBy3FnyqZUF3BMP+AXnYn4oyH8RF012+e7/msMY98FhGL5SrN29NQ9xDgvqCgYnsOiKp1VjZ/fpA==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.59.7", - "@typescript-eslint/utils": "5.59.7", + "@typescript-eslint/typescript-estree": "5.59.8", + "@typescript-eslint/utils": "5.59.8", "debug": "^4.3.4", "tsutils": "^3.21.0" + }, + "dependencies": { + "@typescript-eslint/types": { + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.8.tgz", + "integrity": "sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.8.tgz", + "integrity": "sha512-Jy/lPSDJGNow14vYu6IrW790p7HIf/SOV1Bb6lZ7NUkLc2iB2Z9elESmsaUtLw8kVqogSbtLH9tut5GCX1RLDg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/visitor-keys": "5.59.8", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.8.tgz", + "integrity": "sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.8", + "eslint-visitor-keys": "^3.3.0" + } + } } }, "@typescript-eslint/types": { @@ -8167,19 +8406,62 @@ } }, "@typescript-eslint/utils": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.7.tgz", - "integrity": "sha512-yCX9WpdQKaLufz5luG4aJbOpdXf/fjwGMcLFXZVPUz3QqLirG5QcwwnIHNf8cjLjxK4qtzTO8udUtMQSAToQnQ==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.8.tgz", + "integrity": "sha512-Tr65630KysnNn9f9G7ROF3w1b5/7f6QVCJ+WK9nhIocWmx9F+TmCAcglF26Vm7z8KCTwoKcNEBZrhlklla3CKg==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.7", - "@typescript-eslint/types": "5.59.7", - "@typescript-eslint/typescript-estree": "5.59.7", + "@typescript-eslint/scope-manager": "5.59.8", + "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/typescript-estree": "5.59.8", "eslint-scope": "^5.1.1", "semver": "^7.3.7" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.8.tgz", + "integrity": "sha512-/w08ndCYI8gxGf+9zKf1vtx/16y8MHrZs5/tnjHhMLNSixuNcJavSX4wAiPf4aS5x41Es9YPCn44MIe4cxIlig==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/visitor-keys": "5.59.8" + } + }, + "@typescript-eslint/types": { + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.8.tgz", + "integrity": "sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.8.tgz", + "integrity": "sha512-Jy/lPSDJGNow14vYu6IrW790p7HIf/SOV1Bb6lZ7NUkLc2iB2Z9elESmsaUtLw8kVqogSbtLH9tut5GCX1RLDg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/visitor-keys": "5.59.8", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.8.tgz", + "integrity": "sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.8", + "eslint-visitor-keys": "^3.3.0" + } + } } }, "@typescript-eslint/visitor-keys": { From 16abd1ac6524b8e05ec050f2f53cf4b6b538540a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 May 2023 20:00:08 +0200 Subject: [PATCH 0360/1076] build(deps-dev): bump @typescript-eslint/parser from 5.59.7 to 5.59.8 in /stake-pool/js (#4424) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 354 +++------------------------- 1 file changed, 36 insertions(+), 318 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index e7e768c5..2b021c4e 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1848,62 +1848,15 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.8.tgz", - "integrity": "sha512-/w08ndCYI8gxGf+9zKf1vtx/16y8MHrZs5/tnjHhMLNSixuNcJavSX4wAiPf4aS5x41Es9YPCn44MIe4cxIlig==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.8", - "@typescript-eslint/visitor-keys": "5.59.8" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.8.tgz", - "integrity": "sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "node_modules/@typescript-eslint/parser": { "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.8.tgz", - "integrity": "sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ==", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.8.tgz", + "integrity": "sha512-AnR19RjJcpjoeGojmwZtCwBX/RidqDZtzcbG3xHrmz0aHHoOcbWnpDllenRDmDvsV0RQ6+tbb09/kyc+UT9Orw==", "dev": true, "dependencies": { + "@typescript-eslint/scope-manager": "5.59.8", "@typescript-eslint/types": "5.59.8", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.7.tgz", - "integrity": "sha512-VhpsIEuq/8i5SF+mPg9jSdIwgMBBp0z9XqjiEay+81PYLJuroN+ET1hM5IhkiYMJd9MkTz8iJLt7aaGAgzWUbQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "5.59.7", - "@typescript-eslint/types": "5.59.7", - "@typescript-eslint/typescript-estree": "5.59.7", + "@typescript-eslint/typescript-estree": "5.59.8", "debug": "^4.3.4" }, "engines": { @@ -1923,13 +1876,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.7.tgz", - "integrity": "sha512-FL6hkYWK9zBGdxT2wWEd2W8ocXMu3K94i3gvMrjXpx+koFYdYV7KprKfirpgY34vTGzEPPuKoERpP8kD5h7vZQ==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.8.tgz", + "integrity": "sha512-/w08ndCYI8gxGf+9zKf1vtx/16y8MHrZs5/tnjHhMLNSixuNcJavSX4wAiPf4aS5x41Es9YPCn44MIe4cxIlig==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.7", - "@typescript-eslint/visitor-keys": "5.59.7" + "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/visitor-keys": "5.59.8" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1966,7 +1919,7 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "node_modules/@typescript-eslint/types": { "version": "5.59.8", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.8.tgz", "integrity": "sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w==", @@ -1979,7 +1932,7 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "node_modules/@typescript-eslint/typescript-estree": { "version": "5.59.8", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.8.tgz", "integrity": "sha512-Jy/lPSDJGNow14vYu6IrW790p7HIf/SOV1Bb6lZ7NUkLc2iB2Z9elESmsaUtLw8kVqogSbtLH9tut5GCX1RLDg==", @@ -2006,63 +1959,6 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.8.tgz", - "integrity": "sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.8", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.7.tgz", - "integrity": "sha512-UnVS2MRRg6p7xOSATscWkKjlf/NDKuqo5TdbWck6rIRZbmKpVNTLALzNvcjIfHBE7736kZOFc/4Z3VcZwuOM/A==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.7.tgz", - "integrity": "sha512-4A1NtZ1I3wMN2UGDkU9HMBL+TIQfbrh4uS0WDMMpf3xMRursDbqEf1ahh6vAAe3mObt8k3ZATnezwG4pdtWuUQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.7", - "@typescript-eslint/visitor-keys": "5.59.7", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, "node_modules/@typescript-eslint/utils": { "version": "5.59.8", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.8.tgz", @@ -2089,64 +1985,7 @@ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.8.tgz", - "integrity": "sha512-/w08ndCYI8gxGf+9zKf1vtx/16y8MHrZs5/tnjHhMLNSixuNcJavSX4wAiPf4aS5x41Es9YPCn44MIe4cxIlig==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.8", - "@typescript-eslint/visitor-keys": "5.59.8" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.8.tgz", - "integrity": "sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.8.tgz", - "integrity": "sha512-Jy/lPSDJGNow14vYu6IrW790p7HIf/SOV1Bb6lZ7NUkLc2iB2Z9elESmsaUtLw8kVqogSbtLH9tut5GCX1RLDg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.8", - "@typescript-eslint/visitor-keys": "5.59.8", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "node_modules/@typescript-eslint/visitor-keys": { "version": "5.59.8", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.8.tgz", "integrity": "sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ==", @@ -2163,23 +2002,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.7.tgz", - "integrity": "sha512-tyN+X2jvMslUszIiYbF0ZleP+RqQsFVpGrKI6e0Eet1w8WmhsAtmzaqm8oM8WJQ1ysLwhnsK/4hYHJjOgJVfQQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.7", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/abab": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", @@ -8287,56 +8109,28 @@ "natural-compare-lite": "^1.4.0", "semver": "^7.3.7", "tsutils": "^3.21.0" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.8.tgz", - "integrity": "sha512-/w08ndCYI8gxGf+9zKf1vtx/16y8MHrZs5/tnjHhMLNSixuNcJavSX4wAiPf4aS5x41Es9YPCn44MIe4cxIlig==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.8", - "@typescript-eslint/visitor-keys": "5.59.8" - } - }, - "@typescript-eslint/types": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.8.tgz", - "integrity": "sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w==", - "dev": true - }, - "@typescript-eslint/visitor-keys": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.8.tgz", - "integrity": "sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.8", - "eslint-visitor-keys": "^3.3.0" - } - } } }, "@typescript-eslint/parser": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.7.tgz", - "integrity": "sha512-VhpsIEuq/8i5SF+mPg9jSdIwgMBBp0z9XqjiEay+81PYLJuroN+ET1hM5IhkiYMJd9MkTz8iJLt7aaGAgzWUbQ==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.8.tgz", + "integrity": "sha512-AnR19RjJcpjoeGojmwZtCwBX/RidqDZtzcbG3xHrmz0aHHoOcbWnpDllenRDmDvsV0RQ6+tbb09/kyc+UT9Orw==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.59.7", - "@typescript-eslint/types": "5.59.7", - "@typescript-eslint/typescript-estree": "5.59.7", + "@typescript-eslint/scope-manager": "5.59.8", + "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/typescript-estree": "5.59.8", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.7.tgz", - "integrity": "sha512-FL6hkYWK9zBGdxT2wWEd2W8ocXMu3K94i3gvMrjXpx+koFYdYV7KprKfirpgY34vTGzEPPuKoERpP8kD5h7vZQ==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.8.tgz", + "integrity": "sha512-/w08ndCYI8gxGf+9zKf1vtx/16y8MHrZs5/tnjHhMLNSixuNcJavSX4wAiPf4aS5x41Es9YPCn44MIe4cxIlig==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.7", - "@typescript-eslint/visitor-keys": "5.59.7" + "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/visitor-keys": "5.59.8" } }, "@typescript-eslint/type-utils": { @@ -8349,55 +8143,22 @@ "@typescript-eslint/utils": "5.59.8", "debug": "^4.3.4", "tsutils": "^3.21.0" - }, - "dependencies": { - "@typescript-eslint/types": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.8.tgz", - "integrity": "sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.8.tgz", - "integrity": "sha512-Jy/lPSDJGNow14vYu6IrW790p7HIf/SOV1Bb6lZ7NUkLc2iB2Z9elESmsaUtLw8kVqogSbtLH9tut5GCX1RLDg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.8", - "@typescript-eslint/visitor-keys": "5.59.8", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.8.tgz", - "integrity": "sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.8", - "eslint-visitor-keys": "^3.3.0" - } - } } }, "@typescript-eslint/types": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.7.tgz", - "integrity": "sha512-UnVS2MRRg6p7xOSATscWkKjlf/NDKuqo5TdbWck6rIRZbmKpVNTLALzNvcjIfHBE7736kZOFc/4Z3VcZwuOM/A==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.8.tgz", + "integrity": "sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.7.tgz", - "integrity": "sha512-4A1NtZ1I3wMN2UGDkU9HMBL+TIQfbrh4uS0WDMMpf3xMRursDbqEf1ahh6vAAe3mObt8k3ZATnezwG4pdtWuUQ==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.8.tgz", + "integrity": "sha512-Jy/lPSDJGNow14vYu6IrW790p7HIf/SOV1Bb6lZ7NUkLc2iB2Z9elESmsaUtLw8kVqogSbtLH9tut5GCX1RLDg==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.7", - "@typescript-eslint/visitor-keys": "5.59.7", + "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/visitor-keys": "5.59.8", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -8419,58 +8180,15 @@ "@typescript-eslint/typescript-estree": "5.59.8", "eslint-scope": "^5.1.1", "semver": "^7.3.7" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.8.tgz", - "integrity": "sha512-/w08ndCYI8gxGf+9zKf1vtx/16y8MHrZs5/tnjHhMLNSixuNcJavSX4wAiPf4aS5x41Es9YPCn44MIe4cxIlig==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.8", - "@typescript-eslint/visitor-keys": "5.59.8" - } - }, - "@typescript-eslint/types": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.8.tgz", - "integrity": "sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.8.tgz", - "integrity": "sha512-Jy/lPSDJGNow14vYu6IrW790p7HIf/SOV1Bb6lZ7NUkLc2iB2Z9elESmsaUtLw8kVqogSbtLH9tut5GCX1RLDg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.8", - "@typescript-eslint/visitor-keys": "5.59.8", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.8.tgz", - "integrity": "sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.8", - "eslint-visitor-keys": "^3.3.0" - } - } } }, "@typescript-eslint/visitor-keys": { - "version": "5.59.7", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.7.tgz", - "integrity": "sha512-tyN+X2jvMslUszIiYbF0ZleP+RqQsFVpGrKI6e0Eet1w8WmhsAtmzaqm8oM8WJQ1ysLwhnsK/4hYHJjOgJVfQQ==", + "version": "5.59.8", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.8.tgz", + "integrity": "sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.7", + "@typescript-eslint/types": "5.59.8", "eslint-visitor-keys": "^3.3.0" } }, From 468769c01a5d0bd68f869874b3053d506f68db0e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 31 May 2023 15:51:51 +0200 Subject: [PATCH 0361/1076] build(deps-dev): bump @rollup/plugin-node-resolve from 15.0.2 to 15.1.0 in /stake-pool/js (#4432) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 2b021c4e..b7a74e45 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1435,9 +1435,9 @@ } }, "node_modules/@rollup/plugin-node-resolve": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.0.2.tgz", - "integrity": "sha512-Y35fRGUjC3FaurG722uhUuG8YHOJRJQbI6/CkbRkdPotSpDj9NtIN85z1zrcyDcCQIW4qp5mgG72U+gJ0TAFEg==", + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.1.0.tgz", + "integrity": "sha512-xeZHCgsiZ9pzYVgAo9580eCGqwh/XCEUM9q6iQfGNocjgkufHAqC3exA+45URvhiYV8sBF9RlBai650eNs7AsA==", "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1", @@ -7777,9 +7777,9 @@ } }, "@rollup/plugin-node-resolve": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.0.2.tgz", - "integrity": "sha512-Y35fRGUjC3FaurG722uhUuG8YHOJRJQbI6/CkbRkdPotSpDj9NtIN85z1zrcyDcCQIW4qp5mgG72U+gJ0TAFEg==", + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.1.0.tgz", + "integrity": "sha512-xeZHCgsiZ9pzYVgAo9580eCGqwh/XCEUM9q6iQfGNocjgkufHAqC3exA+45URvhiYV8sBF9RlBai650eNs7AsA==", "dev": true, "requires": { "@rollup/pluginutils": "^5.0.1", From ed130ac9ad3b6631f9d433f09bfe3f30ba015eab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Jun 2023 19:06:17 +0200 Subject: [PATCH 0362/1076] build(deps): bump @solana/web3.js from 1.77.2 to 1.77.3 in /stake-pool/js (#4443) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/js-legacy/package-lock.json | 122 ++++++++-------------------- clients/js-legacy/src/index.ts | 2 +- 2 files changed, 35 insertions(+), 89 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index b7a74e45..e9b8a98d 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1584,9 +1584,9 @@ } }, "node_modules/@solana/web3.js": { - "version": "1.77.2", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.77.2.tgz", - "integrity": "sha512-pKu9S21NGAi6Nsayz2KEdhqOlPUJIr3L911bgQvPg2Dbk/U4gJsk41XGdxyfsfnwKPEI/KbitcByterst4VQ3g==", + "version": "1.77.3", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.77.3.tgz", + "integrity": "sha512-PHaO0BdoiQRPpieC1p31wJsBaxwIOWLh8j2ocXNKX8boCQVldt26Jqm2tZE4KlrvnCIV78owPLv1pEUgqhxZ3w==", "dependencies": { "@babel/runtime": "^7.12.5", "@noble/curves": "^1.0.0", @@ -1599,7 +1599,7 @@ "bs58": "^4.0.1", "buffer": "6.0.3", "fast-stable-stringify": "^1.0.0", - "jayson": "^3.4.4", + "jayson": "^4.1.0", "node-fetch": "^2.6.7", "rpc-websockets": "^7.5.1", "superstruct": "^0.14.2" @@ -1678,16 +1678,6 @@ "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", "dev": true }, - "node_modules/@types/express-serve-static-core": { - "version": "4.17.28", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", - "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" - } - }, "node_modules/@types/graceful-fs": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", @@ -1737,11 +1727,6 @@ "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", "dev": true }, - "node_modules/@types/lodash": { - "version": "4.14.178", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.178.tgz", - "integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==" - }, "node_modules/@types/node": { "version": "20.2.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.5.tgz", @@ -1763,16 +1748,6 @@ "integrity": "sha512-ReVR2rLTV1kvtlWFyuot+d1pkpG2Fw/XKE3PDAdj57rbM97ttSp9JZ2UsP+2EHTylra9cUf6JA7tGwW1INzUrA==", "dev": true }, - "node_modules/@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" - }, - "node_modules/@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" - }, "node_modules/@types/resolve": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", @@ -2901,7 +2876,7 @@ "node_modules/es6-promisify": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", "dependencies": { "es6-promise": "^4.0.3" } @@ -3360,7 +3335,7 @@ "node_modules/eyes": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", - "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=", + "integrity": "sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==", "engines": { "node": "> 0.1.90" } @@ -4128,13 +4103,11 @@ } }, "node_modules/jayson": { - "version": "3.6.6", - "resolved": "https://registry.npmjs.org/jayson/-/jayson-3.6.6.tgz", - "integrity": "sha512-f71uvrAWTtrwoww6MKcl9phQTC+56AopLyEenWvKVAIMz+q0oVGj6tenLZ7Z6UiPBkJtKLj4kt0tACllFQruGQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/jayson/-/jayson-4.1.0.tgz", + "integrity": "sha512-R6JlbyLN53Mjku329XoRT2zJAE6ZgOQ8f91ucYdMCD4nkGCF9kZSrcGXpHIU4jeKj58zUZke2p+cdQchU7Ly7A==", "dependencies": { "@types/connect": "^3.4.33", - "@types/express-serve-static-core": "^4.17.9", - "@types/lodash": "^4.14.159", "@types/node": "^12.12.54", "@types/ws": "^7.4.4", "commander": "^2.20.3", @@ -4144,7 +4117,6 @@ "isomorphic-ws": "^4.0.1", "json-stringify-safe": "^5.0.1", "JSONStream": "^1.3.5", - "lodash": "^4.17.20", "uuid": "^8.3.2", "ws": "^7.4.5" }, @@ -4156,9 +4128,9 @@ } }, "node_modules/jayson/node_modules/@types/node": { - "version": "12.20.45", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.45.tgz", - "integrity": "sha512-1Jg2Qv5tuxBqgQV04+wO5u+wmSHbHgpORCJdeCLM+E+YdPElpdHhgywU+M1V1InL8rfOtpqtOjswk+uXTKwx7w==" + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==" }, "node_modules/jest": { "version": "27.5.1", @@ -4870,7 +4842,7 @@ "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" }, "node_modules/json5": { "version": "2.2.3", @@ -4887,7 +4859,7 @@ "node_modules/jsonparse": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", "engines": [ "node >= 0.2.0" ] @@ -4959,7 +4931,8 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true }, "node_modules/lodash.memoize": { "version": "4.1.2", @@ -6271,7 +6244,7 @@ "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" }, "node_modules/tmpl": { "version": "1.0.5", @@ -7866,9 +7839,9 @@ } }, "@solana/web3.js": { - "version": "1.77.2", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.77.2.tgz", - "integrity": "sha512-pKu9S21NGAi6Nsayz2KEdhqOlPUJIr3L911bgQvPg2Dbk/U4gJsk41XGdxyfsfnwKPEI/KbitcByterst4VQ3g==", + "version": "1.77.3", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.77.3.tgz", + "integrity": "sha512-PHaO0BdoiQRPpieC1p31wJsBaxwIOWLh8j2ocXNKX8boCQVldt26Jqm2tZE4KlrvnCIV78owPLv1pEUgqhxZ3w==", "requires": { "@babel/runtime": "^7.12.5", "@noble/curves": "^1.0.0", @@ -7881,7 +7854,7 @@ "bs58": "^4.0.1", "buffer": "6.0.3", "fast-stable-stringify": "^1.0.0", - "jayson": "^3.4.4", + "jayson": "^4.1.0", "node-fetch": "^2.6.7", "rpc-websockets": "^7.5.1", "superstruct": "^0.14.2" @@ -7957,16 +7930,6 @@ "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", "dev": true }, - "@types/express-serve-static-core": { - "version": "4.17.28", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", - "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", - "requires": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" - } - }, "@types/graceful-fs": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", @@ -8016,11 +7979,6 @@ "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", "dev": true }, - "@types/lodash": { - "version": "4.14.178", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.178.tgz", - "integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==" - }, "@types/node": { "version": "20.2.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.5.tgz", @@ -8042,16 +8000,6 @@ "integrity": "sha512-ReVR2rLTV1kvtlWFyuot+d1pkpG2Fw/XKE3PDAdj57rbM97ttSp9JZ2UsP+2EHTylra9cUf6JA7tGwW1INzUrA==", "dev": true }, - "@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" - }, - "@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" - }, "@types/resolve": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", @@ -8868,7 +8816,7 @@ "es6-promisify": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", "requires": { "es6-promise": "^4.0.3" } @@ -9191,7 +9139,7 @@ "eyes": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", - "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=" + "integrity": "sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==" }, "fast-deep-equal": { "version": "3.1.3", @@ -9765,13 +9713,11 @@ } }, "jayson": { - "version": "3.6.6", - "resolved": "https://registry.npmjs.org/jayson/-/jayson-3.6.6.tgz", - "integrity": "sha512-f71uvrAWTtrwoww6MKcl9phQTC+56AopLyEenWvKVAIMz+q0oVGj6tenLZ7Z6UiPBkJtKLj4kt0tACllFQruGQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/jayson/-/jayson-4.1.0.tgz", + "integrity": "sha512-R6JlbyLN53Mjku329XoRT2zJAE6ZgOQ8f91ucYdMCD4nkGCF9kZSrcGXpHIU4jeKj58zUZke2p+cdQchU7Ly7A==", "requires": { "@types/connect": "^3.4.33", - "@types/express-serve-static-core": "^4.17.9", - "@types/lodash": "^4.14.159", "@types/node": "^12.12.54", "@types/ws": "^7.4.4", "commander": "^2.20.3", @@ -9781,15 +9727,14 @@ "isomorphic-ws": "^4.0.1", "json-stringify-safe": "^5.0.1", "JSONStream": "^1.3.5", - "lodash": "^4.17.20", "uuid": "^8.3.2", "ws": "^7.4.5" }, "dependencies": { "@types/node": { - "version": "12.20.45", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.45.tgz", - "integrity": "sha512-1Jg2Qv5tuxBqgQV04+wO5u+wmSHbHgpORCJdeCLM+E+YdPElpdHhgywU+M1V1InL8rfOtpqtOjswk+uXTKwx7w==" + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==" } } }, @@ -10349,7 +10294,7 @@ "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" }, "json5": { "version": "2.2.3", @@ -10360,7 +10305,7 @@ "jsonparse": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=" + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==" }, "JSONStream": { "version": "1.3.5", @@ -10411,7 +10356,8 @@ "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true }, "lodash.memoize": { "version": "4.1.2", @@ -11371,7 +11317,7 @@ "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" }, "tmpl": { "version": "1.0.5", diff --git a/clients/js-legacy/src/index.ts b/clients/js-legacy/src/index.ts index 7043b90c..9b77e2a3 100644 --- a/clients/js-legacy/src/index.ts +++ b/clients/js-legacy/src/index.ts @@ -141,7 +141,7 @@ export async function getStakePoolAccounts( ): Promise<(StakePoolAccount | ValidatorListAccount)[] | undefined> { const response = await connection.getProgramAccounts(stakePoolProgramAddress); - return response.value.map((a) => { + return response.map((a) => { let decodedData; if (a.account.data.readUInt8() === 1) { From f4e26424ad4213c337a9a481b0680f1c05612c27 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 3 Jun 2023 12:40:17 +0200 Subject: [PATCH 0363/1076] build(deps): bump @solana/spl-token from 0.3.7 to 0.3.8 in /stake-pool/js (#4455) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index e9b8a98d..4228e25d 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1568,9 +1568,9 @@ } }, "node_modules/@solana/spl-token": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.3.7.tgz", - "integrity": "sha512-bKGxWTtIw6VDdCBngjtsGlKGLSmiu/8ghSt/IOYJV24BsymRbgq7r12GToeetpxmPaZYLddKwAz7+EwprLfkfg==", + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.3.8.tgz", + "integrity": "sha512-ogwGDcunP9Lkj+9CODOWMiVJEdRtqHAtX2rWF62KxnnSWtMZtV9rDhTrZFshiyJmxDnRL/1nKE1yJHg4jjs3gg==", "dependencies": { "@solana/buffer-layout": "^4.0.0", "@solana/buffer-layout-utils": "^0.2.0", @@ -7829,9 +7829,9 @@ } }, "@solana/spl-token": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.3.7.tgz", - "integrity": "sha512-bKGxWTtIw6VDdCBngjtsGlKGLSmiu/8ghSt/IOYJV24BsymRbgq7r12GToeetpxmPaZYLddKwAz7+EwprLfkfg==", + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.3.8.tgz", + "integrity": "sha512-ogwGDcunP9Lkj+9CODOWMiVJEdRtqHAtX2rWF62KxnnSWtMZtV9rDhTrZFshiyJmxDnRL/1nKE1yJHg4jjs3gg==", "requires": { "@solana/buffer-layout": "^4.0.0", "@solana/buffer-layout-utils": "^0.2.0", From c61686e730bd5a9f101940531e0d21fbf532e5d9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Jun 2023 16:04:58 +0200 Subject: [PATCH 0364/1076] build(deps-dev): bump eslint from 8.41.0 to 8.42.0 in /stake-pool/js (#4472) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 44 ++++++++++++++--------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 4228e25d..8d90b8aa 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -708,18 +708,18 @@ } }, "node_modules/@eslint/js": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.41.0.tgz", - "integrity": "sha512-LxcyMGxwmTh2lY9FwHPGWOHmYFCZvbrFCBZL4FzSSsxsRPuhrYUg/49/0KDfW8tnIEaEHtfmn6+NPN+1DqaNmA==", + "version": "8.42.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.42.0.tgz", + "integrity": "sha512-6SWlXpWU5AvId8Ac7zjzmIOqMOba/JWY8XZ4A7q7Gn1Vlfg/SFFIlrtHXt9nPn4op9ZPAkl91Jao+QQv3r/ukw==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.8", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", - "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", + "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", @@ -2985,16 +2985,16 @@ } }, "node_modules/eslint": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.41.0.tgz", - "integrity": "sha512-WQDQpzGBOP5IrXPo4Hc0814r4/v2rrIsB0rhT7jtunIalgg6gYXWhRMOejVO8yH21T/FGaxjmFjBMNqcIlmH1Q==", + "version": "8.42.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.42.0.tgz", + "integrity": "sha512-ulg9Ms6E1WPf67PHaEY4/6E2tEn5/f7FXGzr3t9cBMugOmf1INYvuUwwh1aXQN4MfJ6a5K2iNwP3w4AColvI9A==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.4.0", "@eslint/eslintrc": "^2.0.3", - "@eslint/js": "8.41.0", - "@humanwhocodes/config-array": "^0.11.8", + "@eslint/js": "8.42.0", + "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.10.0", @@ -7221,15 +7221,15 @@ } }, "@eslint/js": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.41.0.tgz", - "integrity": "sha512-LxcyMGxwmTh2lY9FwHPGWOHmYFCZvbrFCBZL4FzSSsxsRPuhrYUg/49/0KDfW8tnIEaEHtfmn6+NPN+1DqaNmA==", + "version": "8.42.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.42.0.tgz", + "integrity": "sha512-6SWlXpWU5AvId8Ac7zjzmIOqMOba/JWY8XZ4A7q7Gn1Vlfg/SFFIlrtHXt9nPn4op9ZPAkl91Jao+QQv3r/ukw==", "dev": true }, "@humanwhocodes/config-array": { - "version": "0.11.8", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", - "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", + "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.1", @@ -8894,16 +8894,16 @@ } }, "eslint": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.41.0.tgz", - "integrity": "sha512-WQDQpzGBOP5IrXPo4Hc0814r4/v2rrIsB0rhT7jtunIalgg6gYXWhRMOejVO8yH21T/FGaxjmFjBMNqcIlmH1Q==", + "version": "8.42.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.42.0.tgz", + "integrity": "sha512-ulg9Ms6E1WPf67PHaEY4/6E2tEn5/f7FXGzr3t9cBMugOmf1INYvuUwwh1aXQN4MfJ6a5K2iNwP3w4AColvI9A==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.4.0", "@eslint/eslintrc": "^2.0.3", - "@eslint/js": "8.41.0", - "@humanwhocodes/config-array": "^0.11.8", + "@eslint/js": "8.42.0", + "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.10.0", From 2f0bc149ae5d74d837af8265969373c4352ec815 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Jun 2023 15:27:42 +0200 Subject: [PATCH 0365/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 5.59.8 to 5.59.9 in /stake-pool/js (#4487) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 350 +++++++++++++++++++++++++--- 1 file changed, 316 insertions(+), 34 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 8d90b8aa..97b1d022 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1790,15 +1790,15 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.8.tgz", - "integrity": "sha512-JDMOmhXteJ4WVKOiHXGCoB96ADWg9q7efPWHRViT/f09bA8XOMLAVHHju3l0MkZnG1izaWXYmgvQcUjTRcpShQ==", + "version": "5.59.9", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.9.tgz", + "integrity": "sha512-4uQIBq1ffXd2YvF7MAvehWKW3zVv/w+mSfRAu+8cKbfj3nwzyqJLNcZJpQ/WZ1HLbJDiowwmQ6NO+63nCA+fqA==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.8", - "@typescript-eslint/type-utils": "5.59.8", - "@typescript-eslint/utils": "5.59.8", + "@typescript-eslint/scope-manager": "5.59.9", + "@typescript-eslint/type-utils": "5.59.9", + "@typescript-eslint/utils": "5.59.9", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", @@ -1823,6 +1823,53 @@ } } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "5.59.9", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.9.tgz", + "integrity": "sha512-8RA+E+w78z1+2dzvK/tGZ2cpGigBZ58VMEHDZtpE1v+LLjzrYGc8mMaTONSxKyEkz3IuXFM0IqYiGHlCsmlZxQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.9", + "@typescript-eslint/visitor-keys": "5.59.9" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "5.59.9", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.9.tgz", + "integrity": "sha512-uW8H5NRgTVneSVTfiCVffBb8AbwWSKg7qcA4Ot3JI3MPCJGsB4Db4BhvAODIIYE5mNj7Q+VJkK7JxmRhk2Lyjw==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.59.9", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.9.tgz", + "integrity": "sha512-bT7s0td97KMaLwpEBckbzj/YohnvXtqbe2XgqNvTl6RJVakY5mvENOTPvw5u66nljfZxthESpDozs86U+oLY8Q==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.9", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/parser": { "version": "5.59.8", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.8.tgz", @@ -1868,13 +1915,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.8.tgz", - "integrity": "sha512-+5M518uEIHFBy3FnyqZUF3BMP+AXnYn4oyH8RF012+e7/msMY98FhGL5SrN29NQ9xDgvqCgYnsOiKp1VjZ/fpA==", + "version": "5.59.9", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.9.tgz", + "integrity": "sha512-ksEsT0/mEHg9e3qZu98AlSrONAQtrSTljL3ow9CGej8eRo7pe+yaC/mvTjptp23Xo/xIf2mLZKC6KPv4Sji26Q==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.59.8", - "@typescript-eslint/utils": "5.59.8", + "@typescript-eslint/typescript-estree": "5.59.9", + "@typescript-eslint/utils": "5.59.9", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -1894,6 +1941,63 @@ } } }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "5.59.9", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.9.tgz", + "integrity": "sha512-uW8H5NRgTVneSVTfiCVffBb8AbwWSKg7qcA4Ot3JI3MPCJGsB4Db4BhvAODIIYE5mNj7Q+VJkK7JxmRhk2Lyjw==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.59.9", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.9.tgz", + "integrity": "sha512-pmM0/VQ7kUhd1QyIxgS+aRvMgw+ZljB3eDb+jYyp6d2bC0mQWLzUDF+DLwCTkQ3tlNyVsvZRXjFyV0LkU/aXjA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.9", + "@typescript-eslint/visitor-keys": "5.59.9", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.59.9", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.9.tgz", + "integrity": "sha512-bT7s0td97KMaLwpEBckbzj/YohnvXtqbe2XgqNvTl6RJVakY5mvENOTPvw5u66nljfZxthESpDozs86U+oLY8Q==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.9", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/types": { "version": "5.59.8", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.8.tgz", @@ -1935,17 +2039,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.8.tgz", - "integrity": "sha512-Tr65630KysnNn9f9G7ROF3w1b5/7f6QVCJ+WK9nhIocWmx9F+TmCAcglF26Vm7z8KCTwoKcNEBZrhlklla3CKg==", + "version": "5.59.9", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.9.tgz", + "integrity": "sha512-1PuMYsju/38I5Ggblaeb98TOoUvjhRvLpLa1DoTOFaLWqaXl/1iQ1eGurTXgBY58NUdtfTXKP5xBq7q9NDaLKg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.8", - "@typescript-eslint/types": "5.59.8", - "@typescript-eslint/typescript-estree": "5.59.8", + "@typescript-eslint/scope-manager": "5.59.9", + "@typescript-eslint/types": "5.59.9", + "@typescript-eslint/typescript-estree": "5.59.9", "eslint-scope": "^5.1.1", "semver": "^7.3.7" }, @@ -1960,6 +2064,80 @@ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { + "version": "5.59.9", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.9.tgz", + "integrity": "sha512-8RA+E+w78z1+2dzvK/tGZ2cpGigBZ58VMEHDZtpE1v+LLjzrYGc8mMaTONSxKyEkz3IuXFM0IqYiGHlCsmlZxQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.9", + "@typescript-eslint/visitor-keys": "5.59.9" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { + "version": "5.59.9", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.9.tgz", + "integrity": "sha512-uW8H5NRgTVneSVTfiCVffBb8AbwWSKg7qcA4Ot3JI3MPCJGsB4Db4BhvAODIIYE5mNj7Q+VJkK7JxmRhk2Lyjw==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.59.9", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.9.tgz", + "integrity": "sha512-pmM0/VQ7kUhd1QyIxgS+aRvMgw+ZljB3eDb+jYyp6d2bC0mQWLzUDF+DLwCTkQ3tlNyVsvZRXjFyV0LkU/aXjA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.9", + "@typescript-eslint/visitor-keys": "5.59.9", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.59.9", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.9.tgz", + "integrity": "sha512-bT7s0td97KMaLwpEBckbzj/YohnvXtqbe2XgqNvTl6RJVakY5mvENOTPvw5u66nljfZxthESpDozs86U+oLY8Q==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.9", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/visitor-keys": { "version": "5.59.8", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.8.tgz", @@ -8042,21 +8220,49 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.8.tgz", - "integrity": "sha512-JDMOmhXteJ4WVKOiHXGCoB96ADWg9q7efPWHRViT/f09bA8XOMLAVHHju3l0MkZnG1izaWXYmgvQcUjTRcpShQ==", + "version": "5.59.9", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.9.tgz", + "integrity": "sha512-4uQIBq1ffXd2YvF7MAvehWKW3zVv/w+mSfRAu+8cKbfj3nwzyqJLNcZJpQ/WZ1HLbJDiowwmQ6NO+63nCA+fqA==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.8", - "@typescript-eslint/type-utils": "5.59.8", - "@typescript-eslint/utils": "5.59.8", + "@typescript-eslint/scope-manager": "5.59.9", + "@typescript-eslint/type-utils": "5.59.9", + "@typescript-eslint/utils": "5.59.9", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", "semver": "^7.3.7", "tsutils": "^3.21.0" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "5.59.9", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.9.tgz", + "integrity": "sha512-8RA+E+w78z1+2dzvK/tGZ2cpGigBZ58VMEHDZtpE1v+LLjzrYGc8mMaTONSxKyEkz3IuXFM0IqYiGHlCsmlZxQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.9", + "@typescript-eslint/visitor-keys": "5.59.9" + } + }, + "@typescript-eslint/types": { + "version": "5.59.9", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.9.tgz", + "integrity": "sha512-uW8H5NRgTVneSVTfiCVffBb8AbwWSKg7qcA4Ot3JI3MPCJGsB4Db4BhvAODIIYE5mNj7Q+VJkK7JxmRhk2Lyjw==", + "dev": true + }, + "@typescript-eslint/visitor-keys": { + "version": "5.59.9", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.9.tgz", + "integrity": "sha512-bT7s0td97KMaLwpEBckbzj/YohnvXtqbe2XgqNvTl6RJVakY5mvENOTPvw5u66nljfZxthESpDozs86U+oLY8Q==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.9", + "eslint-visitor-keys": "^3.3.0" + } + } } }, "@typescript-eslint/parser": { @@ -8082,15 +8288,48 @@ } }, "@typescript-eslint/type-utils": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.8.tgz", - "integrity": "sha512-+5M518uEIHFBy3FnyqZUF3BMP+AXnYn4oyH8RF012+e7/msMY98FhGL5SrN29NQ9xDgvqCgYnsOiKp1VjZ/fpA==", + "version": "5.59.9", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.9.tgz", + "integrity": "sha512-ksEsT0/mEHg9e3qZu98AlSrONAQtrSTljL3ow9CGej8eRo7pe+yaC/mvTjptp23Xo/xIf2mLZKC6KPv4Sji26Q==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.59.8", - "@typescript-eslint/utils": "5.59.8", + "@typescript-eslint/typescript-estree": "5.59.9", + "@typescript-eslint/utils": "5.59.9", "debug": "^4.3.4", "tsutils": "^3.21.0" + }, + "dependencies": { + "@typescript-eslint/types": { + "version": "5.59.9", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.9.tgz", + "integrity": "sha512-uW8H5NRgTVneSVTfiCVffBb8AbwWSKg7qcA4Ot3JI3MPCJGsB4Db4BhvAODIIYE5mNj7Q+VJkK7JxmRhk2Lyjw==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.59.9", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.9.tgz", + "integrity": "sha512-pmM0/VQ7kUhd1QyIxgS+aRvMgw+ZljB3eDb+jYyp6d2bC0mQWLzUDF+DLwCTkQ3tlNyVsvZRXjFyV0LkU/aXjA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.9", + "@typescript-eslint/visitor-keys": "5.59.9", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.59.9", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.9.tgz", + "integrity": "sha512-bT7s0td97KMaLwpEBckbzj/YohnvXtqbe2XgqNvTl6RJVakY5mvENOTPvw5u66nljfZxthESpDozs86U+oLY8Q==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.9", + "eslint-visitor-keys": "^3.3.0" + } + } } }, "@typescript-eslint/types": { @@ -8115,19 +8354,62 @@ } }, "@typescript-eslint/utils": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.8.tgz", - "integrity": "sha512-Tr65630KysnNn9f9G7ROF3w1b5/7f6QVCJ+WK9nhIocWmx9F+TmCAcglF26Vm7z8KCTwoKcNEBZrhlklla3CKg==", + "version": "5.59.9", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.9.tgz", + "integrity": "sha512-1PuMYsju/38I5Ggblaeb98TOoUvjhRvLpLa1DoTOFaLWqaXl/1iQ1eGurTXgBY58NUdtfTXKP5xBq7q9NDaLKg==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.8", - "@typescript-eslint/types": "5.59.8", - "@typescript-eslint/typescript-estree": "5.59.8", + "@typescript-eslint/scope-manager": "5.59.9", + "@typescript-eslint/types": "5.59.9", + "@typescript-eslint/typescript-estree": "5.59.9", "eslint-scope": "^5.1.1", "semver": "^7.3.7" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "5.59.9", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.9.tgz", + "integrity": "sha512-8RA+E+w78z1+2dzvK/tGZ2cpGigBZ58VMEHDZtpE1v+LLjzrYGc8mMaTONSxKyEkz3IuXFM0IqYiGHlCsmlZxQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.9", + "@typescript-eslint/visitor-keys": "5.59.9" + } + }, + "@typescript-eslint/types": { + "version": "5.59.9", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.9.tgz", + "integrity": "sha512-uW8H5NRgTVneSVTfiCVffBb8AbwWSKg7qcA4Ot3JI3MPCJGsB4Db4BhvAODIIYE5mNj7Q+VJkK7JxmRhk2Lyjw==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.59.9", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.9.tgz", + "integrity": "sha512-pmM0/VQ7kUhd1QyIxgS+aRvMgw+ZljB3eDb+jYyp6d2bC0mQWLzUDF+DLwCTkQ3tlNyVsvZRXjFyV0LkU/aXjA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.9", + "@typescript-eslint/visitor-keys": "5.59.9", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.59.9", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.9.tgz", + "integrity": "sha512-bT7s0td97KMaLwpEBckbzj/YohnvXtqbe2XgqNvTl6RJVakY5mvENOTPvw5u66nljfZxthESpDozs86U+oLY8Q==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.9", + "eslint-visitor-keys": "^3.3.0" + } + } } }, "@typescript-eslint/visitor-keys": { From cc8efd5a43e95594c16fab90ad9949582725aed2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Jun 2023 19:11:42 +0200 Subject: [PATCH 0366/1076] build(deps-dev): bump @typescript-eslint/parser from 5.59.8 to 5.59.9 in /stake-pool/js (#4488) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 354 +++------------------------- 1 file changed, 36 insertions(+), 318 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 97b1d022..e177e673 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1823,62 +1823,15 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.9.tgz", - "integrity": "sha512-8RA+E+w78z1+2dzvK/tGZ2cpGigBZ58VMEHDZtpE1v+LLjzrYGc8mMaTONSxKyEkz3IuXFM0IqYiGHlCsmlZxQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.9", - "@typescript-eslint/visitor-keys": "5.59.9" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.9.tgz", - "integrity": "sha512-uW8H5NRgTVneSVTfiCVffBb8AbwWSKg7qcA4Ot3JI3MPCJGsB4Db4BhvAODIIYE5mNj7Q+VJkK7JxmRhk2Lyjw==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "node_modules/@typescript-eslint/parser": { "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.9.tgz", - "integrity": "sha512-bT7s0td97KMaLwpEBckbzj/YohnvXtqbe2XgqNvTl6RJVakY5mvENOTPvw5u66nljfZxthESpDozs86U+oLY8Q==", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.9.tgz", + "integrity": "sha512-FsPkRvBtcLQ/eVK1ivDiNYBjn3TGJdXy2fhXX+rc7czWl4ARwnpArwbihSOHI2Peg9WbtGHrbThfBUkZZGTtvQ==", "dev": true, "dependencies": { + "@typescript-eslint/scope-manager": "5.59.9", "@typescript-eslint/types": "5.59.9", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.8.tgz", - "integrity": "sha512-AnR19RjJcpjoeGojmwZtCwBX/RidqDZtzcbG3xHrmz0aHHoOcbWnpDllenRDmDvsV0RQ6+tbb09/kyc+UT9Orw==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "5.59.8", - "@typescript-eslint/types": "5.59.8", - "@typescript-eslint/typescript-estree": "5.59.8", + "@typescript-eslint/typescript-estree": "5.59.9", "debug": "^4.3.4" }, "engines": { @@ -1898,13 +1851,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.8.tgz", - "integrity": "sha512-/w08ndCYI8gxGf+9zKf1vtx/16y8MHrZs5/tnjHhMLNSixuNcJavSX4wAiPf4aS5x41Es9YPCn44MIe4cxIlig==", + "version": "5.59.9", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.9.tgz", + "integrity": "sha512-8RA+E+w78z1+2dzvK/tGZ2cpGigBZ58VMEHDZtpE1v+LLjzrYGc8mMaTONSxKyEkz3IuXFM0IqYiGHlCsmlZxQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.8", - "@typescript-eslint/visitor-keys": "5.59.8" + "@typescript-eslint/types": "5.59.9", + "@typescript-eslint/visitor-keys": "5.59.9" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1941,7 +1894,7 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "node_modules/@typescript-eslint/types": { "version": "5.59.9", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.9.tgz", "integrity": "sha512-uW8H5NRgTVneSVTfiCVffBb8AbwWSKg7qcA4Ot3JI3MPCJGsB4Db4BhvAODIIYE5mNj7Q+VJkK7JxmRhk2Lyjw==", @@ -1954,7 +1907,7 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "node_modules/@typescript-eslint/typescript-estree": { "version": "5.59.9", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.9.tgz", "integrity": "sha512-pmM0/VQ7kUhd1QyIxgS+aRvMgw+ZljB3eDb+jYyp6d2bC0mQWLzUDF+DLwCTkQ3tlNyVsvZRXjFyV0LkU/aXjA==", @@ -1981,63 +1934,6 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.9.tgz", - "integrity": "sha512-bT7s0td97KMaLwpEBckbzj/YohnvXtqbe2XgqNvTl6RJVakY5mvENOTPvw5u66nljfZxthESpDozs86U+oLY8Q==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.9", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.8.tgz", - "integrity": "sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.8.tgz", - "integrity": "sha512-Jy/lPSDJGNow14vYu6IrW790p7HIf/SOV1Bb6lZ7NUkLc2iB2Z9elESmsaUtLw8kVqogSbtLH9tut5GCX1RLDg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.8", - "@typescript-eslint/visitor-keys": "5.59.8", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, "node_modules/@typescript-eslint/utils": { "version": "5.59.9", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.9.tgz", @@ -2064,64 +1960,7 @@ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.9.tgz", - "integrity": "sha512-8RA+E+w78z1+2dzvK/tGZ2cpGigBZ58VMEHDZtpE1v+LLjzrYGc8mMaTONSxKyEkz3IuXFM0IqYiGHlCsmlZxQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.9", - "@typescript-eslint/visitor-keys": "5.59.9" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.9.tgz", - "integrity": "sha512-uW8H5NRgTVneSVTfiCVffBb8AbwWSKg7qcA4Ot3JI3MPCJGsB4Db4BhvAODIIYE5mNj7Q+VJkK7JxmRhk2Lyjw==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.9.tgz", - "integrity": "sha512-pmM0/VQ7kUhd1QyIxgS+aRvMgw+ZljB3eDb+jYyp6d2bC0mQWLzUDF+DLwCTkQ3tlNyVsvZRXjFyV0LkU/aXjA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.9", - "@typescript-eslint/visitor-keys": "5.59.9", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "node_modules/@typescript-eslint/visitor-keys": { "version": "5.59.9", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.9.tgz", "integrity": "sha512-bT7s0td97KMaLwpEBckbzj/YohnvXtqbe2XgqNvTl6RJVakY5mvENOTPvw5u66nljfZxthESpDozs86U+oLY8Q==", @@ -2138,23 +1977,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.8.tgz", - "integrity": "sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.8", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/abab": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", @@ -8235,56 +8057,28 @@ "natural-compare-lite": "^1.4.0", "semver": "^7.3.7", "tsutils": "^3.21.0" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.9.tgz", - "integrity": "sha512-8RA+E+w78z1+2dzvK/tGZ2cpGigBZ58VMEHDZtpE1v+LLjzrYGc8mMaTONSxKyEkz3IuXFM0IqYiGHlCsmlZxQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.9", - "@typescript-eslint/visitor-keys": "5.59.9" - } - }, - "@typescript-eslint/types": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.9.tgz", - "integrity": "sha512-uW8H5NRgTVneSVTfiCVffBb8AbwWSKg7qcA4Ot3JI3MPCJGsB4Db4BhvAODIIYE5mNj7Q+VJkK7JxmRhk2Lyjw==", - "dev": true - }, - "@typescript-eslint/visitor-keys": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.9.tgz", - "integrity": "sha512-bT7s0td97KMaLwpEBckbzj/YohnvXtqbe2XgqNvTl6RJVakY5mvENOTPvw5u66nljfZxthESpDozs86U+oLY8Q==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.9", - "eslint-visitor-keys": "^3.3.0" - } - } } }, "@typescript-eslint/parser": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.8.tgz", - "integrity": "sha512-AnR19RjJcpjoeGojmwZtCwBX/RidqDZtzcbG3xHrmz0aHHoOcbWnpDllenRDmDvsV0RQ6+tbb09/kyc+UT9Orw==", + "version": "5.59.9", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.9.tgz", + "integrity": "sha512-FsPkRvBtcLQ/eVK1ivDiNYBjn3TGJdXy2fhXX+rc7czWl4ARwnpArwbihSOHI2Peg9WbtGHrbThfBUkZZGTtvQ==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.59.8", - "@typescript-eslint/types": "5.59.8", - "@typescript-eslint/typescript-estree": "5.59.8", + "@typescript-eslint/scope-manager": "5.59.9", + "@typescript-eslint/types": "5.59.9", + "@typescript-eslint/typescript-estree": "5.59.9", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.8.tgz", - "integrity": "sha512-/w08ndCYI8gxGf+9zKf1vtx/16y8MHrZs5/tnjHhMLNSixuNcJavSX4wAiPf4aS5x41Es9YPCn44MIe4cxIlig==", + "version": "5.59.9", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.9.tgz", + "integrity": "sha512-8RA+E+w78z1+2dzvK/tGZ2cpGigBZ58VMEHDZtpE1v+LLjzrYGc8mMaTONSxKyEkz3IuXFM0IqYiGHlCsmlZxQ==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.8", - "@typescript-eslint/visitor-keys": "5.59.8" + "@typescript-eslint/types": "5.59.9", + "@typescript-eslint/visitor-keys": "5.59.9" } }, "@typescript-eslint/type-utils": { @@ -8297,55 +8091,22 @@ "@typescript-eslint/utils": "5.59.9", "debug": "^4.3.4", "tsutils": "^3.21.0" - }, - "dependencies": { - "@typescript-eslint/types": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.9.tgz", - "integrity": "sha512-uW8H5NRgTVneSVTfiCVffBb8AbwWSKg7qcA4Ot3JI3MPCJGsB4Db4BhvAODIIYE5mNj7Q+VJkK7JxmRhk2Lyjw==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.9.tgz", - "integrity": "sha512-pmM0/VQ7kUhd1QyIxgS+aRvMgw+ZljB3eDb+jYyp6d2bC0mQWLzUDF+DLwCTkQ3tlNyVsvZRXjFyV0LkU/aXjA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.9", - "@typescript-eslint/visitor-keys": "5.59.9", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.9.tgz", - "integrity": "sha512-bT7s0td97KMaLwpEBckbzj/YohnvXtqbe2XgqNvTl6RJVakY5mvENOTPvw5u66nljfZxthESpDozs86U+oLY8Q==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.9", - "eslint-visitor-keys": "^3.3.0" - } - } } }, "@typescript-eslint/types": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.8.tgz", - "integrity": "sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w==", + "version": "5.59.9", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.9.tgz", + "integrity": "sha512-uW8H5NRgTVneSVTfiCVffBb8AbwWSKg7qcA4Ot3JI3MPCJGsB4Db4BhvAODIIYE5mNj7Q+VJkK7JxmRhk2Lyjw==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.8.tgz", - "integrity": "sha512-Jy/lPSDJGNow14vYu6IrW790p7HIf/SOV1Bb6lZ7NUkLc2iB2Z9elESmsaUtLw8kVqogSbtLH9tut5GCX1RLDg==", + "version": "5.59.9", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.9.tgz", + "integrity": "sha512-pmM0/VQ7kUhd1QyIxgS+aRvMgw+ZljB3eDb+jYyp6d2bC0mQWLzUDF+DLwCTkQ3tlNyVsvZRXjFyV0LkU/aXjA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.8", - "@typescript-eslint/visitor-keys": "5.59.8", + "@typescript-eslint/types": "5.59.9", + "@typescript-eslint/visitor-keys": "5.59.9", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -8367,58 +8128,15 @@ "@typescript-eslint/typescript-estree": "5.59.9", "eslint-scope": "^5.1.1", "semver": "^7.3.7" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.9.tgz", - "integrity": "sha512-8RA+E+w78z1+2dzvK/tGZ2cpGigBZ58VMEHDZtpE1v+LLjzrYGc8mMaTONSxKyEkz3IuXFM0IqYiGHlCsmlZxQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.9", - "@typescript-eslint/visitor-keys": "5.59.9" - } - }, - "@typescript-eslint/types": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.9.tgz", - "integrity": "sha512-uW8H5NRgTVneSVTfiCVffBb8AbwWSKg7qcA4Ot3JI3MPCJGsB4Db4BhvAODIIYE5mNj7Q+VJkK7JxmRhk2Lyjw==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.9.tgz", - "integrity": "sha512-pmM0/VQ7kUhd1QyIxgS+aRvMgw+ZljB3eDb+jYyp6d2bC0mQWLzUDF+DLwCTkQ3tlNyVsvZRXjFyV0LkU/aXjA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.9", - "@typescript-eslint/visitor-keys": "5.59.9", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.9.tgz", - "integrity": "sha512-bT7s0td97KMaLwpEBckbzj/YohnvXtqbe2XgqNvTl6RJVakY5mvENOTPvw5u66nljfZxthESpDozs86U+oLY8Q==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.9", - "eslint-visitor-keys": "^3.3.0" - } - } } }, "@typescript-eslint/visitor-keys": { - "version": "5.59.8", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.8.tgz", - "integrity": "sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ==", + "version": "5.59.9", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.9.tgz", + "integrity": "sha512-bT7s0td97KMaLwpEBckbzj/YohnvXtqbe2XgqNvTl6RJVakY5mvENOTPvw5u66nljfZxthESpDozs86U+oLY8Q==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.8", + "@typescript-eslint/types": "5.59.9", "eslint-visitor-keys": "^3.3.0" } }, From 400ef7e54c6e699857ffe0e070f9eb52b677ac73 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 9 Jun 2023 13:03:04 +0200 Subject: [PATCH 0367/1076] build(deps): bump serde from 1.0.163 to 1.0.164 (#4509) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 50b0cff7..a6ed2213 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "0.7.0" [dependencies] borsh = "0.9" clap = "2.33.3" -serde = "1.0.163" +serde = "1.0.164" serde_derive = "1.0.130" serde_json = "1.0.96" solana-account-decoder = "=1.14.12" diff --git a/program/Cargo.toml b/program/Cargo.toml index f8416574..77d81ac5 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,7 +18,7 @@ mpl-token-metadata = { version = "1.7.0", features = [ "no-entrypoint" ] } num-derive = "0.3" num-traits = "0.2" num_enum = "0.6.1" -serde = "1.0.163" +serde = "1.0.164" serde_derive = "1.0.103" solana-program = "1.14.12" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } From d7f5c8c55353fba7eeac2907bb4a4cdfe2d427c8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Jun 2023 19:32:32 +0200 Subject: [PATCH 0368/1076] build(deps-dev): bump @types/node from 20.2.5 to 20.3.0 in /stake-pool/js (#4519) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index e177e673..69e768ee 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1728,9 +1728,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.2.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.5.tgz", - "integrity": "sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==" + "version": "20.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.0.tgz", + "integrity": "sha512-cumHmIAf6On83X7yP+LrsEyUOf/YlociZelmpRYaGFydoaPdxdt80MAbu6vWerQT2COCp2nPvHdsbD7tHn/YlQ==" }, "node_modules/@types/node-fetch": { "version": "2.6.4", @@ -7980,9 +7980,9 @@ "dev": true }, "@types/node": { - "version": "20.2.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.5.tgz", - "integrity": "sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==" + "version": "20.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.0.tgz", + "integrity": "sha512-cumHmIAf6On83X7yP+LrsEyUOf/YlociZelmpRYaGFydoaPdxdt80MAbu6vWerQT2COCp2nPvHdsbD7tHn/YlQ==" }, "@types/node-fetch": { "version": "2.6.4", From 63be7f65995c6a0c2e843cb657fba4842c1defd5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Jun 2023 19:32:41 +0200 Subject: [PATCH 0369/1076] build(deps-dev): bump @rollup/plugin-commonjs from 25.0.0 to 25.0.1 in /stake-pool/js (#4521) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 69e768ee..8cad6d7e 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1317,9 +1317,9 @@ } }, "node_modules/@rollup/plugin-commonjs": { - "version": "25.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.0.tgz", - "integrity": "sha512-hoho2Kay9TZrLu0bnDsTTCaj4Npa+THk9snajP/XDNb9a9mmjTjh52EQM9sKl3HD1LsnihX7js+eA2sd2uKAhw==", + "version": "25.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.1.tgz", + "integrity": "sha512-2DJ4kv4b1xfTJopWhu61ANdNRHvzQZ2fpaIrlgaP2jOfUv1wDJ0Ucqy8AZlbFmn/iUjiwKoqki9j55Y6L8kyNQ==", "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1", @@ -7675,9 +7675,9 @@ } }, "@rollup/plugin-commonjs": { - "version": "25.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.0.tgz", - "integrity": "sha512-hoho2Kay9TZrLu0bnDsTTCaj4Npa+THk9snajP/XDNb9a9mmjTjh52EQM9sKl3HD1LsnihX7js+eA2sd2uKAhw==", + "version": "25.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.1.tgz", + "integrity": "sha512-2DJ4kv4b1xfTJopWhu61ANdNRHvzQZ2fpaIrlgaP2jOfUv1wDJ0Ucqy8AZlbFmn/iUjiwKoqki9j55Y6L8kyNQ==", "dev": true, "requires": { "@rollup/pluginutils": "^5.0.1", From 46f6dd6d03156a5ba809dc5d33eae7f847e598b0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Jun 2023 19:34:22 +0200 Subject: [PATCH 0370/1076] build(deps): bump @coral-xyz/borsh from 0.27.0 to 0.28.0 in /stake-pool/js (#4520) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 14 +++++++------- clients/js-legacy/package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 8cad6d7e..be8a32da 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -9,7 +9,7 @@ "version": "0.6.5", "license": "ISC", "dependencies": { - "@coral-xyz/borsh": "^0.27.0", + "@coral-xyz/borsh": "^0.28.0", "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "^0.3.7", "@solana/web3.js": "^1.76.0", @@ -646,9 +646,9 @@ "dev": true }, "node_modules/@coral-xyz/borsh": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.27.0.tgz", - "integrity": "sha512-tJKzhLukghTWPLy+n8K8iJKgBq1yLT/AxaNd10yJrX8mI56ao5+OFAKAqW/h0i79KCvb4BK0VGO5ECmmolFz9A==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.28.0.tgz", + "integrity": "sha512-/u1VTzw7XooK7rqeD7JLUSwOyRSesPUk0U37BV9zK0axJc1q0nRbKFGFLYCQ16OtdOJTTwGfGp11Lx9B45bRCQ==", "dependencies": { "bn.js": "^5.1.2", "buffer-layout": "^1.2.0" @@ -7180,9 +7180,9 @@ "dev": true }, "@coral-xyz/borsh": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.27.0.tgz", - "integrity": "sha512-tJKzhLukghTWPLy+n8K8iJKgBq1yLT/AxaNd10yJrX8mI56ao5+OFAKAqW/h0i79KCvb4BK0VGO5ECmmolFz9A==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.28.0.tgz", + "integrity": "sha512-/u1VTzw7XooK7rqeD7JLUSwOyRSesPUk0U37BV9zK0axJc1q0nRbKFGFLYCQ16OtdOJTTwGfGp11Lx9B45bRCQ==", "requires": { "bn.js": "^5.1.2", "buffer-layout": "^1.2.0" diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 89981e48..85546a95 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -44,7 +44,7 @@ ], "license": "ISC", "dependencies": { - "@coral-xyz/borsh": "^0.27.0", + "@coral-xyz/borsh": "^0.28.0", "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "^0.3.7", "@solana/web3.js": "^1.76.0", From b0213f92a4ef35098f58e3283d8a0eda30595fe3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Jun 2023 17:06:01 +0200 Subject: [PATCH 0371/1076] build(deps-dev): bump @typescript-eslint/parser from 5.59.9 to 5.59.11 in /stake-pool/js (#4533) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 141 +++++++++++++++++++++++++--- 1 file changed, 129 insertions(+), 12 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index be8a32da..827115b6 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1824,14 +1824,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.9.tgz", - "integrity": "sha512-FsPkRvBtcLQ/eVK1ivDiNYBjn3TGJdXy2fhXX+rc7czWl4ARwnpArwbihSOHI2Peg9WbtGHrbThfBUkZZGTtvQ==", + "version": "5.59.11", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.11.tgz", + "integrity": "sha512-s9ZF3M+Nym6CAZEkJJeO2TFHHDsKAM3ecNkLuH4i4s8/RCPnF5JRip2GyviYkeEAcwGMJxkqG9h2dAsnA1nZpA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.59.9", - "@typescript-eslint/types": "5.59.9", - "@typescript-eslint/typescript-estree": "5.59.9", + "@typescript-eslint/scope-manager": "5.59.11", + "@typescript-eslint/types": "5.59.11", + "@typescript-eslint/typescript-estree": "5.59.11", "debug": "^4.3.4" }, "engines": { @@ -1850,6 +1850,80 @@ } } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "5.59.11", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.11.tgz", + "integrity": "sha512-dHFOsxoLFtrIcSj5h0QoBT/89hxQONwmn3FOQ0GOQcLOOXm+MIrS8zEAhs4tWl5MraxCY3ZJpaXQQdFMc2Tu+Q==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.11", + "@typescript-eslint/visitor-keys": "5.59.11" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "5.59.11", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.11.tgz", + "integrity": "sha512-epoN6R6tkvBYSc+cllrz+c2sOFWkbisJZWkOE+y3xHtvYaOE6Wk6B8e114McRJwFRjGvYdJwLXQH5c9osME/AA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.59.11", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.11.tgz", + "integrity": "sha512-YupOpot5hJO0maupJXixi6l5ETdrITxeo5eBOeuV7RSKgYdU3G5cxO49/9WRnJq9EMrB7AuTSLH/bqOsXi7wPA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.11", + "@typescript-eslint/visitor-keys": "5.59.11", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.59.11", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.11.tgz", + "integrity": "sha512-KGYniTGG3AMTuKF9QBD7EIrvufkB6O6uX3knP73xbKLMpH+QRPcgnCxjWXSHjMRuOxFLovljqQgQpR0c7GvjoA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.11", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "5.59.9", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.9.tgz", @@ -8060,15 +8134,58 @@ } }, "@typescript-eslint/parser": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.9.tgz", - "integrity": "sha512-FsPkRvBtcLQ/eVK1ivDiNYBjn3TGJdXy2fhXX+rc7czWl4ARwnpArwbihSOHI2Peg9WbtGHrbThfBUkZZGTtvQ==", + "version": "5.59.11", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.11.tgz", + "integrity": "sha512-s9ZF3M+Nym6CAZEkJJeO2TFHHDsKAM3ecNkLuH4i4s8/RCPnF5JRip2GyviYkeEAcwGMJxkqG9h2dAsnA1nZpA==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.59.9", - "@typescript-eslint/types": "5.59.9", - "@typescript-eslint/typescript-estree": "5.59.9", + "@typescript-eslint/scope-manager": "5.59.11", + "@typescript-eslint/types": "5.59.11", + "@typescript-eslint/typescript-estree": "5.59.11", "debug": "^4.3.4" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "5.59.11", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.11.tgz", + "integrity": "sha512-dHFOsxoLFtrIcSj5h0QoBT/89hxQONwmn3FOQ0GOQcLOOXm+MIrS8zEAhs4tWl5MraxCY3ZJpaXQQdFMc2Tu+Q==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.11", + "@typescript-eslint/visitor-keys": "5.59.11" + } + }, + "@typescript-eslint/types": { + "version": "5.59.11", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.11.tgz", + "integrity": "sha512-epoN6R6tkvBYSc+cllrz+c2sOFWkbisJZWkOE+y3xHtvYaOE6Wk6B8e114McRJwFRjGvYdJwLXQH5c9osME/AA==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.59.11", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.11.tgz", + "integrity": "sha512-YupOpot5hJO0maupJXixi6l5ETdrITxeo5eBOeuV7RSKgYdU3G5cxO49/9WRnJq9EMrB7AuTSLH/bqOsXi7wPA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.11", + "@typescript-eslint/visitor-keys": "5.59.11", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.59.11", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.11.tgz", + "integrity": "sha512-KGYniTGG3AMTuKF9QBD7EIrvufkB6O6uX3knP73xbKLMpH+QRPcgnCxjWXSHjMRuOxFLovljqQgQpR0c7GvjoA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.11", + "eslint-visitor-keys": "^3.3.0" + } + } } }, "@typescript-eslint/scope-manager": { From 1e0cadd25cec4e01f92043fd4f166a326a6735ff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Jun 2023 18:02:44 +0200 Subject: [PATCH 0372/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 5.59.9 to 5.59.11 in /stake-pool/js (#4535) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 245 ++++++++-------------------- 1 file changed, 64 insertions(+), 181 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 827115b6..69768a6a 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1790,15 +1790,15 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.9.tgz", - "integrity": "sha512-4uQIBq1ffXd2YvF7MAvehWKW3zVv/w+mSfRAu+8cKbfj3nwzyqJLNcZJpQ/WZ1HLbJDiowwmQ6NO+63nCA+fqA==", + "version": "5.59.11", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.11.tgz", + "integrity": "sha512-XxuOfTkCUiOSyBWIvHlUraLw/JT/6Io1365RO6ZuI88STKMavJZPNMU0lFcUTeQXEhHiv64CbxYxBNoDVSmghg==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.9", - "@typescript-eslint/type-utils": "5.59.9", - "@typescript-eslint/utils": "5.59.9", + "@typescript-eslint/scope-manager": "5.59.11", + "@typescript-eslint/type-utils": "5.59.11", + "@typescript-eslint/utils": "5.59.11", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", @@ -1850,7 +1850,7 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "node_modules/@typescript-eslint/scope-manager": { "version": "5.59.11", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.11.tgz", "integrity": "sha512-dHFOsxoLFtrIcSj5h0QoBT/89hxQONwmn3FOQ0GOQcLOOXm+MIrS8zEAhs4tWl5MraxCY3ZJpaXQQdFMc2Tu+Q==", @@ -1867,88 +1867,14 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.11.tgz", - "integrity": "sha512-epoN6R6tkvBYSc+cllrz+c2sOFWkbisJZWkOE+y3xHtvYaOE6Wk6B8e114McRJwFRjGvYdJwLXQH5c9osME/AA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.11.tgz", - "integrity": "sha512-YupOpot5hJO0maupJXixi6l5ETdrITxeo5eBOeuV7RSKgYdU3G5cxO49/9WRnJq9EMrB7AuTSLH/bqOsXi7wPA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.11", - "@typescript-eslint/visitor-keys": "5.59.11", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.11.tgz", - "integrity": "sha512-KGYniTGG3AMTuKF9QBD7EIrvufkB6O6uX3knP73xbKLMpH+QRPcgnCxjWXSHjMRuOxFLovljqQgQpR0c7GvjoA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.11", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.9.tgz", - "integrity": "sha512-8RA+E+w78z1+2dzvK/tGZ2cpGigBZ58VMEHDZtpE1v+LLjzrYGc8mMaTONSxKyEkz3IuXFM0IqYiGHlCsmlZxQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.9", - "@typescript-eslint/visitor-keys": "5.59.9" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.9.tgz", - "integrity": "sha512-ksEsT0/mEHg9e3qZu98AlSrONAQtrSTljL3ow9CGej8eRo7pe+yaC/mvTjptp23Xo/xIf2mLZKC6KPv4Sji26Q==", + "version": "5.59.11", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.11.tgz", + "integrity": "sha512-LZqVY8hMiVRF2a7/swmkStMYSoXMFlzL6sXV6U/2gL5cwnLWQgLEG8tjWPpaE4rMIdZ6VKWwcffPlo1jPfk43g==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.59.9", - "@typescript-eslint/utils": "5.59.9", + "@typescript-eslint/typescript-estree": "5.59.11", + "@typescript-eslint/utils": "5.59.11", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -1969,9 +1895,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.9.tgz", - "integrity": "sha512-uW8H5NRgTVneSVTfiCVffBb8AbwWSKg7qcA4Ot3JI3MPCJGsB4Db4BhvAODIIYE5mNj7Q+VJkK7JxmRhk2Lyjw==", + "version": "5.59.11", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.11.tgz", + "integrity": "sha512-epoN6R6tkvBYSc+cllrz+c2sOFWkbisJZWkOE+y3xHtvYaOE6Wk6B8e114McRJwFRjGvYdJwLXQH5c9osME/AA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1982,13 +1908,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.9.tgz", - "integrity": "sha512-pmM0/VQ7kUhd1QyIxgS+aRvMgw+ZljB3eDb+jYyp6d2bC0mQWLzUDF+DLwCTkQ3tlNyVsvZRXjFyV0LkU/aXjA==", + "version": "5.59.11", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.11.tgz", + "integrity": "sha512-YupOpot5hJO0maupJXixi6l5ETdrITxeo5eBOeuV7RSKgYdU3G5cxO49/9WRnJq9EMrB7AuTSLH/bqOsXi7wPA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.9", - "@typescript-eslint/visitor-keys": "5.59.9", + "@typescript-eslint/types": "5.59.11", + "@typescript-eslint/visitor-keys": "5.59.11", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2009,17 +1935,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.9.tgz", - "integrity": "sha512-1PuMYsju/38I5Ggblaeb98TOoUvjhRvLpLa1DoTOFaLWqaXl/1iQ1eGurTXgBY58NUdtfTXKP5xBq7q9NDaLKg==", + "version": "5.59.11", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.11.tgz", + "integrity": "sha512-didu2rHSOMUdJThLk4aZ1Or8IcO3HzCw/ZvEjTTIfjIrcdd5cvSIwwDy2AOlE7htSNp7QIZ10fLMyRCveesMLg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.9", - "@typescript-eslint/types": "5.59.9", - "@typescript-eslint/typescript-estree": "5.59.9", + "@typescript-eslint/scope-manager": "5.59.11", + "@typescript-eslint/types": "5.59.11", + "@typescript-eslint/typescript-estree": "5.59.11", "eslint-scope": "^5.1.1", "semver": "^7.3.7" }, @@ -2035,12 +1961,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.9.tgz", - "integrity": "sha512-bT7s0td97KMaLwpEBckbzj/YohnvXtqbe2XgqNvTl6RJVakY5mvENOTPvw5u66nljfZxthESpDozs86U+oLY8Q==", + "version": "5.59.11", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.11.tgz", + "integrity": "sha512-KGYniTGG3AMTuKF9QBD7EIrvufkB6O6uX3knP73xbKLMpH+QRPcgnCxjWXSHjMRuOxFLovljqQgQpR0c7GvjoA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.9", + "@typescript-eslint/types": "5.59.11", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -8116,15 +8042,15 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.9.tgz", - "integrity": "sha512-4uQIBq1ffXd2YvF7MAvehWKW3zVv/w+mSfRAu+8cKbfj3nwzyqJLNcZJpQ/WZ1HLbJDiowwmQ6NO+63nCA+fqA==", + "version": "5.59.11", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.11.tgz", + "integrity": "sha512-XxuOfTkCUiOSyBWIvHlUraLw/JT/6Io1365RO6ZuI88STKMavJZPNMU0lFcUTeQXEhHiv64CbxYxBNoDVSmghg==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.9", - "@typescript-eslint/type-utils": "5.59.9", - "@typescript-eslint/utils": "5.59.9", + "@typescript-eslint/scope-manager": "5.59.11", + "@typescript-eslint/type-utils": "5.59.11", + "@typescript-eslint/utils": "5.59.11", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", @@ -8143,87 +8069,44 @@ "@typescript-eslint/types": "5.59.11", "@typescript-eslint/typescript-estree": "5.59.11", "debug": "^4.3.4" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.11.tgz", - "integrity": "sha512-dHFOsxoLFtrIcSj5h0QoBT/89hxQONwmn3FOQ0GOQcLOOXm+MIrS8zEAhs4tWl5MraxCY3ZJpaXQQdFMc2Tu+Q==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.11", - "@typescript-eslint/visitor-keys": "5.59.11" - } - }, - "@typescript-eslint/types": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.11.tgz", - "integrity": "sha512-epoN6R6tkvBYSc+cllrz+c2sOFWkbisJZWkOE+y3xHtvYaOE6Wk6B8e114McRJwFRjGvYdJwLXQH5c9osME/AA==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.11.tgz", - "integrity": "sha512-YupOpot5hJO0maupJXixi6l5ETdrITxeo5eBOeuV7RSKgYdU3G5cxO49/9WRnJq9EMrB7AuTSLH/bqOsXi7wPA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.11", - "@typescript-eslint/visitor-keys": "5.59.11", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.11.tgz", - "integrity": "sha512-KGYniTGG3AMTuKF9QBD7EIrvufkB6O6uX3knP73xbKLMpH+QRPcgnCxjWXSHjMRuOxFLovljqQgQpR0c7GvjoA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.59.11", - "eslint-visitor-keys": "^3.3.0" - } - } } }, "@typescript-eslint/scope-manager": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.9.tgz", - "integrity": "sha512-8RA+E+w78z1+2dzvK/tGZ2cpGigBZ58VMEHDZtpE1v+LLjzrYGc8mMaTONSxKyEkz3IuXFM0IqYiGHlCsmlZxQ==", + "version": "5.59.11", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.11.tgz", + "integrity": "sha512-dHFOsxoLFtrIcSj5h0QoBT/89hxQONwmn3FOQ0GOQcLOOXm+MIrS8zEAhs4tWl5MraxCY3ZJpaXQQdFMc2Tu+Q==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.9", - "@typescript-eslint/visitor-keys": "5.59.9" + "@typescript-eslint/types": "5.59.11", + "@typescript-eslint/visitor-keys": "5.59.11" } }, "@typescript-eslint/type-utils": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.9.tgz", - "integrity": "sha512-ksEsT0/mEHg9e3qZu98AlSrONAQtrSTljL3ow9CGej8eRo7pe+yaC/mvTjptp23Xo/xIf2mLZKC6KPv4Sji26Q==", + "version": "5.59.11", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.11.tgz", + "integrity": "sha512-LZqVY8hMiVRF2a7/swmkStMYSoXMFlzL6sXV6U/2gL5cwnLWQgLEG8tjWPpaE4rMIdZ6VKWwcffPlo1jPfk43g==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.59.9", - "@typescript-eslint/utils": "5.59.9", + "@typescript-eslint/typescript-estree": "5.59.11", + "@typescript-eslint/utils": "5.59.11", "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.9.tgz", - "integrity": "sha512-uW8H5NRgTVneSVTfiCVffBb8AbwWSKg7qcA4Ot3JI3MPCJGsB4Db4BhvAODIIYE5mNj7Q+VJkK7JxmRhk2Lyjw==", + "version": "5.59.11", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.11.tgz", + "integrity": "sha512-epoN6R6tkvBYSc+cllrz+c2sOFWkbisJZWkOE+y3xHtvYaOE6Wk6B8e114McRJwFRjGvYdJwLXQH5c9osME/AA==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.9.tgz", - "integrity": "sha512-pmM0/VQ7kUhd1QyIxgS+aRvMgw+ZljB3eDb+jYyp6d2bC0mQWLzUDF+DLwCTkQ3tlNyVsvZRXjFyV0LkU/aXjA==", + "version": "5.59.11", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.11.tgz", + "integrity": "sha512-YupOpot5hJO0maupJXixi6l5ETdrITxeo5eBOeuV7RSKgYdU3G5cxO49/9WRnJq9EMrB7AuTSLH/bqOsXi7wPA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.9", - "@typescript-eslint/visitor-keys": "5.59.9", + "@typescript-eslint/types": "5.59.11", + "@typescript-eslint/visitor-keys": "5.59.11", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -8232,28 +8115,28 @@ } }, "@typescript-eslint/utils": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.9.tgz", - "integrity": "sha512-1PuMYsju/38I5Ggblaeb98TOoUvjhRvLpLa1DoTOFaLWqaXl/1iQ1eGurTXgBY58NUdtfTXKP5xBq7q9NDaLKg==", + "version": "5.59.11", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.11.tgz", + "integrity": "sha512-didu2rHSOMUdJThLk4aZ1Or8IcO3HzCw/ZvEjTTIfjIrcdd5cvSIwwDy2AOlE7htSNp7QIZ10fLMyRCveesMLg==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.9", - "@typescript-eslint/types": "5.59.9", - "@typescript-eslint/typescript-estree": "5.59.9", + "@typescript-eslint/scope-manager": "5.59.11", + "@typescript-eslint/types": "5.59.11", + "@typescript-eslint/typescript-estree": "5.59.11", "eslint-scope": "^5.1.1", "semver": "^7.3.7" } }, "@typescript-eslint/visitor-keys": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.9.tgz", - "integrity": "sha512-bT7s0td97KMaLwpEBckbzj/YohnvXtqbe2XgqNvTl6RJVakY5mvENOTPvw5u66nljfZxthESpDozs86U+oLY8Q==", + "version": "5.59.11", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.11.tgz", + "integrity": "sha512-KGYniTGG3AMTuKF9QBD7EIrvufkB6O6uX3knP73xbKLMpH+QRPcgnCxjWXSHjMRuOxFLovljqQgQpR0c7GvjoA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.9", + "@typescript-eslint/types": "5.59.11", "eslint-visitor-keys": "^3.3.0" } }, From 530a3a0ddd7f0cd38da57558d4441c257327cd24 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Jun 2023 18:03:10 +0200 Subject: [PATCH 0373/1076] build(deps-dev): bump @types/node from 20.3.0 to 20.3.1 in /stake-pool/js (#4534) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 69768a6a..7fb93b79 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1728,9 +1728,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.3.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.0.tgz", - "integrity": "sha512-cumHmIAf6On83X7yP+LrsEyUOf/YlociZelmpRYaGFydoaPdxdt80MAbu6vWerQT2COCp2nPvHdsbD7tHn/YlQ==" + "version": "20.3.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.1.tgz", + "integrity": "sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==" }, "node_modules/@types/node-fetch": { "version": "2.6.4", @@ -7980,9 +7980,9 @@ "dev": true }, "@types/node": { - "version": "20.3.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.0.tgz", - "integrity": "sha512-cumHmIAf6On83X7yP+LrsEyUOf/YlociZelmpRYaGFydoaPdxdt80MAbu6vWerQT2COCp2nPvHdsbD7tHn/YlQ==" + "version": "20.3.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.1.tgz", + "integrity": "sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==" }, "@types/node-fetch": { "version": "2.6.4", From ab7b701092f7e6d39dde7f5ee4dcec5f9eda628d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Jun 2023 13:37:06 +0200 Subject: [PATCH 0374/1076] build(deps): bump serde_json from 1.0.96 to 1.0.97 (#4553) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.96 to 1.0.97. Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index a6ed2213..fc0bc696 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ borsh = "0.9" clap = "2.33.3" serde = "1.0.164" serde_derive = "1.0.130" -serde_json = "1.0.96" +serde_json = "1.0.97" solana-account-decoder = "=1.14.12" solana-clap-utils = "=1.14.12" solana-cli-config = "=1.14.12" From 394754cc09f617913d810fb176232706ac1214c9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Jun 2023 15:36:54 +0200 Subject: [PATCH 0375/1076] build(deps-dev): bump eslint from 8.42.0 to 8.43.0 in /stake-pool/js (#4565) Bumps [eslint](https://github.com/eslint/eslint) from 8.42.0 to 8.43.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.42.0...v8.43.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 7fb93b79..3197f784 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -708,9 +708,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.42.0.tgz", - "integrity": "sha512-6SWlXpWU5AvId8Ac7zjzmIOqMOba/JWY8XZ4A7q7Gn1Vlfg/SFFIlrtHXt9nPn4op9ZPAkl91Jao+QQv3r/ukw==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.43.0.tgz", + "integrity": "sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2985,15 +2985,15 @@ } }, "node_modules/eslint": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.42.0.tgz", - "integrity": "sha512-ulg9Ms6E1WPf67PHaEY4/6E2tEn5/f7FXGzr3t9cBMugOmf1INYvuUwwh1aXQN4MfJ6a5K2iNwP3w4AColvI9A==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.43.0.tgz", + "integrity": "sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.4.0", "@eslint/eslintrc": "^2.0.3", - "@eslint/js": "8.42.0", + "@eslint/js": "8.43.0", "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -7221,9 +7221,9 @@ } }, "@eslint/js": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.42.0.tgz", - "integrity": "sha512-6SWlXpWU5AvId8Ac7zjzmIOqMOba/JWY8XZ4A7q7Gn1Vlfg/SFFIlrtHXt9nPn4op9ZPAkl91Jao+QQv3r/ukw==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.43.0.tgz", + "integrity": "sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg==", "dev": true }, "@humanwhocodes/config-array": { @@ -8894,15 +8894,15 @@ } }, "eslint": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.42.0.tgz", - "integrity": "sha512-ulg9Ms6E1WPf67PHaEY4/6E2tEn5/f7FXGzr3t9cBMugOmf1INYvuUwwh1aXQN4MfJ6a5K2iNwP3w4AColvI9A==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.43.0.tgz", + "integrity": "sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.4.0", "@eslint/eslintrc": "^2.0.3", - "@eslint/js": "8.42.0", + "@eslint/js": "8.43.0", "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", From 3246b6f9d73fe3a98d17e96469007b49990705a7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Jun 2023 15:52:39 +0200 Subject: [PATCH 0376/1076] build(deps-dev): bump @typescript-eslint/parser from 5.59.11 to 5.60.0 in /stake-pool/js (#4575) build(deps-dev): bump @typescript-eslint/parser in /stake-pool/js Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.59.11 to 5.60.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.60.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 141 +++++++++++++++++++++++++--- 1 file changed, 129 insertions(+), 12 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 3197f784..a9b9eadd 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1824,14 +1824,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.11.tgz", - "integrity": "sha512-s9ZF3M+Nym6CAZEkJJeO2TFHHDsKAM3ecNkLuH4i4s8/RCPnF5JRip2GyviYkeEAcwGMJxkqG9h2dAsnA1nZpA==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.60.0.tgz", + "integrity": "sha512-jBONcBsDJ9UoTWrARkRRCgDz6wUggmH5RpQVlt7BimSwaTkTjwypGzKORXbR4/2Hqjk9hgwlon2rVQAjWNpkyQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.59.11", - "@typescript-eslint/types": "5.59.11", - "@typescript-eslint/typescript-estree": "5.59.11", + "@typescript-eslint/scope-manager": "5.60.0", + "@typescript-eslint/types": "5.60.0", + "@typescript-eslint/typescript-estree": "5.60.0", "debug": "^4.3.4" }, "engines": { @@ -1850,6 +1850,80 @@ } } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.60.0.tgz", + "integrity": "sha512-hakuzcxPwXi2ihf9WQu1BbRj1e/Pd8ZZwVTG9kfbxAMZstKz8/9OoexIwnmLzShtsdap5U/CoQGRCWlSuPbYxQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.60.0", + "@typescript-eslint/visitor-keys": "5.60.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.60.0.tgz", + "integrity": "sha512-ascOuoCpNZBccFVNJRSC6rPq4EmJ2NkuoKnd6LDNyAQmdDnziAtxbCGWCbefG1CNzmDvd05zO36AmB7H8RzKPA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.0.tgz", + "integrity": "sha512-R43thAuwarC99SnvrBmh26tc7F6sPa2B3evkXp/8q954kYL6Ro56AwASYWtEEi+4j09GbiNAHqYwNNZuNlARGQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.60.0", + "@typescript-eslint/visitor-keys": "5.60.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.0.tgz", + "integrity": "sha512-wm9Uz71SbCyhUKgcaPRauBdTegUyY/ZWl8gLwD/i/ybJqscrrdVSFImpvUz16BLPChIeKBK5Fa9s6KDQjsjyWw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.60.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "5.59.11", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.11.tgz", @@ -8060,15 +8134,58 @@ } }, "@typescript-eslint/parser": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.11.tgz", - "integrity": "sha512-s9ZF3M+Nym6CAZEkJJeO2TFHHDsKAM3ecNkLuH4i4s8/RCPnF5JRip2GyviYkeEAcwGMJxkqG9h2dAsnA1nZpA==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.60.0.tgz", + "integrity": "sha512-jBONcBsDJ9UoTWrARkRRCgDz6wUggmH5RpQVlt7BimSwaTkTjwypGzKORXbR4/2Hqjk9hgwlon2rVQAjWNpkyQ==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.59.11", - "@typescript-eslint/types": "5.59.11", - "@typescript-eslint/typescript-estree": "5.59.11", + "@typescript-eslint/scope-manager": "5.60.0", + "@typescript-eslint/types": "5.60.0", + "@typescript-eslint/typescript-estree": "5.60.0", "debug": "^4.3.4" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.60.0.tgz", + "integrity": "sha512-hakuzcxPwXi2ihf9WQu1BbRj1e/Pd8ZZwVTG9kfbxAMZstKz8/9OoexIwnmLzShtsdap5U/CoQGRCWlSuPbYxQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.60.0", + "@typescript-eslint/visitor-keys": "5.60.0" + } + }, + "@typescript-eslint/types": { + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.60.0.tgz", + "integrity": "sha512-ascOuoCpNZBccFVNJRSC6rPq4EmJ2NkuoKnd6LDNyAQmdDnziAtxbCGWCbefG1CNzmDvd05zO36AmB7H8RzKPA==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.0.tgz", + "integrity": "sha512-R43thAuwarC99SnvrBmh26tc7F6sPa2B3evkXp/8q954kYL6Ro56AwASYWtEEi+4j09GbiNAHqYwNNZuNlARGQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.60.0", + "@typescript-eslint/visitor-keys": "5.60.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.0.tgz", + "integrity": "sha512-wm9Uz71SbCyhUKgcaPRauBdTegUyY/ZWl8gLwD/i/ybJqscrrdVSFImpvUz16BLPChIeKBK5Fa9s6KDQjsjyWw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.60.0", + "eslint-visitor-keys": "^3.3.0" + } + } } }, "@typescript-eslint/scope-manager": { From 6b45c5e587f94a6fbbfd30b6475023813ff29c84 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Jun 2023 16:53:27 +0200 Subject: [PATCH 0377/1076] build(deps-dev): bump @rollup/plugin-commonjs from 25.0.1 to 25.0.2 in /stake-pool/js (#4577) build(deps-dev): bump @rollup/plugin-commonjs in /stake-pool/js Bumps [@rollup/plugin-commonjs](https://github.com/rollup/plugins/tree/HEAD/packages/commonjs) from 25.0.1 to 25.0.2. - [Changelog](https://github.com/rollup/plugins/blob/master/packages/commonjs/CHANGELOG.md) - [Commits](https://github.com/rollup/plugins/commits/commonjs-v25.0.2/packages/commonjs) --- updated-dependencies: - dependency-name: "@rollup/plugin-commonjs" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index a9b9eadd..c21faaca 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1317,9 +1317,9 @@ } }, "node_modules/@rollup/plugin-commonjs": { - "version": "25.0.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.1.tgz", - "integrity": "sha512-2DJ4kv4b1xfTJopWhu61ANdNRHvzQZ2fpaIrlgaP2jOfUv1wDJ0Ucqy8AZlbFmn/iUjiwKoqki9j55Y6L8kyNQ==", + "version": "25.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.2.tgz", + "integrity": "sha512-NGTwaJxIO0klMs+WSFFtBP7b9TdTJ3K76HZkewT8/+yHzMiUGVQgaPtLQxNVYIgT5F7lxkEyVID+yS3K7bhCow==", "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1", @@ -7749,9 +7749,9 @@ } }, "@rollup/plugin-commonjs": { - "version": "25.0.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.1.tgz", - "integrity": "sha512-2DJ4kv4b1xfTJopWhu61ANdNRHvzQZ2fpaIrlgaP2jOfUv1wDJ0Ucqy8AZlbFmn/iUjiwKoqki9j55Y6L8kyNQ==", + "version": "25.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.2.tgz", + "integrity": "sha512-NGTwaJxIO0klMs+WSFFtBP7b9TdTJ3K76HZkewT8/+yHzMiUGVQgaPtLQxNVYIgT5F7lxkEyVID+yS3K7bhCow==", "dev": true, "requires": { "@rollup/pluginutils": "^5.0.1", From a607712814cdde6942e5d07263432989e95878fc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Jun 2023 16:53:43 +0200 Subject: [PATCH 0378/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 5.59.11 to 5.60.0 in /stake-pool/js (#4576) build(deps-dev): bump @typescript-eslint/eslint-plugin in /stake-pool/js Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 5.59.11 to 5.60.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.60.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 245 ++++++++-------------------- 1 file changed, 64 insertions(+), 181 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index c21faaca..f1ec082a 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1790,15 +1790,15 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.11.tgz", - "integrity": "sha512-XxuOfTkCUiOSyBWIvHlUraLw/JT/6Io1365RO6ZuI88STKMavJZPNMU0lFcUTeQXEhHiv64CbxYxBNoDVSmghg==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.60.0.tgz", + "integrity": "sha512-78B+anHLF1TI8Jn/cD0Q00TBYdMgjdOn980JfAVa9yw5sop8nyTfVOQAv6LWywkOGLclDBtv5z3oxN4w7jxyNg==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.11", - "@typescript-eslint/type-utils": "5.59.11", - "@typescript-eslint/utils": "5.59.11", + "@typescript-eslint/scope-manager": "5.60.0", + "@typescript-eslint/type-utils": "5.60.0", + "@typescript-eslint/utils": "5.60.0", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", @@ -1850,7 +1850,7 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "node_modules/@typescript-eslint/scope-manager": { "version": "5.60.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.60.0.tgz", "integrity": "sha512-hakuzcxPwXi2ihf9WQu1BbRj1e/Pd8ZZwVTG9kfbxAMZstKz8/9OoexIwnmLzShtsdap5U/CoQGRCWlSuPbYxQ==", @@ -1867,88 +1867,14 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.60.0.tgz", - "integrity": "sha512-ascOuoCpNZBccFVNJRSC6rPq4EmJ2NkuoKnd6LDNyAQmdDnziAtxbCGWCbefG1CNzmDvd05zO36AmB7H8RzKPA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.0.tgz", - "integrity": "sha512-R43thAuwarC99SnvrBmh26tc7F6sPa2B3evkXp/8q954kYL6Ro56AwASYWtEEi+4j09GbiNAHqYwNNZuNlARGQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.60.0", - "@typescript-eslint/visitor-keys": "5.60.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.0.tgz", - "integrity": "sha512-wm9Uz71SbCyhUKgcaPRauBdTegUyY/ZWl8gLwD/i/ybJqscrrdVSFImpvUz16BLPChIeKBK5Fa9s6KDQjsjyWw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.60.0", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.11.tgz", - "integrity": "sha512-dHFOsxoLFtrIcSj5h0QoBT/89hxQONwmn3FOQ0GOQcLOOXm+MIrS8zEAhs4tWl5MraxCY3ZJpaXQQdFMc2Tu+Q==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.59.11", - "@typescript-eslint/visitor-keys": "5.59.11" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.11.tgz", - "integrity": "sha512-LZqVY8hMiVRF2a7/swmkStMYSoXMFlzL6sXV6U/2gL5cwnLWQgLEG8tjWPpaE4rMIdZ6VKWwcffPlo1jPfk43g==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.60.0.tgz", + "integrity": "sha512-X7NsRQddORMYRFH7FWo6sA9Y/zbJ8s1x1RIAtnlj6YprbToTiQnM6vxcMu7iYhdunmoC0rUWlca13D5DVHkK2g==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.59.11", - "@typescript-eslint/utils": "5.59.11", + "@typescript-eslint/typescript-estree": "5.60.0", + "@typescript-eslint/utils": "5.60.0", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -1969,9 +1895,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.11.tgz", - "integrity": "sha512-epoN6R6tkvBYSc+cllrz+c2sOFWkbisJZWkOE+y3xHtvYaOE6Wk6B8e114McRJwFRjGvYdJwLXQH5c9osME/AA==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.60.0.tgz", + "integrity": "sha512-ascOuoCpNZBccFVNJRSC6rPq4EmJ2NkuoKnd6LDNyAQmdDnziAtxbCGWCbefG1CNzmDvd05zO36AmB7H8RzKPA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1982,13 +1908,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.11.tgz", - "integrity": "sha512-YupOpot5hJO0maupJXixi6l5ETdrITxeo5eBOeuV7RSKgYdU3G5cxO49/9WRnJq9EMrB7AuTSLH/bqOsXi7wPA==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.0.tgz", + "integrity": "sha512-R43thAuwarC99SnvrBmh26tc7F6sPa2B3evkXp/8q954kYL6Ro56AwASYWtEEi+4j09GbiNAHqYwNNZuNlARGQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.11", - "@typescript-eslint/visitor-keys": "5.59.11", + "@typescript-eslint/types": "5.60.0", + "@typescript-eslint/visitor-keys": "5.60.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2009,17 +1935,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.11.tgz", - "integrity": "sha512-didu2rHSOMUdJThLk4aZ1Or8IcO3HzCw/ZvEjTTIfjIrcdd5cvSIwwDy2AOlE7htSNp7QIZ10fLMyRCveesMLg==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.60.0.tgz", + "integrity": "sha512-ba51uMqDtfLQ5+xHtwlO84vkdjrqNzOnqrnwbMHMRY8Tqeme8C2Q8Fc7LajfGR+e3/4LoYiWXUM6BpIIbHJ4hQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.11", - "@typescript-eslint/types": "5.59.11", - "@typescript-eslint/typescript-estree": "5.59.11", + "@typescript-eslint/scope-manager": "5.60.0", + "@typescript-eslint/types": "5.60.0", + "@typescript-eslint/typescript-estree": "5.60.0", "eslint-scope": "^5.1.1", "semver": "^7.3.7" }, @@ -2035,12 +1961,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.11.tgz", - "integrity": "sha512-KGYniTGG3AMTuKF9QBD7EIrvufkB6O6uX3knP73xbKLMpH+QRPcgnCxjWXSHjMRuOxFLovljqQgQpR0c7GvjoA==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.0.tgz", + "integrity": "sha512-wm9Uz71SbCyhUKgcaPRauBdTegUyY/ZWl8gLwD/i/ybJqscrrdVSFImpvUz16BLPChIeKBK5Fa9s6KDQjsjyWw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.11", + "@typescript-eslint/types": "5.60.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -8116,15 +8042,15 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.11.tgz", - "integrity": "sha512-XxuOfTkCUiOSyBWIvHlUraLw/JT/6Io1365RO6ZuI88STKMavJZPNMU0lFcUTeQXEhHiv64CbxYxBNoDVSmghg==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.60.0.tgz", + "integrity": "sha512-78B+anHLF1TI8Jn/cD0Q00TBYdMgjdOn980JfAVa9yw5sop8nyTfVOQAv6LWywkOGLclDBtv5z3oxN4w7jxyNg==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.11", - "@typescript-eslint/type-utils": "5.59.11", - "@typescript-eslint/utils": "5.59.11", + "@typescript-eslint/scope-manager": "5.60.0", + "@typescript-eslint/type-utils": "5.60.0", + "@typescript-eslint/utils": "5.60.0", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", @@ -8143,87 +8069,44 @@ "@typescript-eslint/types": "5.60.0", "@typescript-eslint/typescript-estree": "5.60.0", "debug": "^4.3.4" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.60.0.tgz", - "integrity": "sha512-hakuzcxPwXi2ihf9WQu1BbRj1e/Pd8ZZwVTG9kfbxAMZstKz8/9OoexIwnmLzShtsdap5U/CoQGRCWlSuPbYxQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.60.0", - "@typescript-eslint/visitor-keys": "5.60.0" - } - }, - "@typescript-eslint/types": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.60.0.tgz", - "integrity": "sha512-ascOuoCpNZBccFVNJRSC6rPq4EmJ2NkuoKnd6LDNyAQmdDnziAtxbCGWCbefG1CNzmDvd05zO36AmB7H8RzKPA==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.0.tgz", - "integrity": "sha512-R43thAuwarC99SnvrBmh26tc7F6sPa2B3evkXp/8q954kYL6Ro56AwASYWtEEi+4j09GbiNAHqYwNNZuNlARGQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.60.0", - "@typescript-eslint/visitor-keys": "5.60.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.0.tgz", - "integrity": "sha512-wm9Uz71SbCyhUKgcaPRauBdTegUyY/ZWl8gLwD/i/ybJqscrrdVSFImpvUz16BLPChIeKBK5Fa9s6KDQjsjyWw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.60.0", - "eslint-visitor-keys": "^3.3.0" - } - } } }, "@typescript-eslint/scope-manager": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.11.tgz", - "integrity": "sha512-dHFOsxoLFtrIcSj5h0QoBT/89hxQONwmn3FOQ0GOQcLOOXm+MIrS8zEAhs4tWl5MraxCY3ZJpaXQQdFMc2Tu+Q==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.60.0.tgz", + "integrity": "sha512-hakuzcxPwXi2ihf9WQu1BbRj1e/Pd8ZZwVTG9kfbxAMZstKz8/9OoexIwnmLzShtsdap5U/CoQGRCWlSuPbYxQ==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.11", - "@typescript-eslint/visitor-keys": "5.59.11" + "@typescript-eslint/types": "5.60.0", + "@typescript-eslint/visitor-keys": "5.60.0" } }, "@typescript-eslint/type-utils": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.11.tgz", - "integrity": "sha512-LZqVY8hMiVRF2a7/swmkStMYSoXMFlzL6sXV6U/2gL5cwnLWQgLEG8tjWPpaE4rMIdZ6VKWwcffPlo1jPfk43g==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.60.0.tgz", + "integrity": "sha512-X7NsRQddORMYRFH7FWo6sA9Y/zbJ8s1x1RIAtnlj6YprbToTiQnM6vxcMu7iYhdunmoC0rUWlca13D5DVHkK2g==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.59.11", - "@typescript-eslint/utils": "5.59.11", + "@typescript-eslint/typescript-estree": "5.60.0", + "@typescript-eslint/utils": "5.60.0", "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.11.tgz", - "integrity": "sha512-epoN6R6tkvBYSc+cllrz+c2sOFWkbisJZWkOE+y3xHtvYaOE6Wk6B8e114McRJwFRjGvYdJwLXQH5c9osME/AA==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.60.0.tgz", + "integrity": "sha512-ascOuoCpNZBccFVNJRSC6rPq4EmJ2NkuoKnd6LDNyAQmdDnziAtxbCGWCbefG1CNzmDvd05zO36AmB7H8RzKPA==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.11.tgz", - "integrity": "sha512-YupOpot5hJO0maupJXixi6l5ETdrITxeo5eBOeuV7RSKgYdU3G5cxO49/9WRnJq9EMrB7AuTSLH/bqOsXi7wPA==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.0.tgz", + "integrity": "sha512-R43thAuwarC99SnvrBmh26tc7F6sPa2B3evkXp/8q954kYL6Ro56AwASYWtEEi+4j09GbiNAHqYwNNZuNlARGQ==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.11", - "@typescript-eslint/visitor-keys": "5.59.11", + "@typescript-eslint/types": "5.60.0", + "@typescript-eslint/visitor-keys": "5.60.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -8232,28 +8115,28 @@ } }, "@typescript-eslint/utils": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.11.tgz", - "integrity": "sha512-didu2rHSOMUdJThLk4aZ1Or8IcO3HzCw/ZvEjTTIfjIrcdd5cvSIwwDy2AOlE7htSNp7QIZ10fLMyRCveesMLg==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.60.0.tgz", + "integrity": "sha512-ba51uMqDtfLQ5+xHtwlO84vkdjrqNzOnqrnwbMHMRY8Tqeme8C2Q8Fc7LajfGR+e3/4LoYiWXUM6BpIIbHJ4hQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.11", - "@typescript-eslint/types": "5.59.11", - "@typescript-eslint/typescript-estree": "5.59.11", + "@typescript-eslint/scope-manager": "5.60.0", + "@typescript-eslint/types": "5.60.0", + "@typescript-eslint/typescript-estree": "5.60.0", "eslint-scope": "^5.1.1", "semver": "^7.3.7" } }, "@typescript-eslint/visitor-keys": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.11.tgz", - "integrity": "sha512-KGYniTGG3AMTuKF9QBD7EIrvufkB6O6uX3knP73xbKLMpH+QRPcgnCxjWXSHjMRuOxFLovljqQgQpR0c7GvjoA==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.0.tgz", + "integrity": "sha512-wm9Uz71SbCyhUKgcaPRauBdTegUyY/ZWl8gLwD/i/ybJqscrrdVSFImpvUz16BLPChIeKBK5Fa9s6KDQjsjyWw==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.11", + "@typescript-eslint/types": "5.60.0", "eslint-visitor-keys": "^3.3.0" } }, From f0605d524b39a8a99791697f4fcb5548044de1e2 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 21 Jun 2023 22:30:16 +0200 Subject: [PATCH 0379/1076] stake-pool: Remove mpl crate dependency for 1.16 upgrade (#4588) --- program/Cargo.toml | 1 - program/src/inline_mpl_token_metadata.rs | 137 ++++++++++++++++++++ program/src/instruction.rs | 6 +- program/src/lib.rs | 1 + program/src/processor.rs | 22 ++-- program/tests/create_pool_token_metadata.rs | 14 +- program/tests/helpers/mod.rs | 23 +++- program/tests/update_pool_token_metadata.rs | 14 +- 8 files changed, 174 insertions(+), 44 deletions(-) create mode 100644 program/src/inline_mpl_token_metadata.rs diff --git a/program/Cargo.toml b/program/Cargo.toml index 77d81ac5..216be7d2 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -14,7 +14,6 @@ test-sbf = [] [dependencies] arrayref = "0.3.7" borsh = "0.9" -mpl-token-metadata = { version = "1.7.0", features = [ "no-entrypoint" ] } num-derive = "0.3" num-traits = "0.2" num_enum = "0.6.1" diff --git a/program/src/inline_mpl_token_metadata.rs b/program/src/inline_mpl_token_metadata.rs new file mode 100644 index 00000000..3ee5b37d --- /dev/null +++ b/program/src/inline_mpl_token_metadata.rs @@ -0,0 +1,137 @@ +//! Inlined MPL metadata types to avoid a direct dependency on `mpl-token-metadata' + +solana_program::declare_id!("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"); + +pub(crate) mod instruction { + use { + super::state::DataV2, + borsh::{BorshDeserialize, BorshSerialize}, + solana_program::{ + instruction::{AccountMeta, Instruction}, + pubkey::Pubkey, + }, + }; + + #[derive(BorshSerialize, BorshDeserialize, PartialEq, Eq, Debug, Clone)] + struct CreateMetadataAccountArgsV3 { + /// Note that unique metadatas are disabled for now. + pub data: DataV2, + /// Whether you want your metadata to be updateable in the future. + pub is_mutable: bool, + /// UNUSED If this is a collection parent NFT. + pub collection_details: Option, + } + + #[allow(clippy::too_many_arguments)] + pub(crate) fn create_metadata_accounts_v3( + program_id: Pubkey, + metadata_account: Pubkey, + mint: Pubkey, + mint_authority: Pubkey, + payer: Pubkey, + update_authority: Pubkey, + name: String, + symbol: String, + uri: String, + ) -> Instruction { + let mut data = vec![33]; // CreateMetadataAccountV3 + data.append( + &mut CreateMetadataAccountArgsV3 { + data: DataV2 { + name, + symbol, + uri, + seller_fee_basis_points: 0, + creators: None, + collection: None, + uses: None, + }, + is_mutable: true, + collection_details: None, + } + .try_to_vec() + .unwrap(), + ); + Instruction { + program_id, + accounts: vec![ + AccountMeta::new(metadata_account, false), + AccountMeta::new_readonly(mint, false), + AccountMeta::new_readonly(mint_authority, true), + AccountMeta::new(payer, true), + AccountMeta::new_readonly(update_authority, true), + AccountMeta::new_readonly(solana_program::system_program::ID, false), + ], + data, + } + } + + #[derive(BorshSerialize, BorshDeserialize, PartialEq, Eq, Debug, Clone)] + struct UpdateMetadataAccountArgsV2 { + pub data: Option, + pub update_authority: Option, + pub primary_sale_happened: Option, + pub is_mutable: Option, + } + pub(crate) fn update_metadata_accounts_v2( + program_id: Pubkey, + metadata_account: Pubkey, + update_authority: Pubkey, + new_update_authority: Option, + metadata: Option, + primary_sale_happened: Option, + is_mutable: Option, + ) -> Instruction { + let mut data = vec![15]; // UpdateMetadataAccountV2 + data.append( + &mut UpdateMetadataAccountArgsV2 { + data: metadata, + update_authority: new_update_authority, + primary_sale_happened, + is_mutable, + } + .try_to_vec() + .unwrap(), + ); + Instruction { + program_id, + accounts: vec![ + AccountMeta::new(metadata_account, false), + AccountMeta::new_readonly(update_authority, true), + ], + data, + } + } +} + +/// PDA creation helpers +pub mod pda { + use {super::ID, solana_program::pubkey::Pubkey}; + const PREFIX: &str = "metadata"; + /// Helper to find a metadata account address + pub fn find_metadata_account(mint: &Pubkey) -> (Pubkey, u8) { + Pubkey::find_program_address(&[PREFIX.as_bytes(), ID.as_ref(), mint.as_ref()], &ID) + } +} + +pub(crate) mod state { + use borsh::{BorshDeserialize, BorshSerialize}; + #[repr(C)] + #[derive(BorshSerialize, BorshDeserialize, PartialEq, Eq, Debug, Clone)] + pub(crate) struct DataV2 { + /// The name of the asset + pub name: String, + /// The symbol for the asset + pub symbol: String, + /// URI pointing to JSON representing the asset + pub uri: String, + /// Royalty basis points that goes to creators in secondary sales (0-10000) + pub seller_fee_basis_points: u16, + /// UNUSED Array of creators, optional + pub creators: Option, + /// UNUSED Collection + pub collection: Option, + /// UNUSED Uses + pub uses: Option, + } +} diff --git a/program/src/instruction.rs b/program/src/instruction.rs index a80c861b..286a02a5 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -7,11 +7,11 @@ use { find_deposit_authority_program_address, find_ephemeral_stake_program_address, find_stake_program_address, find_transient_stake_program_address, find_withdraw_authority_program_address, + inline_mpl_token_metadata::{self, pda::find_metadata_account}, state::{Fee, FeeType, StakePool, ValidatorList}, MAX_VALIDATORS_TO_UPDATE, }, borsh::{BorshDeserialize, BorshSchema, BorshSerialize}, - mpl_token_metadata::pda::find_metadata_account, solana_program::{ instruction::{AccountMeta, Instruction}, pubkey::Pubkey, @@ -2228,7 +2228,7 @@ pub fn update_token_metadata( AccountMeta::new_readonly(*manager, true), AccountMeta::new_readonly(stake_pool_withdraw_authority, false), AccountMeta::new(token_metadata, false), - AccountMeta::new_readonly(mpl_token_metadata::id(), false), + AccountMeta::new_readonly(inline_mpl_token_metadata::id(), false), ]; Instruction { @@ -2263,7 +2263,7 @@ pub fn create_token_metadata( AccountMeta::new_readonly(*pool_mint, false), AccountMeta::new(*payer, true), AccountMeta::new(token_metadata, false), - AccountMeta::new_readonly(mpl_token_metadata::id(), false), + AccountMeta::new_readonly(inline_mpl_token_metadata::id(), false), AccountMeta::new_readonly(system_program::id(), false), ]; diff --git a/program/src/lib.rs b/program/src/lib.rs index 66c9dd2c..ab5bef67 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -4,6 +4,7 @@ pub mod big_vec; pub mod error; +pub mod inline_mpl_token_metadata; pub mod instruction; pub mod processor; pub mod state; diff --git a/program/src/processor.rs b/program/src/processor.rs index acc8164f..0d1d1e39 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -4,6 +4,12 @@ use { crate::{ error::StakePoolError, find_deposit_authority_program_address, + inline_mpl_token_metadata::{ + self, + instruction::{create_metadata_accounts_v3, update_metadata_accounts_v2}, + pda::find_metadata_account, + state::DataV2, + }, instruction::{FundingType, PreferredValidatorType, StakePoolInstruction}, minimum_delegation, minimum_reserve_lamports, minimum_stake_lamports, state::{ @@ -15,11 +21,6 @@ use { TRANSIENT_STAKE_SEED_PREFIX, }, borsh::BorshDeserialize, - mpl_token_metadata::{ - instruction::{create_metadata_accounts_v3, update_metadata_accounts_v2}, - pda::find_metadata_account, - state::DataV2, - }, num_traits::FromPrimitive, solana_program::{ account_info::{next_account_info, AccountInfo}, @@ -161,10 +162,10 @@ fn check_stake_program(program_id: &Pubkey) -> Result<(), ProgramError> { /// Check mpl metadata program fn check_mpl_metadata_program(program_id: &Pubkey) -> Result<(), ProgramError> { - if *program_id != mpl_token_metadata::id() { + if *program_id != inline_mpl_token_metadata::id() { msg!( "Expected mpl metadata program {}, received {}", - mpl_token_metadata::id(), + inline_mpl_token_metadata::id(), program_id ); Err(ProgramError::IncorrectProgramId) @@ -3512,13 +3513,6 @@ impl Processor { name, symbol, uri, - None, - 0, - true, - true, - None, - None, - None, ); let (_, stake_withdraw_bump_seed) = diff --git a/program/tests/create_pool_token_metadata.rs b/program/tests/create_pool_token_metadata.rs index 01be0df6..7734c785 100644 --- a/program/tests/create_pool_token_metadata.rs +++ b/program/tests/create_pool_token_metadata.rs @@ -4,10 +4,6 @@ mod helpers; use { helpers::*, - mpl_token_metadata::{ - state::{MAX_NAME_LENGTH, MAX_SYMBOL_LENGTH, MAX_URI_LENGTH}, - utils::puffed_out_string, - }, solana_program::{instruction::InstructionError, pubkey::Pubkey}, solana_program_test::*, solana_sdk::{ @@ -49,10 +45,6 @@ async fn success(token_program_id: Pubkey) { let symbol = "SYM"; let uri = "test_uri"; - let puffed_name = puffed_out_string(name, MAX_NAME_LENGTH); - let puffed_symbol = puffed_out_string(symbol, MAX_SYMBOL_LENGTH); - let puffed_uri = puffed_out_string(uri, MAX_URI_LENGTH); - let ix = instruction::create_token_metadata( &spl_stake_pool::id(), &stake_pool_accounts.stake_pool.pubkey(), @@ -83,9 +75,9 @@ async fn success(token_program_id: Pubkey) { ) .await; - assert_eq!(metadata.data.name, puffed_name); - assert_eq!(metadata.data.symbol, puffed_symbol); - assert_eq!(metadata.data.uri, puffed_uri); + assert!(metadata.name.starts_with(name)); + assert!(metadata.symbol.starts_with(symbol)); + assert!(metadata.uri.starts_with(uri)); } #[tokio::test] diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 4fa7327a..6abcb246 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -1,8 +1,7 @@ #![allow(dead_code)] use { - borsh::BorshSerialize, - mpl_token_metadata::{pda::find_metadata_account, state::Metadata}, + borsh::{BorshDeserialize, BorshSerialize}, solana_program::{ borsh::{get_instance_packed_len, get_packed_len, try_from_slice_unchecked}, hash::Hash, @@ -28,7 +27,9 @@ use { spl_stake_pool::{ find_deposit_authority_program_address, find_ephemeral_stake_program_address, find_stake_program_address, find_transient_stake_program_address, - find_withdraw_authority_program_address, id, instruction, minimum_delegation, + find_withdraw_authority_program_address, id, + inline_mpl_token_metadata::{self, pda::find_metadata_account}, + instruction, minimum_delegation, processor::Processor, state::{self, FeeType, FutureEpoch, StakePool, ValidatorList}, MINIMUM_RESERVE_LAMPORTS, @@ -62,7 +63,7 @@ pub fn program_test() -> ProgramTest { pub fn program_test_with_metadata_program() -> ProgramTest { let mut program_test = ProgramTest::default(); program_test.add_program("spl_stake_pool", id(), processor!(Processor::process)); - program_test.add_program("mpl_token_metadata", mpl_token_metadata::id(), None); + program_test.add_program("mpl_token_metadata", inline_mpl_token_metadata::id(), None); program_test.prefer_bpf(false); program_test.add_program( "spl_token_2022", @@ -430,6 +431,20 @@ pub async fn get_token_balance(banks_client: &mut BanksClient, token: &Pubkey) - account_info.base.amount } +#[derive(Clone, BorshDeserialize, Debug, PartialEq, Eq)] +pub struct Metadata { + pub key: u8, + pub update_authority: Pubkey, + pub mint: Pubkey, + pub name: String, + pub symbol: String, + pub uri: String, + pub seller_fee_basis_points: u16, + pub creators: Option>, + pub primary_sale_happened: bool, + pub is_mutable: bool, +} + pub async fn get_metadata_account(banks_client: &mut BanksClient, token_mint: &Pubkey) -> Metadata { let (token_metadata, _) = find_metadata_account(token_mint); let token_metadata_account = banks_client diff --git a/program/tests/update_pool_token_metadata.rs b/program/tests/update_pool_token_metadata.rs index 881d7f0b..cfa5a3b9 100644 --- a/program/tests/update_pool_token_metadata.rs +++ b/program/tests/update_pool_token_metadata.rs @@ -4,10 +4,6 @@ mod helpers; use { helpers::*, - mpl_token_metadata::{ - state::{MAX_NAME_LENGTH, MAX_SYMBOL_LENGTH, MAX_URI_LENGTH}, - utils::puffed_out_string, - }, solana_program::instruction::InstructionError, solana_program_test::*, solana_sdk::{ @@ -74,10 +70,6 @@ async fn success_update_pool_token_metadata() { let updated_symbol = "USYM"; let updated_uri = "updated_uri"; - let puffed_name = puffed_out_string(updated_name, MAX_NAME_LENGTH); - let puffed_symbol = puffed_out_string(updated_symbol, MAX_SYMBOL_LENGTH); - let puffed_uri = puffed_out_string(updated_uri, MAX_URI_LENGTH); - let ix = instruction::update_token_metadata( &spl_stake_pool::id(), &stake_pool_accounts.stake_pool.pubkey(), @@ -107,9 +99,9 @@ async fn success_update_pool_token_metadata() { ) .await; - assert_eq!(metadata.data.name, puffed_name); - assert_eq!(metadata.data.symbol, puffed_symbol); - assert_eq!(metadata.data.uri, puffed_uri); + assert!(metadata.name.starts_with(updated_name)); + assert!(metadata.symbol.starts_with(updated_symbol)); + assert!(metadata.uri.starts_with(updated_uri)); } #[tokio::test] From 325d4a5797745da22cfc23820dc05214dc2c169e Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 21 Jun 2023 23:15:14 +0200 Subject: [PATCH 0380/1076] single-pool: Inline and remove MPL dependency (#4589) * single-pool: Inline and remove MPL dependency * Link the inline file rather than copy-pasta --- program/src/inline_mpl_token_metadata.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/program/src/inline_mpl_token_metadata.rs b/program/src/inline_mpl_token_metadata.rs index 3ee5b37d..ab42602e 100644 --- a/program/src/inline_mpl_token_metadata.rs +++ b/program/src/inline_mpl_token_metadata.rs @@ -1,4 +1,6 @@ //! Inlined MPL metadata types to avoid a direct dependency on `mpl-token-metadata' +//! NOTE: this file is sym-linked in `spl-single-validator-pool`, so be careful +//! with changes! solana_program::declare_id!("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"); From 1a8bf685b14f878f9dc6d6c769a6f44f6d2476d7 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Mon, 26 Jun 2023 14:42:02 +0200 Subject: [PATCH 0381/1076] Update Solana to 1.16.1 and Rust to 1.69 (#4592) #### Problem The 1.16 Solana crates are out, but SPL is still on 1.14 and needs the new functionality. #### Solution Update the: * rust version to 1.69 * nightly to 2023-04-19 * solana tools to 1.16.1 * solana crates to 1.16.1 * borsh to 0.10 And fix: * new clippy warnings * deprecated warnings in the new solana crates --- clients/cli/Cargo.toml | 20 ++++++++++---------- clients/py/stake_pool/instructions.py | 4 ++-- clients/py/vote/constants.py | 2 +- program/Cargo.toml | 10 +++++----- program/src/big_vec.rs | 2 +- program/src/processor.rs | 4 ++-- program/src/state.rs | 21 ++++++++------------- program/tests/helpers/mod.rs | 6 +++++- 8 files changed, 34 insertions(+), 35 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index fc0bc696..ae59e411 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -9,20 +9,20 @@ repository = "https://github.com/solana-labs/solana-program-library" version = "0.7.0" [dependencies] -borsh = "0.9" +borsh = "0.10" clap = "2.33.3" serde = "1.0.164" serde_derive = "1.0.130" serde_json = "1.0.97" -solana-account-decoder = "=1.14.12" -solana-clap-utils = "=1.14.12" -solana-cli-config = "=1.14.12" -solana-cli-output = "=1.14.12" -solana-client = "=1.14.12" -solana-logger = "=1.14.12" -solana-program = "=1.14.12" -solana-remote-wallet = "=1.14.12" -solana-sdk = "=1.14.12" +solana-account-decoder = "=1.16.1" +solana-clap-utils = "=1.16.1" +solana-cli-config = "=1.16.1" +solana-cli-output = "=1.16.1" +solana-client = "=1.16.1" +solana-logger = "=1.16.1" +solana-program = "=1.16.1" +solana-remote-wallet = "=1.16.1" +solana-sdk = "=1.16.1" spl-associated-token-account = { version = "=1.1.3", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "=0.7.0", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "=3.5.0", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/clients/py/stake_pool/instructions.py b/clients/py/stake_pool/instructions.py index cb52bd7f..5152567c 100644 --- a/clients/py/stake_pool/instructions.py +++ b/clients/py/stake_pool/instructions.py @@ -634,7 +634,7 @@ def add_validator_to_pool(params: AddValidatorToPoolParams) -> TransactionInstru """Creates instruction to add a validator to the pool.""" return TransactionInstruction( keys=[ - AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=True), AccountMeta(pubkey=params.staker, is_signer=True, is_writable=False), AccountMeta(pubkey=params.reserve_stake, is_signer=False, is_writable=True), AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), @@ -695,7 +695,7 @@ def remove_validator_from_pool(params: RemoveValidatorFromPoolParams) -> Transac """Creates instruction to remove a validator from the pool.""" return TransactionInstruction( keys=[ - AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=True), AccountMeta(pubkey=params.staker, is_signer=True, is_writable=False), AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), AccountMeta(pubkey=params.validator_list, is_signer=False, is_writable=True), diff --git a/clients/py/vote/constants.py b/clients/py/vote/constants.py index 21f006e4..701c90a0 100644 --- a/clients/py/vote/constants.py +++ b/clients/py/vote/constants.py @@ -4,5 +4,5 @@ VOTE_PROGRAM_ID = PublicKey("Vote111111111111111111111111111111111111111") """Program id for the native vote program.""" -VOTE_STATE_LEN: int = 3731 +VOTE_STATE_LEN: int = 3762 """Size of vote account.""" diff --git a/program/Cargo.toml b/program/Cargo.toml index 216be7d2..785115a7 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -13,13 +13,13 @@ test-sbf = [] [dependencies] arrayref = "0.3.7" -borsh = "0.9" +borsh = "0.10" num-derive = "0.3" num-traits = "0.2" num_enum = "0.6.1" serde = "1.0.164" serde_derive = "1.0.103" -solana-program = "1.14.12" +solana-program = "1.16.1" spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-token-2022 = { version = "0.6", path = "../../token/program-2022", features = [ "no-entrypoint" ] } thiserror = "1.0" @@ -27,9 +27,9 @@ bincode = "1.3.1" [dev-dependencies] proptest = "1.2" -solana-program-test = "1.14.12" -solana-sdk = "1.14.12" -solana-vote-program = "1.14.12" +solana-program-test = "1.16.1" +solana-sdk = "1.16.1" +solana-vote-program = "1.16.1" spl-token = { version = "3.5", path = "../../token/program", features = [ "no-entrypoint" ] } test-case = "3.1" diff --git a/program/src/big_vec.rs b/program/src/big_vec.rs index 903bb966..40852377 100644 --- a/program/src/big_vec.rs +++ b/program/src/big_vec.rs @@ -267,7 +267,7 @@ mod tests { } } - fn from_slice<'data, 'other>(data: &'data mut [u8], vec: &'other [u64]) -> BigVec<'data> { + fn from_slice<'data>(data: &'data mut [u8], vec: &[u64]) -> BigVec<'data> { let mut big_vec = BigVec { data }; for element in vec { big_vec.push(TestStruct::new(*element)).unwrap(); diff --git a/program/src/processor.rs b/program/src/processor.rs index 0d1d1e39..2ecf789c 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -337,8 +337,8 @@ fn check_transient_stake_account( } /// Create a stake account on a PDA without transferring lamports -fn create_stake_account<'a>( - stake_account_info: AccountInfo<'a>, +fn create_stake_account( + stake_account_info: AccountInfo<'_>, stake_account_signer_seeds: &[&[u8]], stake_space: usize, ) -> Result<(), ProgramError> { diff --git a/program/src/state.rs b/program/src/state.rs index 4751a978..b8ea873b 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -26,9 +26,10 @@ use { }; /// Enum representing the account type managed by the program -#[derive(Clone, Debug, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)] +#[derive(Clone, Debug, Default, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)] pub enum AccountType { /// If the account has not been initialized, the enum will be 0 + #[default] Uninitialized, /// Stake pool StakePool, @@ -36,12 +37,6 @@ pub enum AccountType { ValidatorList, } -impl Default for AccountType { - fn default() -> Self { - AccountType::Uninitialized - } -} - /// Initialized program details. #[repr(C)] #[derive(Clone, Debug, Default, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)] @@ -1042,8 +1037,8 @@ mod test { let size = get_instance_packed_len(&ValidatorList::new(max_validators)).unwrap(); let stake_list = uninitialized_validator_list(); let mut byte_vec = vec![0u8; size]; - let mut bytes = byte_vec.as_mut_slice(); - borsh::to_writer(&mut bytes, &stake_list).unwrap(); + let bytes = byte_vec.as_mut_slice(); + borsh::to_writer(bytes, &stake_list).unwrap(); let stake_list_unpacked = try_from_slice_unchecked::(&byte_vec).unwrap(); assert_eq!(stake_list_unpacked, stake_list); @@ -1056,16 +1051,16 @@ mod test { validators: vec![], }; let mut byte_vec = vec![0u8; size]; - let mut bytes = byte_vec.as_mut_slice(); - borsh::to_writer(&mut bytes, &stake_list).unwrap(); + let bytes = byte_vec.as_mut_slice(); + borsh::to_writer(bytes, &stake_list).unwrap(); let stake_list_unpacked = try_from_slice_unchecked::(&byte_vec).unwrap(); assert_eq!(stake_list_unpacked, stake_list); // With several accounts let stake_list = test_validator_list(max_validators); let mut byte_vec = vec![0u8; size]; - let mut bytes = byte_vec.as_mut_slice(); - borsh::to_writer(&mut bytes, &stake_list).unwrap(); + let bytes = byte_vec.as_mut_slice(); + borsh::to_writer(bytes, &stake_list).unwrap(); let stake_list_unpacked = try_from_slice_unchecked::(&byte_vec).unwrap(); assert_eq!(stake_list_unpacked, stake_list); } diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 6abcb246..84adabf6 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -615,7 +615,7 @@ pub async fn create_vote( 0, &system_program::id(), )]; - instructions.append(&mut vote_instruction::create_account( + instructions.append(&mut vote_instruction::create_account_with_config( &payer.pubkey(), &vote.pubkey(), &VoteInit { @@ -624,6 +624,10 @@ pub async fn create_vote( ..VoteInit::default() }, rent_voter, + vote_instruction::CreateVoteAccountConfig { + space: VoteStateVersions::vote_state_size_of(true) as u64, + ..Default::default() + }, )); let transaction = Transaction::new_signed_with_payer( From 55fe89c1969cbd9af8eaaf049de38fc36e55c881 Mon Sep 17 00:00:00 2001 From: Joe C Date: Mon, 26 Jun 2023 21:24:13 -0400 Subject: [PATCH 0382/1076] bump/math (#4611) --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 785115a7..402ed754 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -20,7 +20,7 @@ num_enum = "0.6.1" serde = "1.0.164" serde_derive = "1.0.103" solana-program = "1.16.1" -spl-math = { version = "0.1", path = "../../libraries/math", features = [ "no-entrypoint" ] } +spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-token-2022 = { version = "0.6", path = "../../token/program-2022", features = [ "no-entrypoint" ] } thiserror = "1.0" bincode = "1.3.1" From d19452615deab939cd5d458a6831984596ece32f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Jun 2023 13:11:36 +0200 Subject: [PATCH 0383/1076] build(deps): bump serde_json from 1.0.97 to 1.0.99 (#4599) * build(deps): bump serde_json from 1.0.97 to 1.0.99 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.97 to 1.0.99. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.97...v1.0.99) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Revert hashbrown update --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index ae59e411..c37d240b 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ borsh = "0.10" clap = "2.33.3" serde = "1.0.164" serde_derive = "1.0.130" -serde_json = "1.0.97" +serde_json = "1.0.99" solana-account-decoder = "=1.16.1" solana-clap-utils = "=1.16.1" solana-cli-config = "=1.16.1" From f30b2d4569752a14a1a78c5eabe9e0d34da84330 Mon Sep 17 00:00:00 2001 From: Joe C Date: Tue, 27 Jun 2023 08:34:11 -0400 Subject: [PATCH 0384/1076] bump token & co. (#4612) * bump token & token cli * token version fix --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index c37d240b..0a920b15 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -25,7 +25,7 @@ solana-remote-wallet = "=1.16.1" solana-sdk = "=1.16.1" spl-associated-token-account = { version = "=1.1.3", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "=0.7.0", path="../program", features = [ "no-entrypoint" ] } -spl-token = { version = "=3.5.0", path="../../token/program", features = [ "no-entrypoint" ] } +spl-token = { version = "=4.0", path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" bincode = "1.3.1" diff --git a/program/Cargo.toml b/program/Cargo.toml index 402ed754..aeb5c55a 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -30,7 +30,7 @@ proptest = "1.2" solana-program-test = "1.16.1" solana-sdk = "1.16.1" solana-vote-program = "1.16.1" -spl-token = { version = "3.5", path = "../../token/program", features = [ "no-entrypoint" ] } +spl-token = { version = "4.0", path = "../../token/program", features = [ "no-entrypoint" ] } test-case = "3.1" [lib] From 0882a0ce71aaa400911d6292af2d4ecaf364cdb2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Jun 2023 16:53:21 +0200 Subject: [PATCH 0385/1076] build(deps-dev): bump @types/node from 20.3.1 to 20.3.2 in /stake-pool/js (#4625) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.3.1 to 20.3.2. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index f1ec082a..dd6893b6 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1728,9 +1728,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.3.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.1.tgz", - "integrity": "sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==" + "version": "20.3.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.2.tgz", + "integrity": "sha512-vOBLVQeCQfIcF/2Y7eKFTqrMnizK5lRNQ7ykML/5RuwVXVWxYkgwS7xbt4B6fKCUPgbSL5FSsjHQpaGQP/dQmw==" }, "node_modules/@types/node-fetch": { "version": "2.6.4", @@ -7980,9 +7980,9 @@ "dev": true }, "@types/node": { - "version": "20.3.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.1.tgz", - "integrity": "sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==" + "version": "20.3.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.2.tgz", + "integrity": "sha512-vOBLVQeCQfIcF/2Y7eKFTqrMnizK5lRNQ7ykML/5RuwVXVWxYkgwS7xbt4B6fKCUPgbSL5FSsjHQpaGQP/dQmw==" }, "@types/node-fetch": { "version": "2.6.4", From 72c9e71cca261fd5b59b93490bd3eac3200355b5 Mon Sep 17 00:00:00 2001 From: Joe C Date: Tue, 27 Jun 2023 11:15:42 -0400 Subject: [PATCH 0386/1076] bump/token-2022 (#4623) * bump/token-2022 * bump/token-2022 - 0.7 --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index aeb5c55a..38a73079 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -21,7 +21,7 @@ serde = "1.0.164" serde_derive = "1.0.103" solana-program = "1.16.1" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } -spl-token-2022 = { version = "0.6", path = "../../token/program-2022", features = [ "no-entrypoint" ] } +spl-token-2022 = { version = "0.7", path = "../../token/program-2022", features = [ "no-entrypoint" ] } thiserror = "1.0" bincode = "1.3.1" From 6f3a8872ecf07a74eaa6178c36bc097b8fc0b640 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Jun 2023 19:40:30 +0200 Subject: [PATCH 0387/1076] build(deps-dev): bump @typescript-eslint/parser from 5.60.0 to 5.60.1 in /stake-pool/js (#4624) build(deps-dev): bump @typescript-eslint/parser in /stake-pool/js Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.60.0 to 5.60.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.60.1/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 141 +++++++++++++++++++++++++--- 1 file changed, 129 insertions(+), 12 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index dd6893b6..db802ca6 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1824,14 +1824,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.60.0.tgz", - "integrity": "sha512-jBONcBsDJ9UoTWrARkRRCgDz6wUggmH5RpQVlt7BimSwaTkTjwypGzKORXbR4/2Hqjk9hgwlon2rVQAjWNpkyQ==", + "version": "5.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.60.1.tgz", + "integrity": "sha512-pHWlc3alg2oSMGwsU/Is8hbm3XFbcrb6P5wIxcQW9NsYBfnrubl/GhVVD/Jm/t8HXhA2WncoIRfBtnCgRGV96Q==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.60.0", - "@typescript-eslint/types": "5.60.0", - "@typescript-eslint/typescript-estree": "5.60.0", + "@typescript-eslint/scope-manager": "5.60.1", + "@typescript-eslint/types": "5.60.1", + "@typescript-eslint/typescript-estree": "5.60.1", "debug": "^4.3.4" }, "engines": { @@ -1850,6 +1850,80 @@ } } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "5.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.60.1.tgz", + "integrity": "sha512-Dn/LnN7fEoRD+KspEOV0xDMynEmR3iSHdgNsarlXNLGGtcUok8L4N71dxUgt3YvlO8si7E+BJ5Fe3wb5yUw7DQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.60.1", + "@typescript-eslint/visitor-keys": "5.60.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "5.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.60.1.tgz", + "integrity": "sha512-zDcDx5fccU8BA0IDZc71bAtYIcG9PowaOwaD8rjYbqwK7dpe/UMQl3inJ4UtUK42nOCT41jTSCwg76E62JpMcg==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.1.tgz", + "integrity": "sha512-hkX70J9+2M2ZT6fhti5Q2FoU9zb+GeZK2SLP1WZlvUDqdMbEKhexZODD1WodNRyO8eS+4nScvT0dts8IdaBzfw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.60.1", + "@typescript-eslint/visitor-keys": "5.60.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.1.tgz", + "integrity": "sha512-xEYIxKcultP6E/RMKqube11pGjXH1DCo60mQoWhVYyKfLkwbIVVjYxmOenNMxILx0TjCujPTjjnTIVzm09TXIw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.60.1", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "5.60.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.60.0.tgz", @@ -8060,15 +8134,58 @@ } }, "@typescript-eslint/parser": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.60.0.tgz", - "integrity": "sha512-jBONcBsDJ9UoTWrARkRRCgDz6wUggmH5RpQVlt7BimSwaTkTjwypGzKORXbR4/2Hqjk9hgwlon2rVQAjWNpkyQ==", + "version": "5.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.60.1.tgz", + "integrity": "sha512-pHWlc3alg2oSMGwsU/Is8hbm3XFbcrb6P5wIxcQW9NsYBfnrubl/GhVVD/Jm/t8HXhA2WncoIRfBtnCgRGV96Q==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.60.0", - "@typescript-eslint/types": "5.60.0", - "@typescript-eslint/typescript-estree": "5.60.0", + "@typescript-eslint/scope-manager": "5.60.1", + "@typescript-eslint/types": "5.60.1", + "@typescript-eslint/typescript-estree": "5.60.1", "debug": "^4.3.4" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "5.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.60.1.tgz", + "integrity": "sha512-Dn/LnN7fEoRD+KspEOV0xDMynEmR3iSHdgNsarlXNLGGtcUok8L4N71dxUgt3YvlO8si7E+BJ5Fe3wb5yUw7DQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.60.1", + "@typescript-eslint/visitor-keys": "5.60.1" + } + }, + "@typescript-eslint/types": { + "version": "5.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.60.1.tgz", + "integrity": "sha512-zDcDx5fccU8BA0IDZc71bAtYIcG9PowaOwaD8rjYbqwK7dpe/UMQl3inJ4UtUK42nOCT41jTSCwg76E62JpMcg==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.1.tgz", + "integrity": "sha512-hkX70J9+2M2ZT6fhti5Q2FoU9zb+GeZK2SLP1WZlvUDqdMbEKhexZODD1WodNRyO8eS+4nScvT0dts8IdaBzfw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.60.1", + "@typescript-eslint/visitor-keys": "5.60.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.1.tgz", + "integrity": "sha512-xEYIxKcultP6E/RMKqube11pGjXH1DCo60mQoWhVYyKfLkwbIVVjYxmOenNMxILx0TjCujPTjjnTIVzm09TXIw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.60.1", + "eslint-visitor-keys": "^3.3.0" + } + } } }, "@typescript-eslint/scope-manager": { From 1d891c846aa504e3454c6b0b89f2b08711c21ee9 Mon Sep 17 00:00:00 2001 From: Joe C Date: Tue, 27 Jun 2023 13:48:06 -0400 Subject: [PATCH 0388/1076] Bump/associated token (#4633) * bump/associated-token * adjusted dependencies for managed token * major release instead --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 0a920b15..ff95defd 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -23,7 +23,7 @@ solana-logger = "=1.16.1" solana-program = "=1.16.1" solana-remote-wallet = "=1.16.1" solana-sdk = "=1.16.1" -spl-associated-token-account = { version = "=1.1.3", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } +spl-associated-token-account = { version = "=2.0", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "=0.7.0", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "=4.0", path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" From 8c6cb9764e90e25d5b63f82697e77ce26f9d7420 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Jun 2023 20:23:12 +0200 Subject: [PATCH 0389/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 5.60.0 to 5.60.1 in /stake-pool/js (#4626) build(deps-dev): bump @typescript-eslint/eslint-plugin in /stake-pool/js Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 5.60.0 to 5.60.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.60.1/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 245 ++++++++-------------------- 1 file changed, 64 insertions(+), 181 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index db802ca6..7f0ddc10 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1790,15 +1790,15 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.60.0.tgz", - "integrity": "sha512-78B+anHLF1TI8Jn/cD0Q00TBYdMgjdOn980JfAVa9yw5sop8nyTfVOQAv6LWywkOGLclDBtv5z3oxN4w7jxyNg==", + "version": "5.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.60.1.tgz", + "integrity": "sha512-KSWsVvsJsLJv3c4e73y/Bzt7OpqMCADUO846bHcuWYSYM19bldbAeDv7dYyV0jwkbMfJ2XdlzwjhXtuD7OY6bw==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.60.0", - "@typescript-eslint/type-utils": "5.60.0", - "@typescript-eslint/utils": "5.60.0", + "@typescript-eslint/scope-manager": "5.60.1", + "@typescript-eslint/type-utils": "5.60.1", + "@typescript-eslint/utils": "5.60.1", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", @@ -1850,7 +1850,7 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "node_modules/@typescript-eslint/scope-manager": { "version": "5.60.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.60.1.tgz", "integrity": "sha512-Dn/LnN7fEoRD+KspEOV0xDMynEmR3iSHdgNsarlXNLGGtcUok8L4N71dxUgt3YvlO8si7E+BJ5Fe3wb5yUw7DQ==", @@ -1867,88 +1867,14 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "5.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.60.1.tgz", - "integrity": "sha512-zDcDx5fccU8BA0IDZc71bAtYIcG9PowaOwaD8rjYbqwK7dpe/UMQl3inJ4UtUK42nOCT41jTSCwg76E62JpMcg==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.1.tgz", - "integrity": "sha512-hkX70J9+2M2ZT6fhti5Q2FoU9zb+GeZK2SLP1WZlvUDqdMbEKhexZODD1WodNRyO8eS+4nScvT0dts8IdaBzfw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.60.1", - "@typescript-eslint/visitor-keys": "5.60.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.1.tgz", - "integrity": "sha512-xEYIxKcultP6E/RMKqube11pGjXH1DCo60mQoWhVYyKfLkwbIVVjYxmOenNMxILx0TjCujPTjjnTIVzm09TXIw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.60.1", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.60.0.tgz", - "integrity": "sha512-hakuzcxPwXi2ihf9WQu1BbRj1e/Pd8ZZwVTG9kfbxAMZstKz8/9OoexIwnmLzShtsdap5U/CoQGRCWlSuPbYxQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.60.0", - "@typescript-eslint/visitor-keys": "5.60.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.60.0.tgz", - "integrity": "sha512-X7NsRQddORMYRFH7FWo6sA9Y/zbJ8s1x1RIAtnlj6YprbToTiQnM6vxcMu7iYhdunmoC0rUWlca13D5DVHkK2g==", + "version": "5.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.60.1.tgz", + "integrity": "sha512-vN6UztYqIu05nu7JqwQGzQKUJctzs3/Hg7E2Yx8rz9J+4LgtIDFWjjl1gm3pycH0P3mHAcEUBd23LVgfrsTR8A==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.60.0", - "@typescript-eslint/utils": "5.60.0", + "@typescript-eslint/typescript-estree": "5.60.1", + "@typescript-eslint/utils": "5.60.1", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -1969,9 +1895,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.60.0.tgz", - "integrity": "sha512-ascOuoCpNZBccFVNJRSC6rPq4EmJ2NkuoKnd6LDNyAQmdDnziAtxbCGWCbefG1CNzmDvd05zO36AmB7H8RzKPA==", + "version": "5.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.60.1.tgz", + "integrity": "sha512-zDcDx5fccU8BA0IDZc71bAtYIcG9PowaOwaD8rjYbqwK7dpe/UMQl3inJ4UtUK42nOCT41jTSCwg76E62JpMcg==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1982,13 +1908,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.0.tgz", - "integrity": "sha512-R43thAuwarC99SnvrBmh26tc7F6sPa2B3evkXp/8q954kYL6Ro56AwASYWtEEi+4j09GbiNAHqYwNNZuNlARGQ==", + "version": "5.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.1.tgz", + "integrity": "sha512-hkX70J9+2M2ZT6fhti5Q2FoU9zb+GeZK2SLP1WZlvUDqdMbEKhexZODD1WodNRyO8eS+4nScvT0dts8IdaBzfw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.60.0", - "@typescript-eslint/visitor-keys": "5.60.0", + "@typescript-eslint/types": "5.60.1", + "@typescript-eslint/visitor-keys": "5.60.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2009,17 +1935,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.60.0.tgz", - "integrity": "sha512-ba51uMqDtfLQ5+xHtwlO84vkdjrqNzOnqrnwbMHMRY8Tqeme8C2Q8Fc7LajfGR+e3/4LoYiWXUM6BpIIbHJ4hQ==", + "version": "5.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.60.1.tgz", + "integrity": "sha512-tiJ7FFdFQOWssFa3gqb94Ilexyw0JVxj6vBzaSpfN/8IhoKkDuSAenUKvsSHw2A/TMpJb26izIszTXaqygkvpQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.60.0", - "@typescript-eslint/types": "5.60.0", - "@typescript-eslint/typescript-estree": "5.60.0", + "@typescript-eslint/scope-manager": "5.60.1", + "@typescript-eslint/types": "5.60.1", + "@typescript-eslint/typescript-estree": "5.60.1", "eslint-scope": "^5.1.1", "semver": "^7.3.7" }, @@ -2035,12 +1961,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.0.tgz", - "integrity": "sha512-wm9Uz71SbCyhUKgcaPRauBdTegUyY/ZWl8gLwD/i/ybJqscrrdVSFImpvUz16BLPChIeKBK5Fa9s6KDQjsjyWw==", + "version": "5.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.1.tgz", + "integrity": "sha512-xEYIxKcultP6E/RMKqube11pGjXH1DCo60mQoWhVYyKfLkwbIVVjYxmOenNMxILx0TjCujPTjjnTIVzm09TXIw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.60.0", + "@typescript-eslint/types": "5.60.1", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -8116,15 +8042,15 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.60.0.tgz", - "integrity": "sha512-78B+anHLF1TI8Jn/cD0Q00TBYdMgjdOn980JfAVa9yw5sop8nyTfVOQAv6LWywkOGLclDBtv5z3oxN4w7jxyNg==", + "version": "5.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.60.1.tgz", + "integrity": "sha512-KSWsVvsJsLJv3c4e73y/Bzt7OpqMCADUO846bHcuWYSYM19bldbAeDv7dYyV0jwkbMfJ2XdlzwjhXtuD7OY6bw==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.60.0", - "@typescript-eslint/type-utils": "5.60.0", - "@typescript-eslint/utils": "5.60.0", + "@typescript-eslint/scope-manager": "5.60.1", + "@typescript-eslint/type-utils": "5.60.1", + "@typescript-eslint/utils": "5.60.1", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", @@ -8143,87 +8069,44 @@ "@typescript-eslint/types": "5.60.1", "@typescript-eslint/typescript-estree": "5.60.1", "debug": "^4.3.4" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "5.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.60.1.tgz", - "integrity": "sha512-Dn/LnN7fEoRD+KspEOV0xDMynEmR3iSHdgNsarlXNLGGtcUok8L4N71dxUgt3YvlO8si7E+BJ5Fe3wb5yUw7DQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.60.1", - "@typescript-eslint/visitor-keys": "5.60.1" - } - }, - "@typescript-eslint/types": { - "version": "5.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.60.1.tgz", - "integrity": "sha512-zDcDx5fccU8BA0IDZc71bAtYIcG9PowaOwaD8rjYbqwK7dpe/UMQl3inJ4UtUK42nOCT41jTSCwg76E62JpMcg==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.1.tgz", - "integrity": "sha512-hkX70J9+2M2ZT6fhti5Q2FoU9zb+GeZK2SLP1WZlvUDqdMbEKhexZODD1WodNRyO8eS+4nScvT0dts8IdaBzfw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.60.1", - "@typescript-eslint/visitor-keys": "5.60.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.1.tgz", - "integrity": "sha512-xEYIxKcultP6E/RMKqube11pGjXH1DCo60mQoWhVYyKfLkwbIVVjYxmOenNMxILx0TjCujPTjjnTIVzm09TXIw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.60.1", - "eslint-visitor-keys": "^3.3.0" - } - } } }, "@typescript-eslint/scope-manager": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.60.0.tgz", - "integrity": "sha512-hakuzcxPwXi2ihf9WQu1BbRj1e/Pd8ZZwVTG9kfbxAMZstKz8/9OoexIwnmLzShtsdap5U/CoQGRCWlSuPbYxQ==", + "version": "5.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.60.1.tgz", + "integrity": "sha512-Dn/LnN7fEoRD+KspEOV0xDMynEmR3iSHdgNsarlXNLGGtcUok8L4N71dxUgt3YvlO8si7E+BJ5Fe3wb5yUw7DQ==", "dev": true, "requires": { - "@typescript-eslint/types": "5.60.0", - "@typescript-eslint/visitor-keys": "5.60.0" + "@typescript-eslint/types": "5.60.1", + "@typescript-eslint/visitor-keys": "5.60.1" } }, "@typescript-eslint/type-utils": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.60.0.tgz", - "integrity": "sha512-X7NsRQddORMYRFH7FWo6sA9Y/zbJ8s1x1RIAtnlj6YprbToTiQnM6vxcMu7iYhdunmoC0rUWlca13D5DVHkK2g==", + "version": "5.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.60.1.tgz", + "integrity": "sha512-vN6UztYqIu05nu7JqwQGzQKUJctzs3/Hg7E2Yx8rz9J+4LgtIDFWjjl1gm3pycH0P3mHAcEUBd23LVgfrsTR8A==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.60.0", - "@typescript-eslint/utils": "5.60.0", + "@typescript-eslint/typescript-estree": "5.60.1", + "@typescript-eslint/utils": "5.60.1", "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.60.0.tgz", - "integrity": "sha512-ascOuoCpNZBccFVNJRSC6rPq4EmJ2NkuoKnd6LDNyAQmdDnziAtxbCGWCbefG1CNzmDvd05zO36AmB7H8RzKPA==", + "version": "5.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.60.1.tgz", + "integrity": "sha512-zDcDx5fccU8BA0IDZc71bAtYIcG9PowaOwaD8rjYbqwK7dpe/UMQl3inJ4UtUK42nOCT41jTSCwg76E62JpMcg==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.0.tgz", - "integrity": "sha512-R43thAuwarC99SnvrBmh26tc7F6sPa2B3evkXp/8q954kYL6Ro56AwASYWtEEi+4j09GbiNAHqYwNNZuNlARGQ==", + "version": "5.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.1.tgz", + "integrity": "sha512-hkX70J9+2M2ZT6fhti5Q2FoU9zb+GeZK2SLP1WZlvUDqdMbEKhexZODD1WodNRyO8eS+4nScvT0dts8IdaBzfw==", "dev": true, "requires": { - "@typescript-eslint/types": "5.60.0", - "@typescript-eslint/visitor-keys": "5.60.0", + "@typescript-eslint/types": "5.60.1", + "@typescript-eslint/visitor-keys": "5.60.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -8232,28 +8115,28 @@ } }, "@typescript-eslint/utils": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.60.0.tgz", - "integrity": "sha512-ba51uMqDtfLQ5+xHtwlO84vkdjrqNzOnqrnwbMHMRY8Tqeme8C2Q8Fc7LajfGR+e3/4LoYiWXUM6BpIIbHJ4hQ==", + "version": "5.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.60.1.tgz", + "integrity": "sha512-tiJ7FFdFQOWssFa3gqb94Ilexyw0JVxj6vBzaSpfN/8IhoKkDuSAenUKvsSHw2A/TMpJb26izIszTXaqygkvpQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.60.0", - "@typescript-eslint/types": "5.60.0", - "@typescript-eslint/typescript-estree": "5.60.0", + "@typescript-eslint/scope-manager": "5.60.1", + "@typescript-eslint/types": "5.60.1", + "@typescript-eslint/typescript-estree": "5.60.1", "eslint-scope": "^5.1.1", "semver": "^7.3.7" } }, "@typescript-eslint/visitor-keys": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.0.tgz", - "integrity": "sha512-wm9Uz71SbCyhUKgcaPRauBdTegUyY/ZWl8gLwD/i/ybJqscrrdVSFImpvUz16BLPChIeKBK5Fa9s6KDQjsjyWw==", + "version": "5.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.1.tgz", + "integrity": "sha512-xEYIxKcultP6E/RMKqube11pGjXH1DCo60mQoWhVYyKfLkwbIVVjYxmOenNMxILx0TjCujPTjjnTIVzm09TXIw==", "dev": true, "requires": { - "@typescript-eslint/types": "5.60.0", + "@typescript-eslint/types": "5.60.1", "eslint-visitor-keys": "^3.3.0" } }, From a9733a3e80b9cfecc11ec5e1df4b18be24817761 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Jun 2023 15:23:58 +0200 Subject: [PATCH 0390/1076] build(deps-dev): bump @rollup/plugin-typescript from 11.1.1 to 11.1.2 in /stake-pool/js (#4643) build(deps-dev): bump @rollup/plugin-typescript in /stake-pool/js Bumps [@rollup/plugin-typescript](https://github.com/rollup/plugins/tree/HEAD/packages/typescript) from 11.1.1 to 11.1.2. - [Changelog](https://github.com/rollup/plugins/blob/master/packages/typescript/CHANGELOG.md) - [Commits](https://github.com/rollup/plugins/commits/typescript-v11.1.2/packages/typescript) --- updated-dependencies: - dependency-name: "@rollup/plugin-typescript" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 7f0ddc10..9bb80e83 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1460,9 +1460,9 @@ } }, "node_modules/@rollup/plugin-typescript": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.1.tgz", - "integrity": "sha512-Ioir+x5Bejv72Lx2Zbz3/qGg7tvGbxQZALCLoJaGrkNXak/19+vKgKYJYM3i/fJxvsb23I9FuFQ8CUBEfsmBRg==", + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.2.tgz", + "integrity": "sha512-0ghSOCMcA7fl1JM+0gYRf+Q/HWyg+zg7/gDSc+fRLmlJWcW5K1I+CLRzaRhXf4Y3DRyPnnDo4M2ktw+a6JcDEg==", "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1", @@ -7764,9 +7764,9 @@ } }, "@rollup/plugin-typescript": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.1.tgz", - "integrity": "sha512-Ioir+x5Bejv72Lx2Zbz3/qGg7tvGbxQZALCLoJaGrkNXak/19+vKgKYJYM3i/fJxvsb23I9FuFQ8CUBEfsmBRg==", + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.2.tgz", + "integrity": "sha512-0ghSOCMcA7fl1JM+0gYRf+Q/HWyg+zg7/gDSc+fRLmlJWcW5K1I+CLRzaRhXf4Y3DRyPnnDo4M2ktw+a6JcDEg==", "dev": true, "requires": { "@rollup/pluginutils": "^5.0.1", From c8cb4a8d1d1eb8c097c669da89ea1efcdeb24522 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 29 Jun 2023 03:06:08 +0200 Subject: [PATCH 0391/1076] token-2022: Make `Extension::get_account_len` fallible (#4646) * token-2022: Make `Extension::get_account_len` fallible * Rename / recomment fallible funcs, redo enum --- program/tests/helpers/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 84adabf6..d9145708 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -94,7 +94,7 @@ pub async fn create_mint( ) -> Result<(), TransportError> { assert!(extension_types.is_empty() || program_id != &spl_token::id()); let rent = banks_client.get_rent().await.unwrap(); - let space = ExtensionType::get_account_len::(extension_types); + let space = ExtensionType::try_get_account_len::(extension_types).unwrap(); let mint_rent = rent.minimum_balance(space); let mint_pubkey = pool_mint.pubkey(); @@ -225,7 +225,7 @@ pub async fn create_token_account( extensions: &[ExtensionType], ) -> Result<(), TransportError> { let rent = banks_client.get_rent().await.unwrap(); - let space = ExtensionType::get_account_len::(extensions); + let space = ExtensionType::try_get_account_len::(extensions).unwrap(); let account_rent = rent.minimum_balance(space); let mut instructions = vec![system_instruction::create_account( From fbcc4dfd36b3ae7eac9b6defb513d62afd757221 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 30 Jun 2023 14:03:21 +0200 Subject: [PATCH 0392/1076] build(deps): bump num-derive from 0.3.3 to 0.4.0 (#4659) * build(deps): bump num-derive from 0.3.3 to 0.4.0 Bumps [num-derive](https://github.com/rust-num/num-derive) from 0.3.3 to 0.4.0. - [Changelog](https://github.com/rust-num/num-derive/blob/master/RELEASES.md) - [Commits](https://github.com/rust-num/num-derive/compare/num-derive-0.3.3...num-derive-0.4.0) --- updated-dependencies: - dependency-name: num-derive dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Unbump hashbrown in borsh --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 38a73079..f0e0ee54 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -14,7 +14,7 @@ test-sbf = [] [dependencies] arrayref = "0.3.7" borsh = "0.10" -num-derive = "0.3" +num-derive = "0.4" num-traits = "0.2" num_enum = "0.6.1" serde = "1.0.164" From 0e7b197e9afe13a1237b246e358b3bfc634a1ccc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jul 2023 14:44:02 +0200 Subject: [PATCH 0393/1076] build(deps-dev): bump @types/node from 20.3.2 to 20.3.3 in /stake-pool/js (#4673) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.3.2 to 20.3.3. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 9bb80e83..6d6f03b5 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1728,9 +1728,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.3.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.2.tgz", - "integrity": "sha512-vOBLVQeCQfIcF/2Y7eKFTqrMnizK5lRNQ7ykML/5RuwVXVWxYkgwS7xbt4B6fKCUPgbSL5FSsjHQpaGQP/dQmw==" + "version": "20.3.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.3.tgz", + "integrity": "sha512-wheIYdr4NYML61AjC8MKj/2jrR/kDQri/CIpVoZwldwhnIrD/j9jIU5bJ8yBKuB2VhpFV7Ab6G2XkBjv9r9Zzw==" }, "node_modules/@types/node-fetch": { "version": "2.6.4", @@ -7980,9 +7980,9 @@ "dev": true }, "@types/node": { - "version": "20.3.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.2.tgz", - "integrity": "sha512-vOBLVQeCQfIcF/2Y7eKFTqrMnizK5lRNQ7ykML/5RuwVXVWxYkgwS7xbt4B6fKCUPgbSL5FSsjHQpaGQP/dQmw==" + "version": "20.3.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.3.tgz", + "integrity": "sha512-wheIYdr4NYML61AjC8MKj/2jrR/kDQri/CIpVoZwldwhnIrD/j9jIU5bJ8yBKuB2VhpFV7Ab6G2XkBjv9r9Zzw==" }, "@types/node-fetch": { "version": "2.6.4", From 371906b5c531521756b3d2bf96dd1986345f4208 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jul 2023 15:15:34 +0200 Subject: [PATCH 0394/1076] build(deps-dev): bump eslint from 8.43.0 to 8.44.0 in /stake-pool/js (#4672) Bumps [eslint](https://github.com/eslint/eslint) from 8.43.0 to 8.44.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.43.0...v8.44.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 119 ++++++++++++++++------------ 1 file changed, 67 insertions(+), 52 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 6d6f03b5..d6bd4724 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -44,6 +44,15 @@ "typescript": "^4.5.4" } }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@ampproject/remapping": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.0.tgz", @@ -685,14 +694,14 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", - "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz", + "integrity": "sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.5.2", + "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -708,9 +717,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.43.0.tgz", - "integrity": "sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg==", + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz", + "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1984,9 +1993,9 @@ "dev": true }, "node_modules/acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz", + "integrity": "sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -2985,15 +2994,15 @@ } }, "node_modules/eslint": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.43.0.tgz", - "integrity": "sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q==", + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.44.0.tgz", + "integrity": "sha512-0wpHoUbDUHgNCyvFB5aXLiQVfK9B0at6gUvzy83k4kAsQ/u769TQDX6iKC+aO4upIHO9WSaA3QoXYQDHbNwf1A==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.3", - "@eslint/js": "8.43.0", + "@eslint/eslintrc": "^2.1.0", + "@eslint/js": "8.44.0", "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -3005,7 +3014,7 @@ "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.2.0", "eslint-visitor-keys": "^3.4.1", - "espree": "^9.5.2", + "espree": "^9.6.0", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -3025,7 +3034,7 @@ "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" @@ -3185,12 +3194,12 @@ } }, "node_modules/espree": { - "version": "9.5.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", - "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.0.tgz", + "integrity": "sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==", "dev": true, "dependencies": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" }, @@ -5231,17 +5240,17 @@ } }, "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" }, "engines": { "node": ">= 0.8.0" @@ -6722,6 +6731,12 @@ } }, "dependencies": { + "@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true + }, "@ampproject/remapping": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.0.tgz", @@ -7204,14 +7219,14 @@ "dev": true }, "@eslint/eslintrc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", - "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz", + "integrity": "sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.5.2", + "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -7221,9 +7236,9 @@ } }, "@eslint/js": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.43.0.tgz", - "integrity": "sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg==", + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz", + "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==", "dev": true }, "@humanwhocodes/config-array": { @@ -8147,9 +8162,9 @@ "dev": true }, "acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz", + "integrity": "sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==", "dev": true }, "acorn-globals": { @@ -8894,15 +8909,15 @@ } }, "eslint": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.43.0.tgz", - "integrity": "sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q==", + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.44.0.tgz", + "integrity": "sha512-0wpHoUbDUHgNCyvFB5aXLiQVfK9B0at6gUvzy83k4kAsQ/u769TQDX6iKC+aO4upIHO9WSaA3QoXYQDHbNwf1A==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.3", - "@eslint/js": "8.43.0", + "@eslint/eslintrc": "^2.1.0", + "@eslint/js": "8.44.0", "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -8914,7 +8929,7 @@ "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.2.0", "eslint-visitor-keys": "^3.4.1", - "espree": "^9.5.2", + "espree": "^9.6.0", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -8934,7 +8949,7 @@ "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" @@ -9028,12 +9043,12 @@ "dev": true }, "espree": { - "version": "9.5.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", - "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.0.tgz", + "integrity": "sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==", "dev": true, "requires": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" } @@ -10593,17 +10608,17 @@ } }, "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "requires": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" } }, "p-limit": { From 543d4f297e924e5fdde58816712f1ab6389bf46b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Jul 2023 18:14:37 +0200 Subject: [PATCH 0395/1076] build(deps): bump serde from 1.0.164 to 1.0.166 (#4680) * build(deps): bump serde from 1.0.164 to 1.0.166 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.164 to 1.0.166. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.164...v1.0.166) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Update Cargo.lock --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index ff95defd..7e56613a 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "0.7.0" [dependencies] borsh = "0.10" clap = "2.33.3" -serde = "1.0.164" +serde = "1.0.166" serde_derive = "1.0.130" serde_json = "1.0.99" solana-account-decoder = "=1.16.1" diff --git a/program/Cargo.toml b/program/Cargo.toml index f0e0ee54..b55f798a 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,7 +17,7 @@ borsh = "0.10" num-derive = "0.4" num-traits = "0.2" num_enum = "0.6.1" -serde = "1.0.164" +serde = "1.0.166" serde_derive = "1.0.103" solana-program = "1.16.1" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } From 5ad233ec60f46a7e58f5b3572bd04a8cae441a3a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Jul 2023 18:15:36 +0200 Subject: [PATCH 0396/1076] build(deps-dev): bump @typescript-eslint/parser from 5.60.1 to 5.61.0 in /stake-pool/js (#4688) build(deps-dev): bump @typescript-eslint/parser in /stake-pool/js Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.60.1 to 5.61.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.61.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 141 +++++++++++++++++++++++++--- 1 file changed, 129 insertions(+), 12 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index d6bd4724..08f608ee 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1833,14 +1833,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.60.1.tgz", - "integrity": "sha512-pHWlc3alg2oSMGwsU/Is8hbm3XFbcrb6P5wIxcQW9NsYBfnrubl/GhVVD/Jm/t8HXhA2WncoIRfBtnCgRGV96Q==", + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.61.0.tgz", + "integrity": "sha512-yGr4Sgyh8uO6fSi9hw3jAFXNBHbCtKKFMdX2IkT3ZqpKmtAq3lHS4ixB/COFuAIJpwl9/AqF7j72ZDWYKmIfvg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.60.1", - "@typescript-eslint/types": "5.60.1", - "@typescript-eslint/typescript-estree": "5.60.1", + "@typescript-eslint/scope-manager": "5.61.0", + "@typescript-eslint/types": "5.61.0", + "@typescript-eslint/typescript-estree": "5.61.0", "debug": "^4.3.4" }, "engines": { @@ -1859,6 +1859,80 @@ } } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.61.0.tgz", + "integrity": "sha512-W8VoMjoSg7f7nqAROEmTt6LoBpn81AegP7uKhhW5KzYlehs8VV0ZW0fIDVbcZRcaP3aPSW+JZFua+ysQN+m/Nw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.61.0", + "@typescript-eslint/visitor-keys": "5.61.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.61.0.tgz", + "integrity": "sha512-ldyueo58KjngXpzloHUog/h9REmHl59G1b3a5Sng1GfBo14BkS3ZbMEb3693gnP1k//97lh7bKsp6/V/0v1veQ==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.61.0.tgz", + "integrity": "sha512-Fud90PxONnnLZ36oR5ClJBLTLfU4pIWBmnvGwTbEa2cXIqj70AEDEmOmpkFComjBZ/037ueKrOdHuYmSFVD7Rw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.61.0", + "@typescript-eslint/visitor-keys": "5.61.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.61.0.tgz", + "integrity": "sha512-50XQ5VdbWrX06mQXhy93WywSFZZGsv3EOjq+lqp6WC2t+j3mb6A9xYVdrRxafvK88vg9k9u+CT4l6D8PEatjKg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.61.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "5.60.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.60.1.tgz", @@ -8075,15 +8149,58 @@ } }, "@typescript-eslint/parser": { - "version": "5.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.60.1.tgz", - "integrity": "sha512-pHWlc3alg2oSMGwsU/Is8hbm3XFbcrb6P5wIxcQW9NsYBfnrubl/GhVVD/Jm/t8HXhA2WncoIRfBtnCgRGV96Q==", + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.61.0.tgz", + "integrity": "sha512-yGr4Sgyh8uO6fSi9hw3jAFXNBHbCtKKFMdX2IkT3ZqpKmtAq3lHS4ixB/COFuAIJpwl9/AqF7j72ZDWYKmIfvg==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.60.1", - "@typescript-eslint/types": "5.60.1", - "@typescript-eslint/typescript-estree": "5.60.1", + "@typescript-eslint/scope-manager": "5.61.0", + "@typescript-eslint/types": "5.61.0", + "@typescript-eslint/typescript-estree": "5.61.0", "debug": "^4.3.4" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.61.0.tgz", + "integrity": "sha512-W8VoMjoSg7f7nqAROEmTt6LoBpn81AegP7uKhhW5KzYlehs8VV0ZW0fIDVbcZRcaP3aPSW+JZFua+ysQN+m/Nw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.61.0", + "@typescript-eslint/visitor-keys": "5.61.0" + } + }, + "@typescript-eslint/types": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.61.0.tgz", + "integrity": "sha512-ldyueo58KjngXpzloHUog/h9REmHl59G1b3a5Sng1GfBo14BkS3ZbMEb3693gnP1k//97lh7bKsp6/V/0v1veQ==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.61.0.tgz", + "integrity": "sha512-Fud90PxONnnLZ36oR5ClJBLTLfU4pIWBmnvGwTbEa2cXIqj70AEDEmOmpkFComjBZ/037ueKrOdHuYmSFVD7Rw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.61.0", + "@typescript-eslint/visitor-keys": "5.61.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.61.0.tgz", + "integrity": "sha512-50XQ5VdbWrX06mQXhy93WywSFZZGsv3EOjq+lqp6WC2t+j3mb6A9xYVdrRxafvK88vg9k9u+CT4l6D8PEatjKg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.61.0", + "eslint-visitor-keys": "^3.3.0" + } + } } }, "@typescript-eslint/scope-manager": { From feea2b3b43db0d20f19dbe839bbd0f001aba0850 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Jul 2023 21:31:03 +0200 Subject: [PATCH 0397/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 5.60.1 to 5.61.0 in /stake-pool/js (#4689) build(deps-dev): bump @typescript-eslint/eslint-plugin in /stake-pool/js Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 5.60.1 to 5.61.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.61.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 261 +++++++--------------------- 1 file changed, 66 insertions(+), 195 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 08f608ee..0d66df1e 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1799,17 +1799,17 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.60.1.tgz", - "integrity": "sha512-KSWsVvsJsLJv3c4e73y/Bzt7OpqMCADUO846bHcuWYSYM19bldbAeDv7dYyV0jwkbMfJ2XdlzwjhXtuD7OY6bw==", + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.61.0.tgz", + "integrity": "sha512-A5l/eUAug103qtkwccSCxn8ZRwT+7RXWkFECdA4Cvl1dOlDUgTpAOfSEElZn2uSUxhdDpnCdetrf0jvU4qrL+g==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.60.1", - "@typescript-eslint/type-utils": "5.60.1", - "@typescript-eslint/utils": "5.60.1", + "@typescript-eslint/scope-manager": "5.61.0", + "@typescript-eslint/type-utils": "5.61.0", + "@typescript-eslint/utils": "5.61.0", "debug": "^4.3.4", - "grapheme-splitter": "^1.0.4", + "graphemer": "^1.4.0", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", "semver": "^7.3.7", @@ -1859,7 +1859,7 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "node_modules/@typescript-eslint/scope-manager": { "version": "5.61.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.61.0.tgz", "integrity": "sha512-W8VoMjoSg7f7nqAROEmTt6LoBpn81AegP7uKhhW5KzYlehs8VV0ZW0fIDVbcZRcaP3aPSW+JZFua+ysQN+m/Nw==", @@ -1876,88 +1876,14 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "5.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.61.0.tgz", - "integrity": "sha512-ldyueo58KjngXpzloHUog/h9REmHl59G1b3a5Sng1GfBo14BkS3ZbMEb3693gnP1k//97lh7bKsp6/V/0v1veQ==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.61.0.tgz", - "integrity": "sha512-Fud90PxONnnLZ36oR5ClJBLTLfU4pIWBmnvGwTbEa2cXIqj70AEDEmOmpkFComjBZ/037ueKrOdHuYmSFVD7Rw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.61.0", - "@typescript-eslint/visitor-keys": "5.61.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.61.0.tgz", - "integrity": "sha512-50XQ5VdbWrX06mQXhy93WywSFZZGsv3EOjq+lqp6WC2t+j3mb6A9xYVdrRxafvK88vg9k9u+CT4l6D8PEatjKg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.61.0", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.60.1.tgz", - "integrity": "sha512-Dn/LnN7fEoRD+KspEOV0xDMynEmR3iSHdgNsarlXNLGGtcUok8L4N71dxUgt3YvlO8si7E+BJ5Fe3wb5yUw7DQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.60.1", - "@typescript-eslint/visitor-keys": "5.60.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.60.1.tgz", - "integrity": "sha512-vN6UztYqIu05nu7JqwQGzQKUJctzs3/Hg7E2Yx8rz9J+4LgtIDFWjjl1gm3pycH0P3mHAcEUBd23LVgfrsTR8A==", + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.61.0.tgz", + "integrity": "sha512-kk8u//r+oVK2Aj3ph/26XdH0pbAkC2RiSjUYhKD+PExemG4XSjpGFeyZ/QM8lBOa7O8aGOU+/yEbMJgQv/DnCg==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.60.1", - "@typescript-eslint/utils": "5.60.1", + "@typescript-eslint/typescript-estree": "5.61.0", + "@typescript-eslint/utils": "5.61.0", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -1978,9 +1904,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.60.1.tgz", - "integrity": "sha512-zDcDx5fccU8BA0IDZc71bAtYIcG9PowaOwaD8rjYbqwK7dpe/UMQl3inJ4UtUK42nOCT41jTSCwg76E62JpMcg==", + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.61.0.tgz", + "integrity": "sha512-ldyueo58KjngXpzloHUog/h9REmHl59G1b3a5Sng1GfBo14BkS3ZbMEb3693gnP1k//97lh7bKsp6/V/0v1veQ==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1991,13 +1917,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.1.tgz", - "integrity": "sha512-hkX70J9+2M2ZT6fhti5Q2FoU9zb+GeZK2SLP1WZlvUDqdMbEKhexZODD1WodNRyO8eS+4nScvT0dts8IdaBzfw==", + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.61.0.tgz", + "integrity": "sha512-Fud90PxONnnLZ36oR5ClJBLTLfU4pIWBmnvGwTbEa2cXIqj70AEDEmOmpkFComjBZ/037ueKrOdHuYmSFVD7Rw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.60.1", - "@typescript-eslint/visitor-keys": "5.60.1", + "@typescript-eslint/types": "5.61.0", + "@typescript-eslint/visitor-keys": "5.61.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2018,17 +1944,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.60.1.tgz", - "integrity": "sha512-tiJ7FFdFQOWssFa3gqb94Ilexyw0JVxj6vBzaSpfN/8IhoKkDuSAenUKvsSHw2A/TMpJb26izIszTXaqygkvpQ==", + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.61.0.tgz", + "integrity": "sha512-mV6O+6VgQmVE6+xzlA91xifndPW9ElFW8vbSF0xCT/czPXVhwDewKila1jOyRwa9AE19zKnrr7Cg5S3pJVrTWQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.60.1", - "@typescript-eslint/types": "5.60.1", - "@typescript-eslint/typescript-estree": "5.60.1", + "@typescript-eslint/scope-manager": "5.61.0", + "@typescript-eslint/types": "5.61.0", + "@typescript-eslint/typescript-estree": "5.61.0", "eslint-scope": "^5.1.1", "semver": "^7.3.7" }, @@ -2044,12 +1970,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.1.tgz", - "integrity": "sha512-xEYIxKcultP6E/RMKqube11pGjXH1DCo60mQoWhVYyKfLkwbIVVjYxmOenNMxILx0TjCujPTjjnTIVzm09TXIw==", + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.61.0.tgz", + "integrity": "sha512-50XQ5VdbWrX06mQXhy93WywSFZZGsv3EOjq+lqp6WC2t+j3mb6A9xYVdrRxafvK88vg9k9u+CT4l6D8PEatjKg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.60.1", + "@typescript-eslint/types": "5.61.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -3754,12 +3680,6 @@ "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", "dev": true }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true - }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -8131,17 +8051,17 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.60.1.tgz", - "integrity": "sha512-KSWsVvsJsLJv3c4e73y/Bzt7OpqMCADUO846bHcuWYSYM19bldbAeDv7dYyV0jwkbMfJ2XdlzwjhXtuD7OY6bw==", + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.61.0.tgz", + "integrity": "sha512-A5l/eUAug103qtkwccSCxn8ZRwT+7RXWkFECdA4Cvl1dOlDUgTpAOfSEElZn2uSUxhdDpnCdetrf0jvU4qrL+g==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.60.1", - "@typescript-eslint/type-utils": "5.60.1", - "@typescript-eslint/utils": "5.60.1", + "@typescript-eslint/scope-manager": "5.61.0", + "@typescript-eslint/type-utils": "5.61.0", + "@typescript-eslint/utils": "5.61.0", "debug": "^4.3.4", - "grapheme-splitter": "^1.0.4", + "graphemer": "^1.4.0", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", "semver": "^7.3.7", @@ -8158,87 +8078,44 @@ "@typescript-eslint/types": "5.61.0", "@typescript-eslint/typescript-estree": "5.61.0", "debug": "^4.3.4" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "5.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.61.0.tgz", - "integrity": "sha512-W8VoMjoSg7f7nqAROEmTt6LoBpn81AegP7uKhhW5KzYlehs8VV0ZW0fIDVbcZRcaP3aPSW+JZFua+ysQN+m/Nw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.61.0", - "@typescript-eslint/visitor-keys": "5.61.0" - } - }, - "@typescript-eslint/types": { - "version": "5.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.61.0.tgz", - "integrity": "sha512-ldyueo58KjngXpzloHUog/h9REmHl59G1b3a5Sng1GfBo14BkS3ZbMEb3693gnP1k//97lh7bKsp6/V/0v1veQ==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.61.0.tgz", - "integrity": "sha512-Fud90PxONnnLZ36oR5ClJBLTLfU4pIWBmnvGwTbEa2cXIqj70AEDEmOmpkFComjBZ/037ueKrOdHuYmSFVD7Rw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.61.0", - "@typescript-eslint/visitor-keys": "5.61.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.61.0.tgz", - "integrity": "sha512-50XQ5VdbWrX06mQXhy93WywSFZZGsv3EOjq+lqp6WC2t+j3mb6A9xYVdrRxafvK88vg9k9u+CT4l6D8PEatjKg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.61.0", - "eslint-visitor-keys": "^3.3.0" - } - } } }, "@typescript-eslint/scope-manager": { - "version": "5.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.60.1.tgz", - "integrity": "sha512-Dn/LnN7fEoRD+KspEOV0xDMynEmR3iSHdgNsarlXNLGGtcUok8L4N71dxUgt3YvlO8si7E+BJ5Fe3wb5yUw7DQ==", + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.61.0.tgz", + "integrity": "sha512-W8VoMjoSg7f7nqAROEmTt6LoBpn81AegP7uKhhW5KzYlehs8VV0ZW0fIDVbcZRcaP3aPSW+JZFua+ysQN+m/Nw==", "dev": true, "requires": { - "@typescript-eslint/types": "5.60.1", - "@typescript-eslint/visitor-keys": "5.60.1" + "@typescript-eslint/types": "5.61.0", + "@typescript-eslint/visitor-keys": "5.61.0" } }, "@typescript-eslint/type-utils": { - "version": "5.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.60.1.tgz", - "integrity": "sha512-vN6UztYqIu05nu7JqwQGzQKUJctzs3/Hg7E2Yx8rz9J+4LgtIDFWjjl1gm3pycH0P3mHAcEUBd23LVgfrsTR8A==", + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.61.0.tgz", + "integrity": "sha512-kk8u//r+oVK2Aj3ph/26XdH0pbAkC2RiSjUYhKD+PExemG4XSjpGFeyZ/QM8lBOa7O8aGOU+/yEbMJgQv/DnCg==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.60.1", - "@typescript-eslint/utils": "5.60.1", + "@typescript-eslint/typescript-estree": "5.61.0", + "@typescript-eslint/utils": "5.61.0", "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.60.1.tgz", - "integrity": "sha512-zDcDx5fccU8BA0IDZc71bAtYIcG9PowaOwaD8rjYbqwK7dpe/UMQl3inJ4UtUK42nOCT41jTSCwg76E62JpMcg==", + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.61.0.tgz", + "integrity": "sha512-ldyueo58KjngXpzloHUog/h9REmHl59G1b3a5Sng1GfBo14BkS3ZbMEb3693gnP1k//97lh7bKsp6/V/0v1veQ==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.1.tgz", - "integrity": "sha512-hkX70J9+2M2ZT6fhti5Q2FoU9zb+GeZK2SLP1WZlvUDqdMbEKhexZODD1WodNRyO8eS+4nScvT0dts8IdaBzfw==", + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.61.0.tgz", + "integrity": "sha512-Fud90PxONnnLZ36oR5ClJBLTLfU4pIWBmnvGwTbEa2cXIqj70AEDEmOmpkFComjBZ/037ueKrOdHuYmSFVD7Rw==", "dev": true, "requires": { - "@typescript-eslint/types": "5.60.1", - "@typescript-eslint/visitor-keys": "5.60.1", + "@typescript-eslint/types": "5.61.0", + "@typescript-eslint/visitor-keys": "5.61.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -8247,28 +8124,28 @@ } }, "@typescript-eslint/utils": { - "version": "5.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.60.1.tgz", - "integrity": "sha512-tiJ7FFdFQOWssFa3gqb94Ilexyw0JVxj6vBzaSpfN/8IhoKkDuSAenUKvsSHw2A/TMpJb26izIszTXaqygkvpQ==", + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.61.0.tgz", + "integrity": "sha512-mV6O+6VgQmVE6+xzlA91xifndPW9ElFW8vbSF0xCT/czPXVhwDewKila1jOyRwa9AE19zKnrr7Cg5S3pJVrTWQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.60.1", - "@typescript-eslint/types": "5.60.1", - "@typescript-eslint/typescript-estree": "5.60.1", + "@typescript-eslint/scope-manager": "5.61.0", + "@typescript-eslint/types": "5.61.0", + "@typescript-eslint/typescript-estree": "5.61.0", "eslint-scope": "^5.1.1", "semver": "^7.3.7" } }, "@typescript-eslint/visitor-keys": { - "version": "5.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.1.tgz", - "integrity": "sha512-xEYIxKcultP6E/RMKqube11pGjXH1DCo60mQoWhVYyKfLkwbIVVjYxmOenNMxILx0TjCujPTjjnTIVzm09TXIw==", + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.61.0.tgz", + "integrity": "sha512-50XQ5VdbWrX06mQXhy93WywSFZZGsv3EOjq+lqp6WC2t+j3mb6A9xYVdrRxafvK88vg9k9u+CT4l6D8PEatjKg==", "dev": true, "requires": { - "@typescript-eslint/types": "5.60.1", + "@typescript-eslint/types": "5.61.0", "eslint-visitor-keys": "^3.3.0" } }, @@ -9528,12 +9405,6 @@ "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", "dev": true }, - "grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true - }, "graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", From 5c0bccb27cb63685b795a80d126f4cc6632ca0d3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Jul 2023 13:20:33 +0200 Subject: [PATCH 0398/1076] build(deps): bump serde_json from 1.0.99 to 1.0.100 (#4695) * build(deps): bump serde_json from 1.0.99 to 1.0.100 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.99 to 1.0.100. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.99...v1.0.100) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Update Cargo.lock --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 7e56613a..e7b03a73 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ borsh = "0.10" clap = "2.33.3" serde = "1.0.166" serde_derive = "1.0.130" -serde_json = "1.0.99" +serde_json = "1.0.100" solana-account-decoder = "=1.16.1" solana-clap-utils = "=1.16.1" solana-cli-config = "=1.16.1" From b61e5edc63d285474dcf651f356fc2009dda94e7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Jul 2023 12:51:03 +0200 Subject: [PATCH 0399/1076] build(deps-dev): bump prettier from 2.8.8 to 3.0.0 in /stake-pool/js (#4699) * build(deps-dev): bump prettier from 2.8.8 to 3.0.0 in /stake-pool/js Bumps [prettier](https://github.com/prettier/prettier) from 2.8.8 to 3.0.0. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/2.8.8...3.0.0) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Update eslint-plugin-prettier --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/js-legacy/package-lock.json | 621 ++++++++++++++++++++++++++-- clients/js-legacy/package.json | 4 +- 2 files changed, 590 insertions(+), 35 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 0d66df1e..e0291b7d 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -32,9 +32,9 @@ "cross-env": "^7.0.3", "eslint": "^8.40.0", "eslint-config-prettier": "^8.8.0", - "eslint-plugin-prettier": "^4.2.1", + "eslint-plugin-prettier": "^5.0.0-alpha.1", "jest": "^27.5.1", - "prettier": "^2.8.8", + "prettier": "^3.0.0", "rimraf": "^5.0.0", "rollup": "^2.66.1", "rollup-plugin-dts": "^4.2.3", @@ -1293,6 +1293,26 @@ "node": ">=14" } }, + "node_modules/@pkgr/utils": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.1.tgz", + "integrity": "sha512-JOqwkgFEyi+OROIyq7l4Jy28h/WwhDnG/cPkXG2Z1iFbubB6jsHW1NDvmyOzTBxHr3yg68YGirmh1JUgMqa+9w==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "fast-glob": "^3.2.12", + "is-glob": "^4.0.3", + "open": "^9.1.0", + "picocolors": "^1.0.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, "node_modules/@rollup/plugin-alias": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.0.0.tgz", @@ -2295,6 +2315,15 @@ } ] }, + "node_modules/big-integer": { + "version": "1.6.51", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", + "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, "node_modules/bigint-buffer": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/bigint-buffer/-/bigint-buffer-1.1.5.tgz", @@ -2338,6 +2367,18 @@ "text-encoding-utf-8": "^1.0.2" } }, + "node_modules/bplist-parser": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz", + "integrity": "sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==", + "dev": true, + "dependencies": { + "big-integer": "^1.6.44" + }, + "engines": { + "node": ">= 5.10.0" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -2480,6 +2521,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/bundle-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", + "integrity": "sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==", + "dev": true, + "dependencies": { + "run-applescript": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -2747,6 +2803,162 @@ "node": ">=0.10.0" } }, + "node_modules/default-browser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz", + "integrity": "sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==", + "dev": true, + "dependencies": { + "bundle-name": "^3.0.0", + "default-browser-id": "^3.0.0", + "execa": "^7.1.1", + "titleize": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz", + "integrity": "sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==", + "dev": true, + "dependencies": { + "bplist-parser": "^0.2.0", + "untildify": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser/node_modules/execa": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-7.1.1.tgz", + "integrity": "sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.1", + "human-signals": "^4.3.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^3.0.7", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": "^14.18.0 || ^16.14.0 || >=18.0.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/default-browser/node_modules/human-signals": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", + "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", + "dev": true, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/default-browser/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser/node_modules/npm-run-path": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", + "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/delay": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", @@ -3062,21 +3274,29 @@ } }, "node_modules/eslint-plugin-prettier": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", - "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", + "version": "5.0.0-alpha.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.0-alpha.2.tgz", + "integrity": "sha512-F6YBCbrRzvZwcINw3crm1+/uX/i+rJYaFErPtwCfUoPLywRfY7pwBtI3yMe5OpIotuaiws8cd29oM80ca6NQSQ==", "dev": true, "dependencies": { - "prettier-linter-helpers": "^1.0.0" + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.8.5" }, "engines": { - "node": ">=12.0.0" + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/prettier" }, "peerDependencies": { - "eslint": ">=7.28.0", - "prettier": ">=2.0.0" + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "prettier": ">=3.0.0" }, "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, "eslint-config-prettier": { "optional": true } @@ -3362,9 +3582,9 @@ "dev": true }, "node_modules/fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.0.tgz", + "integrity": "sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -3902,6 +4122,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -3941,6 +4176,24 @@ "node": ">=0.10.0" } }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", @@ -3998,6 +4251,33 @@ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-wsl/node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -5233,6 +5513,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/open": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-9.1.0.tgz", + "integrity": "sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==", + "dev": true, + "dependencies": { + "default-browser": "^4.0.0", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -5438,15 +5736,15 @@ } }, "node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.0.tgz", + "integrity": "sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==", "dev": true, "bin": { - "prettier": "bin-prettier.js" + "prettier": "bin/prettier.cjs" }, "engines": { - "node": ">=10.13.0" + "node": ">=14" }, "funding": { "url": "https://github.com/prettier/prettier?sponsor=1" @@ -5856,6 +6154,21 @@ } } }, + "node_modules/run-applescript": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz", + "integrity": "sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==", + "dev": true, + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -6179,6 +6492,22 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, + "node_modules/synckit": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.5.tgz", + "integrity": "sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==", + "dev": true, + "dependencies": { + "@pkgr/utils": "^2.3.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, "node_modules/terminal-link": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", @@ -6249,6 +6578,18 @@ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" }, + "node_modules/titleize": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz", + "integrity": "sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -6350,9 +6691,7 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "node_modules/tsutils": { "version": "3.21.0", @@ -6439,6 +6778,15 @@ "node": ">= 4.0.0" } }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -7666,6 +8014,20 @@ "dev": true, "optional": true }, + "@pkgr/utils": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.1.tgz", + "integrity": "sha512-JOqwkgFEyi+OROIyq7l4Jy28h/WwhDnG/cPkXG2Z1iFbubB6jsHW1NDvmyOzTBxHr3yg68YGirmh1JUgMqa+9w==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "fast-glob": "^3.2.12", + "is-glob": "^4.0.3", + "open": "^9.1.0", + "picocolors": "^1.0.0", + "tslib": "^2.5.0" + } + }, "@rollup/plugin-alias": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.0.0.tgz", @@ -8373,6 +8735,12 @@ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, + "big-integer": { + "version": "1.6.51", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", + "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", + "dev": true + }, "bigint-buffer": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/bigint-buffer/-/bigint-buffer-1.1.5.tgz", @@ -8409,6 +8777,15 @@ "text-encoding-utf-8": "^1.0.2" } }, + "bplist-parser": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz", + "integrity": "sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==", + "dev": true, + "requires": { + "big-integer": "^1.6.44" + } + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -8508,6 +8885,15 @@ "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", "dev": true }, + "bundle-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", + "integrity": "sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==", + "dev": true, + "requires": { + "run-applescript": "^5.0.0" + } + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -8721,6 +9107,101 @@ "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", "dev": true }, + "default-browser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz", + "integrity": "sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==", + "dev": true, + "requires": { + "bundle-name": "^3.0.0", + "default-browser-id": "^3.0.0", + "execa": "^7.1.1", + "titleize": "^3.0.0" + }, + "dependencies": { + "execa": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-7.1.1.tgz", + "integrity": "sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.1", + "human-signals": "^4.3.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^3.0.7", + "strip-final-newline": "^3.0.0" + } + }, + "human-signals": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", + "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", + "dev": true + }, + "is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true + }, + "mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true + }, + "npm-run-path": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", + "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", + "dev": true, + "requires": { + "path-key": "^4.0.0" + } + }, + "onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "requires": { + "mimic-fn": "^4.0.0" + } + }, + "path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true + }, + "strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true + } + } + }, + "default-browser-id": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz", + "integrity": "sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==", + "dev": true, + "requires": { + "bplist-parser": "^0.2.0", + "untildify": "^4.0.0" + } + }, + "define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true + }, "delay": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", @@ -9012,12 +9493,13 @@ "requires": {} }, "eslint-plugin-prettier": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", - "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", + "version": "5.0.0-alpha.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.0-alpha.2.tgz", + "integrity": "sha512-F6YBCbrRzvZwcINw3crm1+/uX/i+rJYaFErPtwCfUoPLywRfY7pwBtI3yMe5OpIotuaiws8cd29oM80ca6NQSQ==", "dev": true, "requires": { - "prettier-linter-helpers": "^1.0.0" + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.8.5" } }, "eslint-scope": { @@ -9163,9 +9645,9 @@ "dev": true }, "fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.0.tgz", + "integrity": "sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -9562,6 +10044,12 @@ "has": "^1.0.3" } }, + "is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true + }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -9589,6 +10077,15 @@ "is-extglob": "^2.1.1" } }, + "is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "requires": { + "is-docker": "^3.0.0" + } + }, "is-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", @@ -9634,6 +10131,23 @@ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "requires": { + "is-docker": "^2.0.0" + }, + "dependencies": { + "is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true + } + } + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -10595,6 +11109,18 @@ "mimic-fn": "^2.1.0" } }, + "open": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-9.1.0.tgz", + "integrity": "sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==", + "dev": true, + "requires": { + "default-browser": "^4.0.0", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^2.2.0" + } + }, "optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -10742,9 +11268,9 @@ "dev": true }, "prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.0.tgz", + "integrity": "sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==", "dev": true }, "prettier-linter-helpers": { @@ -11038,6 +11564,15 @@ } } }, + "run-applescript": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz", + "integrity": "sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==", + "dev": true, + "requires": { + "execa": "^5.0.0" + } + }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -11267,6 +11802,16 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, + "synckit": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.5.tgz", + "integrity": "sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==", + "dev": true, + "requires": { + "@pkgr/utils": "^2.3.1", + "tslib": "^2.5.0" + } + }, "terminal-link": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", @@ -11322,6 +11867,12 @@ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" }, + "titleize": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz", + "integrity": "sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==", + "dev": true + }, "tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -11383,9 +11934,7 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "tsutils": { "version": "3.21.0", @@ -11446,6 +11995,12 @@ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true }, + "untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true + }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 85546a95..95875679 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -67,9 +67,9 @@ "cross-env": "^7.0.3", "eslint": "^8.40.0", "eslint-config-prettier": "^8.8.0", - "eslint-plugin-prettier": "^4.2.1", + "eslint-plugin-prettier": "^5.0.0-alpha.1", "jest": "^27.5.1", - "prettier": "^2.8.8", + "prettier": "^3.0.0", "rimraf": "^5.0.0", "rollup": "^2.66.1", "rollup-plugin-dts": "^4.2.3", From 3a55900a452bcb97868ff84af783a419a5e69b46 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Jul 2023 16:25:03 +0200 Subject: [PATCH 0400/1076] build(deps-dev): bump @types/node from 20.3.3 to 20.4.0 in /stake-pool/js (#4714) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.3.3 to 20.4.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index e0291b7d..c828fcc1 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1757,9 +1757,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.3.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.3.tgz", - "integrity": "sha512-wheIYdr4NYML61AjC8MKj/2jrR/kDQri/CIpVoZwldwhnIrD/j9jIU5bJ8yBKuB2VhpFV7Ab6G2XkBjv9r9Zzw==" + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.0.tgz", + "integrity": "sha512-jfT7iTf/4kOQ9S7CHV9BIyRaQqHu67mOjsIQBC3BKZvzvUB6zLxEwJ6sBE3ozcvP8kF6Uk5PXN0Q+c0dfhGX0g==" }, "node_modules/@types/node-fetch": { "version": "2.6.4", @@ -8351,9 +8351,9 @@ "dev": true }, "@types/node": { - "version": "20.3.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.3.tgz", - "integrity": "sha512-wheIYdr4NYML61AjC8MKj/2jrR/kDQri/CIpVoZwldwhnIrD/j9jIU5bJ8yBKuB2VhpFV7Ab6G2XkBjv9r9Zzw==" + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.0.tgz", + "integrity": "sha512-jfT7iTf/4kOQ9S7CHV9BIyRaQqHu67mOjsIQBC3BKZvzvUB6zLxEwJ6sBE3ozcvP8kF6Uk5PXN0Q+c0dfhGX0g==" }, "@types/node-fetch": { "version": "2.6.4", From 93c67cb6e2556c1a25a77b7fe99b8aa004f6ebd5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Jul 2023 14:00:29 +0200 Subject: [PATCH 0401/1076] build(deps): bump serde from 1.0.166 to 1.0.167 (#4722) * build(deps): bump serde from 1.0.166 to 1.0.167 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.166 to 1.0.167. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.166...v1.0.167) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Update Cargo.lock --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index e7b03a73..b031d595 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "0.7.0" [dependencies] borsh = "0.10" clap = "2.33.3" -serde = "1.0.166" +serde = "1.0.167" serde_derive = "1.0.130" serde_json = "1.0.100" solana-account-decoder = "=1.16.1" diff --git a/program/Cargo.toml b/program/Cargo.toml index b55f798a..396405eb 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,7 +17,7 @@ borsh = "0.10" num-derive = "0.4" num-traits = "0.2" num_enum = "0.6.1" -serde = "1.0.166" +serde = "1.0.167" serde_derive = "1.0.103" solana-program = "1.16.1" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } From a1fc95c3c6183928e0c2c20e05195fffcef7ce17 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Jul 2023 15:02:41 +0200 Subject: [PATCH 0402/1076] build(deps): bump @solana/web3.js from 1.77.3 to 1.78.0 in /stake-pool/js (#4729) build(deps): bump @solana/web3.js in /stake-pool/js Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.77.3 to 1.78.0. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.77.3...v1.78.0) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 48 ++++++++++++++--------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index c828fcc1..0ada59c4 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -581,11 +581,11 @@ } }, "node_modules/@babel/runtime": { - "version": "7.17.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz", - "integrity": "sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz", + "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==", "dependencies": { - "regenerator-runtime": "^0.13.4" + "regenerator-runtime": "^0.13.11" }, "engines": { "node": ">=6.9.0" @@ -1613,11 +1613,11 @@ } }, "node_modules/@solana/web3.js": { - "version": "1.77.3", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.77.3.tgz", - "integrity": "sha512-PHaO0BdoiQRPpieC1p31wJsBaxwIOWLh8j2ocXNKX8boCQVldt26Jqm2tZE4KlrvnCIV78owPLv1pEUgqhxZ3w==", + "version": "1.78.0", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.78.0.tgz", + "integrity": "sha512-CSjCjo+RELJ5puoZALfznN5EF0YvL1V8NQrQYovsdjE1lCV6SqbKAIZD0+9LlqCBoa1ibuUaR7G2SooYzvzmug==", "dependencies": { - "@babel/runtime": "^7.12.5", + "@babel/runtime": "^7.22.3", "@noble/curves": "^1.0.0", "@noble/hashes": "^1.3.0", "@solana/buffer-layout": "^4.0.0", @@ -1629,7 +1629,7 @@ "buffer": "6.0.3", "fast-stable-stringify": "^1.0.0", "jayson": "^4.1.0", - "node-fetch": "^2.6.7", + "node-fetch": "^2.6.11", "rpc-websockets": "^7.5.1", "superstruct": "^0.14.2" } @@ -5852,9 +5852,9 @@ "dev": true }, "node_modules/regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" }, "node_modules/require-directory": { "version": "2.1.1", @@ -7476,11 +7476,11 @@ } }, "@babel/runtime": { - "version": "7.17.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz", - "integrity": "sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz", + "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==", "requires": { - "regenerator-runtime": "^0.13.4" + "regenerator-runtime": "^0.13.11" } }, "@babel/template": { @@ -8210,11 +8210,11 @@ } }, "@solana/web3.js": { - "version": "1.77.3", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.77.3.tgz", - "integrity": "sha512-PHaO0BdoiQRPpieC1p31wJsBaxwIOWLh8j2ocXNKX8boCQVldt26Jqm2tZE4KlrvnCIV78owPLv1pEUgqhxZ3w==", + "version": "1.78.0", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.78.0.tgz", + "integrity": "sha512-CSjCjo+RELJ5puoZALfznN5EF0YvL1V8NQrQYovsdjE1lCV6SqbKAIZD0+9LlqCBoa1ibuUaR7G2SooYzvzmug==", "requires": { - "@babel/runtime": "^7.12.5", + "@babel/runtime": "^7.22.3", "@noble/curves": "^1.0.0", "@noble/hashes": "^1.3.0", "@solana/buffer-layout": "^4.0.0", @@ -8226,7 +8226,7 @@ "buffer": "6.0.3", "fast-stable-stringify": "^1.0.0", "jayson": "^4.1.0", - "node-fetch": "^2.6.7", + "node-fetch": "^2.6.11", "rpc-websockets": "^7.5.1", "superstruct": "^0.14.2" } @@ -11345,9 +11345,9 @@ "dev": true }, "regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" }, "require-directory": { "version": "2.1.1", From 72cdf803fe6867c4f53eea4128f61ae07fe8cd74 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Jul 2023 18:18:42 +0200 Subject: [PATCH 0403/1076] build(deps-dev): bump @types/node from 20.4.0 to 20.4.1 in /stake-pool/js (#4739) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.4.0 to 20.4.1. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 0ada59c4..ae37c765 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1757,9 +1757,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.4.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.0.tgz", - "integrity": "sha512-jfT7iTf/4kOQ9S7CHV9BIyRaQqHu67mOjsIQBC3BKZvzvUB6zLxEwJ6sBE3ozcvP8kF6Uk5PXN0Q+c0dfhGX0g==" + "version": "20.4.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.1.tgz", + "integrity": "sha512-JIzsAvJeA/5iY6Y/OxZbv1lUcc8dNSE77lb2gnBH+/PJ3lFR1Ccvgwl5JWnHAkNHcRsT0TbpVOsiMKZ1F/yyJg==" }, "node_modules/@types/node-fetch": { "version": "2.6.4", @@ -8351,9 +8351,9 @@ "dev": true }, "@types/node": { - "version": "20.4.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.0.tgz", - "integrity": "sha512-jfT7iTf/4kOQ9S7CHV9BIyRaQqHu67mOjsIQBC3BKZvzvUB6zLxEwJ6sBE3ozcvP8kF6Uk5PXN0Q+c0dfhGX0g==" + "version": "20.4.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.1.tgz", + "integrity": "sha512-JIzsAvJeA/5iY6Y/OxZbv1lUcc8dNSE77lb2gnBH+/PJ3lFR1Ccvgwl5JWnHAkNHcRsT0TbpVOsiMKZ1F/yyJg==" }, "@types/node-fetch": { "version": "2.6.4", From 0d58093cbf5f001297eb8748637f85dfc77b9be6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Jul 2023 18:42:16 +0200 Subject: [PATCH 0404/1076] build(deps): bump tough-cookie from 4.0.0 to 4.1.3 in /stake-pool/js (#4734) Bumps [tough-cookie](https://github.com/salesforce/tough-cookie) from 4.0.0 to 4.1.3. - [Release notes](https://github.com/salesforce/tough-cookie/releases) - [Changelog](https://github.com/salesforce/tough-cookie/blob/master/CHANGELOG.md) - [Commits](https://github.com/salesforce/tough-cookie/compare/v4.0.0...v4.1.3) --- updated-dependencies: - dependency-name: tough-cookie dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 74 +++++++++++++++++++++++------ 1 file changed, 60 insertions(+), 14 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index ae37c765..677459e4 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -5816,6 +5816,12 @@ "node": ">=6" } }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -5865,6 +5871,12 @@ "node": ">=0.10.0" } }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, "node_modules/resolve": { "version": "1.22.2", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", @@ -6618,14 +6630,15 @@ } }, "node_modules/tough-cookie": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", - "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", + "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", "dev": true, "dependencies": { "psl": "^1.1.33", "punycode": "^2.1.1", - "universalify": "^0.1.2" + "universalify": "^0.2.0", + "url-parse": "^1.5.3" }, "engines": { "node": ">=6" @@ -6770,9 +6783,9 @@ } }, "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", "dev": true, "engines": { "node": ">= 4.0.0" @@ -6796,6 +6809,16 @@ "punycode": "^2.1.0" } }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "node_modules/utf-8-validate": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.8.tgz", @@ -11323,6 +11346,12 @@ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true }, + "querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -11355,6 +11384,12 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, "resolve": { "version": "1.22.2", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", @@ -11895,14 +11930,15 @@ } }, "tough-cookie": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", - "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", + "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", "dev": true, "requires": { "psl": "^1.1.33", "punycode": "^2.1.1", - "universalify": "^0.1.2" + "universalify": "^0.2.0", + "url-parse": "^1.5.3" } }, "tr46": { @@ -11990,9 +12026,9 @@ "dev": true }, "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", "dev": true }, "untildify": { @@ -12010,6 +12046,16 @@ "punycode": "^2.1.0" } }, + "url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "utf-8-validate": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.8.tgz", From 2f1e3befae94e39bf9f864d4acd2fbb07a38933f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Jul 2023 19:16:12 +0200 Subject: [PATCH 0405/1076] build(deps): bump serde from 1.0.167 to 1.0.168 (#4735) * build(deps): bump serde from 1.0.167 to 1.0.168 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.167 to 1.0.168. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.167...v1.0.168) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Update Cargo.lock --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index b031d595..bc3b2c29 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "0.7.0" [dependencies] borsh = "0.10" clap = "2.33.3" -serde = "1.0.167" +serde = "1.0.168" serde_derive = "1.0.130" serde_json = "1.0.100" solana-account-decoder = "=1.16.1" diff --git a/program/Cargo.toml b/program/Cargo.toml index 396405eb..60aee1bd 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,7 +17,7 @@ borsh = "0.10" num-derive = "0.4" num-traits = "0.2" num_enum = "0.6.1" -serde = "1.0.167" +serde = "1.0.168" serde_derive = "1.0.103" solana-program = "1.16.1" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } From 401918b610c45cecbe44102b8c66cc9b227a2f4e Mon Sep 17 00:00:00 2001 From: hanako mumei <81144685+2501babe@users.noreply.github.com> Date: Mon, 10 Jul 2023 13:03:40 -0700 Subject: [PATCH 0406/1076] stake-pool-cli: mark args as global --- clients/cli/src/main.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 2319c6e3..bc51c0e1 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -1940,6 +1940,7 @@ fn main() { .value_name("URL") .takes_value(true) .validator(is_url) + .global(true) .help("JSON RPC URL for the cluster. Default from the configuration file."), ) .arg( @@ -1948,6 +1949,7 @@ fn main() { .value_name("KEYPAIR") .validator(is_valid_signer) .takes_value(true) + .global(true) .help("Stake pool staker. [default: cli config keypair]"), ) .arg( @@ -1956,6 +1958,7 @@ fn main() { .value_name("KEYPAIR") .validator(is_valid_signer) .takes_value(true) + .global(true) .help("Stake pool manager. [default: cli config keypair]"), ) .arg( @@ -1964,6 +1967,7 @@ fn main() { .value_name("KEYPAIR") .validator(is_valid_signer) .takes_value(true) + .global(true) .help("Stake pool funding authority for deposits or withdrawals. [default: cli config keypair]"), ) .arg( @@ -1972,6 +1976,7 @@ fn main() { .value_name("KEYPAIR") .validator(is_valid_signer) .takes_value(true) + .global(true) .help("Owner of pool token account [default: cli config keypair]"), ) .arg( @@ -1980,6 +1985,7 @@ fn main() { .value_name("KEYPAIR") .validator(is_valid_signer) .takes_value(true) + .global(true) .help("Transaction fee payer account [default: cli config keypair]"), ) .subcommand(SubCommand::with_name("create-pool") From 1739c6ccd14616fc7e414f0dc4d31e6045107249 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Mon, 10 Jul 2023 23:48:38 +0200 Subject: [PATCH 0407/1076] token-2022: Add account-level alloc and realloc (#4661) * Add helper to get the number of bytes used in an account * Add function for calculating new account size prior to reallocation * Add test for calculating new account length due to reallocs * Add alloc_and_serialize function * Add realloc_and_serialize for existing extension * Use TLV length in `get_extension_bytes_mut`, not static length * Test realloc_and_serialize * Rename `try_calculate_account_len` * Add new const for base account and account type length * Rename to `try_get_account_len` * Update comments and variable names * Use `set_account_type` rather than directly setting the byte * Add alloc test for extended mint * Rename to `VariableLenPack`, remove `UnsizedExtension` * Update comments for unsized -> variable-len * Implement VariableLenPack on test extension * Implement "getter" and "setter" for variable-length extensions * Lock down `alloc`, remove public usage * Lock down realloc so it isn't public anymore * Rename alloc_internal -> alloc * Lock down `try_get_new_account_len` by taking the value * Address renaming value -> extension + nits * Combine alloc and realloc * Add `overwrite` flag + comment --- program/tests/helpers/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index d9145708..f6620252 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -94,7 +94,7 @@ pub async fn create_mint( ) -> Result<(), TransportError> { assert!(extension_types.is_empty() || program_id != &spl_token::id()); let rent = banks_client.get_rent().await.unwrap(); - let space = ExtensionType::try_get_account_len::(extension_types).unwrap(); + let space = ExtensionType::try_calculate_account_len::(extension_types).unwrap(); let mint_rent = rent.minimum_balance(space); let mint_pubkey = pool_mint.pubkey(); @@ -225,7 +225,7 @@ pub async fn create_token_account( extensions: &[ExtensionType], ) -> Result<(), TransportError> { let rent = banks_client.get_rent().await.unwrap(); - let space = ExtensionType::try_get_account_len::(extensions).unwrap(); + let space = ExtensionType::try_calculate_account_len::(extensions).unwrap(); let account_rent = rent.minimum_balance(space); let mut instructions = vec![system_instruction::create_account( From ad40f5cead91e1f6ba5fe7dac236f96c639e0455 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Jul 2023 17:03:49 +0200 Subject: [PATCH 0408/1076] build(deps-dev): bump eslint-plugin-prettier from 5.0.0-alpha.2 to 5.0.0 in /stake-pool/js (#4760) build(deps-dev): bump eslint-plugin-prettier in /stake-pool/js Bumps [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) from 5.0.0-alpha.2 to 5.0.0. - [Release notes](https://github.com/prettier/eslint-plugin-prettier/releases) - [Changelog](https://github.com/prettier/eslint-plugin-prettier/blob/master/CHANGELOG.md) - [Commits](https://github.com/prettier/eslint-plugin-prettier/commits/v5.0.0) --- updated-dependencies: - dependency-name: eslint-plugin-prettier dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 677459e4..f26d56cc 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -3274,9 +3274,9 @@ } }, "node_modules/eslint-plugin-prettier": { - "version": "5.0.0-alpha.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.0-alpha.2.tgz", - "integrity": "sha512-F6YBCbrRzvZwcINw3crm1+/uX/i+rJYaFErPtwCfUoPLywRfY7pwBtI3yMe5OpIotuaiws8cd29oM80ca6NQSQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.0.tgz", + "integrity": "sha512-AgaZCVuYDXHUGxj/ZGu1u8H8CYgDY3iG6w5kUFw4AzMVXzB7VvbKgYR4nATIN+OvUrghMbiDLeimVjVY5ilq3w==", "dev": true, "dependencies": { "prettier-linter-helpers": "^1.0.0", @@ -9516,9 +9516,9 @@ "requires": {} }, "eslint-plugin-prettier": { - "version": "5.0.0-alpha.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.0-alpha.2.tgz", - "integrity": "sha512-F6YBCbrRzvZwcINw3crm1+/uX/i+rJYaFErPtwCfUoPLywRfY7pwBtI3yMe5OpIotuaiws8cd29oM80ca6NQSQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.0.tgz", + "integrity": "sha512-AgaZCVuYDXHUGxj/ZGu1u8H8CYgDY3iG6w5kUFw4AzMVXzB7VvbKgYR4nATIN+OvUrghMbiDLeimVjVY5ilq3w==", "dev": true, "requires": { "prettier-linter-helpers": "^1.0.0", From f8b45682c091282ab48e2ce77bc6059d05ccb5a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Jul 2023 17:05:24 +0200 Subject: [PATCH 0409/1076] build(deps-dev): bump @typescript-eslint/parser from 5.61.0 to 5.62.0 in /stake-pool/js (#4758) build(deps-dev): bump @typescript-eslint/parser in /stake-pool/js Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.61.0 to 5.62.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.62.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 141 +++++++++++++++++++++++++--- 1 file changed, 129 insertions(+), 12 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index f26d56cc..8c5ee043 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1853,14 +1853,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.61.0.tgz", - "integrity": "sha512-yGr4Sgyh8uO6fSi9hw3jAFXNBHbCtKKFMdX2IkT3ZqpKmtAq3lHS4ixB/COFuAIJpwl9/AqF7j72ZDWYKmIfvg==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", + "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.61.0", - "@typescript-eslint/types": "5.61.0", - "@typescript-eslint/typescript-estree": "5.61.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", "debug": "^4.3.4" }, "engines": { @@ -1879,6 +1879,80 @@ } } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "5.61.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.61.0.tgz", @@ -8454,15 +8528,58 @@ } }, "@typescript-eslint/parser": { - "version": "5.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.61.0.tgz", - "integrity": "sha512-yGr4Sgyh8uO6fSi9hw3jAFXNBHbCtKKFMdX2IkT3ZqpKmtAq3lHS4ixB/COFuAIJpwl9/AqF7j72ZDWYKmIfvg==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", + "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.61.0", - "@typescript-eslint/types": "5.61.0", - "@typescript-eslint/typescript-estree": "5.61.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", "debug": "^4.3.4" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" + } + }, + "@typescript-eslint/types": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" + } + } } }, "@typescript-eslint/scope-manager": { From e7f36a2efea86e0353e08c853404f811804cab02 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Jul 2023 23:25:45 +0200 Subject: [PATCH 0410/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 5.61.0 to 6.0.0 in /stake-pool/js (#4759) * build(deps-dev): bump @typescript-eslint/eslint-plugin in /stake-pool/js Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 5.61.0 to 6.0.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.0.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Fix dependencies --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/js-legacy/package-lock.json | 442 ++++++++++------------------ clients/js-legacy/package.json | 6 +- 2 files changed, 166 insertions(+), 282 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 8c5ee043..adcba4a2 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -27,12 +27,12 @@ "@types/jest": "^27.4.0", "@types/node": "^20.1.2", "@types/node-fetch": "^2.6.3", - "@typescript-eslint/eslint-plugin": "^5.59.5", - "@typescript-eslint/parser": "^5.59.5", + "@typescript-eslint/eslint-plugin": "^6.0.0", + "@typescript-eslint/parser": "^6.0.0", "cross-env": "^7.0.3", "eslint": "^8.40.0", "eslint-config-prettier": "^8.8.0", - "eslint-plugin-prettier": "^5.0.0-alpha.1", + "eslint-plugin-prettier": "^5.0.0", "jest": "^27.5.1", "prettier": "^3.0.0", "rimraf": "^5.0.0", @@ -1819,32 +1819,35 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.61.0.tgz", - "integrity": "sha512-A5l/eUAug103qtkwccSCxn8ZRwT+7RXWkFECdA4Cvl1dOlDUgTpAOfSEElZn2uSUxhdDpnCdetrf0jvU4qrL+g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.0.0.tgz", + "integrity": "sha512-xuv6ghKGoiq856Bww/yVYnXGsKa588kY3M0XK7uUW/3fJNNULKRfZfSBkMTSpqGG/8ZCXCadfh8G/z/B4aqS/A==", "dev": true, "dependencies": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.61.0", - "@typescript-eslint/type-utils": "5.61.0", - "@typescript-eslint/utils": "5.61.0", + "@eslint-community/regexpp": "^4.5.0", + "@typescript-eslint/scope-manager": "6.0.0", + "@typescript-eslint/type-utils": "6.0.0", + "@typescript-eslint/utils": "6.0.0", + "@typescript-eslint/visitor-keys": "6.0.0", "debug": "^4.3.4", + "grapheme-splitter": "^1.0.4", "graphemer": "^1.4.0", - "ignore": "^5.2.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "semver": "^7.5.0", + "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", + "eslint": "^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -1853,25 +1856,26 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", - "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.0.0.tgz", + "integrity": "sha512-TNaufYSPrr1U8n+3xN+Yp9g31vQDJqhXzzPSHfQDLcaO4tU+mCfODPxCwf4H530zo7aUBE3QIdxCXamEnG04Tg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/scope-manager": "6.0.0", + "@typescript-eslint/types": "6.0.0", + "@typescript-eslint/typescript-estree": "6.0.0", + "@typescript-eslint/visitor-keys": "6.0.0", "debug": "^4.3.4" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "eslint": "^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -1879,91 +1883,17 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.61.0.tgz", - "integrity": "sha512-W8VoMjoSg7f7nqAROEmTt6LoBpn81AegP7uKhhW5KzYlehs8VV0ZW0fIDVbcZRcaP3aPSW+JZFua+ysQN+m/Nw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.0.0.tgz", + "integrity": "sha512-o4q0KHlgCZTqjuaZ25nw5W57NeykZT9LiMEG4do/ovwvOcPnDO1BI5BQdCsUkjxFyrCL0cSzLjvIMfR9uo7cWg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.61.0", - "@typescript-eslint/visitor-keys": "5.61.0" + "@typescript-eslint/types": "6.0.0", + "@typescript-eslint/visitor-keys": "6.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", @@ -1971,25 +1901,25 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.61.0.tgz", - "integrity": "sha512-kk8u//r+oVK2Aj3ph/26XdH0pbAkC2RiSjUYhKD+PExemG4XSjpGFeyZ/QM8lBOa7O8aGOU+/yEbMJgQv/DnCg==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.0.0.tgz", + "integrity": "sha512-ah6LJvLgkoZ/pyJ9GAdFkzeuMZ8goV6BH7eC9FPmojrnX9yNCIsfjB+zYcnex28YO3RFvBkV6rMV6WpIqkPvoQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.61.0", - "@typescript-eslint/utils": "5.61.0", + "@typescript-eslint/typescript-estree": "6.0.0", + "@typescript-eslint/utils": "6.0.0", "debug": "^4.3.4", - "tsutils": "^3.21.0" + "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "*" + "eslint": "^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -1998,12 +1928,12 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.61.0.tgz", - "integrity": "sha512-ldyueo58KjngXpzloHUog/h9REmHl59G1b3a5Sng1GfBo14BkS3ZbMEb3693gnP1k//97lh7bKsp6/V/0v1veQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.0.0.tgz", + "integrity": "sha512-Zk9KDggyZM6tj0AJWYYKgF0yQyrcnievdhG0g5FqyU3Y2DRxJn4yWY21sJC0QKBckbsdKKjYDV2yVrrEvuTgxg==", "dev": true, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", @@ -2011,21 +1941,21 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.61.0.tgz", - "integrity": "sha512-Fud90PxONnnLZ36oR5ClJBLTLfU4pIWBmnvGwTbEa2cXIqj70AEDEmOmpkFComjBZ/037ueKrOdHuYmSFVD7Rw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.0.0.tgz", + "integrity": "sha512-2zq4O7P6YCQADfmJ5OTDQTP3ktajnXIRrYAtHM9ofto/CJZV3QfJ89GEaM2BNGeSr1KgmBuLhEkz5FBkS2RQhQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.61.0", - "@typescript-eslint/visitor-keys": "5.61.0", + "@typescript-eslint/types": "6.0.0", + "@typescript-eslint/visitor-keys": "6.0.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "semver": "^7.5.0", + "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", @@ -2038,42 +1968,42 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.61.0.tgz", - "integrity": "sha512-mV6O+6VgQmVE6+xzlA91xifndPW9ElFW8vbSF0xCT/czPXVhwDewKila1jOyRwa9AE19zKnrr7Cg5S3pJVrTWQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.0.0.tgz", + "integrity": "sha512-SOr6l4NB6HE4H/ktz0JVVWNXqCJTOo/mHnvIte1ZhBQ0Cvd04x5uKZa3zT6tiodL06zf5xxdK8COiDvPnQ27JQ==", "dev": true, "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", + "@eslint-community/eslint-utils": "^4.3.0", + "@types/json-schema": "^7.0.11", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.61.0", - "@typescript-eslint/types": "5.61.0", - "@typescript-eslint/typescript-estree": "5.61.0", + "@typescript-eslint/scope-manager": "6.0.0", + "@typescript-eslint/types": "6.0.0", + "@typescript-eslint/typescript-estree": "6.0.0", "eslint-scope": "^5.1.1", - "semver": "^7.3.7" + "semver": "^7.5.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "eslint": "^7.0.0 || ^8.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.61.0.tgz", - "integrity": "sha512-50XQ5VdbWrX06mQXhy93WywSFZZGsv3EOjq+lqp6WC2t+j3mb6A9xYVdrRxafvK88vg9k9u+CT4l6D8PEatjKg==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.0.0.tgz", + "integrity": "sha512-cvJ63l8c0yXdeT5POHpL0Q1cZoRcmRKFCtSjNGJxPkcP571EfZMcNbzWAc7oK3D1dRzm/V5EwtkANTZxqvuuUA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.61.0", - "eslint-visitor-keys": "^3.3.0" + "@typescript-eslint/types": "6.0.0", + "eslint-visitor-keys": "^3.4.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", @@ -3974,6 +3904,12 @@ "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", "dev": true }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -4095,9 +4031,9 @@ ] }, "node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true, "engines": { "node": ">= 4" @@ -6730,6 +6666,18 @@ "node": ">=8" } }, + "node_modules/ts-api-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.1.tgz", + "integrity": "sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==", + "dev": true, + "engines": { + "node": ">=16.13.0" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, "node_modules/ts-jest": { "version": "27.1.3", "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.3.tgz", @@ -6780,27 +6728,6 @@ "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", "dev": true }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -8510,145 +8437,106 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.61.0.tgz", - "integrity": "sha512-A5l/eUAug103qtkwccSCxn8ZRwT+7RXWkFECdA4Cvl1dOlDUgTpAOfSEElZn2uSUxhdDpnCdetrf0jvU4qrL+g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.0.0.tgz", + "integrity": "sha512-xuv6ghKGoiq856Bww/yVYnXGsKa588kY3M0XK7uUW/3fJNNULKRfZfSBkMTSpqGG/8ZCXCadfh8G/z/B4aqS/A==", "dev": true, "requires": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.61.0", - "@typescript-eslint/type-utils": "5.61.0", - "@typescript-eslint/utils": "5.61.0", + "@eslint-community/regexpp": "^4.5.0", + "@typescript-eslint/scope-manager": "6.0.0", + "@typescript-eslint/type-utils": "6.0.0", + "@typescript-eslint/utils": "6.0.0", + "@typescript-eslint/visitor-keys": "6.0.0", "debug": "^4.3.4", + "grapheme-splitter": "^1.0.4", "graphemer": "^1.4.0", - "ignore": "^5.2.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "semver": "^7.5.0", + "ts-api-utils": "^1.0.1" } }, "@typescript-eslint/parser": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", - "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.0.0.tgz", + "integrity": "sha512-TNaufYSPrr1U8n+3xN+Yp9g31vQDJqhXzzPSHfQDLcaO4tU+mCfODPxCwf4H530zo7aUBE3QIdxCXamEnG04Tg==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/scope-manager": "6.0.0", + "@typescript-eslint/types": "6.0.0", + "@typescript-eslint/typescript-estree": "6.0.0", + "@typescript-eslint/visitor-keys": "6.0.0", "debug": "^4.3.4" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" - } - }, - "@typescript-eslint/types": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" - } - } } }, "@typescript-eslint/scope-manager": { - "version": "5.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.61.0.tgz", - "integrity": "sha512-W8VoMjoSg7f7nqAROEmTt6LoBpn81AegP7uKhhW5KzYlehs8VV0ZW0fIDVbcZRcaP3aPSW+JZFua+ysQN+m/Nw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.0.0.tgz", + "integrity": "sha512-o4q0KHlgCZTqjuaZ25nw5W57NeykZT9LiMEG4do/ovwvOcPnDO1BI5BQdCsUkjxFyrCL0cSzLjvIMfR9uo7cWg==", "dev": true, "requires": { - "@typescript-eslint/types": "5.61.0", - "@typescript-eslint/visitor-keys": "5.61.0" + "@typescript-eslint/types": "6.0.0", + "@typescript-eslint/visitor-keys": "6.0.0" } }, "@typescript-eslint/type-utils": { - "version": "5.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.61.0.tgz", - "integrity": "sha512-kk8u//r+oVK2Aj3ph/26XdH0pbAkC2RiSjUYhKD+PExemG4XSjpGFeyZ/QM8lBOa7O8aGOU+/yEbMJgQv/DnCg==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.0.0.tgz", + "integrity": "sha512-ah6LJvLgkoZ/pyJ9GAdFkzeuMZ8goV6BH7eC9FPmojrnX9yNCIsfjB+zYcnex28YO3RFvBkV6rMV6WpIqkPvoQ==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.61.0", - "@typescript-eslint/utils": "5.61.0", + "@typescript-eslint/typescript-estree": "6.0.0", + "@typescript-eslint/utils": "6.0.0", "debug": "^4.3.4", - "tsutils": "^3.21.0" + "ts-api-utils": "^1.0.1" } }, "@typescript-eslint/types": { - "version": "5.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.61.0.tgz", - "integrity": "sha512-ldyueo58KjngXpzloHUog/h9REmHl59G1b3a5Sng1GfBo14BkS3ZbMEb3693gnP1k//97lh7bKsp6/V/0v1veQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.0.0.tgz", + "integrity": "sha512-Zk9KDggyZM6tj0AJWYYKgF0yQyrcnievdhG0g5FqyU3Y2DRxJn4yWY21sJC0QKBckbsdKKjYDV2yVrrEvuTgxg==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.61.0.tgz", - "integrity": "sha512-Fud90PxONnnLZ36oR5ClJBLTLfU4pIWBmnvGwTbEa2cXIqj70AEDEmOmpkFComjBZ/037ueKrOdHuYmSFVD7Rw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.0.0.tgz", + "integrity": "sha512-2zq4O7P6YCQADfmJ5OTDQTP3ktajnXIRrYAtHM9ofto/CJZV3QfJ89GEaM2BNGeSr1KgmBuLhEkz5FBkS2RQhQ==", "dev": true, "requires": { - "@typescript-eslint/types": "5.61.0", - "@typescript-eslint/visitor-keys": "5.61.0", + "@typescript-eslint/types": "6.0.0", + "@typescript-eslint/visitor-keys": "6.0.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "semver": "^7.5.0", + "ts-api-utils": "^1.0.1" } }, "@typescript-eslint/utils": { - "version": "5.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.61.0.tgz", - "integrity": "sha512-mV6O+6VgQmVE6+xzlA91xifndPW9ElFW8vbSF0xCT/czPXVhwDewKila1jOyRwa9AE19zKnrr7Cg5S3pJVrTWQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.0.0.tgz", + "integrity": "sha512-SOr6l4NB6HE4H/ktz0JVVWNXqCJTOo/mHnvIte1ZhBQ0Cvd04x5uKZa3zT6tiodL06zf5xxdK8COiDvPnQ27JQ==", "dev": true, "requires": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", + "@eslint-community/eslint-utils": "^4.3.0", + "@types/json-schema": "^7.0.11", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.61.0", - "@typescript-eslint/types": "5.61.0", - "@typescript-eslint/typescript-estree": "5.61.0", + "@typescript-eslint/scope-manager": "6.0.0", + "@typescript-eslint/types": "6.0.0", + "@typescript-eslint/typescript-estree": "6.0.0", "eslint-scope": "^5.1.1", - "semver": "^7.3.7" + "semver": "^7.5.0" } }, "@typescript-eslint/visitor-keys": { - "version": "5.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.61.0.tgz", - "integrity": "sha512-50XQ5VdbWrX06mQXhy93WywSFZZGsv3EOjq+lqp6WC2t+j3mb6A9xYVdrRxafvK88vg9k9u+CT4l6D8PEatjKg==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.0.0.tgz", + "integrity": "sha512-cvJ63l8c0yXdeT5POHpL0Q1cZoRcmRKFCtSjNGJxPkcP571EfZMcNbzWAc7oK3D1dRzm/V5EwtkANTZxqvuuUA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.61.0", - "eslint-visitor-keys": "^3.3.0" + "@typescript-eslint/types": "6.0.0", + "eslint-visitor-keys": "^3.4.1" } }, "abab": { @@ -10027,6 +9915,12 @@ "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", "dev": true }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, "graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -10113,9 +10007,9 @@ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true }, "import-fresh": { @@ -12067,6 +11961,13 @@ "punycode": "^2.1.1" } }, + "ts-api-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.1.tgz", + "integrity": "sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==", + "dev": true, + "requires": {} + }, "ts-jest": { "version": "27.1.3", "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.3.tgz", @@ -12089,23 +11990,6 @@ "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", "dev": true }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - } - } - }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 95875679..f26acd58 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -62,12 +62,12 @@ "@types/jest": "^27.4.0", "@types/node": "^20.1.2", "@types/node-fetch": "^2.6.3", - "@typescript-eslint/eslint-plugin": "^5.59.5", - "@typescript-eslint/parser": "^5.59.5", + "@typescript-eslint/eslint-plugin": "^6.0.0", + "@typescript-eslint/parser": "^6.0.0", "cross-env": "^7.0.3", "eslint": "^8.40.0", "eslint-config-prettier": "^8.8.0", - "eslint-plugin-prettier": "^5.0.0-alpha.1", + "eslint-plugin-prettier": "^5.0.0", "jest": "^27.5.1", "prettier": "^3.0.0", "rimraf": "^5.0.0", From 1f386e83b1608ca566c5c505d373375fdff000b0 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 12 Jul 2023 01:09:58 +0200 Subject: [PATCH 0411/1076] stake-pool: Allow pool token mint to include metadata (#4770) stake-pool: Allow token mint to include metadata --- program/src/state.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/program/src/state.rs b/program/src/state.rs index b8ea873b..f87be227 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -492,12 +492,14 @@ impl StakePool { /// Checks if the given extension is supported for the stake pool mint pub fn is_extension_supported_for_mint(extension_type: &ExtensionType) -> bool { - const SUPPORTED_EXTENSIONS: [ExtensionType; 5] = [ + const SUPPORTED_EXTENSIONS: [ExtensionType; 7] = [ ExtensionType::Uninitialized, ExtensionType::TransferFeeConfig, ExtensionType::ConfidentialTransferMint, ExtensionType::DefaultAccountState, // ok, but a freeze authority is not ExtensionType::InterestBearingConfig, + ExtensionType::MetadataPointer, + ExtensionType::TokenMetadata, ]; if !SUPPORTED_EXTENSIONS.contains(extension_type) { msg!( From 3469c9a0e23d9a12b888de6c427a24c24326bd7a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Jul 2023 13:54:21 +0200 Subject: [PATCH 0412/1076] build(deps): bump serde_json from 1.0.100 to 1.0.102 (#4771) * build(deps): bump serde_json from 1.0.100 to 1.0.102 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.100 to 1.0.102. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.100...v1.0.102) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Update Cargo.lock --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index bc3b2c29..ced5d6a8 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ borsh = "0.10" clap = "2.33.3" serde = "1.0.168" serde_derive = "1.0.130" -serde_json = "1.0.100" +serde_json = "1.0.102" solana-account-decoder = "=1.16.1" solana-clap-utils = "=1.16.1" solana-cli-config = "=1.16.1" From 7145fbdf43c94948ecd602568d0ffcc075030c4f Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Thu, 13 Jul 2023 11:06:07 +0900 Subject: [PATCH 0413/1076] Upgrade to solana 1.16.3 (#4679) * upgrade to solana 1.16.3 * bring down hashbrown dependency to 0.12.3 --- clients/cli/Cargo.toml | 18 +++++++++--------- program/Cargo.toml | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index ced5d6a8..a421394f 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -14,15 +14,15 @@ clap = "2.33.3" serde = "1.0.168" serde_derive = "1.0.130" serde_json = "1.0.102" -solana-account-decoder = "=1.16.1" -solana-clap-utils = "=1.16.1" -solana-cli-config = "=1.16.1" -solana-cli-output = "=1.16.1" -solana-client = "=1.16.1" -solana-logger = "=1.16.1" -solana-program = "=1.16.1" -solana-remote-wallet = "=1.16.1" -solana-sdk = "=1.16.1" +solana-account-decoder = "=1.16.3" +solana-clap-utils = "=1.16.3" +solana-cli-config = "=1.16.3" +solana-cli-output = "=1.16.3" +solana-client = "=1.16.3" +solana-logger = "=1.16.3" +solana-program = "=1.16.3" +solana-remote-wallet = "=1.16.3" +solana-sdk = "=1.16.3" spl-associated-token-account = { version = "=2.0", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "=0.7.0", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "=4.0", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/program/Cargo.toml b/program/Cargo.toml index 60aee1bd..be8e4c29 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -19,7 +19,7 @@ num-traits = "0.2" num_enum = "0.6.1" serde = "1.0.168" serde_derive = "1.0.103" -solana-program = "1.16.1" +solana-program = "1.16.3" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-token-2022 = { version = "0.7", path = "../../token/program-2022", features = [ "no-entrypoint" ] } thiserror = "1.0" @@ -27,9 +27,9 @@ bincode = "1.3.1" [dev-dependencies] proptest = "1.2" -solana-program-test = "1.16.1" -solana-sdk = "1.16.1" -solana-vote-program = "1.16.1" +solana-program-test = "1.16.3" +solana-sdk = "1.16.3" +solana-vote-program = "1.16.3" spl-token = { version = "4.0", path = "../../token/program", features = [ "no-entrypoint" ] } test-case = "3.1" From 9e4e8388648642c7fd7a75704aac47cb87697aad Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Jul 2023 15:15:09 +0200 Subject: [PATCH 0414/1076] build(deps-dev): bump @types/node from 20.4.1 to 20.4.2 in /stake-pool/js (#4782) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.4.1 to 20.4.2. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index adcba4a2..d38bcc30 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1757,9 +1757,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.4.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.1.tgz", - "integrity": "sha512-JIzsAvJeA/5iY6Y/OxZbv1lUcc8dNSE77lb2gnBH+/PJ3lFR1Ccvgwl5JWnHAkNHcRsT0TbpVOsiMKZ1F/yyJg==" + "version": "20.4.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.2.tgz", + "integrity": "sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==" }, "node_modules/@types/node-fetch": { "version": "2.6.4", @@ -8375,9 +8375,9 @@ "dev": true }, "@types/node": { - "version": "20.4.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.1.tgz", - "integrity": "sha512-JIzsAvJeA/5iY6Y/OxZbv1lUcc8dNSE77lb2gnBH+/PJ3lFR1Ccvgwl5JWnHAkNHcRsT0TbpVOsiMKZ1F/yyJg==" + "version": "20.4.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.2.tgz", + "integrity": "sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==" }, "@types/node-fetch": { "version": "2.6.4", From d9d0001a4bf6b7179bbd213b4236dfea65d63430 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Jul 2023 16:32:16 +0200 Subject: [PATCH 0415/1076] build(deps-dev): bump eslint from 8.44.0 to 8.45.0 in /stake-pool/js (#4801) Bumps [eslint](https://github.com/eslint/eslint) from 8.44.0 to 8.45.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.44.0...v8.45.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index d38bcc30..4904baad 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -3210,9 +3210,9 @@ } }, "node_modules/eslint": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.44.0.tgz", - "integrity": "sha512-0wpHoUbDUHgNCyvFB5aXLiQVfK9B0at6gUvzy83k4kAsQ/u769TQDX6iKC+aO4upIHO9WSaA3QoXYQDHbNwf1A==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.45.0.tgz", + "integrity": "sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", @@ -3240,7 +3240,6 @@ "globals": "^13.19.0", "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", @@ -3252,7 +3251,6 @@ "natural-compare": "^1.4.0", "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "bin": { @@ -9412,9 +9410,9 @@ } }, "eslint": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.44.0.tgz", - "integrity": "sha512-0wpHoUbDUHgNCyvFB5aXLiQVfK9B0at6gUvzy83k4kAsQ/u769TQDX6iKC+aO4upIHO9WSaA3QoXYQDHbNwf1A==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.45.0.tgz", + "integrity": "sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", @@ -9442,7 +9440,6 @@ "globals": "^13.19.0", "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", @@ -9454,7 +9451,6 @@ "natural-compare": "^1.4.0", "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "dependencies": { From fbc54c1faaf4ed17d4ebf4a4ce0fad0202be01c1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Jul 2023 16:35:11 +0200 Subject: [PATCH 0416/1076] build(deps): bump serde from 1.0.168 to 1.0.171 (#4795) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.168 to 1.0.171. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.168...v1.0.171) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index a421394f..dadfcdae 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "0.7.0" [dependencies] borsh = "0.10" clap = "2.33.3" -serde = "1.0.168" +serde = "1.0.171" serde_derive = "1.0.130" serde_json = "1.0.102" solana-account-decoder = "=1.16.3" diff --git a/program/Cargo.toml b/program/Cargo.toml index be8e4c29..b9747e12 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,7 +17,7 @@ borsh = "0.10" num-derive = "0.4" num-traits = "0.2" num_enum = "0.6.1" -serde = "1.0.168" +serde = "1.0.171" serde_derive = "1.0.103" solana-program = "1.16.3" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } From c0b91e5e7d0b4af81d7265fb03914ea05c719c36 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Jul 2023 16:36:21 +0200 Subject: [PATCH 0417/1076] build(deps-dev): bump @rollup/plugin-commonjs from 25.0.2 to 25.0.3 in /stake-pool/js (#4802) build(deps-dev): bump @rollup/plugin-commonjs in /stake-pool/js Bumps [@rollup/plugin-commonjs](https://github.com/rollup/plugins/tree/HEAD/packages/commonjs) from 25.0.2 to 25.0.3. - [Changelog](https://github.com/rollup/plugins/blob/master/packages/commonjs/CHANGELOG.md) - [Commits](https://github.com/rollup/plugins/commits/commonjs-v25.0.3/packages/commonjs) --- updated-dependencies: - dependency-name: "@rollup/plugin-commonjs" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 4904baad..7c04836f 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1346,9 +1346,9 @@ } }, "node_modules/@rollup/plugin-commonjs": { - "version": "25.0.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.2.tgz", - "integrity": "sha512-NGTwaJxIO0klMs+WSFFtBP7b9TdTJ3K76HZkewT8/+yHzMiUGVQgaPtLQxNVYIgT5F7lxkEyVID+yS3K7bhCow==", + "version": "25.0.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.3.tgz", + "integrity": "sha512-uBdtWr/H3BVcgm97MUdq2oJmqBR23ny1hOrWe2PKo9FTbjsGqg32jfasJUKYAI5ouqacjRnj65mBB/S79F+GQA==", "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1", @@ -8068,9 +8068,9 @@ } }, "@rollup/plugin-commonjs": { - "version": "25.0.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.2.tgz", - "integrity": "sha512-NGTwaJxIO0klMs+WSFFtBP7b9TdTJ3K76HZkewT8/+yHzMiUGVQgaPtLQxNVYIgT5F7lxkEyVID+yS3K7bhCow==", + "version": "25.0.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.3.tgz", + "integrity": "sha512-uBdtWr/H3BVcgm97MUdq2oJmqBR23ny1hOrWe2PKo9FTbjsGqg32jfasJUKYAI5ouqacjRnj65mBB/S79F+GQA==", "dev": true, "requires": { "@rollup/pluginutils": "^5.0.1", From 5c1455168502e1f6d351442ae97c71e802af4d10 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Jul 2023 17:46:34 +0200 Subject: [PATCH 0418/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.0.0 to 6.1.0 in /stake-pool/js (#4811) build(deps-dev): bump @typescript-eslint/eslint-plugin in /stake-pool/js Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.0.0 to 6.1.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.1.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 444 +++++++++++++++++++++------- 1 file changed, 336 insertions(+), 108 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 7c04836f..1e2eb986 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1819,23 +1819,22 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.0.0.tgz", - "integrity": "sha512-xuv6ghKGoiq856Bww/yVYnXGsKa588kY3M0XK7uUW/3fJNNULKRfZfSBkMTSpqGG/8ZCXCadfh8G/z/B4aqS/A==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.1.0.tgz", + "integrity": "sha512-qg7Bm5TyP/I7iilGyp6DRqqkt8na00lI6HbjWZObgk3FFSzH5ypRwAHXJhJkwiRtTcfn+xYQIMOR5kJgpo6upw==", "dev": true, "dependencies": { - "@eslint-community/regexpp": "^4.5.0", - "@typescript-eslint/scope-manager": "6.0.0", - "@typescript-eslint/type-utils": "6.0.0", - "@typescript-eslint/utils": "6.0.0", - "@typescript-eslint/visitor-keys": "6.0.0", + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.1.0", + "@typescript-eslint/type-utils": "6.1.0", + "@typescript-eslint/utils": "6.1.0", + "@typescript-eslint/visitor-keys": "6.1.0", "debug": "^4.3.4", - "grapheme-splitter": "^1.0.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", "natural-compare": "^1.4.0", "natural-compare-lite": "^1.4.0", - "semver": "^7.5.0", + "semver": "^7.5.4", "ts-api-utils": "^1.0.1" }, "engines": { @@ -1855,6 +1854,53 @@ } } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.1.0.tgz", + "integrity": "sha512-AxjgxDn27hgPpe2rQe19k0tXw84YCOsjDJ2r61cIebq1t+AIxbgiXKvD4999Wk49GVaAcdJ/d49FYel+Pp3jjw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.1.0", + "@typescript-eslint/visitor-keys": "6.1.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.1.0.tgz", + "integrity": "sha512-+Gfd5NHCpDoHDOaU/yIF3WWRI2PcBRKKpP91ZcVbL0t5tQpqYWBs3z/GGhvU+EV1D0262g9XCnyqQh19prU0JQ==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.1.0.tgz", + "integrity": "sha512-yQeh+EXhquh119Eis4k0kYhj9vmFzNpbhM3LftWQVwqVjipCkwHBQOZutcYW+JVkjtTG9k8nrZU1UoNedPDd1A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.1.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/parser": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.0.0.tgz", @@ -1901,13 +1947,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.0.0.tgz", - "integrity": "sha512-ah6LJvLgkoZ/pyJ9GAdFkzeuMZ8goV6BH7eC9FPmojrnX9yNCIsfjB+zYcnex28YO3RFvBkV6rMV6WpIqkPvoQ==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.1.0.tgz", + "integrity": "sha512-kFXBx6QWS1ZZ5Ni89TyT1X9Ag6RXVIVhqDs0vZE/jUeWlBv/ixq2diua6G7ece6+fXw3TvNRxP77/5mOMusx2w==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.0.0", - "@typescript-eslint/utils": "6.0.0", + "@typescript-eslint/typescript-estree": "6.1.0", + "@typescript-eslint/utils": "6.1.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -1927,6 +1973,63 @@ } } }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.1.0.tgz", + "integrity": "sha512-+Gfd5NHCpDoHDOaU/yIF3WWRI2PcBRKKpP91ZcVbL0t5tQpqYWBs3z/GGhvU+EV1D0262g9XCnyqQh19prU0JQ==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.1.0.tgz", + "integrity": "sha512-nUKAPWOaP/tQjU1IQw9sOPCDavs/iU5iYLiY/6u7gxS7oKQoi4aUxXS1nrrVGTyBBaGesjkcwwHkbkiD5eBvcg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.1.0", + "@typescript-eslint/visitor-keys": "6.1.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.1.0.tgz", + "integrity": "sha512-yQeh+EXhquh119Eis4k0kYhj9vmFzNpbhM3LftWQVwqVjipCkwHBQOZutcYW+JVkjtTG9k8nrZU1UoNedPDd1A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.1.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/types": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.0.0.tgz", @@ -1968,19 +2071,18 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.0.0.tgz", - "integrity": "sha512-SOr6l4NB6HE4H/ktz0JVVWNXqCJTOo/mHnvIte1ZhBQ0Cvd04x5uKZa3zT6tiodL06zf5xxdK8COiDvPnQ27JQ==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.1.0.tgz", + "integrity": "sha512-wp652EogZlKmQoMS5hAvWqRKplXvkuOnNzZSE0PVvsKjpexd/XznRVHAtrfHFYmqaJz0DFkjlDsGYC9OXw+OhQ==", "dev": true, "dependencies": { - "@eslint-community/eslint-utils": "^4.3.0", - "@types/json-schema": "^7.0.11", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "6.0.0", - "@typescript-eslint/types": "6.0.0", - "@typescript-eslint/typescript-estree": "6.0.0", - "eslint-scope": "^5.1.1", - "semver": "^7.5.0" + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.1.0", + "@typescript-eslint/types": "6.1.0", + "@typescript-eslint/typescript-estree": "6.1.0", + "semver": "^7.5.4" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -1993,6 +2095,80 @@ "eslint": "^7.0.0 || ^8.0.0" } }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.1.0.tgz", + "integrity": "sha512-AxjgxDn27hgPpe2rQe19k0tXw84YCOsjDJ2r61cIebq1t+AIxbgiXKvD4999Wk49GVaAcdJ/d49FYel+Pp3jjw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.1.0", + "@typescript-eslint/visitor-keys": "6.1.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.1.0.tgz", + "integrity": "sha512-+Gfd5NHCpDoHDOaU/yIF3WWRI2PcBRKKpP91ZcVbL0t5tQpqYWBs3z/GGhvU+EV1D0262g9XCnyqQh19prU0JQ==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.1.0.tgz", + "integrity": "sha512-nUKAPWOaP/tQjU1IQw9sOPCDavs/iU5iYLiY/6u7gxS7oKQoi4aUxXS1nrrVGTyBBaGesjkcwwHkbkiD5eBvcg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.1.0", + "@typescript-eslint/visitor-keys": "6.1.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.1.0.tgz", + "integrity": "sha512-yQeh+EXhquh119Eis4k0kYhj9vmFzNpbhM3LftWQVwqVjipCkwHBQOZutcYW+JVkjtTG9k8nrZU1UoNedPDd1A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.1.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/visitor-keys": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.0.0.tgz", @@ -3304,19 +3480,6 @@ } } }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/eslint-visitor-keys": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", @@ -3487,15 +3650,6 @@ "node": ">=4.0" } }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, "node_modules/estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", @@ -3902,12 +4056,6 @@ "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", "dev": true }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true - }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -6250,9 +6398,9 @@ } }, "node_modules/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -8435,24 +8583,51 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.0.0.tgz", - "integrity": "sha512-xuv6ghKGoiq856Bww/yVYnXGsKa588kY3M0XK7uUW/3fJNNULKRfZfSBkMTSpqGG/8ZCXCadfh8G/z/B4aqS/A==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.1.0.tgz", + "integrity": "sha512-qg7Bm5TyP/I7iilGyp6DRqqkt8na00lI6HbjWZObgk3FFSzH5ypRwAHXJhJkwiRtTcfn+xYQIMOR5kJgpo6upw==", "dev": true, "requires": { - "@eslint-community/regexpp": "^4.5.0", - "@typescript-eslint/scope-manager": "6.0.0", - "@typescript-eslint/type-utils": "6.0.0", - "@typescript-eslint/utils": "6.0.0", - "@typescript-eslint/visitor-keys": "6.0.0", + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.1.0", + "@typescript-eslint/type-utils": "6.1.0", + "@typescript-eslint/utils": "6.1.0", + "@typescript-eslint/visitor-keys": "6.1.0", "debug": "^4.3.4", - "grapheme-splitter": "^1.0.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", "natural-compare": "^1.4.0", "natural-compare-lite": "^1.4.0", - "semver": "^7.5.0", + "semver": "^7.5.4", "ts-api-utils": "^1.0.1" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.1.0.tgz", + "integrity": "sha512-AxjgxDn27hgPpe2rQe19k0tXw84YCOsjDJ2r61cIebq1t+AIxbgiXKvD4999Wk49GVaAcdJ/d49FYel+Pp3jjw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.1.0", + "@typescript-eslint/visitor-keys": "6.1.0" + } + }, + "@typescript-eslint/types": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.1.0.tgz", + "integrity": "sha512-+Gfd5NHCpDoHDOaU/yIF3WWRI2PcBRKKpP91ZcVbL0t5tQpqYWBs3z/GGhvU+EV1D0262g9XCnyqQh19prU0JQ==", + "dev": true + }, + "@typescript-eslint/visitor-keys": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.1.0.tgz", + "integrity": "sha512-yQeh+EXhquh119Eis4k0kYhj9vmFzNpbhM3LftWQVwqVjipCkwHBQOZutcYW+JVkjtTG9k8nrZU1UoNedPDd1A==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.1.0", + "eslint-visitor-keys": "^3.4.1" + } + } } }, "@typescript-eslint/parser": { @@ -8479,15 +8654,48 @@ } }, "@typescript-eslint/type-utils": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.0.0.tgz", - "integrity": "sha512-ah6LJvLgkoZ/pyJ9GAdFkzeuMZ8goV6BH7eC9FPmojrnX9yNCIsfjB+zYcnex28YO3RFvBkV6rMV6WpIqkPvoQ==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.1.0.tgz", + "integrity": "sha512-kFXBx6QWS1ZZ5Ni89TyT1X9Ag6RXVIVhqDs0vZE/jUeWlBv/ixq2diua6G7ece6+fXw3TvNRxP77/5mOMusx2w==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "6.0.0", - "@typescript-eslint/utils": "6.0.0", + "@typescript-eslint/typescript-estree": "6.1.0", + "@typescript-eslint/utils": "6.1.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" + }, + "dependencies": { + "@typescript-eslint/types": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.1.0.tgz", + "integrity": "sha512-+Gfd5NHCpDoHDOaU/yIF3WWRI2PcBRKKpP91ZcVbL0t5tQpqYWBs3z/GGhvU+EV1D0262g9XCnyqQh19prU0JQ==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.1.0.tgz", + "integrity": "sha512-nUKAPWOaP/tQjU1IQw9sOPCDavs/iU5iYLiY/6u7gxS7oKQoi4aUxXS1nrrVGTyBBaGesjkcwwHkbkiD5eBvcg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.1.0", + "@typescript-eslint/visitor-keys": "6.1.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.1.0.tgz", + "integrity": "sha512-yQeh+EXhquh119Eis4k0kYhj9vmFzNpbhM3LftWQVwqVjipCkwHBQOZutcYW+JVkjtTG9k8nrZU1UoNedPDd1A==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.1.0", + "eslint-visitor-keys": "^3.4.1" + } + } } }, "@typescript-eslint/types": { @@ -8512,19 +8720,61 @@ } }, "@typescript-eslint/utils": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.0.0.tgz", - "integrity": "sha512-SOr6l4NB6HE4H/ktz0JVVWNXqCJTOo/mHnvIte1ZhBQ0Cvd04x5uKZa3zT6tiodL06zf5xxdK8COiDvPnQ27JQ==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.1.0.tgz", + "integrity": "sha512-wp652EogZlKmQoMS5hAvWqRKplXvkuOnNzZSE0PVvsKjpexd/XznRVHAtrfHFYmqaJz0DFkjlDsGYC9OXw+OhQ==", "dev": true, "requires": { - "@eslint-community/eslint-utils": "^4.3.0", - "@types/json-schema": "^7.0.11", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "6.0.0", - "@typescript-eslint/types": "6.0.0", - "@typescript-eslint/typescript-estree": "6.0.0", - "eslint-scope": "^5.1.1", - "semver": "^7.5.0" + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.1.0", + "@typescript-eslint/types": "6.1.0", + "@typescript-eslint/typescript-estree": "6.1.0", + "semver": "^7.5.4" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.1.0.tgz", + "integrity": "sha512-AxjgxDn27hgPpe2rQe19k0tXw84YCOsjDJ2r61cIebq1t+AIxbgiXKvD4999Wk49GVaAcdJ/d49FYel+Pp3jjw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.1.0", + "@typescript-eslint/visitor-keys": "6.1.0" + } + }, + "@typescript-eslint/types": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.1.0.tgz", + "integrity": "sha512-+Gfd5NHCpDoHDOaU/yIF3WWRI2PcBRKKpP91ZcVbL0t5tQpqYWBs3z/GGhvU+EV1D0262g9XCnyqQh19prU0JQ==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.1.0.tgz", + "integrity": "sha512-nUKAPWOaP/tQjU1IQw9sOPCDavs/iU5iYLiY/6u7gxS7oKQoi4aUxXS1nrrVGTyBBaGesjkcwwHkbkiD5eBvcg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.1.0", + "@typescript-eslint/visitor-keys": "6.1.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.1.0.tgz", + "integrity": "sha512-yQeh+EXhquh119Eis4k0kYhj9vmFzNpbhM3LftWQVwqVjipCkwHBQOZutcYW+JVkjtTG9k8nrZU1UoNedPDd1A==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.1.0", + "eslint-visitor-keys": "^3.4.1" + } + } } }, "@typescript-eslint/visitor-keys": { @@ -9526,16 +9776,6 @@ "synckit": "^0.8.5" } }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, "eslint-visitor-keys": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", @@ -9593,12 +9833,6 @@ } } }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, "estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", @@ -9911,12 +10145,6 @@ "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", "dev": true }, - "grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true - }, "graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -11645,9 +11873,9 @@ } }, "semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "requires": { "lru-cache": "^6.0.0" From 435477e29346b215b0b9117f16aa19028cd621ab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Jul 2023 17:07:07 +0200 Subject: [PATCH 0419/1076] build(deps-dev): bump word-wrap from 1.2.3 to 1.2.4 in /stake-pool/js (#4820) Bumps [word-wrap](https://github.com/jonschlinkert/word-wrap) from 1.2.3 to 1.2.4. - [Release notes](https://github.com/jonschlinkert/word-wrap/releases) - [Commits](https://github.com/jonschlinkert/word-wrap/compare/1.2.3...1.2.4) --- updated-dependencies: - dependency-name: word-wrap dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 1e2eb986..467677c2 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -7094,9 +7094,9 @@ } }, "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", + "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", "dev": true, "engines": { "node": ">=0.10.0" @@ -12383,9 +12383,9 @@ } }, "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", + "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", "dev": true }, "wrap-ansi": { From cb476999c36f8531139fecde262334598b4bd95c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Jul 2023 17:09:30 +0200 Subject: [PATCH 0420/1076] build(deps-dev): bump @typescript-eslint/parser from 6.0.0 to 6.1.0 in /stake-pool/js (#4823) build(deps-dev): bump @typescript-eslint/parser in /stake-pool/js Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.0.0 to 6.1.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.1.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 360 +++------------------------- 1 file changed, 39 insertions(+), 321 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 467677c2..e4fb6f2e 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1854,63 +1854,16 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.1.0.tgz", - "integrity": "sha512-AxjgxDn27hgPpe2rQe19k0tXw84YCOsjDJ2r61cIebq1t+AIxbgiXKvD4999Wk49GVaAcdJ/d49FYel+Pp3jjw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.1.0", - "@typescript-eslint/visitor-keys": "6.1.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.1.0.tgz", - "integrity": "sha512-+Gfd5NHCpDoHDOaU/yIF3WWRI2PcBRKKpP91ZcVbL0t5tQpqYWBs3z/GGhvU+EV1D0262g9XCnyqQh19prU0JQ==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "node_modules/@typescript-eslint/parser": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.1.0.tgz", - "integrity": "sha512-yQeh+EXhquh119Eis4k0kYhj9vmFzNpbhM3LftWQVwqVjipCkwHBQOZutcYW+JVkjtTG9k8nrZU1UoNedPDd1A==", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.1.0.tgz", + "integrity": "sha512-hIzCPvX4vDs4qL07SYzyomamcs2/tQYXg5DtdAfj35AyJ5PIUqhsLf4YrEIFzZcND7R2E8tpQIZKayxg8/6Wbw==", "dev": true, "dependencies": { + "@typescript-eslint/scope-manager": "6.1.0", "@typescript-eslint/types": "6.1.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.0.0.tgz", - "integrity": "sha512-TNaufYSPrr1U8n+3xN+Yp9g31vQDJqhXzzPSHfQDLcaO4tU+mCfODPxCwf4H530zo7aUBE3QIdxCXamEnG04Tg==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "6.0.0", - "@typescript-eslint/types": "6.0.0", - "@typescript-eslint/typescript-estree": "6.0.0", - "@typescript-eslint/visitor-keys": "6.0.0", + "@typescript-eslint/typescript-estree": "6.1.0", + "@typescript-eslint/visitor-keys": "6.1.0", "debug": "^4.3.4" }, "engines": { @@ -1930,13 +1883,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.0.0.tgz", - "integrity": "sha512-o4q0KHlgCZTqjuaZ25nw5W57NeykZT9LiMEG4do/ovwvOcPnDO1BI5BQdCsUkjxFyrCL0cSzLjvIMfR9uo7cWg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.1.0.tgz", + "integrity": "sha512-AxjgxDn27hgPpe2rQe19k0tXw84YCOsjDJ2r61cIebq1t+AIxbgiXKvD4999Wk49GVaAcdJ/d49FYel+Pp3jjw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.0.0", - "@typescript-eslint/visitor-keys": "6.0.0" + "@typescript-eslint/types": "6.1.0", + "@typescript-eslint/visitor-keys": "6.1.0" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -1973,7 +1926,7 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "node_modules/@typescript-eslint/types": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.1.0.tgz", "integrity": "sha512-+Gfd5NHCpDoHDOaU/yIF3WWRI2PcBRKKpP91ZcVbL0t5tQpqYWBs3z/GGhvU+EV1D0262g9XCnyqQh19prU0JQ==", @@ -1986,7 +1939,7 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "node_modules/@typescript-eslint/typescript-estree": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.1.0.tgz", "integrity": "sha512-nUKAPWOaP/tQjU1IQw9sOPCDavs/iU5iYLiY/6u7gxS7oKQoi4aUxXS1nrrVGTyBBaGesjkcwwHkbkiD5eBvcg==", @@ -2013,63 +1966,6 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.1.0.tgz", - "integrity": "sha512-yQeh+EXhquh119Eis4k0kYhj9vmFzNpbhM3LftWQVwqVjipCkwHBQOZutcYW+JVkjtTG9k8nrZU1UoNedPDd1A==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.1.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.0.0.tgz", - "integrity": "sha512-Zk9KDggyZM6tj0AJWYYKgF0yQyrcnievdhG0g5FqyU3Y2DRxJn4yWY21sJC0QKBckbsdKKjYDV2yVrrEvuTgxg==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.0.0.tgz", - "integrity": "sha512-2zq4O7P6YCQADfmJ5OTDQTP3ktajnXIRrYAtHM9ofto/CJZV3QfJ89GEaM2BNGeSr1KgmBuLhEkz5FBkS2RQhQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.0.0", - "@typescript-eslint/visitor-keys": "6.0.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.0", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, "node_modules/@typescript-eslint/utils": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.1.0.tgz", @@ -2095,64 +1991,7 @@ "eslint": "^7.0.0 || ^8.0.0" } }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.1.0.tgz", - "integrity": "sha512-AxjgxDn27hgPpe2rQe19k0tXw84YCOsjDJ2r61cIebq1t+AIxbgiXKvD4999Wk49GVaAcdJ/d49FYel+Pp3jjw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.1.0", - "@typescript-eslint/visitor-keys": "6.1.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.1.0.tgz", - "integrity": "sha512-+Gfd5NHCpDoHDOaU/yIF3WWRI2PcBRKKpP91ZcVbL0t5tQpqYWBs3z/GGhvU+EV1D0262g9XCnyqQh19prU0JQ==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.1.0.tgz", - "integrity": "sha512-nUKAPWOaP/tQjU1IQw9sOPCDavs/iU5iYLiY/6u7gxS7oKQoi4aUxXS1nrrVGTyBBaGesjkcwwHkbkiD5eBvcg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.1.0", - "@typescript-eslint/visitor-keys": "6.1.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "node_modules/@typescript-eslint/visitor-keys": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.1.0.tgz", "integrity": "sha512-yQeh+EXhquh119Eis4k0kYhj9vmFzNpbhM3LftWQVwqVjipCkwHBQOZutcYW+JVkjtTG9k8nrZU1UoNedPDd1A==", @@ -2169,23 +2008,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.0.0.tgz", - "integrity": "sha512-cvJ63l8c0yXdeT5POHpL0Q1cZoRcmRKFCtSjNGJxPkcP571EfZMcNbzWAc7oK3D1dRzm/V5EwtkANTZxqvuuUA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.0.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/abab": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", @@ -8600,57 +8422,29 @@ "natural-compare-lite": "^1.4.0", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.1.0.tgz", - "integrity": "sha512-AxjgxDn27hgPpe2rQe19k0tXw84YCOsjDJ2r61cIebq1t+AIxbgiXKvD4999Wk49GVaAcdJ/d49FYel+Pp3jjw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.1.0", - "@typescript-eslint/visitor-keys": "6.1.0" - } - }, - "@typescript-eslint/types": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.1.0.tgz", - "integrity": "sha512-+Gfd5NHCpDoHDOaU/yIF3WWRI2PcBRKKpP91ZcVbL0t5tQpqYWBs3z/GGhvU+EV1D0262g9XCnyqQh19prU0JQ==", - "dev": true - }, - "@typescript-eslint/visitor-keys": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.1.0.tgz", - "integrity": "sha512-yQeh+EXhquh119Eis4k0kYhj9vmFzNpbhM3LftWQVwqVjipCkwHBQOZutcYW+JVkjtTG9k8nrZU1UoNedPDd1A==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.1.0", - "eslint-visitor-keys": "^3.4.1" - } - } } }, "@typescript-eslint/parser": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.0.0.tgz", - "integrity": "sha512-TNaufYSPrr1U8n+3xN+Yp9g31vQDJqhXzzPSHfQDLcaO4tU+mCfODPxCwf4H530zo7aUBE3QIdxCXamEnG04Tg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.1.0.tgz", + "integrity": "sha512-hIzCPvX4vDs4qL07SYzyomamcs2/tQYXg5DtdAfj35AyJ5PIUqhsLf4YrEIFzZcND7R2E8tpQIZKayxg8/6Wbw==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "6.0.0", - "@typescript-eslint/types": "6.0.0", - "@typescript-eslint/typescript-estree": "6.0.0", - "@typescript-eslint/visitor-keys": "6.0.0", + "@typescript-eslint/scope-manager": "6.1.0", + "@typescript-eslint/types": "6.1.0", + "@typescript-eslint/typescript-estree": "6.1.0", + "@typescript-eslint/visitor-keys": "6.1.0", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.0.0.tgz", - "integrity": "sha512-o4q0KHlgCZTqjuaZ25nw5W57NeykZT9LiMEG4do/ovwvOcPnDO1BI5BQdCsUkjxFyrCL0cSzLjvIMfR9uo7cWg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.1.0.tgz", + "integrity": "sha512-AxjgxDn27hgPpe2rQe19k0tXw84YCOsjDJ2r61cIebq1t+AIxbgiXKvD4999Wk49GVaAcdJ/d49FYel+Pp3jjw==", "dev": true, "requires": { - "@typescript-eslint/types": "6.0.0", - "@typescript-eslint/visitor-keys": "6.0.0" + "@typescript-eslint/types": "6.1.0", + "@typescript-eslint/visitor-keys": "6.1.0" } }, "@typescript-eslint/type-utils": { @@ -8663,59 +8457,26 @@ "@typescript-eslint/utils": "6.1.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" - }, - "dependencies": { - "@typescript-eslint/types": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.1.0.tgz", - "integrity": "sha512-+Gfd5NHCpDoHDOaU/yIF3WWRI2PcBRKKpP91ZcVbL0t5tQpqYWBs3z/GGhvU+EV1D0262g9XCnyqQh19prU0JQ==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.1.0.tgz", - "integrity": "sha512-nUKAPWOaP/tQjU1IQw9sOPCDavs/iU5iYLiY/6u7gxS7oKQoi4aUxXS1nrrVGTyBBaGesjkcwwHkbkiD5eBvcg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.1.0", - "@typescript-eslint/visitor-keys": "6.1.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.1.0.tgz", - "integrity": "sha512-yQeh+EXhquh119Eis4k0kYhj9vmFzNpbhM3LftWQVwqVjipCkwHBQOZutcYW+JVkjtTG9k8nrZU1UoNedPDd1A==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.1.0", - "eslint-visitor-keys": "^3.4.1" - } - } } }, "@typescript-eslint/types": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.0.0.tgz", - "integrity": "sha512-Zk9KDggyZM6tj0AJWYYKgF0yQyrcnievdhG0g5FqyU3Y2DRxJn4yWY21sJC0QKBckbsdKKjYDV2yVrrEvuTgxg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.1.0.tgz", + "integrity": "sha512-+Gfd5NHCpDoHDOaU/yIF3WWRI2PcBRKKpP91ZcVbL0t5tQpqYWBs3z/GGhvU+EV1D0262g9XCnyqQh19prU0JQ==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.0.0.tgz", - "integrity": "sha512-2zq4O7P6YCQADfmJ5OTDQTP3ktajnXIRrYAtHM9ofto/CJZV3QfJ89GEaM2BNGeSr1KgmBuLhEkz5FBkS2RQhQ==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.1.0.tgz", + "integrity": "sha512-nUKAPWOaP/tQjU1IQw9sOPCDavs/iU5iYLiY/6u7gxS7oKQoi4aUxXS1nrrVGTyBBaGesjkcwwHkbkiD5eBvcg==", "dev": true, "requires": { - "@typescript-eslint/types": "6.0.0", - "@typescript-eslint/visitor-keys": "6.0.0", + "@typescript-eslint/types": "6.1.0", + "@typescript-eslint/visitor-keys": "6.1.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "semver": "^7.5.0", + "semver": "^7.5.4", "ts-api-utils": "^1.0.1" } }, @@ -8732,58 +8493,15 @@ "@typescript-eslint/types": "6.1.0", "@typescript-eslint/typescript-estree": "6.1.0", "semver": "^7.5.4" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.1.0.tgz", - "integrity": "sha512-AxjgxDn27hgPpe2rQe19k0tXw84YCOsjDJ2r61cIebq1t+AIxbgiXKvD4999Wk49GVaAcdJ/d49FYel+Pp3jjw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.1.0", - "@typescript-eslint/visitor-keys": "6.1.0" - } - }, - "@typescript-eslint/types": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.1.0.tgz", - "integrity": "sha512-+Gfd5NHCpDoHDOaU/yIF3WWRI2PcBRKKpP91ZcVbL0t5tQpqYWBs3z/GGhvU+EV1D0262g9XCnyqQh19prU0JQ==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.1.0.tgz", - "integrity": "sha512-nUKAPWOaP/tQjU1IQw9sOPCDavs/iU5iYLiY/6u7gxS7oKQoi4aUxXS1nrrVGTyBBaGesjkcwwHkbkiD5eBvcg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.1.0", - "@typescript-eslint/visitor-keys": "6.1.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.1.0.tgz", - "integrity": "sha512-yQeh+EXhquh119Eis4k0kYhj9vmFzNpbhM3LftWQVwqVjipCkwHBQOZutcYW+JVkjtTG9k8nrZU1UoNedPDd1A==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.1.0", - "eslint-visitor-keys": "^3.4.1" - } - } } }, "@typescript-eslint/visitor-keys": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.0.0.tgz", - "integrity": "sha512-cvJ63l8c0yXdeT5POHpL0Q1cZoRcmRKFCtSjNGJxPkcP571EfZMcNbzWAc7oK3D1dRzm/V5EwtkANTZxqvuuUA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.1.0.tgz", + "integrity": "sha512-yQeh+EXhquh119Eis4k0kYhj9vmFzNpbhM3LftWQVwqVjipCkwHBQOZutcYW+JVkjtTG9k8nrZU1UoNedPDd1A==", "dev": true, "requires": { - "@typescript-eslint/types": "6.0.0", + "@typescript-eslint/types": "6.1.0", "eslint-visitor-keys": "^3.4.1" } }, From ec206f508570a1aa7ec886a5fedb2800a8c12f8a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Jul 2023 13:41:03 +0200 Subject: [PATCH 0421/1076] build(deps): bump serde from 1.0.171 to 1.0.173 (#4826) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.171 to 1.0.173. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.171...v1.0.173) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index dadfcdae..da21bcf8 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "0.7.0" [dependencies] borsh = "0.10" clap = "2.33.3" -serde = "1.0.171" +serde = "1.0.173" serde_derive = "1.0.130" serde_json = "1.0.102" solana-account-decoder = "=1.16.3" diff --git a/program/Cargo.toml b/program/Cargo.toml index b9747e12..9db3bc4a 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,7 +17,7 @@ borsh = "0.10" num-derive = "0.4" num-traits = "0.2" num_enum = "0.6.1" -serde = "1.0.171" +serde = "1.0.173" serde_derive = "1.0.103" solana-program = "1.16.3" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } From fd49ae63d44620ae155f4af3a8eab919ee34b66c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Jul 2023 20:18:18 +0200 Subject: [PATCH 0422/1076] build(deps): bump serde from 1.0.173 to 1.0.174 (#4831) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.173 to 1.0.174. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.173...v1.0.174) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index da21bcf8..2ef8fd59 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "0.7.0" [dependencies] borsh = "0.10" clap = "2.33.3" -serde = "1.0.173" +serde = "1.0.174" serde_derive = "1.0.130" serde_json = "1.0.102" solana-account-decoder = "=1.16.3" diff --git a/program/Cargo.toml b/program/Cargo.toml index 9db3bc4a..8997057a 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,7 +17,7 @@ borsh = "0.10" num-derive = "0.4" num-traits = "0.2" num_enum = "0.6.1" -serde = "1.0.173" +serde = "1.0.174" serde_derive = "1.0.103" solana-program = "1.16.3" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } From df4e1957caafcb1929a291b37a3139955f7f1bbf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Jul 2023 22:15:04 +0200 Subject: [PATCH 0423/1076] build(deps): bump serde_json from 1.0.102 to 1.0.103 (#4793) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.102 to 1.0.103. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.102...v1.0.103) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 2ef8fd59..62ef8953 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ borsh = "0.10" clap = "2.33.3" serde = "1.0.174" serde_derive = "1.0.130" -serde_json = "1.0.102" +serde_json = "1.0.103" solana-account-decoder = "=1.16.3" solana-clap-utils = "=1.16.3" solana-cli-config = "=1.16.3" From c107d5bdc2d441840c8e93b9a95ee7ebd351fcfc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jul 2023 14:24:59 +0200 Subject: [PATCH 0424/1076] build(deps): bump serde from 1.0.174 to 1.0.175 (#4835) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.174 to 1.0.175. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.174...v1.0.175) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 62ef8953..91bbb3d0 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "0.7.0" [dependencies] borsh = "0.10" clap = "2.33.3" -serde = "1.0.174" +serde = "1.0.175" serde_derive = "1.0.130" serde_json = "1.0.103" solana-account-decoder = "=1.16.3" diff --git a/program/Cargo.toml b/program/Cargo.toml index 8997057a..296ee1d5 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,7 +17,7 @@ borsh = "0.10" num-derive = "0.4" num-traits = "0.2" num_enum = "0.6.1" -serde = "1.0.174" +serde = "1.0.175" serde_derive = "1.0.103" solana-program = "1.16.3" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } From 9fbd24f845ecaa040818347a4c38e9f3d3450a94 Mon Sep 17 00:00:00 2001 From: HaoranYi Date: Mon, 24 Jul 2023 09:10:12 -0500 Subject: [PATCH 0425/1076] Update Stake with the additional deactivation flag (#4504) update Stake with the additional deactivation flag Co-authored-by: HaoranYi --- clients/cli/src/main.rs | 4 ++-- program/src/processor.rs | 10 +++++----- program/tests/helpers/mod.rs | 4 +++- program/tests/vsa_add.rs | 4 ++-- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index bc51c0e1..208c2307 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -683,7 +683,7 @@ fn command_deposit_stake( println!("Depositing stake account {:?}", stake_state); } let vote_account = match stake_state { - stake::state::StakeState::Stake(_, stake) => Ok(stake.delegation.voter_pubkey), + stake::state::StakeState::Stake(_, stake, _) => Ok(stake.delegation.voter_pubkey), _ => Err("Wrong stake account state, must be delegated to validator"), }?; @@ -865,7 +865,7 @@ fn command_deposit_all_stake( let stake_state = get_stake_state(&config.rpc_client, &stake_address)?; let vote_account = match stake_state { - stake::state::StakeState::Stake(_, stake) => Ok(stake.delegation.voter_pubkey), + stake::state::StakeState::Stake(_, stake, _) => Ok(stake.delegation.voter_pubkey), _ => Err("Wrong stake account state, must be delegated to validator"), }?; diff --git a/program/src/processor.rs b/program/src/processor.rs index 2ecf789c..4bc168be 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -51,7 +51,7 @@ fn get_stake_state( let stake_state = try_from_slice_unchecked::(&stake_account_info.data.borrow())?; match stake_state { - stake::state::StakeState::Stake(meta, stake) => Ok((meta, stake)), + stake::state::StakeState::Stake(meta, stake, _) => Ok((meta, stake)), _ => Err(StakePoolError::WrongStakeState.into()), } } @@ -1738,7 +1738,7 @@ impl Processor { )?; match stake_state { // if it was delegated on or before this epoch, we're good - stake::state::StakeState::Stake(_, stake) + stake::state::StakeState::Stake(_, stake, _) if stake.delegation.activation_epoch <= clock.epoch => {} // all other situations, delegate! _ => { @@ -2275,7 +2275,7 @@ impl Processor { } } } - Some(stake::state::StakeState::Stake(meta, stake)) => { + Some(stake::state::StakeState::Stake(meta, stake, _)) => { if stake_is_usable_by_pool( &meta, withdraw_authority_info.key, @@ -2297,7 +2297,7 @@ impl Processor { )?; validator_stake_record.status.remove_transient_stake(); } else if stake.delegation.activation_epoch < clock.epoch { - if let Some(stake::state::StakeState::Stake(_, validator_stake)) = + if let Some(stake::state::StakeState::Stake(_, validator_stake, _)) = validator_stake_state { if validator_stake.delegation.activation_epoch < clock.epoch { @@ -2338,7 +2338,7 @@ impl Processor { ) .ok(); match validator_stake_state { - Some(stake::state::StakeState::Stake(meta, stake)) => { + Some(stake::state::StakeState::Stake(meta, stake, _)) => { let additional_lamports = validator_stake_info .lamports() .saturating_sub(stake.delegation.stake) diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index f6620252..00697290 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -2382,7 +2382,9 @@ pub fn add_validator_stake_account( let stake_account = SolanaAccount::create( stake_amount + STAKE_ACCOUNT_RENT_EXEMPTION, bincode::serialize::(&stake::state::StakeState::Stake( - meta, stake, + meta, + stake, + stake::stake_flags::StakeFlags::empty(), )) .unwrap(), stake::program::id(), diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index 9b71900c..c21496af 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -129,7 +129,7 @@ async fn success() { let stake = get_account(&mut banks_client, &validator_stake.stake_account).await; let stake_state = deserialize::(&stake.data).unwrap(); match stake_state { - stake::state::StakeState::Stake(meta, _) => { + stake::state::StakeState::Stake(meta, _, _) => { assert_eq!( &meta.authorized.staker, &stake_pool_accounts.withdraw_authority @@ -595,7 +595,7 @@ async fn success_with_lamports_in_account() { let stake = get_account(&mut banks_client, &validator_stake.stake_account).await; let stake_state = deserialize::(&stake.data).unwrap(); match stake_state { - stake::state::StakeState::Stake(meta, _) => { + stake::state::StakeState::Stake(meta, _, _) => { assert_eq!( &meta.authorized.staker, &stake_pool_accounts.withdraw_authority From cbaaa6ddd0e897a7e0284ef1829590f1ebe9ef0b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jul 2023 17:12:37 +0200 Subject: [PATCH 0426/1076] build(deps-dev): bump @types/node from 20.4.2 to 20.4.4 in /stake-pool/js (#4838) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.4.2 to 20.4.4. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index e4fb6f2e..625b345b 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1757,9 +1757,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.4.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.2.tgz", - "integrity": "sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==" + "version": "20.4.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.4.tgz", + "integrity": "sha512-CukZhumInROvLq3+b5gLev+vgpsIqC2D0deQr/yS1WnxvmYLlJXZpaQrQiseMY+6xusl79E04UjWoqyr+t1/Ew==" }, "node_modules/@types/node-fetch": { "version": "2.6.4", @@ -8343,9 +8343,9 @@ "dev": true }, "@types/node": { - "version": "20.4.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.2.tgz", - "integrity": "sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==" + "version": "20.4.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.4.tgz", + "integrity": "sha512-CukZhumInROvLq3+b5gLev+vgpsIqC2D0deQr/yS1WnxvmYLlJXZpaQrQiseMY+6xusl79E04UjWoqyr+t1/Ew==" }, "@types/node-fetch": { "version": "2.6.4", From 516e93cf30c91c7b7f5593a19fa9dfd9bab56c4c Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Mon, 24 Jul 2023 17:37:11 +0200 Subject: [PATCH 0427/1076] Revert "Update Stake with the additional deactivation flag (#4504)" (#4841) This reverts commit 02b3bc6c4551fb7da7ac210663df0878b1b196f1. --- clients/cli/src/main.rs | 4 ++-- program/src/processor.rs | 10 +++++----- program/tests/helpers/mod.rs | 4 +--- program/tests/vsa_add.rs | 4 ++-- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 208c2307..bc51c0e1 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -683,7 +683,7 @@ fn command_deposit_stake( println!("Depositing stake account {:?}", stake_state); } let vote_account = match stake_state { - stake::state::StakeState::Stake(_, stake, _) => Ok(stake.delegation.voter_pubkey), + stake::state::StakeState::Stake(_, stake) => Ok(stake.delegation.voter_pubkey), _ => Err("Wrong stake account state, must be delegated to validator"), }?; @@ -865,7 +865,7 @@ fn command_deposit_all_stake( let stake_state = get_stake_state(&config.rpc_client, &stake_address)?; let vote_account = match stake_state { - stake::state::StakeState::Stake(_, stake, _) => Ok(stake.delegation.voter_pubkey), + stake::state::StakeState::Stake(_, stake) => Ok(stake.delegation.voter_pubkey), _ => Err("Wrong stake account state, must be delegated to validator"), }?; diff --git a/program/src/processor.rs b/program/src/processor.rs index 4bc168be..2ecf789c 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -51,7 +51,7 @@ fn get_stake_state( let stake_state = try_from_slice_unchecked::(&stake_account_info.data.borrow())?; match stake_state { - stake::state::StakeState::Stake(meta, stake, _) => Ok((meta, stake)), + stake::state::StakeState::Stake(meta, stake) => Ok((meta, stake)), _ => Err(StakePoolError::WrongStakeState.into()), } } @@ -1738,7 +1738,7 @@ impl Processor { )?; match stake_state { // if it was delegated on or before this epoch, we're good - stake::state::StakeState::Stake(_, stake, _) + stake::state::StakeState::Stake(_, stake) if stake.delegation.activation_epoch <= clock.epoch => {} // all other situations, delegate! _ => { @@ -2275,7 +2275,7 @@ impl Processor { } } } - Some(stake::state::StakeState::Stake(meta, stake, _)) => { + Some(stake::state::StakeState::Stake(meta, stake)) => { if stake_is_usable_by_pool( &meta, withdraw_authority_info.key, @@ -2297,7 +2297,7 @@ impl Processor { )?; validator_stake_record.status.remove_transient_stake(); } else if stake.delegation.activation_epoch < clock.epoch { - if let Some(stake::state::StakeState::Stake(_, validator_stake, _)) = + if let Some(stake::state::StakeState::Stake(_, validator_stake)) = validator_stake_state { if validator_stake.delegation.activation_epoch < clock.epoch { @@ -2338,7 +2338,7 @@ impl Processor { ) .ok(); match validator_stake_state { - Some(stake::state::StakeState::Stake(meta, stake, _)) => { + Some(stake::state::StakeState::Stake(meta, stake)) => { let additional_lamports = validator_stake_info .lamports() .saturating_sub(stake.delegation.stake) diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 00697290..f6620252 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -2382,9 +2382,7 @@ pub fn add_validator_stake_account( let stake_account = SolanaAccount::create( stake_amount + STAKE_ACCOUNT_RENT_EXEMPTION, bincode::serialize::(&stake::state::StakeState::Stake( - meta, - stake, - stake::stake_flags::StakeFlags::empty(), + meta, stake, )) .unwrap(), stake::program::id(), diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index c21496af..9b71900c 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -129,7 +129,7 @@ async fn success() { let stake = get_account(&mut banks_client, &validator_stake.stake_account).await; let stake_state = deserialize::(&stake.data).unwrap(); match stake_state { - stake::state::StakeState::Stake(meta, _, _) => { + stake::state::StakeState::Stake(meta, _) => { assert_eq!( &meta.authorized.staker, &stake_pool_accounts.withdraw_authority @@ -595,7 +595,7 @@ async fn success_with_lamports_in_account() { let stake = get_account(&mut banks_client, &validator_stake.stake_account).await; let stake_state = deserialize::(&stake.data).unwrap(); match stake_state { - stake::state::StakeState::Stake(meta, _, _) => { + stake::state::StakeState::Stake(meta, _) => { assert_eq!( &meta.authorized.staker, &stake_pool_accounts.withdraw_authority From a8d497b691bf2e13404320f1aa2583e3166dfb32 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Jul 2023 17:14:13 +0200 Subject: [PATCH 0428/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.1.0 to 6.2.0 in /stake-pool/js (#4852) build(deps-dev): bump @typescript-eslint/eslint-plugin in /stake-pool/js Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.1.0 to 6.2.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.2.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 354 +++++++++++++++++++++++++--- 1 file changed, 318 insertions(+), 36 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 625b345b..96045be3 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1819,16 +1819,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.1.0.tgz", - "integrity": "sha512-qg7Bm5TyP/I7iilGyp6DRqqkt8na00lI6HbjWZObgk3FFSzH5ypRwAHXJhJkwiRtTcfn+xYQIMOR5kJgpo6upw==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.2.0.tgz", + "integrity": "sha512-rClGrMuyS/3j0ETa1Ui7s6GkLhfZGKZL3ZrChLeAiACBE/tRc1wq8SNZESUuluxhLj9FkUefRs2l6bCIArWBiQ==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.1.0", - "@typescript-eslint/type-utils": "6.1.0", - "@typescript-eslint/utils": "6.1.0", - "@typescript-eslint/visitor-keys": "6.1.0", + "@typescript-eslint/scope-manager": "6.2.0", + "@typescript-eslint/type-utils": "6.2.0", + "@typescript-eslint/utils": "6.2.0", + "@typescript-eslint/visitor-keys": "6.2.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -1854,6 +1854,53 @@ } } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.0.tgz", + "integrity": "sha512-1ZMNVgm5nnHURU8ZSJ3snsHzpFeNK84rdZjluEVBGNu7jDymfqceB3kdIZ6A4xCfEFFhRIB6rF8q/JIqJd2R0Q==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.2.0", + "@typescript-eslint/visitor-keys": "6.2.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.0.tgz", + "integrity": "sha512-1nRRaDlp/XYJQLvkQJG5F3uBTno5SHPT7XVcJ5n1/k2WfNI28nJsvLakxwZRNY5spuatEKO7d5nZWsQpkqXwBA==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.0.tgz", + "integrity": "sha512-QbaYUQVKKo9bgCzpjz45llCfwakyoxHetIy8CAvYCtd16Zu1KrpzNHofwF8kGkpPOxZB2o6kz+0nqH8ZkIzuoQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.2.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/parser": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.1.0.tgz", @@ -1900,13 +1947,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.1.0.tgz", - "integrity": "sha512-kFXBx6QWS1ZZ5Ni89TyT1X9Ag6RXVIVhqDs0vZE/jUeWlBv/ixq2diua6G7ece6+fXw3TvNRxP77/5mOMusx2w==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.2.0.tgz", + "integrity": "sha512-DnGZuNU2JN3AYwddYIqrVkYW0uUQdv0AY+kz2M25euVNlujcN2u+rJgfJsBFlUEzBB6OQkUqSZPyuTLf2bP5mw==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.1.0", - "@typescript-eslint/utils": "6.1.0", + "@typescript-eslint/typescript-estree": "6.2.0", + "@typescript-eslint/utils": "6.2.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -1926,6 +1973,63 @@ } } }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.0.tgz", + "integrity": "sha512-1nRRaDlp/XYJQLvkQJG5F3uBTno5SHPT7XVcJ5n1/k2WfNI28nJsvLakxwZRNY5spuatEKO7d5nZWsQpkqXwBA==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.0.tgz", + "integrity": "sha512-Mts6+3HQMSM+LZCglsc2yMIny37IhUgp1Qe8yJUYVyO6rHP7/vN0vajKu3JvHCBIy8TSiKddJ/Zwu80jhnGj1w==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.2.0", + "@typescript-eslint/visitor-keys": "6.2.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.0.tgz", + "integrity": "sha512-QbaYUQVKKo9bgCzpjz45llCfwakyoxHetIy8CAvYCtd16Zu1KrpzNHofwF8kGkpPOxZB2o6kz+0nqH8ZkIzuoQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.2.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/types": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.1.0.tgz", @@ -1967,17 +2071,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.1.0.tgz", - "integrity": "sha512-wp652EogZlKmQoMS5hAvWqRKplXvkuOnNzZSE0PVvsKjpexd/XznRVHAtrfHFYmqaJz0DFkjlDsGYC9OXw+OhQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.2.0.tgz", + "integrity": "sha512-RCFrC1lXiX1qEZN8LmLrxYRhOkElEsPKTVSNout8DMzf8PeWoQG7Rxz2SadpJa3VSh5oYKGwt7j7X/VRg+Y3OQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.1.0", - "@typescript-eslint/types": "6.1.0", - "@typescript-eslint/typescript-estree": "6.1.0", + "@typescript-eslint/scope-manager": "6.2.0", + "@typescript-eslint/types": "6.2.0", + "@typescript-eslint/typescript-estree": "6.2.0", "semver": "^7.5.4" }, "engines": { @@ -1991,6 +2095,80 @@ "eslint": "^7.0.0 || ^8.0.0" } }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.0.tgz", + "integrity": "sha512-1ZMNVgm5nnHURU8ZSJ3snsHzpFeNK84rdZjluEVBGNu7jDymfqceB3kdIZ6A4xCfEFFhRIB6rF8q/JIqJd2R0Q==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.2.0", + "@typescript-eslint/visitor-keys": "6.2.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.0.tgz", + "integrity": "sha512-1nRRaDlp/XYJQLvkQJG5F3uBTno5SHPT7XVcJ5n1/k2WfNI28nJsvLakxwZRNY5spuatEKO7d5nZWsQpkqXwBA==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.0.tgz", + "integrity": "sha512-Mts6+3HQMSM+LZCglsc2yMIny37IhUgp1Qe8yJUYVyO6rHP7/vN0vajKu3JvHCBIy8TSiKddJ/Zwu80jhnGj1w==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.2.0", + "@typescript-eslint/visitor-keys": "6.2.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.0.tgz", + "integrity": "sha512-QbaYUQVKKo9bgCzpjz45llCfwakyoxHetIy8CAvYCtd16Zu1KrpzNHofwF8kGkpPOxZB2o6kz+0nqH8ZkIzuoQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.2.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/visitor-keys": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.1.0.tgz", @@ -8405,16 +8583,16 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.1.0.tgz", - "integrity": "sha512-qg7Bm5TyP/I7iilGyp6DRqqkt8na00lI6HbjWZObgk3FFSzH5ypRwAHXJhJkwiRtTcfn+xYQIMOR5kJgpo6upw==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.2.0.tgz", + "integrity": "sha512-rClGrMuyS/3j0ETa1Ui7s6GkLhfZGKZL3ZrChLeAiACBE/tRc1wq8SNZESUuluxhLj9FkUefRs2l6bCIArWBiQ==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.1.0", - "@typescript-eslint/type-utils": "6.1.0", - "@typescript-eslint/utils": "6.1.0", - "@typescript-eslint/visitor-keys": "6.1.0", + "@typescript-eslint/scope-manager": "6.2.0", + "@typescript-eslint/type-utils": "6.2.0", + "@typescript-eslint/utils": "6.2.0", + "@typescript-eslint/visitor-keys": "6.2.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -8422,6 +8600,34 @@ "natural-compare-lite": "^1.4.0", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.0.tgz", + "integrity": "sha512-1ZMNVgm5nnHURU8ZSJ3snsHzpFeNK84rdZjluEVBGNu7jDymfqceB3kdIZ6A4xCfEFFhRIB6rF8q/JIqJd2R0Q==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.2.0", + "@typescript-eslint/visitor-keys": "6.2.0" + } + }, + "@typescript-eslint/types": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.0.tgz", + "integrity": "sha512-1nRRaDlp/XYJQLvkQJG5F3uBTno5SHPT7XVcJ5n1/k2WfNI28nJsvLakxwZRNY5spuatEKO7d5nZWsQpkqXwBA==", + "dev": true + }, + "@typescript-eslint/visitor-keys": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.0.tgz", + "integrity": "sha512-QbaYUQVKKo9bgCzpjz45llCfwakyoxHetIy8CAvYCtd16Zu1KrpzNHofwF8kGkpPOxZB2o6kz+0nqH8ZkIzuoQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.2.0", + "eslint-visitor-keys": "^3.4.1" + } + } } }, "@typescript-eslint/parser": { @@ -8448,15 +8654,48 @@ } }, "@typescript-eslint/type-utils": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.1.0.tgz", - "integrity": "sha512-kFXBx6QWS1ZZ5Ni89TyT1X9Ag6RXVIVhqDs0vZE/jUeWlBv/ixq2diua6G7ece6+fXw3TvNRxP77/5mOMusx2w==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.2.0.tgz", + "integrity": "sha512-DnGZuNU2JN3AYwddYIqrVkYW0uUQdv0AY+kz2M25euVNlujcN2u+rJgfJsBFlUEzBB6OQkUqSZPyuTLf2bP5mw==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "6.1.0", - "@typescript-eslint/utils": "6.1.0", + "@typescript-eslint/typescript-estree": "6.2.0", + "@typescript-eslint/utils": "6.2.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" + }, + "dependencies": { + "@typescript-eslint/types": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.0.tgz", + "integrity": "sha512-1nRRaDlp/XYJQLvkQJG5F3uBTno5SHPT7XVcJ5n1/k2WfNI28nJsvLakxwZRNY5spuatEKO7d5nZWsQpkqXwBA==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.0.tgz", + "integrity": "sha512-Mts6+3HQMSM+LZCglsc2yMIny37IhUgp1Qe8yJUYVyO6rHP7/vN0vajKu3JvHCBIy8TSiKddJ/Zwu80jhnGj1w==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.2.0", + "@typescript-eslint/visitor-keys": "6.2.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.0.tgz", + "integrity": "sha512-QbaYUQVKKo9bgCzpjz45llCfwakyoxHetIy8CAvYCtd16Zu1KrpzNHofwF8kGkpPOxZB2o6kz+0nqH8ZkIzuoQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.2.0", + "eslint-visitor-keys": "^3.4.1" + } + } } }, "@typescript-eslint/types": { @@ -8481,18 +8720,61 @@ } }, "@typescript-eslint/utils": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.1.0.tgz", - "integrity": "sha512-wp652EogZlKmQoMS5hAvWqRKplXvkuOnNzZSE0PVvsKjpexd/XznRVHAtrfHFYmqaJz0DFkjlDsGYC9OXw+OhQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.2.0.tgz", + "integrity": "sha512-RCFrC1lXiX1qEZN8LmLrxYRhOkElEsPKTVSNout8DMzf8PeWoQG7Rxz2SadpJa3VSh5oYKGwt7j7X/VRg+Y3OQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.1.0", - "@typescript-eslint/types": "6.1.0", - "@typescript-eslint/typescript-estree": "6.1.0", + "@typescript-eslint/scope-manager": "6.2.0", + "@typescript-eslint/types": "6.2.0", + "@typescript-eslint/typescript-estree": "6.2.0", "semver": "^7.5.4" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.0.tgz", + "integrity": "sha512-1ZMNVgm5nnHURU8ZSJ3snsHzpFeNK84rdZjluEVBGNu7jDymfqceB3kdIZ6A4xCfEFFhRIB6rF8q/JIqJd2R0Q==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.2.0", + "@typescript-eslint/visitor-keys": "6.2.0" + } + }, + "@typescript-eslint/types": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.0.tgz", + "integrity": "sha512-1nRRaDlp/XYJQLvkQJG5F3uBTno5SHPT7XVcJ5n1/k2WfNI28nJsvLakxwZRNY5spuatEKO7d5nZWsQpkqXwBA==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.0.tgz", + "integrity": "sha512-Mts6+3HQMSM+LZCglsc2yMIny37IhUgp1Qe8yJUYVyO6rHP7/vN0vajKu3JvHCBIy8TSiKddJ/Zwu80jhnGj1w==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.2.0", + "@typescript-eslint/visitor-keys": "6.2.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.0.tgz", + "integrity": "sha512-QbaYUQVKKo9bgCzpjz45llCfwakyoxHetIy8CAvYCtd16Zu1KrpzNHofwF8kGkpPOxZB2o6kz+0nqH8ZkIzuoQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.2.0", + "eslint-visitor-keys": "^3.4.1" + } + } } }, "@typescript-eslint/visitor-keys": { From 37411ef0793ff4a3a7b5596ecd596e452599b0cd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Jul 2023 18:05:41 +0200 Subject: [PATCH 0429/1076] build(deps-dev): bump @typescript-eslint/parser from 6.1.0 to 6.2.0 in /stake-pool/js (#4851) build(deps-dev): bump @typescript-eslint/parser in /stake-pool/js Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.1.0 to 6.2.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.2.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 358 +++------------------------- 1 file changed, 38 insertions(+), 320 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 96045be3..b5ab219f 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1854,63 +1854,16 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.0.tgz", - "integrity": "sha512-1ZMNVgm5nnHURU8ZSJ3snsHzpFeNK84rdZjluEVBGNu7jDymfqceB3kdIZ6A4xCfEFFhRIB6rF8q/JIqJd2R0Q==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.2.0", - "@typescript-eslint/visitor-keys": "6.2.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.0.tgz", - "integrity": "sha512-1nRRaDlp/XYJQLvkQJG5F3uBTno5SHPT7XVcJ5n1/k2WfNI28nJsvLakxwZRNY5spuatEKO7d5nZWsQpkqXwBA==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "node_modules/@typescript-eslint/parser": { "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.0.tgz", - "integrity": "sha512-QbaYUQVKKo9bgCzpjz45llCfwakyoxHetIy8CAvYCtd16Zu1KrpzNHofwF8kGkpPOxZB2o6kz+0nqH8ZkIzuoQ==", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.2.0.tgz", + "integrity": "sha512-igVYOqtiK/UsvKAmmloQAruAdUHihsOCvplJpplPZ+3h4aDkC/UKZZNKgB6h93ayuYLuEymU3h8nF1xMRbh37g==", "dev": true, "dependencies": { + "@typescript-eslint/scope-manager": "6.2.0", "@typescript-eslint/types": "6.2.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.1.0.tgz", - "integrity": "sha512-hIzCPvX4vDs4qL07SYzyomamcs2/tQYXg5DtdAfj35AyJ5PIUqhsLf4YrEIFzZcND7R2E8tpQIZKayxg8/6Wbw==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "6.1.0", - "@typescript-eslint/types": "6.1.0", - "@typescript-eslint/typescript-estree": "6.1.0", - "@typescript-eslint/visitor-keys": "6.1.0", + "@typescript-eslint/typescript-estree": "6.2.0", + "@typescript-eslint/visitor-keys": "6.2.0", "debug": "^4.3.4" }, "engines": { @@ -1930,13 +1883,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.1.0.tgz", - "integrity": "sha512-AxjgxDn27hgPpe2rQe19k0tXw84YCOsjDJ2r61cIebq1t+AIxbgiXKvD4999Wk49GVaAcdJ/d49FYel+Pp3jjw==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.0.tgz", + "integrity": "sha512-1ZMNVgm5nnHURU8ZSJ3snsHzpFeNK84rdZjluEVBGNu7jDymfqceB3kdIZ6A4xCfEFFhRIB6rF8q/JIqJd2R0Q==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.1.0", - "@typescript-eslint/visitor-keys": "6.1.0" + "@typescript-eslint/types": "6.2.0", + "@typescript-eslint/visitor-keys": "6.2.0" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -1973,7 +1926,7 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "node_modules/@typescript-eslint/types": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.0.tgz", "integrity": "sha512-1nRRaDlp/XYJQLvkQJG5F3uBTno5SHPT7XVcJ5n1/k2WfNI28nJsvLakxwZRNY5spuatEKO7d5nZWsQpkqXwBA==", @@ -1986,7 +1939,7 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "node_modules/@typescript-eslint/typescript-estree": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.0.tgz", "integrity": "sha512-Mts6+3HQMSM+LZCglsc2yMIny37IhUgp1Qe8yJUYVyO6rHP7/vN0vajKu3JvHCBIy8TSiKddJ/Zwu80jhnGj1w==", @@ -2013,63 +1966,6 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.0.tgz", - "integrity": "sha512-QbaYUQVKKo9bgCzpjz45llCfwakyoxHetIy8CAvYCtd16Zu1KrpzNHofwF8kGkpPOxZB2o6kz+0nqH8ZkIzuoQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.2.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.1.0.tgz", - "integrity": "sha512-+Gfd5NHCpDoHDOaU/yIF3WWRI2PcBRKKpP91ZcVbL0t5tQpqYWBs3z/GGhvU+EV1D0262g9XCnyqQh19prU0JQ==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.1.0.tgz", - "integrity": "sha512-nUKAPWOaP/tQjU1IQw9sOPCDavs/iU5iYLiY/6u7gxS7oKQoi4aUxXS1nrrVGTyBBaGesjkcwwHkbkiD5eBvcg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.1.0", - "@typescript-eslint/visitor-keys": "6.1.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, "node_modules/@typescript-eslint/utils": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.2.0.tgz", @@ -2095,64 +1991,7 @@ "eslint": "^7.0.0 || ^8.0.0" } }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.0.tgz", - "integrity": "sha512-1ZMNVgm5nnHURU8ZSJ3snsHzpFeNK84rdZjluEVBGNu7jDymfqceB3kdIZ6A4xCfEFFhRIB6rF8q/JIqJd2R0Q==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.2.0", - "@typescript-eslint/visitor-keys": "6.2.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.0.tgz", - "integrity": "sha512-1nRRaDlp/XYJQLvkQJG5F3uBTno5SHPT7XVcJ5n1/k2WfNI28nJsvLakxwZRNY5spuatEKO7d5nZWsQpkqXwBA==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.0.tgz", - "integrity": "sha512-Mts6+3HQMSM+LZCglsc2yMIny37IhUgp1Qe8yJUYVyO6rHP7/vN0vajKu3JvHCBIy8TSiKddJ/Zwu80jhnGj1w==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.2.0", - "@typescript-eslint/visitor-keys": "6.2.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "node_modules/@typescript-eslint/visitor-keys": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.0.tgz", "integrity": "sha512-QbaYUQVKKo9bgCzpjz45llCfwakyoxHetIy8CAvYCtd16Zu1KrpzNHofwF8kGkpPOxZB2o6kz+0nqH8ZkIzuoQ==", @@ -2169,23 +2008,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.1.0.tgz", - "integrity": "sha512-yQeh+EXhquh119Eis4k0kYhj9vmFzNpbhM3LftWQVwqVjipCkwHBQOZutcYW+JVkjtTG9k8nrZU1UoNedPDd1A==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.1.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/abab": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", @@ -8600,57 +8422,29 @@ "natural-compare-lite": "^1.4.0", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.0.tgz", - "integrity": "sha512-1ZMNVgm5nnHURU8ZSJ3snsHzpFeNK84rdZjluEVBGNu7jDymfqceB3kdIZ6A4xCfEFFhRIB6rF8q/JIqJd2R0Q==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.2.0", - "@typescript-eslint/visitor-keys": "6.2.0" - } - }, - "@typescript-eslint/types": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.0.tgz", - "integrity": "sha512-1nRRaDlp/XYJQLvkQJG5F3uBTno5SHPT7XVcJ5n1/k2WfNI28nJsvLakxwZRNY5spuatEKO7d5nZWsQpkqXwBA==", - "dev": true - }, - "@typescript-eslint/visitor-keys": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.0.tgz", - "integrity": "sha512-QbaYUQVKKo9bgCzpjz45llCfwakyoxHetIy8CAvYCtd16Zu1KrpzNHofwF8kGkpPOxZB2o6kz+0nqH8ZkIzuoQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.2.0", - "eslint-visitor-keys": "^3.4.1" - } - } } }, "@typescript-eslint/parser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.1.0.tgz", - "integrity": "sha512-hIzCPvX4vDs4qL07SYzyomamcs2/tQYXg5DtdAfj35AyJ5PIUqhsLf4YrEIFzZcND7R2E8tpQIZKayxg8/6Wbw==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.2.0.tgz", + "integrity": "sha512-igVYOqtiK/UsvKAmmloQAruAdUHihsOCvplJpplPZ+3h4aDkC/UKZZNKgB6h93ayuYLuEymU3h8nF1xMRbh37g==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "6.1.0", - "@typescript-eslint/types": "6.1.0", - "@typescript-eslint/typescript-estree": "6.1.0", - "@typescript-eslint/visitor-keys": "6.1.0", + "@typescript-eslint/scope-manager": "6.2.0", + "@typescript-eslint/types": "6.2.0", + "@typescript-eslint/typescript-estree": "6.2.0", + "@typescript-eslint/visitor-keys": "6.2.0", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.1.0.tgz", - "integrity": "sha512-AxjgxDn27hgPpe2rQe19k0tXw84YCOsjDJ2r61cIebq1t+AIxbgiXKvD4999Wk49GVaAcdJ/d49FYel+Pp3jjw==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.0.tgz", + "integrity": "sha512-1ZMNVgm5nnHURU8ZSJ3snsHzpFeNK84rdZjluEVBGNu7jDymfqceB3kdIZ6A4xCfEFFhRIB6rF8q/JIqJd2R0Q==", "dev": true, "requires": { - "@typescript-eslint/types": "6.1.0", - "@typescript-eslint/visitor-keys": "6.1.0" + "@typescript-eslint/types": "6.2.0", + "@typescript-eslint/visitor-keys": "6.2.0" } }, "@typescript-eslint/type-utils": { @@ -8663,55 +8457,22 @@ "@typescript-eslint/utils": "6.2.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" - }, - "dependencies": { - "@typescript-eslint/types": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.0.tgz", - "integrity": "sha512-1nRRaDlp/XYJQLvkQJG5F3uBTno5SHPT7XVcJ5n1/k2WfNI28nJsvLakxwZRNY5spuatEKO7d5nZWsQpkqXwBA==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.0.tgz", - "integrity": "sha512-Mts6+3HQMSM+LZCglsc2yMIny37IhUgp1Qe8yJUYVyO6rHP7/vN0vajKu3JvHCBIy8TSiKddJ/Zwu80jhnGj1w==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.2.0", - "@typescript-eslint/visitor-keys": "6.2.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.0.tgz", - "integrity": "sha512-QbaYUQVKKo9bgCzpjz45llCfwakyoxHetIy8CAvYCtd16Zu1KrpzNHofwF8kGkpPOxZB2o6kz+0nqH8ZkIzuoQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.2.0", - "eslint-visitor-keys": "^3.4.1" - } - } } }, "@typescript-eslint/types": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.1.0.tgz", - "integrity": "sha512-+Gfd5NHCpDoHDOaU/yIF3WWRI2PcBRKKpP91ZcVbL0t5tQpqYWBs3z/GGhvU+EV1D0262g9XCnyqQh19prU0JQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.0.tgz", + "integrity": "sha512-1nRRaDlp/XYJQLvkQJG5F3uBTno5SHPT7XVcJ5n1/k2WfNI28nJsvLakxwZRNY5spuatEKO7d5nZWsQpkqXwBA==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.1.0.tgz", - "integrity": "sha512-nUKAPWOaP/tQjU1IQw9sOPCDavs/iU5iYLiY/6u7gxS7oKQoi4aUxXS1nrrVGTyBBaGesjkcwwHkbkiD5eBvcg==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.0.tgz", + "integrity": "sha512-Mts6+3HQMSM+LZCglsc2yMIny37IhUgp1Qe8yJUYVyO6rHP7/vN0vajKu3JvHCBIy8TSiKddJ/Zwu80jhnGj1w==", "dev": true, "requires": { - "@typescript-eslint/types": "6.1.0", - "@typescript-eslint/visitor-keys": "6.1.0", + "@typescript-eslint/types": "6.2.0", + "@typescript-eslint/visitor-keys": "6.2.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -8732,58 +8493,15 @@ "@typescript-eslint/types": "6.2.0", "@typescript-eslint/typescript-estree": "6.2.0", "semver": "^7.5.4" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.0.tgz", - "integrity": "sha512-1ZMNVgm5nnHURU8ZSJ3snsHzpFeNK84rdZjluEVBGNu7jDymfqceB3kdIZ6A4xCfEFFhRIB6rF8q/JIqJd2R0Q==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.2.0", - "@typescript-eslint/visitor-keys": "6.2.0" - } - }, - "@typescript-eslint/types": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.0.tgz", - "integrity": "sha512-1nRRaDlp/XYJQLvkQJG5F3uBTno5SHPT7XVcJ5n1/k2WfNI28nJsvLakxwZRNY5spuatEKO7d5nZWsQpkqXwBA==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.0.tgz", - "integrity": "sha512-Mts6+3HQMSM+LZCglsc2yMIny37IhUgp1Qe8yJUYVyO6rHP7/vN0vajKu3JvHCBIy8TSiKddJ/Zwu80jhnGj1w==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.2.0", - "@typescript-eslint/visitor-keys": "6.2.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.0.tgz", - "integrity": "sha512-QbaYUQVKKo9bgCzpjz45llCfwakyoxHetIy8CAvYCtd16Zu1KrpzNHofwF8kGkpPOxZB2o6kz+0nqH8ZkIzuoQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.2.0", - "eslint-visitor-keys": "^3.4.1" - } - } } }, "@typescript-eslint/visitor-keys": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.1.0.tgz", - "integrity": "sha512-yQeh+EXhquh119Eis4k0kYhj9vmFzNpbhM3LftWQVwqVjipCkwHBQOZutcYW+JVkjtTG9k8nrZU1UoNedPDd1A==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.0.tgz", + "integrity": "sha512-QbaYUQVKKo9bgCzpjz45llCfwakyoxHetIy8CAvYCtd16Zu1KrpzNHofwF8kGkpPOxZB2o6kz+0nqH8ZkIzuoQ==", "dev": true, "requires": { - "@typescript-eslint/types": "6.1.0", + "@typescript-eslint/types": "6.2.0", "eslint-visitor-keys": "^3.4.1" } }, From 5495c95904db2b6531b2f806c299cbb01452ff5e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Jul 2023 18:06:01 +0200 Subject: [PATCH 0430/1076] build(deps): bump certifi from 2022.12.7 to 2023.7.22 in /stake-pool/py (#4855) Bumps [certifi](https://github.com/certifi/python-certifi) from 2022.12.7 to 2023.7.22. - [Commits](https://github.com/certifi/python-certifi/compare/2022.12.07...2023.07.22) --- updated-dependencies: - dependency-name: certifi dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/py/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/py/requirements.txt b/clients/py/requirements.txt index 6469d765..3367e7fd 100644 --- a/clients/py/requirements.txt +++ b/clients/py/requirements.txt @@ -1,7 +1,7 @@ anyio==3.6.1 base58==2.1.1 cachetools==4.2.4 -certifi==2022.12.7 +certifi==2023.7.22 cffi==1.15.1 charset-normalizer==2.1.0 construct==2.10.68 From d3b1d5624c3d5f0ee6c848e512927e45e6571358 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 26 Jul 2023 17:17:01 +0200 Subject: [PATCH 0431/1076] build(deps-dev): bump @types/node from 20.4.4 to 20.4.5 in /stake-pool/js (#4861) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.4.4 to 20.4.5. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index b5ab219f..2ae4088e 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1757,9 +1757,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.4.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.4.tgz", - "integrity": "sha512-CukZhumInROvLq3+b5gLev+vgpsIqC2D0deQr/yS1WnxvmYLlJXZpaQrQiseMY+6xusl79E04UjWoqyr+t1/Ew==" + "version": "20.4.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.5.tgz", + "integrity": "sha512-rt40Nk13II9JwQBdeYqmbn2Q6IVTA5uPhvSO+JVqdXw/6/4glI6oR9ezty/A9Hg5u7JH4OmYmuQ+XvjKm0Datg==" }, "node_modules/@types/node-fetch": { "version": "2.6.4", @@ -8343,9 +8343,9 @@ "dev": true }, "@types/node": { - "version": "20.4.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.4.tgz", - "integrity": "sha512-CukZhumInROvLq3+b5gLev+vgpsIqC2D0deQr/yS1WnxvmYLlJXZpaQrQiseMY+6xusl79E04UjWoqyr+t1/Ew==" + "version": "20.4.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.5.tgz", + "integrity": "sha512-rt40Nk13II9JwQBdeYqmbn2Q6IVTA5uPhvSO+JVqdXw/6/4glI6oR9ezty/A9Hg5u7JH4OmYmuQ+XvjKm0Datg==" }, "@types/node-fetch": { "version": "2.6.4", From 5f515b32ffe2a36e3778f04531d08c4e142b158c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Jul 2023 13:43:18 +0200 Subject: [PATCH 0432/1076] build(deps): bump serde from 1.0.175 to 1.0.176 (#4865) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.175 to 1.0.176. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.175...v1.0.176) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 91bbb3d0..f2e81871 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "0.7.0" [dependencies] borsh = "0.10" clap = "2.33.3" -serde = "1.0.175" +serde = "1.0.176" serde_derive = "1.0.130" serde_json = "1.0.103" solana-account-decoder = "=1.16.3" diff --git a/program/Cargo.toml b/program/Cargo.toml index 296ee1d5..5349b8e0 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,7 +17,7 @@ borsh = "0.10" num-derive = "0.4" num-traits = "0.2" num_enum = "0.6.1" -serde = "1.0.175" +serde = "1.0.176" serde_derive = "1.0.103" solana-program = "1.16.3" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } From c0432c48b39910006806e04033116459e85e4d44 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Jul 2023 13:43:32 +0200 Subject: [PATCH 0433/1076] build(deps): bump serde_json from 1.0.103 to 1.0.104 (#4866) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.103 to 1.0.104. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.103...v1.0.104) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index f2e81871..6220b778 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ borsh = "0.10" clap = "2.33.3" serde = "1.0.176" serde_derive = "1.0.130" -serde_json = "1.0.103" +serde_json = "1.0.104" solana-account-decoder = "=1.16.3" solana-clap-utils = "=1.16.3" solana-cli-config = "=1.16.3" From ae362261d0bb94b5f07dffc924efe847037af12d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Jul 2023 15:39:16 +0200 Subject: [PATCH 0434/1076] build(deps-dev): bump eslint-config-prettier from 8.8.0 to 8.9.0 in /stake-pool/js (#4867) build(deps-dev): bump eslint-config-prettier in /stake-pool/js Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 8.8.0 to 8.9.0. - [Changelog](https://github.com/prettier/eslint-config-prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/eslint-config-prettier/compare/v8.8.0...v8.9.0) --- updated-dependencies: - dependency-name: eslint-config-prettier dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 2ae4088e..c896ac68 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -3262,9 +3262,9 @@ } }, "node_modules/eslint-config-prettier": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz", - "integrity": "sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==", + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.9.0.tgz", + "integrity": "sha512-+sbni7NfVXnOpnRadUA8S28AUlsZt9GjgFvABIRL9Hkn8KqNzOp+7Lw4QWtrwn20KzU3wqu1QoOj2m+7rKRqkA==", "dev": true, "bin": { "eslint-config-prettier": "bin/cli.js" @@ -9478,9 +9478,9 @@ } }, "eslint-config-prettier": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz", - "integrity": "sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==", + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.9.0.tgz", + "integrity": "sha512-+sbni7NfVXnOpnRadUA8S28AUlsZt9GjgFvABIRL9Hkn8KqNzOp+7Lw4QWtrwn20KzU3wqu1QoOj2m+7rKRqkA==", "dev": true, "requires": {} }, From f43f25d2f9d548e9c003dc13f7893ad2bf77f831 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Jul 2023 12:53:19 +0200 Subject: [PATCH 0435/1076] build(deps): bump serde from 1.0.176 to 1.0.177 (#4872) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.176 to 1.0.177. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.176...v1.0.177) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 6220b778..bf4bb2ac 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "0.7.0" [dependencies] borsh = "0.10" clap = "2.33.3" -serde = "1.0.176" +serde = "1.0.177" serde_derive = "1.0.130" serde_json = "1.0.104" solana-account-decoder = "=1.16.3" diff --git a/program/Cargo.toml b/program/Cargo.toml index 5349b8e0..23f55565 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,7 +17,7 @@ borsh = "0.10" num-derive = "0.4" num-traits = "0.2" num_enum = "0.6.1" -serde = "1.0.176" +serde = "1.0.177" serde_derive = "1.0.103" solana-program = "1.16.3" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } From 5577c6232191413b32cb2042f057127c18be7ffe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Jul 2023 12:50:58 +0200 Subject: [PATCH 0436/1076] build(deps): bump serde from 1.0.177 to 1.0.179 (#4879) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.177 to 1.0.179. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.177...v1.0.179) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index bf4bb2ac..e2b63a05 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "0.7.0" [dependencies] borsh = "0.10" clap = "2.33.3" -serde = "1.0.177" +serde = "1.0.179" serde_derive = "1.0.130" serde_json = "1.0.104" solana-account-decoder = "=1.16.3" diff --git a/program/Cargo.toml b/program/Cargo.toml index 23f55565..ca1c6eca 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,7 +17,7 @@ borsh = "0.10" num-derive = "0.4" num-traits = "0.2" num_enum = "0.6.1" -serde = "1.0.177" +serde = "1.0.179" serde_derive = "1.0.103" solana-program = "1.16.3" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } From 3aacc5b1860e0c1dbcc6597002da1453657bb080 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Jul 2023 15:12:23 +0200 Subject: [PATCH 0437/1076] build(deps): bump @solana/web3.js from 1.78.0 to 1.78.1 in /stake-pool/js (#4889) build(deps): bump @solana/web3.js in /stake-pool/js Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.78.0 to 1.78.1. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.78.0...v1.78.1) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 32 ++++++++++++++--------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index c896ac68..64b8ba87 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1613,11 +1613,11 @@ } }, "node_modules/@solana/web3.js": { - "version": "1.78.0", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.78.0.tgz", - "integrity": "sha512-CSjCjo+RELJ5puoZALfznN5EF0YvL1V8NQrQYovsdjE1lCV6SqbKAIZD0+9LlqCBoa1ibuUaR7G2SooYzvzmug==", + "version": "1.78.1", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.78.1.tgz", + "integrity": "sha512-r0WZAYwCfVElfONP/dmWkEfw6wufL+u7lWojEsNecn9PyIIYq+r4eb0h2MRiJ3xkctvTN76G0T6FTGcTJhXh3Q==", "dependencies": { - "@babel/runtime": "^7.22.3", + "@babel/runtime": "^7.22.6", "@noble/curves": "^1.0.0", "@noble/hashes": "^1.3.0", "@solana/buffer-layout": "^4.0.0", @@ -1629,7 +1629,7 @@ "buffer": "6.0.3", "fast-stable-stringify": "^1.0.0", "jayson": "^4.1.0", - "node-fetch": "^2.6.11", + "node-fetch": "^2.6.12", "rpc-websockets": "^7.5.1", "superstruct": "^0.14.2" } @@ -5380,9 +5380,9 @@ "dev": true }, "node_modules/node-fetch": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz", - "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==", + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -8202,11 +8202,11 @@ } }, "@solana/web3.js": { - "version": "1.78.0", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.78.0.tgz", - "integrity": "sha512-CSjCjo+RELJ5puoZALfznN5EF0YvL1V8NQrQYovsdjE1lCV6SqbKAIZD0+9LlqCBoa1ibuUaR7G2SooYzvzmug==", + "version": "1.78.1", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.78.1.tgz", + "integrity": "sha512-r0WZAYwCfVElfONP/dmWkEfw6wufL+u7lWojEsNecn9PyIIYq+r4eb0h2MRiJ3xkctvTN76G0T6FTGcTJhXh3Q==", "requires": { - "@babel/runtime": "^7.22.3", + "@babel/runtime": "^7.22.6", "@noble/curves": "^1.0.0", "@noble/hashes": "^1.3.0", "@solana/buffer-layout": "^4.0.0", @@ -8218,7 +8218,7 @@ "buffer": "6.0.3", "fast-stable-stringify": "^1.0.0", "jayson": "^4.1.0", - "node-fetch": "^2.6.11", + "node-fetch": "^2.6.12", "rpc-websockets": "^7.5.1", "superstruct": "^0.14.2" } @@ -11000,9 +11000,9 @@ "dev": true }, "node-fetch": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz", - "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==", + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==", "requires": { "whatwg-url": "^5.0.0" }, From f6e3e1b51c165097e3d0d0cf2ce83f5133ed7530 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Jul 2023 15:12:34 +0200 Subject: [PATCH 0438/1076] build(deps-dev): bump eslint from 8.45.0 to 8.46.0 in /stake-pool/js (#4890) Bumps [eslint](https://github.com/eslint/eslint) from 8.45.0 to 8.46.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.45.0...v8.46.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 201 +++++++++++----------------- 1 file changed, 76 insertions(+), 125 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 64b8ba87..1f3845dc 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -685,18 +685,18 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", - "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.2.tgz", + "integrity": "sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz", - "integrity": "sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.1.tgz", + "integrity": "sha512-9t7ZA7NGGK8ckelF0PQCfcxIUzs1Md5rrO6U/c+FIQNanea5UZC0wqKXH4vHBccmu4ZJgZ2idtPeW7+Q2npOEA==", "dev": true, "dependencies": { "ajv": "^6.12.4", @@ -717,9 +717,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz", - "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==", + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.46.0.tgz", + "integrity": "sha512-a8TLtmPi8xzPkCbp/OGFUo5yhRkHM2Ko9kOWP4znJr0WAhWyThaw3PnwX4vOTWOAMsV2uRt32PPDcEz63esSaA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3147,15 +3147,6 @@ "source-map": "~0.6.1" } }, - "node_modules/escodegen/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, "node_modules/escodegen/node_modules/levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -3208,27 +3199,27 @@ } }, "node_modules/eslint": { - "version": "8.45.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.45.0.tgz", - "integrity": "sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw==", + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.46.0.tgz", + "integrity": "sha512-cIO74PvbW0qU8e0mIvk5IV3ToWdCq5FYG6gWPHHkx6gNdjlbAYvtfHmlCMXxjcoVaIdwy/IAt3+mDkZkfvb2Dg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.1.0", - "@eslint/js": "8.44.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.1", + "@eslint/js": "^8.46.0", "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.1", - "espree": "^9.6.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.2", + "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -3302,22 +3293,10 @@ } } }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", - "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", @@ -3330,13 +3309,16 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "node_modules/eslint-visitor-keys": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.2.tgz", + "integrity": "sha512-8drBzUEyZ2llkpCA67iYrgEssKDUu68V8ChqqOfFupIaG/LCVPUT+CoGJpT77zJprs4T/W7p07LP7zAIMuweVw==", "dev": true, "engines": { - "node": ">=4.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/find-up": { @@ -3401,9 +3383,9 @@ } }, "node_modules/espree": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.0.tgz", - "integrity": "sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "dependencies": { "acorn": "^8.9.0", @@ -3442,15 +3424,6 @@ "node": ">=0.10" } }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", @@ -3463,7 +3436,7 @@ "node": ">=4.0" } }, - "node_modules/esrecurse/node_modules/estraverse": { + "node_modules/estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", @@ -7547,15 +7520,15 @@ } }, "@eslint-community/regexpp": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", - "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.2.tgz", + "integrity": "sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==", "dev": true }, "@eslint/eslintrc": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz", - "integrity": "sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.1.tgz", + "integrity": "sha512-9t7ZA7NGGK8ckelF0PQCfcxIUzs1Md5rrO6U/c+FIQNanea5UZC0wqKXH4vHBccmu4ZJgZ2idtPeW7+Q2npOEA==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -7570,9 +7543,9 @@ } }, "@eslint/js": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz", - "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==", + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.46.0.tgz", + "integrity": "sha512-a8TLtmPi8xzPkCbp/OGFUo5yhRkHM2Ko9kOWP4znJr0WAhWyThaw3PnwX4vOTWOAMsV2uRt32PPDcEz63esSaA==", "dev": true }, "@humanwhocodes/config-array": { @@ -9330,12 +9303,6 @@ "source-map": "~0.6.1" }, "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -9378,27 +9345,27 @@ } }, "eslint": { - "version": "8.45.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.45.0.tgz", - "integrity": "sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw==", + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.46.0.tgz", + "integrity": "sha512-cIO74PvbW0qU8e0mIvk5IV3ToWdCq5FYG6gWPHHkx6gNdjlbAYvtfHmlCMXxjcoVaIdwy/IAt3+mDkZkfvb2Dg==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.1.0", - "@eslint/js": "8.44.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.1", + "@eslint/js": "^8.46.0", "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.1", - "espree": "^9.6.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.2", + "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -9422,22 +9389,6 @@ "text-table": "^0.2.0" }, "dependencies": { - "eslint-scope": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", - "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, "find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -9494,16 +9445,26 @@ "synckit": "^0.8.5" } }, + "eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, "eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.2.tgz", + "integrity": "sha512-8drBzUEyZ2llkpCA67iYrgEssKDUu68V8ChqqOfFupIaG/LCVPUT+CoGJpT77zJprs4T/W7p07LP7zAIMuweVw==", "dev": true }, "espree": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.0.tgz", - "integrity": "sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "requires": { "acorn": "^8.9.0", @@ -9524,14 +9485,6 @@ "dev": true, "requires": { "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } } }, "esrecurse": { @@ -9541,16 +9494,14 @@ "dev": true, "requires": { "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } } }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, "estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", From 5f9bd47c5a85b26e38c44df494a248edeb2d11a2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 2 Aug 2023 00:12:14 +0200 Subject: [PATCH 0439/1076] build(deps): bump serde from 1.0.179 to 1.0.180 (#4897) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.179 to 1.0.180. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.179...v1.0.180) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index e2b63a05..161a7679 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "0.7.0" [dependencies] borsh = "0.10" clap = "2.33.3" -serde = "1.0.179" +serde = "1.0.180" serde_derive = "1.0.130" serde_json = "1.0.104" solana-account-decoder = "=1.16.3" diff --git a/program/Cargo.toml b/program/Cargo.toml index ca1c6eca..b808694f 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,7 +17,7 @@ borsh = "0.10" num-derive = "0.4" num-traits = "0.2" num_enum = "0.6.1" -serde = "1.0.179" +serde = "1.0.180" serde_derive = "1.0.103" solana-program = "1.16.3" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } From 6e6a9e557c3bdd0909571583f53ad92fc5de560a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 2 Aug 2023 01:11:42 +0200 Subject: [PATCH 0440/1076] build(deps): bump @solana/web3.js from 1.78.1 to 1.78.2 in /stake-pool/js (#4906) build(deps): bump @solana/web3.js in /stake-pool/js Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.78.1 to 1.78.2. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.78.1...v1.78.2) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 1f3845dc..45a29987 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1613,9 +1613,9 @@ } }, "node_modules/@solana/web3.js": { - "version": "1.78.1", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.78.1.tgz", - "integrity": "sha512-r0WZAYwCfVElfONP/dmWkEfw6wufL+u7lWojEsNecn9PyIIYq+r4eb0h2MRiJ3xkctvTN76G0T6FTGcTJhXh3Q==", + "version": "1.78.2", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.78.2.tgz", + "integrity": "sha512-oF+TmBZCt3eAEl4Meu3GO2p6G8wdyoKgXgTKzQpIUIhpMGA/dVQzyMFpKjCgoTU1Kx+/UF3gXUdsZOxQukGbvQ==", "dependencies": { "@babel/runtime": "^7.22.6", "@noble/curves": "^1.0.0", @@ -1623,7 +1623,7 @@ "@solana/buffer-layout": "^4.0.0", "agentkeepalive": "^4.2.1", "bigint-buffer": "^1.1.5", - "bn.js": "^5.0.0", + "bn.js": "^5.2.1", "borsh": "^0.7.0", "bs58": "^4.0.1", "buffer": "6.0.3", @@ -8175,9 +8175,9 @@ } }, "@solana/web3.js": { - "version": "1.78.1", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.78.1.tgz", - "integrity": "sha512-r0WZAYwCfVElfONP/dmWkEfw6wufL+u7lWojEsNecn9PyIIYq+r4eb0h2MRiJ3xkctvTN76G0T6FTGcTJhXh3Q==", + "version": "1.78.2", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.78.2.tgz", + "integrity": "sha512-oF+TmBZCt3eAEl4Meu3GO2p6G8wdyoKgXgTKzQpIUIhpMGA/dVQzyMFpKjCgoTU1Kx+/UF3gXUdsZOxQukGbvQ==", "requires": { "@babel/runtime": "^7.22.6", "@noble/curves": "^1.0.0", @@ -8185,7 +8185,7 @@ "@solana/buffer-layout": "^4.0.0", "agentkeepalive": "^4.2.1", "bigint-buffer": "^1.1.5", - "bn.js": "^5.0.0", + "bn.js": "^5.2.1", "borsh": "^0.7.0", "bs58": "^4.0.1", "buffer": "6.0.3", From d5aaca859e0eb7c9e5ea954f6f129e49de8efa85 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 2 Aug 2023 01:11:50 +0200 Subject: [PATCH 0441/1076] build(deps-dev): bump @typescript-eslint/parser from 6.2.0 to 6.2.1 in /stake-pool/js (#4907) build(deps-dev): bump @typescript-eslint/parser in /stake-pool/js Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.2.0 to 6.2.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.2.1/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 145 +++++++++++++++++++++++++--- 1 file changed, 131 insertions(+), 14 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 45a29987..3f5a10c3 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1855,15 +1855,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.2.0.tgz", - "integrity": "sha512-igVYOqtiK/UsvKAmmloQAruAdUHihsOCvplJpplPZ+3h4aDkC/UKZZNKgB6h93ayuYLuEymU3h8nF1xMRbh37g==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.2.1.tgz", + "integrity": "sha512-Ld+uL1kYFU8e6btqBFpsHkwQ35rw30IWpdQxgOqOh4NfxSDH6uCkah1ks8R/RgQqI5hHPXMaLy9fbFseIe+dIg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.2.0", - "@typescript-eslint/types": "6.2.0", - "@typescript-eslint/typescript-estree": "6.2.0", - "@typescript-eslint/visitor-keys": "6.2.0", + "@typescript-eslint/scope-manager": "6.2.1", + "@typescript-eslint/types": "6.2.1", + "@typescript-eslint/typescript-estree": "6.2.1", + "@typescript-eslint/visitor-keys": "6.2.1", "debug": "^4.3.4" }, "engines": { @@ -1882,6 +1882,80 @@ } } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.1.tgz", + "integrity": "sha512-UCqBF9WFqv64xNsIEPfBtenbfodPXsJ3nPAr55mGPkQIkiQvgoWNo+astj9ZUfJfVKiYgAZDMnM6dIpsxUMp3Q==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.2.1", + "@typescript-eslint/visitor-keys": "6.2.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.1.tgz", + "integrity": "sha512-528bGcoelrpw+sETlyM91k51Arl2ajbNT9L4JwoXE2dvRe1yd8Q64E4OL7vHYw31mlnVsf+BeeLyAZUEQtqahQ==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.1.tgz", + "integrity": "sha512-G+UJeQx9AKBHRQBpmvr8T/3K5bJa485eu+4tQBxFq0KoT22+jJyzo1B50JDT9QdC1DEmWQfdKsa8ybiNWYsi0Q==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.2.1", + "@typescript-eslint/visitor-keys": "6.2.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.1.tgz", + "integrity": "sha512-iTN6w3k2JEZ7cyVdZJTVJx2Lv7t6zFA8DCrJEHD2mwfc16AEvvBWVhbFh34XyG2NORCd0viIgQY1+u7kPI0WpA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.2.1", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.0.tgz", @@ -8398,16 +8472,59 @@ } }, "@typescript-eslint/parser": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.2.0.tgz", - "integrity": "sha512-igVYOqtiK/UsvKAmmloQAruAdUHihsOCvplJpplPZ+3h4aDkC/UKZZNKgB6h93ayuYLuEymU3h8nF1xMRbh37g==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.2.1.tgz", + "integrity": "sha512-Ld+uL1kYFU8e6btqBFpsHkwQ35rw30IWpdQxgOqOh4NfxSDH6uCkah1ks8R/RgQqI5hHPXMaLy9fbFseIe+dIg==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "6.2.0", - "@typescript-eslint/types": "6.2.0", - "@typescript-eslint/typescript-estree": "6.2.0", - "@typescript-eslint/visitor-keys": "6.2.0", + "@typescript-eslint/scope-manager": "6.2.1", + "@typescript-eslint/types": "6.2.1", + "@typescript-eslint/typescript-estree": "6.2.1", + "@typescript-eslint/visitor-keys": "6.2.1", "debug": "^4.3.4" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.1.tgz", + "integrity": "sha512-UCqBF9WFqv64xNsIEPfBtenbfodPXsJ3nPAr55mGPkQIkiQvgoWNo+astj9ZUfJfVKiYgAZDMnM6dIpsxUMp3Q==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.2.1", + "@typescript-eslint/visitor-keys": "6.2.1" + } + }, + "@typescript-eslint/types": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.1.tgz", + "integrity": "sha512-528bGcoelrpw+sETlyM91k51Arl2ajbNT9L4JwoXE2dvRe1yd8Q64E4OL7vHYw31mlnVsf+BeeLyAZUEQtqahQ==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.1.tgz", + "integrity": "sha512-G+UJeQx9AKBHRQBpmvr8T/3K5bJa485eu+4tQBxFq0KoT22+jJyzo1B50JDT9QdC1DEmWQfdKsa8ybiNWYsi0Q==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.2.1", + "@typescript-eslint/visitor-keys": "6.2.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.1.tgz", + "integrity": "sha512-iTN6w3k2JEZ7cyVdZJTVJx2Lv7t6zFA8DCrJEHD2mwfc16AEvvBWVhbFh34XyG2NORCd0viIgQY1+u7kPI0WpA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.2.1", + "eslint-visitor-keys": "^3.4.1" + } + } } }, "@typescript-eslint/scope-manager": { From 9d631d83200b1379ec80fbd9cb987a43322a7150 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 2 Aug 2023 01:13:34 +0200 Subject: [PATCH 0442/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.2.0 to 6.2.1 in /stake-pool/js (#4908) build(deps-dev): bump @typescript-eslint/eslint-plugin in /stake-pool/js Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.2.0 to 6.2.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.2.1/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 354 +++++++++++++++++++++++++--- 1 file changed, 318 insertions(+), 36 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 3f5a10c3..7cdd9f19 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1819,16 +1819,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.2.0.tgz", - "integrity": "sha512-rClGrMuyS/3j0ETa1Ui7s6GkLhfZGKZL3ZrChLeAiACBE/tRc1wq8SNZESUuluxhLj9FkUefRs2l6bCIArWBiQ==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.2.1.tgz", + "integrity": "sha512-iZVM/ALid9kO0+I81pnp1xmYiFyqibAHzrqX4q5YvvVEyJqY+e6rfTXSCsc2jUxGNqJqTfFSSij/NFkZBiBzLw==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.2.0", - "@typescript-eslint/type-utils": "6.2.0", - "@typescript-eslint/utils": "6.2.0", - "@typescript-eslint/visitor-keys": "6.2.0", + "@typescript-eslint/scope-manager": "6.2.1", + "@typescript-eslint/type-utils": "6.2.1", + "@typescript-eslint/utils": "6.2.1", + "@typescript-eslint/visitor-keys": "6.2.1", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -1854,6 +1854,53 @@ } } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.1.tgz", + "integrity": "sha512-UCqBF9WFqv64xNsIEPfBtenbfodPXsJ3nPAr55mGPkQIkiQvgoWNo+astj9ZUfJfVKiYgAZDMnM6dIpsxUMp3Q==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.2.1", + "@typescript-eslint/visitor-keys": "6.2.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.1.tgz", + "integrity": "sha512-528bGcoelrpw+sETlyM91k51Arl2ajbNT9L4JwoXE2dvRe1yd8Q64E4OL7vHYw31mlnVsf+BeeLyAZUEQtqahQ==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.1.tgz", + "integrity": "sha512-iTN6w3k2JEZ7cyVdZJTVJx2Lv7t6zFA8DCrJEHD2mwfc16AEvvBWVhbFh34XyG2NORCd0viIgQY1+u7kPI0WpA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.2.1", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/parser": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.2.1.tgz", @@ -1974,13 +2021,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.2.0.tgz", - "integrity": "sha512-DnGZuNU2JN3AYwddYIqrVkYW0uUQdv0AY+kz2M25euVNlujcN2u+rJgfJsBFlUEzBB6OQkUqSZPyuTLf2bP5mw==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.2.1.tgz", + "integrity": "sha512-fTfCgomBMIgu2Dh2Or3gMYgoNAnQm3RLtRp+jP7A8fY+LJ2+9PNpi5p6QB5C4RSP+U3cjI0vDlI3mspAkpPVbQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.2.0", - "@typescript-eslint/utils": "6.2.0", + "@typescript-eslint/typescript-estree": "6.2.1", + "@typescript-eslint/utils": "6.2.1", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -2000,6 +2047,63 @@ } } }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.1.tgz", + "integrity": "sha512-528bGcoelrpw+sETlyM91k51Arl2ajbNT9L4JwoXE2dvRe1yd8Q64E4OL7vHYw31mlnVsf+BeeLyAZUEQtqahQ==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.1.tgz", + "integrity": "sha512-G+UJeQx9AKBHRQBpmvr8T/3K5bJa485eu+4tQBxFq0KoT22+jJyzo1B50JDT9QdC1DEmWQfdKsa8ybiNWYsi0Q==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.2.1", + "@typescript-eslint/visitor-keys": "6.2.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.1.tgz", + "integrity": "sha512-iTN6w3k2JEZ7cyVdZJTVJx2Lv7t6zFA8DCrJEHD2mwfc16AEvvBWVhbFh34XyG2NORCd0viIgQY1+u7kPI0WpA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.2.1", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/types": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.0.tgz", @@ -2041,17 +2145,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.2.0.tgz", - "integrity": "sha512-RCFrC1lXiX1qEZN8LmLrxYRhOkElEsPKTVSNout8DMzf8PeWoQG7Rxz2SadpJa3VSh5oYKGwt7j7X/VRg+Y3OQ==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.2.1.tgz", + "integrity": "sha512-eBIXQeupYmxVB6S7x+B9SdBeB6qIdXKjgQBge2J+Ouv8h9Cxm5dHf/gfAZA6dkMaag+03HdbVInuXMmqFB/lKQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.2.0", - "@typescript-eslint/types": "6.2.0", - "@typescript-eslint/typescript-estree": "6.2.0", + "@typescript-eslint/scope-manager": "6.2.1", + "@typescript-eslint/types": "6.2.1", + "@typescript-eslint/typescript-estree": "6.2.1", "semver": "^7.5.4" }, "engines": { @@ -2065,6 +2169,80 @@ "eslint": "^7.0.0 || ^8.0.0" } }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.1.tgz", + "integrity": "sha512-UCqBF9WFqv64xNsIEPfBtenbfodPXsJ3nPAr55mGPkQIkiQvgoWNo+astj9ZUfJfVKiYgAZDMnM6dIpsxUMp3Q==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.2.1", + "@typescript-eslint/visitor-keys": "6.2.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.1.tgz", + "integrity": "sha512-528bGcoelrpw+sETlyM91k51Arl2ajbNT9L4JwoXE2dvRe1yd8Q64E4OL7vHYw31mlnVsf+BeeLyAZUEQtqahQ==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.1.tgz", + "integrity": "sha512-G+UJeQx9AKBHRQBpmvr8T/3K5bJa485eu+4tQBxFq0KoT22+jJyzo1B50JDT9QdC1DEmWQfdKsa8ybiNWYsi0Q==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.2.1", + "@typescript-eslint/visitor-keys": "6.2.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.1.tgz", + "integrity": "sha512-iTN6w3k2JEZ7cyVdZJTVJx2Lv7t6zFA8DCrJEHD2mwfc16AEvvBWVhbFh34XyG2NORCd0viIgQY1+u7kPI0WpA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.2.1", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/visitor-keys": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.0.tgz", @@ -8452,16 +8630,16 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.2.0.tgz", - "integrity": "sha512-rClGrMuyS/3j0ETa1Ui7s6GkLhfZGKZL3ZrChLeAiACBE/tRc1wq8SNZESUuluxhLj9FkUefRs2l6bCIArWBiQ==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.2.1.tgz", + "integrity": "sha512-iZVM/ALid9kO0+I81pnp1xmYiFyqibAHzrqX4q5YvvVEyJqY+e6rfTXSCsc2jUxGNqJqTfFSSij/NFkZBiBzLw==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.2.0", - "@typescript-eslint/type-utils": "6.2.0", - "@typescript-eslint/utils": "6.2.0", - "@typescript-eslint/visitor-keys": "6.2.0", + "@typescript-eslint/scope-manager": "6.2.1", + "@typescript-eslint/type-utils": "6.2.1", + "@typescript-eslint/utils": "6.2.1", + "@typescript-eslint/visitor-keys": "6.2.1", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -8469,6 +8647,34 @@ "natural-compare-lite": "^1.4.0", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.1.tgz", + "integrity": "sha512-UCqBF9WFqv64xNsIEPfBtenbfodPXsJ3nPAr55mGPkQIkiQvgoWNo+astj9ZUfJfVKiYgAZDMnM6dIpsxUMp3Q==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.2.1", + "@typescript-eslint/visitor-keys": "6.2.1" + } + }, + "@typescript-eslint/types": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.1.tgz", + "integrity": "sha512-528bGcoelrpw+sETlyM91k51Arl2ajbNT9L4JwoXE2dvRe1yd8Q64E4OL7vHYw31mlnVsf+BeeLyAZUEQtqahQ==", + "dev": true + }, + "@typescript-eslint/visitor-keys": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.1.tgz", + "integrity": "sha512-iTN6w3k2JEZ7cyVdZJTVJx2Lv7t6zFA8DCrJEHD2mwfc16AEvvBWVhbFh34XyG2NORCd0viIgQY1+u7kPI0WpA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.2.1", + "eslint-visitor-keys": "^3.4.1" + } + } } }, "@typescript-eslint/parser": { @@ -8538,15 +8744,48 @@ } }, "@typescript-eslint/type-utils": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.2.0.tgz", - "integrity": "sha512-DnGZuNU2JN3AYwddYIqrVkYW0uUQdv0AY+kz2M25euVNlujcN2u+rJgfJsBFlUEzBB6OQkUqSZPyuTLf2bP5mw==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.2.1.tgz", + "integrity": "sha512-fTfCgomBMIgu2Dh2Or3gMYgoNAnQm3RLtRp+jP7A8fY+LJ2+9PNpi5p6QB5C4RSP+U3cjI0vDlI3mspAkpPVbQ==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "6.2.0", - "@typescript-eslint/utils": "6.2.0", + "@typescript-eslint/typescript-estree": "6.2.1", + "@typescript-eslint/utils": "6.2.1", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" + }, + "dependencies": { + "@typescript-eslint/types": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.1.tgz", + "integrity": "sha512-528bGcoelrpw+sETlyM91k51Arl2ajbNT9L4JwoXE2dvRe1yd8Q64E4OL7vHYw31mlnVsf+BeeLyAZUEQtqahQ==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.1.tgz", + "integrity": "sha512-G+UJeQx9AKBHRQBpmvr8T/3K5bJa485eu+4tQBxFq0KoT22+jJyzo1B50JDT9QdC1DEmWQfdKsa8ybiNWYsi0Q==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.2.1", + "@typescript-eslint/visitor-keys": "6.2.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.1.tgz", + "integrity": "sha512-iTN6w3k2JEZ7cyVdZJTVJx2Lv7t6zFA8DCrJEHD2mwfc16AEvvBWVhbFh34XyG2NORCd0viIgQY1+u7kPI0WpA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.2.1", + "eslint-visitor-keys": "^3.4.1" + } + } } }, "@typescript-eslint/types": { @@ -8571,18 +8810,61 @@ } }, "@typescript-eslint/utils": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.2.0.tgz", - "integrity": "sha512-RCFrC1lXiX1qEZN8LmLrxYRhOkElEsPKTVSNout8DMzf8PeWoQG7Rxz2SadpJa3VSh5oYKGwt7j7X/VRg+Y3OQ==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.2.1.tgz", + "integrity": "sha512-eBIXQeupYmxVB6S7x+B9SdBeB6qIdXKjgQBge2J+Ouv8h9Cxm5dHf/gfAZA6dkMaag+03HdbVInuXMmqFB/lKQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.2.0", - "@typescript-eslint/types": "6.2.0", - "@typescript-eslint/typescript-estree": "6.2.0", + "@typescript-eslint/scope-manager": "6.2.1", + "@typescript-eslint/types": "6.2.1", + "@typescript-eslint/typescript-estree": "6.2.1", "semver": "^7.5.4" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.1.tgz", + "integrity": "sha512-UCqBF9WFqv64xNsIEPfBtenbfodPXsJ3nPAr55mGPkQIkiQvgoWNo+astj9ZUfJfVKiYgAZDMnM6dIpsxUMp3Q==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.2.1", + "@typescript-eslint/visitor-keys": "6.2.1" + } + }, + "@typescript-eslint/types": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.1.tgz", + "integrity": "sha512-528bGcoelrpw+sETlyM91k51Arl2ajbNT9L4JwoXE2dvRe1yd8Q64E4OL7vHYw31mlnVsf+BeeLyAZUEQtqahQ==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.1.tgz", + "integrity": "sha512-G+UJeQx9AKBHRQBpmvr8T/3K5bJa485eu+4tQBxFq0KoT22+jJyzo1B50JDT9QdC1DEmWQfdKsa8ybiNWYsi0Q==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.2.1", + "@typescript-eslint/visitor-keys": "6.2.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.1.tgz", + "integrity": "sha512-iTN6w3k2JEZ7cyVdZJTVJx2Lv7t6zFA8DCrJEHD2mwfc16AEvvBWVhbFh34XyG2NORCd0viIgQY1+u7kPI0WpA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.2.1", + "eslint-visitor-keys": "^3.4.1" + } + } } }, "@typescript-eslint/visitor-keys": { From e02ce7278afbdbedfe7c5d55f0988db714e59c2d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 3 Aug 2023 18:41:17 +0200 Subject: [PATCH 0443/1076] build(deps-dev): bump @types/node from 20.4.5 to 20.4.6 in /stake-pool/js (#4924) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.4.5 to 20.4.6. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 127 ++-------------------------- 1 file changed, 6 insertions(+), 121 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 7cdd9f19..3194e207 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1757,9 +1757,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.4.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.5.tgz", - "integrity": "sha512-rt40Nk13II9JwQBdeYqmbn2Q6IVTA5uPhvSO+JVqdXw/6/4glI6oR9ezty/A9Hg5u7JH4OmYmuQ+XvjKm0Datg==" + "version": "20.4.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.6.tgz", + "integrity": "sha512-q0RkvNgMweWWIvSMDiXhflGUKMdIxBo2M2tYM/0kEGDueQByFzK4KZAgu5YHGFNxziTlppNpTIBcqHQAxlfHdA==" }, "node_modules/@types/node-fetch": { "version": "2.6.4", @@ -2003,23 +2003,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.0.tgz", - "integrity": "sha512-1ZMNVgm5nnHURU8ZSJ3snsHzpFeNK84rdZjluEVBGNu7jDymfqceB3kdIZ6A4xCfEFFhRIB6rF8q/JIqJd2R0Q==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.2.0", - "@typescript-eslint/visitor-keys": "6.2.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/type-utils": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.2.1.tgz", @@ -2104,46 +2087,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/types": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.0.tgz", - "integrity": "sha512-1nRRaDlp/XYJQLvkQJG5F3uBTno5SHPT7XVcJ5n1/k2WfNI28nJsvLakxwZRNY5spuatEKO7d5nZWsQpkqXwBA==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.0.tgz", - "integrity": "sha512-Mts6+3HQMSM+LZCglsc2yMIny37IhUgp1Qe8yJUYVyO6rHP7/vN0vajKu3JvHCBIy8TSiKddJ/Zwu80jhnGj1w==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.2.0", - "@typescript-eslint/visitor-keys": "6.2.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, "node_modules/@typescript-eslint/utils": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.2.1.tgz", @@ -2243,23 +2186,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.0.tgz", - "integrity": "sha512-QbaYUQVKKo9bgCzpjz45llCfwakyoxHetIy8CAvYCtd16Zu1KrpzNHofwF8kGkpPOxZB2o6kz+0nqH8ZkIzuoQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.2.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/abab": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", @@ -8568,9 +8494,9 @@ "dev": true }, "@types/node": { - "version": "20.4.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.5.tgz", - "integrity": "sha512-rt40Nk13II9JwQBdeYqmbn2Q6IVTA5uPhvSO+JVqdXw/6/4glI6oR9ezty/A9Hg5u7JH4OmYmuQ+XvjKm0Datg==" + "version": "20.4.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.6.tgz", + "integrity": "sha512-q0RkvNgMweWWIvSMDiXhflGUKMdIxBo2M2tYM/0kEGDueQByFzK4KZAgu5YHGFNxziTlppNpTIBcqHQAxlfHdA==" }, "@types/node-fetch": { "version": "2.6.4", @@ -8733,16 +8659,6 @@ } } }, - "@typescript-eslint/scope-manager": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.0.tgz", - "integrity": "sha512-1ZMNVgm5nnHURU8ZSJ3snsHzpFeNK84rdZjluEVBGNu7jDymfqceB3kdIZ6A4xCfEFFhRIB6rF8q/JIqJd2R0Q==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.2.0", - "@typescript-eslint/visitor-keys": "6.2.0" - } - }, "@typescript-eslint/type-utils": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.2.1.tgz", @@ -8788,27 +8704,6 @@ } } }, - "@typescript-eslint/types": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.0.tgz", - "integrity": "sha512-1nRRaDlp/XYJQLvkQJG5F3uBTno5SHPT7XVcJ5n1/k2WfNI28nJsvLakxwZRNY5spuatEKO7d5nZWsQpkqXwBA==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.0.tgz", - "integrity": "sha512-Mts6+3HQMSM+LZCglsc2yMIny37IhUgp1Qe8yJUYVyO6rHP7/vN0vajKu3JvHCBIy8TSiKddJ/Zwu80jhnGj1w==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.2.0", - "@typescript-eslint/visitor-keys": "6.2.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, "@typescript-eslint/utils": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.2.1.tgz", @@ -8867,16 +8762,6 @@ } } }, - "@typescript-eslint/visitor-keys": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.0.tgz", - "integrity": "sha512-QbaYUQVKKo9bgCzpjz45llCfwakyoxHetIy8CAvYCtd16Zu1KrpzNHofwF8kGkpPOxZB2o6kz+0nqH8ZkIzuoQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.2.0", - "eslint-visitor-keys": "^3.4.1" - } - }, "abab": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", From 9a3ee87a9a9e9488272a937b0afc3d1785866b3e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 3 Aug 2023 18:41:27 +0200 Subject: [PATCH 0444/1076] build(deps-dev): bump eslint-config-prettier from 8.9.0 to 8.10.0 in /stake-pool/js (#4925) build(deps-dev): bump eslint-config-prettier in /stake-pool/js Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 8.9.0 to 8.10.0. - [Changelog](https://github.com/prettier/eslint-config-prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/eslint-config-prettier/compare/v8.9.0...v8.10.0) --- updated-dependencies: - dependency-name: eslint-config-prettier dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 3194e207..18d4c1e7 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -3431,9 +3431,9 @@ } }, "node_modules/eslint-config-prettier": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.9.0.tgz", - "integrity": "sha512-+sbni7NfVXnOpnRadUA8S28AUlsZt9GjgFvABIRL9Hkn8KqNzOp+7Lw4QWtrwn20KzU3wqu1QoOj2m+7rKRqkA==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz", + "integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==", "dev": true, "bin": { "eslint-config-prettier": "bin/cli.js" @@ -9713,9 +9713,9 @@ } }, "eslint-config-prettier": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.9.0.tgz", - "integrity": "sha512-+sbni7NfVXnOpnRadUA8S28AUlsZt9GjgFvABIRL9Hkn8KqNzOp+7Lw4QWtrwn20KzU3wqu1QoOj2m+7rKRqkA==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz", + "integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==", "dev": true, "requires": {} }, From 5de3cab75e363c968bcfdfa86e8e233480a8d3be Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 3 Aug 2023 18:41:34 +0200 Subject: [PATCH 0445/1076] build(deps-dev): bump prettier from 3.0.0 to 3.0.1 in /stake-pool/js (#4926) Bumps [prettier](https://github.com/prettier/prettier) from 3.0.0 to 3.0.1. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/3.0.0...3.0.1) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 18d4c1e7..7f51ef27 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -5865,9 +5865,9 @@ } }, "node_modules/prettier": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.0.tgz", - "integrity": "sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.1.tgz", + "integrity": "sha512-fcOWSnnpCrovBsmFZIGIy9UqK2FaI7Hqax+DIO0A9UxeVoY4iweyaFjS5TavZN97Hfehph0nhsZnjlVKzEQSrQ==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" @@ -11479,9 +11479,9 @@ "dev": true }, "prettier": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.0.tgz", - "integrity": "sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.1.tgz", + "integrity": "sha512-fcOWSnnpCrovBsmFZIGIy9UqK2FaI7Hqax+DIO0A9UxeVoY4iweyaFjS5TavZN97Hfehph0nhsZnjlVKzEQSrQ==", "dev": true }, "prettier-linter-helpers": { From 83edd03d9e90d0acae33b921e8ce8f31956f7bf8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Aug 2023 13:04:38 +0200 Subject: [PATCH 0446/1076] build(deps): bump serde from 1.0.180 to 1.0.181 (#4933) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.180 to 1.0.181. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.180...v1.0.181) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 161a7679..68589f06 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "0.7.0" [dependencies] borsh = "0.10" clap = "2.33.3" -serde = "1.0.180" +serde = "1.0.181" serde_derive = "1.0.130" serde_json = "1.0.104" solana-account-decoder = "=1.16.3" diff --git a/program/Cargo.toml b/program/Cargo.toml index b808694f..6cf2ef55 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,7 +17,7 @@ borsh = "0.10" num-derive = "0.4" num-traits = "0.2" num_enum = "0.6.1" -serde = "1.0.180" +serde = "1.0.181" serde_derive = "1.0.103" solana-program = "1.16.3" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } From 53b0fee4f88c031a46664f7e9c74617d21a29100 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Aug 2023 15:26:47 +0200 Subject: [PATCH 0447/1076] build(deps-dev): bump @types/node from 20.4.6 to 20.4.7 in /stake-pool/js (#4937) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.4.6 to 20.4.7. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 7f51ef27..727349e1 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1757,9 +1757,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.4.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.6.tgz", - "integrity": "sha512-q0RkvNgMweWWIvSMDiXhflGUKMdIxBo2M2tYM/0kEGDueQByFzK4KZAgu5YHGFNxziTlppNpTIBcqHQAxlfHdA==" + "version": "20.4.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.7.tgz", + "integrity": "sha512-bUBrPjEry2QUTsnuEjzjbS7voGWCc30W0qzgMf90GPeDGFRakvrz47ju+oqDAKCXLUCe39u57/ORMl/O/04/9g==" }, "node_modules/@types/node-fetch": { "version": "2.6.4", @@ -8494,9 +8494,9 @@ "dev": true }, "@types/node": { - "version": "20.4.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.6.tgz", - "integrity": "sha512-q0RkvNgMweWWIvSMDiXhflGUKMdIxBo2M2tYM/0kEGDueQByFzK4KZAgu5YHGFNxziTlppNpTIBcqHQAxlfHdA==" + "version": "20.4.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.7.tgz", + "integrity": "sha512-bUBrPjEry2QUTsnuEjzjbS7voGWCc30W0qzgMf90GPeDGFRakvrz47ju+oqDAKCXLUCe39u57/ORMl/O/04/9g==" }, "@types/node-fetch": { "version": "2.6.4", From 8a39bf732625d614dd91476b6b2e94b63a48cfd6 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Sun, 6 Aug 2023 18:03:09 +0200 Subject: [PATCH 0448/1076] stake-pool: Update tests for 1.17 (#4913) * stake-pool: Refactor `retain` into a closure * stake-pool: Update tests by advancing slot + 1, 200 bytes for stakes * single-pool: Update tests to warp to slot + 1 * Write into slice rather than extending --- program/src/big_vec.rs | 7 +++- program/src/processor.rs | 2 +- program/tests/decrease.rs | 2 +- program/tests/deposit.rs | 2 +- program/tests/deposit_edge_cases.rs | 2 +- program/tests/helpers/mod.rs | 8 ++-- program/tests/huge_pool.rs | 4 +- program/tests/increase.rs | 2 +- program/tests/redelegate.rs | 4 +- program/tests/set_epoch_fee.rs | 15 ++----- program/tests/set_withdrawal_fee.rs | 40 ++++++------------- program/tests/update_stake_pool_balance.rs | 4 +- .../tests/update_validator_list_balance.rs | 2 +- .../update_validator_list_balance_hijack.rs | 2 +- program/tests/vsa_remove.rs | 2 +- program/tests/withdraw_edge_cases.rs | 25 +++--------- 16 files changed, 44 insertions(+), 79 deletions(-) diff --git a/program/src/big_vec.rs b/program/src/big_vec.rs index 40852377..5c74018f 100644 --- a/program/src/big_vec.rs +++ b/program/src/big_vec.rs @@ -32,7 +32,10 @@ impl<'data> BigVec<'data> { } /// Retain all elements that match the provided function, discard all others - pub fn retain(&mut self, predicate: fn(&[u8]) -> bool) -> Result<(), ProgramError> { + pub fn retain bool>( + &mut self, + predicate: F, + ) -> Result<(), ProgramError> { let mut vec_len = self.len(); let mut removals_found = 0; let mut dst_start_index = 0; @@ -307,7 +310,7 @@ mod tests { let mut data = [0u8; 4 + 8 * 4]; let mut v = from_slice(&mut data, &[1, 2, 3, 4]); - v.retain::(mod_2_predicate).unwrap(); + v.retain::(mod_2_predicate).unwrap(); check_big_vec_eq(&v, &[2, 4]); } diff --git a/program/src/processor.rs b/program/src/processor.rs index 2ecf789c..ee926d4a 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -2582,7 +2582,7 @@ impl Processor { return Err(StakePoolError::InvalidState.into()); } - validator_list.retain::(ValidatorStakeInfo::is_not_removed)?; + validator_list.retain::(ValidatorStakeInfo::is_not_removed)?; Ok(()) } diff --git a/program/tests/decrease.rs b/program/tests/decrease.rs index 1293fd78..b1f17cc1 100644 --- a/program/tests/decrease.rs +++ b/program/tests/decrease.rs @@ -537,7 +537,7 @@ async fn fail_additional_with_increasing() { // warp forward to activation let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; - context.warp_to_slot(first_normal_slot).unwrap(); + context.warp_to_slot(first_normal_slot + 1).unwrap(); let last_blockhash = context .banks_client .get_new_latest_blockhash(&context.last_blockhash) diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 7736918c..aafeca1f 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -88,7 +88,7 @@ async fn setup( .await; let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; - context.warp_to_slot(first_normal_slot).unwrap(); + context.warp_to_slot(first_normal_slot + 1).unwrap(); stake_pool_accounts .update_all( &mut context.banks_client, diff --git a/program/tests/deposit_edge_cases.rs b/program/tests/deposit_edge_cases.rs index 13482fd5..a1312bb8 100644 --- a/program/tests/deposit_edge_cases.rs +++ b/program/tests/deposit_edge_cases.rs @@ -81,7 +81,7 @@ async fn setup( .await; let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; - context.warp_to_slot(first_normal_slot).unwrap(); + context.warp_to_slot(first_normal_slot + 1).unwrap(); stake_pool_accounts .update_all( &mut context.banks_client, diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index f6620252..b709fab8 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -2379,12 +2379,12 @@ pub fn add_validator_stake_account( credits_observed: 0, }; + let mut data = vec![0u8; std::mem::size_of::()]; + let stake_data = bincode::serialize(&stake::state::StakeState::Stake(meta, stake)).unwrap(); + data[..stake_data.len()].copy_from_slice(&stake_data); let stake_account = SolanaAccount::create( stake_amount + STAKE_ACCOUNT_RENT_EXEMPTION, - bincode::serialize::(&stake::state::StakeState::Stake( - meta, stake, - )) - .unwrap(), + data, stake::program::id(), false, Epoch::default(), diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index ad1ac200..1bb975a4 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -107,7 +107,7 @@ async fn setup( let mut context = program_test.start_with_context().await; let epoch_schedule = context.genesis_config().epoch_schedule; - let slot = epoch_schedule.first_normal_slot + epoch_schedule.slots_per_epoch; + let slot = epoch_schedule.first_normal_slot + epoch_schedule.slots_per_epoch + 1; context.warp_to_slot(slot).unwrap(); let vote_pubkey = vote_account_pubkeys[max_validators as usize - 1]; @@ -635,7 +635,7 @@ async fn withdraw(max_validators: u32) { &pool_account_pubkey, &stake_address, &user.pubkey(), - STAKE_AMOUNT, + TEST_STAKE_AMOUNT, ) .await; assert!(error.is_none(), "{:?}", error); diff --git a/program/tests/increase.rs b/program/tests/increase.rs index 4cb8f128..ac50c786 100644 --- a/program/tests/increase.rs +++ b/program/tests/increase.rs @@ -536,7 +536,7 @@ async fn fail_additional_with_decreasing() { // warp forward to activation let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; - context.warp_to_slot(first_normal_slot).unwrap(); + context.warp_to_slot(first_normal_slot + 1).unwrap(); let last_blockhash = context .banks_client .get_new_latest_blockhash(&context.last_blockhash) diff --git a/program/tests/redelegate.rs b/program/tests/redelegate.rs index 24191842..8f14746c 100644 --- a/program/tests/redelegate.rs +++ b/program/tests/redelegate.rs @@ -83,9 +83,9 @@ async fn setup( .await .unwrap(); - let mut slot = 0; + let mut slot = 1; if do_warp { - slot = context.genesis_config().epoch_schedule.first_normal_slot; + slot += context.genesis_config().epoch_schedule.first_normal_slot; context.warp_to_slot(slot).unwrap(); stake_pool_accounts .update_all( diff --git a/program/tests/set_epoch_fee.rs b/program/tests/set_epoch_fee.rs index 57d183bd..d1c5dc94 100644 --- a/program/tests/set_epoch_fee.rs +++ b/program/tests/set_epoch_fee.rs @@ -80,10 +80,8 @@ async fn success() { let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; - - context - .warp_to_slot(first_normal_slot + slots_per_epoch) - .unwrap(); + let slot = first_normal_slot + 1; + context.warp_to_slot(slot).unwrap(); stake_pool_accounts .update_all( &mut context.banks_client, @@ -108,9 +106,7 @@ async fn success() { .get_new_latest_blockhash(&context.last_blockhash) .await .unwrap(); - context - .warp_to_slot(first_normal_slot + 2 * slots_per_epoch) - .unwrap(); + context.warp_to_slot(slot + slots_per_epoch).unwrap(); stake_pool_accounts .update_all( &mut context.banks_client, @@ -220,10 +216,7 @@ async fn fail_not_updated() { // move forward so an update is required let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; - let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; - context - .warp_to_slot(first_normal_slot + slots_per_epoch) - .unwrap(); + context.warp_to_slot(first_normal_slot + 1).unwrap(); let transaction = Transaction::new_signed_with_payer( &[instruction::set_fee( diff --git a/program/tests/set_withdrawal_fee.rs b/program/tests/set_withdrawal_fee.rs index 6ebf6ea3..e0e2075f 100644 --- a/program/tests/set_withdrawal_fee.rs +++ b/program/tests/set_withdrawal_fee.rs @@ -109,10 +109,9 @@ async fn success() { let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + let slot = first_normal_slot + 1; - context - .warp_to_slot(first_normal_slot + slots_per_epoch) - .unwrap(); + context.warp_to_slot(slot).unwrap(); stake_pool_accounts .update_all( &mut context.banks_client, @@ -145,9 +144,7 @@ async fn success() { .get_new_latest_blockhash(&context.last_blockhash) .await .unwrap(); - context - .warp_to_slot(first_normal_slot + 2 * slots_per_epoch) - .unwrap(); + context.warp_to_slot(slot + slots_per_epoch).unwrap(); stake_pool_accounts .update_all( &mut context.banks_client, @@ -237,10 +234,9 @@ async fn success_fee_cannot_increase_more_than_once() { let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + let slot = first_normal_slot + 1; - context - .warp_to_slot(first_normal_slot + slots_per_epoch) - .unwrap(); + context.warp_to_slot(slot).unwrap(); stake_pool_accounts .update_all( &mut context.banks_client, @@ -273,9 +269,7 @@ async fn success_fee_cannot_increase_more_than_once() { .get_new_latest_blockhash(&context.last_blockhash) .await .unwrap(); - context - .warp_to_slot(first_normal_slot + 2 * slots_per_epoch) - .unwrap(); + context.warp_to_slot(slot + slots_per_epoch).unwrap(); stake_pool_accounts .update_all( &mut context.banks_client, @@ -443,11 +437,7 @@ async fn success_reset_fee_after_one_epoch() { ); let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; - let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; - - context - .warp_to_slot(first_normal_slot + slots_per_epoch) - .unwrap(); + context.warp_to_slot(first_normal_slot + 1).unwrap(); stake_pool_accounts .update_all( &mut context.banks_client, @@ -603,10 +593,8 @@ async fn success_increase_fee_from_0() { let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; - - context - .warp_to_slot(first_normal_slot + slots_per_epoch) - .unwrap(); + let slot = first_normal_slot + 1; + context.warp_to_slot(slot).unwrap(); stake_pool_accounts .update_all( &mut context.banks_client, @@ -639,9 +627,7 @@ async fn success_increase_fee_from_0() { .get_new_latest_blockhash(&context.last_blockhash) .await .unwrap(); - context - .warp_to_slot(first_normal_slot + 2 * slots_per_epoch) - .unwrap(); + context.warp_to_slot(slot + slots_per_epoch).unwrap(); stake_pool_accounts .update_all( &mut context.banks_client, @@ -902,10 +888,8 @@ async fn fail_not_updated() { // move forward so an update is required let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; - let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; - context - .warp_to_slot(first_normal_slot + slots_per_epoch) - .unwrap(); + let slot = first_normal_slot + 1; + context.warp_to_slot(slot).unwrap(); let transaction = Transaction::new_signed_with_payer( &[instruction::set_fee( diff --git a/program/tests/update_stake_pool_balance.rs b/program/tests/update_stake_pool_balance.rs index b0623550..388ea98b 100644 --- a/program/tests/update_stake_pool_balance.rs +++ b/program/tests/update_stake_pool_balance.rs @@ -165,7 +165,7 @@ async fn success() { } // Update epoch - let slot = context.genesis_config().epoch_schedule.first_normal_slot; + let slot = context.genesis_config().epoch_schedule.first_normal_slot + 1; context.warp_to_slot(slot).unwrap(); let last_blockhash = context @@ -279,7 +279,7 @@ async fn success_absorbing_extra_lamports() { let expected_fee = stake_pool.calc_epoch_fee_amount(extra_lamports).unwrap(); // Update epoch - let slot = context.genesis_config().epoch_schedule.first_normal_slot; + let slot = context.genesis_config().epoch_schedule.first_normal_slot + 1; context.warp_to_slot(slot).unwrap(); let last_blockhash = context .banks_client diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index 841b8b88..e97c786b 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -31,7 +31,7 @@ async fn setup( let mut context = program_test().start_with_context().await; let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; - let mut slot = first_normal_slot; + let mut slot = first_normal_slot + 1; context.warp_to_slot(slot).unwrap(); let reserve_stake_amount = TEST_STAKE_AMOUNT * 2 * num_validators as u64; diff --git a/program/tests/update_validator_list_balance_hijack.rs b/program/tests/update_validator_list_balance_hijack.rs index 71e8f13c..d7449984 100644 --- a/program/tests/update_validator_list_balance_hijack.rs +++ b/program/tests/update_validator_list_balance_hijack.rs @@ -38,7 +38,7 @@ async fn setup( let mut context = program_test().start_with_context().await; let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; - let mut slot = first_normal_slot; + let mut slot = first_normal_slot + 1; context.warp_to_slot(slot).unwrap(); let reserve_stake_amount = TEST_STAKE_AMOUNT * 2 * num_validators as u64; diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index b2594bb7..09fde679 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -690,7 +690,7 @@ async fn success_with_hijacked_transient_account() { // warp forward to merge let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; - let mut slot = first_normal_slot + slots_per_epoch; + let mut slot = first_normal_slot + slots_per_epoch + 1; context.warp_to_slot(slot).unwrap(); stake_pool_accounts .update_all( diff --git a/program/tests/withdraw_edge_cases.rs b/program/tests/withdraw_edge_cases.rs index 27e25d9b..ab4523a1 100644 --- a/program/tests/withdraw_edge_cases.rs +++ b/program/tests/withdraw_edge_cases.rs @@ -43,10 +43,7 @@ async fn fail_remove_validator() { // warp forward to deactivation let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; - let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; - context - .warp_to_slot(first_normal_slot + slots_per_epoch) - .unwrap(); + context.warp_to_slot(first_normal_slot + 1).unwrap(); // update to merge deactivated stake into reserve stake_pool_accounts @@ -146,10 +143,7 @@ async fn success_remove_validator(multiple: u64) { // warp forward to deactivation let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; - let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; - context - .warp_to_slot(first_normal_slot + slots_per_epoch) - .unwrap(); + context.warp_to_slot(first_normal_slot + 1).unwrap(); let last_blockhash = context .banks_client @@ -262,10 +256,7 @@ async fn fail_with_reserve() { // warp forward to deactivation let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; - let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; - context - .warp_to_slot(first_normal_slot + slots_per_epoch) - .unwrap(); + context.warp_to_slot(first_normal_slot + 1).unwrap(); // update to merge deactivated stake into reserve stake_pool_accounts @@ -335,10 +326,7 @@ async fn success_with_reserve() { // warp forward to deactivation let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; - let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; - context - .warp_to_slot(first_normal_slot + slots_per_epoch) - .unwrap(); + context.warp_to_slot(first_normal_slot + 1).unwrap(); // update to merge deactivated stake into reserve stake_pool_accounts @@ -834,10 +822,7 @@ async fn success_with_small_preferred_withdraw() { // warp forward to deactivation let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; - let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; - context - .warp_to_slot(first_normal_slot + slots_per_epoch) - .unwrap(); + context.warp_to_slot(first_normal_slot + 1).unwrap(); // update to merge deactivated stake into reserve stake_pool_accounts From 9ee067e9a49f8afa3a7453bcce854a4e7ea316da Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Aug 2023 14:27:30 +0200 Subject: [PATCH 0449/1076] build(deps): bump serde from 1.0.181 to 1.0.183 (#4946) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.181 to 1.0.183. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.181...v1.0.183) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 68589f06..5b4b176d 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "0.7.0" [dependencies] borsh = "0.10" clap = "2.33.3" -serde = "1.0.181" +serde = "1.0.183" serde_derive = "1.0.130" serde_json = "1.0.104" solana-account-decoder = "=1.16.3" diff --git a/program/Cargo.toml b/program/Cargo.toml index 6cf2ef55..73173237 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,7 +17,7 @@ borsh = "0.10" num-derive = "0.4" num-traits = "0.2" num_enum = "0.6.1" -serde = "1.0.181" +serde = "1.0.183" serde_derive = "1.0.103" solana-program = "1.16.3" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } From bfbb8519ef29b9238623889d163c39b052cf9510 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Aug 2023 14:28:03 +0200 Subject: [PATCH 0450/1076] build(deps-dev): bump @types/node from 20.4.7 to 20.4.8 in /stake-pool/js (#4954) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.4.7 to 20.4.8. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 727349e1..938f1c09 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1757,9 +1757,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.4.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.7.tgz", - "integrity": "sha512-bUBrPjEry2QUTsnuEjzjbS7voGWCc30W0qzgMf90GPeDGFRakvrz47ju+oqDAKCXLUCe39u57/ORMl/O/04/9g==" + "version": "20.4.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.8.tgz", + "integrity": "sha512-0mHckf6D2DiIAzh8fM8f3HQCvMKDpK94YQ0DSVkfWTG9BZleYIWudw9cJxX8oCk9bM+vAkDyujDV6dmKHbvQpg==" }, "node_modules/@types/node-fetch": { "version": "2.6.4", @@ -8494,9 +8494,9 @@ "dev": true }, "@types/node": { - "version": "20.4.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.7.tgz", - "integrity": "sha512-bUBrPjEry2QUTsnuEjzjbS7voGWCc30W0qzgMf90GPeDGFRakvrz47ju+oqDAKCXLUCe39u57/ORMl/O/04/9g==" + "version": "20.4.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.8.tgz", + "integrity": "sha512-0mHckf6D2DiIAzh8fM8f3HQCvMKDpK94YQ0DSVkfWTG9BZleYIWudw9cJxX8oCk9bM+vAkDyujDV6dmKHbvQpg==" }, "@types/node-fetch": { "version": "2.6.4", From 352512745085b925d2da49958987bb2c0e1fb729 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Aug 2023 14:28:13 +0200 Subject: [PATCH 0451/1076] build(deps): bump @solana/web3.js from 1.78.2 to 1.78.3 in /stake-pool/js (#4955) build(deps): bump @solana/web3.js in /stake-pool/js Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.78.2 to 1.78.3. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.78.2...v1.78.3) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 938f1c09..47f52491 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1613,15 +1613,15 @@ } }, "node_modules/@solana/web3.js": { - "version": "1.78.2", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.78.2.tgz", - "integrity": "sha512-oF+TmBZCt3eAEl4Meu3GO2p6G8wdyoKgXgTKzQpIUIhpMGA/dVQzyMFpKjCgoTU1Kx+/UF3gXUdsZOxQukGbvQ==", + "version": "1.78.3", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.78.3.tgz", + "integrity": "sha512-qhpnyIlrj/4Czw1dBFZK6KgZBk5FwuJhvMl0C7m94jhl90yDC8b6w4svKwPjhB+OOrdQAzHyRp0+ocEs/Liw7w==", "dependencies": { "@babel/runtime": "^7.22.6", "@noble/curves": "^1.0.0", "@noble/hashes": "^1.3.0", "@solana/buffer-layout": "^4.0.0", - "agentkeepalive": "^4.2.1", + "agentkeepalive": "^4.3.0", "bigint-buffer": "^1.1.5", "bn.js": "^5.2.1", "borsh": "^0.7.0", @@ -8353,15 +8353,15 @@ } }, "@solana/web3.js": { - "version": "1.78.2", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.78.2.tgz", - "integrity": "sha512-oF+TmBZCt3eAEl4Meu3GO2p6G8wdyoKgXgTKzQpIUIhpMGA/dVQzyMFpKjCgoTU1Kx+/UF3gXUdsZOxQukGbvQ==", + "version": "1.78.3", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.78.3.tgz", + "integrity": "sha512-qhpnyIlrj/4Czw1dBFZK6KgZBk5FwuJhvMl0C7m94jhl90yDC8b6w4svKwPjhB+OOrdQAzHyRp0+ocEs/Liw7w==", "requires": { "@babel/runtime": "^7.22.6", "@noble/curves": "^1.0.0", "@noble/hashes": "^1.3.0", "@solana/buffer-layout": "^4.0.0", - "agentkeepalive": "^4.2.1", + "agentkeepalive": "^4.3.0", "bigint-buffer": "^1.1.5", "bn.js": "^5.2.1", "borsh": "^0.7.0", From 1733303b220349d002fbc59e4de811059a231090 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Aug 2023 14:28:30 +0200 Subject: [PATCH 0452/1076] build(deps-dev): bump eslint-config-prettier from 8.10.0 to 9.0.0 in /stake-pool/js (#4956) build(deps-dev): bump eslint-config-prettier in /stake-pool/js Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 8.10.0 to 9.0.0. - [Changelog](https://github.com/prettier/eslint-config-prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/eslint-config-prettier/compare/v8.10.0...v9.0.0) --- updated-dependencies: - dependency-name: eslint-config-prettier dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 14 +++++++------- clients/js-legacy/package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 47f52491..1cd75208 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -31,7 +31,7 @@ "@typescript-eslint/parser": "^6.0.0", "cross-env": "^7.0.3", "eslint": "^8.40.0", - "eslint-config-prettier": "^8.8.0", + "eslint-config-prettier": "^9.0.0", "eslint-plugin-prettier": "^5.0.0", "jest": "^27.5.1", "prettier": "^3.0.0", @@ -3431,9 +3431,9 @@ } }, "node_modules/eslint-config-prettier": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz", - "integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz", + "integrity": "sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==", "dev": true, "bin": { "eslint-config-prettier": "bin/cli.js" @@ -9713,9 +9713,9 @@ } }, "eslint-config-prettier": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz", - "integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz", + "integrity": "sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==", "dev": true, "requires": {} }, diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index f26acd58..512b088f 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -66,7 +66,7 @@ "@typescript-eslint/parser": "^6.0.0", "cross-env": "^7.0.3", "eslint": "^8.40.0", - "eslint-config-prettier": "^8.8.0", + "eslint-config-prettier": "^9.0.0", "eslint-plugin-prettier": "^5.0.0", "jest": "^27.5.1", "prettier": "^3.0.0", From a81511a7eaa332002b886e03e5d92e964459dd5e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Aug 2023 15:34:42 +0200 Subject: [PATCH 0453/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.2.1 to 6.3.0 in /stake-pool/js (#4970) build(deps-dev): bump @typescript-eslint/eslint-plugin in /stake-pool/js Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.2.1 to 6.3.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.3.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 385 ++++++++-------------------- 1 file changed, 109 insertions(+), 276 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 1cd75208..f5f4336a 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1819,16 +1819,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.2.1.tgz", - "integrity": "sha512-iZVM/ALid9kO0+I81pnp1xmYiFyqibAHzrqX4q5YvvVEyJqY+e6rfTXSCsc2jUxGNqJqTfFSSij/NFkZBiBzLw==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.3.0.tgz", + "integrity": "sha512-IZYjYZ0ifGSLZbwMqIip/nOamFiWJ9AH+T/GYNZBWkVcyNQOFGtSMoWV7RvY4poYCMZ/4lHzNl796WOSNxmk8A==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.2.1", - "@typescript-eslint/type-utils": "6.2.1", - "@typescript-eslint/utils": "6.2.1", - "@typescript-eslint/visitor-keys": "6.2.1", + "@typescript-eslint/scope-manager": "6.3.0", + "@typescript-eslint/type-utils": "6.3.0", + "@typescript-eslint/utils": "6.3.0", + "@typescript-eslint/visitor-keys": "6.3.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -1854,53 +1854,6 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.1.tgz", - "integrity": "sha512-UCqBF9WFqv64xNsIEPfBtenbfodPXsJ3nPAr55mGPkQIkiQvgoWNo+astj9ZUfJfVKiYgAZDMnM6dIpsxUMp3Q==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.2.1", - "@typescript-eslint/visitor-keys": "6.2.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.1.tgz", - "integrity": "sha512-528bGcoelrpw+sETlyM91k51Arl2ajbNT9L4JwoXE2dvRe1yd8Q64E4OL7vHYw31mlnVsf+BeeLyAZUEQtqahQ==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.1.tgz", - "integrity": "sha512-iTN6w3k2JEZ7cyVdZJTVJx2Lv7t6zFA8DCrJEHD2mwfc16AEvvBWVhbFh34XyG2NORCd0viIgQY1+u7kPI0WpA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.2.1", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/parser": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.2.1.tgz", @@ -2003,14 +1956,31 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.3.0.tgz", + "integrity": "sha512-WlNFgBEuGu74ahrXzgefiz/QlVb+qg8KDTpknKwR7hMH+lQygWyx0CQFoUmMn1zDkQjTBBIn75IxtWss77iBIQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.3.0", + "@typescript-eslint/visitor-keys": "6.3.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.2.1.tgz", - "integrity": "sha512-fTfCgomBMIgu2Dh2Or3gMYgoNAnQm3RLtRp+jP7A8fY+LJ2+9PNpi5p6QB5C4RSP+U3cjI0vDlI3mspAkpPVbQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.3.0.tgz", + "integrity": "sha512-7Oj+1ox1T2Yc8PKpBvOKWhoI/4rWFd1j7FA/rPE0lbBPXTKjdbtC+7Ev0SeBjEKkIhKWVeZSP+mR7y1Db1CdfQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.2.1", - "@typescript-eslint/utils": "6.2.1", + "@typescript-eslint/typescript-estree": "6.3.0", + "@typescript-eslint/utils": "6.3.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -2030,10 +2000,10 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.1.tgz", - "integrity": "sha512-528bGcoelrpw+sETlyM91k51Arl2ajbNT9L4JwoXE2dvRe1yd8Q64E4OL7vHYw31mlnVsf+BeeLyAZUEQtqahQ==", + "node_modules/@typescript-eslint/types": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.3.0.tgz", + "integrity": "sha512-K6TZOvfVyc7MO9j60MkRNWyFSf86IbOatTKGrpTQnzarDZPYPVy0oe3myTMq7VjhfsUAbNUW8I5s+2lZvtx1gg==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -2043,14 +2013,14 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.1.tgz", - "integrity": "sha512-G+UJeQx9AKBHRQBpmvr8T/3K5bJa485eu+4tQBxFq0KoT22+jJyzo1B50JDT9QdC1DEmWQfdKsa8ybiNWYsi0Q==", + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.3.0.tgz", + "integrity": "sha512-Xh4NVDaC4eYKY4O3QGPuQNp5NxBAlEvNQYOqJquR2MePNxO11E5K3t5x4M4Mx53IZvtpW+mBxIT0s274fLUocg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.2.1", - "@typescript-eslint/visitor-keys": "6.2.1", + "@typescript-eslint/types": "6.3.0", + "@typescript-eslint/visitor-keys": "6.3.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2070,35 +2040,18 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.1.tgz", - "integrity": "sha512-iTN6w3k2JEZ7cyVdZJTVJx2Lv7t6zFA8DCrJEHD2mwfc16AEvvBWVhbFh34XyG2NORCd0viIgQY1+u7kPI0WpA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.2.1", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/utils": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.2.1.tgz", - "integrity": "sha512-eBIXQeupYmxVB6S7x+B9SdBeB6qIdXKjgQBge2J+Ouv8h9Cxm5dHf/gfAZA6dkMaag+03HdbVInuXMmqFB/lKQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.3.0.tgz", + "integrity": "sha512-hLLg3BZE07XHnpzglNBG8P/IXq/ZVXraEbgY7FM0Cnc1ehM8RMdn9mat3LubJ3KBeYXXPxV1nugWbQPjGeJk6Q==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.2.1", - "@typescript-eslint/types": "6.2.1", - "@typescript-eslint/typescript-estree": "6.2.1", + "@typescript-eslint/scope-manager": "6.3.0", + "@typescript-eslint/types": "6.3.0", + "@typescript-eslint/typescript-estree": "6.3.0", "semver": "^7.5.4" }, "engines": { @@ -2112,70 +2065,13 @@ "eslint": "^7.0.0 || ^8.0.0" } }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.1.tgz", - "integrity": "sha512-UCqBF9WFqv64xNsIEPfBtenbfodPXsJ3nPAr55mGPkQIkiQvgoWNo+astj9ZUfJfVKiYgAZDMnM6dIpsxUMp3Q==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.2.1", - "@typescript-eslint/visitor-keys": "6.2.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.1.tgz", - "integrity": "sha512-528bGcoelrpw+sETlyM91k51Arl2ajbNT9L4JwoXE2dvRe1yd8Q64E4OL7vHYw31mlnVsf+BeeLyAZUEQtqahQ==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.1.tgz", - "integrity": "sha512-G+UJeQx9AKBHRQBpmvr8T/3K5bJa485eu+4tQBxFq0KoT22+jJyzo1B50JDT9QdC1DEmWQfdKsa8ybiNWYsi0Q==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.2.1", - "@typescript-eslint/visitor-keys": "6.2.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.1.tgz", - "integrity": "sha512-iTN6w3k2JEZ7cyVdZJTVJx2Lv7t6zFA8DCrJEHD2mwfc16AEvvBWVhbFh34XyG2NORCd0viIgQY1+u7kPI0WpA==", + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.3.0.tgz", + "integrity": "sha512-kEhRRj7HnvaSjux1J9+7dBen15CdWmDnwrpyiHsFX6Qx2iW5LOBUgNefOFeh2PjWPlNwN8TOn6+4eBU3J/gupw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.2.1", + "@typescript-eslint/types": "6.3.0", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -8556,16 +8452,16 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.2.1.tgz", - "integrity": "sha512-iZVM/ALid9kO0+I81pnp1xmYiFyqibAHzrqX4q5YvvVEyJqY+e6rfTXSCsc2jUxGNqJqTfFSSij/NFkZBiBzLw==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.3.0.tgz", + "integrity": "sha512-IZYjYZ0ifGSLZbwMqIip/nOamFiWJ9AH+T/GYNZBWkVcyNQOFGtSMoWV7RvY4poYCMZ/4lHzNl796WOSNxmk8A==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.2.1", - "@typescript-eslint/type-utils": "6.2.1", - "@typescript-eslint/utils": "6.2.1", - "@typescript-eslint/visitor-keys": "6.2.1", + "@typescript-eslint/scope-manager": "6.3.0", + "@typescript-eslint/type-utils": "6.3.0", + "@typescript-eslint/utils": "6.3.0", + "@typescript-eslint/visitor-keys": "6.3.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -8573,34 +8469,6 @@ "natural-compare-lite": "^1.4.0", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.1.tgz", - "integrity": "sha512-UCqBF9WFqv64xNsIEPfBtenbfodPXsJ3nPAr55mGPkQIkiQvgoWNo+astj9ZUfJfVKiYgAZDMnM6dIpsxUMp3Q==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.2.1", - "@typescript-eslint/visitor-keys": "6.2.1" - } - }, - "@typescript-eslint/types": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.1.tgz", - "integrity": "sha512-528bGcoelrpw+sETlyM91k51Arl2ajbNT9L4JwoXE2dvRe1yd8Q64E4OL7vHYw31mlnVsf+BeeLyAZUEQtqahQ==", - "dev": true - }, - "@typescript-eslint/visitor-keys": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.1.tgz", - "integrity": "sha512-iTN6w3k2JEZ7cyVdZJTVJx2Lv7t6zFA8DCrJEHD2mwfc16AEvvBWVhbFh34XyG2NORCd0viIgQY1+u7kPI0WpA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.2.1", - "eslint-visitor-keys": "^3.4.1" - } - } } }, "@typescript-eslint/parser": { @@ -8659,107 +8527,72 @@ } } }, + "@typescript-eslint/scope-manager": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.3.0.tgz", + "integrity": "sha512-WlNFgBEuGu74ahrXzgefiz/QlVb+qg8KDTpknKwR7hMH+lQygWyx0CQFoUmMn1zDkQjTBBIn75IxtWss77iBIQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.3.0", + "@typescript-eslint/visitor-keys": "6.3.0" + } + }, "@typescript-eslint/type-utils": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.2.1.tgz", - "integrity": "sha512-fTfCgomBMIgu2Dh2Or3gMYgoNAnQm3RLtRp+jP7A8fY+LJ2+9PNpi5p6QB5C4RSP+U3cjI0vDlI3mspAkpPVbQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.3.0.tgz", + "integrity": "sha512-7Oj+1ox1T2Yc8PKpBvOKWhoI/4rWFd1j7FA/rPE0lbBPXTKjdbtC+7Ev0SeBjEKkIhKWVeZSP+mR7y1Db1CdfQ==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "6.2.1", - "@typescript-eslint/utils": "6.2.1", + "@typescript-eslint/typescript-estree": "6.3.0", + "@typescript-eslint/utils": "6.3.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" - }, - "dependencies": { - "@typescript-eslint/types": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.1.tgz", - "integrity": "sha512-528bGcoelrpw+sETlyM91k51Arl2ajbNT9L4JwoXE2dvRe1yd8Q64E4OL7vHYw31mlnVsf+BeeLyAZUEQtqahQ==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.1.tgz", - "integrity": "sha512-G+UJeQx9AKBHRQBpmvr8T/3K5bJa485eu+4tQBxFq0KoT22+jJyzo1B50JDT9QdC1DEmWQfdKsa8ybiNWYsi0Q==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.2.1", - "@typescript-eslint/visitor-keys": "6.2.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.1.tgz", - "integrity": "sha512-iTN6w3k2JEZ7cyVdZJTVJx2Lv7t6zFA8DCrJEHD2mwfc16AEvvBWVhbFh34XyG2NORCd0viIgQY1+u7kPI0WpA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.2.1", - "eslint-visitor-keys": "^3.4.1" - } - } + } + }, + "@typescript-eslint/types": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.3.0.tgz", + "integrity": "sha512-K6TZOvfVyc7MO9j60MkRNWyFSf86IbOatTKGrpTQnzarDZPYPVy0oe3myTMq7VjhfsUAbNUW8I5s+2lZvtx1gg==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.3.0.tgz", + "integrity": "sha512-Xh4NVDaC4eYKY4O3QGPuQNp5NxBAlEvNQYOqJquR2MePNxO11E5K3t5x4M4Mx53IZvtpW+mBxIT0s274fLUocg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.3.0", + "@typescript-eslint/visitor-keys": "6.3.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" } }, "@typescript-eslint/utils": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.2.1.tgz", - "integrity": "sha512-eBIXQeupYmxVB6S7x+B9SdBeB6qIdXKjgQBge2J+Ouv8h9Cxm5dHf/gfAZA6dkMaag+03HdbVInuXMmqFB/lKQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.3.0.tgz", + "integrity": "sha512-hLLg3BZE07XHnpzglNBG8P/IXq/ZVXraEbgY7FM0Cnc1ehM8RMdn9mat3LubJ3KBeYXXPxV1nugWbQPjGeJk6Q==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.2.1", - "@typescript-eslint/types": "6.2.1", - "@typescript-eslint/typescript-estree": "6.2.1", + "@typescript-eslint/scope-manager": "6.3.0", + "@typescript-eslint/types": "6.3.0", + "@typescript-eslint/typescript-estree": "6.3.0", "semver": "^7.5.4" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.1.tgz", - "integrity": "sha512-UCqBF9WFqv64xNsIEPfBtenbfodPXsJ3nPAr55mGPkQIkiQvgoWNo+astj9ZUfJfVKiYgAZDMnM6dIpsxUMp3Q==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.2.1", - "@typescript-eslint/visitor-keys": "6.2.1" - } - }, - "@typescript-eslint/types": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.1.tgz", - "integrity": "sha512-528bGcoelrpw+sETlyM91k51Arl2ajbNT9L4JwoXE2dvRe1yd8Q64E4OL7vHYw31mlnVsf+BeeLyAZUEQtqahQ==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.1.tgz", - "integrity": "sha512-G+UJeQx9AKBHRQBpmvr8T/3K5bJa485eu+4tQBxFq0KoT22+jJyzo1B50JDT9QdC1DEmWQfdKsa8ybiNWYsi0Q==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.2.1", - "@typescript-eslint/visitor-keys": "6.2.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.1.tgz", - "integrity": "sha512-iTN6w3k2JEZ7cyVdZJTVJx2Lv7t6zFA8DCrJEHD2mwfc16AEvvBWVhbFh34XyG2NORCd0viIgQY1+u7kPI0WpA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.2.1", - "eslint-visitor-keys": "^3.4.1" - } - } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.3.0.tgz", + "integrity": "sha512-kEhRRj7HnvaSjux1J9+7dBen15CdWmDnwrpyiHsFX6Qx2iW5LOBUgNefOFeh2PjWPlNwN8TOn6+4eBU3J/gupw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.3.0", + "eslint-visitor-keys": "^3.4.1" } }, "abab": { From 7b2d4fe36e3ed9287af700f21d74cfe997f625aa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Aug 2023 16:41:32 +0200 Subject: [PATCH 0454/1076] build(deps-dev): bump @typescript-eslint/parser from 6.2.1 to 6.3.0 in /stake-pool/js (#4971) build(deps-dev): bump @typescript-eslint/parser in /stake-pool/js Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.2.1 to 6.3.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.3.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 145 +++------------------------- 1 file changed, 14 insertions(+), 131 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index f5f4336a..35ab2843 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1855,15 +1855,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.2.1.tgz", - "integrity": "sha512-Ld+uL1kYFU8e6btqBFpsHkwQ35rw30IWpdQxgOqOh4NfxSDH6uCkah1ks8R/RgQqI5hHPXMaLy9fbFseIe+dIg==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.3.0.tgz", + "integrity": "sha512-ibP+y2Gr6p0qsUkhs7InMdXrwldjxZw66wpcQq9/PzAroM45wdwyu81T+7RibNCh8oc0AgrsyCwJByncY0Ongg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.2.1", - "@typescript-eslint/types": "6.2.1", - "@typescript-eslint/typescript-estree": "6.2.1", - "@typescript-eslint/visitor-keys": "6.2.1", + "@typescript-eslint/scope-manager": "6.3.0", + "@typescript-eslint/types": "6.3.0", + "@typescript-eslint/typescript-estree": "6.3.0", + "@typescript-eslint/visitor-keys": "6.3.0", "debug": "^4.3.4" }, "engines": { @@ -1882,80 +1882,6 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.1.tgz", - "integrity": "sha512-UCqBF9WFqv64xNsIEPfBtenbfodPXsJ3nPAr55mGPkQIkiQvgoWNo+astj9ZUfJfVKiYgAZDMnM6dIpsxUMp3Q==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.2.1", - "@typescript-eslint/visitor-keys": "6.2.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.1.tgz", - "integrity": "sha512-528bGcoelrpw+sETlyM91k51Arl2ajbNT9L4JwoXE2dvRe1yd8Q64E4OL7vHYw31mlnVsf+BeeLyAZUEQtqahQ==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.1.tgz", - "integrity": "sha512-G+UJeQx9AKBHRQBpmvr8T/3K5bJa485eu+4tQBxFq0KoT22+jJyzo1B50JDT9QdC1DEmWQfdKsa8ybiNWYsi0Q==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.2.1", - "@typescript-eslint/visitor-keys": "6.2.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.1.tgz", - "integrity": "sha512-iTN6w3k2JEZ7cyVdZJTVJx2Lv7t6zFA8DCrJEHD2mwfc16AEvvBWVhbFh34XyG2NORCd0viIgQY1+u7kPI0WpA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.2.1", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/scope-manager": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.3.0.tgz", @@ -8472,59 +8398,16 @@ } }, "@typescript-eslint/parser": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.2.1.tgz", - "integrity": "sha512-Ld+uL1kYFU8e6btqBFpsHkwQ35rw30IWpdQxgOqOh4NfxSDH6uCkah1ks8R/RgQqI5hHPXMaLy9fbFseIe+dIg==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.3.0.tgz", + "integrity": "sha512-ibP+y2Gr6p0qsUkhs7InMdXrwldjxZw66wpcQq9/PzAroM45wdwyu81T+7RibNCh8oc0AgrsyCwJByncY0Ongg==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "6.2.1", - "@typescript-eslint/types": "6.2.1", - "@typescript-eslint/typescript-estree": "6.2.1", - "@typescript-eslint/visitor-keys": "6.2.1", + "@typescript-eslint/scope-manager": "6.3.0", + "@typescript-eslint/types": "6.3.0", + "@typescript-eslint/typescript-estree": "6.3.0", + "@typescript-eslint/visitor-keys": "6.3.0", "debug": "^4.3.4" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.1.tgz", - "integrity": "sha512-UCqBF9WFqv64xNsIEPfBtenbfodPXsJ3nPAr55mGPkQIkiQvgoWNo+astj9ZUfJfVKiYgAZDMnM6dIpsxUMp3Q==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.2.1", - "@typescript-eslint/visitor-keys": "6.2.1" - } - }, - "@typescript-eslint/types": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.1.tgz", - "integrity": "sha512-528bGcoelrpw+sETlyM91k51Arl2ajbNT9L4JwoXE2dvRe1yd8Q64E4OL7vHYw31mlnVsf+BeeLyAZUEQtqahQ==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.1.tgz", - "integrity": "sha512-G+UJeQx9AKBHRQBpmvr8T/3K5bJa485eu+4tQBxFq0KoT22+jJyzo1B50JDT9QdC1DEmWQfdKsa8ybiNWYsi0Q==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.2.1", - "@typescript-eslint/visitor-keys": "6.2.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.1.tgz", - "integrity": "sha512-iTN6w3k2JEZ7cyVdZJTVJx2Lv7t6zFA8DCrJEHD2mwfc16AEvvBWVhbFh34XyG2NORCd0viIgQY1+u7kPI0WpA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.2.1", - "eslint-visitor-keys": "^3.4.1" - } - } } }, "@typescript-eslint/scope-manager": { From 70a9cfd1c85f52e4f55be5099478339f38b8e4e8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Aug 2023 14:54:19 +0200 Subject: [PATCH 0455/1076] build(deps-dev): bump @types/node from 20.4.8 to 20.4.9 in /stake-pool/js (#4979) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.4.8 to 20.4.9. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 35ab2843..8f02c35d 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1757,9 +1757,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.4.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.8.tgz", - "integrity": "sha512-0mHckf6D2DiIAzh8fM8f3HQCvMKDpK94YQ0DSVkfWTG9BZleYIWudw9cJxX8oCk9bM+vAkDyujDV6dmKHbvQpg==" + "version": "20.4.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.9.tgz", + "integrity": "sha512-8e2HYcg7ohnTUbHk8focoklEQYvemQmu9M/f43DZVx43kHn0tE3BY/6gSDxS7k0SprtS0NHvj+L80cGLnoOUcQ==" }, "node_modules/@types/node-fetch": { "version": "2.6.4", @@ -8316,9 +8316,9 @@ "dev": true }, "@types/node": { - "version": "20.4.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.8.tgz", - "integrity": "sha512-0mHckf6D2DiIAzh8fM8f3HQCvMKDpK94YQ0DSVkfWTG9BZleYIWudw9cJxX8oCk9bM+vAkDyujDV6dmKHbvQpg==" + "version": "20.4.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.9.tgz", + "integrity": "sha512-8e2HYcg7ohnTUbHk8focoklEQYvemQmu9M/f43DZVx43kHn0tE3BY/6gSDxS7k0SprtS0NHvj+L80cGLnoOUcQ==" }, "@types/node-fetch": { "version": "2.6.4", From 6dce0f4928d11c5bee13e2b83b3d9f98135765a5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 12 Aug 2023 15:15:13 +0200 Subject: [PATCH 0456/1076] build(deps): bump @solana/web3.js from 1.78.3 to 1.78.4 in /stake-pool/js (#4995) build(deps): bump @solana/web3.js in /stake-pool/js Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.78.3 to 1.78.4. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.78.3...v1.78.4) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 34 ++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 8f02c35d..fec51e97 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1613,13 +1613,13 @@ } }, "node_modules/@solana/web3.js": { - "version": "1.78.3", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.78.3.tgz", - "integrity": "sha512-qhpnyIlrj/4Czw1dBFZK6KgZBk5FwuJhvMl0C7m94jhl90yDC8b6w4svKwPjhB+OOrdQAzHyRp0+ocEs/Liw7w==", + "version": "1.78.4", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.78.4.tgz", + "integrity": "sha512-up5VG1dK+GPhykmuMIozJZBbVqpm77vbOG6/r5dS7NBGZonwHfTLdBbsYc3rjmaQ4DpCXUa3tUc4RZHRORvZrw==", "dependencies": { "@babel/runtime": "^7.22.6", "@noble/curves": "^1.0.0", - "@noble/hashes": "^1.3.0", + "@noble/hashes": "^1.3.1", "@solana/buffer-layout": "^4.0.0", "agentkeepalive": "^4.3.0", "bigint-buffer": "^1.1.5", @@ -1634,6 +1634,17 @@ "superstruct": "^0.14.2" } }, + "node_modules/@solana/web3.js/node_modules/@noble/hashes": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", + "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", @@ -8175,13 +8186,13 @@ } }, "@solana/web3.js": { - "version": "1.78.3", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.78.3.tgz", - "integrity": "sha512-qhpnyIlrj/4Czw1dBFZK6KgZBk5FwuJhvMl0C7m94jhl90yDC8b6w4svKwPjhB+OOrdQAzHyRp0+ocEs/Liw7w==", + "version": "1.78.4", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.78.4.tgz", + "integrity": "sha512-up5VG1dK+GPhykmuMIozJZBbVqpm77vbOG6/r5dS7NBGZonwHfTLdBbsYc3rjmaQ4DpCXUa3tUc4RZHRORvZrw==", "requires": { "@babel/runtime": "^7.22.6", "@noble/curves": "^1.0.0", - "@noble/hashes": "^1.3.0", + "@noble/hashes": "^1.3.1", "@solana/buffer-layout": "^4.0.0", "agentkeepalive": "^4.3.0", "bigint-buffer": "^1.1.5", @@ -8194,6 +8205,13 @@ "node-fetch": "^2.6.12", "rpc-websockets": "^7.5.1", "superstruct": "^0.14.2" + }, + "dependencies": { + "@noble/hashes": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", + "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==" + } } }, "@tootallnate/once": { From 048ce859632f1b969e69f9ed391da5d5d53ecda6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Aug 2023 12:04:17 +0200 Subject: [PATCH 0457/1076] build(deps): bump num_enum from 0.6.1 to 0.7.0 (#5003) Bumps [num_enum](https://github.com/illicitonion/num_enum) from 0.6.1 to 0.7.0. - [Commits](https://github.com/illicitonion/num_enum/commits) --- updated-dependencies: - dependency-name: num_enum dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 73173237..11fe64b8 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -16,7 +16,7 @@ arrayref = "0.3.7" borsh = "0.10" num-derive = "0.4" num-traits = "0.2" -num_enum = "0.6.1" +num_enum = "0.7.0" serde = "1.0.183" serde_derive = "1.0.103" solana-program = "1.16.3" From 808355ebdc6e336d7b7f82a0fd004a10c3db3113 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Aug 2023 14:50:34 +0200 Subject: [PATCH 0458/1076] build(deps-dev): bump @types/node from 20.4.9 to 20.5.0 in /stake-pool/js (#5012) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.4.9 to 20.5.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index fec51e97..d9482003 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1768,9 +1768,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.4.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.9.tgz", - "integrity": "sha512-8e2HYcg7ohnTUbHk8focoklEQYvemQmu9M/f43DZVx43kHn0tE3BY/6gSDxS7k0SprtS0NHvj+L80cGLnoOUcQ==" + "version": "20.5.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.0.tgz", + "integrity": "sha512-Mgq7eCtoTjT89FqNoTzzXg2XvCi5VMhRV6+I2aYanc6kQCBImeNaAYRs/DyoVqk1YEUJK5gN9VO7HRIdz4Wo3Q==" }, "node_modules/@types/node-fetch": { "version": "2.6.4", @@ -8334,9 +8334,9 @@ "dev": true }, "@types/node": { - "version": "20.4.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.9.tgz", - "integrity": "sha512-8e2HYcg7ohnTUbHk8focoklEQYvemQmu9M/f43DZVx43kHn0tE3BY/6gSDxS7k0SprtS0NHvj+L80cGLnoOUcQ==" + "version": "20.5.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.0.tgz", + "integrity": "sha512-Mgq7eCtoTjT89FqNoTzzXg2XvCi5VMhRV6+I2aYanc6kQCBImeNaAYRs/DyoVqk1YEUJK5gN9VO7HRIdz4Wo3Q==" }, "@types/node-fetch": { "version": "2.6.4", From f3335ed99ea9984253f27f09d7cd635322611d84 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Aug 2023 14:54:10 +0200 Subject: [PATCH 0459/1076] build(deps-dev): bump eslint from 8.46.0 to 8.47.0 in /stake-pool/js (#5013) Bumps [eslint](https://github.com/eslint/eslint) from 8.46.0 to 8.47.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.46.0...v8.47.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 72 ++++++++++++++--------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index d9482003..2c5eac9d 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -694,9 +694,9 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.1.tgz", - "integrity": "sha512-9t7ZA7NGGK8ckelF0PQCfcxIUzs1Md5rrO6U/c+FIQNanea5UZC0wqKXH4vHBccmu4ZJgZ2idtPeW7+Q2npOEA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", + "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", "dev": true, "dependencies": { "ajv": "^6.12.4", @@ -717,9 +717,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.46.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.46.0.tgz", - "integrity": "sha512-a8TLtmPi8xzPkCbp/OGFUo5yhRkHM2Ko9kOWP4znJr0WAhWyThaw3PnwX4vOTWOAMsV2uRt32PPDcEz63esSaA==", + "version": "8.47.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.47.0.tgz", + "integrity": "sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3210,15 +3210,15 @@ } }, "node_modules/eslint": { - "version": "8.46.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.46.0.tgz", - "integrity": "sha512-cIO74PvbW0qU8e0mIvk5IV3ToWdCq5FYG6gWPHHkx6gNdjlbAYvtfHmlCMXxjcoVaIdwy/IAt3+mDkZkfvb2Dg==", + "version": "8.47.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz", + "integrity": "sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.1", - "@eslint/js": "^8.46.0", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "^8.47.0", "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -3229,7 +3229,7 @@ "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.2", + "eslint-visitor-keys": "^3.4.3", "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", @@ -3321,9 +3321,9 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.2.tgz", - "integrity": "sha512-8drBzUEyZ2llkpCA67iYrgEssKDUu68V8ChqqOfFupIaG/LCVPUT+CoGJpT77zJprs4T/W7p07LP7zAIMuweVw==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3822,9 +3822,9 @@ } }, "node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.21.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", + "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -7537,9 +7537,9 @@ "dev": true }, "@eslint/eslintrc": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.1.tgz", - "integrity": "sha512-9t7ZA7NGGK8ckelF0PQCfcxIUzs1Md5rrO6U/c+FIQNanea5UZC0wqKXH4vHBccmu4ZJgZ2idtPeW7+Q2npOEA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", + "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -7554,9 +7554,9 @@ } }, "@eslint/js": { - "version": "8.46.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.46.0.tgz", - "integrity": "sha512-a8TLtmPi8xzPkCbp/OGFUo5yhRkHM2Ko9kOWP4znJr0WAhWyThaw3PnwX4vOTWOAMsV2uRt32PPDcEz63esSaA==", + "version": "8.47.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.47.0.tgz", + "integrity": "sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og==", "dev": true }, "@humanwhocodes/config-array": { @@ -9363,15 +9363,15 @@ } }, "eslint": { - "version": "8.46.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.46.0.tgz", - "integrity": "sha512-cIO74PvbW0qU8e0mIvk5IV3ToWdCq5FYG6gWPHHkx6gNdjlbAYvtfHmlCMXxjcoVaIdwy/IAt3+mDkZkfvb2Dg==", + "version": "8.47.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz", + "integrity": "sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.1", - "@eslint/js": "^8.46.0", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "^8.47.0", "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -9382,7 +9382,7 @@ "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.2", + "eslint-visitor-keys": "^3.4.3", "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", @@ -9474,9 +9474,9 @@ } }, "eslint-visitor-keys": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.2.tgz", - "integrity": "sha512-8drBzUEyZ2llkpCA67iYrgEssKDUu68V8ChqqOfFupIaG/LCVPUT+CoGJpT77zJprs4T/W7p07LP7zAIMuweVw==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true }, "espree": { @@ -9804,9 +9804,9 @@ } }, "globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.21.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", + "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", "dev": true, "requires": { "type-fest": "^0.20.2" From 100b704dcf0aac0d6a09f8738309be3cf634c45e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Aug 2023 14:57:07 +0200 Subject: [PATCH 0460/1076] build(deps-dev): bump @rollup/plugin-commonjs from 25.0.3 to 25.0.4 in /stake-pool/js (#5014) build(deps-dev): bump @rollup/plugin-commonjs in /stake-pool/js Bumps [@rollup/plugin-commonjs](https://github.com/rollup/plugins/tree/HEAD/packages/commonjs) from 25.0.3 to 25.0.4. - [Changelog](https://github.com/rollup/plugins/blob/master/packages/commonjs/CHANGELOG.md) - [Commits](https://github.com/rollup/plugins/commits/commonjs-v25.0.4/packages/commonjs) --- updated-dependencies: - dependency-name: "@rollup/plugin-commonjs" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 2c5eac9d..2cc7c695 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1346,9 +1346,9 @@ } }, "node_modules/@rollup/plugin-commonjs": { - "version": "25.0.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.3.tgz", - "integrity": "sha512-uBdtWr/H3BVcgm97MUdq2oJmqBR23ny1hOrWe2PKo9FTbjsGqg32jfasJUKYAI5ouqacjRnj65mBB/S79F+GQA==", + "version": "25.0.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.4.tgz", + "integrity": "sha512-L92Vz9WUZXDnlQQl3EwbypJR4+DM2EbsO+/KOcEkP4Mc6Ct453EeDB2uH9lgRwj4w5yflgNpq9pHOiY8aoUXBQ==", "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1", @@ -8022,9 +8022,9 @@ } }, "@rollup/plugin-commonjs": { - "version": "25.0.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.3.tgz", - "integrity": "sha512-uBdtWr/H3BVcgm97MUdq2oJmqBR23ny1hOrWe2PKo9FTbjsGqg32jfasJUKYAI5ouqacjRnj65mBB/S79F+GQA==", + "version": "25.0.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.4.tgz", + "integrity": "sha512-L92Vz9WUZXDnlQQl3EwbypJR4+DM2EbsO+/KOcEkP4Mc6Ct453EeDB2uH9lgRwj4w5yflgNpq9pHOiY8aoUXBQ==", "dev": true, "requires": { "@rollup/pluginutils": "^5.0.1", From 9b61a7a83df4c306a9bcc9f3d59095622a2f23cc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Aug 2023 23:36:25 +0200 Subject: [PATCH 0461/1076] build(deps-dev): bump @typescript-eslint/parser from 6.3.0 to 6.4.0 in /stake-pool/js (#5025) build(deps-dev): bump @typescript-eslint/parser in /stake-pool/js Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.3.0 to 6.4.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.4.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 145 +++++++++++++++++++++++++--- 1 file changed, 131 insertions(+), 14 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 2cc7c695..bb7325f2 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1866,15 +1866,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.3.0.tgz", - "integrity": "sha512-ibP+y2Gr6p0qsUkhs7InMdXrwldjxZw66wpcQq9/PzAroM45wdwyu81T+7RibNCh8oc0AgrsyCwJByncY0Ongg==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.4.0.tgz", + "integrity": "sha512-I1Ah1irl033uxjxO9Xql7+biL3YD7w9IU8zF+xlzD/YxY6a4b7DYA08PXUUCbm2sEljwJF6ERFy2kTGAGcNilg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.3.0", - "@typescript-eslint/types": "6.3.0", - "@typescript-eslint/typescript-estree": "6.3.0", - "@typescript-eslint/visitor-keys": "6.3.0", + "@typescript-eslint/scope-manager": "6.4.0", + "@typescript-eslint/types": "6.4.0", + "@typescript-eslint/typescript-estree": "6.4.0", + "@typescript-eslint/visitor-keys": "6.4.0", "debug": "^4.3.4" }, "engines": { @@ -1893,6 +1893,80 @@ } } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.4.0.tgz", + "integrity": "sha512-TUS7vaKkPWDVvl7GDNHFQMsMruD+zhkd3SdVW0d7b+7Zo+bd/hXJQ8nsiUZMi1jloWo6c9qt3B7Sqo+flC1nig==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.4.0", + "@typescript-eslint/visitor-keys": "6.4.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.4.0.tgz", + "integrity": "sha512-+FV9kVFrS7w78YtzkIsNSoYsnOtrYVnKWSTVXoL1761CsCRv5wpDOINgsXpxD67YCLZtVQekDDyaxfjVWUJmmg==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.4.0.tgz", + "integrity": "sha512-iDPJArf/K2sxvjOR6skeUCNgHR/tCQXBsa+ee1/clRKr3olZjZ/dSkXPZjG6YkPtnW6p5D1egeEPMCW6Gn4yLA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.4.0", + "@typescript-eslint/visitor-keys": "6.4.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.4.0.tgz", + "integrity": "sha512-yJSfyT+uJm+JRDWYRYdCm2i+pmvXJSMtPR9Cq5/XQs4QIgNoLcoRtDdzsLbLsFM/c6um6ohQkg/MLxWvoIndJA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.4.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.3.0.tgz", @@ -8416,16 +8490,59 @@ } }, "@typescript-eslint/parser": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.3.0.tgz", - "integrity": "sha512-ibP+y2Gr6p0qsUkhs7InMdXrwldjxZw66wpcQq9/PzAroM45wdwyu81T+7RibNCh8oc0AgrsyCwJByncY0Ongg==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.4.0.tgz", + "integrity": "sha512-I1Ah1irl033uxjxO9Xql7+biL3YD7w9IU8zF+xlzD/YxY6a4b7DYA08PXUUCbm2sEljwJF6ERFy2kTGAGcNilg==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "6.3.0", - "@typescript-eslint/types": "6.3.0", - "@typescript-eslint/typescript-estree": "6.3.0", - "@typescript-eslint/visitor-keys": "6.3.0", + "@typescript-eslint/scope-manager": "6.4.0", + "@typescript-eslint/types": "6.4.0", + "@typescript-eslint/typescript-estree": "6.4.0", + "@typescript-eslint/visitor-keys": "6.4.0", "debug": "^4.3.4" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.4.0.tgz", + "integrity": "sha512-TUS7vaKkPWDVvl7GDNHFQMsMruD+zhkd3SdVW0d7b+7Zo+bd/hXJQ8nsiUZMi1jloWo6c9qt3B7Sqo+flC1nig==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.4.0", + "@typescript-eslint/visitor-keys": "6.4.0" + } + }, + "@typescript-eslint/types": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.4.0.tgz", + "integrity": "sha512-+FV9kVFrS7w78YtzkIsNSoYsnOtrYVnKWSTVXoL1761CsCRv5wpDOINgsXpxD67YCLZtVQekDDyaxfjVWUJmmg==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.4.0.tgz", + "integrity": "sha512-iDPJArf/K2sxvjOR6skeUCNgHR/tCQXBsa+ee1/clRKr3olZjZ/dSkXPZjG6YkPtnW6p5D1egeEPMCW6Gn4yLA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.4.0", + "@typescript-eslint/visitor-keys": "6.4.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.4.0.tgz", + "integrity": "sha512-yJSfyT+uJm+JRDWYRYdCm2i+pmvXJSMtPR9Cq5/XQs4QIgNoLcoRtDdzsLbLsFM/c6um6ohQkg/MLxWvoIndJA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.4.0", + "eslint-visitor-keys": "^3.4.1" + } + } } }, "@typescript-eslint/scope-manager": { From 30d9ba14f36871ca0800dd0cd1c2c438435620da Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Aug 2023 00:08:52 +0200 Subject: [PATCH 0462/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.3.0 to 6.4.0 in /stake-pool/js (#5026) build(deps-dev): bump @typescript-eslint/eslint-plugin in /stake-pool/js Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.3.0 to 6.4.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.4.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 263 +++++++--------------------- 1 file changed, 66 insertions(+), 197 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index bb7325f2..6d006019 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1830,21 +1830,20 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.3.0.tgz", - "integrity": "sha512-IZYjYZ0ifGSLZbwMqIip/nOamFiWJ9AH+T/GYNZBWkVcyNQOFGtSMoWV7RvY4poYCMZ/4lHzNl796WOSNxmk8A==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.4.0.tgz", + "integrity": "sha512-62o2Hmc7Gs3p8SLfbXcipjWAa6qk2wZGChXG2JbBtYpwSRmti/9KHLqfbLs9uDigOexG+3PaQ9G2g3201FWLKg==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.3.0", - "@typescript-eslint/type-utils": "6.3.0", - "@typescript-eslint/utils": "6.3.0", - "@typescript-eslint/visitor-keys": "6.3.0", + "@typescript-eslint/scope-manager": "6.4.0", + "@typescript-eslint/type-utils": "6.4.0", + "@typescript-eslint/utils": "6.4.0", + "@typescript-eslint/visitor-keys": "6.4.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", "natural-compare": "^1.4.0", - "natural-compare-lite": "^1.4.0", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" }, @@ -1893,7 +1892,7 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "node_modules/@typescript-eslint/scope-manager": { "version": "6.4.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.4.0.tgz", "integrity": "sha512-TUS7vaKkPWDVvl7GDNHFQMsMruD+zhkd3SdVW0d7b+7Zo+bd/hXJQ8nsiUZMi1jloWo6c9qt3B7Sqo+flC1nig==", @@ -1910,88 +1909,14 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.4.0.tgz", - "integrity": "sha512-+FV9kVFrS7w78YtzkIsNSoYsnOtrYVnKWSTVXoL1761CsCRv5wpDOINgsXpxD67YCLZtVQekDDyaxfjVWUJmmg==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.4.0.tgz", - "integrity": "sha512-iDPJArf/K2sxvjOR6skeUCNgHR/tCQXBsa+ee1/clRKr3olZjZ/dSkXPZjG6YkPtnW6p5D1egeEPMCW6Gn4yLA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.4.0", - "@typescript-eslint/visitor-keys": "6.4.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.4.0.tgz", - "integrity": "sha512-yJSfyT+uJm+JRDWYRYdCm2i+pmvXJSMtPR9Cq5/XQs4QIgNoLcoRtDdzsLbLsFM/c6um6ohQkg/MLxWvoIndJA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.4.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.3.0.tgz", - "integrity": "sha512-WlNFgBEuGu74ahrXzgefiz/QlVb+qg8KDTpknKwR7hMH+lQygWyx0CQFoUmMn1zDkQjTBBIn75IxtWss77iBIQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.3.0", - "@typescript-eslint/visitor-keys": "6.3.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.3.0.tgz", - "integrity": "sha512-7Oj+1ox1T2Yc8PKpBvOKWhoI/4rWFd1j7FA/rPE0lbBPXTKjdbtC+7Ev0SeBjEKkIhKWVeZSP+mR7y1Db1CdfQ==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.4.0.tgz", + "integrity": "sha512-TvqrUFFyGY0cX3WgDHcdl2/mMCWCDv/0thTtx/ODMY1QhEiyFtv/OlLaNIiYLwRpAxAtOLOY9SUf1H3Q3dlwAg==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.3.0", - "@typescript-eslint/utils": "6.3.0", + "@typescript-eslint/typescript-estree": "6.4.0", + "@typescript-eslint/utils": "6.4.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -2012,9 +1937,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.3.0.tgz", - "integrity": "sha512-K6TZOvfVyc7MO9j60MkRNWyFSf86IbOatTKGrpTQnzarDZPYPVy0oe3myTMq7VjhfsUAbNUW8I5s+2lZvtx1gg==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.4.0.tgz", + "integrity": "sha512-+FV9kVFrS7w78YtzkIsNSoYsnOtrYVnKWSTVXoL1761CsCRv5wpDOINgsXpxD67YCLZtVQekDDyaxfjVWUJmmg==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -2025,13 +1950,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.3.0.tgz", - "integrity": "sha512-Xh4NVDaC4eYKY4O3QGPuQNp5NxBAlEvNQYOqJquR2MePNxO11E5K3t5x4M4Mx53IZvtpW+mBxIT0s274fLUocg==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.4.0.tgz", + "integrity": "sha512-iDPJArf/K2sxvjOR6skeUCNgHR/tCQXBsa+ee1/clRKr3olZjZ/dSkXPZjG6YkPtnW6p5D1egeEPMCW6Gn4yLA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.3.0", - "@typescript-eslint/visitor-keys": "6.3.0", + "@typescript-eslint/types": "6.4.0", + "@typescript-eslint/visitor-keys": "6.4.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2052,17 +1977,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.3.0.tgz", - "integrity": "sha512-hLLg3BZE07XHnpzglNBG8P/IXq/ZVXraEbgY7FM0Cnc1ehM8RMdn9mat3LubJ3KBeYXXPxV1nugWbQPjGeJk6Q==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.4.0.tgz", + "integrity": "sha512-BvvwryBQpECPGo8PwF/y/q+yacg8Hn/2XS+DqL/oRsOPK+RPt29h5Ui5dqOKHDlbXrAeHUTnyG3wZA0KTDxRZw==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.3.0", - "@typescript-eslint/types": "6.3.0", - "@typescript-eslint/typescript-estree": "6.3.0", + "@typescript-eslint/scope-manager": "6.4.0", + "@typescript-eslint/types": "6.4.0", + "@typescript-eslint/typescript-estree": "6.4.0", "semver": "^7.5.4" }, "engines": { @@ -2077,12 +2002,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.3.0.tgz", - "integrity": "sha512-kEhRRj7HnvaSjux1J9+7dBen15CdWmDnwrpyiHsFX6Qx2iW5LOBUgNefOFeh2PjWPlNwN8TOn6+4eBU3J/gupw==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.4.0.tgz", + "integrity": "sha512-yJSfyT+uJm+JRDWYRYdCm2i+pmvXJSMtPR9Cq5/XQs4QIgNoLcoRtDdzsLbLsFM/c6um6ohQkg/MLxWvoIndJA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.3.0", + "@typescript-eslint/types": "6.4.0", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -5431,12 +5356,6 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true - }, "node_modules/node-fetch": { "version": "2.6.12", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", @@ -8470,21 +8389,20 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.3.0.tgz", - "integrity": "sha512-IZYjYZ0ifGSLZbwMqIip/nOamFiWJ9AH+T/GYNZBWkVcyNQOFGtSMoWV7RvY4poYCMZ/4lHzNl796WOSNxmk8A==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.4.0.tgz", + "integrity": "sha512-62o2Hmc7Gs3p8SLfbXcipjWAa6qk2wZGChXG2JbBtYpwSRmti/9KHLqfbLs9uDigOexG+3PaQ9G2g3201FWLKg==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.3.0", - "@typescript-eslint/type-utils": "6.3.0", - "@typescript-eslint/utils": "6.3.0", - "@typescript-eslint/visitor-keys": "6.3.0", + "@typescript-eslint/scope-manager": "6.4.0", + "@typescript-eslint/type-utils": "6.4.0", + "@typescript-eslint/utils": "6.4.0", + "@typescript-eslint/visitor-keys": "6.4.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", "natural-compare": "^1.4.0", - "natural-compare-lite": "^1.4.0", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" } @@ -8500,87 +8418,44 @@ "@typescript-eslint/typescript-estree": "6.4.0", "@typescript-eslint/visitor-keys": "6.4.0", "debug": "^4.3.4" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.4.0.tgz", - "integrity": "sha512-TUS7vaKkPWDVvl7GDNHFQMsMruD+zhkd3SdVW0d7b+7Zo+bd/hXJQ8nsiUZMi1jloWo6c9qt3B7Sqo+flC1nig==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.4.0", - "@typescript-eslint/visitor-keys": "6.4.0" - } - }, - "@typescript-eslint/types": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.4.0.tgz", - "integrity": "sha512-+FV9kVFrS7w78YtzkIsNSoYsnOtrYVnKWSTVXoL1761CsCRv5wpDOINgsXpxD67YCLZtVQekDDyaxfjVWUJmmg==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.4.0.tgz", - "integrity": "sha512-iDPJArf/K2sxvjOR6skeUCNgHR/tCQXBsa+ee1/clRKr3olZjZ/dSkXPZjG6YkPtnW6p5D1egeEPMCW6Gn4yLA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.4.0", - "@typescript-eslint/visitor-keys": "6.4.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.4.0.tgz", - "integrity": "sha512-yJSfyT+uJm+JRDWYRYdCm2i+pmvXJSMtPR9Cq5/XQs4QIgNoLcoRtDdzsLbLsFM/c6um6ohQkg/MLxWvoIndJA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.4.0", - "eslint-visitor-keys": "^3.4.1" - } - } } }, "@typescript-eslint/scope-manager": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.3.0.tgz", - "integrity": "sha512-WlNFgBEuGu74ahrXzgefiz/QlVb+qg8KDTpknKwR7hMH+lQygWyx0CQFoUmMn1zDkQjTBBIn75IxtWss77iBIQ==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.4.0.tgz", + "integrity": "sha512-TUS7vaKkPWDVvl7GDNHFQMsMruD+zhkd3SdVW0d7b+7Zo+bd/hXJQ8nsiUZMi1jloWo6c9qt3B7Sqo+flC1nig==", "dev": true, "requires": { - "@typescript-eslint/types": "6.3.0", - "@typescript-eslint/visitor-keys": "6.3.0" + "@typescript-eslint/types": "6.4.0", + "@typescript-eslint/visitor-keys": "6.4.0" } }, "@typescript-eslint/type-utils": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.3.0.tgz", - "integrity": "sha512-7Oj+1ox1T2Yc8PKpBvOKWhoI/4rWFd1j7FA/rPE0lbBPXTKjdbtC+7Ev0SeBjEKkIhKWVeZSP+mR7y1Db1CdfQ==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.4.0.tgz", + "integrity": "sha512-TvqrUFFyGY0cX3WgDHcdl2/mMCWCDv/0thTtx/ODMY1QhEiyFtv/OlLaNIiYLwRpAxAtOLOY9SUf1H3Q3dlwAg==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "6.3.0", - "@typescript-eslint/utils": "6.3.0", + "@typescript-eslint/typescript-estree": "6.4.0", + "@typescript-eslint/utils": "6.4.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" } }, "@typescript-eslint/types": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.3.0.tgz", - "integrity": "sha512-K6TZOvfVyc7MO9j60MkRNWyFSf86IbOatTKGrpTQnzarDZPYPVy0oe3myTMq7VjhfsUAbNUW8I5s+2lZvtx1gg==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.4.0.tgz", + "integrity": "sha512-+FV9kVFrS7w78YtzkIsNSoYsnOtrYVnKWSTVXoL1761CsCRv5wpDOINgsXpxD67YCLZtVQekDDyaxfjVWUJmmg==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.3.0.tgz", - "integrity": "sha512-Xh4NVDaC4eYKY4O3QGPuQNp5NxBAlEvNQYOqJquR2MePNxO11E5K3t5x4M4Mx53IZvtpW+mBxIT0s274fLUocg==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.4.0.tgz", + "integrity": "sha512-iDPJArf/K2sxvjOR6skeUCNgHR/tCQXBsa+ee1/clRKr3olZjZ/dSkXPZjG6YkPtnW6p5D1egeEPMCW6Gn4yLA==", "dev": true, "requires": { - "@typescript-eslint/types": "6.3.0", - "@typescript-eslint/visitor-keys": "6.3.0", + "@typescript-eslint/types": "6.4.0", + "@typescript-eslint/visitor-keys": "6.4.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -8589,27 +8464,27 @@ } }, "@typescript-eslint/utils": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.3.0.tgz", - "integrity": "sha512-hLLg3BZE07XHnpzglNBG8P/IXq/ZVXraEbgY7FM0Cnc1ehM8RMdn9mat3LubJ3KBeYXXPxV1nugWbQPjGeJk6Q==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.4.0.tgz", + "integrity": "sha512-BvvwryBQpECPGo8PwF/y/q+yacg8Hn/2XS+DqL/oRsOPK+RPt29h5Ui5dqOKHDlbXrAeHUTnyG3wZA0KTDxRZw==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.3.0", - "@typescript-eslint/types": "6.3.0", - "@typescript-eslint/typescript-estree": "6.3.0", + "@typescript-eslint/scope-manager": "6.4.0", + "@typescript-eslint/types": "6.4.0", + "@typescript-eslint/typescript-estree": "6.4.0", "semver": "^7.5.4" } }, "@typescript-eslint/visitor-keys": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.3.0.tgz", - "integrity": "sha512-kEhRRj7HnvaSjux1J9+7dBen15CdWmDnwrpyiHsFX6Qx2iW5LOBUgNefOFeh2PjWPlNwN8TOn6+4eBU3J/gupw==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.4.0.tgz", + "integrity": "sha512-yJSfyT+uJm+JRDWYRYdCm2i+pmvXJSMtPR9Cq5/XQs4QIgNoLcoRtDdzsLbLsFM/c6um6ohQkg/MLxWvoIndJA==", "dev": true, "requires": { - "@typescript-eslint/types": "6.3.0", + "@typescript-eslint/types": "6.4.0", "eslint-visitor-keys": "^3.4.1" } }, @@ -11079,12 +10954,6 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true - }, "node-fetch": { "version": "2.6.12", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", From 032f92b7bc20b655f4f713e4e1713b616e00d332 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Aug 2023 13:06:14 +0200 Subject: [PATCH 0463/1076] build(deps): bump serde_json from 1.0.104 to 1.0.105 (#5038) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.104 to 1.0.105. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.104...v1.0.105) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 5b4b176d..19e0e3b4 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ borsh = "0.10" clap = "2.33.3" serde = "1.0.183" serde_derive = "1.0.130" -serde_json = "1.0.104" +serde_json = "1.0.105" solana-account-decoder = "=1.16.3" solana-clap-utils = "=1.16.3" solana-cli-config = "=1.16.3" From 36730a776c9eb14ead203c096722552cbb264dea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Aug 2023 15:53:05 +0200 Subject: [PATCH 0464/1076] build(deps-dev): bump prettier from 3.0.1 to 3.0.2 in /stake-pool/js (#5044) Bumps [prettier](https://github.com/prettier/prettier) from 3.0.1 to 3.0.2. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/3.0.1...3.0.2) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 6d006019..b94dbe89 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -5691,9 +5691,9 @@ } }, "node_modules/prettier": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.1.tgz", - "integrity": "sha512-fcOWSnnpCrovBsmFZIGIy9UqK2FaI7Hqax+DIO0A9UxeVoY4iweyaFjS5TavZN97Hfehph0nhsZnjlVKzEQSrQ==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.2.tgz", + "integrity": "sha512-o2YR9qtniXvwEZlOKbveKfDQVyqxbEIWn48Z8m3ZJjBjcCmUy3xZGIv+7AkaeuaTr6yPXJjwv07ZWlsWbEy1rQ==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" @@ -11199,9 +11199,9 @@ "dev": true }, "prettier": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.1.tgz", - "integrity": "sha512-fcOWSnnpCrovBsmFZIGIy9UqK2FaI7Hqax+DIO0A9UxeVoY4iweyaFjS5TavZN97Hfehph0nhsZnjlVKzEQSrQ==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.2.tgz", + "integrity": "sha512-o2YR9qtniXvwEZlOKbveKfDQVyqxbEIWn48Z8m3ZJjBjcCmUy3xZGIv+7AkaeuaTr6yPXJjwv07ZWlsWbEy1rQ==", "dev": true }, "prettier-linter-helpers": { From 86c1e7475e10461360033da2e361277b87c95fea Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 17 Aug 2023 12:36:47 +0200 Subject: [PATCH 0465/1076] stake-pool: Update minimum reserve balance to 0 (#5031) * stake-pool: Update minimum reserve balance to 0 * Also update the python bindings * Update JS bindings too --- clients/js-legacy/src/index.ts | 5 +++-- clients/js-legacy/src/utils/stake.ts | 2 +- clients/py/stake_pool/constants.py | 2 +- program/src/lib.rs | 4 +--- program/src/processor.rs | 4 ++-- program/tests/helpers/mod.rs | 2 +- program/tests/withdraw_edge_cases.rs | 10 ++++------ 7 files changed, 13 insertions(+), 16 deletions(-) diff --git a/clients/js-legacy/src/index.ts b/clients/js-legacy/src/index.ts index 9b77e2a3..122214b2 100644 --- a/clients/js-legacy/src/index.ts +++ b/clients/js-legacy/src/index.ts @@ -934,8 +934,9 @@ export async function stakePoolInfo(connection: Connection, stakePoolAddress: Pu stakePoolAddress, ); - const minimumReserveStakeBalance = - (await connection.getMinimumBalanceForRentExemption(StakeProgram.space)) + 1; + const minimumReserveStakeBalance = await connection.getMinimumBalanceForRentExemption( + StakeProgram.space, + ); const stakeAccounts = await Promise.all( validatorList.account.data.validators.map(async (validator) => { diff --git a/clients/js-legacy/src/utils/stake.ts b/clients/js-legacy/src/utils/stake.ts index 9eef2c6c..25535431 100644 --- a/clients/js-legacy/src/utils/stake.ts +++ b/clients/js-legacy/src/utils/stake.ts @@ -115,7 +115,7 @@ export async function prepareWithdrawAccounts( accounts = accounts.sort(compareFn ? compareFn : (a, b) => b.lamports - a.lamports); const reserveStake = await connection.getAccountInfo(stakePool.reserveStake); - const reserveStakeBalance = (reserveStake?.lamports ?? 0) - minBalanceForRentExemption - 1; + const reserveStakeBalance = (reserveStake?.lamports ?? 0) - minBalanceForRentExemption; if (reserveStakeBalance > 0) { accounts.push({ type: 'reserve', diff --git a/clients/py/stake_pool/constants.py b/clients/py/stake_pool/constants.py index 766a0d2d..f6c278e2 100644 --- a/clients/py/stake_pool/constants.py +++ b/clients/py/stake_pool/constants.py @@ -11,7 +11,7 @@ MAX_VALIDATORS_TO_UPDATE: int = 5 """Maximum number of validators to update during UpdateValidatorListBalance.""" -MINIMUM_RESERVE_LAMPORTS: int = 1 +MINIMUM_RESERVE_LAMPORTS: int = 0 """Minimum balance required in the stake pool reserve""" MINIMUM_ACTIVE_STAKE: int = MINIMUM_DELEGATION diff --git a/program/src/lib.rs b/program/src/lib.rs index ab5bef67..8ef0193f 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -37,9 +37,7 @@ const EPHEMERAL_STAKE_SEED_PREFIX: &[u8] = b"ephemeral"; pub const MINIMUM_ACTIVE_STAKE: u64 = 1_000_000; /// Minimum amount of lamports in the reserve -/// NOTE: This can be changed to 0 once the `stake_allow_zero_undelegated_amount` -/// feature is enabled on all clusters -pub const MINIMUM_RESERVE_LAMPORTS: u64 = 1; +pub const MINIMUM_RESERVE_LAMPORTS: u64 = 0; /// Maximum amount of validator stake accounts to update per /// `UpdateValidatorListBalance` instruction, based on compute limits diff --git a/program/src/processor.rs b/program/src/processor.rs index ee926d4a..04249143 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1619,13 +1619,13 @@ impl Processor { if reserve_stake_account_info .lamports() .saturating_sub(total_lamports) - <= stake_rent + < stake_rent { let max_split_amount = reserve_stake_account_info .lamports() .saturating_sub(stake_rent.saturating_mul(2)); msg!( - "Reserve stake does not have enough lamports for increase, must be less than {}, {} requested", + "Reserve stake does not have enough lamports for increase, maximum amount {}, {} requested", max_split_amount, lamports ); diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index b709fab8..7057228c 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -676,7 +676,7 @@ pub async fn create_blank_stake_account( stake: &Keypair, ) -> u64 { let rent = banks_client.get_rent().await.unwrap(); - let lamports = rent.minimum_balance(std::mem::size_of::()) + 1; + let lamports = rent.minimum_balance(std::mem::size_of::()); let transaction = Transaction::new_signed_with_payer( &[system_instruction::create_account( diff --git a/program/tests/withdraw_edge_cases.rs b/program/tests/withdraw_edge_cases.rs index ab4523a1..46c49b34 100644 --- a/program/tests/withdraw_edge_cases.rs +++ b/program/tests/withdraw_edge_cases.rs @@ -11,7 +11,7 @@ use { }, solana_program_test::*, solana_sdk::{signature::Signer, transaction::TransactionError}, - spl_stake_pool::{error::StakePoolError, instruction, state, MINIMUM_RESERVE_LAMPORTS}, + spl_stake_pool::{error::StakePoolError, instruction, state}, test_case::test_case, }; @@ -205,7 +205,7 @@ async fn success_remove_validator(multiple: u64) { get_account(&mut context.banks_client, &user_stake_recipient.pubkey()).await; assert_eq!( user_stake_recipient_account.lamports, - remaining_lamports + stake_rent + 1 + remaining_lamports + stake_rent ); // Check that cleanup happens correctly @@ -398,7 +398,7 @@ async fn success_with_reserve() { let stake_state = deserialize::(&reserve_stake_account.data).unwrap(); let meta = stake_state.meta().unwrap(); assert_eq!( - MINIMUM_RESERVE_LAMPORTS + meta.rent_exempt_reserve + withdrawal_fee + deposit_fee, + meta.rent_exempt_reserve + withdrawal_fee + deposit_fee, reserve_stake_account.lamports ); @@ -407,9 +407,7 @@ async fn success_with_reserve() { get_account(&mut context.banks_client, &user_stake_recipient.pubkey()).await; assert_eq!( user_stake_recipient_account.lamports, - MINIMUM_RESERVE_LAMPORTS + deposit_info.stake_lamports + stake_rent * 2 - - withdrawal_fee - - deposit_fee + deposit_info.stake_lamports + stake_rent * 2 - withdrawal_fee - deposit_fee ); } From 5ecffb08609f6773ecd43accfc428a7adc682cef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 17 Aug 2023 15:08:29 +0200 Subject: [PATCH 0466/1076] build(deps-dev): bump @rollup/plugin-node-resolve from 15.1.0 to 15.2.0 in /stake-pool/js (#5049) build(deps-dev): bump @rollup/plugin-node-resolve in /stake-pool/js Bumps [@rollup/plugin-node-resolve](https://github.com/rollup/plugins/tree/HEAD/packages/node-resolve) from 15.1.0 to 15.2.0. - [Changelog](https://github.com/rollup/plugins/blob/master/packages/node-resolve/CHANGELOG.md) - [Commits](https://github.com/rollup/plugins/commits/node-resolve-v15.2.0/packages/node-resolve) --- updated-dependencies: - dependency-name: "@rollup/plugin-node-resolve" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index b94dbe89..016f7a52 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1464,9 +1464,9 @@ } }, "node_modules/@rollup/plugin-node-resolve": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.1.0.tgz", - "integrity": "sha512-xeZHCgsiZ9pzYVgAo9580eCGqwh/XCEUM9q6iQfGNocjgkufHAqC3exA+45URvhiYV8sBF9RlBai650eNs7AsA==", + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.0.tgz", + "integrity": "sha512-mKur03xNGT8O9ODO6FtT43ITGqHWZbKPdVJHZb+iV9QYcdlhUUB0wgknvA4KCUmC5oHJF6O2W1EgmyOQyVUI4Q==", "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1", @@ -8090,9 +8090,9 @@ } }, "@rollup/plugin-node-resolve": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.1.0.tgz", - "integrity": "sha512-xeZHCgsiZ9pzYVgAo9580eCGqwh/XCEUM9q6iQfGNocjgkufHAqC3exA+45URvhiYV8sBF9RlBai650eNs7AsA==", + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.0.tgz", + "integrity": "sha512-mKur03xNGT8O9ODO6FtT43ITGqHWZbKPdVJHZb+iV9QYcdlhUUB0wgknvA4KCUmC5oHJF6O2W1EgmyOQyVUI4Q==", "dev": true, "requires": { "@rollup/pluginutils": "^5.0.1", From fc0e0bc3d1568cfe28cfec887296d9ed4bbd860d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Aug 2023 15:04:05 +0200 Subject: [PATCH 0467/1076] build(deps): bump serde from 1.0.183 to 1.0.185 (#5055) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.183 to 1.0.185. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.183...v1.0.185) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 19e0e3b4..7d43911c 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "0.7.0" [dependencies] borsh = "0.10" clap = "2.33.3" -serde = "1.0.183" +serde = "1.0.185" serde_derive = "1.0.130" serde_json = "1.0.105" solana-account-decoder = "=1.16.3" diff --git a/program/Cargo.toml b/program/Cargo.toml index 11fe64b8..46f69ec3 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,7 +17,7 @@ borsh = "0.10" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.0" -serde = "1.0.183" +serde = "1.0.185" serde_derive = "1.0.103" solana-program = "1.16.3" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } From abf4d65077349b8b707d732558dfed67f57ed937 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Aug 2023 15:05:36 +0200 Subject: [PATCH 0468/1076] build(deps-dev): bump @types/node from 20.5.0 to 20.5.1 in /stake-pool/js (#5063) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.5.0 to 20.5.1. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 016f7a52..7730c5a8 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1768,9 +1768,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.0.tgz", - "integrity": "sha512-Mgq7eCtoTjT89FqNoTzzXg2XvCi5VMhRV6+I2aYanc6kQCBImeNaAYRs/DyoVqk1YEUJK5gN9VO7HRIdz4Wo3Q==" + "version": "20.5.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.1.tgz", + "integrity": "sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==" }, "node_modules/@types/node-fetch": { "version": "2.6.4", @@ -8327,9 +8327,9 @@ "dev": true }, "@types/node": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.0.tgz", - "integrity": "sha512-Mgq7eCtoTjT89FqNoTzzXg2XvCi5VMhRV6+I2aYanc6kQCBImeNaAYRs/DyoVqk1YEUJK5gN9VO7HRIdz4Wo3Q==" + "version": "20.5.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.1.tgz", + "integrity": "sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==" }, "@types/node-fetch": { "version": "2.6.4", From 677cc38e55c486a9fc02f8c28de20e059203479d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Aug 2023 19:14:05 +0200 Subject: [PATCH 0469/1076] build(deps-dev): bump @typescript-eslint/parser from 6.4.0 to 6.4.1 in /stake-pool/js (#5076) build(deps-dev): bump @typescript-eslint/parser in /stake-pool/js Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.4.0 to 6.4.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.4.1/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 145 +++++++++++++++++++++++++--- 1 file changed, 131 insertions(+), 14 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 7730c5a8..75f73f69 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1865,15 +1865,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.4.0.tgz", - "integrity": "sha512-I1Ah1irl033uxjxO9Xql7+biL3YD7w9IU8zF+xlzD/YxY6a4b7DYA08PXUUCbm2sEljwJF6ERFy2kTGAGcNilg==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.4.1.tgz", + "integrity": "sha512-610G6KHymg9V7EqOaNBMtD1GgpAmGROsmfHJPXNLCU9bfIuLrkdOygltK784F6Crboyd5tBFayPB7Sf0McrQwg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.4.0", - "@typescript-eslint/types": "6.4.0", - "@typescript-eslint/typescript-estree": "6.4.0", - "@typescript-eslint/visitor-keys": "6.4.0", + "@typescript-eslint/scope-manager": "6.4.1", + "@typescript-eslint/types": "6.4.1", + "@typescript-eslint/typescript-estree": "6.4.1", + "@typescript-eslint/visitor-keys": "6.4.1", "debug": "^4.3.4" }, "engines": { @@ -1892,6 +1892,80 @@ } } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.4.1.tgz", + "integrity": "sha512-p/OavqOQfm4/Hdrr7kvacOSFjwQ2rrDVJRPxt/o0TOWdFnjJptnjnZ+sYDR7fi4OimvIuKp+2LCkc+rt9fIW+A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.4.1", + "@typescript-eslint/visitor-keys": "6.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.4.1.tgz", + "integrity": "sha512-zAAopbNuYu++ijY1GV2ylCsQsi3B8QvfPHVqhGdDcbx/NK5lkqMnCGU53amAjccSpk+LfeONxwzUhDzArSfZJg==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.4.1.tgz", + "integrity": "sha512-xF6Y7SatVE/OyV93h1xGgfOkHr2iXuo8ip0gbfzaKeGGuKiAnzS+HtVhSPx8Www243bwlW8IF7X0/B62SzFftg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.4.1", + "@typescript-eslint/visitor-keys": "6.4.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.4.1.tgz", + "integrity": "sha512-y/TyRJsbZPkJIZQXrHfdnxVnxyKegnpEvnRGNam7s3TRR2ykGefEWOhaef00/UUN3IZxizS7BTO3svd3lCOJRQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.4.1", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "6.4.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.4.0.tgz", @@ -8408,16 +8482,59 @@ } }, "@typescript-eslint/parser": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.4.0.tgz", - "integrity": "sha512-I1Ah1irl033uxjxO9Xql7+biL3YD7w9IU8zF+xlzD/YxY6a4b7DYA08PXUUCbm2sEljwJF6ERFy2kTGAGcNilg==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.4.1.tgz", + "integrity": "sha512-610G6KHymg9V7EqOaNBMtD1GgpAmGROsmfHJPXNLCU9bfIuLrkdOygltK784F6Crboyd5tBFayPB7Sf0McrQwg==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "6.4.0", - "@typescript-eslint/types": "6.4.0", - "@typescript-eslint/typescript-estree": "6.4.0", - "@typescript-eslint/visitor-keys": "6.4.0", + "@typescript-eslint/scope-manager": "6.4.1", + "@typescript-eslint/types": "6.4.1", + "@typescript-eslint/typescript-estree": "6.4.1", + "@typescript-eslint/visitor-keys": "6.4.1", "debug": "^4.3.4" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.4.1.tgz", + "integrity": "sha512-p/OavqOQfm4/Hdrr7kvacOSFjwQ2rrDVJRPxt/o0TOWdFnjJptnjnZ+sYDR7fi4OimvIuKp+2LCkc+rt9fIW+A==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.4.1", + "@typescript-eslint/visitor-keys": "6.4.1" + } + }, + "@typescript-eslint/types": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.4.1.tgz", + "integrity": "sha512-zAAopbNuYu++ijY1GV2ylCsQsi3B8QvfPHVqhGdDcbx/NK5lkqMnCGU53amAjccSpk+LfeONxwzUhDzArSfZJg==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.4.1.tgz", + "integrity": "sha512-xF6Y7SatVE/OyV93h1xGgfOkHr2iXuo8ip0gbfzaKeGGuKiAnzS+HtVhSPx8Www243bwlW8IF7X0/B62SzFftg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.4.1", + "@typescript-eslint/visitor-keys": "6.4.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.4.1.tgz", + "integrity": "sha512-y/TyRJsbZPkJIZQXrHfdnxVnxyKegnpEvnRGNam7s3TRR2ykGefEWOhaef00/UUN3IZxizS7BTO3svd3lCOJRQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.4.1", + "eslint-visitor-keys": "^3.4.1" + } + } } }, "@typescript-eslint/scope-manager": { From 01663c7634782fbab83bca4f71d07e5eee9ab8cf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Aug 2023 19:14:38 +0200 Subject: [PATCH 0470/1076] build(deps-dev): bump @rollup/plugin-node-resolve from 15.2.0 to 15.2.1 in /stake-pool/js (#5078) build(deps-dev): bump @rollup/plugin-node-resolve in /stake-pool/js Bumps [@rollup/plugin-node-resolve](https://github.com/rollup/plugins/tree/HEAD/packages/node-resolve) from 15.2.0 to 15.2.1. - [Changelog](https://github.com/rollup/plugins/blob/master/packages/node-resolve/CHANGELOG.md) - [Commits](https://github.com/rollup/plugins/commits/node-resolve-v15.2.1/packages/node-resolve) --- updated-dependencies: - dependency-name: "@rollup/plugin-node-resolve" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 75f73f69..0d987fed 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1464,9 +1464,9 @@ } }, "node_modules/@rollup/plugin-node-resolve": { - "version": "15.2.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.0.tgz", - "integrity": "sha512-mKur03xNGT8O9ODO6FtT43ITGqHWZbKPdVJHZb+iV9QYcdlhUUB0wgknvA4KCUmC5oHJF6O2W1EgmyOQyVUI4Q==", + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.1.tgz", + "integrity": "sha512-nsbUg588+GDSu8/NS8T4UAshO6xeaOfINNuXeVHcKV02LJtoRaM1SiOacClw4kws1SFiNhdLGxlbMY9ga/zs/w==", "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1", @@ -8164,9 +8164,9 @@ } }, "@rollup/plugin-node-resolve": { - "version": "15.2.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.0.tgz", - "integrity": "sha512-mKur03xNGT8O9ODO6FtT43ITGqHWZbKPdVJHZb+iV9QYcdlhUUB0wgknvA4KCUmC5oHJF6O2W1EgmyOQyVUI4Q==", + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.1.tgz", + "integrity": "sha512-nsbUg588+GDSu8/NS8T4UAshO6xeaOfINNuXeVHcKV02LJtoRaM1SiOacClw4kws1SFiNhdLGxlbMY9ga/zs/w==", "dev": true, "requires": { "@rollup/pluginutils": "^5.0.1", From 47f000995da780bef9aa3323b02633fb200577b8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Aug 2023 19:44:23 +0200 Subject: [PATCH 0471/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.4.0 to 6.4.1 in /stake-pool/js (#5077) build(deps-dev): bump @typescript-eslint/eslint-plugin in /stake-pool/js Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.4.0 to 6.4.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.4.1/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 249 ++++++++-------------------- 1 file changed, 66 insertions(+), 183 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 0d987fed..186df98b 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1830,16 +1830,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.4.0.tgz", - "integrity": "sha512-62o2Hmc7Gs3p8SLfbXcipjWAa6qk2wZGChXG2JbBtYpwSRmti/9KHLqfbLs9uDigOexG+3PaQ9G2g3201FWLKg==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.4.1.tgz", + "integrity": "sha512-3F5PtBzUW0dYlq77Lcqo13fv+58KDwUib3BddilE8ajPJT+faGgxmI9Sw+I8ZS22BYwoir9ZhNXcLi+S+I2bkw==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.4.0", - "@typescript-eslint/type-utils": "6.4.0", - "@typescript-eslint/utils": "6.4.0", - "@typescript-eslint/visitor-keys": "6.4.0", + "@typescript-eslint/scope-manager": "6.4.1", + "@typescript-eslint/type-utils": "6.4.1", + "@typescript-eslint/utils": "6.4.1", + "@typescript-eslint/visitor-keys": "6.4.1", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -1892,7 +1892,7 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "node_modules/@typescript-eslint/scope-manager": { "version": "6.4.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.4.1.tgz", "integrity": "sha512-p/OavqOQfm4/Hdrr7kvacOSFjwQ2rrDVJRPxt/o0TOWdFnjJptnjnZ+sYDR7fi4OimvIuKp+2LCkc+rt9fIW+A==", @@ -1909,88 +1909,14 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.4.1.tgz", - "integrity": "sha512-zAAopbNuYu++ijY1GV2ylCsQsi3B8QvfPHVqhGdDcbx/NK5lkqMnCGU53amAjccSpk+LfeONxwzUhDzArSfZJg==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.4.1.tgz", - "integrity": "sha512-xF6Y7SatVE/OyV93h1xGgfOkHr2iXuo8ip0gbfzaKeGGuKiAnzS+HtVhSPx8Www243bwlW8IF7X0/B62SzFftg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.4.1", - "@typescript-eslint/visitor-keys": "6.4.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.4.1.tgz", - "integrity": "sha512-y/TyRJsbZPkJIZQXrHfdnxVnxyKegnpEvnRGNam7s3TRR2ykGefEWOhaef00/UUN3IZxizS7BTO3svd3lCOJRQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.4.1", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.4.0.tgz", - "integrity": "sha512-TUS7vaKkPWDVvl7GDNHFQMsMruD+zhkd3SdVW0d7b+7Zo+bd/hXJQ8nsiUZMi1jloWo6c9qt3B7Sqo+flC1nig==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.4.0", - "@typescript-eslint/visitor-keys": "6.4.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.4.0.tgz", - "integrity": "sha512-TvqrUFFyGY0cX3WgDHcdl2/mMCWCDv/0thTtx/ODMY1QhEiyFtv/OlLaNIiYLwRpAxAtOLOY9SUf1H3Q3dlwAg==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.4.1.tgz", + "integrity": "sha512-7ON8M8NXh73SGZ5XvIqWHjgX2f+vvaOarNliGhjrJnv1vdjG0LVIz+ToYfPirOoBi56jxAKLfsLm40+RvxVVXA==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.4.0", - "@typescript-eslint/utils": "6.4.0", + "@typescript-eslint/typescript-estree": "6.4.1", + "@typescript-eslint/utils": "6.4.1", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -2011,9 +1937,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.4.0.tgz", - "integrity": "sha512-+FV9kVFrS7w78YtzkIsNSoYsnOtrYVnKWSTVXoL1761CsCRv5wpDOINgsXpxD67YCLZtVQekDDyaxfjVWUJmmg==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.4.1.tgz", + "integrity": "sha512-zAAopbNuYu++ijY1GV2ylCsQsi3B8QvfPHVqhGdDcbx/NK5lkqMnCGU53amAjccSpk+LfeONxwzUhDzArSfZJg==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -2024,13 +1950,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.4.0.tgz", - "integrity": "sha512-iDPJArf/K2sxvjOR6skeUCNgHR/tCQXBsa+ee1/clRKr3olZjZ/dSkXPZjG6YkPtnW6p5D1egeEPMCW6Gn4yLA==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.4.1.tgz", + "integrity": "sha512-xF6Y7SatVE/OyV93h1xGgfOkHr2iXuo8ip0gbfzaKeGGuKiAnzS+HtVhSPx8Www243bwlW8IF7X0/B62SzFftg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.4.0", - "@typescript-eslint/visitor-keys": "6.4.0", + "@typescript-eslint/types": "6.4.1", + "@typescript-eslint/visitor-keys": "6.4.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2051,17 +1977,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.4.0.tgz", - "integrity": "sha512-BvvwryBQpECPGo8PwF/y/q+yacg8Hn/2XS+DqL/oRsOPK+RPt29h5Ui5dqOKHDlbXrAeHUTnyG3wZA0KTDxRZw==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.4.1.tgz", + "integrity": "sha512-F/6r2RieNeorU0zhqZNv89s9bDZSovv3bZQpUNOmmQK1L80/cV4KEu95YUJWi75u5PhboFoKUJBnZ4FQcoqhDw==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.4.0", - "@typescript-eslint/types": "6.4.0", - "@typescript-eslint/typescript-estree": "6.4.0", + "@typescript-eslint/scope-manager": "6.4.1", + "@typescript-eslint/types": "6.4.1", + "@typescript-eslint/typescript-estree": "6.4.1", "semver": "^7.5.4" }, "engines": { @@ -2076,12 +2002,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.4.0.tgz", - "integrity": "sha512-yJSfyT+uJm+JRDWYRYdCm2i+pmvXJSMtPR9Cq5/XQs4QIgNoLcoRtDdzsLbLsFM/c6um6ohQkg/MLxWvoIndJA==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.4.1.tgz", + "integrity": "sha512-y/TyRJsbZPkJIZQXrHfdnxVnxyKegnpEvnRGNam7s3TRR2ykGefEWOhaef00/UUN3IZxizS7BTO3svd3lCOJRQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.4.0", + "@typescript-eslint/types": "6.4.1", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -8463,16 +8389,16 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.4.0.tgz", - "integrity": "sha512-62o2Hmc7Gs3p8SLfbXcipjWAa6qk2wZGChXG2JbBtYpwSRmti/9KHLqfbLs9uDigOexG+3PaQ9G2g3201FWLKg==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.4.1.tgz", + "integrity": "sha512-3F5PtBzUW0dYlq77Lcqo13fv+58KDwUib3BddilE8ajPJT+faGgxmI9Sw+I8ZS22BYwoir9ZhNXcLi+S+I2bkw==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.4.0", - "@typescript-eslint/type-utils": "6.4.0", - "@typescript-eslint/utils": "6.4.0", - "@typescript-eslint/visitor-keys": "6.4.0", + "@typescript-eslint/scope-manager": "6.4.1", + "@typescript-eslint/type-utils": "6.4.1", + "@typescript-eslint/utils": "6.4.1", + "@typescript-eslint/visitor-keys": "6.4.1", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -8492,87 +8418,44 @@ "@typescript-eslint/typescript-estree": "6.4.1", "@typescript-eslint/visitor-keys": "6.4.1", "debug": "^4.3.4" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.4.1.tgz", - "integrity": "sha512-p/OavqOQfm4/Hdrr7kvacOSFjwQ2rrDVJRPxt/o0TOWdFnjJptnjnZ+sYDR7fi4OimvIuKp+2LCkc+rt9fIW+A==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.4.1", - "@typescript-eslint/visitor-keys": "6.4.1" - } - }, - "@typescript-eslint/types": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.4.1.tgz", - "integrity": "sha512-zAAopbNuYu++ijY1GV2ylCsQsi3B8QvfPHVqhGdDcbx/NK5lkqMnCGU53amAjccSpk+LfeONxwzUhDzArSfZJg==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.4.1.tgz", - "integrity": "sha512-xF6Y7SatVE/OyV93h1xGgfOkHr2iXuo8ip0gbfzaKeGGuKiAnzS+HtVhSPx8Www243bwlW8IF7X0/B62SzFftg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.4.1", - "@typescript-eslint/visitor-keys": "6.4.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.4.1.tgz", - "integrity": "sha512-y/TyRJsbZPkJIZQXrHfdnxVnxyKegnpEvnRGNam7s3TRR2ykGefEWOhaef00/UUN3IZxizS7BTO3svd3lCOJRQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.4.1", - "eslint-visitor-keys": "^3.4.1" - } - } } }, "@typescript-eslint/scope-manager": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.4.0.tgz", - "integrity": "sha512-TUS7vaKkPWDVvl7GDNHFQMsMruD+zhkd3SdVW0d7b+7Zo+bd/hXJQ8nsiUZMi1jloWo6c9qt3B7Sqo+flC1nig==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.4.1.tgz", + "integrity": "sha512-p/OavqOQfm4/Hdrr7kvacOSFjwQ2rrDVJRPxt/o0TOWdFnjJptnjnZ+sYDR7fi4OimvIuKp+2LCkc+rt9fIW+A==", "dev": true, "requires": { - "@typescript-eslint/types": "6.4.0", - "@typescript-eslint/visitor-keys": "6.4.0" + "@typescript-eslint/types": "6.4.1", + "@typescript-eslint/visitor-keys": "6.4.1" } }, "@typescript-eslint/type-utils": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.4.0.tgz", - "integrity": "sha512-TvqrUFFyGY0cX3WgDHcdl2/mMCWCDv/0thTtx/ODMY1QhEiyFtv/OlLaNIiYLwRpAxAtOLOY9SUf1H3Q3dlwAg==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.4.1.tgz", + "integrity": "sha512-7ON8M8NXh73SGZ5XvIqWHjgX2f+vvaOarNliGhjrJnv1vdjG0LVIz+ToYfPirOoBi56jxAKLfsLm40+RvxVVXA==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "6.4.0", - "@typescript-eslint/utils": "6.4.0", + "@typescript-eslint/typescript-estree": "6.4.1", + "@typescript-eslint/utils": "6.4.1", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" } }, "@typescript-eslint/types": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.4.0.tgz", - "integrity": "sha512-+FV9kVFrS7w78YtzkIsNSoYsnOtrYVnKWSTVXoL1761CsCRv5wpDOINgsXpxD67YCLZtVQekDDyaxfjVWUJmmg==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.4.1.tgz", + "integrity": "sha512-zAAopbNuYu++ijY1GV2ylCsQsi3B8QvfPHVqhGdDcbx/NK5lkqMnCGU53amAjccSpk+LfeONxwzUhDzArSfZJg==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.4.0.tgz", - "integrity": "sha512-iDPJArf/K2sxvjOR6skeUCNgHR/tCQXBsa+ee1/clRKr3olZjZ/dSkXPZjG6YkPtnW6p5D1egeEPMCW6Gn4yLA==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.4.1.tgz", + "integrity": "sha512-xF6Y7SatVE/OyV93h1xGgfOkHr2iXuo8ip0gbfzaKeGGuKiAnzS+HtVhSPx8Www243bwlW8IF7X0/B62SzFftg==", "dev": true, "requires": { - "@typescript-eslint/types": "6.4.0", - "@typescript-eslint/visitor-keys": "6.4.0", + "@typescript-eslint/types": "6.4.1", + "@typescript-eslint/visitor-keys": "6.4.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -8581,27 +8464,27 @@ } }, "@typescript-eslint/utils": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.4.0.tgz", - "integrity": "sha512-BvvwryBQpECPGo8PwF/y/q+yacg8Hn/2XS+DqL/oRsOPK+RPt29h5Ui5dqOKHDlbXrAeHUTnyG3wZA0KTDxRZw==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.4.1.tgz", + "integrity": "sha512-F/6r2RieNeorU0zhqZNv89s9bDZSovv3bZQpUNOmmQK1L80/cV4KEu95YUJWi75u5PhboFoKUJBnZ4FQcoqhDw==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.4.0", - "@typescript-eslint/types": "6.4.0", - "@typescript-eslint/typescript-estree": "6.4.0", + "@typescript-eslint/scope-manager": "6.4.1", + "@typescript-eslint/types": "6.4.1", + "@typescript-eslint/typescript-estree": "6.4.1", "semver": "^7.5.4" } }, "@typescript-eslint/visitor-keys": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.4.0.tgz", - "integrity": "sha512-yJSfyT+uJm+JRDWYRYdCm2i+pmvXJSMtPR9Cq5/XQs4QIgNoLcoRtDdzsLbLsFM/c6um6ohQkg/MLxWvoIndJA==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.4.1.tgz", + "integrity": "sha512-y/TyRJsbZPkJIZQXrHfdnxVnxyKegnpEvnRGNam7s3TRR2ykGefEWOhaef00/UUN3IZxizS7BTO3svd3lCOJRQ==", "dev": true, "requires": { - "@typescript-eslint/types": "6.4.0", + "@typescript-eslint/types": "6.4.1", "eslint-visitor-keys": "^3.4.1" } }, From 66bc5853f6710b6f5790dacf1316fe92f0c061cb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 23 Aug 2023 14:56:37 +0200 Subject: [PATCH 0472/1076] build(deps-dev): bump @types/node from 20.5.1 to 20.5.3 in /stake-pool/js (#5089) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.5.1 to 20.5.3. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 186df98b..cdffb053 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1768,9 +1768,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.5.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.1.tgz", - "integrity": "sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==" + "version": "20.5.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.3.tgz", + "integrity": "sha512-ITI7rbWczR8a/S6qjAW7DMqxqFMjjTo61qZVWJ1ubPvbIQsL5D/TvwjYEalM8Kthpe3hTzOGrF2TGbAu2uyqeA==" }, "node_modules/@types/node-fetch": { "version": "2.6.4", @@ -8327,9 +8327,9 @@ "dev": true }, "@types/node": { - "version": "20.5.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.1.tgz", - "integrity": "sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==" + "version": "20.5.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.3.tgz", + "integrity": "sha512-ITI7rbWczR8a/S6qjAW7DMqxqFMjjTo61qZVWJ1ubPvbIQsL5D/TvwjYEalM8Kthpe3hTzOGrF2TGbAu2uyqeA==" }, "@types/node-fetch": { "version": "2.6.4", From 4ac3d133792706682f1e92801e0851f07505f056 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 24 Aug 2023 12:22:18 +0200 Subject: [PATCH 0473/1076] build(deps): bump serde from 1.0.185 to 1.0.186 (#5097) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.185 to 1.0.186. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.185...v1.0.186) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 7d43911c..503db519 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "0.7.0" [dependencies] borsh = "0.10" clap = "2.33.3" -serde = "1.0.185" +serde = "1.0.186" serde_derive = "1.0.130" serde_json = "1.0.105" solana-account-decoder = "=1.16.3" diff --git a/program/Cargo.toml b/program/Cargo.toml index 46f69ec3..71202515 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,7 +17,7 @@ borsh = "0.10" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.0" -serde = "1.0.185" +serde = "1.0.186" serde_derive = "1.0.103" solana-program = "1.16.3" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } From 25641867c17ea7dc0a70d7f355d339d870f12523 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 24 Aug 2023 15:54:59 +0200 Subject: [PATCH 0474/1076] build(deps-dev): bump @types/node from 20.5.3 to 20.5.4 in /stake-pool/js (#5101) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.5.3 to 20.5.4. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index cdffb053..ef4ca57e 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1768,9 +1768,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.5.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.3.tgz", - "integrity": "sha512-ITI7rbWczR8a/S6qjAW7DMqxqFMjjTo61qZVWJ1ubPvbIQsL5D/TvwjYEalM8Kthpe3hTzOGrF2TGbAu2uyqeA==" + "version": "20.5.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.4.tgz", + "integrity": "sha512-Y9vbIAoM31djQZrPYjpTLo0XlaSwOIsrlfE3LpulZeRblttsLQRFRlBAppW0LOxyT3ALj2M5vU1ucQQayQH3jA==" }, "node_modules/@types/node-fetch": { "version": "2.6.4", @@ -8327,9 +8327,9 @@ "dev": true }, "@types/node": { - "version": "20.5.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.3.tgz", - "integrity": "sha512-ITI7rbWczR8a/S6qjAW7DMqxqFMjjTo61qZVWJ1ubPvbIQsL5D/TvwjYEalM8Kthpe3hTzOGrF2TGbAu2uyqeA==" + "version": "20.5.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.4.tgz", + "integrity": "sha512-Y9vbIAoM31djQZrPYjpTLo0XlaSwOIsrlfE3LpulZeRblttsLQRFRlBAppW0LOxyT3ALj2M5vU1ucQQayQH3jA==" }, "@types/node-fetch": { "version": "2.6.4", From 8c67a9847ea3f61ff68f2b847bf995f75378ddc1 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 24 Aug 2023 18:16:05 +0200 Subject: [PATCH 0475/1076] stake-pool-js: implement bindings for token metadata instructions (#5103) * stake-pool-js: implement bindings for token metadata instructions - revert changes - add token metadata - remove MINIMUM_RESERVE_LAMPORTS * Support dynamic instruction layouts for metadata * Fix merge error * Fixup tests --------- Co-authored-by: Alexander Ray --- clients/js-legacy/src/constants.ts | 6 + clients/js-legacy/src/index.ts | 78 ++++++++++ clients/js-legacy/src/instructions.ts | 142 +++++++++++++++++- .../js-legacy/src/utils/program-address.ts | 17 ++- clients/js-legacy/test/instructions.test.ts | 44 ++++++ 5 files changed, 285 insertions(+), 2 deletions(-) diff --git a/clients/js-legacy/src/constants.ts b/clients/js-legacy/src/constants.ts index 9423f7ce..d0f24ffa 100644 --- a/clients/js-legacy/src/constants.ts +++ b/clients/js-legacy/src/constants.ts @@ -1,6 +1,12 @@ import { Buffer } from 'buffer'; import { LAMPORTS_PER_SOL, PublicKey } from '@solana/web3.js'; +// Public key that identifies the metadata program. +export const METADATA_PROGRAM_ID = new PublicKey('metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s'); +export const METADATA_MAX_NAME_LENGTH = 32; +export const METADATA_MAX_SYMBOL_LENGTH = 10; +export const METADATA_MAX_URI_LENGTH = 200; + // Public key that identifies the SPL Stake Pool program. export const STAKE_POOL_PROGRAM_ID = new PublicKey('SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy'); diff --git a/clients/js-legacy/src/index.ts b/clients/js-legacy/src/index.ts index 122214b2..a06dd6d4 100644 --- a/clients/js-legacy/src/index.ts +++ b/clients/js-legacy/src/index.ts @@ -28,6 +28,7 @@ import { lamportsToSol, solToLamports, findEphemeralStakeProgramAddress, + findMetadataAddress, } from './utils'; import { StakePoolInstruction } from './instructions'; import { @@ -1109,3 +1110,80 @@ export async function redelegate(props: RedelegateProps) { instructions, }; } + +/** + * Creates instructions required to create pool token metadata. + */ +export async function createPoolTokenMetadata( + connection: Connection, + stakePoolAddress: PublicKey, + payer: PublicKey, + name: string, + symbol: string, + uri: string, +) { + const stakePool = await getStakePoolAccount(connection, stakePoolAddress); + + const withdrawAuthority = await findWithdrawAuthorityProgramAddress( + STAKE_POOL_PROGRAM_ID, + stakePoolAddress, + ); + const tokenMetadata = findMetadataAddress(stakePool.account.data.poolMint); + const manager = stakePool.account.data.manager; + + const instructions: TransactionInstruction[] = []; + instructions.push( + StakePoolInstruction.createTokenMetadata({ + stakePool: stakePoolAddress, + poolMint: stakePool.account.data.poolMint, + payer, + manager, + tokenMetadata, + withdrawAuthority, + name, + symbol, + uri, + }), + ); + + return { + instructions, + }; +} + +/** + * Creates instructions required to update pool token metadata. + */ +export async function updatePoolTokenMetadata( + connection: Connection, + stakePoolAddress: PublicKey, + name: string, + symbol: string, + uri: string, +) { + const stakePool = await getStakePoolAccount(connection, stakePoolAddress); + + const withdrawAuthority = await findWithdrawAuthorityProgramAddress( + STAKE_POOL_PROGRAM_ID, + stakePoolAddress, + ); + + const tokenMetadata = findMetadataAddress(stakePool.account.data.poolMint); + + const instructions: TransactionInstruction[] = []; + instructions.push( + StakePoolInstruction.updateTokenMetadata({ + stakePool: stakePoolAddress, + manager: stakePool.account.data.manager, + tokenMetadata, + withdrawAuthority, + name, + symbol, + uri, + }), + ); + + return { + instructions, + }; +} diff --git a/clients/js-legacy/src/instructions.ts b/clients/js-legacy/src/instructions.ts index bfc35f38..60cd9b64 100644 --- a/clients/js-legacy/src/instructions.ts +++ b/clients/js-legacy/src/instructions.ts @@ -10,9 +10,15 @@ import { } from '@solana/web3.js'; import * as BufferLayout from '@solana/buffer-layout'; import { TOKEN_PROGRAM_ID } from '@solana/spl-token'; -import { STAKE_POOL_PROGRAM_ID } from './constants'; import { InstructionType, encodeData, decodeData } from './utils'; import BN from 'bn.js'; +import { + METADATA_MAX_NAME_LENGTH, + METADATA_MAX_SYMBOL_LENGTH, + METADATA_MAX_URI_LENGTH, + METADATA_PROGRAM_ID, + STAKE_POOL_PROGRAM_ID, +} from './constants'; /** * An enumeration of valid StakePoolInstructionType's @@ -31,6 +37,8 @@ export type StakePoolInstructionType = | 'DecreaseAdditionalValidatorStake' | 'Redelegate'; +// 'UpdateTokenMetadata' and 'CreateTokenMetadata' have dynamic layouts + const MOVE_STAKE_LAYOUT = BufferLayout.struct([ BufferLayout.u8('instruction'), BufferLayout.ns64('lamports'), @@ -43,6 +51,38 @@ const UPDATE_VALIDATOR_LIST_BALANCE_LAYOUT = BufferLayout.struct([ BufferLayout.u8('noMerge'), ]); +export function tokenMetadataLayout( + instruction: number, + nameLength: number, + symbolLength: number, + uriLength: number, +) { + if (nameLength > METADATA_MAX_NAME_LENGTH) { + throw 'maximum token name length is 32 characters'; + } + + if (symbolLength > METADATA_MAX_SYMBOL_LENGTH) { + throw 'maximum token symbol length is 10 characters'; + } + + if (uriLength > METADATA_MAX_URI_LENGTH) { + throw 'maximum token uri length is 200 characters'; + } + + return { + index: instruction, + layout: BufferLayout.struct([ + BufferLayout.u8('instruction'), + BufferLayout.u32('nameLen'), + BufferLayout.blob(nameLength, 'name'), + BufferLayout.u32('symbolLen'), + BufferLayout.blob(symbolLength, 'symbol'), + BufferLayout.u32('uriLen'), + BufferLayout.blob(uriLength, 'uri'), + ]), + }; +} + /** * An enumeration of valid stake InstructionType's * @internal @@ -303,6 +343,28 @@ export type RedelegateParams = { destinationTransientStakeSeed: number | BN; }; +export type CreateTokenMetadataParams = { + stakePool: PublicKey; + manager: PublicKey; + tokenMetadata: PublicKey; + withdrawAuthority: PublicKey; + poolMint: PublicKey; + payer: PublicKey; + name: string; + symbol: string; + uri: string; +}; + +export type UpdateTokenMetadataParams = { + stakePool: PublicKey; + manager: PublicKey; + tokenMetadata: PublicKey; + withdrawAuthority: PublicKey; + name: string; + symbol: string; + uri: string; +}; + /** * Stake Pool Instruction class */ @@ -823,6 +885,84 @@ export class StakePoolInstruction { }); } + /** + * Creates an instruction to create metadata + * using the mpl token metadata program for the pool token + */ + static createTokenMetadata(params: CreateTokenMetadataParams): TransactionInstruction { + const { + stakePool, + withdrawAuthority, + tokenMetadata, + manager, + payer, + poolMint, + name, + symbol, + uri, + } = params; + + const keys = [ + { pubkey: stakePool, isSigner: false, isWritable: false }, + { pubkey: manager, isSigner: true, isWritable: false }, + { pubkey: withdrawAuthority, isSigner: false, isWritable: false }, + { pubkey: poolMint, isSigner: false, isWritable: false }, + { pubkey: payer, isSigner: true, isWritable: true }, + { pubkey: tokenMetadata, isSigner: false, isWritable: true }, + { pubkey: METADATA_PROGRAM_ID, isSigner: false, isWritable: false }, + { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, + { pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false }, + ]; + + const type = tokenMetadataLayout(17, name.length, symbol.length, uri.length); + const data = encodeData(type, { + nameLen: name.length, + name: Buffer.from(name), + symbolLen: symbol.length, + symbol: Buffer.from(symbol), + uriLen: uri.length, + uri: Buffer.from(uri), + }); + + return new TransactionInstruction({ + programId: STAKE_POOL_PROGRAM_ID, + keys, + data, + }); + } + + /** + * Creates an instruction to update metadata + * in the mpl token metadata program account for the pool token + */ + static updateTokenMetadata(params: UpdateTokenMetadataParams): TransactionInstruction { + const { stakePool, withdrawAuthority, tokenMetadata, manager, name, symbol, uri } = params; + + const keys = [ + { pubkey: stakePool, isSigner: false, isWritable: false }, + { pubkey: manager, isSigner: true, isWritable: false }, + { pubkey: withdrawAuthority, isSigner: false, isWritable: false }, + { pubkey: tokenMetadata, isSigner: false, isWritable: true }, + { pubkey: METADATA_PROGRAM_ID, isSigner: false, isWritable: false }, + ]; + + const type = tokenMetadataLayout(18, name.length, symbol.length, uri.length); + const data = encodeData(type, { + nameLen: name.length, + name: Buffer.from(name), + symbolLen: symbol.length, + symbol: Buffer.from(symbol), + uriLen: uri.length, + uri: Buffer.from(uri), + }); + + return new TransactionInstruction({ + programId: STAKE_POOL_PROGRAM_ID, + keys, + data, + }); + } + /** * Decode a deposit stake pool instruction and retrieve the instruction params. */ diff --git a/clients/js-legacy/src/utils/program-address.ts b/clients/js-legacy/src/utils/program-address.ts index 7d198235..49d106b1 100644 --- a/clients/js-legacy/src/utils/program-address.ts +++ b/clients/js-legacy/src/utils/program-address.ts @@ -1,7 +1,11 @@ import { PublicKey } from '@solana/web3.js'; import BN from 'bn.js'; import { Buffer } from 'buffer'; -import { EPHEMERAL_STAKE_SEED_PREFIX, TRANSIENT_STAKE_SEED_PREFIX } from '../constants'; +import { + METADATA_PROGRAM_ID, + EPHEMERAL_STAKE_SEED_PREFIX, + TRANSIENT_STAKE_SEED_PREFIX, +} from '../constants'; /** * Generates the withdraw authority program address for the stake pool @@ -67,3 +71,14 @@ export async function findEphemeralStakeProgramAddress( ); return publicKey; } + +/** + * Generates the metadata program address for the stake pool + */ +export function findMetadataAddress(stakePoolMintAddress: PublicKey) { + const [publicKey] = PublicKey.findProgramAddressSync( + [Buffer.from('metadata'), METADATA_PROGRAM_ID.toBuffer(), stakePoolMintAddress.toBuffer()], + METADATA_PROGRAM_ID, + ); + return publicKey; +} diff --git a/clients/js-legacy/test/instructions.test.ts b/clients/js-legacy/test/instructions.test.ts index 6552d0c3..9941d07a 100644 --- a/clients/js-legacy/test/instructions.test.ts +++ b/clients/js-legacy/test/instructions.test.ts @@ -26,6 +26,9 @@ import { withdrawStake, redelegate, getStakeAccount, + createPoolTokenMetadata, + updatePoolTokenMetadata, + tokenMetadataLayout, } from '../src'; import { decodeData } from '../src/utils'; @@ -351,4 +354,45 @@ describe('StakePoolProgram', () => { expect(decodedData.ephemeralStakeSeed).toBe(data.ephemeralStakeSeed); }); }); + describe('createPoolTokenMetadata', () => { + it('should create pool token metadata', async () => { + connection.getAccountInfo = jest.fn(async (pubKey: PublicKey) => { + if (pubKey == stakePoolAddress) { + return stakePoolAccount; + } + return null; + }); + const name = 'test'; + const symbol = 'TEST'; + const uri = 'https://example.com'; + + const payer = new PublicKey(0); + const res = await createPoolTokenMetadata( + connection, + stakePoolAddress, + payer, + name, + symbol, + uri, + ); + + const type = tokenMetadataLayout(17, name.length, symbol.length, uri.length); + const data = decodeData(type, res.instructions[0].data); + expect(Buffer.from(data.name).toString()).toBe(name); + expect(Buffer.from(data.symbol).toString()).toBe(symbol); + expect(Buffer.from(data.uri).toString()).toBe(uri); + }); + + it('should update pool token metadata', async () => { + const name = 'test'; + const symbol = 'TEST'; + const uri = 'https://example.com'; + const res = await updatePoolTokenMetadata(connection, stakePoolAddress, name, symbol, uri); + const type = tokenMetadataLayout(18, name.length, symbol.length, uri.length); + const data = decodeData(type, res.instructions[0].data); + expect(Buffer.from(data.name).toString()).toBe(name); + expect(Buffer.from(data.symbol).toString()).toBe(symbol); + expect(Buffer.from(data.uri).toString()).toBe(uri); + }); + }); }); From af629315632278ecae26b7704cb5568eede11bca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 25 Aug 2023 15:17:40 +0200 Subject: [PATCH 0476/1076] build(deps-dev): bump @types/node from 20.5.4 to 20.5.6 in /stake-pool/js (#5115) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.5.4 to 20.5.6. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index ef4ca57e..3d156640 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1768,9 +1768,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.5.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.4.tgz", - "integrity": "sha512-Y9vbIAoM31djQZrPYjpTLo0XlaSwOIsrlfE3LpulZeRblttsLQRFRlBAppW0LOxyT3ALj2M5vU1ucQQayQH3jA==" + "version": "20.5.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.6.tgz", + "integrity": "sha512-Gi5wRGPbbyOTX+4Y2iULQ27oUPrefaB0PxGQJnfyWN3kvEDGM3mIB5M/gQLmitZf7A9FmLeaqxD3L1CXpm3VKQ==" }, "node_modules/@types/node-fetch": { "version": "2.6.4", @@ -8327,9 +8327,9 @@ "dev": true }, "@types/node": { - "version": "20.5.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.4.tgz", - "integrity": "sha512-Y9vbIAoM31djQZrPYjpTLo0XlaSwOIsrlfE3LpulZeRblttsLQRFRlBAppW0LOxyT3ALj2M5vU1ucQQayQH3jA==" + "version": "20.5.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.6.tgz", + "integrity": "sha512-Gi5wRGPbbyOTX+4Y2iULQ27oUPrefaB0PxGQJnfyWN3kvEDGM3mIB5M/gQLmitZf7A9FmLeaqxD3L1CXpm3VKQ==" }, "@types/node-fetch": { "version": "2.6.4", From 09503923121a81ae36ed0eda136c05909d2f5401 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 25 Aug 2023 22:34:40 +0200 Subject: [PATCH 0477/1076] build(deps): bump serde from 1.0.186 to 1.0.187 (#5124) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.186 to 1.0.187. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.186...v1.0.187) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 503db519..09fa3719 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "0.7.0" [dependencies] borsh = "0.10" clap = "2.33.3" -serde = "1.0.186" +serde = "1.0.187" serde_derive = "1.0.130" serde_json = "1.0.105" solana-account-decoder = "=1.16.3" diff --git a/program/Cargo.toml b/program/Cargo.toml index 71202515..c1134470 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,7 +17,7 @@ borsh = "0.10" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.0" -serde = "1.0.186" +serde = "1.0.187" serde_derive = "1.0.103" solana-program = "1.16.3" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } From 246a1eb3658c38cfb0731eb56794c235d0971a83 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Aug 2023 21:07:22 +0200 Subject: [PATCH 0478/1076] build(deps): bump serde from 1.0.187 to 1.0.188 (#5130) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.187 to 1.0.188. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.187...v1.0.188) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 09fa3719..b269de34 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "0.7.0" [dependencies] borsh = "0.10" clap = "2.33.3" -serde = "1.0.187" +serde = "1.0.188" serde_derive = "1.0.130" serde_json = "1.0.105" solana-account-decoder = "=1.16.3" diff --git a/program/Cargo.toml b/program/Cargo.toml index c1134470..2deaf6a9 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,7 +17,7 @@ borsh = "0.10" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.0" -serde = "1.0.187" +serde = "1.0.188" serde_derive = "1.0.103" solana-program = "1.16.3" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } From 24391aa3ce125a7e44c9945151466a103e41bcaa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Aug 2023 21:18:02 +0200 Subject: [PATCH 0479/1076] build(deps-dev): bump @rollup/plugin-typescript from 11.1.2 to 11.1.3 in /stake-pool/js (#5140) build(deps-dev): bump @rollup/plugin-typescript in /stake-pool/js Bumps [@rollup/plugin-typescript](https://github.com/rollup/plugins/tree/HEAD/packages/typescript) from 11.1.2 to 11.1.3. - [Changelog](https://github.com/rollup/plugins/blob/master/packages/typescript/CHANGELOG.md) - [Commits](https://github.com/rollup/plugins/commits/typescript-v11.1.3/packages/typescript) --- updated-dependencies: - dependency-name: "@rollup/plugin-typescript" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 3d156640..00375f68 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1489,9 +1489,9 @@ } }, "node_modules/@rollup/plugin-typescript": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.2.tgz", - "integrity": "sha512-0ghSOCMcA7fl1JM+0gYRf+Q/HWyg+zg7/gDSc+fRLmlJWcW5K1I+CLRzaRhXf4Y3DRyPnnDo4M2ktw+a6JcDEg==", + "version": "11.1.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.3.tgz", + "integrity": "sha512-8o6cNgN44kQBcpsUJTbTXMTtb87oR1O0zgP3Dxm71hrNgparap3VujgofEilTYJo+ivf2ke6uy3/E5QEaiRlDA==", "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1", @@ -8104,9 +8104,9 @@ } }, "@rollup/plugin-typescript": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.2.tgz", - "integrity": "sha512-0ghSOCMcA7fl1JM+0gYRf+Q/HWyg+zg7/gDSc+fRLmlJWcW5K1I+CLRzaRhXf4Y3DRyPnnDo4M2ktw+a6JcDEg==", + "version": "11.1.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.3.tgz", + "integrity": "sha512-8o6cNgN44kQBcpsUJTbTXMTtb87oR1O0zgP3Dxm71hrNgparap3VujgofEilTYJo+ivf2ke6uy3/E5QEaiRlDA==", "dev": true, "requires": { "@rollup/pluginutils": "^5.0.1", From 22f8fe1623a63087388deba064c0e14b9655579d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Aug 2023 23:20:58 +0200 Subject: [PATCH 0480/1076] build(deps-dev): bump @types/node from 20.5.6 to 20.5.7 in /stake-pool/js (#5141) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.5.6 to 20.5.7. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 00375f68..7dd14de9 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1768,9 +1768,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.5.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.6.tgz", - "integrity": "sha512-Gi5wRGPbbyOTX+4Y2iULQ27oUPrefaB0PxGQJnfyWN3kvEDGM3mIB5M/gQLmitZf7A9FmLeaqxD3L1CXpm3VKQ==" + "version": "20.5.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.7.tgz", + "integrity": "sha512-dP7f3LdZIysZnmvP3ANJYTSwg+wLLl8p7RqniVlV7j+oXSXAbt9h0WIBFmJy5inWZoX9wZN6eXx+YXd9Rh3RBA==" }, "node_modules/@types/node-fetch": { "version": "2.6.4", @@ -8327,9 +8327,9 @@ "dev": true }, "@types/node": { - "version": "20.5.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.6.tgz", - "integrity": "sha512-Gi5wRGPbbyOTX+4Y2iULQ27oUPrefaB0PxGQJnfyWN3kvEDGM3mIB5M/gQLmitZf7A9FmLeaqxD3L1CXpm3VKQ==" + "version": "20.5.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.7.tgz", + "integrity": "sha512-dP7f3LdZIysZnmvP3ANJYTSwg+wLLl8p7RqniVlV7j+oXSXAbt9h0WIBFmJy5inWZoX9wZN6eXx+YXd9Rh3RBA==" }, "@types/node-fetch": { "version": "2.6.4", From a7ce13e105b5b953654275c07e90de1fa1617ae8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 29 Aug 2023 00:08:22 +0200 Subject: [PATCH 0481/1076] build(deps-dev): bump eslint from 8.47.0 to 8.48.0 in /stake-pool/js (#5139) Bumps [eslint](https://github.com/eslint/eslint) from 8.47.0 to 8.48.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.47.0...v8.48.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 7dd14de9..b1236ad2 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -717,9 +717,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.47.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.47.0.tgz", - "integrity": "sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og==", + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.48.0.tgz", + "integrity": "sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3209,15 +3209,15 @@ } }, "node_modules/eslint": { - "version": "8.47.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz", - "integrity": "sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q==", + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.48.0.tgz", + "integrity": "sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "^8.47.0", + "@eslint/js": "8.48.0", "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -7547,9 +7547,9 @@ } }, "@eslint/js": { - "version": "8.47.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.47.0.tgz", - "integrity": "sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og==", + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.48.0.tgz", + "integrity": "sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==", "dev": true }, "@humanwhocodes/config-array": { @@ -9355,15 +9355,15 @@ } }, "eslint": { - "version": "8.47.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz", - "integrity": "sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q==", + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.48.0.tgz", + "integrity": "sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "^8.47.0", + "@eslint/js": "8.48.0", "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", From 3db61d951a8b43cc00241fa307f9ba05c881fccf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 29 Aug 2023 16:31:41 +0200 Subject: [PATCH 0482/1076] build(deps-dev): bump @typescript-eslint/parser from 6.4.1 to 6.5.0 in /stake-pool/js (#5159) build(deps-dev): bump @typescript-eslint/parser in /stake-pool/js Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.4.1 to 6.5.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.5.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 145 +++++++++++++++++++++++++--- 1 file changed, 131 insertions(+), 14 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index b1236ad2..95fba1bc 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1865,15 +1865,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.4.1.tgz", - "integrity": "sha512-610G6KHymg9V7EqOaNBMtD1GgpAmGROsmfHJPXNLCU9bfIuLrkdOygltK784F6Crboyd5tBFayPB7Sf0McrQwg==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.5.0.tgz", + "integrity": "sha512-LMAVtR5GN8nY0G0BadkG0XIe4AcNMeyEy3DyhKGAh9k4pLSMBO7rF29JvDBpZGCmp5Pgz5RLHP6eCpSYZJQDuQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.4.1", - "@typescript-eslint/types": "6.4.1", - "@typescript-eslint/typescript-estree": "6.4.1", - "@typescript-eslint/visitor-keys": "6.4.1", + "@typescript-eslint/scope-manager": "6.5.0", + "@typescript-eslint/types": "6.5.0", + "@typescript-eslint/typescript-estree": "6.5.0", + "@typescript-eslint/visitor-keys": "6.5.0", "debug": "^4.3.4" }, "engines": { @@ -1892,6 +1892,80 @@ } } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.5.0.tgz", + "integrity": "sha512-A8hZ7OlxURricpycp5kdPTH3XnjG85UpJS6Fn4VzeoH4T388gQJ/PGP4ole5NfKt4WDVhmLaQ/dBLNDC4Xl/Kw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.5.0", + "@typescript-eslint/visitor-keys": "6.5.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.5.0.tgz", + "integrity": "sha512-eqLLOEF5/lU8jW3Bw+8auf4lZSbbljHR2saKnYqON12G/WsJrGeeDHWuQePoEf9ro22+JkbPfWQwKEC5WwLQ3w==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.5.0.tgz", + "integrity": "sha512-q0rGwSe9e5Kk/XzliB9h2LBc9tmXX25G0833r7kffbl5437FPWb2tbpIV9wAATebC/018pGa9fwPDuvGN+LxWQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.5.0", + "@typescript-eslint/visitor-keys": "6.5.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.5.0.tgz", + "integrity": "sha512-yCB/2wkbv3hPsh02ZS8dFQnij9VVQXJMN/gbQsaaY+zxALkZnxa/wagvLEFsAWMPv7d7lxQmNsIzGU1w/T/WyA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.5.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "6.4.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.4.1.tgz", @@ -8408,16 +8482,59 @@ } }, "@typescript-eslint/parser": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.4.1.tgz", - "integrity": "sha512-610G6KHymg9V7EqOaNBMtD1GgpAmGROsmfHJPXNLCU9bfIuLrkdOygltK784F6Crboyd5tBFayPB7Sf0McrQwg==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.5.0.tgz", + "integrity": "sha512-LMAVtR5GN8nY0G0BadkG0XIe4AcNMeyEy3DyhKGAh9k4pLSMBO7rF29JvDBpZGCmp5Pgz5RLHP6eCpSYZJQDuQ==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "6.4.1", - "@typescript-eslint/types": "6.4.1", - "@typescript-eslint/typescript-estree": "6.4.1", - "@typescript-eslint/visitor-keys": "6.4.1", + "@typescript-eslint/scope-manager": "6.5.0", + "@typescript-eslint/types": "6.5.0", + "@typescript-eslint/typescript-estree": "6.5.0", + "@typescript-eslint/visitor-keys": "6.5.0", "debug": "^4.3.4" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.5.0.tgz", + "integrity": "sha512-A8hZ7OlxURricpycp5kdPTH3XnjG85UpJS6Fn4VzeoH4T388gQJ/PGP4ole5NfKt4WDVhmLaQ/dBLNDC4Xl/Kw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.5.0", + "@typescript-eslint/visitor-keys": "6.5.0" + } + }, + "@typescript-eslint/types": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.5.0.tgz", + "integrity": "sha512-eqLLOEF5/lU8jW3Bw+8auf4lZSbbljHR2saKnYqON12G/WsJrGeeDHWuQePoEf9ro22+JkbPfWQwKEC5WwLQ3w==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.5.0.tgz", + "integrity": "sha512-q0rGwSe9e5Kk/XzliB9h2LBc9tmXX25G0833r7kffbl5437FPWb2tbpIV9wAATebC/018pGa9fwPDuvGN+LxWQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.5.0", + "@typescript-eslint/visitor-keys": "6.5.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.5.0.tgz", + "integrity": "sha512-yCB/2wkbv3hPsh02ZS8dFQnij9VVQXJMN/gbQsaaY+zxALkZnxa/wagvLEFsAWMPv7d7lxQmNsIzGU1w/T/WyA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.5.0", + "eslint-visitor-keys": "^3.4.1" + } + } } }, "@typescript-eslint/scope-manager": { From f063c0db00ebcfd6e1f9cca0f0cf5ecda78da91b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 29 Aug 2023 16:31:49 +0200 Subject: [PATCH 0483/1076] build(deps-dev): bump prettier from 3.0.2 to 3.0.3 in /stake-pool/js (#5161) Bumps [prettier](https://github.com/prettier/prettier) from 3.0.2 to 3.0.3. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/3.0.2...3.0.3) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 95fba1bc..0fa2d06a 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -5765,9 +5765,9 @@ } }, "node_modules/prettier": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.2.tgz", - "integrity": "sha512-o2YR9qtniXvwEZlOKbveKfDQVyqxbEIWn48Z8m3ZJjBjcCmUy3xZGIv+7AkaeuaTr6yPXJjwv07ZWlsWbEy1rQ==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz", + "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" @@ -11316,9 +11316,9 @@ "dev": true }, "prettier": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.2.tgz", - "integrity": "sha512-o2YR9qtniXvwEZlOKbveKfDQVyqxbEIWn48Z8m3ZJjBjcCmUy3xZGIv+7AkaeuaTr6yPXJjwv07ZWlsWbEy1rQ==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz", + "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==", "dev": true }, "prettier-linter-helpers": { From dc4e5e33ac04630a40da843400822f881e8e5bac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 29 Aug 2023 18:30:39 +0200 Subject: [PATCH 0484/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.4.1 to 6.5.0 in /stake-pool/js (#5160) build(deps-dev): bump @typescript-eslint/eslint-plugin in /stake-pool/js Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.4.1 to 6.5.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.5.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 261 ++++++++-------------------- 1 file changed, 72 insertions(+), 189 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 0fa2d06a..14ec8cfc 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1795,9 +1795,9 @@ "dev": true }, "node_modules/@types/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.1.tgz", + "integrity": "sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg==", "dev": true }, "node_modules/@types/stack-utils": { @@ -1830,16 +1830,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.4.1.tgz", - "integrity": "sha512-3F5PtBzUW0dYlq77Lcqo13fv+58KDwUib3BddilE8ajPJT+faGgxmI9Sw+I8ZS22BYwoir9ZhNXcLi+S+I2bkw==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.5.0.tgz", + "integrity": "sha512-2pktILyjvMaScU6iK3925uvGU87E+N9rh372uGZgiMYwafaw9SXq86U04XPq3UH6tzRvNgBsub6x2DacHc33lw==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.4.1", - "@typescript-eslint/type-utils": "6.4.1", - "@typescript-eslint/utils": "6.4.1", - "@typescript-eslint/visitor-keys": "6.4.1", + "@typescript-eslint/scope-manager": "6.5.0", + "@typescript-eslint/type-utils": "6.5.0", + "@typescript-eslint/utils": "6.5.0", + "@typescript-eslint/visitor-keys": "6.5.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -1892,7 +1892,7 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "node_modules/@typescript-eslint/scope-manager": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.5.0.tgz", "integrity": "sha512-A8hZ7OlxURricpycp5kdPTH3XnjG85UpJS6Fn4VzeoH4T388gQJ/PGP4ole5NfKt4WDVhmLaQ/dBLNDC4Xl/Kw==", @@ -1909,88 +1909,14 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.5.0.tgz", - "integrity": "sha512-eqLLOEF5/lU8jW3Bw+8auf4lZSbbljHR2saKnYqON12G/WsJrGeeDHWuQePoEf9ro22+JkbPfWQwKEC5WwLQ3w==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.5.0.tgz", - "integrity": "sha512-q0rGwSe9e5Kk/XzliB9h2LBc9tmXX25G0833r7kffbl5437FPWb2tbpIV9wAATebC/018pGa9fwPDuvGN+LxWQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.5.0.tgz", - "integrity": "sha512-yCB/2wkbv3hPsh02ZS8dFQnij9VVQXJMN/gbQsaaY+zxALkZnxa/wagvLEFsAWMPv7d7lxQmNsIzGU1w/T/WyA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.5.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.4.1.tgz", - "integrity": "sha512-p/OavqOQfm4/Hdrr7kvacOSFjwQ2rrDVJRPxt/o0TOWdFnjJptnjnZ+sYDR7fi4OimvIuKp+2LCkc+rt9fIW+A==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.4.1", - "@typescript-eslint/visitor-keys": "6.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.4.1.tgz", - "integrity": "sha512-7ON8M8NXh73SGZ5XvIqWHjgX2f+vvaOarNliGhjrJnv1vdjG0LVIz+ToYfPirOoBi56jxAKLfsLm40+RvxVVXA==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.5.0.tgz", + "integrity": "sha512-f7OcZOkRivtujIBQ4yrJNIuwyCQO1OjocVqntl9dgSIZAdKqicj3xFDqDOzHDlGCZX990LqhLQXWRnQvsapq8A==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.4.1", - "@typescript-eslint/utils": "6.4.1", + "@typescript-eslint/typescript-estree": "6.5.0", + "@typescript-eslint/utils": "6.5.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -2011,9 +1937,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.4.1.tgz", - "integrity": "sha512-zAAopbNuYu++ijY1GV2ylCsQsi3B8QvfPHVqhGdDcbx/NK5lkqMnCGU53amAjccSpk+LfeONxwzUhDzArSfZJg==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.5.0.tgz", + "integrity": "sha512-eqLLOEF5/lU8jW3Bw+8auf4lZSbbljHR2saKnYqON12G/WsJrGeeDHWuQePoEf9ro22+JkbPfWQwKEC5WwLQ3w==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -2024,13 +1950,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.4.1.tgz", - "integrity": "sha512-xF6Y7SatVE/OyV93h1xGgfOkHr2iXuo8ip0gbfzaKeGGuKiAnzS+HtVhSPx8Www243bwlW8IF7X0/B62SzFftg==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.5.0.tgz", + "integrity": "sha512-q0rGwSe9e5Kk/XzliB9h2LBc9tmXX25G0833r7kffbl5437FPWb2tbpIV9wAATebC/018pGa9fwPDuvGN+LxWQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.4.1", - "@typescript-eslint/visitor-keys": "6.4.1", + "@typescript-eslint/types": "6.5.0", + "@typescript-eslint/visitor-keys": "6.5.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2051,17 +1977,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.4.1.tgz", - "integrity": "sha512-F/6r2RieNeorU0zhqZNv89s9bDZSovv3bZQpUNOmmQK1L80/cV4KEu95YUJWi75u5PhboFoKUJBnZ4FQcoqhDw==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.5.0.tgz", + "integrity": "sha512-9nqtjkNykFzeVtt9Pj6lyR9WEdd8npPhhIPM992FWVkZuS6tmxHfGVnlUcjpUP2hv8r4w35nT33mlxd+Be1ACQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.4.1", - "@typescript-eslint/types": "6.4.1", - "@typescript-eslint/typescript-estree": "6.4.1", + "@typescript-eslint/scope-manager": "6.5.0", + "@typescript-eslint/types": "6.5.0", + "@typescript-eslint/typescript-estree": "6.5.0", "semver": "^7.5.4" }, "engines": { @@ -2076,12 +2002,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.4.1.tgz", - "integrity": "sha512-y/TyRJsbZPkJIZQXrHfdnxVnxyKegnpEvnRGNam7s3TRR2ykGefEWOhaef00/UUN3IZxizS7BTO3svd3lCOJRQ==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.5.0.tgz", + "integrity": "sha512-yCB/2wkbv3hPsh02ZS8dFQnij9VVQXJMN/gbQsaaY+zxALkZnxa/wagvLEFsAWMPv7d7lxQmNsIzGU1w/T/WyA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.4.1", + "@typescript-eslint/types": "6.5.0", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -8428,9 +8354,9 @@ "dev": true }, "@types/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.1.tgz", + "integrity": "sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg==", "dev": true }, "@types/stack-utils": { @@ -8463,16 +8389,16 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.4.1.tgz", - "integrity": "sha512-3F5PtBzUW0dYlq77Lcqo13fv+58KDwUib3BddilE8ajPJT+faGgxmI9Sw+I8ZS22BYwoir9ZhNXcLi+S+I2bkw==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.5.0.tgz", + "integrity": "sha512-2pktILyjvMaScU6iK3925uvGU87E+N9rh372uGZgiMYwafaw9SXq86U04XPq3UH6tzRvNgBsub6x2DacHc33lw==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.4.1", - "@typescript-eslint/type-utils": "6.4.1", - "@typescript-eslint/utils": "6.4.1", - "@typescript-eslint/visitor-keys": "6.4.1", + "@typescript-eslint/scope-manager": "6.5.0", + "@typescript-eslint/type-utils": "6.5.0", + "@typescript-eslint/utils": "6.5.0", + "@typescript-eslint/visitor-keys": "6.5.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -8492,87 +8418,44 @@ "@typescript-eslint/typescript-estree": "6.5.0", "@typescript-eslint/visitor-keys": "6.5.0", "debug": "^4.3.4" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.5.0.tgz", - "integrity": "sha512-A8hZ7OlxURricpycp5kdPTH3XnjG85UpJS6Fn4VzeoH4T388gQJ/PGP4ole5NfKt4WDVhmLaQ/dBLNDC4Xl/Kw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0" - } - }, - "@typescript-eslint/types": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.5.0.tgz", - "integrity": "sha512-eqLLOEF5/lU8jW3Bw+8auf4lZSbbljHR2saKnYqON12G/WsJrGeeDHWuQePoEf9ro22+JkbPfWQwKEC5WwLQ3w==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.5.0.tgz", - "integrity": "sha512-q0rGwSe9e5Kk/XzliB9h2LBc9tmXX25G0833r7kffbl5437FPWb2tbpIV9wAATebC/018pGa9fwPDuvGN+LxWQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.5.0.tgz", - "integrity": "sha512-yCB/2wkbv3hPsh02ZS8dFQnij9VVQXJMN/gbQsaaY+zxALkZnxa/wagvLEFsAWMPv7d7lxQmNsIzGU1w/T/WyA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.5.0", - "eslint-visitor-keys": "^3.4.1" - } - } } }, "@typescript-eslint/scope-manager": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.4.1.tgz", - "integrity": "sha512-p/OavqOQfm4/Hdrr7kvacOSFjwQ2rrDVJRPxt/o0TOWdFnjJptnjnZ+sYDR7fi4OimvIuKp+2LCkc+rt9fIW+A==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.5.0.tgz", + "integrity": "sha512-A8hZ7OlxURricpycp5kdPTH3XnjG85UpJS6Fn4VzeoH4T388gQJ/PGP4ole5NfKt4WDVhmLaQ/dBLNDC4Xl/Kw==", "dev": true, "requires": { - "@typescript-eslint/types": "6.4.1", - "@typescript-eslint/visitor-keys": "6.4.1" + "@typescript-eslint/types": "6.5.0", + "@typescript-eslint/visitor-keys": "6.5.0" } }, "@typescript-eslint/type-utils": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.4.1.tgz", - "integrity": "sha512-7ON8M8NXh73SGZ5XvIqWHjgX2f+vvaOarNliGhjrJnv1vdjG0LVIz+ToYfPirOoBi56jxAKLfsLm40+RvxVVXA==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.5.0.tgz", + "integrity": "sha512-f7OcZOkRivtujIBQ4yrJNIuwyCQO1OjocVqntl9dgSIZAdKqicj3xFDqDOzHDlGCZX990LqhLQXWRnQvsapq8A==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "6.4.1", - "@typescript-eslint/utils": "6.4.1", + "@typescript-eslint/typescript-estree": "6.5.0", + "@typescript-eslint/utils": "6.5.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" } }, "@typescript-eslint/types": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.4.1.tgz", - "integrity": "sha512-zAAopbNuYu++ijY1GV2ylCsQsi3B8QvfPHVqhGdDcbx/NK5lkqMnCGU53amAjccSpk+LfeONxwzUhDzArSfZJg==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.5.0.tgz", + "integrity": "sha512-eqLLOEF5/lU8jW3Bw+8auf4lZSbbljHR2saKnYqON12G/WsJrGeeDHWuQePoEf9ro22+JkbPfWQwKEC5WwLQ3w==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.4.1.tgz", - "integrity": "sha512-xF6Y7SatVE/OyV93h1xGgfOkHr2iXuo8ip0gbfzaKeGGuKiAnzS+HtVhSPx8Www243bwlW8IF7X0/B62SzFftg==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.5.0.tgz", + "integrity": "sha512-q0rGwSe9e5Kk/XzliB9h2LBc9tmXX25G0833r7kffbl5437FPWb2tbpIV9wAATebC/018pGa9fwPDuvGN+LxWQ==", "dev": true, "requires": { - "@typescript-eslint/types": "6.4.1", - "@typescript-eslint/visitor-keys": "6.4.1", + "@typescript-eslint/types": "6.5.0", + "@typescript-eslint/visitor-keys": "6.5.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -8581,27 +8464,27 @@ } }, "@typescript-eslint/utils": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.4.1.tgz", - "integrity": "sha512-F/6r2RieNeorU0zhqZNv89s9bDZSovv3bZQpUNOmmQK1L80/cV4KEu95YUJWi75u5PhboFoKUJBnZ4FQcoqhDw==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.5.0.tgz", + "integrity": "sha512-9nqtjkNykFzeVtt9Pj6lyR9WEdd8npPhhIPM992FWVkZuS6tmxHfGVnlUcjpUP2hv8r4w35nT33mlxd+Be1ACQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.4.1", - "@typescript-eslint/types": "6.4.1", - "@typescript-eslint/typescript-estree": "6.4.1", + "@typescript-eslint/scope-manager": "6.5.0", + "@typescript-eslint/types": "6.5.0", + "@typescript-eslint/typescript-estree": "6.5.0", "semver": "^7.5.4" } }, "@typescript-eslint/visitor-keys": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.4.1.tgz", - "integrity": "sha512-y/TyRJsbZPkJIZQXrHfdnxVnxyKegnpEvnRGNam7s3TRR2ykGefEWOhaef00/UUN3IZxizS7BTO3svd3lCOJRQ==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.5.0.tgz", + "integrity": "sha512-yCB/2wkbv3hPsh02ZS8dFQnij9VVQXJMN/gbQsaaY+zxALkZnxa/wagvLEFsAWMPv7d7lxQmNsIzGU1w/T/WyA==", "dev": true, "requires": { - "@typescript-eslint/types": "6.4.1", + "@typescript-eslint/types": "6.5.0", "eslint-visitor-keys": "^3.4.1" } }, From f693dbb1b40e5c325f4f3b4dc0585a8921353b48 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 31 Aug 2023 09:53:41 +0200 Subject: [PATCH 0485/1076] stake-pool: Use unaligned types for safe pointer cast (#5179) * stake-pool: Use unaligned types for safe pointer cast * Update CLI for modified types --- clients/cli/src/main.rs | 42 +++-- clients/cli/src/output.rs | 12 +- program/Cargo.toml | 1 + program/src/big_vec.rs | 23 +-- program/src/instruction.rs | 4 +- program/src/processor.rs | 167 ++++++++++-------- program/src/state.rs | 59 ++++--- program/tests/decrease.rs | 2 +- program/tests/deposit.rs | 10 +- program/tests/force_destake.rs | 12 +- program/tests/helpers/mod.rs | 12 +- program/tests/huge_pool.rs | 22 +-- program/tests/increase.rs | 2 +- program/tests/redelegate.rs | 28 +-- .../tests/update_validator_list_balance.rs | 4 +- program/tests/vsa_add.rs | 13 +- program/tests/vsa_remove.rs | 13 +- program/tests/withdraw.rs | 4 +- 18 files changed, 226 insertions(+), 204 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index bc51c0e1..2ca68eba 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -499,7 +499,7 @@ fn command_vsa_remove( .find(vote_account) .ok_or("Vote account not found in validator list")?; - let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix); + let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix.into()); let (stake_account_address, _) = find_stake_program_address( &spl_stake_pool::id(), vote_account, @@ -520,7 +520,7 @@ fn command_vsa_remove( stake_pool_address, vote_account, validator_seed, - validator_stake_info.transient_seed_suffix, + validator_stake_info.transient_seed_suffix.into(), ), ]; unique_signers!(signers); @@ -545,7 +545,7 @@ fn command_increase_validator_stake( let validator_stake_info = validator_list .find(vote_account) .ok_or("Vote account not found in validator list")?; - let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix); + let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix.into()); let mut signers = vec![config.fee_payer.as_ref(), config.staker.as_ref()]; unique_signers!(signers); @@ -559,7 +559,7 @@ fn command_increase_validator_stake( vote_account, lamports, validator_seed, - validator_stake_info.transient_seed_suffix, + validator_stake_info.transient_seed_suffix.into(), ), ], &signers, @@ -584,7 +584,7 @@ fn command_decrease_validator_stake( let validator_stake_info = validator_list .find(vote_account) .ok_or("Vote account not found in validator list")?; - let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix); + let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix.into()); let mut signers = vec![config.fee_payer.as_ref(), config.staker.as_ref()]; unique_signers!(signers); @@ -598,7 +598,7 @@ fn command_decrease_validator_stake( vote_account, lamports, validator_seed, - validator_stake_info.transient_seed_suffix, + validator_stake_info.transient_seed_suffix.into(), ), ], &signers, @@ -692,7 +692,7 @@ fn command_deposit_stake( let validator_stake_info = validator_list .find(&vote_account) .ok_or("Vote account not found in the stake pool")?; - let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix); + let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix.into()); // Calculate validator stake account address linked to the pool let (validator_stake_account, _) = find_stake_program_address( @@ -872,7 +872,7 @@ fn command_deposit_all_stake( let validator_stake_info = validator_list .find(&vote_account) .ok_or("Vote account not found in the stake pool")?; - let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix); + let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix.into()); // Calculate validator stake account address linked to the pool let (validator_stake_account, _) = find_stake_program_address( @@ -1084,7 +1084,7 @@ fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { .validators .iter() .map(|validator| { - let validator_seed = NonZeroU32::new(validator.validator_seed_suffix); + let validator_seed = NonZeroU32::new(validator.validator_seed_suffix.into()); let (stake_account_address, _) = find_stake_program_address( &spl_stake_pool::id(), &validator.vote_account_address, @@ -1095,18 +1095,18 @@ fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { &spl_stake_pool::id(), &validator.vote_account_address, stake_pool_address, - validator.transient_seed_suffix, + validator.transient_seed_suffix.into(), ); - let update_required = validator.last_update_epoch != epoch_info.epoch; + let update_required = u64::from(validator.last_update_epoch) != epoch_info.epoch; CliStakePoolStakeAccountInfo { vote_account_address: validator.vote_account_address.to_string(), stake_account_address: stake_account_address.to_string(), - validator_active_stake_lamports: validator.active_stake_lamports, - validator_last_update_epoch: validator.last_update_epoch, + validator_active_stake_lamports: validator.active_stake_lamports.into(), + validator_last_update_epoch: validator.last_update_epoch.into(), validator_lamports: validator.stake_lamports().unwrap(), validator_transient_stake_account_address: transient_stake_account_address .to_string(), - validator_transient_stake_lamports: validator.transient_stake_lamports, + validator_transient_stake_lamports: validator.transient_stake_lamports.into(), update_required, } }) @@ -1255,7 +1255,7 @@ fn prepare_withdraw_accounts( &validator_list, stake_pool, |validator| { - let validator_seed = NonZeroU32::new(validator.validator_seed_suffix); + let validator_seed = NonZeroU32::new(validator.validator_seed_suffix.into()); let (stake_account_address, _) = find_stake_program_address( &spl_stake_pool::id(), &validator.vote_account_address, @@ -1265,7 +1265,7 @@ fn prepare_withdraw_accounts( ( stake_account_address, - validator.active_stake_lamports, + validator.active_stake_lamports.into(), Some(validator.vote_account_address), ) }, @@ -1279,14 +1279,12 @@ fn prepare_withdraw_accounts( &spl_stake_pool::id(), &validator.vote_account_address, stake_pool_address, - validator.transient_seed_suffix, + validator.transient_seed_suffix.into(), ); ( transient_stake_account_address, - validator - .transient_stake_lamports - .saturating_sub(min_balance), + u64::from(validator.transient_stake_lamports).saturating_sub(min_balance), Some(validator.vote_account_address), ) }, @@ -1438,7 +1436,7 @@ fn command_withdraw_stake( let validator_stake_info = validator_list .find(&vote_account) .ok_or(format!("Provided stake account is delegated to a vote account {} which does not exist in the stake pool", vote_account))?; - let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix); + let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix.into()); let (stake_account_address, _) = find_stake_program_address( &spl_stake_pool::id(), &vote_account, @@ -1474,7 +1472,7 @@ fn command_withdraw_stake( "Provided vote account address {} does not exist in the stake pool", vote_account_address ))?; - let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix); + let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix.into()); let (stake_account_address, _) = find_stake_program_address( &spl_stake_pool::id(), vote_account_address, diff --git a/clients/cli/src/output.rs b/clients/cli/src/output.rs index 097e9334..3b2beaac 100644 --- a/clients/cli/src/output.rs +++ b/clients/cli/src/output.rs @@ -372,12 +372,12 @@ pub(crate) struct CliStakePoolValidator { impl From for CliStakePoolValidator { fn from(v: ValidatorStakeInfo) -> Self { Self { - active_stake_lamports: v.active_stake_lamports, - transient_stake_lamports: v.transient_stake_lamports, - last_update_epoch: v.last_update_epoch, - transient_seed_suffix: v.transient_seed_suffix, - unused: v.unused, - validator_seed_suffix: v.validator_seed_suffix, + active_stake_lamports: v.active_stake_lamports.into(), + transient_stake_lamports: v.transient_stake_lamports.into(), + last_update_epoch: v.last_update_epoch.into(), + transient_seed_suffix: v.transient_seed_suffix.into(), + unused: v.unused.into(), + validator_seed_suffix: v.validator_seed_suffix.into(), status: CliStakePoolValidatorStakeStatus::from(v.status), vote_account_address: v.vote_account_address.to_string(), } diff --git a/program/Cargo.toml b/program/Cargo.toml index 2deaf6a9..4ba2812d 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -21,6 +21,7 @@ serde = "1.0.188" serde_derive = "1.0.103" solana-program = "1.16.3" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } +spl-pod = { version = "0.1", path = "../../libraries/pod", features = ["borsh"] } spl-token-2022 = { version = "0.7", path = "../../token/program-2022", features = [ "no-entrypoint" ] } thiserror = "1.0" bincode = "1.3.1" diff --git a/program/src/big_vec.rs b/program/src/big_vec.rs index 5c74018f..490fdaf2 100644 --- a/program/src/big_vec.rs +++ b/program/src/big_vec.rs @@ -246,7 +246,7 @@ mod tests { #[derive(Debug, PartialEq)] struct TestStruct { - value: u64, + value: [u8; 8], } impl Sealed for TestStruct {} @@ -259,18 +259,19 @@ mod tests { } fn unpack_from_slice(src: &[u8]) -> Result { Ok(TestStruct { - value: u64::try_from_slice(src).unwrap(), + value: src.try_into().unwrap(), }) } } impl TestStruct { - fn new(value: u64) -> Self { + fn new(value: u8) -> Self { + let value = [value, 0, 0, 0, 0, 0, 0, 0]; Self { value } } } - fn from_slice<'data>(data: &'data mut [u8], vec: &[u64]) -> BigVec<'data> { + fn from_slice<'data>(data: &'data mut [u8], vec: &[u8]) -> BigVec<'data> { let mut big_vec = BigVec { data }; for element in vec { big_vec.push(TestStruct::new(*element)).unwrap(); @@ -278,10 +279,10 @@ mod tests { big_vec } - fn check_big_vec_eq(big_vec: &BigVec, slice: &[u64]) { + fn check_big_vec_eq(big_vec: &BigVec, slice: &[u8]) { assert!(big_vec .iter::() - .map(|x| &x.value) + .map(|x| &x.value[0]) .zip(slice.iter()) .all(|(a, b)| a == b)); } @@ -314,11 +315,11 @@ mod tests { check_big_vec_eq(&v, &[2, 4]); } - fn find_predicate(a: &[u8], b: u64) -> bool { + fn find_predicate(a: &[u8], b: u8) -> bool { if a.len() != 8 { false } else { - u64::try_from_slice(&a[0..8]).unwrap() == b + a[0] == b } } @@ -344,7 +345,7 @@ mod tests { let mut test_struct = v .find_mut::(|x| find_predicate(x, 1)) .unwrap(); - test_struct.value = 0; + test_struct.value = [0; 8]; check_big_vec_eq(&v, &[0, 2, 3, 4]); assert_eq!(v.find_mut::(|x| find_predicate(x, 5)), None); } @@ -354,8 +355,8 @@ mod tests { let mut data = [0u8; 4 + 8 * 4]; let mut v = from_slice(&mut data, &[1, 2, 3, 4]); let mut slice = v.deserialize_mut_slice::(1, 2).unwrap(); - slice[0].value = 10; - slice[1].value = 11; + slice[0].value[0] = 10; + slice[1].value[0] = 11; check_big_vec_eq(&v, &[1, 10, 11, 4]); assert_eq!( v.deserialize_mut_slice::(1, 4).unwrap_err(), diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 286a02a5..fcda9082 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -1247,13 +1247,13 @@ pub fn update_validator_list_balance( program_id, vote_account_address, stake_pool, - NonZeroU32::new(validator_stake_info.validator_seed_suffix), + NonZeroU32::new(validator_stake_info.validator_seed_suffix.into()), ); let (transient_stake_account, _) = find_transient_stake_program_address( program_id, vote_account_address, stake_pool, - validator_stake_info.transient_seed_suffix, + validator_stake_info.transient_seed_suffix.into(), ); vec![ AccountMeta::new(validator_stake_account, false), diff --git a/program/src/processor.rs b/program/src/processor.rs index 04249143..d267d1e5 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1078,12 +1078,12 @@ impl Processor { validator_list.push(ValidatorStakeInfo { status: StakeStatus::Active, vote_account_address: *validator_vote_info.key, - active_stake_lamports: required_lamports, - transient_stake_lamports: 0, - last_update_epoch: clock.epoch, - transient_seed_suffix: 0, - unused: 0, - validator_seed_suffix: raw_validator_seed, + active_stake_lamports: required_lamports.into(), + transient_stake_lamports: 0.into(), + last_update_epoch: clock.epoch.into(), + transient_seed_suffix: 0.into(), + unused: 0.into(), + validator_seed_suffix: raw_validator_seed.into(), })?; Ok(()) @@ -1158,7 +1158,7 @@ impl Processor { stake_pool_info.key, stake_account_info.key, &vote_account_address, - NonZeroU32::new(validator_stake_info.validator_seed_suffix), + NonZeroU32::new(validator_stake_info.validator_seed_suffix.into()), )?; if validator_stake_info.status != StakeStatus::Active { @@ -1166,13 +1166,13 @@ impl Processor { return Err(StakePoolError::ValidatorNotFound.into()); } - let new_status = if validator_stake_info.transient_stake_lamports > 0 { + let new_status = if u64::from(validator_stake_info.transient_stake_lamports) > 0 { check_transient_stake_address( program_id, stake_pool_info.key, transient_stake_account_info.key, &vote_account_address, - validator_stake_info.transient_seed_suffix, + validator_stake_info.transient_seed_suffix.into(), )?; match get_stake_state(transient_stake_account_info) { @@ -1308,17 +1308,17 @@ impl Processor { stake_pool_info.key, validator_stake_account_info.key, &vote_account_address, - NonZeroU32::new(validator_stake_info.validator_seed_suffix), + NonZeroU32::new(validator_stake_info.validator_seed_suffix.into()), )?; - if validator_stake_info.transient_stake_lamports > 0 { + if u64::from(validator_stake_info.transient_stake_lamports) > 0 { if maybe_ephemeral_stake_seed.is_none() { msg!("Attempting to decrease stake on a validator with pending transient stake, use DecreaseAdditionalValidatorStake with the existing seed"); return Err(StakePoolError::TransientAccountInUse.into()); } - if transient_stake_seed != validator_stake_info.transient_seed_suffix { + if transient_stake_seed != u64::from(validator_stake_info.transient_seed_suffix) { msg!( "Transient stake already exists with seed {}, you must use that one", - validator_stake_info.transient_seed_suffix + u64::from(validator_stake_info.transient_seed_suffix) ); return Err(ProgramError::InvalidSeeds); } @@ -1414,7 +1414,7 @@ impl Processor { transient_stake_seed, )?; - if validator_stake_info.transient_stake_lamports > 0 { + if u64::from(validator_stake_info.transient_stake_lamports) > 0 { let stake_history_info = maybe_stake_history_info.unwrap(); // transient stake exists, try to merge from the source account, // which is always an ephemeral account @@ -1468,15 +1468,17 @@ impl Processor { } } - validator_stake_info.active_stake_lamports = validator_stake_info - .active_stake_lamports - .checked_sub(lamports) - .ok_or(StakePoolError::CalculationFailure)?; - validator_stake_info.transient_stake_lamports = validator_stake_info - .transient_stake_lamports - .checked_add(lamports) - .ok_or(StakePoolError::CalculationFailure)?; - validator_stake_info.transient_seed_suffix = transient_stake_seed; + validator_stake_info.active_stake_lamports = + u64::from(validator_stake_info.active_stake_lamports) + .checked_sub(lamports) + .ok_or(StakePoolError::CalculationFailure)? + .into(); + validator_stake_info.transient_stake_lamports = + u64::from(validator_stake_info.transient_stake_lamports) + .checked_add(lamports) + .ok_or(StakePoolError::CalculationFailure)? + .into(); + validator_stake_info.transient_seed_suffix = transient_stake_seed.into(); Ok(()) } @@ -1562,15 +1564,15 @@ impl Processor { return Err(StakePoolError::ValidatorNotFound.into()); } let mut validator_stake_info = maybe_validator_stake_info.unwrap(); - if validator_stake_info.transient_stake_lamports > 0 { + if u64::from(validator_stake_info.transient_stake_lamports) > 0 { if maybe_ephemeral_stake_seed.is_none() { msg!("Attempting to increase stake on a validator with pending transient stake, use IncreaseAdditionalValidatorStake with the existing seed"); return Err(StakePoolError::TransientAccountInUse.into()); } - if transient_stake_seed != validator_stake_info.transient_seed_suffix { + if transient_stake_seed != u64::from(validator_stake_info.transient_seed_suffix) { msg!( "Transient stake already exists with seed {}, you must use that one", - validator_stake_info.transient_seed_suffix + u64::from(validator_stake_info.transient_seed_suffix) ); return Err(ProgramError::InvalidSeeds); } @@ -1587,7 +1589,7 @@ impl Processor { stake_pool_info.key, withdraw_authority_info.key, vote_account_address, - validator_stake_info.validator_seed_suffix, + validator_stake_info.validator_seed_suffix.into(), &stake_pool.lockup, )?; @@ -1692,7 +1694,7 @@ impl Processor { transient_stake_seed, )?; - if validator_stake_info.transient_stake_lamports > 0 { + if u64::from(validator_stake_info.transient_stake_lamports) > 0 { // transient stake exists, try to merge from the source account, // which is always an ephemeral account Self::stake_merge( @@ -1757,11 +1759,12 @@ impl Processor { } } - validator_stake_info.transient_stake_lamports = validator_stake_info - .transient_stake_lamports - .checked_add(total_lamports) - .ok_or(StakePoolError::CalculationFailure)?; - validator_stake_info.transient_seed_suffix = transient_stake_seed; + validator_stake_info.transient_stake_lamports = + u64::from(validator_stake_info.transient_stake_lamports) + .checked_add(total_lamports) + .ok_or(StakePoolError::CalculationFailure)? + .into(); + validator_stake_info.transient_seed_suffix = transient_stake_seed.into(); Ok(()) } @@ -1891,21 +1894,22 @@ impl Processor { stake_pool_info.key, source_validator_stake_account_info.key, &vote_account_address, - NonZeroU32::new(validator_stake_info.validator_seed_suffix), + NonZeroU32::new(validator_stake_info.validator_seed_suffix.into()), )?; - if validator_stake_info.transient_stake_lamports > 0 { + if u64::from(validator_stake_info.transient_stake_lamports) > 0 { return Err(StakePoolError::TransientAccountInUse.into()); } if validator_stake_info.status != StakeStatus::Active { msg!("Validator is marked for removal and no longer allows redelegation"); return Err(StakePoolError::ValidatorNotFound.into()); } - validator_stake_info.active_stake_lamports = validator_stake_info - .active_stake_lamports - .checked_sub(lamports) - .ok_or(StakePoolError::CalculationFailure)?; - validator_stake_info.transient_stake_lamports = stake_rent; - validator_stake_info.transient_seed_suffix = source_transient_stake_seed; + validator_stake_info.active_stake_lamports = + u64::from(validator_stake_info.active_stake_lamports) + .checked_sub(lamports) + .ok_or(StakePoolError::CalculationFailure)? + .into(); + validator_stake_info.transient_stake_lamports = stake_rent.into(); + validator_stake_info.transient_seed_suffix = source_transient_stake_seed.into(); } // split from source, into source transient @@ -1995,7 +1999,7 @@ impl Processor { stake_pool_info.key, withdraw_authority_info.key, vote_account_address, - validator_stake_info.validator_seed_suffix, + validator_stake_info.validator_seed_suffix.into(), &stake_pool.lockup, )?; if validator_stake_info.status != StakeStatus::Active { @@ -2004,19 +2008,23 @@ impl Processor { ); return Err(StakePoolError::ValidatorNotFound.into()); } - let transient_account_exists = validator_stake_info.transient_stake_lamports > 0; - validator_stake_info.transient_stake_lamports = validator_stake_info - .transient_stake_lamports - .checked_add(destination_transient_lamports) - .ok_or(StakePoolError::CalculationFailure)?; + let transient_account_exists = + u64::from(validator_stake_info.transient_stake_lamports) > 0; + validator_stake_info.transient_stake_lamports = + u64::from(validator_stake_info.transient_stake_lamports) + .checked_add(destination_transient_lamports) + .ok_or(StakePoolError::CalculationFailure)? + .into(); if transient_account_exists { // if transient stake exists, make sure it's the right one and that it's // usable by the pool - if validator_stake_info.transient_seed_suffix != destination_transient_stake_seed { + if u64::from(validator_stake_info.transient_seed_suffix) + != destination_transient_stake_seed + { msg!("Provided seed {} does not match current seed {} for transient stake account", destination_transient_stake_seed, - validator_stake_info.transient_seed_suffix + u64::from(validator_stake_info.transient_seed_suffix) ); return Err(StakePoolError::InvalidStakeAccountAddress.into()); } @@ -2074,7 +2082,8 @@ impl Processor { destination_transient_lamports, destination_transient_stake_account_info.clone(), )?; - validator_stake_info.transient_seed_suffix = destination_transient_stake_seed; + validator_stake_info.transient_seed_suffix = + destination_transient_stake_seed.into(); } } @@ -2215,7 +2224,7 @@ impl Processor { stake_pool_info.key, validator_stake_info.key, &validator_stake_record.vote_account_address, - NonZeroU32::new(validator_stake_record.validator_seed_suffix), + NonZeroU32::new(validator_stake_record.validator_seed_suffix.into()), ) .is_err() { @@ -2226,7 +2235,7 @@ impl Processor { stake_pool_info.key, transient_stake_info.key, &validator_stake_record.vote_account_address, - validator_stake_record.transient_seed_suffix, + validator_stake_record.transient_seed_suffix.into(), ) .is_err() { @@ -2427,9 +2436,9 @@ impl Processor { } } - validator_stake_record.last_update_epoch = clock.epoch; - validator_stake_record.active_stake_lamports = active_stake_lamports; - validator_stake_record.transient_stake_lamports = transient_stake_lamports; + validator_stake_record.last_update_epoch = clock.epoch.into(); + validator_stake_record.active_stake_lamports = active_stake_lamports.into(); + validator_stake_record.transient_stake_lamports = transient_stake_lamports.into(); } Ok(()) @@ -2494,7 +2503,7 @@ impl Processor { return Err(StakePoolError::WrongStakeState.into()); }; for validator_stake_record in validator_list.iter::() { - if validator_stake_record.last_update_epoch < clock.epoch { + if u64::from(validator_stake_record.last_update_epoch) < clock.epoch { return Err(StakePoolError::StakeListOutOfDate.into()); } total_lamports = total_lamports @@ -2677,7 +2686,7 @@ impl Processor { stake_pool_info.key, validator_stake_account_info.key, &vote_account_address, - NonZeroU32::new(validator_stake_info.validator_seed_suffix), + NonZeroU32::new(validator_stake_info.validator_seed_suffix.into()), )?; if validator_stake_info.status != StakeStatus::Active { @@ -2847,7 +2856,7 @@ impl Processor { .ok_or(StakePoolError::CalculationFailure)?; borsh::to_writer(&mut stake_pool_info.data.borrow_mut()[..], &stake_pool)?; - validator_stake_info.active_stake_lamports = validator_stake_account_info.lamports(); + validator_stake_info.active_stake_lamports = validator_stake_account_info.lamports().into(); Ok(()) } @@ -3143,11 +3152,10 @@ impl Processor { ValidatorStakeInfo::memcmp_pubkey(x, &preferred_withdraw_validator) }) .ok_or(StakePoolError::ValidatorNotFound)?; - let available_lamports = preferred_validator_info - .active_stake_lamports + let available_lamports = u64::from(preferred_validator_info.active_stake_lamports) .saturating_sub(minimum_lamports_with_tolerance); if preferred_withdraw_validator != vote_account_address && available_lamports > 0 { - msg!("Validator vote address {} is preferred for withdrawals, it currently has {} lamports available. Please withdraw those before using other validator stake accounts.", preferred_withdraw_validator, preferred_validator_info.active_stake_lamports); + msg!("Validator vote address {} is preferred for withdrawals, it currently has {} lamports available. Please withdraw those before using other validator stake accounts.", preferred_withdraw_validator, u64::from(preferred_validator_info.active_stake_lamports)); return Err(StakePoolError::IncorrectWithdrawVoteAddress.into()); } } @@ -3166,7 +3174,7 @@ impl Processor { stake_pool_info.key, stake_split_from.key, &vote_account_address, - NonZeroU32::new(validator_stake_info.validator_seed_suffix), + NonZeroU32::new(validator_stake_info.validator_seed_suffix.into()), )?; StakeWithdrawSource::Active } else if has_transient_stake { @@ -3176,7 +3184,7 @@ impl Processor { stake_pool_info.key, stake_split_from.key, &vote_account_address, - validator_stake_info.transient_seed_suffix, + validator_stake_info.transient_seed_suffix.into(), )?; StakeWithdrawSource::Transient } else { @@ -3186,7 +3194,7 @@ impl Processor { stake_pool_info.key, stake_split_from.key, &vote_account_address, - NonZeroU32::new(validator_stake_info.validator_seed_suffix), + NonZeroU32::new(validator_stake_info.validator_seed_suffix.into()), )?; StakeWithdrawSource::ValidatorRemoval }; @@ -3280,25 +3288,28 @@ impl Processor { if let Some((validator_list_item, withdraw_source)) = validator_list_item_info { match withdraw_source { StakeWithdrawSource::Active => { - validator_list_item.active_stake_lamports = validator_list_item - .active_stake_lamports - .checked_sub(withdraw_lamports) - .ok_or(StakePoolError::CalculationFailure)? + validator_list_item.active_stake_lamports = + u64::from(validator_list_item.active_stake_lamports) + .checked_sub(withdraw_lamports) + .ok_or(StakePoolError::CalculationFailure)? + .into() } StakeWithdrawSource::Transient => { - validator_list_item.transient_stake_lamports = validator_list_item - .transient_stake_lamports - .checked_sub(withdraw_lamports) - .ok_or(StakePoolError::CalculationFailure)? + validator_list_item.transient_stake_lamports = + u64::from(validator_list_item.transient_stake_lamports) + .checked_sub(withdraw_lamports) + .ok_or(StakePoolError::CalculationFailure)? + .into() } StakeWithdrawSource::ValidatorRemoval => { - validator_list_item.active_stake_lamports = validator_list_item - .active_stake_lamports - .checked_sub(withdraw_lamports) - .ok_or(StakePoolError::CalculationFailure)?; - if validator_list_item.active_stake_lamports != 0 { + validator_list_item.active_stake_lamports = + u64::from(validator_list_item.active_stake_lamports) + .checked_sub(withdraw_lamports) + .ok_or(StakePoolError::CalculationFailure)? + .into(); + if u64::from(validator_list_item.active_stake_lamports) != 0 { msg!("Attempting to remove a validator from the pool, but withdrawal leaves {} lamports, update the pool to merge any unaccounted lamports", - validator_list_item.active_stake_lamports); + u64::from(validator_list_item.active_stake_lamports)); return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); } // since we already checked that there's no transient stake, diff --git a/program/src/state.rs b/program/src/state.rs index f87be227..fc6b4b0f 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -18,6 +18,7 @@ use { pubkey::{Pubkey, PUBKEY_BYTES}, stake::state::Lockup, }, + spl_pod::primitives::{PodU32, PodU64}, spl_token_2022::{ extension::{BaseStateWithExtensions, ExtensionType, StateWithExtensions}, state::{Account, AccountState, Mint}, @@ -625,25 +626,25 @@ pub struct ValidatorStakeInfo { /// /// Note that if `last_update_epoch` does not match the current epoch then /// this field may not be accurate - pub active_stake_lamports: u64, + pub active_stake_lamports: PodU64, /// Amount of transient stake delegated to this validator /// /// Note that if `last_update_epoch` does not match the current epoch then /// this field may not be accurate - pub transient_stake_lamports: u64, + pub transient_stake_lamports: PodU64, /// Last epoch the active and transient stake lamports fields were updated - pub last_update_epoch: u64, + pub last_update_epoch: PodU64, /// Transient account seed suffix, used to derive the transient stake account address - pub transient_seed_suffix: u64, + pub transient_seed_suffix: PodU64, /// Unused space, initially meant to specify the end of seed suffixes - pub unused: u32, + pub unused: PodU32, /// Validator account seed suffix - pub validator_seed_suffix: u32, // really `Option` so 0 is `None` + pub validator_seed_suffix: PodU32, // really `Option` so 0 is `None` /// Status of the validator stake account pub status: StakeStatus, @@ -655,8 +656,8 @@ pub struct ValidatorStakeInfo { impl ValidatorStakeInfo { /// Get the total lamports on this validator (active and transient) pub fn stake_lamports(&self) -> Result { - self.active_stake_lamports - .checked_add(self.transient_stake_lamports) + u64::from(self.active_stake_lamports) + .checked_add(self.transient_stake_lamports.into()) .ok_or(StakePoolError::CalculationFailure) } @@ -748,7 +749,9 @@ impl ValidatorList { /// Check if the list has any active stake pub fn has_active_stake(&self) -> bool { - self.validators.iter().any(|x| x.active_stake_lamports > 0) + self.validators + .iter() + .any(|x| u64::from(x.active_stake_lamports) > 0) } } @@ -1002,32 +1005,32 @@ mod test { ValidatorStakeInfo { status: StakeStatus::Active, vote_account_address: Pubkey::new_from_array([1; 32]), - active_stake_lamports: u64::from_le_bytes([255; 8]), - transient_stake_lamports: u64::from_le_bytes([128; 8]), - last_update_epoch: u64::from_le_bytes([64; 8]), - transient_seed_suffix: 0, - unused: 0, - validator_seed_suffix: 0, + active_stake_lamports: u64::from_le_bytes([255; 8]).into(), + transient_stake_lamports: u64::from_le_bytes([128; 8]).into(), + last_update_epoch: u64::from_le_bytes([64; 8]).into(), + transient_seed_suffix: 0.into(), + unused: 0.into(), + validator_seed_suffix: 0.into(), }, ValidatorStakeInfo { status: StakeStatus::DeactivatingTransient, vote_account_address: Pubkey::new_from_array([2; 32]), - active_stake_lamports: 998877665544, - transient_stake_lamports: 222222222, - last_update_epoch: 11223445566, - transient_seed_suffix: 0, - unused: 0, - validator_seed_suffix: 0, + active_stake_lamports: 998877665544.into(), + transient_stake_lamports: 222222222.into(), + last_update_epoch: 11223445566.into(), + transient_seed_suffix: 0.into(), + unused: 0.into(), + validator_seed_suffix: 0.into(), }, ValidatorStakeInfo { status: StakeStatus::ReadyForRemoval, vote_account_address: Pubkey::new_from_array([3; 32]), - active_stake_lamports: 0, - transient_stake_lamports: 0, - last_update_epoch: 999999999999999, - transient_seed_suffix: 0, - unused: 0, - validator_seed_suffix: 0, + active_stake_lamports: 0.into(), + transient_stake_lamports: 0.into(), + last_update_epoch: 999999999999999.into(), + transient_seed_suffix: 0.into(), + unused: 0.into(), + validator_seed_suffix: 0.into(), }, ], } @@ -1073,7 +1076,7 @@ mod test { let mut validator_list = test_validator_list(max_validators); assert!(validator_list.has_active_stake()); for validator in validator_list.validators.iter_mut() { - validator.active_stake_lamports = 0; + validator.active_stake_lamports = 0.into(); } assert!(!validator_list.has_active_stake()); } diff --git a/program/tests/decrease.rs b/program/tests/decrease.rs index b1f17cc1..802ecf65 100644 --- a/program/tests/decrease.rs +++ b/program/tests/decrease.rs @@ -424,7 +424,7 @@ async fn twice(success: bool, use_additional_first_time: bool, use_additional_se .get_validator_list(&mut context.banks_client) .await; let entry = validator_list.find(&validator_stake.vote.pubkey()).unwrap(); - assert_eq!(entry.transient_stake_lamports, total_decrease); + assert_eq!(u64::from(entry.transient_stake_lamports), total_decrease); } else { let error = error.unwrap().unwrap(); assert_eq!( diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index aafeca1f..929774cc 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -249,7 +249,10 @@ async fn success(token_program_id: Pubkey) { validator_stake_account.lamports, post_validator_stake_item.stake_lamports().unwrap() ); - assert_eq!(post_validator_stake_item.transient_stake_lamports, 0); + assert_eq!( + u64::from(post_validator_stake_item.transient_stake_lamports), + 0 + ); // Check reserve let post_reserve_lamports = get_account( @@ -443,7 +446,10 @@ async fn success_with_extra_stake_lamports() { validator_stake_account.lamports, post_validator_stake_item.stake_lamports().unwrap() ); - assert_eq!(post_validator_stake_item.transient_stake_lamports, 0); + assert_eq!( + u64::from(post_validator_stake_item.transient_stake_lamports), + 0 + ); // Check reserve let post_reserve_lamports = get_account( diff --git a/program/tests/force_destake.rs b/program/tests/force_destake.rs index 1aedc5e8..32fc8ff7 100644 --- a/program/tests/force_destake.rs +++ b/program/tests/force_destake.rs @@ -65,12 +65,12 @@ async fn setup() -> ( validator_list.validators.push(ValidatorStakeInfo { status: StakeStatus::Active, vote_account_address: voter_pubkey, - active_stake_lamports, - transient_stake_lamports: 0, - last_update_epoch: 0, - transient_seed_suffix: 0, - unused: 0, - validator_seed_suffix: raw_validator_seed, + active_stake_lamports: active_stake_lamports.into(), + transient_stake_lamports: 0.into(), + last_update_epoch: 0.into(), + transient_seed_suffix: 0.into(), + unused: 0.into(), + validator_seed_suffix: raw_validator_seed.into(), }); stake_pool.total_lamports += active_stake_lamports; diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 7057228c..8625853e 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -2405,12 +2405,12 @@ pub fn add_validator_stake_account( validator_list.validators.push(state::ValidatorStakeInfo { status, vote_account_address: *voter_pubkey, - active_stake_lamports, - transient_stake_lamports: 0, - last_update_epoch: FIRST_NORMAL_EPOCH, - transient_seed_suffix: 0, - unused: 0, - validator_seed_suffix: raw_suffix, + active_stake_lamports: active_stake_lamports.into(), + transient_stake_lamports: 0.into(), + last_update_epoch: FIRST_NORMAL_EPOCH.into(), + transient_seed_suffix: 0.into(), + unused: 0.into(), + validator_seed_suffix: raw_suffix.into(), }); stake_pool.total_lamports += active_stake_lamports; diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index 1bb975a4..5c58cecf 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -25,7 +25,7 @@ use { // the test require so many helper accounts. // 20k is also a very safe number for the current upper bound of the network. const MAX_POOL_SIZE_WITH_REQUESTED_COMPUTE_UNITS: u32 = 20_000; -const MAX_POOL_SIZE: u32 = 3_000; +const MAX_POOL_SIZE: u32 = 2_650; const STAKE_AMOUNT: u64 = 200_000_000_000; async fn setup( @@ -300,26 +300,26 @@ async fn remove_validator_from_pool(max_validators: u32) { let first_element = &validator_list.validators[0]; assert_eq!(first_element.status, StakeStatus::DeactivatingValidator); assert_eq!( - first_element.active_stake_lamports, + u64::from(first_element.active_stake_lamports), LAMPORTS_PER_SOL + STAKE_ACCOUNT_RENT_EXEMPTION ); - assert_eq!(first_element.transient_stake_lamports, 0); + assert_eq!(u64::from(first_element.transient_stake_lamports), 0); let middle_element = &validator_list.validators[middle_index]; assert_eq!(middle_element.status, StakeStatus::DeactivatingValidator); assert_eq!( - middle_element.active_stake_lamports, + u64::from(middle_element.active_stake_lamports), LAMPORTS_PER_SOL + STAKE_ACCOUNT_RENT_EXEMPTION ); - assert_eq!(middle_element.transient_stake_lamports, 0); + assert_eq!(u64::from(middle_element.transient_stake_lamports), 0); let last_element = &validator_list.validators[last_index]; assert_eq!(last_element.status, StakeStatus::DeactivatingValidator); assert_eq!( - last_element.active_stake_lamports, + u64::from(last_element.active_stake_lamports), LAMPORTS_PER_SOL + STAKE_ACCOUNT_RENT_EXEMPTION ); - assert_eq!(last_element.transient_stake_lamports, 0); + assert_eq!(u64::from(last_element.transient_stake_lamports), 0); let error = stake_pool_accounts .update_validator_list_balance( @@ -467,10 +467,10 @@ async fn add_validator_to_pool(max_validators: u32) { let last_element = validator_list.validators[last_index]; assert_eq!(last_element.status, StakeStatus::Active); assert_eq!( - last_element.active_stake_lamports, + u64::from(last_element.active_stake_lamports), LAMPORTS_PER_SOL + STAKE_ACCOUNT_RENT_EXEMPTION ); - assert_eq!(last_element.transient_stake_lamports, 0); + assert_eq!(u64::from(last_element.transient_stake_lamports), 0); assert_eq!(last_element.vote_account_address, test_vote_address); let transient_stake_seed = u64::MAX; @@ -505,11 +505,11 @@ async fn add_validator_to_pool(max_validators: u32) { let last_element = validator_list.validators[last_index]; assert_eq!(last_element.status, StakeStatus::Active); assert_eq!( - last_element.active_stake_lamports, + u64::from(last_element.active_stake_lamports), LAMPORTS_PER_SOL + STAKE_ACCOUNT_RENT_EXEMPTION ); assert_eq!( - last_element.transient_stake_lamports, + u64::from(last_element.transient_stake_lamports), increase_amount + STAKE_ACCOUNT_RENT_EXEMPTION ); assert_eq!(last_element.vote_account_address, test_vote_address); diff --git a/program/tests/increase.rs b/program/tests/increase.rs index ac50c786..3e15a7b2 100644 --- a/program/tests/increase.rs +++ b/program/tests/increase.rs @@ -440,7 +440,7 @@ async fn twice(success: bool, use_additional_first_time: bool, use_additional_se .await; let entry = validator_list.find(&validator_stake.vote.pubkey()).unwrap(); assert_eq!( - entry.transient_stake_lamports, + u64::from(entry.transient_stake_lamports), total_increase + stake_rent * 2 ); } else { diff --git a/program/tests/redelegate.rs b/program/tests/redelegate.rs index 8f14746c..eec2eff9 100644 --- a/program/tests/redelegate.rs +++ b/program/tests/redelegate.rs @@ -250,15 +250,15 @@ async fn success() { .find(&source_validator_stake.vote.pubkey()) .unwrap(); assert_eq!( - source_item.active_stake_lamports, + u64::from(source_item.active_stake_lamports), validator_stake_account.lamports ); assert_eq!( - source_item.transient_stake_lamports, + u64::from(source_item.transient_stake_lamports), source_transient_stake_account.lamports ); assert_eq!( - source_item.transient_seed_suffix, + u64::from(source_item.transient_seed_suffix), source_validator_stake.transient_stake_seed ); @@ -266,11 +266,11 @@ async fn success() { .find(&destination_validator_stake.vote.pubkey()) .unwrap(); assert_eq!( - destination_item.transient_stake_lamports, + u64::from(destination_item.transient_stake_lamports), destination_transient_stake_account.lamports ); assert_eq!( - destination_item.transient_seed_suffix, + u64::from(destination_item.transient_seed_suffix), destination_validator_stake.transient_stake_seed ); @@ -313,17 +313,17 @@ async fn success() { .find(&source_validator_stake.vote.pubkey()) .unwrap(); assert_eq!( - source_item.active_stake_lamports, + u64::from(source_item.active_stake_lamports), validator_stake_account.lamports ); - assert_eq!(source_item.transient_stake_lamports, 0); + assert_eq!(u64::from(source_item.transient_stake_lamports), 0); let destination_item = validator_list .find(&destination_validator_stake.vote.pubkey()) .unwrap(); - assert_eq!(destination_item.transient_stake_lamports, 0); + assert_eq!(u64::from(destination_item.transient_stake_lamports), 0); assert_eq!( - destination_item.active_stake_lamports, + u64::from(destination_item.active_stake_lamports), pre_destination_validator_stake_account.lamports + redelegate_lamports - stake_rent * 2 ); let post_destination_validator_stake_account = get_account( @@ -386,7 +386,7 @@ async fn success_with_increasing_stake() { .find(&destination_validator_stake.vote.pubkey()) .unwrap(); assert_eq!( - destination_item.transient_stake_lamports, + u64::from(destination_item.transient_stake_lamports), current_minimum_delegation + stake_rent ); let pre_transient_stake_account = get_account( @@ -499,11 +499,11 @@ async fn success_with_increasing_stake() { .find(&destination_validator_stake.vote.pubkey()) .unwrap(); assert_eq!( - destination_item.transient_stake_lamports, + u64::from(destination_item.transient_stake_lamports), destination_transient_stake_account.lamports ); assert_eq!( - destination_item.transient_seed_suffix, + u64::from(destination_item.transient_seed_suffix), destination_validator_stake.transient_stake_seed ); @@ -539,11 +539,11 @@ async fn success_with_increasing_stake() { let destination_item = validator_list .find(&destination_validator_stake.vote.pubkey()) .unwrap(); - assert_eq!(destination_item.transient_stake_lamports, 0); + assert_eq!(u64::from(destination_item.transient_stake_lamports), 0); // redelegate is smart enough to activate *everything*, so there's only one rent-exemption // worth of inactive stake! assert_eq!( - destination_item.active_stake_lamports, + u64::from(destination_item.active_stake_lamports), pre_validator_stake_account.lamports + redelegate_lamports + current_minimum_delegation - stake_rent ); diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index e97c786b..181df916 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -611,11 +611,11 @@ async fn merge_transient_stake_after_remove() { StakeStatus::DeactivatingAll ); assert_eq!( - validator_list.validators[0].active_stake_lamports, + u64::from(validator_list.validators[0].active_stake_lamports), stake_rent + current_minimum_delegation ); assert_eq!( - validator_list.validators[0].transient_stake_lamports, + u64::from(validator_list.validators[0].transient_stake_lamports), deactivated_lamports ); diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index 9b71900c..aac22d66 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -112,15 +112,16 @@ async fn success() { validators: vec![state::ValidatorStakeInfo { status: state::StakeStatus::Active, vote_account_address: validator_stake.vote.pubkey(), - last_update_epoch: 0, - active_stake_lamports: stake_rent + current_minimum_delegation, - transient_stake_lamports: 0, - transient_seed_suffix: 0, - unused: 0, + last_update_epoch: 0.into(), + active_stake_lamports: (stake_rent + current_minimum_delegation).into(), + transient_stake_lamports: 0.into(), + transient_seed_suffix: 0.into(), + unused: 0.into(), validator_seed_suffix: validator_stake .validator_stake_seed .map(|s| s.get()) - .unwrap_or(0), + .unwrap_or(0) + .into(), }] } ); diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 09fde679..61a1b4f6 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -544,15 +544,16 @@ async fn success_with_deactivating_transient_stake() { validators: vec![state::ValidatorStakeInfo { status: state::StakeStatus::DeactivatingAll, vote_account_address: validator_stake.vote.pubkey(), - last_update_epoch: 0, - active_stake_lamports: stake_rent + current_minimum_delegation, - transient_stake_lamports: TEST_STAKE_AMOUNT + stake_rent, - transient_seed_suffix: validator_stake.transient_stake_seed, - unused: 0, + last_update_epoch: 0.into(), + active_stake_lamports: (stake_rent + current_minimum_delegation).into(), + transient_stake_lamports: (TEST_STAKE_AMOUNT + stake_rent).into(), + transient_seed_suffix: validator_stake.transient_stake_seed.into(), + unused: 0.into(), validator_seed_suffix: validator_stake .validator_stake_seed .map(|s| s.get()) - .unwrap_or(0), + .unwrap_or(0) + .into(), }], }; assert_eq!(validator_list, expected_list); diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 6ee5bf60..9edeeec9 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -223,7 +223,7 @@ async fn _success(token_program_id: Pubkey, test_type: SuccessTestType) { validator_stake_item_before.stake_lamports().unwrap() - tokens_burnt ); assert_eq!( - validator_stake_item.active_stake_lamports, + u64::from(validator_stake_item.active_stake_lamports), validator_stake_item.stake_lamports().unwrap(), ); @@ -246,7 +246,7 @@ async fn _success(token_program_id: Pubkey, test_type: SuccessTestType) { .await; assert_eq!( validator_stake_account.lamports, - validator_stake_item.active_stake_lamports + u64::from(validator_stake_item.active_stake_lamports) ); // Check user recipient stake account balance From 1fd325e5481f653fbe1a1b659b0fbf6125c9e0f8 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 1 Sep 2023 18:55:06 +0200 Subject: [PATCH 0486/1076] stake-pool: Enforce that pool mint uses 9 decimal places (HAL-03) (#5085) --- program/src/error.rs | 5 +++++ program/src/processor.rs | 6 ++++++ program/tests/helpers/mod.rs | 3 ++- program/tests/initialize.rs | 29 ++++++++++++++++++++++++++++- 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/program/src/error.rs b/program/src/error.rs index 39fae329..b3ed8e09 100644 --- a/program/src/error.rs +++ b/program/src/error.rs @@ -144,6 +144,11 @@ pub enum StakePoolError { /// Instruction exceeds desired slippage limit #[error("Instruction exceeds desired slippage limit")] ExceededSlippage, + + // 40. + /// Provided mint does not have 9 decimals to match SOL + #[error("IncorrectMintDecimals")] + IncorrectMintDecimals, } impl From for ProgramError { fn from(e: StakePoolError) -> Self { diff --git a/program/src/processor.rs b/program/src/processor.rs index d267d1e5..167f19a5 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -39,6 +39,7 @@ use { spl_token_2022::{ check_spl_token_program_account, extension::{BaseStateWithExtensions, StateWithExtensions}, + native_mint, state::Mint, }, std::num::NonZeroU32, @@ -828,6 +829,10 @@ impl Processor { return Err(StakePoolError::NonZeroPoolTokenSupply.into()); } + if pool_mint.base.decimals != native_mint::DECIMALS { + return Err(StakePoolError::IncorrectMintDecimals.into()); + } + if !pool_mint .base .mint_authority @@ -4006,6 +4011,7 @@ impl PrintProgramError for StakePoolError { StakePoolError::UnsupportedMintExtension => msg!("Error: mint has an unsupported extension"), StakePoolError::UnsupportedFeeAccountExtension => msg!("Error: fee account has an unsupported extension"), StakePoolError::ExceededSlippage => msg!("Error: instruction exceeds desired slippage limit"), + StakePoolError::IncorrectMintDecimals => msg!("Error: Provided mint does not have 9 decimals to match SOL"), } } } diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 8625853e..36f48fb6 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -36,6 +36,7 @@ use { }, spl_token_2022::{ extension::{ExtensionType, StateWithExtensionsOwned}, + native_mint, state::{Account, Mint}, }, std::{convert::TryInto, num::NonZeroU32}, @@ -2013,7 +2014,7 @@ impl Default for StakePoolAccounts { token_program_id: spl_token::id(), pool_mint, pool_fee_account, - pool_decimals: 0, + pool_decimals: native_mint::DECIMALS, manager, staker, withdraw_authority, diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index 750ab08b..55e7c2fb 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -448,7 +448,7 @@ async fn fail_with_freeze_authority() { &wrong_mint.pubkey(), &stake_pool_accounts.withdraw_authority, Some(&stake_pool_accounts.withdraw_authority), - 0, + stake_pool_accounts.pool_decimals, ) .unwrap(), ], @@ -1603,3 +1603,30 @@ async fn success_with_extra_reserve_lamports() { .await; assert_eq!(init_pool_tokens, init_lamports); } + +#[tokio::test] +async fn fail_with_incorrect_mint_decimals() { + let (mut banks_client, payer, recent_blockhash) = program_test().start().await; + let stake_pool_accounts = StakePoolAccounts { + pool_decimals: 8, + ..Default::default() + }; + let error = stake_pool_accounts + .initialize_stake_pool( + &mut banks_client, + &payer, + &recent_blockhash, + MINIMUM_RESERVE_LAMPORTS, + ) + .await + .unwrap_err() + .unwrap(); + + assert_eq!( + error, + TransactionError::InstructionError( + 2, + InstructionError::Custom(error::StakePoolError::IncorrectMintDecimals as u32), + ) + ); +} From 0f1a0e74100e883bc27e051e40e98b597a5a6625 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 1 Sep 2023 18:55:19 +0200 Subject: [PATCH 0487/1076] stake-pool: Add comments about unnecessary ownership checks (HAL-01) (#5084) --- program/src/processor.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/program/src/processor.rs b/program/src/processor.rs index 167f19a5..52ce25e7 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -739,6 +739,8 @@ impl Processor { return Err(StakePoolError::AlreadyInUse.into()); } + // This check is unnecessary since the runtime will check the ownership, + // but provides clarity that the parameter is in fact checked. check_account_owner(stake_pool_info, program_id)?; let mut stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; if !stake_pool.is_uninitialized() { @@ -746,6 +748,8 @@ impl Processor { return Err(StakePoolError::AlreadyInUse.into()); } + // This check is unnecessary since the runtime will check the ownership, + // but provides clarity that the parameter is in fact checked. check_account_owner(validator_list_info, program_id)?; let mut validator_list = try_from_slice_unchecked::(&validator_list_info.data.borrow())?; From efa8e05965943734b7ba207a7653b4a59b607166 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 1 Sep 2023 21:55:38 +0200 Subject: [PATCH 0488/1076] release: Bump token-2022 and all dependencies (#5189) * release: Bump token-2022 and all dependencies In order to release a new token-2022, we need to bump its version and every local crate that it depends on. That means the following: * spl-token-2022 * spl-program-error * spl-tlv-account-resolution * spl-type-length-value * spl-token-metadata-interface * spl-token-metadata-example * spl-transfer-hook-interface * spl-transfer-hook-example * spl-token-client (this one's not needed, but it's cleaner) * Also bump spl-token-cli * Also bump associated-token-account --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index b269de34..b4cdccc3 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -23,7 +23,7 @@ solana-logger = "=1.16.3" solana-program = "=1.16.3" solana-remote-wallet = "=1.16.3" solana-sdk = "=1.16.3" -spl-associated-token-account = { version = "=2.0", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } +spl-associated-token-account = { version = "=2.1", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "=0.7.0", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "=4.0", path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" diff --git a/program/Cargo.toml b/program/Cargo.toml index 4ba2812d..3eadc07c 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -22,7 +22,7 @@ serde_derive = "1.0.103" solana-program = "1.16.3" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-pod = { version = "0.1", path = "../../libraries/pod", features = ["borsh"] } -spl-token-2022 = { version = "0.7", path = "../../token/program-2022", features = [ "no-entrypoint" ] } +spl-token-2022 = { version = "0.8", path = "../../token/program-2022", features = [ "no-entrypoint" ] } thiserror = "1.0" bincode = "1.3.1" From c5df56af024e2781870e1c20ab316448f18eaec8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Sep 2023 12:41:55 -0700 Subject: [PATCH 0489/1076] build(deps-dev): bump @types/node from 20.5.7 to 20.5.9 in /stake-pool/js (#5194) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.5.7 to 20.5.9. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 14ec8cfc..c065e54b 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1768,9 +1768,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.5.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.7.tgz", - "integrity": "sha512-dP7f3LdZIysZnmvP3ANJYTSwg+wLLl8p7RqniVlV7j+oXSXAbt9h0WIBFmJy5inWZoX9wZN6eXx+YXd9Rh3RBA==" + "version": "20.5.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.9.tgz", + "integrity": "sha512-PcGNd//40kHAS3sTlzKB9C9XL4K0sTup8nbG5lC14kzEteTNuAFh9u5nA0o5TWnSG2r/JNPRXFVcHJIIeRlmqQ==" }, "node_modules/@types/node-fetch": { "version": "2.6.4", @@ -8327,9 +8327,9 @@ "dev": true }, "@types/node": { - "version": "20.5.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.7.tgz", - "integrity": "sha512-dP7f3LdZIysZnmvP3ANJYTSwg+wLLl8p7RqniVlV7j+oXSXAbt9h0WIBFmJy5inWZoX9wZN6eXx+YXd9Rh3RBA==" + "version": "20.5.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.9.tgz", + "integrity": "sha512-PcGNd//40kHAS3sTlzKB9C9XL4K0sTup8nbG5lC14kzEteTNuAFh9u5nA0o5TWnSG2r/JNPRXFVcHJIIeRlmqQ==" }, "@types/node-fetch": { "version": "2.6.4", From 320295652ee363b0738fe1e07f5b5784e36e7945 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Sep 2023 14:46:05 -0700 Subject: [PATCH 0490/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.5.0 to 6.6.0 in /stake-pool/js (#5203) build(deps-dev): bump @typescript-eslint/eslint-plugin in /stake-pool/js Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.5.0 to 6.6.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.6.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 354 +++++++++++++++++++++++++--- 1 file changed, 318 insertions(+), 36 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index c065e54b..60fa130d 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1830,16 +1830,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.5.0.tgz", - "integrity": "sha512-2pktILyjvMaScU6iK3925uvGU87E+N9rh372uGZgiMYwafaw9SXq86U04XPq3UH6tzRvNgBsub6x2DacHc33lw==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.6.0.tgz", + "integrity": "sha512-CW9YDGTQnNYMIo5lMeuiIG08p4E0cXrXTbcZ2saT/ETE7dWUrNxlijsQeU04qAAKkILiLzdQz+cGFxCJjaZUmA==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.5.0", - "@typescript-eslint/type-utils": "6.5.0", - "@typescript-eslint/utils": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0", + "@typescript-eslint/scope-manager": "6.6.0", + "@typescript-eslint/type-utils": "6.6.0", + "@typescript-eslint/utils": "6.6.0", + "@typescript-eslint/visitor-keys": "6.6.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -1864,6 +1864,53 @@ } } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.6.0.tgz", + "integrity": "sha512-pT08u5W/GT4KjPUmEtc2kSYvrH8x89cVzkA0Sy2aaOUIw6YxOIjA8ilwLr/1fLjOedX1QAuBpG9XggWqIIfERw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.6.0", + "@typescript-eslint/visitor-keys": "6.6.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.6.0.tgz", + "integrity": "sha512-CB6QpJQ6BAHlJXdwUmiaXDBmTqIE2bzGTDLADgvqtHWuhfNP3rAOK7kAgRMAET5rDRr9Utt+qAzRBdu3AhR3sg==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.6.0.tgz", + "integrity": "sha512-L61uJT26cMOfFQ+lMZKoJNbAEckLe539VhTxiGHrWl5XSKQgA0RTBZJW2HFPy5T0ZvPVSD93QsrTKDkfNwJGyQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.6.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/parser": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.5.0.tgz", @@ -1910,13 +1957,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.5.0.tgz", - "integrity": "sha512-f7OcZOkRivtujIBQ4yrJNIuwyCQO1OjocVqntl9dgSIZAdKqicj3xFDqDOzHDlGCZX990LqhLQXWRnQvsapq8A==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.6.0.tgz", + "integrity": "sha512-8m16fwAcEnQc69IpeDyokNO+D5spo0w1jepWWY2Q6y5ZKNuj5EhVQXjtVAeDDqvW6Yg7dhclbsz6rTtOvcwpHg==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.5.0", - "@typescript-eslint/utils": "6.5.0", + "@typescript-eslint/typescript-estree": "6.6.0", + "@typescript-eslint/utils": "6.6.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -1936,6 +1983,63 @@ } } }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.6.0.tgz", + "integrity": "sha512-CB6QpJQ6BAHlJXdwUmiaXDBmTqIE2bzGTDLADgvqtHWuhfNP3rAOK7kAgRMAET5rDRr9Utt+qAzRBdu3AhR3sg==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.6.0.tgz", + "integrity": "sha512-hMcTQ6Al8MP2E6JKBAaSxSVw5bDhdmbCEhGW/V8QXkb9oNsFkA4SBuOMYVPxD3jbtQ4R/vSODBsr76R6fP3tbA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.6.0", + "@typescript-eslint/visitor-keys": "6.6.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.6.0.tgz", + "integrity": "sha512-L61uJT26cMOfFQ+lMZKoJNbAEckLe539VhTxiGHrWl5XSKQgA0RTBZJW2HFPy5T0ZvPVSD93QsrTKDkfNwJGyQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.6.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/types": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.5.0.tgz", @@ -1977,17 +2081,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.5.0.tgz", - "integrity": "sha512-9nqtjkNykFzeVtt9Pj6lyR9WEdd8npPhhIPM992FWVkZuS6tmxHfGVnlUcjpUP2hv8r4w35nT33mlxd+Be1ACQ==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.6.0.tgz", + "integrity": "sha512-mPHFoNa2bPIWWglWYdR0QfY9GN0CfvvXX1Sv6DlSTive3jlMTUy+an67//Gysc+0Me9pjitrq0LJp0nGtLgftw==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.5.0", - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/typescript-estree": "6.5.0", + "@typescript-eslint/scope-manager": "6.6.0", + "@typescript-eslint/types": "6.6.0", + "@typescript-eslint/typescript-estree": "6.6.0", "semver": "^7.5.4" }, "engines": { @@ -2001,6 +2105,80 @@ "eslint": "^7.0.0 || ^8.0.0" } }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.6.0.tgz", + "integrity": "sha512-pT08u5W/GT4KjPUmEtc2kSYvrH8x89cVzkA0Sy2aaOUIw6YxOIjA8ilwLr/1fLjOedX1QAuBpG9XggWqIIfERw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.6.0", + "@typescript-eslint/visitor-keys": "6.6.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.6.0.tgz", + "integrity": "sha512-CB6QpJQ6BAHlJXdwUmiaXDBmTqIE2bzGTDLADgvqtHWuhfNP3rAOK7kAgRMAET5rDRr9Utt+qAzRBdu3AhR3sg==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.6.0.tgz", + "integrity": "sha512-hMcTQ6Al8MP2E6JKBAaSxSVw5bDhdmbCEhGW/V8QXkb9oNsFkA4SBuOMYVPxD3jbtQ4R/vSODBsr76R6fP3tbA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.6.0", + "@typescript-eslint/visitor-keys": "6.6.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.6.0.tgz", + "integrity": "sha512-L61uJT26cMOfFQ+lMZKoJNbAEckLe539VhTxiGHrWl5XSKQgA0RTBZJW2HFPy5T0ZvPVSD93QsrTKDkfNwJGyQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.6.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/visitor-keys": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.5.0.tgz", @@ -8389,22 +8567,50 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.5.0.tgz", - "integrity": "sha512-2pktILyjvMaScU6iK3925uvGU87E+N9rh372uGZgiMYwafaw9SXq86U04XPq3UH6tzRvNgBsub6x2DacHc33lw==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.6.0.tgz", + "integrity": "sha512-CW9YDGTQnNYMIo5lMeuiIG08p4E0cXrXTbcZ2saT/ETE7dWUrNxlijsQeU04qAAKkILiLzdQz+cGFxCJjaZUmA==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.5.0", - "@typescript-eslint/type-utils": "6.5.0", - "@typescript-eslint/utils": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0", + "@typescript-eslint/scope-manager": "6.6.0", + "@typescript-eslint/type-utils": "6.6.0", + "@typescript-eslint/utils": "6.6.0", + "@typescript-eslint/visitor-keys": "6.6.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", "natural-compare": "^1.4.0", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.6.0.tgz", + "integrity": "sha512-pT08u5W/GT4KjPUmEtc2kSYvrH8x89cVzkA0Sy2aaOUIw6YxOIjA8ilwLr/1fLjOedX1QAuBpG9XggWqIIfERw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.6.0", + "@typescript-eslint/visitor-keys": "6.6.0" + } + }, + "@typescript-eslint/types": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.6.0.tgz", + "integrity": "sha512-CB6QpJQ6BAHlJXdwUmiaXDBmTqIE2bzGTDLADgvqtHWuhfNP3rAOK7kAgRMAET5rDRr9Utt+qAzRBdu3AhR3sg==", + "dev": true + }, + "@typescript-eslint/visitor-keys": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.6.0.tgz", + "integrity": "sha512-L61uJT26cMOfFQ+lMZKoJNbAEckLe539VhTxiGHrWl5XSKQgA0RTBZJW2HFPy5T0ZvPVSD93QsrTKDkfNwJGyQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.6.0", + "eslint-visitor-keys": "^3.4.1" + } + } } }, "@typescript-eslint/parser": { @@ -8431,15 +8637,48 @@ } }, "@typescript-eslint/type-utils": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.5.0.tgz", - "integrity": "sha512-f7OcZOkRivtujIBQ4yrJNIuwyCQO1OjocVqntl9dgSIZAdKqicj3xFDqDOzHDlGCZX990LqhLQXWRnQvsapq8A==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.6.0.tgz", + "integrity": "sha512-8m16fwAcEnQc69IpeDyokNO+D5spo0w1jepWWY2Q6y5ZKNuj5EhVQXjtVAeDDqvW6Yg7dhclbsz6rTtOvcwpHg==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "6.5.0", - "@typescript-eslint/utils": "6.5.0", + "@typescript-eslint/typescript-estree": "6.6.0", + "@typescript-eslint/utils": "6.6.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" + }, + "dependencies": { + "@typescript-eslint/types": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.6.0.tgz", + "integrity": "sha512-CB6QpJQ6BAHlJXdwUmiaXDBmTqIE2bzGTDLADgvqtHWuhfNP3rAOK7kAgRMAET5rDRr9Utt+qAzRBdu3AhR3sg==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.6.0.tgz", + "integrity": "sha512-hMcTQ6Al8MP2E6JKBAaSxSVw5bDhdmbCEhGW/V8QXkb9oNsFkA4SBuOMYVPxD3jbtQ4R/vSODBsr76R6fP3tbA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.6.0", + "@typescript-eslint/visitor-keys": "6.6.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.6.0.tgz", + "integrity": "sha512-L61uJT26cMOfFQ+lMZKoJNbAEckLe539VhTxiGHrWl5XSKQgA0RTBZJW2HFPy5T0ZvPVSD93QsrTKDkfNwJGyQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.6.0", + "eslint-visitor-keys": "^3.4.1" + } + } } }, "@typescript-eslint/types": { @@ -8464,18 +8703,61 @@ } }, "@typescript-eslint/utils": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.5.0.tgz", - "integrity": "sha512-9nqtjkNykFzeVtt9Pj6lyR9WEdd8npPhhIPM992FWVkZuS6tmxHfGVnlUcjpUP2hv8r4w35nT33mlxd+Be1ACQ==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.6.0.tgz", + "integrity": "sha512-mPHFoNa2bPIWWglWYdR0QfY9GN0CfvvXX1Sv6DlSTive3jlMTUy+an67//Gysc+0Me9pjitrq0LJp0nGtLgftw==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.5.0", - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/typescript-estree": "6.5.0", + "@typescript-eslint/scope-manager": "6.6.0", + "@typescript-eslint/types": "6.6.0", + "@typescript-eslint/typescript-estree": "6.6.0", "semver": "^7.5.4" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.6.0.tgz", + "integrity": "sha512-pT08u5W/GT4KjPUmEtc2kSYvrH8x89cVzkA0Sy2aaOUIw6YxOIjA8ilwLr/1fLjOedX1QAuBpG9XggWqIIfERw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.6.0", + "@typescript-eslint/visitor-keys": "6.6.0" + } + }, + "@typescript-eslint/types": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.6.0.tgz", + "integrity": "sha512-CB6QpJQ6BAHlJXdwUmiaXDBmTqIE2bzGTDLADgvqtHWuhfNP3rAOK7kAgRMAET5rDRr9Utt+qAzRBdu3AhR3sg==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.6.0.tgz", + "integrity": "sha512-hMcTQ6Al8MP2E6JKBAaSxSVw5bDhdmbCEhGW/V8QXkb9oNsFkA4SBuOMYVPxD3jbtQ4R/vSODBsr76R6fP3tbA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.6.0", + "@typescript-eslint/visitor-keys": "6.6.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.6.0.tgz", + "integrity": "sha512-L61uJT26cMOfFQ+lMZKoJNbAEckLe539VhTxiGHrWl5XSKQgA0RTBZJW2HFPy5T0ZvPVSD93QsrTKDkfNwJGyQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.6.0", + "eslint-visitor-keys": "^3.4.1" + } + } } }, "@typescript-eslint/visitor-keys": { From f80350c4bc9577c0f61ef7a85d3c6b2ecc6178f8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Sep 2023 14:46:19 -0700 Subject: [PATCH 0491/1076] build(deps-dev): bump @typescript-eslint/parser from 6.5.0 to 6.6.0 in /stake-pool/js (#5204) build(deps-dev): bump @typescript-eslint/parser in /stake-pool/js Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.5.0 to 6.6.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.6.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 145 +++++++++++++++++++++++++--- 1 file changed, 131 insertions(+), 14 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 60fa130d..11091a49 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1912,15 +1912,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.5.0.tgz", - "integrity": "sha512-LMAVtR5GN8nY0G0BadkG0XIe4AcNMeyEy3DyhKGAh9k4pLSMBO7rF29JvDBpZGCmp5Pgz5RLHP6eCpSYZJQDuQ==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.6.0.tgz", + "integrity": "sha512-setq5aJgUwtzGrhW177/i+DMLqBaJbdwGj2CPIVFFLE0NCliy5ujIdLHd2D1ysmlmsjdL2GWW+hR85neEfc12w==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.5.0", - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/typescript-estree": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0", + "@typescript-eslint/scope-manager": "6.6.0", + "@typescript-eslint/types": "6.6.0", + "@typescript-eslint/typescript-estree": "6.6.0", + "@typescript-eslint/visitor-keys": "6.6.0", "debug": "^4.3.4" }, "engines": { @@ -1939,6 +1939,80 @@ } } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.6.0.tgz", + "integrity": "sha512-pT08u5W/GT4KjPUmEtc2kSYvrH8x89cVzkA0Sy2aaOUIw6YxOIjA8ilwLr/1fLjOedX1QAuBpG9XggWqIIfERw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.6.0", + "@typescript-eslint/visitor-keys": "6.6.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.6.0.tgz", + "integrity": "sha512-CB6QpJQ6BAHlJXdwUmiaXDBmTqIE2bzGTDLADgvqtHWuhfNP3rAOK7kAgRMAET5rDRr9Utt+qAzRBdu3AhR3sg==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.6.0.tgz", + "integrity": "sha512-hMcTQ6Al8MP2E6JKBAaSxSVw5bDhdmbCEhGW/V8QXkb9oNsFkA4SBuOMYVPxD3jbtQ4R/vSODBsr76R6fP3tbA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.6.0", + "@typescript-eslint/visitor-keys": "6.6.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.6.0.tgz", + "integrity": "sha512-L61uJT26cMOfFQ+lMZKoJNbAEckLe539VhTxiGHrWl5XSKQgA0RTBZJW2HFPy5T0ZvPVSD93QsrTKDkfNwJGyQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.6.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.5.0.tgz", @@ -8614,16 +8688,59 @@ } }, "@typescript-eslint/parser": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.5.0.tgz", - "integrity": "sha512-LMAVtR5GN8nY0G0BadkG0XIe4AcNMeyEy3DyhKGAh9k4pLSMBO7rF29JvDBpZGCmp5Pgz5RLHP6eCpSYZJQDuQ==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.6.0.tgz", + "integrity": "sha512-setq5aJgUwtzGrhW177/i+DMLqBaJbdwGj2CPIVFFLE0NCliy5ujIdLHd2D1ysmlmsjdL2GWW+hR85neEfc12w==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "6.5.0", - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/typescript-estree": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0", + "@typescript-eslint/scope-manager": "6.6.0", + "@typescript-eslint/types": "6.6.0", + "@typescript-eslint/typescript-estree": "6.6.0", + "@typescript-eslint/visitor-keys": "6.6.0", "debug": "^4.3.4" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.6.0.tgz", + "integrity": "sha512-pT08u5W/GT4KjPUmEtc2kSYvrH8x89cVzkA0Sy2aaOUIw6YxOIjA8ilwLr/1fLjOedX1QAuBpG9XggWqIIfERw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.6.0", + "@typescript-eslint/visitor-keys": "6.6.0" + } + }, + "@typescript-eslint/types": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.6.0.tgz", + "integrity": "sha512-CB6QpJQ6BAHlJXdwUmiaXDBmTqIE2bzGTDLADgvqtHWuhfNP3rAOK7kAgRMAET5rDRr9Utt+qAzRBdu3AhR3sg==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.6.0.tgz", + "integrity": "sha512-hMcTQ6Al8MP2E6JKBAaSxSVw5bDhdmbCEhGW/V8QXkb9oNsFkA4SBuOMYVPxD3jbtQ4R/vSODBsr76R6fP3tbA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.6.0", + "@typescript-eslint/visitor-keys": "6.6.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.6.0.tgz", + "integrity": "sha512-L61uJT26cMOfFQ+lMZKoJNbAEckLe539VhTxiGHrWl5XSKQgA0RTBZJW2HFPy5T0ZvPVSD93QsrTKDkfNwJGyQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.6.0", + "eslint-visitor-keys": "^3.4.1" + } + } } }, "@typescript-eslint/scope-manager": { From 0e409f2c5f5dfec3a20181c90e82e6167f8a5111 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 17:45:37 -0700 Subject: [PATCH 0492/1076] build(deps-dev): bump @types/node from 20.5.9 to 20.6.0 in /stake-pool/js (#5238) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.5.9 to 20.6.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 127 ++-------------------------- 1 file changed, 6 insertions(+), 121 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 11091a49..1f8150e2 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1768,9 +1768,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.5.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.9.tgz", - "integrity": "sha512-PcGNd//40kHAS3sTlzKB9C9XL4K0sTup8nbG5lC14kzEteTNuAFh9u5nA0o5TWnSG2r/JNPRXFVcHJIIeRlmqQ==" + "version": "20.6.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.0.tgz", + "integrity": "sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg==" }, "node_modules/@types/node-fetch": { "version": "2.6.4", @@ -2013,23 +2013,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.5.0.tgz", - "integrity": "sha512-A8hZ7OlxURricpycp5kdPTH3XnjG85UpJS6Fn4VzeoH4T388gQJ/PGP4ole5NfKt4WDVhmLaQ/dBLNDC4Xl/Kw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/type-utils": { "version": "6.6.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.6.0.tgz", @@ -2114,46 +2097,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/types": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.5.0.tgz", - "integrity": "sha512-eqLLOEF5/lU8jW3Bw+8auf4lZSbbljHR2saKnYqON12G/WsJrGeeDHWuQePoEf9ro22+JkbPfWQwKEC5WwLQ3w==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.5.0.tgz", - "integrity": "sha512-q0rGwSe9e5Kk/XzliB9h2LBc9tmXX25G0833r7kffbl5437FPWb2tbpIV9wAATebC/018pGa9fwPDuvGN+LxWQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, "node_modules/@typescript-eslint/utils": { "version": "6.6.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.6.0.tgz", @@ -2253,23 +2196,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.5.0.tgz", - "integrity": "sha512-yCB/2wkbv3hPsh02ZS8dFQnij9VVQXJMN/gbQsaaY+zxALkZnxa/wagvLEFsAWMPv7d7lxQmNsIzGU1w/T/WyA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.5.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/abab": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", @@ -8579,9 +8505,9 @@ "dev": true }, "@types/node": { - "version": "20.5.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.9.tgz", - "integrity": "sha512-PcGNd//40kHAS3sTlzKB9C9XL4K0sTup8nbG5lC14kzEteTNuAFh9u5nA0o5TWnSG2r/JNPRXFVcHJIIeRlmqQ==" + "version": "20.6.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.0.tgz", + "integrity": "sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg==" }, "@types/node-fetch": { "version": "2.6.4", @@ -8743,16 +8669,6 @@ } } }, - "@typescript-eslint/scope-manager": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.5.0.tgz", - "integrity": "sha512-A8hZ7OlxURricpycp5kdPTH3XnjG85UpJS6Fn4VzeoH4T388gQJ/PGP4ole5NfKt4WDVhmLaQ/dBLNDC4Xl/Kw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0" - } - }, "@typescript-eslint/type-utils": { "version": "6.6.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.6.0.tgz", @@ -8798,27 +8714,6 @@ } } }, - "@typescript-eslint/types": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.5.0.tgz", - "integrity": "sha512-eqLLOEF5/lU8jW3Bw+8auf4lZSbbljHR2saKnYqON12G/WsJrGeeDHWuQePoEf9ro22+JkbPfWQwKEC5WwLQ3w==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.5.0.tgz", - "integrity": "sha512-q0rGwSe9e5Kk/XzliB9h2LBc9tmXX25G0833r7kffbl5437FPWb2tbpIV9wAATebC/018pGa9fwPDuvGN+LxWQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, "@typescript-eslint/utils": { "version": "6.6.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.6.0.tgz", @@ -8877,16 +8772,6 @@ } } }, - "@typescript-eslint/visitor-keys": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.5.0.tgz", - "integrity": "sha512-yCB/2wkbv3hPsh02ZS8dFQnij9VVQXJMN/gbQsaaY+zxALkZnxa/wagvLEFsAWMPv7d7lxQmNsIzGU1w/T/WyA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.5.0", - "eslint-visitor-keys": "^3.4.1" - } - }, "abab": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", From a1d1c4d49df48f15a10c01d1867a48f02e49e45d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Sep 2023 09:03:43 -0400 Subject: [PATCH 0493/1076] build(deps): bump serde_json from 1.0.105 to 1.0.106 (#5232) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.105 to 1.0.106. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.105...v1.0.106) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index b4cdccc3..1f39aa7c 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ borsh = "0.10" clap = "2.33.3" serde = "1.0.188" serde_derive = "1.0.130" -serde_json = "1.0.105" +serde_json = "1.0.106" solana-account-decoder = "=1.16.3" solana-clap-utils = "=1.16.3" solana-cli-config = "=1.16.3" From 77649d8c3b0d46dfbe15b383827daf58c6381d64 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Sep 2023 09:04:07 -0400 Subject: [PATCH 0494/1076] build(deps-dev): bump eslint from 8.48.0 to 8.49.0 in /stake-pool/js (#5239) Bumps [eslint](https://github.com/eslint/eslint) from 8.48.0 to 8.49.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.48.0...v8.49.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 44 ++++++++++++++--------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 1f8150e2..d26e6b63 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -717,18 +717,18 @@ } }, "node_modules/@eslint/js": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.48.0.tgz", - "integrity": "sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==", + "version": "8.49.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.49.0.tgz", + "integrity": "sha512-1S8uAY/MTJqVx0SC4epBq+N2yhuwtNwLbJYNZyhL2pO1ZVKn5HFXav5T41Ryzy9K9V7ZId2JB2oy/W4aCd9/2w==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", - "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", + "version": "0.11.11", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", + "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", @@ -3387,16 +3387,16 @@ } }, "node_modules/eslint": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.48.0.tgz", - "integrity": "sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==", + "version": "8.49.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.49.0.tgz", + "integrity": "sha512-jw03ENfm6VJI0jA9U+8H5zfl5b+FvuU3YYvZRdZHOlU2ggJkxrlkJH4HcDrZpj6YwD8kuYqvQM8LyesoazrSOQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.48.0", - "@humanwhocodes/config-array": "^0.11.10", + "@eslint/js": "8.49.0", + "@humanwhocodes/config-array": "^0.11.11", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.12.4", @@ -7725,15 +7725,15 @@ } }, "@eslint/js": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.48.0.tgz", - "integrity": "sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==", + "version": "8.49.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.49.0.tgz", + "integrity": "sha512-1S8uAY/MTJqVx0SC4epBq+N2yhuwtNwLbJYNZyhL2pO1ZVKn5HFXav5T41Ryzy9K9V7ZId2JB2oy/W4aCd9/2w==", "dev": true }, "@humanwhocodes/config-array": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", - "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", + "version": "0.11.11", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", + "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.1", @@ -9639,16 +9639,16 @@ } }, "eslint": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.48.0.tgz", - "integrity": "sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==", + "version": "8.49.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.49.0.tgz", + "integrity": "sha512-jw03ENfm6VJI0jA9U+8H5zfl5b+FvuU3YYvZRdZHOlU2ggJkxrlkJH4HcDrZpj6YwD8kuYqvQM8LyesoazrSOQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.48.0", - "@humanwhocodes/config-array": "^0.11.10", + "@eslint/js": "8.49.0", + "@humanwhocodes/config-array": "^0.11.11", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.12.4", From f15fdb5715ddddab1cb7af6b7fee84e9928fd092 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Sep 2023 09:05:02 -0400 Subject: [PATCH 0495/1076] build(deps): bump @solana/web3.js from 1.78.4 to 1.78.5 in /stake-pool/js (#5249) build(deps): bump @solana/web3.js in /stake-pool/js Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.78.4 to 1.78.5. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.78.4...v1.78.5) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index d26e6b63..cd57b154 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1613,9 +1613,9 @@ } }, "node_modules/@solana/web3.js": { - "version": "1.78.4", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.78.4.tgz", - "integrity": "sha512-up5VG1dK+GPhykmuMIozJZBbVqpm77vbOG6/r5dS7NBGZonwHfTLdBbsYc3rjmaQ4DpCXUa3tUc4RZHRORvZrw==", + "version": "1.78.5", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.78.5.tgz", + "integrity": "sha512-2ZHsDNqkKdglJQrIvJ3p2DmgS3cGnary3VJyqt9C1SPrpAtLYzcElr3xyXJOznyQTU/8AMw+GoF11lFoKbicKg==", "dependencies": { "@babel/runtime": "^7.22.6", "@noble/curves": "^1.0.0", @@ -8357,9 +8357,9 @@ } }, "@solana/web3.js": { - "version": "1.78.4", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.78.4.tgz", - "integrity": "sha512-up5VG1dK+GPhykmuMIozJZBbVqpm77vbOG6/r5dS7NBGZonwHfTLdBbsYc3rjmaQ4DpCXUa3tUc4RZHRORvZrw==", + "version": "1.78.5", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.78.5.tgz", + "integrity": "sha512-2ZHsDNqkKdglJQrIvJ3p2DmgS3cGnary3VJyqt9C1SPrpAtLYzcElr3xyXJOznyQTU/8AMw+GoF11lFoKbicKg==", "requires": { "@babel/runtime": "^7.22.6", "@noble/curves": "^1.0.0", From c2bbaa3fd56c7630b47572ec707175640246ea2b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Sep 2023 11:10:03 -0400 Subject: [PATCH 0496/1076] build(deps-dev): bump @typescript-eslint/parser from 6.6.0 to 6.7.0 in /stake-pool/js (#5250) build(deps-dev): bump @typescript-eslint/parser in /stake-pool/js Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.6.0 to 6.7.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.7.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 236 ++++++++++++++-------------- 1 file changed, 117 insertions(+), 119 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index cd57b154..14ab013d 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1912,15 +1912,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.6.0.tgz", - "integrity": "sha512-setq5aJgUwtzGrhW177/i+DMLqBaJbdwGj2CPIVFFLE0NCliy5ujIdLHd2D1ysmlmsjdL2GWW+hR85neEfc12w==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.0.tgz", + "integrity": "sha512-jZKYwqNpNm5kzPVP5z1JXAuxjtl2uG+5NpaMocFPTNC2EdYIgbXIPImObOkhbONxtFTTdoZstLZefbaK+wXZng==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.6.0", - "@typescript-eslint/types": "6.6.0", - "@typescript-eslint/typescript-estree": "6.6.0", - "@typescript-eslint/visitor-keys": "6.6.0", + "@typescript-eslint/scope-manager": "6.7.0", + "@typescript-eslint/types": "6.7.0", + "@typescript-eslint/typescript-estree": "6.7.0", + "@typescript-eslint/visitor-keys": "6.7.0", "debug": "^4.3.4" }, "engines": { @@ -1939,14 +1939,33 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.0.tgz", + "integrity": "sha512-lAT1Uau20lQyjoLUQ5FUMSX/dS07qux9rYd5FGzKz/Kf8W8ccuvMyldb8hadHdK/qOI7aikvQWqulnEq2nCEYA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.7.0", + "@typescript-eslint/visitor-keys": "6.7.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.6.0.tgz", - "integrity": "sha512-pT08u5W/GT4KjPUmEtc2kSYvrH8x89cVzkA0Sy2aaOUIw6YxOIjA8ilwLr/1fLjOedX1QAuBpG9XggWqIIfERw==", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.6.0.tgz", + "integrity": "sha512-8m16fwAcEnQc69IpeDyokNO+D5spo0w1jepWWY2Q6y5ZKNuj5EhVQXjtVAeDDqvW6Yg7dhclbsz6rTtOvcwpHg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.6.0", - "@typescript-eslint/visitor-keys": "6.6.0" + "@typescript-eslint/typescript-estree": "6.6.0", + "@typescript-eslint/utils": "6.6.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -1954,9 +1973,17 @@ "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { "version": "6.6.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.6.0.tgz", "integrity": "sha512-CB6QpJQ6BAHlJXdwUmiaXDBmTqIE2bzGTDLADgvqtHWuhfNP3rAOK7kAgRMAET5rDRr9Utt+qAzRBdu3AhR3sg==", @@ -1969,7 +1996,7 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { "version": "6.6.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.6.0.tgz", "integrity": "sha512-hMcTQ6Al8MP2E6JKBAaSxSVw5bDhdmbCEhGW/V8QXkb9oNsFkA4SBuOMYVPxD3jbtQ4R/vSODBsr76R6fP3tbA==", @@ -1996,7 +2023,7 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { "version": "6.6.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.6.0.tgz", "integrity": "sha512-L61uJT26cMOfFQ+lMZKoJNbAEckLe539VhTxiGHrWl5XSKQgA0RTBZJW2HFPy5T0ZvPVSD93QsrTKDkfNwJGyQ==", @@ -2013,37 +2040,10 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/type-utils": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.6.0.tgz", - "integrity": "sha512-8m16fwAcEnQc69IpeDyokNO+D5spo0w1jepWWY2Q6y5ZKNuj5EhVQXjtVAeDDqvW6Yg7dhclbsz6rTtOvcwpHg==", - "dev": true, - "dependencies": { - "@typescript-eslint/typescript-estree": "6.6.0", - "@typescript-eslint/utils": "6.6.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.6.0.tgz", - "integrity": "sha512-CB6QpJQ6BAHlJXdwUmiaXDBmTqIE2bzGTDLADgvqtHWuhfNP3rAOK7kAgRMAET5rDRr9Utt+qAzRBdu3AhR3sg==", + "node_modules/@typescript-eslint/types": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.0.tgz", + "integrity": "sha512-ihPfvOp7pOcN/ysoj0RpBPOx3HQTJTrIN8UZK+WFd3/iDeFHHqeyYxa4hQk4rMhsz9H9mXpR61IzwlBVGXtl9Q==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -2053,14 +2053,14 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.6.0.tgz", - "integrity": "sha512-hMcTQ6Al8MP2E6JKBAaSxSVw5bDhdmbCEhGW/V8QXkb9oNsFkA4SBuOMYVPxD3jbtQ4R/vSODBsr76R6fP3tbA==", + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.0.tgz", + "integrity": "sha512-dPvkXj3n6e9yd/0LfojNU8VMUGHWiLuBZvbM6V6QYD+2qxqInE7J+J/ieY2iGwR9ivf/R/haWGkIj04WVUeiSQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.6.0", - "@typescript-eslint/visitor-keys": "6.6.0", + "@typescript-eslint/types": "6.7.0", + "@typescript-eslint/visitor-keys": "6.7.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2080,23 +2080,6 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.6.0.tgz", - "integrity": "sha512-L61uJT26cMOfFQ+lMZKoJNbAEckLe539VhTxiGHrWl5XSKQgA0RTBZJW2HFPy5T0ZvPVSD93QsrTKDkfNwJGyQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.6.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/utils": { "version": "6.6.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.6.0.tgz", @@ -2196,6 +2179,23 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.0.tgz", + "integrity": "sha512-/C1RVgKFDmGMcVGeD8HjKv2bd72oI1KxQDeY8uc66gw9R0OK0eMq48cA+jv9/2Ag6cdrsUGySm1yzYmfz0hxwQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.7.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/abab": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", @@ -8614,59 +8614,26 @@ } }, "@typescript-eslint/parser": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.6.0.tgz", - "integrity": "sha512-setq5aJgUwtzGrhW177/i+DMLqBaJbdwGj2CPIVFFLE0NCliy5ujIdLHd2D1ysmlmsjdL2GWW+hR85neEfc12w==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.0.tgz", + "integrity": "sha512-jZKYwqNpNm5kzPVP5z1JXAuxjtl2uG+5NpaMocFPTNC2EdYIgbXIPImObOkhbONxtFTTdoZstLZefbaK+wXZng==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "6.6.0", - "@typescript-eslint/types": "6.6.0", - "@typescript-eslint/typescript-estree": "6.6.0", - "@typescript-eslint/visitor-keys": "6.6.0", + "@typescript-eslint/scope-manager": "6.7.0", + "@typescript-eslint/types": "6.7.0", + "@typescript-eslint/typescript-estree": "6.7.0", + "@typescript-eslint/visitor-keys": "6.7.0", "debug": "^4.3.4" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.6.0.tgz", - "integrity": "sha512-pT08u5W/GT4KjPUmEtc2kSYvrH8x89cVzkA0Sy2aaOUIw6YxOIjA8ilwLr/1fLjOedX1QAuBpG9XggWqIIfERw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.6.0", - "@typescript-eslint/visitor-keys": "6.6.0" - } - }, - "@typescript-eslint/types": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.6.0.tgz", - "integrity": "sha512-CB6QpJQ6BAHlJXdwUmiaXDBmTqIE2bzGTDLADgvqtHWuhfNP3rAOK7kAgRMAET5rDRr9Utt+qAzRBdu3AhR3sg==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.6.0.tgz", - "integrity": "sha512-hMcTQ6Al8MP2E6JKBAaSxSVw5bDhdmbCEhGW/V8QXkb9oNsFkA4SBuOMYVPxD3jbtQ4R/vSODBsr76R6fP3tbA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.6.0", - "@typescript-eslint/visitor-keys": "6.6.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.6.0.tgz", - "integrity": "sha512-L61uJT26cMOfFQ+lMZKoJNbAEckLe539VhTxiGHrWl5XSKQgA0RTBZJW2HFPy5T0ZvPVSD93QsrTKDkfNwJGyQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.6.0", - "eslint-visitor-keys": "^3.4.1" - } - } + } + }, + "@typescript-eslint/scope-manager": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.0.tgz", + "integrity": "sha512-lAT1Uau20lQyjoLUQ5FUMSX/dS07qux9rYd5FGzKz/Kf8W8ccuvMyldb8hadHdK/qOI7aikvQWqulnEq2nCEYA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.7.0", + "@typescript-eslint/visitor-keys": "6.7.0" } }, "@typescript-eslint/type-utils": { @@ -8714,6 +8681,27 @@ } } }, + "@typescript-eslint/types": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.0.tgz", + "integrity": "sha512-ihPfvOp7pOcN/ysoj0RpBPOx3HQTJTrIN8UZK+WFd3/iDeFHHqeyYxa4hQk4rMhsz9H9mXpR61IzwlBVGXtl9Q==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.0.tgz", + "integrity": "sha512-dPvkXj3n6e9yd/0LfojNU8VMUGHWiLuBZvbM6V6QYD+2qxqInE7J+J/ieY2iGwR9ivf/R/haWGkIj04WVUeiSQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.7.0", + "@typescript-eslint/visitor-keys": "6.7.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, "@typescript-eslint/utils": { "version": "6.6.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.6.0.tgz", @@ -8772,6 +8760,16 @@ } } }, + "@typescript-eslint/visitor-keys": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.0.tgz", + "integrity": "sha512-/C1RVgKFDmGMcVGeD8HjKv2bd72oI1KxQDeY8uc66gw9R0OK0eMq48cA+jv9/2Ag6cdrsUGySm1yzYmfz0hxwQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.7.0", + "eslint-visitor-keys": "^3.4.1" + } + }, "abab": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", From abff9b623f13fb71fd0393b44be666747014e27f Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 13 Sep 2023 17:27:50 +0200 Subject: [PATCH 0497/1076] stake-pool-js: Bump to 0.7.0 to release (#5269) --- clients/js-legacy/package-lock.json | 4 ++-- clients/js-legacy/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 14ab013d..f29572ca 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1,12 +1,12 @@ { "name": "@solana/spl-stake-pool", - "version": "0.6.5", + "version": "0.7.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@solana/spl-stake-pool", - "version": "0.6.5", + "version": "0.7.0", "license": "ISC", "dependencies": { "@coral-xyz/borsh": "^0.28.0", diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 512b088f..61d8bcad 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-stake-pool", - "version": "0.6.5", + "version": "0.7.0", "description": "SPL Stake Pool Program JS API", "scripts": { "build": "npm run clean && tsc && cross-env NODE_ENV=production rollup -c", From a6b7477145176e4e38ba2784063730f8c87ea62d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Sep 2023 12:01:14 +0200 Subject: [PATCH 0498/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.6.0 to 6.7.0 in /stake-pool/js (#5266) build(deps-dev): bump @typescript-eslint/eslint-plugin in /stake-pool/js Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.6.0 to 6.7.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.7.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 354 +++------------------------- 1 file changed, 36 insertions(+), 318 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index f29572ca..c3936107 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1830,16 +1830,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.6.0.tgz", - "integrity": "sha512-CW9YDGTQnNYMIo5lMeuiIG08p4E0cXrXTbcZ2saT/ETE7dWUrNxlijsQeU04qAAKkILiLzdQz+cGFxCJjaZUmA==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.0.tgz", + "integrity": "sha512-gUqtknHm0TDs1LhY12K2NA3Rmlmp88jK9Tx8vGZMfHeNMLE3GH2e9TRub+y+SOjuYgtOmok+wt1AyDPZqxbNag==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.6.0", - "@typescript-eslint/type-utils": "6.6.0", - "@typescript-eslint/utils": "6.6.0", - "@typescript-eslint/visitor-keys": "6.6.0", + "@typescript-eslint/scope-manager": "6.7.0", + "@typescript-eslint/type-utils": "6.7.0", + "@typescript-eslint/utils": "6.7.0", + "@typescript-eslint/visitor-keys": "6.7.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -1864,53 +1864,6 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.6.0.tgz", - "integrity": "sha512-pT08u5W/GT4KjPUmEtc2kSYvrH8x89cVzkA0Sy2aaOUIw6YxOIjA8ilwLr/1fLjOedX1QAuBpG9XggWqIIfERw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.6.0", - "@typescript-eslint/visitor-keys": "6.6.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.6.0.tgz", - "integrity": "sha512-CB6QpJQ6BAHlJXdwUmiaXDBmTqIE2bzGTDLADgvqtHWuhfNP3rAOK7kAgRMAET5rDRr9Utt+qAzRBdu3AhR3sg==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.6.0.tgz", - "integrity": "sha512-L61uJT26cMOfFQ+lMZKoJNbAEckLe539VhTxiGHrWl5XSKQgA0RTBZJW2HFPy5T0ZvPVSD93QsrTKDkfNwJGyQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.6.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/parser": { "version": "6.7.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.0.tgz", @@ -1957,13 +1910,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.6.0.tgz", - "integrity": "sha512-8m16fwAcEnQc69IpeDyokNO+D5spo0w1jepWWY2Q6y5ZKNuj5EhVQXjtVAeDDqvW6Yg7dhclbsz6rTtOvcwpHg==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.0.tgz", + "integrity": "sha512-f/QabJgDAlpSz3qduCyQT0Fw7hHpmhOzY/Rv6zO3yO+HVIdPfIWhrQoAyG+uZVtWAIS85zAyzgAFfyEr+MgBpg==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.6.0", - "@typescript-eslint/utils": "6.6.0", + "@typescript-eslint/typescript-estree": "6.7.0", + "@typescript-eslint/utils": "6.7.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -1983,63 +1936,6 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.6.0.tgz", - "integrity": "sha512-CB6QpJQ6BAHlJXdwUmiaXDBmTqIE2bzGTDLADgvqtHWuhfNP3rAOK7kAgRMAET5rDRr9Utt+qAzRBdu3AhR3sg==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.6.0.tgz", - "integrity": "sha512-hMcTQ6Al8MP2E6JKBAaSxSVw5bDhdmbCEhGW/V8QXkb9oNsFkA4SBuOMYVPxD3jbtQ4R/vSODBsr76R6fP3tbA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.6.0", - "@typescript-eslint/visitor-keys": "6.6.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.6.0.tgz", - "integrity": "sha512-L61uJT26cMOfFQ+lMZKoJNbAEckLe539VhTxiGHrWl5XSKQgA0RTBZJW2HFPy5T0ZvPVSD93QsrTKDkfNwJGyQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.6.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/types": { "version": "6.7.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.0.tgz", @@ -2081,17 +1977,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.6.0.tgz", - "integrity": "sha512-mPHFoNa2bPIWWglWYdR0QfY9GN0CfvvXX1Sv6DlSTive3jlMTUy+an67//Gysc+0Me9pjitrq0LJp0nGtLgftw==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.0.tgz", + "integrity": "sha512-MfCq3cM0vh2slSikQYqK2Gq52gvOhe57vD2RM3V4gQRZYX4rDPnKLu5p6cm89+LJiGlwEXU8hkYxhqqEC/V3qA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.6.0", - "@typescript-eslint/types": "6.6.0", - "@typescript-eslint/typescript-estree": "6.6.0", + "@typescript-eslint/scope-manager": "6.7.0", + "@typescript-eslint/types": "6.7.0", + "@typescript-eslint/typescript-estree": "6.7.0", "semver": "^7.5.4" }, "engines": { @@ -2105,80 +2001,6 @@ "eslint": "^7.0.0 || ^8.0.0" } }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.6.0.tgz", - "integrity": "sha512-pT08u5W/GT4KjPUmEtc2kSYvrH8x89cVzkA0Sy2aaOUIw6YxOIjA8ilwLr/1fLjOedX1QAuBpG9XggWqIIfERw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.6.0", - "@typescript-eslint/visitor-keys": "6.6.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.6.0.tgz", - "integrity": "sha512-CB6QpJQ6BAHlJXdwUmiaXDBmTqIE2bzGTDLADgvqtHWuhfNP3rAOK7kAgRMAET5rDRr9Utt+qAzRBdu3AhR3sg==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.6.0.tgz", - "integrity": "sha512-hMcTQ6Al8MP2E6JKBAaSxSVw5bDhdmbCEhGW/V8QXkb9oNsFkA4SBuOMYVPxD3jbtQ4R/vSODBsr76R6fP3tbA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.6.0", - "@typescript-eslint/visitor-keys": "6.6.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.6.0.tgz", - "integrity": "sha512-L61uJT26cMOfFQ+lMZKoJNbAEckLe539VhTxiGHrWl5XSKQgA0RTBZJW2HFPy5T0ZvPVSD93QsrTKDkfNwJGyQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.6.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/visitor-keys": { "version": "6.7.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.0.tgz", @@ -8567,50 +8389,22 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.6.0.tgz", - "integrity": "sha512-CW9YDGTQnNYMIo5lMeuiIG08p4E0cXrXTbcZ2saT/ETE7dWUrNxlijsQeU04qAAKkILiLzdQz+cGFxCJjaZUmA==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.0.tgz", + "integrity": "sha512-gUqtknHm0TDs1LhY12K2NA3Rmlmp88jK9Tx8vGZMfHeNMLE3GH2e9TRub+y+SOjuYgtOmok+wt1AyDPZqxbNag==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.6.0", - "@typescript-eslint/type-utils": "6.6.0", - "@typescript-eslint/utils": "6.6.0", - "@typescript-eslint/visitor-keys": "6.6.0", + "@typescript-eslint/scope-manager": "6.7.0", + "@typescript-eslint/type-utils": "6.7.0", + "@typescript-eslint/utils": "6.7.0", + "@typescript-eslint/visitor-keys": "6.7.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", "natural-compare": "^1.4.0", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.6.0.tgz", - "integrity": "sha512-pT08u5W/GT4KjPUmEtc2kSYvrH8x89cVzkA0Sy2aaOUIw6YxOIjA8ilwLr/1fLjOedX1QAuBpG9XggWqIIfERw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.6.0", - "@typescript-eslint/visitor-keys": "6.6.0" - } - }, - "@typescript-eslint/types": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.6.0.tgz", - "integrity": "sha512-CB6QpJQ6BAHlJXdwUmiaXDBmTqIE2bzGTDLADgvqtHWuhfNP3rAOK7kAgRMAET5rDRr9Utt+qAzRBdu3AhR3sg==", - "dev": true - }, - "@typescript-eslint/visitor-keys": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.6.0.tgz", - "integrity": "sha512-L61uJT26cMOfFQ+lMZKoJNbAEckLe539VhTxiGHrWl5XSKQgA0RTBZJW2HFPy5T0ZvPVSD93QsrTKDkfNwJGyQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.6.0", - "eslint-visitor-keys": "^3.4.1" - } - } } }, "@typescript-eslint/parser": { @@ -8637,48 +8431,15 @@ } }, "@typescript-eslint/type-utils": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.6.0.tgz", - "integrity": "sha512-8m16fwAcEnQc69IpeDyokNO+D5spo0w1jepWWY2Q6y5ZKNuj5EhVQXjtVAeDDqvW6Yg7dhclbsz6rTtOvcwpHg==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.0.tgz", + "integrity": "sha512-f/QabJgDAlpSz3qduCyQT0Fw7hHpmhOzY/Rv6zO3yO+HVIdPfIWhrQoAyG+uZVtWAIS85zAyzgAFfyEr+MgBpg==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "6.6.0", - "@typescript-eslint/utils": "6.6.0", + "@typescript-eslint/typescript-estree": "6.7.0", + "@typescript-eslint/utils": "6.7.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" - }, - "dependencies": { - "@typescript-eslint/types": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.6.0.tgz", - "integrity": "sha512-CB6QpJQ6BAHlJXdwUmiaXDBmTqIE2bzGTDLADgvqtHWuhfNP3rAOK7kAgRMAET5rDRr9Utt+qAzRBdu3AhR3sg==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.6.0.tgz", - "integrity": "sha512-hMcTQ6Al8MP2E6JKBAaSxSVw5bDhdmbCEhGW/V8QXkb9oNsFkA4SBuOMYVPxD3jbtQ4R/vSODBsr76R6fP3tbA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.6.0", - "@typescript-eslint/visitor-keys": "6.6.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.6.0.tgz", - "integrity": "sha512-L61uJT26cMOfFQ+lMZKoJNbAEckLe539VhTxiGHrWl5XSKQgA0RTBZJW2HFPy5T0ZvPVSD93QsrTKDkfNwJGyQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.6.0", - "eslint-visitor-keys": "^3.4.1" - } - } } }, "@typescript-eslint/types": { @@ -8703,61 +8464,18 @@ } }, "@typescript-eslint/utils": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.6.0.tgz", - "integrity": "sha512-mPHFoNa2bPIWWglWYdR0QfY9GN0CfvvXX1Sv6DlSTive3jlMTUy+an67//Gysc+0Me9pjitrq0LJp0nGtLgftw==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.0.tgz", + "integrity": "sha512-MfCq3cM0vh2slSikQYqK2Gq52gvOhe57vD2RM3V4gQRZYX4rDPnKLu5p6cm89+LJiGlwEXU8hkYxhqqEC/V3qA==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.6.0", - "@typescript-eslint/types": "6.6.0", - "@typescript-eslint/typescript-estree": "6.6.0", + "@typescript-eslint/scope-manager": "6.7.0", + "@typescript-eslint/types": "6.7.0", + "@typescript-eslint/typescript-estree": "6.7.0", "semver": "^7.5.4" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.6.0.tgz", - "integrity": "sha512-pT08u5W/GT4KjPUmEtc2kSYvrH8x89cVzkA0Sy2aaOUIw6YxOIjA8ilwLr/1fLjOedX1QAuBpG9XggWqIIfERw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.6.0", - "@typescript-eslint/visitor-keys": "6.6.0" - } - }, - "@typescript-eslint/types": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.6.0.tgz", - "integrity": "sha512-CB6QpJQ6BAHlJXdwUmiaXDBmTqIE2bzGTDLADgvqtHWuhfNP3rAOK7kAgRMAET5rDRr9Utt+qAzRBdu3AhR3sg==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.6.0.tgz", - "integrity": "sha512-hMcTQ6Al8MP2E6JKBAaSxSVw5bDhdmbCEhGW/V8QXkb9oNsFkA4SBuOMYVPxD3jbtQ4R/vSODBsr76R6fP3tbA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.6.0", - "@typescript-eslint/visitor-keys": "6.6.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.6.0.tgz", - "integrity": "sha512-L61uJT26cMOfFQ+lMZKoJNbAEckLe539VhTxiGHrWl5XSKQgA0RTBZJW2HFPy5T0ZvPVSD93QsrTKDkfNwJGyQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.6.0", - "eslint-visitor-keys": "^3.4.1" - } - } } }, "@typescript-eslint/visitor-keys": { From 2b14a6bb0954de309a41d785f6ea062e80838f39 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Sep 2023 12:01:58 +0200 Subject: [PATCH 0499/1076] build(deps): bump serde_json from 1.0.106 to 1.0.107 (#5275) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.106 to 1.0.107. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.106...v1.0.107) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 1f39aa7c..532e9568 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ borsh = "0.10" clap = "2.33.3" serde = "1.0.188" serde_derive = "1.0.130" -serde_json = "1.0.106" +serde_json = "1.0.107" solana-account-decoder = "=1.16.3" solana-clap-utils = "=1.16.3" solana-cli-config = "=1.16.3" From 9baf7483ab618e0606ca9704fdf27c4d37954941 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 14 Sep 2023 13:28:12 +0200 Subject: [PATCH 0500/1076] stake-pool: Add error logging during test failures (#5278) --- program/tests/decrease.rs | 10 +++--- program/tests/deposit.rs | 6 ++-- program/tests/deposit_authority.rs | 2 +- program/tests/deposit_edge_cases.rs | 2 +- program/tests/deposit_sol.rs | 8 ++--- program/tests/force_destake.rs | 2 +- program/tests/helpers/mod.rs | 6 ++-- program/tests/huge_pool.rs | 32 ++++++++--------- program/tests/increase.rs | 10 +++--- program/tests/redelegate.rs | 10 +++--- program/tests/set_preferred.rs | 12 +++---- program/tests/set_withdrawal_fee.rs | 2 +- program/tests/update_stake_pool_balance.rs | 8 ++--- .../tests/update_validator_list_balance.rs | 22 ++++++------ .../update_validator_list_balance_hijack.rs | 14 ++++---- program/tests/vsa_add.rs | 6 ++-- program/tests/vsa_remove.rs | 34 +++++++++---------- program/tests/withdraw.rs | 6 ++-- program/tests/withdraw_edge_cases.rs | 26 +++++++------- program/tests/withdraw_sol.rs | 10 +++--- program/tests/withdraw_with_fee.rs | 4 +-- 21 files changed, 116 insertions(+), 116 deletions(-) diff --git a/program/tests/decrease.rs b/program/tests/decrease.rs index 802ecf65..e20e752e 100644 --- a/program/tests/decrease.rs +++ b/program/tests/decrease.rs @@ -108,7 +108,7 @@ async fn success(use_additional_instruction: bool) { use_additional_instruction, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // Check validator stake account balance let validator_stake_account = @@ -291,7 +291,7 @@ async fn fail_twice_diff_seed(use_additional_instruction: bool) { use_additional_instruction, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let transient_stake_seed = validator_stake.transient_stake_seed * 100; let transient_stake_address = find_transient_stake_program_address( @@ -358,7 +358,7 @@ async fn twice(success: bool, use_additional_first_time: bool, use_additional_se use_additional_first_time, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let error = stake_pool_accounts .decrease_validator_stake_either( @@ -374,7 +374,7 @@ async fn twice(success: bool, use_additional_first_time: bool, use_additional_se .await; if success { - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // no ephemeral account let ephemeral_stake = find_ephemeral_stake_program_address( &id(), @@ -565,7 +565,7 @@ async fn fail_additional_with_increasing() { validator_stake.transient_stake_seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let error = stake_pool_accounts .decrease_validator_stake_either( diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 929774cc..61c0222d 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -182,7 +182,7 @@ async fn success(token_program_id: Pubkey) { &user, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // Original stake account should be drained assert!(context @@ -355,7 +355,7 @@ async fn success_with_extra_stake_lamports() { &referrer_token_account.pubkey(), ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // Original stake account should be drained assert!(context @@ -875,7 +875,7 @@ async fn success_with_slippage(token_program_id: Pubkey) { tokens_issued_user, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // Original stake account should be drained assert!(context diff --git a/program/tests/deposit_authority.rs b/program/tests/deposit_authority.rs index 8e44178a..c0e4aaee 100644 --- a/program/tests/deposit_authority.rs +++ b/program/tests/deposit_authority.rs @@ -120,7 +120,7 @@ async fn success_deposit() { &user, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); } #[tokio::test] diff --git a/program/tests/deposit_edge_cases.rs b/program/tests/deposit_edge_cases.rs index a1312bb8..df9bd30d 100644 --- a/program/tests/deposit_edge_cases.rs +++ b/program/tests/deposit_edge_cases.rs @@ -151,7 +151,7 @@ async fn success_with_preferred_deposit() { &user, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); } #[tokio::test] diff --git a/program/tests/deposit_sol.rs b/program/tests/deposit_sol.rs index 5d390f00..90dd6c96 100644 --- a/program/tests/deposit_sol.rs +++ b/program/tests/deposit_sol.rs @@ -98,7 +98,7 @@ async fn success(token_program_id: Pubkey) { None, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let tokens_issued = TEST_STAKE_AMOUNT; // For now tokens are 1:1 to stake @@ -309,7 +309,7 @@ async fn success_with_sol_deposit_authority() { None, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let sol_deposit_authority = Keypair::new(); @@ -336,7 +336,7 @@ async fn success_with_sol_deposit_authority() { Some(&sol_deposit_authority), ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); } #[tokio::test] @@ -569,7 +569,7 @@ async fn success_with_slippage(token_program_id: Pubkey) { tokens_issued, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // Stake pool should add its balance to the pool balance let post_stake_pool = get_account( diff --git a/program/tests/force_destake.rs b/program/tests/force_destake.rs index 32fc8ff7..13ef7c72 100644 --- a/program/tests/force_destake.rs +++ b/program/tests/force_destake.rs @@ -146,7 +146,7 @@ async fn success_update() { false, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let post_reserve_lamports = context .banks_client .get_account(stake_pool_accounts.reserve_stake.pubkey()) diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 36f48fb6..3b9bd42e 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -2085,7 +2085,7 @@ pub async fn simple_add_validator_to_pool( sol_deposit_authority, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); create_vote( banks_client, @@ -2106,7 +2106,7 @@ pub async fn simple_add_validator_to_pool( validator_stake.validator_stake_seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); validator_stake } @@ -2207,7 +2207,7 @@ impl DepositStakeAccount { ) .await; self.pool_tokens = get_token_balance(banks_client, &self.pool_account.pubkey()).await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); } } diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index 5c58cecf..a4adb5f6 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -184,7 +184,7 @@ async fn update(max_validators: u32) { false, /* no_merge */ ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let error = stake_pool_accounts .update_stake_pool_balance( @@ -193,7 +193,7 @@ async fn update(max_validators: u32) { &context.last_blockhash, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let error = stake_pool_accounts .cleanup_removed_validator_entries( @@ -202,7 +202,7 @@ async fn update(max_validators: u32) { &context.last_blockhash, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); } //#[test_case(MAX_POOL_SIZE_WITH_REQUESTED_COMPUTE_UNITS; "compute-budget")] @@ -236,7 +236,7 @@ async fn remove_validator_from_pool(max_validators: u32) { &transient_stake_address, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let middle_index = max_validators as usize / 2; let middle_vote = vote_account_pubkeys[middle_index]; @@ -262,7 +262,7 @@ async fn remove_validator_from_pool(max_validators: u32) { &transient_stake_address, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let last_index = max_validators as usize - 1; let last_vote = vote_account_pubkeys[last_index]; @@ -288,7 +288,7 @@ async fn remove_validator_from_pool(max_validators: u32) { &transient_stake_address, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let validator_list = get_account( &mut context.banks_client, @@ -330,7 +330,7 @@ async fn remove_validator_from_pool(max_validators: u32) { false, /* no_merge */ ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let mut instructions = vec![instruction::update_validator_list_balance( &id(), @@ -355,7 +355,7 @@ async fn remove_validator_from_pool(max_validators: u32) { .process_transaction(transaction) .await .err(); - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let mut instructions = vec![instruction::update_validator_list_balance( &id(), @@ -380,7 +380,7 @@ async fn remove_validator_from_pool(max_validators: u32) { .process_transaction(transaction) .await .err(); - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let error = stake_pool_accounts .cleanup_removed_validator_entries( @@ -389,7 +389,7 @@ async fn remove_validator_from_pool(max_validators: u32) { &context.last_blockhash, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let validator_list = get_account( &mut context.banks_client, @@ -454,7 +454,7 @@ async fn add_validator_to_pool(max_validators: u32) { None, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let validator_list = get_account( &mut context.banks_client, @@ -531,7 +531,7 @@ async fn set_preferred(max_validators: u32) { Some(vote_account_address), ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let error = stake_pool_accounts .set_preferred_validator( &mut context.banks_client, @@ -541,7 +541,7 @@ async fn set_preferred(max_validators: u32) { Some(vote_account_address), ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let stake_pool = get_account( &mut context.banks_client, @@ -585,7 +585,7 @@ async fn deposit_stake(max_validators: u32) { &user, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); } #[test_case(MAX_POOL_SIZE_WITH_REQUESTED_COMPUTE_UNITS; "compute-budget")] @@ -613,7 +613,7 @@ async fn withdraw(max_validators: u32) { &user, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // Create stake account to withdraw to let user_stake_recipient = Keypair::new(); @@ -695,5 +695,5 @@ async fn cleanup_all(max_validators: u32) { &context.last_blockhash, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); } diff --git a/program/tests/increase.rs b/program/tests/increase.rs index 3e15a7b2..b42dd789 100644 --- a/program/tests/increase.rs +++ b/program/tests/increase.rs @@ -113,7 +113,7 @@ async fn success(use_additional_instruction: bool) { use_additional_instruction, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // Check reserve stake account balance let reserve_stake_account = get_account( @@ -298,7 +298,7 @@ async fn fail_twice_diff_seed(use_additional_instruction: bool) { use_additional_instruction, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let transient_stake_seed = validator_stake.transient_stake_seed * 100; let transient_stake_address = find_transient_stake_program_address( @@ -370,7 +370,7 @@ async fn twice(success: bool, use_additional_first_time: bool, use_additional_se use_additional_first_time, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let error = stake_pool_accounts .increase_validator_stake_either( @@ -387,7 +387,7 @@ async fn twice(success: bool, use_additional_first_time: bool, use_additional_se .await; if success { - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); // no ephemeral account @@ -563,7 +563,7 @@ async fn fail_additional_with_decreasing() { validator_stake.transient_stake_seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let error = stake_pool_accounts .increase_validator_stake_either( diff --git a/program/tests/redelegate.rs b/program/tests/redelegate.rs index eec2eff9..5645baf8 100644 --- a/program/tests/redelegate.rs +++ b/program/tests/redelegate.rs @@ -176,7 +176,7 @@ async fn success() { destination_validator_stake.transient_stake_seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // Check validator stake account balance let validator_stake_account = get_account( @@ -377,7 +377,7 @@ async fn success_with_increasing_stake() { destination_validator_stake.transient_stake_seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let validator_list = stake_pool_accounts .get_validator_list(&mut context.banks_client) @@ -467,7 +467,7 @@ async fn success_with_increasing_stake() { destination_validator_stake.transient_stake_seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // Check destination transient stake account let destination_transient_stake_account = get_account( @@ -624,7 +624,7 @@ async fn fail_with_decreasing_stake() { destination_validator_stake.transient_stake_seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let ephemeral_stake_seed = 20; let ephemeral_stake = find_ephemeral_stake_program_address( @@ -993,7 +993,7 @@ async fn fail_redelegate_twice() { destination_validator_stake.transient_stake_seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let last_blockhash = context .banks_client diff --git a/program/tests/set_preferred.rs b/program/tests/set_preferred.rs index 8c280277..04de8196 100644 --- a/program/tests/set_preferred.rs +++ b/program/tests/set_preferred.rs @@ -74,7 +74,7 @@ async fn success_deposit() { Some(vote_account_address), ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); @@ -102,7 +102,7 @@ async fn success_withdraw() { Some(vote_account_address), ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); @@ -129,7 +129,7 @@ async fn success_unset() { Some(vote_account_address), ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); @@ -148,7 +148,7 @@ async fn success_unset() { None, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let stake_pool = get_account(&mut banks_client, &stake_pool_accounts.stake_pool.pubkey()).await; let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); @@ -230,7 +230,7 @@ async fn fail_ready_for_removal() { &stake_pool_accounts.stake_pool.pubkey(), transient_stake_seed, ); - let remove_err = stake_pool_accounts + let error = stake_pool_accounts .remove_validator_from_pool( &mut banks_client, &payer, @@ -239,7 +239,7 @@ async fn fail_ready_for_removal() { &transient_stake_address, ) .await; - assert!(remove_err.is_none()); + assert!(error.is_none(), "{:?}", error); let error = stake_pool_accounts .set_preferred_validator( diff --git a/program/tests/set_withdrawal_fee.rs b/program/tests/set_withdrawal_fee.rs index e0e2075f..6f0afe68 100644 --- a/program/tests/set_withdrawal_fee.rs +++ b/program/tests/set_withdrawal_fee.rs @@ -350,7 +350,7 @@ async fn success_fee_cannot_increase_more_than_once() { &context.last_blockhash, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // Check that nothing has changed after updating the stake pool let stake_pool = get_account( diff --git a/program/tests/update_stake_pool_balance.rs b/program/tests/update_stake_pool_balance.rs index 388ea98b..763c7a80 100644 --- a/program/tests/update_stake_pool_balance.rs +++ b/program/tests/update_stake_pool_balance.rs @@ -60,7 +60,7 @@ async fn setup( None, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let mut last_blockhash = context .banks_client @@ -95,7 +95,7 @@ async fn setup( stake_account.validator_stake_seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let mut deposit_account = DepositStakeAccount::new_with_vote( stake_account.vote.pubkey(), @@ -188,7 +188,7 @@ async fn success() { false, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // Check fee let post_balance = get_validator_list_sum( @@ -301,7 +301,7 @@ async fn success_absorbing_extra_lamports() { false, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // Check extra lamports are absorbed and fee'd as rewards let post_balance = get_validator_list_sum( diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index 181df916..97691a7e 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -74,7 +74,7 @@ async fn setup( stake_account.validator_stake_seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let deposit_account = DepositStakeAccount::new_with_vote( stake_account.vote.pubkey(), @@ -289,7 +289,7 @@ async fn merge_into_reserve() { stake_account.transient_stake_seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); } println!("Update, should not change, no merges yet"); @@ -417,7 +417,7 @@ async fn merge_into_validator_stake() { stake_account.transient_stake_seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); } // Warp just a little bit to get a new blockhash and update again @@ -442,7 +442,7 @@ async fn merge_into_validator_stake() { false, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let expected_lamports = get_validator_list_sum( &mut context.banks_client, @@ -482,7 +482,7 @@ async fn merge_into_validator_stake() { false, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let current_lamports = get_validator_list_sum( &mut context.banks_client, &stake_pool_accounts.reserve_stake.pubkey(), @@ -564,7 +564,7 @@ async fn merge_transient_stake_after_remove() { stake_account.transient_stake_seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let error = stake_pool_accounts .remove_validator_from_pool( &mut context.banks_client, @@ -574,7 +574,7 @@ async fn merge_transient_stake_after_remove() { &stake_account.transient_stake_account, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); } // Warp forward to merge time @@ -596,7 +596,7 @@ async fn merge_transient_stake_after_remove() { true, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let validator_list = get_account( &mut context.banks_client, @@ -633,7 +633,7 @@ async fn merge_transient_stake_after_remove() { false, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // stake accounts were merged in, none exist anymore for stake_account in &stake_accounts { @@ -679,7 +679,7 @@ async fn merge_transient_stake_after_remove() { let error = stake_pool_accounts .update_stake_pool_balance(&mut context.banks_client, &context.payer, &last_blockhash) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let error = stake_pool_accounts .cleanup_removed_validator_entries( @@ -688,7 +688,7 @@ async fn merge_transient_stake_after_remove() { &last_blockhash, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let validator_list = get_account( &mut context.banks_client, diff --git a/program/tests/update_validator_list_balance_hijack.rs b/program/tests/update_validator_list_balance_hijack.rs index d7449984..6de06cf3 100644 --- a/program/tests/update_validator_list_balance_hijack.rs +++ b/program/tests/update_validator_list_balance_hijack.rs @@ -81,7 +81,7 @@ async fn setup( stake_account.validator_stake_seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let deposit_account = DepositStakeAccount::new_with_vote( stake_account.vote.pubkey(), @@ -230,7 +230,7 @@ async fn check_ignored_hijacked_transient_stake( stake_account.transient_stake_seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); println!("Warp one epoch so the stakes deactivate and merge"); let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; @@ -296,7 +296,7 @@ async fn check_ignored_hijacked_transient_stake( .process_transaction(transaction) .await .err(); - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); println!("Update again normally, should be no change in the lamports"); let last_blockhash = context @@ -394,7 +394,7 @@ async fn check_ignored_hijacked_validator_stake( stake_account.transient_stake_seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let error = stake_pool_accounts .remove_validator_from_pool( @@ -405,7 +405,7 @@ async fn check_ignored_hijacked_validator_stake( &stake_account.transient_stake_account, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); println!("Warp one epoch so the stakes deactivate and merge"); let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; @@ -464,7 +464,7 @@ async fn check_ignored_hijacked_validator_stake( .process_transaction(transaction) .await .err(); - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); println!("Update again normally, should be no change in the lamports"); let last_blockhash = context @@ -542,7 +542,7 @@ async fn check_ignored_hijacked_validator_stake( seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let stake_pool_info = get_account( &mut context.banks_client, diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index aac22d66..e83a6628 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -88,7 +88,7 @@ async fn success() { validator_stake.validator_stake_seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // Check if validator account was added to the list let validator_list = get_account( @@ -471,7 +471,7 @@ async fn fail_add_too_many_validator_stake_accounts() { validator_stake.validator_stake_seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let validator_stake = ValidatorStakeAccount::new(&stake_pool_accounts.stake_pool.pubkey(), None, 0); @@ -590,7 +590,7 @@ async fn success_with_lamports_in_account() { validator_stake.validator_stake_seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // Check stake account existence and authority let stake = get_account(&mut banks_client, &validator_stake.stake_account).await; diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 61a1b4f6..78719363 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -62,7 +62,7 @@ async fn setup() -> (ProgramTestContext, StakePoolAccounts, ValidatorStakeAccoun validator_stake.validator_stake_seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); (context, stake_pool_accounts, validator_stake) } @@ -79,7 +79,7 @@ async fn success() { &validator_stake.transient_stake_account, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let error = stake_pool_accounts .update_all( @@ -90,7 +90,7 @@ async fn success() { false, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // Check if account was removed from the list of stake accounts let validator_list = get_account( @@ -243,7 +243,7 @@ async fn success_at_large_value() { &validator_stake.transient_stake_account, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); } #[tokio::test] @@ -259,7 +259,7 @@ async fn fail_double_remove() { &validator_stake.transient_stake_account, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let error = stake_pool_accounts .update_all( @@ -270,7 +270,7 @@ async fn fail_double_remove() { false, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let last_blockhash = context .banks_client @@ -405,7 +405,7 @@ async fn fail_with_activating_transient_stake() { validator_stake.transient_stake_seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let error = stake_pool_accounts .remove_validator_from_pool( @@ -465,7 +465,7 @@ async fn success_with_deactivating_transient_stake() { validator_stake.transient_stake_seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let error = stake_pool_accounts .remove_validator_from_pool( @@ -476,7 +476,7 @@ async fn success_with_deactivating_transient_stake() { &validator_stake.transient_stake_account, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // fail deposit let maybe_deposit = simple_deposit_stake( @@ -568,7 +568,7 @@ async fn success_with_deactivating_transient_stake() { false, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let validator_list = get_account( &mut context.banks_client, @@ -619,7 +619,7 @@ async fn success_resets_preferred_validator() { &validator_stake.transient_stake_account, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let error = stake_pool_accounts .update_all( @@ -630,7 +630,7 @@ async fn success_resets_preferred_validator() { false, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // Check if account was removed from the list of stake accounts let validator_list = get_account( @@ -686,7 +686,7 @@ async fn success_with_hijacked_transient_account() { validator_stake.transient_stake_seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // warp forward to merge let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; @@ -715,7 +715,7 @@ async fn success_with_hijacked_transient_account() { validator_stake.transient_stake_seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // warp forward to merge slot += slots_per_epoch; @@ -784,7 +784,7 @@ async fn success_with_hijacked_transient_account() { .process_transaction(transaction) .await .err(); - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // activate transient stake account delegate_stake_account( @@ -807,7 +807,7 @@ async fn success_with_hijacked_transient_account() { &validator_stake.transient_stake_account, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // warp forward to merge slot += slots_per_epoch; @@ -822,7 +822,7 @@ async fn success_with_hijacked_transient_account() { false, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // Check if account was removed from the list of stake accounts let validator_list = get_account( diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 9edeeec9..8b5146c2 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -167,7 +167,7 @@ async fn _success(token_program_id: Pubkey, test_type: SuccessTestType) { tokens_to_withdraw, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // Check pool stats let stake_pool = get_account( @@ -528,7 +528,7 @@ async fn fail_double_withdraw_to_the_same_account() { tokens_to_burn / 2, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let latest_blockhash = context.banks_client.get_latest_blockhash().await.unwrap(); @@ -825,7 +825,7 @@ async fn success_with_slippage(token_program_id: Pubkey) { received_lamports, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // Check tokens used let user_token_balance = get_token_balance( diff --git a/program/tests/withdraw_edge_cases.rs b/program/tests/withdraw_edge_cases.rs index 46c49b34..e495fea4 100644 --- a/program/tests/withdraw_edge_cases.rs +++ b/program/tests/withdraw_edge_cases.rs @@ -39,7 +39,7 @@ async fn fail_remove_validator() { validator_stake.transient_stake_seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // warp forward to deactivation let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; @@ -139,7 +139,7 @@ async fn success_remove_validator(multiple: u64) { validator_stake.transient_stake_seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // warp forward to deactivation let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; @@ -190,7 +190,7 @@ async fn success_remove_validator(multiple: u64) { pool_tokens, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // Check validator stake account gone let validator_stake_account = context @@ -252,7 +252,7 @@ async fn fail_with_reserve() { validator_stake.transient_stake_seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // warp forward to deactivation let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; @@ -322,7 +322,7 @@ async fn success_with_reserve() { validator_stake.transient_stake_seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // warp forward to deactivation let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; @@ -354,7 +354,7 @@ async fn success_with_reserve() { deposit_info.pool_tokens, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // first and only deposit, lamports:pool 1:1 let stake_pool = get_account( @@ -457,7 +457,7 @@ async fn success_with_empty_preferred_withdraw() { tokens_to_burn / 2, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); } #[tokio::test] @@ -553,7 +553,7 @@ async fn success_and_fail_with_preferred_withdraw() { tokens_to_burn / 2, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); } #[tokio::test] @@ -615,7 +615,7 @@ async fn fail_withdraw_from_transient() { validator_stake_account.transient_stake_seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // fail withdrawing from transient, still a lamport in the validator stake account let new_user_authority = Pubkey::new_unique(); @@ -702,7 +702,7 @@ async fn success_withdraw_from_transient() { validator_stake_account.transient_stake_seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // nothing left in the validator stake account (or any others), so withdrawing // from the transient account is ok! @@ -720,7 +720,7 @@ async fn success_withdraw_from_transient() { tokens_to_withdraw / 2, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); } #[tokio::test] @@ -816,7 +816,7 @@ async fn success_with_small_preferred_withdraw() { preferred_validator.transient_stake_seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // warp forward to deactivation let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; @@ -868,5 +868,5 @@ async fn success_with_small_preferred_withdraw() { tokens_to_burn / 6, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); } diff --git a/program/tests/withdraw_sol.rs b/program/tests/withdraw_sol.rs index 8370dd92..1d61e95e 100644 --- a/program/tests/withdraw_sol.rs +++ b/program/tests/withdraw_sol.rs @@ -65,7 +65,7 @@ async fn setup( None, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); let tokens_issued = get_token_balance(&mut context.banks_client, &pool_token_account.pubkey()).await; @@ -114,7 +114,7 @@ async fn success(token_program_id: Pubkey) { None, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // Stake pool should add its balance to the pool balance let post_stake_pool = get_account( @@ -212,7 +212,7 @@ async fn fail_overdraw_reserve() { validator_stake.transient_stake_seed, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // try to withdraw one lamport, will overdraw let error = stake_pool_accounts @@ -273,7 +273,7 @@ async fn success_with_sol_withdraw_authority() { Some(&sol_withdraw_authority), ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); } #[tokio::test] @@ -373,7 +373,7 @@ async fn success_with_slippage(token_program_id: Pubkey) { amount_received, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // Check burned tokens let user_token_balance = diff --git a/program/tests/withdraw_with_fee.rs b/program/tests/withdraw_with_fee.rs index 1817ba40..243e3d4b 100644 --- a/program/tests/withdraw_with_fee.rs +++ b/program/tests/withdraw_with_fee.rs @@ -78,7 +78,7 @@ async fn success_withdraw_all_fee_tokens() { fee_tokens, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // Check balance is 0 let fee_tokens = get_token_balance( @@ -217,7 +217,7 @@ async fn success_empty_out_stake_with_fee() { pool_tokens_to_withdraw, ) .await; - assert!(error.is_none()); + assert!(error.is_none(), "{:?}", error); // Check balance of validator stake account is MINIMUM + rent-exemption let validator_stake_account = get_account( From 88899cb5b0768df45fbe528df00c5aa4c39826df Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 14 Sep 2023 13:36:45 +0200 Subject: [PATCH 0501/1076] stake-pool: Remove unsafe pointer casts via `Pod` types (#5185) * stake-pool: Force BigVec to work with Pod types * Remove all unsafe through an enum wrapper struct * Also fix the CLI --- clients/cli/src/output.rs | 9 +- program/Cargo.toml | 1 + program/src/big_vec.rs | 175 ++++++------------ program/src/processor.rs | 47 ++--- program/src/state.rs | 147 ++++++++++----- program/tests/force_destake.rs | 2 +- program/tests/helpers/mod.rs | 2 +- program/tests/huge_pool.rs | 21 ++- .../tests/update_validator_list_balance.rs | 4 +- program/tests/vsa_add.rs | 2 +- program/tests/vsa_remove.rs | 2 +- 11 files changed, 208 insertions(+), 204 deletions(-) diff --git a/clients/cli/src/output.rs b/clients/cli/src/output.rs index 3b2beaac..f1305245 100644 --- a/clients/cli/src/output.rs +++ b/clients/cli/src/output.rs @@ -3,7 +3,9 @@ use { solana_cli_output::{QuietDisplay, VerboseDisplay}, solana_sdk::native_token::Sol, solana_sdk::{pubkey::Pubkey, stake::state::Lockup}, - spl_stake_pool::state::{Fee, StakePool, StakeStatus, ValidatorList, ValidatorStakeInfo}, + spl_stake_pool::state::{ + Fee, PodStakeStatus, StakePool, StakeStatus, ValidatorList, ValidatorStakeInfo, + }, std::fmt::{Display, Formatter, Result, Write}, }; @@ -384,8 +386,9 @@ impl From for CliStakePoolValidator { } } -impl From for CliStakePoolValidatorStakeStatus { - fn from(s: StakeStatus) -> CliStakePoolValidatorStakeStatus { +impl From for CliStakePoolValidatorStakeStatus { + fn from(s: PodStakeStatus) -> CliStakePoolValidatorStakeStatus { + let s = StakeStatus::try_from(s).unwrap(); match s { StakeStatus::Active => CliStakePoolValidatorStakeStatus::Active, StakeStatus::DeactivatingTransient => { diff --git a/program/Cargo.toml b/program/Cargo.toml index 3eadc07c..b9eba075 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -14,6 +14,7 @@ test-sbf = [] [dependencies] arrayref = "0.3.7" borsh = "0.10" +bytemuck = "1.13" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.0" diff --git a/program/src/big_vec.rs b/program/src/big_vec.rs index 490fdaf2..3ba5afce 100644 --- a/program/src/big_vec.rs +++ b/program/src/big_vec.rs @@ -4,10 +4,9 @@ use { arrayref::array_ref, borsh::BorshDeserialize, - solana_program::{ - program_error::ProgramError, program_memory::sol_memmove, program_pack::Pack, - }, - std::marker::PhantomData, + bytemuck::Pod, + solana_program::{program_error::ProgramError, program_memory::sol_memmove}, + std::mem, }; /// Contains easy to use utilities for a big vector of Borsh-compatible types, @@ -32,7 +31,7 @@ impl<'data> BigVec<'data> { } /// Retain all elements that match the provided function, discard all others - pub fn retain bool>( + pub fn retain bool>( &mut self, predicate: F, ) -> Result<(), ProgramError> { @@ -42,12 +41,12 @@ impl<'data> BigVec<'data> { let data_start_index = VEC_SIZE_BYTES; let data_end_index = - data_start_index.saturating_add((vec_len as usize).saturating_mul(T::LEN)); - for start_index in (data_start_index..data_end_index).step_by(T::LEN) { - let end_index = start_index + T::LEN; + data_start_index.saturating_add((vec_len as usize).saturating_mul(mem::size_of::())); + for start_index in (data_start_index..data_end_index).step_by(mem::size_of::()) { + let end_index = start_index + mem::size_of::(); let slice = &self.data[start_index..end_index]; if !predicate(slice) { - let gap = removals_found * T::LEN; + let gap = removals_found * mem::size_of::(); if removals_found > 0 { // In case the compute budget is ever bumped up, allowing us // to use this safe code instead: @@ -68,7 +67,7 @@ impl<'data> BigVec<'data> { // final memmove if removals_found > 0 { - let gap = removals_found * T::LEN; + let gap = removals_found * mem::size_of::(); // In case the compute budget is ever bumped up, allowing us // to use this safe code instead: //self.data.copy_within(dst_start_index + gap..data_end_index, dst_start_index); @@ -88,11 +87,11 @@ impl<'data> BigVec<'data> { } /// Extracts a slice of the data types - pub fn deserialize_mut_slice( + pub fn deserialize_mut_slice( &mut self, skip: usize, len: usize, - ) -> Result, ProgramError> { + ) -> Result<&mut [T], ProgramError> { let vec_len = self.len(); let last_item_index = skip .checked_add(len) @@ -101,22 +100,35 @@ impl<'data> BigVec<'data> { return Err(ProgramError::AccountDataTooSmall); } - let start_index = VEC_SIZE_BYTES.saturating_add(skip.saturating_mul(T::LEN)); - let end_index = start_index.saturating_add(len.saturating_mul(T::LEN)); - let mut deserialized = vec![]; - for slice in self.data[start_index..end_index].chunks_exact_mut(T::LEN) { - deserialized.push(unsafe { &mut *(slice.as_ptr() as *mut T) }); + let start_index = VEC_SIZE_BYTES.saturating_add(skip.saturating_mul(mem::size_of::())); + let end_index = start_index.saturating_add(len.saturating_mul(mem::size_of::())); + bytemuck::try_cast_slice_mut(&mut self.data[start_index..end_index]) + .map_err(|_| ProgramError::InvalidAccountData) + } + + /// Extracts a slice of the data types + pub fn deserialize_slice(&self, skip: usize, len: usize) -> Result<&[T], ProgramError> { + let vec_len = self.len(); + let last_item_index = skip + .checked_add(len) + .ok_or(ProgramError::AccountDataTooSmall)?; + if last_item_index > vec_len as usize { + return Err(ProgramError::AccountDataTooSmall); } - Ok(deserialized) + + let start_index = VEC_SIZE_BYTES.saturating_add(skip.saturating_mul(mem::size_of::())); + let end_index = start_index.saturating_add(len.saturating_mul(mem::size_of::())); + bytemuck::try_cast_slice(&self.data[start_index..end_index]) + .map_err(|_| ProgramError::InvalidAccountData) } /// Add new element to the end - pub fn push(&mut self, element: T) -> Result<(), ProgramError> { + pub fn push(&mut self, element: T) -> Result<(), ProgramError> { let mut vec_len_ref = &mut self.data[0..VEC_SIZE_BYTES]; let mut vec_len = u32::try_from_slice(vec_len_ref)?; - let start_index = VEC_SIZE_BYTES + vec_len as usize * T::LEN; - let end_index = start_index + T::LEN; + let start_index = VEC_SIZE_BYTES + vec_len as usize * mem::size_of::(); + let end_index = start_index + mem::size_of::(); vec_len += 1; borsh::to_writer(&mut vec_len_ref, &vec_len)?; @@ -124,43 +136,24 @@ impl<'data> BigVec<'data> { if self.data.len() < end_index { return Err(ProgramError::AccountDataTooSmall); } - let element_ref = &mut self.data[start_index..start_index + T::LEN]; - element.pack_into_slice(element_ref); + let element_ref = bytemuck::try_from_bytes_mut( + &mut self.data[start_index..start_index + mem::size_of::()], + ) + .map_err(|_| ProgramError::InvalidAccountData)?; + *element_ref = element; Ok(()) } - /// Get an iterator for the type provided - pub fn iter<'vec, T: Pack>(&'vec self) -> Iter<'data, 'vec, T> { - Iter { - len: self.len() as usize, - current: 0, - current_index: VEC_SIZE_BYTES, - inner: self, - phantom: PhantomData, - } - } - - /// Get a mutable iterator for the type provided - pub fn iter_mut<'vec, T: Pack>(&'vec mut self) -> IterMut<'data, 'vec, T> { - IterMut { - len: self.len() as usize, - current: 0, - current_index: VEC_SIZE_BYTES, - inner: self, - phantom: PhantomData, - } - } - /// Find matching data in the array - pub fn find bool>(&self, predicate: F) -> Option<&T> { + pub fn find bool>(&self, predicate: F) -> Option<&T> { let len = self.len() as usize; let mut current = 0; let mut current_index = VEC_SIZE_BYTES; while current != len { - let end_index = current_index + T::LEN; + let end_index = current_index + mem::size_of::(); let current_slice = &self.data[current_index..end_index]; if predicate(current_slice) { - return Some(unsafe { &*(current_slice.as_ptr() as *const T) }); + return Some(bytemuck::from_bytes(current_slice)); } current_index = end_index; current += 1; @@ -169,15 +162,17 @@ impl<'data> BigVec<'data> { } /// Find matching data in the array - pub fn find_mut bool>(&mut self, predicate: F) -> Option<&mut T> { + pub fn find_mut bool>(&mut self, predicate: F) -> Option<&mut T> { let len = self.len() as usize; let mut current = 0; let mut current_index = VEC_SIZE_BYTES; while current != len { - let end_index = current_index + T::LEN; + let end_index = current_index + mem::size_of::(); let current_slice = &self.data[current_index..end_index]; if predicate(current_slice) { - return Some(unsafe { &mut *(current_slice.as_ptr() as *mut T) }); + return Some(bytemuck::from_bytes_mut( + &mut self.data[current_index..end_index], + )); } current_index = end_index; current += 1; @@ -186,84 +181,16 @@ impl<'data> BigVec<'data> { } } -/// Iterator wrapper over a BigVec -pub struct Iter<'data, 'vec, T> { - len: usize, - current: usize, - current_index: usize, - inner: &'vec BigVec<'data>, - phantom: PhantomData, -} - -impl<'data, 'vec, T: Pack + 'data> Iterator for Iter<'data, 'vec, T> { - type Item = &'data T; - - fn next(&mut self) -> Option { - if self.current == self.len { - None - } else { - let end_index = self.current_index + T::LEN; - let value = Some(unsafe { - &*(self.inner.data[self.current_index..end_index].as_ptr() as *const T) - }); - self.current += 1; - self.current_index = end_index; - value - } - } -} - -/// Iterator wrapper over a BigVec -pub struct IterMut<'data, 'vec, T> { - len: usize, - current: usize, - current_index: usize, - inner: &'vec mut BigVec<'data>, - phantom: PhantomData, -} - -impl<'data, 'vec, T: Pack + 'data> Iterator for IterMut<'data, 'vec, T> { - type Item = &'data mut T; - - fn next(&mut self) -> Option { - if self.current == self.len { - None - } else { - let end_index = self.current_index + T::LEN; - let value = Some(unsafe { - &mut *(self.inner.data[self.current_index..end_index].as_ptr() as *mut T) - }); - self.current += 1; - self.current_index = end_index; - value - } - } -} - #[cfg(test)] mod tests { - use {super::*, solana_program::program_pack::Sealed}; + use {super::*, bytemuck::Zeroable}; - #[derive(Debug, PartialEq)] + #[repr(C)] + #[derive(Debug, Copy, Clone, PartialEq, Pod, Zeroable)] struct TestStruct { value: [u8; 8], } - impl Sealed for TestStruct {} - - impl Pack for TestStruct { - const LEN: usize = 8; - fn pack_into_slice(&self, data: &mut [u8]) { - let mut data = data; - borsh::to_writer(&mut data, &self.value).unwrap(); - } - fn unpack_from_slice(src: &[u8]) -> Result { - Ok(TestStruct { - value: src.try_into().unwrap(), - }) - } - } - impl TestStruct { fn new(value: u8) -> Self { let value = [value, 0, 0, 0, 0, 0, 0, 0]; @@ -281,7 +208,9 @@ mod tests { fn check_big_vec_eq(big_vec: &BigVec, slice: &[u8]) { assert!(big_vec - .iter::() + .deserialize_slice::(0, big_vec.len() as usize) + .unwrap() + .iter() .map(|x| &x.value[0]) .zip(slice.iter()) .all(|(a, b)| a == b)); diff --git a/program/src/processor.rs b/program/src/processor.rs index 52ce25e7..ae6c416b 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1085,7 +1085,7 @@ impl Processor { )?; validator_list.push(ValidatorStakeInfo { - status: StakeStatus::Active, + status: StakeStatus::Active.into(), vote_account_address: *validator_vote_info.key, active_stake_lamports: required_lamports.into(), transient_stake_lamports: 0.into(), @@ -1170,7 +1170,7 @@ impl Processor { NonZeroU32::new(validator_stake_info.validator_seed_suffix.into()), )?; - if validator_stake_info.status != StakeStatus::Active { + if validator_stake_info.status != StakeStatus::Active.into() { msg!("Validator is already marked for removal"); return Err(StakePoolError::ValidatorNotFound.into()); } @@ -1220,7 +1220,7 @@ impl Processor { stake_pool.stake_withdraw_bump_seed, )?; - validator_stake_info.status = new_status; + validator_stake_info.status = new_status.into(); if stake_pool.preferred_deposit_validator_vote_address == Some(vote_account_address) { stake_pool.preferred_deposit_validator_vote_address = None; @@ -1602,7 +1602,7 @@ impl Processor { &stake_pool.lockup, )?; - if validator_stake_info.status != StakeStatus::Active { + if validator_stake_info.status != StakeStatus::Active.into() { msg!("Validator is marked for removal and no longer allows increases"); return Err(StakePoolError::ValidatorNotFound.into()); } @@ -1908,7 +1908,7 @@ impl Processor { if u64::from(validator_stake_info.transient_stake_lamports) > 0 { return Err(StakePoolError::TransientAccountInUse.into()); } - if validator_stake_info.status != StakeStatus::Active { + if validator_stake_info.status != StakeStatus::Active.into() { msg!("Validator is marked for removal and no longer allows redelegation"); return Err(StakePoolError::ValidatorNotFound.into()); } @@ -2011,7 +2011,7 @@ impl Processor { validator_stake_info.validator_seed_suffix.into(), &stake_pool.lockup, )?; - if validator_stake_info.status != StakeStatus::Active { + if validator_stake_info.status != StakeStatus::Active.into() { msg!( "Destination validator is marked for removal and no longer allows redelegation" ); @@ -2137,7 +2137,7 @@ impl Processor { }); match maybe_validator_stake_info { Some(vsi) => { - if vsi.status != StakeStatus::Active { + if vsi.status != StakeStatus::Active.into() { msg!("Validator for {:?} about to be removed, cannot set as preferred deposit account", validator_type); return Err(StakePoolError::InvalidPreferredValidator.into()); } @@ -2206,12 +2206,13 @@ impl Processor { check_account_owner(validator_list_info, program_id)?; let mut validator_list_data = validator_list_info.data.borrow_mut(); - let (validator_list_header, mut validator_slice) = - ValidatorListHeader::deserialize_mut_slice( - &mut validator_list_data, - start_index as usize, - validator_stake_accounts.len() / 2, - )?; + let (validator_list_header, mut big_vec) = + ValidatorListHeader::deserialize_vec(&mut validator_list_data)?; + let validator_slice = ValidatorListHeader::deserialize_mut_slice( + &mut big_vec, + start_index as usize, + validator_stake_accounts.len() / 2, + )?; if !validator_list_header.is_valid() { return Err(StakePoolError::InvalidState.into()); @@ -2289,7 +2290,7 @@ impl Processor { clock_info.clone(), stake_history_info.clone(), )?; - validator_stake_record.status.remove_transient_stake(); + validator_stake_record.status.remove_transient_stake()?; } } } @@ -2313,7 +2314,7 @@ impl Processor { clock_info.clone(), stake_history_info.clone(), )?; - validator_stake_record.status.remove_transient_stake(); + validator_stake_record.status.remove_transient_stake()?; } else if stake.delegation.activation_epoch < clock.epoch { if let Some(stake::state::StakeState::Stake(_, validator_stake)) = validator_stake_state @@ -2381,7 +2382,7 @@ impl Processor { additional_lamports, )?; } - match validator_stake_record.status { + match validator_stake_record.status.try_into()? { StakeStatus::Active => { active_stake_lamports = validator_stake_info.lamports(); } @@ -2406,7 +2407,7 @@ impl Processor { clock_info.clone(), stake_history_info.clone(), )?; - validator_stake_record.status.remove_validator_stake(); + validator_stake_record.status.remove_validator_stake()?; } } StakeStatus::DeactivatingTransient | StakeStatus::ReadyForRemoval => { @@ -2435,7 +2436,7 @@ impl Processor { clock_info.clone(), stake_history_info.clone(), )?; - validator_stake_record.status.remove_validator_stake(); + validator_stake_record.status.remove_validator_stake()?; } Some(stake::state::StakeState::Initialized(_)) | Some(stake::state::StakeState::Uninitialized) @@ -2511,7 +2512,9 @@ impl Processor { msg!("Reserve stake account in unknown state, aborting"); return Err(StakePoolError::WrongStakeState.into()); }; - for validator_stake_record in validator_list.iter::() { + for validator_stake_record in validator_list + .deserialize_slice::(0, validator_list.len() as usize)? + { if u64::from(validator_stake_record.last_update_epoch) < clock.epoch { return Err(StakePoolError::StakeListOutOfDate.into()); } @@ -2698,7 +2701,7 @@ impl Processor { NonZeroU32::new(validator_stake_info.validator_seed_suffix.into()), )?; - if validator_stake_info.status != StakeStatus::Active { + if validator_stake_info.status != StakeStatus::Active.into() { msg!("Validator is marked for removal and no longer accepting deposits"); return Err(StakePoolError::ValidatorNotFound.into()); } @@ -3208,7 +3211,7 @@ impl Processor { StakeWithdrawSource::ValidatorRemoval }; - if validator_stake_info.status != StakeStatus::Active { + if validator_stake_info.status != StakeStatus::Active.into() { msg!("Validator is marked for removal and no longer allowing withdrawals"); return Err(StakePoolError::ValidatorNotFound.into()); } @@ -3323,7 +3326,7 @@ impl Processor { } // since we already checked that there's no transient stake, // we can immediately set this as ready for removal - validator_list_item.status = StakeStatus::ReadyForRemoval; + validator_list_item.status = StakeStatus::ReadyForRemoval.into(); } } } diff --git a/program/src/state.rs b/program/src/state.rs index fc6b4b0f..50883228 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -6,8 +6,9 @@ use { WITHDRAWAL_BASELINE_FEE, }, borsh::{BorshDeserialize, BorshSchema, BorshSerialize}, - num_derive::FromPrimitive, - num_traits::FromPrimitive, + bytemuck::{Pod, Zeroable}, + num_derive::{FromPrimitive, ToPrimitive}, + num_traits::{FromPrimitive, ToPrimitive}, solana_program::{ account_info::AccountInfo, borsh::get_instance_packed_len, @@ -556,7 +557,15 @@ pub struct ValidatorListHeader { /// Status of the stake account in the validator list, for accounting #[derive( - FromPrimitive, Copy, Clone, Debug, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema, + ToPrimitive, + FromPrimitive, + Copy, + Clone, + Debug, + PartialEq, + BorshDeserialize, + BorshSerialize, + BorshSchema, )] pub enum StakeStatus { /// Stake account is active, there may be a transient stake as well @@ -574,29 +583,67 @@ pub enum StakeStatus { /// a validator is removed with a transient stake active DeactivatingAll, } -impl StakeStatus { +impl Default for StakeStatus { + fn default() -> Self { + Self::Active + } +} + +/// Wrapper struct that can be `Pod`, containing a byte that *should* be a valid +/// `StakeStatus` underneath. +#[repr(transparent)] +#[derive( + Clone, + Copy, + Debug, + Default, + PartialEq, + Pod, + Zeroable, + BorshDeserialize, + BorshSerialize, + BorshSchema, +)] +pub struct PodStakeStatus(u8); +impl PodStakeStatus { /// Downgrade the status towards ready for removal by removing the validator stake - pub fn remove_validator_stake(&mut self) { - let new_self = match self { - Self::Active | Self::DeactivatingTransient | Self::ReadyForRemoval => *self, - Self::DeactivatingAll => Self::DeactivatingTransient, - Self::DeactivatingValidator => Self::ReadyForRemoval, + pub fn remove_validator_stake(&mut self) -> Result<(), ProgramError> { + let status = StakeStatus::try_from(*self)?; + let new_self = match status { + StakeStatus::Active + | StakeStatus::DeactivatingTransient + | StakeStatus::ReadyForRemoval => status, + StakeStatus::DeactivatingAll => StakeStatus::DeactivatingTransient, + StakeStatus::DeactivatingValidator => StakeStatus::ReadyForRemoval, }; - *self = new_self; + *self = new_self.into(); + Ok(()) } /// Downgrade the status towards ready for removal by removing the transient stake - pub fn remove_transient_stake(&mut self) { - let new_self = match self { - Self::Active | Self::DeactivatingValidator | Self::ReadyForRemoval => *self, - Self::DeactivatingAll => Self::DeactivatingValidator, - Self::DeactivatingTransient => Self::ReadyForRemoval, + pub fn remove_transient_stake(&mut self) -> Result<(), ProgramError> { + let status = StakeStatus::try_from(*self)?; + let new_self = match status { + StakeStatus::Active + | StakeStatus::DeactivatingValidator + | StakeStatus::ReadyForRemoval => status, + StakeStatus::DeactivatingAll => StakeStatus::DeactivatingValidator, + StakeStatus::DeactivatingTransient => StakeStatus::ReadyForRemoval, }; - *self = new_self; + *self = new_self.into(); + Ok(()) } } -impl Default for StakeStatus { - fn default() -> Self { - Self::Active +impl TryFrom for StakeStatus { + type Error = ProgramError; + fn try_from(pod: PodStakeStatus) -> Result { + FromPrimitive::from_u8(pod.0).ok_or(ProgramError::InvalidAccountData) + } +} +impl From for PodStakeStatus { + fn from(status: StakeStatus) -> Self { + // unwrap is safe here because the variants of `StakeStatus` fit very + // comfortably within a `u8` + PodStakeStatus(status.to_u8().unwrap()) } } @@ -616,11 +663,22 @@ pub(crate) enum StakeWithdrawSource { /// NOTE: ORDER IS VERY IMPORTANT HERE, PLEASE DO NOT RE-ORDER THE FIELDS UNLESS /// THERE'S AN EXTREMELY GOOD REASON. /// -/// To save on BPF instructions, the serialized bytes are reinterpreted with an -/// unsafe pointer cast, which means that this structure cannot have any +/// To save on BPF instructions, the serialized bytes are reinterpreted with a +/// bytemuck transmute, which means that this structure cannot have any /// undeclared alignment-padding in its representation. #[repr(C)] -#[derive(Clone, Copy, Debug, Default, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)] +#[derive( + Clone, + Copy, + Debug, + Default, + PartialEq, + Pod, + Zeroable, + BorshDeserialize, + BorshSerialize, + BorshSchema, +)] pub struct ValidatorStakeInfo { /// Amount of lamports on the validator stake account, including rent /// @@ -647,7 +705,7 @@ pub struct ValidatorStakeInfo { pub validator_seed_suffix: PodU32, // really `Option` so 0 is `None` /// Status of the validator stake account - pub status: StakeStatus, + pub status: PodStakeStatus, /// Validator vote account address pub vote_account_address: Pubkey, @@ -770,14 +828,12 @@ impl ValidatorListHeader { /// Extracts a slice of ValidatorStakeInfo types from the vec part /// of the ValidatorList - pub fn deserialize_mut_slice( - data: &mut [u8], + pub fn deserialize_mut_slice<'a>( + big_vec: &'a mut BigVec, skip: usize, len: usize, - ) -> Result<(Self, Vec<&mut ValidatorStakeInfo>), ProgramError> { - let (header, mut big_vec) = Self::deserialize_vec(data)?; - let validator_list = big_vec.deserialize_mut_slice::(skip, len)?; - Ok((header, validator_list)) + ) -> Result<&'a mut [ValidatorStakeInfo], ProgramError> { + big_vec.deserialize_mut_slice::(skip, len) } /// Extracts the validator list into its header and internal BigVec @@ -1003,7 +1059,7 @@ mod test { }, validators: vec![ ValidatorStakeInfo { - status: StakeStatus::Active, + status: StakeStatus::Active.into(), vote_account_address: Pubkey::new_from_array([1; 32]), active_stake_lamports: u64::from_le_bytes([255; 8]).into(), transient_stake_lamports: u64::from_le_bytes([128; 8]).into(), @@ -1013,7 +1069,7 @@ mod test { validator_seed_suffix: 0.into(), }, ValidatorStakeInfo { - status: StakeStatus::DeactivatingTransient, + status: StakeStatus::DeactivatingTransient.into(), vote_account_address: Pubkey::new_from_array([2; 32]), active_stake_lamports: 998877665544.into(), transient_stake_lamports: 222222222.into(), @@ -1023,7 +1079,7 @@ mod test { validator_seed_suffix: 0.into(), }, ValidatorStakeInfo { - status: StakeStatus::ReadyForRemoval, + status: StakeStatus::ReadyForRemoval.into(), vote_account_address: Pubkey::new_from_array([3; 32]), active_stake_lamports: 0.into(), transient_stake_lamports: 0.into(), @@ -1086,8 +1142,9 @@ mod test { let max_validators = 10; let stake_list = test_validator_list(max_validators); let mut serialized = stake_list.try_to_vec().unwrap(); - let (header, list) = ValidatorListHeader::deserialize_mut_slice( - &mut serialized, + let (header, mut big_vec) = ValidatorListHeader::deserialize_vec(&mut serialized).unwrap(); + let list = ValidatorListHeader::deserialize_mut_slice( + &mut big_vec, 0, stake_list.validators.len(), ) @@ -1097,30 +1154,30 @@ mod test { assert!(list .iter() .zip(stake_list.validators.iter()) - .all(|(a, b)| *a == b)); + .all(|(a, b)| a == b)); - let (_, list) = ValidatorListHeader::deserialize_mut_slice(&mut serialized, 1, 2).unwrap(); + let list = ValidatorListHeader::deserialize_mut_slice(&mut big_vec, 1, 2).unwrap(); assert!(list .iter() .zip(stake_list.validators[1..].iter()) - .all(|(a, b)| *a == b)); - let (_, list) = ValidatorListHeader::deserialize_mut_slice(&mut serialized, 2, 1).unwrap(); + .all(|(a, b)| a == b)); + let list = ValidatorListHeader::deserialize_mut_slice(&mut big_vec, 2, 1).unwrap(); assert!(list .iter() .zip(stake_list.validators[2..].iter()) - .all(|(a, b)| *a == b)); - let (_, list) = ValidatorListHeader::deserialize_mut_slice(&mut serialized, 0, 2).unwrap(); + .all(|(a, b)| a == b)); + let list = ValidatorListHeader::deserialize_mut_slice(&mut big_vec, 0, 2).unwrap(); assert!(list .iter() .zip(stake_list.validators[..2].iter()) - .all(|(a, b)| *a == b)); + .all(|(a, b)| a == b)); assert_eq!( - ValidatorListHeader::deserialize_mut_slice(&mut serialized, 0, 4).unwrap_err(), + ValidatorListHeader::deserialize_mut_slice(&mut big_vec, 0, 4).unwrap_err(), ProgramError::AccountDataTooSmall ); assert_eq!( - ValidatorListHeader::deserialize_mut_slice(&mut serialized, 1, 3).unwrap_err(), + ValidatorListHeader::deserialize_mut_slice(&mut big_vec, 1, 3).unwrap_err(), ProgramError::AccountDataTooSmall ); } @@ -1132,7 +1189,9 @@ mod test { let mut serialized = stake_list.try_to_vec().unwrap(); let (_, big_vec) = ValidatorListHeader::deserialize_vec(&mut serialized).unwrap(); for (a, b) in big_vec - .iter::() + .deserialize_slice::(0, big_vec.len() as usize) + .unwrap() + .iter() .zip(stake_list.validators.iter()) { assert_eq!(a, b); diff --git a/program/tests/force_destake.rs b/program/tests/force_destake.rs index 13ef7c72..99d3fe97 100644 --- a/program/tests/force_destake.rs +++ b/program/tests/force_destake.rs @@ -63,7 +63,7 @@ async fn setup() -> ( let active_stake_lamports = TEST_STAKE_AMOUNT - MINIMUM_ACTIVE_STAKE; // add to validator list validator_list.validators.push(ValidatorStakeInfo { - status: StakeStatus::Active, + status: StakeStatus::Active.into(), vote_account_address: voter_pubkey, active_stake_lamports: active_stake_lamports.into(), transient_stake_lamports: 0.into(), diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 3b9bd42e..b5cf20ac 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -2404,7 +2404,7 @@ pub fn add_validator_stake_account( let active_stake_lamports = stake_amount + STAKE_ACCOUNT_RENT_EXEMPTION; validator_list.validators.push(state::ValidatorStakeInfo { - status, + status: status.into(), vote_account_address: *voter_pubkey, active_stake_lamports: active_stake_lamports.into(), transient_stake_lamports: 0.into(), diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index a4adb5f6..53d72c92 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -25,7 +25,7 @@ use { // the test require so many helper accounts. // 20k is also a very safe number for the current upper bound of the network. const MAX_POOL_SIZE_WITH_REQUESTED_COMPUTE_UNITS: u32 = 20_000; -const MAX_POOL_SIZE: u32 = 2_650; +const MAX_POOL_SIZE: u32 = 3_000; const STAKE_AMOUNT: u64 = 200_000_000_000; async fn setup( @@ -298,7 +298,10 @@ async fn remove_validator_from_pool(max_validators: u32) { let validator_list = try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); let first_element = &validator_list.validators[0]; - assert_eq!(first_element.status, StakeStatus::DeactivatingValidator); + assert_eq!( + first_element.status, + StakeStatus::DeactivatingValidator.into() + ); assert_eq!( u64::from(first_element.active_stake_lamports), LAMPORTS_PER_SOL + STAKE_ACCOUNT_RENT_EXEMPTION @@ -306,7 +309,10 @@ async fn remove_validator_from_pool(max_validators: u32) { assert_eq!(u64::from(first_element.transient_stake_lamports), 0); let middle_element = &validator_list.validators[middle_index]; - assert_eq!(middle_element.status, StakeStatus::DeactivatingValidator); + assert_eq!( + middle_element.status, + StakeStatus::DeactivatingValidator.into() + ); assert_eq!( u64::from(middle_element.active_stake_lamports), LAMPORTS_PER_SOL + STAKE_ACCOUNT_RENT_EXEMPTION @@ -314,7 +320,10 @@ async fn remove_validator_from_pool(max_validators: u32) { assert_eq!(u64::from(middle_element.transient_stake_lamports), 0); let last_element = &validator_list.validators[last_index]; - assert_eq!(last_element.status, StakeStatus::DeactivatingValidator); + assert_eq!( + last_element.status, + StakeStatus::DeactivatingValidator.into() + ); assert_eq!( u64::from(last_element.active_stake_lamports), LAMPORTS_PER_SOL + STAKE_ACCOUNT_RENT_EXEMPTION @@ -465,7 +474,7 @@ async fn add_validator_to_pool(max_validators: u32) { try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); assert_eq!(validator_list.validators.len(), last_index + 1); let last_element = validator_list.validators[last_index]; - assert_eq!(last_element.status, StakeStatus::Active); + assert_eq!(last_element.status, StakeStatus::Active.into()); assert_eq!( u64::from(last_element.active_stake_lamports), LAMPORTS_PER_SOL + STAKE_ACCOUNT_RENT_EXEMPTION @@ -503,7 +512,7 @@ async fn add_validator_to_pool(max_validators: u32) { let validator_list = try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); let last_element = validator_list.validators[last_index]; - assert_eq!(last_element.status, StakeStatus::Active); + assert_eq!(last_element.status, StakeStatus::Active.into()); assert_eq!( u64::from(last_element.active_stake_lamports), LAMPORTS_PER_SOL + STAKE_ACCOUNT_RENT_EXEMPTION diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index 97691a7e..9d494b45 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -608,7 +608,7 @@ async fn merge_transient_stake_after_remove() { assert_eq!(validator_list.validators.len(), 1); assert_eq!( validator_list.validators[0].status, - StakeStatus::DeactivatingAll + StakeStatus::DeactivatingAll.into() ); assert_eq!( u64::from(validator_list.validators[0].active_stake_lamports), @@ -660,7 +660,7 @@ async fn merge_transient_stake_after_remove() { assert_eq!(validator_list.validators.len(), 1); assert_eq!( validator_list.validators[0].status, - StakeStatus::ReadyForRemoval + StakeStatus::ReadyForRemoval.into() ); assert_eq!(validator_list.validators[0].stake_lamports().unwrap(), 0); diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index e83a6628..28f40efa 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -110,7 +110,7 @@ async fn success() { max_validators: stake_pool_accounts.max_validators, }, validators: vec![state::ValidatorStakeInfo { - status: state::StakeStatus::Active, + status: state::StakeStatus::Active.into(), vote_account_address: validator_stake.vote.pubkey(), last_update_epoch: 0.into(), active_stake_lamports: (stake_rent + current_minimum_delegation).into(), diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 78719363..6b795b84 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -542,7 +542,7 @@ async fn success_with_deactivating_transient_stake() { max_validators: stake_pool_accounts.max_validators, }, validators: vec![state::ValidatorStakeInfo { - status: state::StakeStatus::DeactivatingAll, + status: state::StakeStatus::DeactivatingAll.into(), vote_account_address: validator_stake.vote.pubkey(), last_update_epoch: 0.into(), active_stake_lamports: (stake_rent + current_minimum_delegation).into(), From d5dac9d65006a58ecd72501578452a15a21e564e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Sep 2023 16:01:11 +0200 Subject: [PATCH 0502/1076] build(deps-dev): bump @types/node-fetch from 2.6.4 to 2.6.5 in /stake-pool/js (#5280) build(deps-dev): bump @types/node-fetch in /stake-pool/js Bumps [@types/node-fetch](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node-fetch) from 2.6.4 to 2.6.5. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node-fetch) --- updated-dependencies: - dependency-name: "@types/node-fetch" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 43 +++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index c3936107..64943f0f 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1773,13 +1773,27 @@ "integrity": "sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg==" }, "node_modules/@types/node-fetch": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.4.tgz", - "integrity": "sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==", + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.5.tgz", + "integrity": "sha512-OZsUlr2nxvkqUFLSaY2ZbA+P1q22q+KrlxWOn/38RX+u5kTkYL2mTujEpzUhGkS+K/QCYp9oagfXG39XOzyySg==", "dev": true, "dependencies": { "@types/node": "*", - "form-data": "^3.0.0" + "form-data": "^4.0.0" + } + }, + "node_modules/@types/node-fetch/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" } }, "node_modules/@types/prettier": { @@ -8332,13 +8346,26 @@ "integrity": "sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg==" }, "@types/node-fetch": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.4.tgz", - "integrity": "sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==", + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.5.tgz", + "integrity": "sha512-OZsUlr2nxvkqUFLSaY2ZbA+P1q22q+KrlxWOn/38RX+u5kTkYL2mTujEpzUhGkS+K/QCYp9oagfXG39XOzyySg==", "dev": true, "requires": { "@types/node": "*", - "form-data": "^3.0.0" + "form-data": "^4.0.0" + }, + "dependencies": { + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + } } }, "@types/prettier": { From 3989e4a99fe7a9cc9d46ee6dd287a7ff86bb7342 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Sep 2023 16:31:49 +0200 Subject: [PATCH 0503/1076] build(deps-dev): bump @types/node from 20.6.0 to 20.6.1 in /stake-pool/js (#5287) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.6.0 to 20.6.1. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 64943f0f..1df91afb 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1768,9 +1768,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.6.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.0.tgz", - "integrity": "sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg==" + "version": "20.6.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.1.tgz", + "integrity": "sha512-4LcJvuXQlv4lTHnxwyHQZ3uR9Zw2j7m1C9DfuwoTFQQP4Pmu04O6IfLYgMmHoOCt0nosItLLZAH+sOrRE0Bo8g==" }, "node_modules/@types/node-fetch": { "version": "2.6.5", @@ -8341,9 +8341,9 @@ "dev": true }, "@types/node": { - "version": "20.6.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.0.tgz", - "integrity": "sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg==" + "version": "20.6.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.1.tgz", + "integrity": "sha512-4LcJvuXQlv4lTHnxwyHQZ3uR9Zw2j7m1C9DfuwoTFQQP4Pmu04O6IfLYgMmHoOCt0nosItLLZAH+sOrRE0Bo8g==" }, "@types/node-fetch": { "version": "2.6.5", From 98bba64dc143fe83df0eac3cdc91b4d91b477aaf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 10:58:20 +0200 Subject: [PATCH 0504/1076] build(deps): bump test-case from 3.1.0 to 3.2.1 (#5295) Bumps [test-case](https://github.com/frondeus/test-case) from 3.1.0 to 3.2.1. - [Release notes](https://github.com/frondeus/test-case/releases) - [Changelog](https://github.com/frondeus/test-case/blob/master/CHANGELOG.md) - [Commits](https://github.com/frondeus/test-case/compare/v3.1.0...v3.2.1) --- updated-dependencies: - dependency-name: test-case dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index b9eba075..90ec865c 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -33,7 +33,7 @@ solana-program-test = "1.16.3" solana-sdk = "1.16.3" solana-vote-program = "1.16.3" spl-token = { version = "4.0", path = "../../token/program", features = [ "no-entrypoint" ] } -test-case = "3.1" +test-case = "3.2" [lib] crate-type = ["cdylib", "lib"] From 126cd594ddb18034e80153364d7e18d8ecceff84 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 10:59:20 +0200 Subject: [PATCH 0505/1076] build(deps-dev): bump @types/node from 20.6.1 to 20.6.2 in /stake-pool/js (#5300) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.6.1 to 20.6.2. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 1df91afb..2247ad7e 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1768,9 +1768,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.6.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.1.tgz", - "integrity": "sha512-4LcJvuXQlv4lTHnxwyHQZ3uR9Zw2j7m1C9DfuwoTFQQP4Pmu04O6IfLYgMmHoOCt0nosItLLZAH+sOrRE0Bo8g==" + "version": "20.6.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.2.tgz", + "integrity": "sha512-Y+/1vGBHV/cYk6OI1Na/LHzwnlNCAfU3ZNGrc1LdRe/LAIbdDPTTv/HU3M7yXN448aTVDq3eKRm2cg7iKLb8gw==" }, "node_modules/@types/node-fetch": { "version": "2.6.5", @@ -8341,9 +8341,9 @@ "dev": true }, "@types/node": { - "version": "20.6.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.1.tgz", - "integrity": "sha512-4LcJvuXQlv4lTHnxwyHQZ3uR9Zw2j7m1C9DfuwoTFQQP4Pmu04O6IfLYgMmHoOCt0nosItLLZAH+sOrRE0Bo8g==" + "version": "20.6.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.2.tgz", + "integrity": "sha512-Y+/1vGBHV/cYk6OI1Na/LHzwnlNCAfU3ZNGrc1LdRe/LAIbdDPTTv/HU3M7yXN448aTVDq3eKRm2cg7iKLb8gw==" }, "@types/node-fetch": { "version": "2.6.5", From 503ce7b6877bf6a6f27ddb0d125b9092147c5ff9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 10:59:30 +0200 Subject: [PATCH 0506/1076] build(deps-dev): bump @types/bn.js from 5.1.1 to 5.1.2 in /stake-pool/js (#5301) Bumps [@types/bn.js](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/bn.js) from 5.1.1 to 5.1.2. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/bn.js) --- updated-dependencies: - dependency-name: "@types/bn.js" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 2247ad7e..0897219b 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1696,9 +1696,9 @@ } }, "node_modules/@types/bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.2.tgz", + "integrity": "sha512-dkpZu0szUtn9UXTmw+e0AJFd4D2XAxDnsCLdc05SfqpqzPEBft8eQr8uaFitfo/dUUOZERaLec2hHMG87A4Dxg==", "dev": true, "dependencies": { "@types/node": "*" @@ -8269,9 +8269,9 @@ } }, "@types/bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.2.tgz", + "integrity": "sha512-dkpZu0szUtn9UXTmw+e0AJFd4D2XAxDnsCLdc05SfqpqzPEBft8eQr8uaFitfo/dUUOZERaLec2hHMG87A4Dxg==", "dev": true, "requires": { "@types/node": "*" From 4643b481e26b2e89afb870937aa2f2a69c7936e0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 20:19:43 +0200 Subject: [PATCH 0507/1076] build(deps-dev): bump @typescript-eslint/parser from 6.7.0 to 6.7.2 in /stake-pool/js (#5312) build(deps-dev): bump @typescript-eslint/parser in /stake-pool/js Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.7.0 to 6.7.2. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.7.2/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 145 +++++++++++++++++++++++++--- 1 file changed, 131 insertions(+), 14 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 0897219b..7db3d8f0 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1879,15 +1879,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.0.tgz", - "integrity": "sha512-jZKYwqNpNm5kzPVP5z1JXAuxjtl2uG+5NpaMocFPTNC2EdYIgbXIPImObOkhbONxtFTTdoZstLZefbaK+wXZng==", + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.2.tgz", + "integrity": "sha512-KA3E4ox0ws+SPyxQf9iSI25R6b4Ne78ORhNHeVKrPQnoYsb9UhieoiRoJgrzgEeKGOXhcY1i8YtOeCHHTDa6Fw==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.7.0", - "@typescript-eslint/types": "6.7.0", - "@typescript-eslint/typescript-estree": "6.7.0", - "@typescript-eslint/visitor-keys": "6.7.0", + "@typescript-eslint/scope-manager": "6.7.2", + "@typescript-eslint/types": "6.7.2", + "@typescript-eslint/typescript-estree": "6.7.2", + "@typescript-eslint/visitor-keys": "6.7.2", "debug": "^4.3.4" }, "engines": { @@ -1906,6 +1906,80 @@ } } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.2.tgz", + "integrity": "sha512-bgi6plgyZjEqapr7u2mhxGR6E8WCzKNUFWNh6fkpVe9+yzRZeYtDTbsIBzKbcxI+r1qVWt6VIoMSNZ4r2A+6Yw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.7.2", + "@typescript-eslint/visitor-keys": "6.7.2" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.2.tgz", + "integrity": "sha512-flJYwMYgnUNDAN9/GAI3l8+wTmvTYdv64fcH8aoJK76Y+1FCZ08RtI5zDerM/FYT5DMkAc+19E4aLmd5KqdFyg==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.2.tgz", + "integrity": "sha512-kiJKVMLkoSciGyFU0TOY0fRxnp9qq1AzVOHNeN1+B9erKFCJ4Z8WdjAkKQPP+b1pWStGFqezMLltxO+308dJTQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.7.2", + "@typescript-eslint/visitor-keys": "6.7.2", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.2.tgz", + "integrity": "sha512-uVw9VIMFBUTz8rIeaUT3fFe8xIUx8r4ywAdlQv1ifH+6acn/XF8Y6rwJ7XNmkNMDrTW+7+vxFFPIF40nJCVsMQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.7.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "6.7.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.0.tgz", @@ -8435,16 +8509,59 @@ } }, "@typescript-eslint/parser": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.0.tgz", - "integrity": "sha512-jZKYwqNpNm5kzPVP5z1JXAuxjtl2uG+5NpaMocFPTNC2EdYIgbXIPImObOkhbONxtFTTdoZstLZefbaK+wXZng==", + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.2.tgz", + "integrity": "sha512-KA3E4ox0ws+SPyxQf9iSI25R6b4Ne78ORhNHeVKrPQnoYsb9UhieoiRoJgrzgEeKGOXhcY1i8YtOeCHHTDa6Fw==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "6.7.0", - "@typescript-eslint/types": "6.7.0", - "@typescript-eslint/typescript-estree": "6.7.0", - "@typescript-eslint/visitor-keys": "6.7.0", + "@typescript-eslint/scope-manager": "6.7.2", + "@typescript-eslint/types": "6.7.2", + "@typescript-eslint/typescript-estree": "6.7.2", + "@typescript-eslint/visitor-keys": "6.7.2", "debug": "^4.3.4" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.2.tgz", + "integrity": "sha512-bgi6plgyZjEqapr7u2mhxGR6E8WCzKNUFWNh6fkpVe9+yzRZeYtDTbsIBzKbcxI+r1qVWt6VIoMSNZ4r2A+6Yw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.7.2", + "@typescript-eslint/visitor-keys": "6.7.2" + } + }, + "@typescript-eslint/types": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.2.tgz", + "integrity": "sha512-flJYwMYgnUNDAN9/GAI3l8+wTmvTYdv64fcH8aoJK76Y+1FCZ08RtI5zDerM/FYT5DMkAc+19E4aLmd5KqdFyg==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.2.tgz", + "integrity": "sha512-kiJKVMLkoSciGyFU0TOY0fRxnp9qq1AzVOHNeN1+B9erKFCJ4Z8WdjAkKQPP+b1pWStGFqezMLltxO+308dJTQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.7.2", + "@typescript-eslint/visitor-keys": "6.7.2", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.2.tgz", + "integrity": "sha512-uVw9VIMFBUTz8rIeaUT3fFe8xIUx8r4ywAdlQv1ifH+6acn/XF8Y6rwJ7XNmkNMDrTW+7+vxFFPIF40nJCVsMQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.7.2", + "eslint-visitor-keys": "^3.4.1" + } + } } }, "@typescript-eslint/scope-manager": { From 700552858ea4807b6ba348d95278769b7fd17653 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 22:02:38 +0200 Subject: [PATCH 0508/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.7.0 to 6.7.2 in /stake-pool/js (#5313) build(deps-dev): bump @typescript-eslint/eslint-plugin in /stake-pool/js Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.7.0 to 6.7.2. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.7.2/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 273 ++++++++-------------------- 1 file changed, 78 insertions(+), 195 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 7db3d8f0..db6fed63 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1762,9 +1762,9 @@ } }, "node_modules/@types/json-schema": { - "version": "7.0.12", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", - "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", + "version": "7.0.13", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.13.tgz", + "integrity": "sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==", "dev": true }, "node_modules/@types/node": { @@ -1809,9 +1809,9 @@ "dev": true }, "node_modules/@types/semver": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.1.tgz", - "integrity": "sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg==", + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.2.tgz", + "integrity": "sha512-7aqorHYgdNO4DM36stTiGO3DvKoex9TQRwsJU6vMaFGyqpBA1MNZkz+PG3gaNUPpTAOYhT1WR7M1JyA3fbS9Cw==", "dev": true }, "node_modules/@types/stack-utils": { @@ -1844,16 +1844,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.0.tgz", - "integrity": "sha512-gUqtknHm0TDs1LhY12K2NA3Rmlmp88jK9Tx8vGZMfHeNMLE3GH2e9TRub+y+SOjuYgtOmok+wt1AyDPZqxbNag==", + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.2.tgz", + "integrity": "sha512-ooaHxlmSgZTM6CHYAFRlifqh1OAr3PAQEwi7lhYhaegbnXrnh7CDcHmc3+ihhbQC7H0i4JF0psI5ehzkF6Yl6Q==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.7.0", - "@typescript-eslint/type-utils": "6.7.0", - "@typescript-eslint/utils": "6.7.0", - "@typescript-eslint/visitor-keys": "6.7.0", + "@typescript-eslint/scope-manager": "6.7.2", + "@typescript-eslint/type-utils": "6.7.2", + "@typescript-eslint/utils": "6.7.2", + "@typescript-eslint/visitor-keys": "6.7.2", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -1906,7 +1906,7 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "node_modules/@typescript-eslint/scope-manager": { "version": "6.7.2", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.2.tgz", "integrity": "sha512-bgi6plgyZjEqapr7u2mhxGR6E8WCzKNUFWNh6fkpVe9+yzRZeYtDTbsIBzKbcxI+r1qVWt6VIoMSNZ4r2A+6Yw==", @@ -1923,88 +1923,14 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.2.tgz", - "integrity": "sha512-flJYwMYgnUNDAN9/GAI3l8+wTmvTYdv64fcH8aoJK76Y+1FCZ08RtI5zDerM/FYT5DMkAc+19E4aLmd5KqdFyg==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.2.tgz", - "integrity": "sha512-kiJKVMLkoSciGyFU0TOY0fRxnp9qq1AzVOHNeN1+B9erKFCJ4Z8WdjAkKQPP+b1pWStGFqezMLltxO+308dJTQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.7.2", - "@typescript-eslint/visitor-keys": "6.7.2", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.2.tgz", - "integrity": "sha512-uVw9VIMFBUTz8rIeaUT3fFe8xIUx8r4ywAdlQv1ifH+6acn/XF8Y6rwJ7XNmkNMDrTW+7+vxFFPIF40nJCVsMQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.7.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.0.tgz", - "integrity": "sha512-lAT1Uau20lQyjoLUQ5FUMSX/dS07qux9rYd5FGzKz/Kf8W8ccuvMyldb8hadHdK/qOI7aikvQWqulnEq2nCEYA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.7.0", - "@typescript-eslint/visitor-keys": "6.7.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.0.tgz", - "integrity": "sha512-f/QabJgDAlpSz3qduCyQT0Fw7hHpmhOzY/Rv6zO3yO+HVIdPfIWhrQoAyG+uZVtWAIS85zAyzgAFfyEr+MgBpg==", + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.2.tgz", + "integrity": "sha512-36F4fOYIROYRl0qj95dYKx6kybddLtsbmPIYNK0OBeXv2j9L5nZ17j9jmfy+bIDHKQgn2EZX+cofsqi8NPATBQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.7.0", - "@typescript-eslint/utils": "6.7.0", + "@typescript-eslint/typescript-estree": "6.7.2", + "@typescript-eslint/utils": "6.7.2", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -2025,9 +1951,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.0.tgz", - "integrity": "sha512-ihPfvOp7pOcN/ysoj0RpBPOx3HQTJTrIN8UZK+WFd3/iDeFHHqeyYxa4hQk4rMhsz9H9mXpR61IzwlBVGXtl9Q==", + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.2.tgz", + "integrity": "sha512-flJYwMYgnUNDAN9/GAI3l8+wTmvTYdv64fcH8aoJK76Y+1FCZ08RtI5zDerM/FYT5DMkAc+19E4aLmd5KqdFyg==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -2038,13 +1964,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.0.tgz", - "integrity": "sha512-dPvkXj3n6e9yd/0LfojNU8VMUGHWiLuBZvbM6V6QYD+2qxqInE7J+J/ieY2iGwR9ivf/R/haWGkIj04WVUeiSQ==", + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.2.tgz", + "integrity": "sha512-kiJKVMLkoSciGyFU0TOY0fRxnp9qq1AzVOHNeN1+B9erKFCJ4Z8WdjAkKQPP+b1pWStGFqezMLltxO+308dJTQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.7.0", - "@typescript-eslint/visitor-keys": "6.7.0", + "@typescript-eslint/types": "6.7.2", + "@typescript-eslint/visitor-keys": "6.7.2", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2065,17 +1991,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.0.tgz", - "integrity": "sha512-MfCq3cM0vh2slSikQYqK2Gq52gvOhe57vD2RM3V4gQRZYX4rDPnKLu5p6cm89+LJiGlwEXU8hkYxhqqEC/V3qA==", + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.2.tgz", + "integrity": "sha512-ZCcBJug/TS6fXRTsoTkgnsvyWSiXwMNiPzBUani7hDidBdj1779qwM1FIAmpH4lvlOZNF3EScsxxuGifjpLSWQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.7.0", - "@typescript-eslint/types": "6.7.0", - "@typescript-eslint/typescript-estree": "6.7.0", + "@typescript-eslint/scope-manager": "6.7.2", + "@typescript-eslint/types": "6.7.2", + "@typescript-eslint/typescript-estree": "6.7.2", "semver": "^7.5.4" }, "engines": { @@ -2090,12 +2016,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.0.tgz", - "integrity": "sha512-/C1RVgKFDmGMcVGeD8HjKv2bd72oI1KxQDeY8uc66gw9R0OK0eMq48cA+jv9/2Ag6cdrsUGySm1yzYmfz0hxwQ==", + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.2.tgz", + "integrity": "sha512-uVw9VIMFBUTz8rIeaUT3fFe8xIUx8r4ywAdlQv1ifH+6acn/XF8Y6rwJ7XNmkNMDrTW+7+vxFFPIF40nJCVsMQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.7.0", + "@typescript-eslint/types": "6.7.2", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -8409,9 +8335,9 @@ } }, "@types/json-schema": { - "version": "7.0.12", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", - "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", + "version": "7.0.13", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.13.tgz", + "integrity": "sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==", "dev": true }, "@types/node": { @@ -8455,9 +8381,9 @@ "dev": true }, "@types/semver": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.1.tgz", - "integrity": "sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg==", + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.2.tgz", + "integrity": "sha512-7aqorHYgdNO4DM36stTiGO3DvKoex9TQRwsJU6vMaFGyqpBA1MNZkz+PG3gaNUPpTAOYhT1WR7M1JyA3fbS9Cw==", "dev": true }, "@types/stack-utils": { @@ -8490,16 +8416,16 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.0.tgz", - "integrity": "sha512-gUqtknHm0TDs1LhY12K2NA3Rmlmp88jK9Tx8vGZMfHeNMLE3GH2e9TRub+y+SOjuYgtOmok+wt1AyDPZqxbNag==", + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.2.tgz", + "integrity": "sha512-ooaHxlmSgZTM6CHYAFRlifqh1OAr3PAQEwi7lhYhaegbnXrnh7CDcHmc3+ihhbQC7H0i4JF0psI5ehzkF6Yl6Q==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.7.0", - "@typescript-eslint/type-utils": "6.7.0", - "@typescript-eslint/utils": "6.7.0", - "@typescript-eslint/visitor-keys": "6.7.0", + "@typescript-eslint/scope-manager": "6.7.2", + "@typescript-eslint/type-utils": "6.7.2", + "@typescript-eslint/utils": "6.7.2", + "@typescript-eslint/visitor-keys": "6.7.2", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -8519,87 +8445,44 @@ "@typescript-eslint/typescript-estree": "6.7.2", "@typescript-eslint/visitor-keys": "6.7.2", "debug": "^4.3.4" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.2.tgz", - "integrity": "sha512-bgi6plgyZjEqapr7u2mhxGR6E8WCzKNUFWNh6fkpVe9+yzRZeYtDTbsIBzKbcxI+r1qVWt6VIoMSNZ4r2A+6Yw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.7.2", - "@typescript-eslint/visitor-keys": "6.7.2" - } - }, - "@typescript-eslint/types": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.2.tgz", - "integrity": "sha512-flJYwMYgnUNDAN9/GAI3l8+wTmvTYdv64fcH8aoJK76Y+1FCZ08RtI5zDerM/FYT5DMkAc+19E4aLmd5KqdFyg==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.2.tgz", - "integrity": "sha512-kiJKVMLkoSciGyFU0TOY0fRxnp9qq1AzVOHNeN1+B9erKFCJ4Z8WdjAkKQPP+b1pWStGFqezMLltxO+308dJTQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.7.2", - "@typescript-eslint/visitor-keys": "6.7.2", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.2.tgz", - "integrity": "sha512-uVw9VIMFBUTz8rIeaUT3fFe8xIUx8r4ywAdlQv1ifH+6acn/XF8Y6rwJ7XNmkNMDrTW+7+vxFFPIF40nJCVsMQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.7.2", - "eslint-visitor-keys": "^3.4.1" - } - } } }, "@typescript-eslint/scope-manager": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.0.tgz", - "integrity": "sha512-lAT1Uau20lQyjoLUQ5FUMSX/dS07qux9rYd5FGzKz/Kf8W8ccuvMyldb8hadHdK/qOI7aikvQWqulnEq2nCEYA==", + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.2.tgz", + "integrity": "sha512-bgi6plgyZjEqapr7u2mhxGR6E8WCzKNUFWNh6fkpVe9+yzRZeYtDTbsIBzKbcxI+r1qVWt6VIoMSNZ4r2A+6Yw==", "dev": true, "requires": { - "@typescript-eslint/types": "6.7.0", - "@typescript-eslint/visitor-keys": "6.7.0" + "@typescript-eslint/types": "6.7.2", + "@typescript-eslint/visitor-keys": "6.7.2" } }, "@typescript-eslint/type-utils": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.0.tgz", - "integrity": "sha512-f/QabJgDAlpSz3qduCyQT0Fw7hHpmhOzY/Rv6zO3yO+HVIdPfIWhrQoAyG+uZVtWAIS85zAyzgAFfyEr+MgBpg==", + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.2.tgz", + "integrity": "sha512-36F4fOYIROYRl0qj95dYKx6kybddLtsbmPIYNK0OBeXv2j9L5nZ17j9jmfy+bIDHKQgn2EZX+cofsqi8NPATBQ==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "6.7.0", - "@typescript-eslint/utils": "6.7.0", + "@typescript-eslint/typescript-estree": "6.7.2", + "@typescript-eslint/utils": "6.7.2", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" } }, "@typescript-eslint/types": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.0.tgz", - "integrity": "sha512-ihPfvOp7pOcN/ysoj0RpBPOx3HQTJTrIN8UZK+WFd3/iDeFHHqeyYxa4hQk4rMhsz9H9mXpR61IzwlBVGXtl9Q==", + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.2.tgz", + "integrity": "sha512-flJYwMYgnUNDAN9/GAI3l8+wTmvTYdv64fcH8aoJK76Y+1FCZ08RtI5zDerM/FYT5DMkAc+19E4aLmd5KqdFyg==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.0.tgz", - "integrity": "sha512-dPvkXj3n6e9yd/0LfojNU8VMUGHWiLuBZvbM6V6QYD+2qxqInE7J+J/ieY2iGwR9ivf/R/haWGkIj04WVUeiSQ==", + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.2.tgz", + "integrity": "sha512-kiJKVMLkoSciGyFU0TOY0fRxnp9qq1AzVOHNeN1+B9erKFCJ4Z8WdjAkKQPP+b1pWStGFqezMLltxO+308dJTQ==", "dev": true, "requires": { - "@typescript-eslint/types": "6.7.0", - "@typescript-eslint/visitor-keys": "6.7.0", + "@typescript-eslint/types": "6.7.2", + "@typescript-eslint/visitor-keys": "6.7.2", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -8608,27 +8491,27 @@ } }, "@typescript-eslint/utils": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.0.tgz", - "integrity": "sha512-MfCq3cM0vh2slSikQYqK2Gq52gvOhe57vD2RM3V4gQRZYX4rDPnKLu5p6cm89+LJiGlwEXU8hkYxhqqEC/V3qA==", + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.2.tgz", + "integrity": "sha512-ZCcBJug/TS6fXRTsoTkgnsvyWSiXwMNiPzBUani7hDidBdj1779qwM1FIAmpH4lvlOZNF3EScsxxuGifjpLSWQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.7.0", - "@typescript-eslint/types": "6.7.0", - "@typescript-eslint/typescript-estree": "6.7.0", + "@typescript-eslint/scope-manager": "6.7.2", + "@typescript-eslint/types": "6.7.2", + "@typescript-eslint/typescript-estree": "6.7.2", "semver": "^7.5.4" } }, "@typescript-eslint/visitor-keys": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.0.tgz", - "integrity": "sha512-/C1RVgKFDmGMcVGeD8HjKv2bd72oI1KxQDeY8uc66gw9R0OK0eMq48cA+jv9/2Ag6cdrsUGySm1yzYmfz0hxwQ==", + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.2.tgz", + "integrity": "sha512-uVw9VIMFBUTz8rIeaUT3fFe8xIUx8r4ywAdlQv1ifH+6acn/XF8Y6rwJ7XNmkNMDrTW+7+vxFFPIF40nJCVsMQ==", "dev": true, "requires": { - "@typescript-eslint/types": "6.7.0", + "@typescript-eslint/types": "6.7.2", "eslint-visitor-keys": "^3.4.1" } }, From c4c662d99f44a54cb8a5127ae793c1e0eadf565b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Sep 2023 15:00:44 +0200 Subject: [PATCH 0509/1076] build(deps-dev): bump @types/node from 20.6.2 to 20.6.3 in /stake-pool/js (#5319) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.6.2 to 20.6.3. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index db6fed63..6d2eee15 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1768,9 +1768,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.6.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.2.tgz", - "integrity": "sha512-Y+/1vGBHV/cYk6OI1Na/LHzwnlNCAfU3ZNGrc1LdRe/LAIbdDPTTv/HU3M7yXN448aTVDq3eKRm2cg7iKLb8gw==" + "version": "20.6.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.3.tgz", + "integrity": "sha512-HksnYH4Ljr4VQgEy2lTStbCKv/P590tmPe5HqOnv9Gprffgv5WXAY+Y5Gqniu0GGqeTCUdBnzC3QSrzPkBkAMA==" }, "node_modules/@types/node-fetch": { "version": "2.6.5", @@ -8341,9 +8341,9 @@ "dev": true }, "@types/node": { - "version": "20.6.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.2.tgz", - "integrity": "sha512-Y+/1vGBHV/cYk6OI1Na/LHzwnlNCAfU3ZNGrc1LdRe/LAIbdDPTTv/HU3M7yXN448aTVDq3eKRm2cg7iKLb8gw==" + "version": "20.6.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.3.tgz", + "integrity": "sha512-HksnYH4Ljr4VQgEy2lTStbCKv/P590tmPe5HqOnv9Gprffgv5WXAY+Y5Gqniu0GGqeTCUdBnzC3QSrzPkBkAMA==" }, "@types/node-fetch": { "version": "2.6.5", From c751aba2a1a3b93ceb1abc83e07113d3d585fe10 Mon Sep 17 00:00:00 2001 From: Andrew Fitzgerald Date: Wed, 20 Sep 2023 12:30:19 -0700 Subject: [PATCH 0510/1076] Access epoch_schedule by reference (#5323) --- program/tests/huge_pool.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index 53d72c92..9990ee37 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -106,7 +106,7 @@ async fn setup( ); let mut context = program_test.start_with_context().await; - let epoch_schedule = context.genesis_config().epoch_schedule; + let epoch_schedule = &context.genesis_config().epoch_schedule; let slot = epoch_schedule.first_normal_slot + epoch_schedule.slots_per_epoch + 1; context.warp_to_slot(slot).unwrap(); From 7dcd2ba41b7397d2ec568be81a0c598c40117e99 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 20 Sep 2023 21:31:20 +0200 Subject: [PATCH 0511/1076] stake-pool: Prefund split account during redelegate (#5285) * stake-pool: Prefund split account during redelegate * stake-pool-js: Add reserve account to redelegate * Only pre-fund the rent-exempt reserve if needed * Add error type for depleting the reserve during rebalance * Do not deplete the reserve while funding rent-exemption * Move error check for overdraw --- clients/js-legacy/src/index.ts | 1 + clients/js-legacy/src/instructions.ts | 3 + program/src/error.rs | 5 + program/src/instruction.rs | 44 +++++---- program/src/processor.rs | 35 +++++-- program/tests/helpers/mod.rs | 1 + program/tests/redelegate.rs | 133 ++++++++++++++++++++++---- 7 files changed, 178 insertions(+), 44 deletions(-) diff --git a/clients/js-legacy/src/index.ts b/clients/js-legacy/src/index.ts index a06dd6d4..4e932033 100644 --- a/clients/js-legacy/src/index.ts +++ b/clients/js-legacy/src/index.ts @@ -1092,6 +1092,7 @@ export async function redelegate(props: RedelegateProps) { stakePool: stakePool.pubkey, staker: stakePool.account.data.staker, validatorList: stakePool.account.data.validatorList, + reserveStake: stakePool.account.data.reserveStake, stakePoolWithdrawAuthority, ephemeralStake, ephemeralStakeSeed, diff --git a/clients/js-legacy/src/instructions.ts b/clients/js-legacy/src/instructions.ts index 60cd9b64..2a8fc9af 100644 --- a/clients/js-legacy/src/instructions.ts +++ b/clients/js-legacy/src/instructions.ts @@ -325,6 +325,7 @@ export type RedelegateParams = { staker: PublicKey; stakePoolWithdrawAuthority: PublicKey; validatorList: PublicKey; + reserveStake: PublicKey; sourceValidatorStake: PublicKey; sourceTransientStake: PublicKey; ephemeralStake: PublicKey; @@ -841,6 +842,7 @@ export class StakePoolInstruction { staker, stakePoolWithdrawAuthority, validatorList, + reserveStake, sourceValidatorStake, sourceTransientStake, ephemeralStake, @@ -858,6 +860,7 @@ export class StakePoolInstruction { { pubkey: staker, isSigner: true, isWritable: false }, { pubkey: stakePoolWithdrawAuthority, isSigner: false, isWritable: false }, { pubkey: validatorList, isSigner: false, isWritable: true }, + { pubkey: reserveStake, isSigner: false, isWritable: true }, { pubkey: sourceValidatorStake, isSigner: false, isWritable: true }, { pubkey: sourceTransientStake, isSigner: false, isWritable: true }, { pubkey: ephemeralStake, isSigner: false, isWritable: true }, diff --git a/program/src/error.rs b/program/src/error.rs index b3ed8e09..9433a230 100644 --- a/program/src/error.rs +++ b/program/src/error.rs @@ -149,6 +149,11 @@ pub enum StakePoolError { /// Provided mint does not have 9 decimals to match SOL #[error("IncorrectMintDecimals")] IncorrectMintDecimals, + /// Pool reserve does not have enough lamports to fund rent-exempt reserve in split + /// destination. Deposit more SOL in reserve, or pre-fund split destination with + /// the rent-exempt reserve for a stake account. + #[error("ReserveDepleted")] + ReserveDepleted, } impl From for ProgramError { fn from(e: StakePoolError) -> Self { diff --git a/program/src/instruction.rs b/program/src/instruction.rs index fcda9082..6a0f6ad0 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -487,34 +487,36 @@ pub enum StakePoolInstruction { /// The instruction only succeeds if the source transient stake account and /// ephemeral stake account do not exist. /// - /// The amount of lamports to move must be at least twice rent-exemption - /// plus the minimum delegation amount. Rent-exemption is required for the - /// source transient stake account, and rent-exemption plus minimum delegation + /// The amount of lamports to move must be at least rent-exemption plus the + /// minimum delegation amount. Rent-exemption plus minimum delegation /// is required for the destination ephemeral stake account. /// + /// The rent-exemption for the source transient account comes from the stake + /// pool reserve, if needed. + /// /// The amount that arrives at the destination validator in the end is - /// `redelegate_lamports - 2 * rent_exemption` if the destination transient - /// account does *not* exist, and `redelegate_lamports - rent_exemption` if - /// the destination transient account already exists. One `rent_exemption` - /// is deactivated with the source transient account during redelegation, - /// and another `rent_exemption` is deactivated when creating the destination - /// transient stake account. + /// `redelegate_lamports - rent_exemption` if the destination transient + /// account does *not* exist, and `redelegate_lamports` if the destination + /// transient account already exists. The `rent_exemption` is not activated + /// when creating the destination transient stake account, but if it already + /// exists, then the full amount is delegated. /// /// 0. `[]` Stake pool /// 1. `[s]` Stake pool staker /// 2. `[]` Stake pool withdraw authority /// 3. `[w]` Validator list - /// 4. `[w]` Source canonical stake account to split from - /// 5. `[w]` Source transient stake account to receive split and be redelegated - /// 6. `[w]` Uninitialized ephemeral stake account to receive redelegation - /// 7. `[w]` Destination transient stake account to receive ephemeral stake by merge - /// 8. `[]` Destination stake account to receive transient stake after activation - /// 9. `[]` Destination validator vote account - /// 10. `[]` Clock sysvar - /// 11. `[]` Stake History sysvar - /// 12. `[]` Stake Config sysvar - /// 13. `[]` System program - /// 14. `[]` Stake program + /// 4. `[w]` Reserve stake account, to withdraw rent exempt reserve + /// 5. `[w]` Source canonical stake account to split from + /// 6. `[w]` Source transient stake account to receive split and be redelegated + /// 7. `[w]` Uninitialized ephemeral stake account to receive redelegation + /// 8. `[w]` Destination transient stake account to receive ephemeral stake by merge + /// 9. `[]` Destination stake account to receive transient stake after activation + /// 10. `[]` Destination validator vote account + /// 11. `[]` Clock sysvar + /// 12. `[]` Stake History sysvar + /// 13. `[]` Stake Config sysvar + /// 14. `[]` System program + /// 15. `[]` Stake program Redelegate { /// Amount of lamports to redelegate #[allow(dead_code)] // but it's not @@ -920,6 +922,7 @@ pub fn redelegate( staker: &Pubkey, stake_pool_withdraw_authority: &Pubkey, validator_list: &Pubkey, + reserve_stake: &Pubkey, source_validator_stake: &Pubkey, source_transient_stake: &Pubkey, ephemeral_stake: &Pubkey, @@ -936,6 +939,7 @@ pub fn redelegate( AccountMeta::new_readonly(*staker, true), AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), AccountMeta::new(*validator_list, false), + AccountMeta::new(*reserve_stake, false), AccountMeta::new(*source_validator_stake, false), AccountMeta::new(*source_transient_stake, false), AccountMeta::new(*ephemeral_stake, false), diff --git a/program/src/processor.rs b/program/src/processor.rs index ae6c416b..2024d674 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1793,6 +1793,7 @@ impl Processor { let staker_info = next_account_info(account_info_iter)?; let withdraw_authority_info = next_account_info(account_info_iter)?; let validator_list_info = next_account_info(account_info_iter)?; + let reserve_stake_info = next_account_info(account_info_iter)?; let source_validator_stake_account_info = next_account_info(account_info_iter)?; let source_transient_stake_account_info = next_account_info(account_info_iter)?; let ephemeral_stake_account_info = next_account_info(account_info_iter)?; @@ -1829,6 +1830,7 @@ impl Processor { stake_pool.check_validator_list(validator_list_info)?; check_account_owner(validator_list_info, program_id)?; + stake_pool.check_reserve_stake(reserve_stake_info)?; let mut validator_list_data = validator_list_info.data.borrow_mut(); let (header, mut validator_list) = @@ -1844,11 +1846,11 @@ impl Processor { let current_minimum_delegation = minimum_delegation(stake_minimum_delegation); // check that we're redelegating enough - let destination_transient_lamports = { + { // redelegation requires that the source account maintains rent exemption and that // the destination account has rent-exemption and minimum delegation let minimum_redelegation_lamports = - current_minimum_delegation.saturating_add(stake_rent.saturating_mul(2)); + current_minimum_delegation.saturating_add(stake_rent); if lamports < minimum_redelegation_lamports { msg!( "Need more than {} lamports for redelegated stake and transient stake to meet minimum delegation requirement, {} provided", @@ -1877,10 +1879,7 @@ impl Processor { ); return Err(ProgramError::InsufficientFunds); } - lamports - .checked_sub(stake_rent) - .ok_or(StakePoolError::CalculationFailure)? - }; + } // check source account state let (_, stake) = get_stake_state(source_validator_stake_account_info)?; @@ -1945,6 +1944,25 @@ impl Processor { stake_space, )?; + // if needed, pre-fund the rent-exempt reserve from the reserve stake + let required_lamports_for_rent_exemption = + stake_rent.saturating_sub(source_transient_stake_account_info.lamports()); + if required_lamports_for_rent_exemption > 0 { + if required_lamports_for_rent_exemption >= reserve_stake_info.lamports() { + return Err(StakePoolError::ReserveDepleted.into()); + } + Self::stake_withdraw( + stake_pool_info.key, + reserve_stake_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + source_transient_stake_account_info.clone(), + clock_info.clone(), + stake_history_info.clone(), + required_lamports_for_rent_exemption, + )?; + } Self::stake_split( stake_pool_info.key, source_validator_stake_account_info.clone(), @@ -2021,7 +2039,7 @@ impl Processor { u64::from(validator_stake_info.transient_stake_lamports) > 0; validator_stake_info.transient_stake_lamports = u64::from(validator_stake_info.transient_stake_lamports) - .checked_add(destination_transient_lamports) + .checked_add(lamports) .ok_or(StakePoolError::CalculationFailure)? .into(); @@ -2088,7 +2106,7 @@ impl Processor { withdraw_authority_info.clone(), AUTHORITY_WITHDRAW, stake_pool.stake_withdraw_bump_seed, - destination_transient_lamports, + lamports, destination_transient_stake_account_info.clone(), )?; validator_stake_info.transient_seed_suffix = @@ -4019,6 +4037,7 @@ impl PrintProgramError for StakePoolError { StakePoolError::UnsupportedFeeAccountExtension => msg!("Error: fee account has an unsupported extension"), StakePoolError::ExceededSlippage => msg!("Error: instruction exceeds desired slippage limit"), StakePoolError::IncorrectMintDecimals => msg!("Error: Provided mint does not have 9 decimals to match SOL"), + StakePoolError::ReserveDepleted => msg!("Error: Pool reserve does not have enough lamports to fund rent-exempt reserve in split destination. Deposit more SOL in reserve, or pre-fund split destination with the rent-exempt reserve for a stake account."), } } } diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index b5cf20ac..0682e30a 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -1890,6 +1890,7 @@ impl StakePoolAccounts { &self.staker.pubkey(), &self.withdraw_authority, &self.validator_list.pubkey(), + &self.reserve_stake.pubkey(), source_validator_stake, source_transient_stake, ephemeral_stake, diff --git a/program/tests/redelegate.rs b/program/tests/redelegate.rs index 5645baf8..707b7067 100644 --- a/program/tests/redelegate.rs +++ b/program/tests/redelegate.rs @@ -48,7 +48,7 @@ async fn setup( &mut context.banks_client, &context.payer, &context.last_blockhash, - MINIMUM_RESERVE_LAMPORTS + current_minimum_delegation + stake_rent, + MINIMUM_RESERVE_LAMPORTS + current_minimum_delegation + stake_rent * 2, ) .await .unwrap(); @@ -71,7 +71,7 @@ async fn setup( ) .await; - let minimum_redelegate_lamports = current_minimum_delegation + stake_rent * 2; + let minimum_redelegate_lamports = current_minimum_delegation + stake_rent; simple_deposit_stake( &mut context.banks_client, &context.payer, @@ -212,7 +212,22 @@ async fn success() { assert_eq!(source_transient_stake_account.lamports, stake_rent); let transient_delegation = transient_stake_state.delegation().unwrap(); assert_ne!(transient_delegation.deactivation_epoch, Epoch::MAX); - assert_eq!(transient_delegation.stake, redelegate_lamports - stake_rent); + assert_eq!(transient_delegation.stake, redelegate_lamports); + + // Check reserve stake + let current_minimum_delegation = stake_pool_get_minimum_delegation( + &mut context.banks_client, + &context.payer, + &last_blockhash, + ) + .await; + let reserve_lamports = MINIMUM_RESERVE_LAMPORTS + current_minimum_delegation + stake_rent * 2; + let reserve_stake_account = get_account( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + ) + .await; + assert_eq!(reserve_stake_account.lamports, reserve_lamports); // Check ephemeral account doesn't exist let maybe_account = context @@ -232,15 +247,12 @@ async fn success() { deserialize::(&destination_transient_stake_account.data).unwrap(); assert_eq!( destination_transient_stake_account.lamports, - redelegate_lamports - stake_rent + redelegate_lamports ); let transient_delegation = transient_stake_state.delegation().unwrap(); assert_eq!(transient_delegation.deactivation_epoch, Epoch::MAX); assert_ne!(transient_delegation.activation_epoch, Epoch::MAX); - assert_eq!( - transient_delegation.stake, - redelegate_lamports - stake_rent * 2 - ); + assert_eq!(transient_delegation.stake, redelegate_lamports - stake_rent); // Check validator list let validator_list = stake_pool_accounts @@ -324,7 +336,7 @@ async fn success() { assert_eq!(u64::from(destination_item.transient_stake_lamports), 0); assert_eq!( u64::from(destination_item.active_stake_lamports), - pre_destination_validator_stake_account.lamports + redelegate_lamports - stake_rent * 2 + pre_destination_validator_stake_account.lamports + redelegate_lamports - stake_rent ); let post_destination_validator_stake_account = get_account( &mut context.banks_client, @@ -333,7 +345,18 @@ async fn success() { .await; assert_eq!( post_destination_validator_stake_account.lamports, - pre_destination_validator_stake_account.lamports + redelegate_lamports - stake_rent * 2 + pre_destination_validator_stake_account.lamports + redelegate_lamports - stake_rent + ); + + // Check reserve stake, which has claimed back all rent-exempt reserves + let reserve_stake_account = get_account( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + ) + .await; + assert_eq!( + reserve_stake_account.lamports, + reserve_lamports + stake_rent * 2 ); } @@ -477,10 +500,9 @@ async fn success_with_increasing_stake() { .await; let transient_stake_state = deserialize::(&destination_transient_stake_account.data).unwrap(); - // stake rent cancels out assert_eq!( destination_transient_stake_account.lamports, - redelegate_lamports + current_minimum_delegation + redelegate_lamports + current_minimum_delegation + stake_rent ); let transient_delegation = transient_stake_state.delegation().unwrap(); @@ -488,9 +510,17 @@ async fn success_with_increasing_stake() { assert_ne!(transient_delegation.activation_epoch, Epoch::MAX); assert_eq!( transient_delegation.stake, - redelegate_lamports + current_minimum_delegation - stake_rent + redelegate_lamports + current_minimum_delegation ); + // Check reserve stake + let reserve_stake_account = get_account( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + ) + .await; + assert_eq!(reserve_stake_account.lamports, stake_rent); + // Check validator list let validator_list = stake_pool_accounts .get_validator_list(&mut context.banks_client) @@ -540,12 +570,11 @@ async fn success_with_increasing_stake() { .find(&destination_validator_stake.vote.pubkey()) .unwrap(); assert_eq!(u64::from(destination_item.transient_stake_lamports), 0); - // redelegate is smart enough to activate *everything*, so there's only one rent-exemption + // redelegate is smart enough to activate *everything*, so there's no rent-exemption // worth of inactive stake! assert_eq!( u64::from(destination_item.active_stake_lamports), pre_validator_stake_account.lamports + redelegate_lamports + current_minimum_delegation - - stake_rent ); let post_validator_stake_account = get_account( &mut context.banks_client, @@ -555,8 +584,16 @@ async fn success_with_increasing_stake() { assert_eq!( post_validator_stake_account.lamports, pre_validator_stake_account.lamports + redelegate_lamports + current_minimum_delegation - - stake_rent ); + + // Check reserve has claimed back rent-exempt reserve from both transient + // accounts + let reserve_stake_account = get_account( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + ) + .await; + assert_eq!(reserve_stake_account.lamports, stake_rent * 3); } #[tokio::test] @@ -690,6 +727,7 @@ async fn fail_with_wrong_withdraw_authority() { &stake_pool_accounts.staker.pubkey(), &wrong_withdraw_authority, &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), &source_validator_stake.stake_account, &source_validator_stake.transient_stake_account, &ephemeral_stake, @@ -750,6 +788,7 @@ async fn fail_with_wrong_validator_list() { &stake_pool_accounts.staker.pubkey(), &stake_pool_accounts.withdraw_authority, &wrong_validator_list, + &stake_pool_accounts.reserve_stake.pubkey(), &source_validator_stake.stake_account, &source_validator_stake.transient_stake_account, &ephemeral_stake, @@ -782,6 +821,67 @@ async fn fail_with_wrong_validator_list() { ); } +#[tokio::test] +async fn fail_with_wrong_reserve() { + let ( + mut context, + last_blockhash, + stake_pool_accounts, + source_validator_stake, + destination_validator_stake, + redelegate_lamports, + _, + ) = setup(true).await; + + let ephemeral_stake_seed = 2; + let ephemeral_stake = find_ephemeral_stake_program_address( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + ephemeral_stake_seed, + ) + .0; + + let wrong_reserve = Keypair::new(); + let transaction = Transaction::new_signed_with_payer( + &[instruction::redelegate( + &id(), + &stake_pool_accounts.stake_pool.pubkey(), + &stake_pool_accounts.staker.pubkey(), + &stake_pool_accounts.withdraw_authority, + &stake_pool_accounts.validator_list.pubkey(), + &wrong_reserve.pubkey(), + &source_validator_stake.stake_account, + &source_validator_stake.transient_stake_account, + &ephemeral_stake, + &destination_validator_stake.transient_stake_account, + &destination_validator_stake.stake_account, + &destination_validator_stake.vote.pubkey(), + redelegate_lamports, + source_validator_stake.transient_stake_seed, + ephemeral_stake_seed, + destination_validator_stake.transient_stake_seed, + )], + Some(&context.payer.pubkey()), + &[&context.payer, &stake_pool_accounts.staker], + last_blockhash, + ); + let error = context + .banks_client + .process_transaction(transaction) + .await + .err() + .unwrap() + .unwrap(); + + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::InvalidProgramAddress as u32) + ) + ); +} + #[tokio::test] async fn fail_with_wrong_staker() { let ( @@ -810,6 +910,7 @@ async fn fail_with_wrong_staker() { &wrong_staker.pubkey(), &stake_pool_accounts.withdraw_authority, &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), &source_validator_stake.stake_account, &source_validator_stake.transient_stake_account, &ephemeral_stake, From 612d35549fd946532ed3fff4ed567b5493dca483 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 20 Sep 2023 22:02:53 +0200 Subject: [PATCH 0512/1076] stake-pool: Fund rent-exemption from reserve in `decrease_additional` (#5288) * stake-pool: Fund rent-exemption from reserve in `decrease_additional` * stake-pool-js: Add reserve stake to "decrease additional" * Only withdraw required lamports into split destination * Avoid depleting the reserve * Use actual lamport number from ephemeral account * Cargo fmt * Move error check --- clients/js-legacy/src/index.ts | 1 + clients/js-legacy/src/instructions.ts | 3 + program/src/error.rs | 3 + program/src/instruction.rs | 29 +++++--- program/src/processor.rs | 56 ++++++++++++-- program/tests/decrease.rs | 102 +++++++++++++++++++++----- program/tests/helpers/mod.rs | 1 + 7 files changed, 159 insertions(+), 36 deletions(-) diff --git a/clients/js-legacy/src/index.ts b/clients/js-legacy/src/index.ts index 4e932033..a65274ef 100644 --- a/clients/js-legacy/src/index.ts +++ b/clients/js-legacy/src/index.ts @@ -795,6 +795,7 @@ export async function decreaseValidatorStake( stakePool: stakePoolAddress, staker: stakePool.account.data.staker, validatorList: stakePool.account.data.validatorList, + reserveStake: stakePool.account.data.reserveStake, transientStakeSeed: transientStakeSeed.toNumber(), withdrawAuthority, validatorStake, diff --git a/clients/js-legacy/src/instructions.ts b/clients/js-legacy/src/instructions.ts index 2a8fc9af..7c1d645a 100644 --- a/clients/js-legacy/src/instructions.ts +++ b/clients/js-legacy/src/instructions.ts @@ -226,6 +226,7 @@ export type DecreaseValidatorStakeParams = { }; export interface DecreaseAdditionalValidatorStakeParams extends DecreaseValidatorStakeParams { + reserveStake: PublicKey; ephemeralStake: PublicKey; ephemeralStakeSeed: number; } @@ -612,6 +613,7 @@ export class StakePoolInstruction { staker, withdrawAuthority, validatorList, + reserveStake, validatorStake, transientStake, lamports, @@ -628,6 +630,7 @@ export class StakePoolInstruction { { pubkey: staker, isSigner: true, isWritable: false }, { pubkey: withdrawAuthority, isSigner: false, isWritable: false }, { pubkey: validatorList, isSigner: false, isWritable: true }, + { pubkey: reserveStake, isSigner: false, isWritable: true }, { pubkey: validatorStake, isSigner: false, isWritable: true }, { pubkey: ephemeralStake, isSigner: false, isWritable: true }, { pubkey: transientStake, isSigner: false, isWritable: true }, diff --git a/program/src/error.rs b/program/src/error.rs index 9433a230..83bcb1a0 100644 --- a/program/src/error.rs +++ b/program/src/error.rs @@ -154,6 +154,9 @@ pub enum StakePoolError { /// the rent-exempt reserve for a stake account. #[error("ReserveDepleted")] ReserveDepleted, + /// Missing required sysvar account + #[error("Missing required sysvar account")] + MissingRequiredSysvar, } impl From for ProgramError { fn from(e: StakePoolError) -> Self { diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 6a0f6ad0..6e9c5788 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -446,24 +446,28 @@ pub enum StakePoolInstruction { /// /// Works regardless if the transient stake account already exists. /// - /// Internally, this instruction splits a validator stake account into an - /// ephemeral stake account, deactivates it, then merges or splits it into - /// the transient stake account delegated to the appropriate validator. + /// Internally, this instruction: + /// * withdraws rent-exempt reserve lamports from the reserve into the ephemeral stake + /// * splits a validator stake account into an ephemeral stake account + /// * deactivates the ephemeral account + /// * merges or splits the ephemeral account into the transient stake account + /// delegated to the appropriate validator /// - /// The amount of lamports to move must be at least rent-exemption plus + /// The amount of lamports to move must be at least /// `max(crate::MINIMUM_ACTIVE_STAKE, solana_program::stake::tools::get_minimum_delegation())`. /// /// 0. `[]` Stake pool /// 1. `[s]` Stake pool staker /// 2. `[]` Stake pool withdraw authority /// 3. `[w]` Validator list - /// 4. `[w]` Canonical stake account to split from - /// 5. `[w]` Uninitialized ephemeral stake account to receive stake - /// 6. `[w]` Transient stake account - /// 7. `[]` Clock sysvar - /// 8. '[]' Stake history sysvar - /// 9. `[]` System program - /// 10. `[]` Stake program + /// 4. `[w]` Reserve stake account, to fund rent exempt reserve + /// 5. `[w]` Canonical stake account to split from + /// 6. `[w]` Uninitialized ephemeral stake account to receive stake + /// 7. `[w]` Transient stake account + /// 8. `[]` Clock sysvar + /// 9. '[]' Stake history sysvar + /// 10. `[]` System program + /// 11. `[]` Stake program DecreaseAdditionalValidatorStake { /// amount of lamports to split into the transient stake account lamports: u64, @@ -793,6 +797,7 @@ pub fn decrease_additional_validator_stake( staker: &Pubkey, stake_pool_withdraw_authority: &Pubkey, validator_list: &Pubkey, + reserve_stake: &Pubkey, validator_stake: &Pubkey, ephemeral_stake: &Pubkey, transient_stake: &Pubkey, @@ -805,6 +810,7 @@ pub fn decrease_additional_validator_stake( AccountMeta::new_readonly(*staker, true), AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), AccountMeta::new(*validator_list, false), + AccountMeta::new(*reserve_stake, false), AccountMeta::new(*validator_stake, false), AccountMeta::new(*ephemeral_stake, false), AccountMeta::new(*transient_stake, false), @@ -1211,6 +1217,7 @@ pub fn decrease_additional_validator_stake_with_vote( &stake_pool.staker, &pool_withdraw_authority, &stake_pool.validator_list, + &stake_pool.reserve_stake, &validator_stake_address, &ephemeral_stake_address, &transient_stake_address, diff --git a/program/src/processor.rs b/program/src/processor.rs index 2024d674..938fcf17 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1241,12 +1241,16 @@ impl Processor { lamports: u64, transient_stake_seed: u64, maybe_ephemeral_stake_seed: Option, + fund_rent_exempt_reserve: bool, ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let stake_pool_info = next_account_info(account_info_iter)?; let staker_info = next_account_info(account_info_iter)?; let withdraw_authority_info = next_account_info(account_info_iter)?; let validator_list_info = next_account_info(account_info_iter)?; + let maybe_reserve_stake_info = fund_rent_exempt_reserve + .then(|| next_account_info(account_info_iter)) + .transpose()?; let validator_stake_account_info = next_account_info(account_info_iter)?; let maybe_ephemeral_stake_account_info = maybe_ephemeral_stake_seed .map(|_| next_account_info(account_info_iter)) @@ -1298,6 +1302,10 @@ impl Processor { return Err(StakePoolError::InvalidState.into()); } + if let Some(reserve_stake_info) = maybe_reserve_stake_info { + stake_pool.check_reserve_stake(reserve_stake_info)?; + } + let (meta, stake) = get_stake_state(validator_stake_account_info)?; let vote_account_address = stake.delegation.voter_pubkey; @@ -1339,10 +1347,10 @@ impl Processor { } let stake_space = std::mem::size_of::(); - let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; let stake_rent = rent.minimum_balance(stake_space); - let current_minimum_lamports = - stake_rent.saturating_add(minimum_delegation(stake_minimum_delegation)); + + let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; + let current_minimum_lamports = minimum_delegation(stake_minimum_delegation); if lamports < current_minimum_lamports { msg!( "Need at least {} lamports for transient stake to meet minimum delegation and rent-exempt requirements, {} provided", @@ -1366,7 +1374,7 @@ impl Processor { return Err(ProgramError::InsufficientFunds); } - let source_stake_account_info = + let (source_stake_account_info, split_lamports) = if let Some((ephemeral_stake_seed, ephemeral_stake_account_info)) = maybe_ephemeral_stake_seed.zip(maybe_ephemeral_stake_account_info) { @@ -1388,6 +1396,30 @@ impl Processor { stake_space, )?; + // if needed, withdraw rent-exempt reserve for ephemeral account + if let Some(reserve_stake_info) = maybe_reserve_stake_info { + let required_lamports_for_rent_exemption = + stake_rent.saturating_sub(ephemeral_stake_account_info.lamports()); + if required_lamports_for_rent_exemption > 0 { + if required_lamports_for_rent_exemption >= reserve_stake_info.lamports() { + return Err(StakePoolError::ReserveDepleted.into()); + } + let stake_history_info = maybe_stake_history_info + .ok_or(StakePoolError::MissingRequiredSysvar)?; + Self::stake_withdraw( + stake_pool_info.key, + reserve_stake_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + ephemeral_stake_account_info.clone(), + clock_info.clone(), + stake_history_info.clone(), + required_lamports_for_rent_exemption, + )?; + } + } + // split into ephemeral stake account Self::stake_split( stake_pool_info.key, @@ -1408,11 +1440,14 @@ impl Processor { stake_pool.stake_withdraw_bump_seed, )?; - ephemeral_stake_account_info + ( + ephemeral_stake_account_info, + ephemeral_stake_account_info.lamports(), + ) } else { // if no ephemeral account is provided, split everything from the // validator stake account, into the transient stake account - validator_stake_account_info + (validator_stake_account_info, lamports) }; let transient_stake_bump_seed = check_transient_stake_address( @@ -1459,7 +1494,7 @@ impl Processor { withdraw_authority_info.clone(), AUTHORITY_WITHDRAW, stake_pool.stake_withdraw_bump_seed, - lamports, + split_lamports, transient_stake_account_info.clone(), )?; @@ -1482,9 +1517,11 @@ impl Processor { .checked_sub(lamports) .ok_or(StakePoolError::CalculationFailure)? .into(); + // `split_lamports` may be greater than `lamports` if the reserve stake + // funded the rent-exempt reserve validator_stake_info.transient_stake_lamports = u64::from(validator_stake_info.transient_stake_lamports) - .checked_add(lamports) + .checked_add(split_lamports) .ok_or(StakePoolError::CalculationFailure)? .into(); validator_stake_info.transient_seed_suffix = transient_stake_seed.into(); @@ -3811,6 +3848,7 @@ impl Processor { lamports, transient_stake_seed, None, + false, ) } StakePoolInstruction::DecreaseAdditionalValidatorStake { @@ -3825,6 +3863,7 @@ impl Processor { lamports, transient_stake_seed, Some(ephemeral_stake_seed), + true, ) } StakePoolInstruction::IncreaseValidatorStake { @@ -4038,6 +4077,7 @@ impl PrintProgramError for StakePoolError { StakePoolError::ExceededSlippage => msg!("Error: instruction exceeds desired slippage limit"), StakePoolError::IncorrectMintDecimals => msg!("Error: Provided mint does not have 9 decimals to match SOL"), StakePoolError::ReserveDepleted => msg!("Error: Pool reserve does not have enough lamports to fund rent-exempt reserve in split destination. Deposit more SOL in reserve, or pre-fund split destination with the rent-exempt reserve for a stake account."), + StakePoolError::MissingRequiredSysvar => msg!("Missing required sysvar account"), } } } diff --git a/program/tests/decrease.rs b/program/tests/decrease.rs index e20e752e..493e75ad 100644 --- a/program/tests/decrease.rs +++ b/program/tests/decrease.rs @@ -25,6 +25,7 @@ async fn setup() -> ( ValidatorStakeAccount, DepositStakeAccount, u64, + u64, ) { let mut context = program_test().start_with_context().await; let rent = context.banks_client.get_rent().await.unwrap(); @@ -37,12 +38,13 @@ async fn setup() -> ( .await; let stake_pool_accounts = StakePoolAccounts::default(); + let reserve_lamports = MINIMUM_RESERVE_LAMPORTS + stake_rent + current_minimum_delegation; stake_pool_accounts .initialize_stake_pool( &mut context.banks_client, &context.payer, &context.last_blockhash, - MINIMUM_RESERVE_LAMPORTS + stake_rent + current_minimum_delegation, + reserve_lamports, ) .await .unwrap(); @@ -74,6 +76,7 @@ async fn setup() -> ( validator_stake_account, deposit_info, decrease_lamports, + reserve_lamports + stake_rent, ) } @@ -81,8 +84,14 @@ async fn setup() -> ( #[test_case(false; "no-additional")] #[tokio::test] async fn success(use_additional_instruction: bool) { - let (mut context, stake_pool_accounts, validator_stake, _deposit_info, decrease_lamports) = - setup().await; + let ( + mut context, + stake_pool_accounts, + validator_stake, + _deposit_info, + decrease_lamports, + reserve_lamports, + ) = setup().await; // Save validator stake let pre_validator_stake_account = @@ -128,6 +137,9 @@ async fn success(use_additional_instruction: bool) { ); // Check transient stake account state and balance + let rent = context.banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let transient_stake_account = get_account( &mut context.banks_client, &validator_stake.transient_stake_account, @@ -135,7 +147,23 @@ async fn success(use_additional_instruction: bool) { .await; let transient_stake_state = deserialize::(&transient_stake_account.data).unwrap(); - assert_eq!(transient_stake_account.lamports, decrease_lamports); + let transient_lamports = if use_additional_instruction { + decrease_lamports + stake_rent + } else { + decrease_lamports + }; + assert_eq!(transient_stake_account.lamports, transient_lamports); + let reserve_lamports = if use_additional_instruction { + reserve_lamports - stake_rent + } else { + reserve_lamports + }; + let reserve_stake_account = get_account( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + ) + .await; + assert_eq!(reserve_stake_account.lamports, reserve_lamports); assert_ne!( transient_stake_state .delegation() @@ -147,7 +175,7 @@ async fn success(use_additional_instruction: bool) { #[tokio::test] async fn fail_with_wrong_withdraw_authority() { - let (mut context, stake_pool_accounts, validator_stake, _deposit_info, decrease_lamports) = + let (mut context, stake_pool_accounts, validator_stake, _deposit_info, decrease_lamports, _) = setup().await; let wrong_authority = Pubkey::new_unique(); @@ -187,8 +215,14 @@ async fn fail_with_wrong_withdraw_authority() { #[tokio::test] async fn fail_with_wrong_validator_list() { - let (mut context, mut stake_pool_accounts, validator_stake, _deposit_info, decrease_lamports) = - setup().await; + let ( + mut context, + mut stake_pool_accounts, + validator_stake, + _deposit_info, + decrease_lamports, + _, + ) = setup().await; stake_pool_accounts.validator_list = Keypair::new(); @@ -227,7 +261,7 @@ async fn fail_with_wrong_validator_list() { #[tokio::test] async fn fail_with_unknown_validator() { - let (mut context, stake_pool_accounts, _validator_stake, _deposit_info, decrease_lamports) = + let (mut context, stake_pool_accounts, _validator_stake, _deposit_info, decrease_lamports, _) = setup().await; let unknown_stake = create_unknown_validator_stake( @@ -276,7 +310,7 @@ async fn fail_with_unknown_validator() { #[test_case(false; "no-additional")] #[tokio::test] async fn fail_twice_diff_seed(use_additional_instruction: bool) { - let (mut context, stake_pool_accounts, validator_stake, _deposit_info, decrease_lamports) = + let (mut context, stake_pool_accounts, validator_stake, _deposit_info, decrease_lamports, _) = setup().await; let error = stake_pool_accounts @@ -337,12 +371,21 @@ async fn fail_twice_diff_seed(use_additional_instruction: bool) { #[test_case(false, false, false; "fail-no-additional")] #[tokio::test] async fn twice(success: bool, use_additional_first_time: bool, use_additional_second_time: bool) { - let (mut context, stake_pool_accounts, validator_stake, _deposit_info, decrease_lamports) = - setup().await; + let ( + mut context, + stake_pool_accounts, + validator_stake, + _deposit_info, + decrease_lamports, + mut reserve_lamports, + ) = setup().await; let pre_stake_account = get_account(&mut context.banks_client, &validator_stake.stake_account).await; + let rent = context.banks_client.get_rent().await.unwrap(); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let first_decrease = decrease_lamports / 3; let second_decrease = decrease_lamports / 2; let total_decrease = first_decrease + second_decrease; @@ -410,7 +453,14 @@ async fn twice(success: bool, use_additional_first_time: bool, use_additional_se .await; let transient_stake_state = deserialize::(&transient_stake_account.data).unwrap(); - assert_eq!(transient_stake_account.lamports, total_decrease); + let mut transient_lamports = total_decrease; + if use_additional_first_time { + transient_lamports += stake_rent; + } + if use_additional_second_time { + transient_lamports += stake_rent; + } + assert_eq!(transient_stake_account.lamports, transient_lamports); assert_ne!( transient_stake_state .delegation() @@ -424,7 +474,24 @@ async fn twice(success: bool, use_additional_first_time: bool, use_additional_se .get_validator_list(&mut context.banks_client) .await; let entry = validator_list.find(&validator_stake.vote.pubkey()).unwrap(); - assert_eq!(u64::from(entry.transient_stake_lamports), total_decrease); + assert_eq!( + u64::from(entry.transient_stake_lamports), + transient_lamports + ); + + // reserve deducted properly + if use_additional_first_time { + reserve_lamports -= stake_rent; + } + if use_additional_second_time { + reserve_lamports -= stake_rent; + } + let reserve_stake_account = get_account( + &mut context.banks_client, + &stake_pool_accounts.reserve_stake.pubkey(), + ) + .await; + assert_eq!(reserve_stake_account.lamports, reserve_lamports); } else { let error = error.unwrap().unwrap(); assert_eq!( @@ -441,7 +508,7 @@ async fn twice(success: bool, use_additional_first_time: bool, use_additional_se #[test_case(false; "no-additional")] #[tokio::test] async fn fail_with_small_lamport_amount(use_additional_instruction: bool) { - let (mut context, stake_pool_accounts, validator_stake, _deposit_info, _decrease_lamports) = + let (mut context, stake_pool_accounts, validator_stake, _deposit_info, _decrease_lamports, _) = setup().await; let rent = context.banks_client.get_rent().await.unwrap(); @@ -470,7 +537,7 @@ async fn fail_with_small_lamport_amount(use_additional_instruction: bool) { #[tokio::test] async fn fail_big_overdraw() { - let (mut context, stake_pool_accounts, validator_stake, deposit_info, _decrease_lamports) = + let (mut context, stake_pool_accounts, validator_stake, deposit_info, _decrease_lamports, _) = setup().await; let error = stake_pool_accounts @@ -497,7 +564,7 @@ async fn fail_big_overdraw() { #[test_case(false; "no-additional")] #[tokio::test] async fn fail_overdraw(use_additional_instruction: bool) { - let (mut context, stake_pool_accounts, validator_stake, deposit_info, _decrease_lamports) = + let (mut context, stake_pool_accounts, validator_stake, deposit_info, _decrease_lamports, _) = setup().await; let rent = context.banks_client.get_rent().await.unwrap(); @@ -526,7 +593,8 @@ async fn fail_overdraw(use_additional_instruction: bool) { #[tokio::test] async fn fail_additional_with_increasing() { - let (mut context, stake_pool_accounts, validator_stake, _, decrease_lamports) = setup().await; + let (mut context, stake_pool_accounts, validator_stake, _, decrease_lamports, _) = + setup().await; let current_minimum_delegation = stake_pool_get_minimum_delegation( &mut context.banks_client, diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 0682e30a..4dccee90 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -1668,6 +1668,7 @@ impl StakePoolAccounts { &self.staker.pubkey(), &self.withdraw_authority, &self.validator_list.pubkey(), + &self.reserve_stake.pubkey(), validator_stake, ephemeral_stake, transient_stake, From 1238f2d8d5180c00d5eeb25da4f19b99d3b9de9f Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 21 Sep 2023 10:44:57 +0200 Subject: [PATCH 0513/1076] Bump repo to 1.16.13 (#5324) * Run update script * Update everything to use non-deprecated functions --- clients/cli/Cargo.toml | 18 +++++++++--------- clients/cli/src/client.rs | 4 +++- clients/cli/src/main.rs | 2 +- program/Cargo.toml | 8 ++++---- program/src/instruction.rs | 4 ++++ program/src/processor.rs | 2 +- program/src/state.rs | 4 ++-- program/tests/deposit.rs | 2 +- program/tests/deposit_authority.rs | 2 +- program/tests/deposit_edge_cases.rs | 2 +- program/tests/deposit_sol.rs | 2 +- program/tests/helpers/mod.rs | 4 ++-- program/tests/huge_pool.rs | 2 +- program/tests/initialize.rs | 2 +- program/tests/set_deposit_fee.rs | 2 +- program/tests/set_epoch_fee.rs | 2 +- program/tests/set_funding_authority.rs | 2 +- program/tests/set_manager.rs | 2 +- program/tests/set_preferred.rs | 2 +- program/tests/set_referral_fee.rs | 2 +- program/tests/set_staker.rs | 2 +- program/tests/set_withdrawal_fee.rs | 2 +- program/tests/update_stake_pool_balance.rs | 2 +- program/tests/update_validator_list_balance.rs | 2 +- .../update_validator_list_balance_hijack.rs | 2 +- program/tests/vsa_add.rs | 5 ++++- program/tests/vsa_remove.rs | 2 +- program/tests/withdraw.rs | 2 +- program/tests/withdraw_edge_cases.rs | 2 +- program/tests/withdraw_sol.rs | 2 +- program/tests/withdraw_with_fee.rs | 2 +- 31 files changed, 52 insertions(+), 43 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 532e9568..8492beca 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -14,15 +14,15 @@ clap = "2.33.3" serde = "1.0.188" serde_derive = "1.0.130" serde_json = "1.0.107" -solana-account-decoder = "=1.16.3" -solana-clap-utils = "=1.16.3" -solana-cli-config = "=1.16.3" -solana-cli-output = "=1.16.3" -solana-client = "=1.16.3" -solana-logger = "=1.16.3" -solana-program = "=1.16.3" -solana-remote-wallet = "=1.16.3" -solana-sdk = "=1.16.3" +solana-account-decoder = "=1.16.13" +solana-clap-utils = "=1.16.13" +solana-cli-config = "=1.16.13" +solana-cli-output = "=1.16.13" +solana-client = "=1.16.13" +solana-logger = "=1.16.13" +solana-program = "=1.16.13" +solana-remote-wallet = "=1.16.13" +solana-sdk = "=1.16.13" spl-associated-token-account = { version = "=2.1", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "=0.7.0", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "=4.0", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/clients/cli/src/client.rs b/clients/cli/src/client.rs index 039d057c..444e4608 100644 --- a/clients/cli/src/client.rs +++ b/clients/cli/src/client.rs @@ -7,7 +7,9 @@ use { rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig}, rpc_filter::{Memcmp, RpcFilterType}, }, - solana_program::{borsh::try_from_slice_unchecked, program_pack::Pack, pubkey::Pubkey, stake}, + solana_program::{ + borsh0_10::try_from_slice_unchecked, program_pack::Pack, pubkey::Pubkey, stake, + }, spl_stake_pool::{ find_withdraw_authority_program_address, state::{StakePool, ValidatorList}, diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 2ca68eba..37c8cb50 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -23,7 +23,7 @@ use { solana_cli_output::OutputFormat, solana_client::rpc_client::RpcClient, solana_program::{ - borsh::{get_instance_packed_len, get_packed_len}, + borsh0_10::{get_instance_packed_len, get_packed_len}, instruction::Instruction, program_pack::Pack, pubkey::Pubkey, diff --git a/program/Cargo.toml b/program/Cargo.toml index 90ec865c..f90b0675 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -20,7 +20,7 @@ num-traits = "0.2" num_enum = "0.7.0" serde = "1.0.188" serde_derive = "1.0.103" -solana-program = "1.16.3" +solana-program = "1.16.13" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-pod = { version = "0.1", path = "../../libraries/pod", features = ["borsh"] } spl-token-2022 = { version = "0.8", path = "../../token/program-2022", features = [ "no-entrypoint" ] } @@ -29,9 +29,9 @@ bincode = "1.3.1" [dev-dependencies] proptest = "1.2" -solana-program-test = "1.16.3" -solana-sdk = "1.16.3" -solana-vote-program = "1.16.3" +solana-program-test = "1.16.13" +solana-sdk = "1.16.13" +solana-vote-program = "1.16.13" spl-token = { version = "4.0", path = "../../token/program", features = [ "no-entrypoint" ] } test-case = "3.2" diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 6e9c5788..46d11255 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -709,6 +709,7 @@ pub fn add_validator_to_pool( AccountMeta::new_readonly(sysvar::rent::id(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), + #[allow(deprecated)] AccountMeta::new_readonly(stake::config::id(), false), AccountMeta::new_readonly(system_program::id(), false), AccountMeta::new_readonly(stake::program::id(), false), @@ -859,6 +860,7 @@ pub fn increase_validator_stake( AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::rent::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), + #[allow(deprecated)] AccountMeta::new_readonly(stake::config::id(), false), AccountMeta::new_readonly(system_program::id(), false), AccountMeta::new_readonly(stake::program::id(), false), @@ -904,6 +906,7 @@ pub fn increase_additional_validator_stake( AccountMeta::new_readonly(*validator, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), + #[allow(deprecated)] AccountMeta::new_readonly(stake::config::id(), false), AccountMeta::new_readonly(system_program::id(), false), AccountMeta::new_readonly(stake::program::id(), false), @@ -954,6 +957,7 @@ pub fn redelegate( AccountMeta::new_readonly(*validator, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), + #[allow(deprecated)] AccountMeta::new_readonly(stake::config::id(), false), AccountMeta::new_readonly(system_program::id(), false), AccountMeta::new_readonly(stake::program::id(), false), diff --git a/program/src/processor.rs b/program/src/processor.rs index 938fcf17..17ed181a 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -24,7 +24,7 @@ use { num_traits::FromPrimitive, solana_program::{ account_info::{next_account_info, AccountInfo}, - borsh::try_from_slice_unchecked, + borsh0_10::try_from_slice_unchecked, clock::{Clock, Epoch}, decode_error::DecodeError, entrypoint::ProgramResult, diff --git a/program/src/state.rs b/program/src/state.rs index 50883228..7d12add0 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -11,7 +11,7 @@ use { num_traits::{FromPrimitive, ToPrimitive}, solana_program::{ account_info::AccountInfo, - borsh::get_instance_packed_len, + borsh0_10::get_instance_packed_len, msg, program_error::ProgramError, program_memory::sol_memcmp, @@ -1035,7 +1035,7 @@ mod test { super::*, proptest::prelude::*, solana_program::{ - borsh::{get_instance_packed_len, get_packed_len, try_from_slice_unchecked}, + borsh0_10::{get_packed_len, try_from_slice_unchecked}, clock::{DEFAULT_SLOTS_PER_EPOCH, DEFAULT_S_PER_SLOT, SECONDS_PER_DAY}, native_token::LAMPORTS_PER_SOL, }, diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 61c0222d..2bd29b40 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -7,7 +7,7 @@ use { borsh::BorshSerialize, helpers::*, solana_program::{ - borsh::try_from_slice_unchecked, + borsh0_10::try_from_slice_unchecked, instruction::{AccountMeta, Instruction, InstructionError}, pubkey::Pubkey, stake, sysvar, diff --git a/program/tests/deposit_authority.rs b/program/tests/deposit_authority.rs index c0e4aaee..55665572 100644 --- a/program/tests/deposit_authority.rs +++ b/program/tests/deposit_authority.rs @@ -8,7 +8,7 @@ use { solana_program::{instruction::InstructionError, stake}, solana_program_test::*, solana_sdk::{ - borsh::try_from_slice_unchecked, + borsh0_10::try_from_slice_unchecked, signature::{Keypair, Signer}, transaction::TransactionError, }, diff --git a/program/tests/deposit_edge_cases.rs b/program/tests/deposit_edge_cases.rs index df9bd30d..bd549805 100644 --- a/program/tests/deposit_edge_cases.rs +++ b/program/tests/deposit_edge_cases.rs @@ -6,7 +6,7 @@ mod helpers; use { helpers::*, solana_program::{ - borsh::try_from_slice_unchecked, instruction::InstructionError, pubkey::Pubkey, stake, + borsh0_10::try_from_slice_unchecked, instruction::InstructionError, pubkey::Pubkey, stake, }, solana_program_test::*, solana_sdk::{ diff --git a/program/tests/deposit_sol.rs b/program/tests/deposit_sol.rs index 90dd6c96..7fefde70 100644 --- a/program/tests/deposit_sol.rs +++ b/program/tests/deposit_sol.rs @@ -6,7 +6,7 @@ mod helpers; use { helpers::*, solana_program::{ - borsh::try_from_slice_unchecked, instruction::InstructionError, pubkey::Pubkey, + borsh0_10::try_from_slice_unchecked, instruction::InstructionError, pubkey::Pubkey, }, solana_program_test::*, solana_sdk::{ diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 4dccee90..a07eec40 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -3,7 +3,7 @@ use { borsh::{BorshDeserialize, BorshSerialize}, solana_program::{ - borsh::{get_instance_packed_len, get_packed_len, try_from_slice_unchecked}, + borsh0_10::{get_instance_packed_len, get_packed_len, try_from_slice_unchecked}, hash::Hash, instruction::Instruction, program_option::COption, @@ -2377,7 +2377,7 @@ pub fn add_validator_stake_account( stake: stake_amount, activation_epoch: FIRST_NORMAL_EPOCH, deactivation_epoch: u64::MAX, - warmup_cooldown_rate: 0.25, // default + ..Default::default() }, credits_observed: 0, }; diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index 9990ee37..1fd94683 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -5,7 +5,7 @@ mod helpers; use { helpers::*, - solana_program::{borsh::try_from_slice_unchecked, pubkey::Pubkey, stake}, + solana_program::{borsh0_10::try_from_slice_unchecked, pubkey::Pubkey, stake}, solana_program_test::*, solana_sdk::{ native_token::LAMPORTS_PER_SOL, diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index 55e7c2fb..5d0baba6 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -7,7 +7,7 @@ use { borsh::BorshSerialize, helpers::*, solana_program::{ - borsh::{get_instance_packed_len, get_packed_len, try_from_slice_unchecked}, + borsh0_10::{get_instance_packed_len, get_packed_len, try_from_slice_unchecked}, hash::Hash, instruction::{AccountMeta, Instruction}, program_pack::Pack, diff --git a/program/tests/set_deposit_fee.rs b/program/tests/set_deposit_fee.rs index 85397ffb..b8cbd286 100644 --- a/program/tests/set_deposit_fee.rs +++ b/program/tests/set_deposit_fee.rs @@ -7,7 +7,7 @@ use { helpers::*, solana_program_test::*, solana_sdk::{ - borsh::try_from_slice_unchecked, + borsh0_10::try_from_slice_unchecked, instruction::InstructionError, signature::{Keypair, Signer}, transaction::{Transaction, TransactionError}, diff --git a/program/tests/set_epoch_fee.rs b/program/tests/set_epoch_fee.rs index d1c5dc94..ccdb6b8d 100644 --- a/program/tests/set_epoch_fee.rs +++ b/program/tests/set_epoch_fee.rs @@ -7,7 +7,7 @@ use { helpers::*, solana_program_test::*, solana_sdk::{ - borsh::try_from_slice_unchecked, + borsh0_10::try_from_slice_unchecked, instruction::InstructionError, signature::{Keypair, Signer}, transaction::{Transaction, TransactionError}, diff --git a/program/tests/set_funding_authority.rs b/program/tests/set_funding_authority.rs index 5fe7b8a9..6e091562 100644 --- a/program/tests/set_funding_authority.rs +++ b/program/tests/set_funding_authority.rs @@ -7,7 +7,7 @@ use { borsh::BorshSerialize, helpers::*, solana_program::{ - borsh::try_from_slice_unchecked, + borsh0_10::try_from_slice_unchecked, hash::Hash, instruction::{AccountMeta, Instruction}, }, diff --git a/program/tests/set_manager.rs b/program/tests/set_manager.rs index 0dff30aa..0e3416e0 100644 --- a/program/tests/set_manager.rs +++ b/program/tests/set_manager.rs @@ -7,7 +7,7 @@ use { borsh::BorshSerialize, helpers::*, solana_program::{ - borsh::try_from_slice_unchecked, + borsh0_10::try_from_slice_unchecked, hash::Hash, instruction::{AccountMeta, Instruction}, }, diff --git a/program/tests/set_preferred.rs b/program/tests/set_preferred.rs index 04de8196..fffd9bc2 100644 --- a/program/tests/set_preferred.rs +++ b/program/tests/set_preferred.rs @@ -8,7 +8,7 @@ use { solana_program::hash::Hash, solana_program_test::*, solana_sdk::{ - borsh::try_from_slice_unchecked, + borsh0_10::try_from_slice_unchecked, instruction::InstructionError, pubkey::Pubkey, signature::{Keypair, Signer}, diff --git a/program/tests/set_referral_fee.rs b/program/tests/set_referral_fee.rs index 829a2fb6..93c22560 100644 --- a/program/tests/set_referral_fee.rs +++ b/program/tests/set_referral_fee.rs @@ -7,7 +7,7 @@ use { helpers::*, solana_program_test::*, solana_sdk::{ - borsh::try_from_slice_unchecked, + borsh0_10::try_from_slice_unchecked, instruction::InstructionError, signature::{Keypair, Signer}, transaction::{Transaction, TransactionError}, diff --git a/program/tests/set_staker.rs b/program/tests/set_staker.rs index bf30fac6..f2a72fe3 100644 --- a/program/tests/set_staker.rs +++ b/program/tests/set_staker.rs @@ -7,7 +7,7 @@ use { borsh::BorshSerialize, helpers::*, solana_program::{ - borsh::try_from_slice_unchecked, + borsh0_10::try_from_slice_unchecked, hash::Hash, instruction::{AccountMeta, Instruction}, }, diff --git a/program/tests/set_withdrawal_fee.rs b/program/tests/set_withdrawal_fee.rs index 6f0afe68..1d510636 100644 --- a/program/tests/set_withdrawal_fee.rs +++ b/program/tests/set_withdrawal_fee.rs @@ -7,7 +7,7 @@ use { helpers::*, solana_program_test::*, solana_sdk::{ - borsh::try_from_slice_unchecked, + borsh0_10::try_from_slice_unchecked, instruction::InstructionError, signature::{Keypair, Signer}, transaction::{Transaction, TransactionError}, diff --git a/program/tests/update_stake_pool_balance.rs b/program/tests/update_stake_pool_balance.rs index 763c7a80..77612bf2 100644 --- a/program/tests/update_stake_pool_balance.rs +++ b/program/tests/update_stake_pool_balance.rs @@ -6,7 +6,7 @@ mod helpers; use { helpers::*, solana_program::{ - borsh::try_from_slice_unchecked, instruction::InstructionError, pubkey::Pubkey, + borsh0_10::try_from_slice_unchecked, instruction::InstructionError, pubkey::Pubkey, }, solana_program_test::*, solana_sdk::{ diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index 9d494b45..1c6b3369 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -5,7 +5,7 @@ mod helpers; use { helpers::*, - solana_program::{borsh::try_from_slice_unchecked, program_pack::Pack, pubkey::Pubkey}, + solana_program::{borsh0_10::try_from_slice_unchecked, program_pack::Pack, pubkey::Pubkey}, solana_program_test::*, solana_sdk::{hash::Hash, signature::Signer, stake::state::StakeState}, spl_stake_pool::{ diff --git a/program/tests/update_validator_list_balance_hijack.rs b/program/tests/update_validator_list_balance_hijack.rs index 6de06cf3..8ef0e59e 100644 --- a/program/tests/update_validator_list_balance_hijack.rs +++ b/program/tests/update_validator_list_balance_hijack.rs @@ -5,7 +5,7 @@ mod helpers; use { helpers::*, - solana_program::{borsh::try_from_slice_unchecked, pubkey::Pubkey, stake}, + solana_program::{borsh0_10::try_from_slice_unchecked, pubkey::Pubkey, stake}, solana_program_test::*, solana_sdk::{ hash::Hash, diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index 28f40efa..36eb0490 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -8,7 +8,7 @@ use { borsh::BorshSerialize, helpers::*, solana_program::{ - borsh::try_from_slice_unchecked, + borsh0_10::try_from_slice_unchecked, hash::Hash, instruction::{AccountMeta, Instruction, InstructionError}, pubkey::Pubkey, @@ -284,6 +284,7 @@ async fn fail_without_signature() { AccountMeta::new_readonly(sysvar::rent::id(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), + #[allow(deprecated)] AccountMeta::new_readonly(stake::config::id(), false), AccountMeta::new_readonly(system_program::id(), false), AccountMeta::new_readonly(stake::program::id(), false), @@ -339,6 +340,7 @@ async fn fail_with_wrong_stake_program_id() { AccountMeta::new_readonly(sysvar::rent::id(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), + #[allow(deprecated)] AccountMeta::new_readonly(stake::config::id(), false), AccountMeta::new_readonly(system_program::id(), false), AccountMeta::new_readonly(wrong_stake_program, false), @@ -392,6 +394,7 @@ async fn fail_with_wrong_system_program_id() { AccountMeta::new_readonly(sysvar::rent::id(), false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::stake_history::id(), false), + #[allow(deprecated)] AccountMeta::new_readonly(stake::config::id(), false), AccountMeta::new_readonly(wrong_system_program, false), AccountMeta::new_readonly(stake::program::id(), false), diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 6b795b84..18730637 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -7,7 +7,7 @@ use { borsh::BorshSerialize, helpers::*, solana_program::{ - borsh::try_from_slice_unchecked, + borsh0_10::try_from_slice_unchecked, instruction::{AccountMeta, Instruction, InstructionError}, pubkey::Pubkey, stake, system_instruction, sysvar, diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 8b5146c2..3fd44962 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -7,7 +7,7 @@ use { borsh::BorshSerialize, helpers::*, solana_program::{ - borsh::try_from_slice_unchecked, + borsh0_10::try_from_slice_unchecked, instruction::{AccountMeta, Instruction, InstructionError}, pubkey::Pubkey, sysvar, diff --git a/program/tests/withdraw_edge_cases.rs b/program/tests/withdraw_edge_cases.rs index e495fea4..90cb5a7a 100644 --- a/program/tests/withdraw_edge_cases.rs +++ b/program/tests/withdraw_edge_cases.rs @@ -7,7 +7,7 @@ use { bincode::deserialize, helpers::*, solana_program::{ - borsh::try_from_slice_unchecked, instruction::InstructionError, pubkey::Pubkey, stake, + borsh0_10::try_from_slice_unchecked, instruction::InstructionError, pubkey::Pubkey, stake, }, solana_program_test::*, solana_sdk::{signature::Signer, transaction::TransactionError}, diff --git a/program/tests/withdraw_sol.rs b/program/tests/withdraw_sol.rs index 1d61e95e..75c6594f 100644 --- a/program/tests/withdraw_sol.rs +++ b/program/tests/withdraw_sol.rs @@ -6,7 +6,7 @@ mod helpers; use { helpers::*, solana_program::{ - borsh::try_from_slice_unchecked, instruction::InstructionError, pubkey::Pubkey, stake, + borsh0_10::try_from_slice_unchecked, instruction::InstructionError, pubkey::Pubkey, stake, }, solana_program_test::*, solana_sdk::{ diff --git a/program/tests/withdraw_with_fee.rs b/program/tests/withdraw_with_fee.rs index 243e3d4b..1a2b0134 100644 --- a/program/tests/withdraw_with_fee.rs +++ b/program/tests/withdraw_with_fee.rs @@ -6,7 +6,7 @@ mod helpers; use { bincode::deserialize, helpers::*, - solana_program::{borsh::try_from_slice_unchecked, pubkey::Pubkey, stake}, + solana_program::{borsh0_10::try_from_slice_unchecked, pubkey::Pubkey, stake}, solana_program_test::*, solana_sdk::signature::{Keypair, Signer}, spl_stake_pool::{minimum_stake_lamports, state}, From ef5dd0a8de10894545f5b60000767e6fd8dc38e9 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Mon, 25 Sep 2023 19:36:39 +0200 Subject: [PATCH 0514/1076] stake-pool: add new version of `DecreaseValidatorStake` to use reserve, add compatibility with master (#5322) * stake-pool: Fund rent-exemption from reserve during decrease * Update tests to use new instruction * Fix withdrawal tests * Fixup test to use reserve * Use assert_matches for decrease tests * Fix deprecated decrease tests by transferring rent-exempt reserve --- program/Cargo.toml | 1 + program/src/instruction.rs | 83 ++++++++- program/src/processor.rs | 70 +++++-- program/tests/decrease.rs | 173 +++++++++--------- program/tests/helpers/mod.rs | 140 ++++++++++---- program/tests/increase.rs | 3 +- program/tests/redelegate.rs | 3 +- .../tests/update_validator_list_balance.rs | 8 +- .../update_validator_list_balance_hijack.rs | 6 +- program/tests/vsa_remove.rs | 8 +- program/tests/withdraw.rs | 20 +- program/tests/withdraw_edge_cases.rs | 44 +++-- program/tests/withdraw_with_fee.rs | 4 +- 13 files changed, 387 insertions(+), 176 deletions(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index f90b0675..275ce9da 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -28,6 +28,7 @@ thiserror = "1.0" bincode = "1.3.1" [dev-dependencies] +assert_matches = "1.5.0" proptest = "1.2" solana-program-test = "1.16.13" solana-sdk = "1.16.13" diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 46d11255..d7e35590 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -117,6 +117,9 @@ pub enum StakePoolInstruction { /// 7. `[]` Stake program id, RemoveValidatorFromPool, + /// NOTE: This instruction has been deprecated since version 0.7.0. Please + /// use `DecreaseValidatorStakeWithReserve` instead. + /// /// (Staker only) Decrease active stake on a validator, eventually moving it to the reserve /// /// Internally, this instruction splits a validator stake account into its @@ -477,6 +480,40 @@ pub enum StakePoolInstruction { ephemeral_stake_seed: u64, }, + /// (Staker only) Decrease active stake on a validator, eventually moving it to the reserve + /// + /// Internally, this instruction: + /// * withdraws enough lamports to make the transient account rent-exempt + /// * splits from a validator stake account into a transient stake account + /// * deactivates the transient stake account + /// + /// In order to rebalance the pool without taking custody, the staker needs + /// a way of reducing the stake on a stake account. This instruction splits + /// some amount of stake, up to the total activated stake, from the canonical + /// validator stake account, into its "transient" stake account. + /// + /// The instruction only succeeds if the transient stake account does not + /// exist. The amount of lamports to move must be at least rent-exemption plus + /// `max(crate::MINIMUM_ACTIVE_STAKE, solana_program::stake::tools::get_minimum_delegation())`. + /// + /// 0. `[]` Stake pool + /// 1. `[s]` Stake pool staker + /// 2. `[]` Stake pool withdraw authority + /// 3. `[w]` Validator list + /// 4. `[w]` Reserve stake account, to fund rent exempt reserve + /// 5. `[w]` Canonical stake account to split from + /// 6. `[w]` Transient stake account to receive split + /// 7. `[]` Clock sysvar + /// 8. '[]' Stake history sysvar + /// 9. `[]` System program + /// 10. `[]` Stake program + DecreaseValidatorStakeWithReserve { + /// amount of lamports to split into the transient stake account + lamports: u64, + /// seed used to create transient stake account + transient_stake_seed: u64, + }, + /// (Staker only) Redelegate active stake on a validator, eventually moving it to another /// /// Internally, this instruction splits a validator stake account into its @@ -755,6 +792,10 @@ pub fn remove_validator_from_pool( /// Creates `DecreaseValidatorStake` instruction (rebalance from validator account to /// transient account) +#[deprecated( + since = "0.7.0", + note = "please use `decrease_validator_stake_with_reserve`" +)] pub fn decrease_validator_stake( program_id: &Pubkey, stake_pool: &Pubkey, @@ -833,6 +874,45 @@ pub fn decrease_additional_validator_stake( } } +/// Creates `DecreaseValidatorStakeWithReserve` instruction (rebalance from +/// validator account to transient account) +pub fn decrease_validator_stake_with_reserve( + program_id: &Pubkey, + stake_pool: &Pubkey, + staker: &Pubkey, + stake_pool_withdraw_authority: &Pubkey, + validator_list: &Pubkey, + reserve_stake: &Pubkey, + validator_stake: &Pubkey, + transient_stake: &Pubkey, + lamports: u64, + transient_stake_seed: u64, +) -> Instruction { + let accounts = vec![ + AccountMeta::new_readonly(*stake_pool, false), + AccountMeta::new_readonly(*staker, true), + AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), + AccountMeta::new(*validator_list, false), + AccountMeta::new(*reserve_stake, false), + AccountMeta::new(*validator_stake, false), + AccountMeta::new(*transient_stake, false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(sysvar::stake_history::id(), false), + AccountMeta::new_readonly(system_program::id(), false), + AccountMeta::new_readonly(stake::program::id(), false), + ]; + Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::DecreaseValidatorStakeWithReserve { + lamports, + transient_stake_seed, + } + .try_to_vec() + .unwrap(), + } +} + /// Creates `IncreaseValidatorStake` instruction (rebalance from reserve account to /// transient account) pub fn increase_validator_stake( @@ -1174,12 +1254,13 @@ pub fn decrease_validator_stake_with_vote( stake_pool_address, transient_stake_seed, ); - decrease_validator_stake( + decrease_validator_stake_with_reserve( program_id, stake_pool_address, &stake_pool.staker, &pool_withdraw_authority, &stake_pool.validator_list, + &stake_pool.reserve_stake, &validator_stake_address, &transient_stake_address, lamports, diff --git a/program/src/processor.rs b/program/src/processor.rs index 17ed181a..aeb40520 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1258,17 +1258,14 @@ impl Processor { let transient_stake_account_info = next_account_info(account_info_iter)?; let clock_info = next_account_info(account_info_iter)?; let clock = &Clock::from_account_info(clock_info)?; - let rent = if maybe_ephemeral_stake_seed.is_some() { - // instruction with ephemeral account doesn't take the rent account - Rent::get()? - } else { - // legacy instruction takes the rent account - let rent_info = next_account_info(account_info_iter)?; - Rent::from_account_info(rent_info)? - }; - let maybe_stake_history_info = maybe_ephemeral_stake_seed - .map(|_| next_account_info(account_info_iter)) - .transpose()?; + let (rent, maybe_stake_history_info) = + if maybe_ephemeral_stake_seed.is_some() || fund_rent_exempt_reserve { + (Rent::get()?, Some(next_account_info(account_info_iter)?)) + } else { + // legacy instruction takes the rent account + let rent_info = next_account_info(account_info_iter)?; + (Rent::from_account_info(rent_info)?, None) + }; let system_program_info = next_account_info(account_info_iter)?; let stake_program_info = next_account_info(account_info_iter)?; @@ -1487,6 +1484,35 @@ impl Processor { stake_space, )?; + // if needed, withdraw rent-exempt reserve for transient account + if let Some(reserve_stake_info) = maybe_reserve_stake_info { + let required_lamports = + stake_rent.saturating_sub(transient_stake_account_info.lamports()); + // in the case of doing a full split from an ephemeral account, + // the rent-exempt reserve moves over, so no need to fund it from + // the pool reserve + if source_stake_account_info.lamports() != split_lamports { + let stake_history_info = + maybe_stake_history_info.ok_or(StakePoolError::MissingRequiredSysvar)?; + if required_lamports >= reserve_stake_info.lamports() { + return Err(StakePoolError::ReserveDepleted.into()); + } + if required_lamports > 0 { + Self::stake_withdraw( + stake_pool_info.key, + reserve_stake_info.clone(), + withdraw_authority_info.clone(), + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + transient_stake_account_info.clone(), + clock_info.clone(), + stake_history_info.clone(), + required_lamports, + )?; + } + } + } + // split into transient stake account Self::stake_split( stake_pool_info.key, @@ -1517,13 +1543,8 @@ impl Processor { .checked_sub(lamports) .ok_or(StakePoolError::CalculationFailure)? .into(); - // `split_lamports` may be greater than `lamports` if the reserve stake - // funded the rent-exempt reserve validator_stake_info.transient_stake_lamports = - u64::from(validator_stake_info.transient_stake_lamports) - .checked_add(split_lamports) - .ok_or(StakePoolError::CalculationFailure)? - .into(); + transient_stake_account_info.lamports().into(); validator_stake_info.transient_seed_suffix = transient_stake_seed.into(); Ok(()) @@ -3842,6 +3863,7 @@ impl Processor { transient_stake_seed, } => { msg!("Instruction: DecreaseValidatorStake"); + msg!("NOTE: This instruction is deprecated, please use `DecreaseValidatorStakeWithReserve`"); Self::process_decrease_validator_stake( program_id, accounts, @@ -3851,6 +3873,20 @@ impl Processor { false, ) } + StakePoolInstruction::DecreaseValidatorStakeWithReserve { + lamports, + transient_stake_seed, + } => { + msg!("Instruction: DecreaseValidatorStakeWithReserve"); + Self::process_decrease_validator_stake( + program_id, + accounts, + lamports, + transient_stake_seed, + None, + true, + ) + } StakePoolInstruction::DecreaseAdditionalValidatorStake { lamports, transient_stake_seed, diff --git a/program/tests/decrease.rs b/program/tests/decrease.rs index 493e75ad..c6ea4542 100644 --- a/program/tests/decrease.rs +++ b/program/tests/decrease.rs @@ -4,6 +4,7 @@ mod helpers; use { + assert_matches::assert_matches, bincode::deserialize, helpers::*, solana_program::{clock::Epoch, instruction::InstructionError, pubkey::Pubkey, stake}, @@ -80,10 +81,11 @@ async fn setup() -> ( ) } -#[test_case(true; "additional")] -#[test_case(false; "no-additional")] +#[test_case(DecreaseInstruction::Additional; "additional")] +#[test_case(DecreaseInstruction::Reserve; "reserve")] +#[test_case(DecreaseInstruction::Deprecated; "deprecated")] #[tokio::test] -async fn success(use_additional_instruction: bool) { +async fn success(instruction_type: DecreaseInstruction) { let ( mut context, stake_pool_accounts, @@ -114,7 +116,7 @@ async fn success(use_additional_instruction: bool) { &validator_stake.transient_stake_account, decrease_lamports, validator_stake.transient_stake_seed, - use_additional_instruction, + instruction_type, ) .await; assert!(error.is_none(), "{:?}", error); @@ -147,16 +149,12 @@ async fn success(use_additional_instruction: bool) { .await; let transient_stake_state = deserialize::(&transient_stake_account.data).unwrap(); - let transient_lamports = if use_additional_instruction { - decrease_lamports + stake_rent - } else { - decrease_lamports - }; + let transient_lamports = decrease_lamports + stake_rent; assert_eq!(transient_stake_account.lamports, transient_lamports); - let reserve_lamports = if use_additional_instruction { - reserve_lamports - stake_rent - } else { + let reserve_lamports = if instruction_type == DecreaseInstruction::Deprecated { reserve_lamports + } else { + reserve_lamports - stake_rent }; let reserve_stake_account = get_account( &mut context.banks_client, @@ -181,12 +179,13 @@ async fn fail_with_wrong_withdraw_authority() { let wrong_authority = Pubkey::new_unique(); let transaction = Transaction::new_signed_with_payer( - &[instruction::decrease_validator_stake( + &[instruction::decrease_validator_stake_with_reserve( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.staker.pubkey(), &wrong_authority, &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), &validator_stake.stake_account, &validator_stake.transient_stake_account, decrease_lamports, @@ -204,13 +203,13 @@ async fn fail_with_wrong_withdraw_authority() { .unwrap() .unwrap(); - match error { - TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { - let program_error = StakePoolError::InvalidProgramAddress as u32; - assert_eq!(error_index, program_error); - } - _ => panic!("Wrong error occurs while decreasing with wrong withdraw authority"), - } + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::InvalidProgramAddress as u32) + ) + ); } #[tokio::test] @@ -227,12 +226,13 @@ async fn fail_with_wrong_validator_list() { stake_pool_accounts.validator_list = Keypair::new(); let transaction = Transaction::new_signed_with_payer( - &[instruction::decrease_validator_stake( + &[instruction::decrease_validator_stake_with_reserve( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.staker.pubkey(), &stake_pool_accounts.withdraw_authority, &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), &validator_stake.stake_account, &validator_stake.transient_stake_account, decrease_lamports, @@ -250,13 +250,13 @@ async fn fail_with_wrong_validator_list() { .unwrap() .unwrap(); - match error { - TransactionError::InstructionError(_, InstructionError::Custom(error_index)) => { - let program_error = StakePoolError::InvalidValidatorStakeList as u32; - assert_eq!(error_index, program_error); - } - _ => panic!("Wrong error occurs while decreasing with wrong validator stake list account"), - } + assert_eq!( + error, + TransactionError::InstructionError( + 0, + InstructionError::Custom(StakePoolError::InvalidValidatorStakeList as u32) + ) + ); } #[tokio::test] @@ -274,12 +274,13 @@ async fn fail_with_unknown_validator() { .await; let transaction = Transaction::new_signed_with_payer( - &[instruction::decrease_validator_stake( + &[instruction::decrease_validator_stake_with_reserve( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.staker.pubkey(), &stake_pool_accounts.withdraw_authority, &stake_pool_accounts.validator_list.pubkey(), + &stake_pool_accounts.reserve_stake.pubkey(), &unknown_stake.stake_account, &unknown_stake.transient_stake_account, decrease_lamports, @@ -306,10 +307,11 @@ async fn fail_with_unknown_validator() { ); } -#[test_case(true; "additional")] -#[test_case(false; "no-additional")] +#[test_case(DecreaseInstruction::Additional; "additional")] +#[test_case(DecreaseInstruction::Reserve; "reserve")] +#[test_case(DecreaseInstruction::Deprecated; "deprecated")] #[tokio::test] -async fn fail_twice_diff_seed(use_additional_instruction: bool) { +async fn fail_twice_diff_seed(instruction_type: DecreaseInstruction) { let (mut context, stake_pool_accounts, validator_stake, _deposit_info, decrease_lamports, _) = setup().await; @@ -322,7 +324,7 @@ async fn fail_twice_diff_seed(use_additional_instruction: bool) { &validator_stake.transient_stake_account, decrease_lamports / 3, validator_stake.transient_stake_seed, - use_additional_instruction, + instruction_type, ) .await; assert!(error.is_none(), "{:?}", error); @@ -344,40 +346,44 @@ async fn fail_twice_diff_seed(use_additional_instruction: bool) { &transient_stake_address, decrease_lamports / 2, transient_stake_seed, - use_additional_instruction, + instruction_type, ) .await .unwrap() .unwrap(); - if use_additional_instruction { + if instruction_type == DecreaseInstruction::Additional { assert_eq!( error, TransactionError::InstructionError(0, InstructionError::InvalidSeeds) ); } else { - assert_eq!( + assert_matches!( error, TransactionError::InstructionError( - 0, - InstructionError::Custom(StakePoolError::TransientAccountInUse as u32) - ) + _, + InstructionError::Custom(code) + ) if code == StakePoolError::TransientAccountInUse as u32 ); } } -#[test_case(true, true, true; "success-all-additional")] -#[test_case(true, false, true; "success-with-additional")] -#[test_case(false, true, false; "fail-without-additional")] -#[test_case(false, false, false; "fail-no-additional")] +#[test_case(true, DecreaseInstruction::Additional, DecreaseInstruction::Additional; "success-all-additional")] +#[test_case(true, DecreaseInstruction::Reserve, DecreaseInstruction::Additional; "success-with-additional")] +#[test_case(false, DecreaseInstruction::Additional, DecreaseInstruction::Reserve; "fail-without-additional")] +#[test_case(false, DecreaseInstruction::Reserve, DecreaseInstruction::Reserve; "fail-no-additional")] #[tokio::test] -async fn twice(success: bool, use_additional_first_time: bool, use_additional_second_time: bool) { +async fn twice( + success: bool, + first_instruction: DecreaseInstruction, + second_instruction: DecreaseInstruction, +) { let ( mut context, stake_pool_accounts, validator_stake, _deposit_info, decrease_lamports, - mut reserve_lamports, + reserve_lamports, ) = setup().await; let pre_stake_account = @@ -398,7 +404,7 @@ async fn twice(success: bool, use_additional_first_time: bool, use_additional_se &validator_stake.transient_stake_account, first_decrease, validator_stake.transient_stake_seed, - use_additional_first_time, + first_instruction, ) .await; assert!(error.is_none(), "{:?}", error); @@ -412,7 +418,7 @@ async fn twice(success: bool, use_additional_first_time: bool, use_additional_se &validator_stake.transient_stake_account, second_decrease, validator_stake.transient_stake_seed, - use_additional_second_time, + second_instruction, ) .await; @@ -453,11 +459,8 @@ async fn twice(success: bool, use_additional_first_time: bool, use_additional_se .await; let transient_stake_state = deserialize::(&transient_stake_account.data).unwrap(); - let mut transient_lamports = total_decrease; - if use_additional_first_time { - transient_lamports += stake_rent; - } - if use_additional_second_time { + let mut transient_lamports = total_decrease + stake_rent; + if second_instruction == DecreaseInstruction::Additional { transient_lamports += stake_rent; } assert_eq!(transient_stake_account.lamports, transient_lamports); @@ -480,10 +483,8 @@ async fn twice(success: bool, use_additional_first_time: bool, use_additional_se ); // reserve deducted properly - if use_additional_first_time { - reserve_lamports -= stake_rent; - } - if use_additional_second_time { + let mut reserve_lamports = reserve_lamports - stake_rent; + if second_instruction == DecreaseInstruction::Additional { reserve_lamports -= stake_rent; } let reserve_stake_account = get_account( @@ -494,20 +495,21 @@ async fn twice(success: bool, use_additional_first_time: bool, use_additional_se assert_eq!(reserve_stake_account.lamports, reserve_lamports); } else { let error = error.unwrap().unwrap(); - assert_eq!( + assert_matches!( error, TransactionError::InstructionError( - 0, - InstructionError::Custom(StakePoolError::TransientAccountInUse as u32) - ) + _, + InstructionError::Custom(code) + ) if code == StakePoolError::TransientAccountInUse as u32 ); } } -#[test_case(true; "additional")] -#[test_case(false; "no-additional")] +#[test_case(DecreaseInstruction::Additional; "additional")] +#[test_case(DecreaseInstruction::Reserve; "reserve")] +#[test_case(DecreaseInstruction::Deprecated; "deprecated")] #[tokio::test] -async fn fail_with_small_lamport_amount(use_additional_instruction: bool) { +async fn fail_with_small_lamport_amount(instruction_type: DecreaseInstruction) { let (mut context, stake_pool_accounts, validator_stake, _deposit_info, _decrease_lamports, _) = setup().await; @@ -523,25 +525,28 @@ async fn fail_with_small_lamport_amount(use_additional_instruction: bool) { &validator_stake.transient_stake_account, lamports, validator_stake.transient_stake_seed, - use_additional_instruction, + instruction_type, ) .await .unwrap() .unwrap(); - match error { - TransactionError::InstructionError(_, InstructionError::AccountNotRentExempt) => {} - _ => panic!("Wrong error occurs while try to decrease small stake"), - } + assert_matches!( + error, + TransactionError::InstructionError(_, InstructionError::AccountNotRentExempt) + ); } +#[test_case(DecreaseInstruction::Additional; "additional")] +#[test_case(DecreaseInstruction::Reserve; "reserve")] +#[test_case(DecreaseInstruction::Deprecated; "deprecated")] #[tokio::test] -async fn fail_big_overdraw() { +async fn fail_big_overdraw(instruction_type: DecreaseInstruction) { let (mut context, stake_pool_accounts, validator_stake, deposit_info, _decrease_lamports, _) = setup().await; let error = stake_pool_accounts - .decrease_validator_stake( + .decrease_validator_stake_either( &mut context.banks_client, &context.payer, &context.last_blockhash, @@ -549,21 +554,23 @@ async fn fail_big_overdraw() { &validator_stake.transient_stake_account, deposit_info.stake_lamports * 1_000_000, validator_stake.transient_stake_seed, + instruction_type, ) .await .unwrap() .unwrap(); - assert_eq!( + assert_matches!( error, - TransactionError::InstructionError(0, InstructionError::InsufficientFunds) + TransactionError::InstructionError(_, InstructionError::InsufficientFunds) ); } -#[test_case(true; "additional")] -#[test_case(false; "no-additional")] +#[test_case(DecreaseInstruction::Additional; "additional")] +#[test_case(DecreaseInstruction::Reserve; "reserve")] +#[test_case(DecreaseInstruction::Deprecated; "deprecated")] #[tokio::test] -async fn fail_overdraw(use_additional_instruction: bool) { +async fn fail_overdraw(instruction_type: DecreaseInstruction) { let (mut context, stake_pool_accounts, validator_stake, deposit_info, _decrease_lamports, _) = setup().await; @@ -579,15 +586,15 @@ async fn fail_overdraw(use_additional_instruction: bool) { &validator_stake.transient_stake_account, deposit_info.stake_lamports + stake_rent + 1, validator_stake.transient_stake_seed, - use_additional_instruction, + instruction_type, ) .await .unwrap() .unwrap(); - assert_eq!( + assert_matches!( error, - TransactionError::InstructionError(0, InstructionError::InsufficientFunds) + TransactionError::InstructionError(_, InstructionError::InsufficientFunds) ); } @@ -644,17 +651,17 @@ async fn fail_additional_with_increasing() { &validator_stake.transient_stake_account, decrease_lamports / 2, validator_stake.transient_stake_seed, - true, + DecreaseInstruction::Additional, ) .await .unwrap() .unwrap(); - assert_eq!( + assert_matches!( error, TransactionError::InstructionError( - 0, - InstructionError::Custom(StakePoolError::WrongStakeState as u32) - ) + _, + InstructionError::Custom(code) + ) if code == StakePoolError::WrongStakeState as u32 ); } diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index a07eec40..4f001295 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -1614,7 +1614,7 @@ impl StakePoolAccounts { } #[allow(clippy::too_many_arguments)] - pub async fn decrease_validator_stake( + pub async fn decrease_validator_stake_deprecated( &self, banks_client: &mut BanksClient, payer: &Keypair, @@ -1624,12 +1624,57 @@ impl StakePoolAccounts { lamports: u64, transient_stake_seed: u64, ) -> Option { - let mut instructions = vec![instruction::decrease_validator_stake( + #[allow(deprecated)] + let mut instructions = vec![ + system_instruction::transfer( + &payer.pubkey(), + transient_stake, + STAKE_ACCOUNT_RENT_EXEMPTION, + ), + instruction::decrease_validator_stake( + &id(), + &self.stake_pool.pubkey(), + &self.staker.pubkey(), + &self.withdraw_authority, + &self.validator_list.pubkey(), + validator_stake, + transient_stake, + lamports, + transient_stake_seed, + ), + ]; + self.maybe_add_compute_budget_instruction(&mut instructions); + let transaction = Transaction::new_signed_with_payer( + &instructions, + Some(&payer.pubkey()), + &[payer, &self.staker], + *recent_blockhash, + ); + banks_client + .process_transaction(transaction) + .await + .map_err(|e| e.into()) + .err() + } + + #[allow(clippy::too_many_arguments)] + pub async fn decrease_validator_stake_with_reserve( + &self, + banks_client: &mut BanksClient, + payer: &Keypair, + recent_blockhash: &Hash, + validator_stake: &Pubkey, + transient_stake: &Pubkey, + lamports: u64, + transient_stake_seed: u64, + ) -> Option { + let mut instructions = vec![instruction::decrease_validator_stake_with_reserve( &id(), &self.stake_pool.pubkey(), &self.staker.pubkey(), &self.withdraw_authority, &self.validator_list.pubkey(), + &self.reserve_stake.pubkey(), validator_stake, transient_stake, lamports, @@ -1700,39 +1745,56 @@ impl StakePoolAccounts { transient_stake: &Pubkey, lamports: u64, transient_stake_seed: u64, - use_additional_instruction: bool, + instruction_type: DecreaseInstruction, ) -> Option { - if use_additional_instruction { - let ephemeral_stake_seed = 0; - let ephemeral_stake = find_ephemeral_stake_program_address( - &id(), - &self.stake_pool.pubkey(), - ephemeral_stake_seed, - ) - .0; - self.decrease_additional_validator_stake( - banks_client, - payer, - recent_blockhash, - validator_stake, - &ephemeral_stake, - transient_stake, - lamports, - transient_stake_seed, - ephemeral_stake_seed, - ) - .await - } else { - self.decrease_validator_stake( - banks_client, - payer, - recent_blockhash, - validator_stake, - transient_stake, - lamports, - transient_stake_seed, - ) - .await + match instruction_type { + DecreaseInstruction::Additional => { + let ephemeral_stake_seed = 0; + let ephemeral_stake = find_ephemeral_stake_program_address( + &id(), + &self.stake_pool.pubkey(), + ephemeral_stake_seed, + ) + .0; + self.decrease_additional_validator_stake( + banks_client, + payer, + recent_blockhash, + validator_stake, + &ephemeral_stake, + transient_stake, + lamports, + transient_stake_seed, + ephemeral_stake_seed, + ) + .await + } + DecreaseInstruction::Reserve => { + self.decrease_validator_stake_with_reserve( + banks_client, + payer, + recent_blockhash, + validator_stake, + transient_stake, + lamports, + transient_stake_seed, + ) + .await + } + DecreaseInstruction::Deprecated => + { + #[allow(deprecated)] + self.decrease_validator_stake_deprecated( + banks_client, + payer, + recent_blockhash, + validator_stake, + transient_stake, + lamports, + transient_stake_seed, + ) + .await + } } } @@ -2545,6 +2607,7 @@ pub fn add_token_account( pub async fn setup_for_withdraw( token_program_id: Pubkey, + reserve_lamports: u64, ) -> ( ProgramTestContext, StakePoolAccounts, @@ -2561,7 +2624,7 @@ pub async fn setup_for_withdraw( &mut context.banks_client, &context.payer, &context.last_blockhash, - MINIMUM_RESERVE_LAMPORTS, + reserve_lamports, ) .await .unwrap(); @@ -2629,3 +2692,10 @@ pub async fn setup_for_withdraw( tokens_to_withdraw, ) } + +#[derive(Copy, Clone, Debug, PartialEq)] +pub enum DecreaseInstruction { + Additional, + Reserve, + Deprecated, +} diff --git a/program/tests/increase.rs b/program/tests/increase.rs index b42dd789..22612372 100644 --- a/program/tests/increase.rs +++ b/program/tests/increase.rs @@ -553,7 +553,7 @@ async fn fail_additional_with_decreasing() { .await; let error = stake_pool_accounts - .decrease_validator_stake( + .decrease_validator_stake_either( &mut context.banks_client, &context.payer, &last_blockhash, @@ -561,6 +561,7 @@ async fn fail_additional_with_decreasing() { &validator_stake.transient_stake_account, current_minimum_delegation + stake_rent, validator_stake.transient_stake_seed, + DecreaseInstruction::Reserve, ) .await; assert!(error.is_none(), "{:?}", error); diff --git a/program/tests/redelegate.rs b/program/tests/redelegate.rs index 707b7067..0fc70db6 100644 --- a/program/tests/redelegate.rs +++ b/program/tests/redelegate.rs @@ -651,7 +651,7 @@ async fn fail_with_decreasing_stake() { .unwrap(); let error = stake_pool_accounts - .decrease_validator_stake( + .decrease_validator_stake_either( &mut context.banks_client, &context.payer, &context.last_blockhash, @@ -659,6 +659,7 @@ async fn fail_with_decreasing_stake() { &destination_validator_stake.transient_stake_account, minimum_decrease_lamports, destination_validator_stake.transient_stake_seed, + DecreaseInstruction::Reserve, ) .await; assert!(error.is_none(), "{:?}", error); diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index 1c6b3369..831ad30d 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -279,7 +279,7 @@ async fn merge_into_reserve() { println!("Decrease from all validators"); for stake_account in &stake_accounts { let error = stake_pool_accounts - .decrease_validator_stake( + .decrease_validator_stake_either( &mut context.banks_client, &context.payer, &last_blockhash, @@ -287,6 +287,7 @@ async fn merge_into_reserve() { &stake_account.transient_stake_account, lamports, stake_account.transient_stake_seed, + DecreaseInstruction::Reserve, ) .await; assert!(error.is_none(), "{:?}", error); @@ -554,7 +555,7 @@ async fn merge_transient_stake_after_remove() { // Decrease and remove all validators for stake_account in &stake_accounts { let error = stake_pool_accounts - .decrease_validator_stake( + .decrease_validator_stake_either( &mut context.banks_client, &context.payer, &last_blockhash, @@ -562,6 +563,7 @@ async fn merge_transient_stake_after_remove() { &stake_account.transient_stake_account, deactivated_lamports, stake_account.transient_stake_seed, + DecreaseInstruction::Reserve, ) .await; assert!(error.is_none(), "{:?}", error); @@ -616,7 +618,7 @@ async fn merge_transient_stake_after_remove() { ); assert_eq!( u64::from(validator_list.validators[0].transient_stake_lamports), - deactivated_lamports + deactivated_lamports + stake_rent ); // Update with merge, status should be ReadyForRemoval and no lamports diff --git a/program/tests/update_validator_list_balance_hijack.rs b/program/tests/update_validator_list_balance_hijack.rs index 8ef0e59e..feb05248 100644 --- a/program/tests/update_validator_list_balance_hijack.rs +++ b/program/tests/update_validator_list_balance_hijack.rs @@ -220,7 +220,7 @@ async fn check_ignored_hijacked_transient_stake( println!("Decrease from all validators"); let stake_account = &stake_accounts[0]; let error = stake_pool_accounts - .decrease_validator_stake( + .decrease_validator_stake_either( &mut context.banks_client, &context.payer, &last_blockhash, @@ -228,6 +228,7 @@ async fn check_ignored_hijacked_transient_stake( &stake_account.transient_stake_account, lamports, stake_account.transient_stake_seed, + DecreaseInstruction::Reserve, ) .await; assert!(error.is_none(), "{:?}", error); @@ -384,7 +385,7 @@ async fn check_ignored_hijacked_validator_stake( let stake_account = &stake_accounts[0]; let error = stake_pool_accounts - .decrease_validator_stake( + .decrease_validator_stake_either( &mut context.banks_client, &context.payer, &last_blockhash, @@ -392,6 +393,7 @@ async fn check_ignored_hijacked_validator_stake( &stake_account.transient_stake_account, lamports, stake_account.transient_stake_seed, + DecreaseInstruction::Reserve, ) .await; assert!(error.is_none(), "{:?}", error); diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 18730637..b305052f 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -455,7 +455,7 @@ async fn success_with_deactivating_transient_stake() { // increase the validator stake let error = stake_pool_accounts - .decrease_validator_stake( + .decrease_validator_stake_either( &mut context.banks_client, &context.payer, &context.last_blockhash, @@ -463,6 +463,7 @@ async fn success_with_deactivating_transient_stake() { &validator_stake.transient_stake_account, TEST_STAKE_AMOUNT + stake_rent, validator_stake.transient_stake_seed, + DecreaseInstruction::Reserve, ) .await; assert!(error.is_none(), "{:?}", error); @@ -546,7 +547,7 @@ async fn success_with_deactivating_transient_stake() { vote_account_address: validator_stake.vote.pubkey(), last_update_epoch: 0.into(), active_stake_lamports: (stake_rent + current_minimum_delegation).into(), - transient_stake_lamports: (TEST_STAKE_AMOUNT + stake_rent).into(), + transient_stake_lamports: (TEST_STAKE_AMOUNT + stake_rent * 2).into(), transient_seed_suffix: validator_stake.transient_stake_seed.into(), unused: 0.into(), validator_seed_suffix: validator_stake @@ -705,7 +706,7 @@ async fn success_with_hijacked_transient_account() { // decrease let error = stake_pool_accounts - .decrease_validator_stake( + .decrease_validator_stake_either( &mut context.banks_client, &context.payer, &context.last_blockhash, @@ -713,6 +714,7 @@ async fn success_with_hijacked_transient_account() { &validator_stake.transient_stake_account, increase_amount, validator_stake.transient_stake_seed, + DecreaseInstruction::Reserve, ) .await; assert!(error.is_none(), "{:?}", error); diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 3fd44962..1baddb17 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -49,7 +49,7 @@ async fn _success(token_program_id: Pubkey, test_type: SuccessTestType) { user_transfer_authority, user_stake_recipient, tokens_to_withdraw, - ) = setup_for_withdraw(token_program_id).await; + ) = setup_for_withdraw(token_program_id, 0).await; // Save stake pool state before withdrawal let stake_pool_before = get_account( @@ -268,7 +268,7 @@ async fn fail_with_wrong_stake_program() { user_transfer_authority, user_stake_recipient, tokens_to_burn, - ) = setup_for_withdraw(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id(), 0).await; let new_authority = Pubkey::new_unique(); let wrong_stake_program = Pubkey::new_unique(); @@ -328,7 +328,7 @@ async fn fail_with_wrong_withdraw_authority() { user_transfer_authority, user_stake_recipient, tokens_to_burn, - ) = setup_for_withdraw(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id(), 0).await; let new_authority = Pubkey::new_unique(); stake_pool_accounts.withdraw_authority = Keypair::new().pubkey(); @@ -370,7 +370,7 @@ async fn fail_with_wrong_token_program_id() { user_transfer_authority, user_stake_recipient, tokens_to_burn, - ) = setup_for_withdraw(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id(), 0).await; let new_authority = Pubkey::new_unique(); let wrong_token_program = Keypair::new(); @@ -421,7 +421,7 @@ async fn fail_with_wrong_validator_list() { user_transfer_authority, user_stake_recipient, tokens_to_burn, - ) = setup_for_withdraw(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id(), 0).await; let new_authority = Pubkey::new_unique(); stake_pool_accounts.validator_list = Keypair::new(); @@ -465,7 +465,7 @@ async fn fail_with_unknown_validator() { user_transfer_authority, user_stake_recipient, tokens_to_withdraw, - ) = setup_for_withdraw(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id(), 0).await; let unknown_stake = create_unknown_validator_stake( &mut context.banks_client, @@ -512,7 +512,7 @@ async fn fail_double_withdraw_to_the_same_account() { user_transfer_authority, user_stake_recipient, tokens_to_burn, - ) = setup_for_withdraw(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id(), 0).await; let new_authority = Pubkey::new_unique(); let error = stake_pool_accounts @@ -578,7 +578,7 @@ async fn fail_without_token_approval() { user_transfer_authority, user_stake_recipient, tokens_to_burn, - ) = setup_for_withdraw(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id(), 0).await; revoke_tokens( &mut context.banks_client, @@ -630,7 +630,7 @@ async fn fail_with_not_enough_tokens() { user_transfer_authority, user_stake_recipient, tokens_to_burn, - ) = setup_for_withdraw(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id(), 0).await; let last_blockhash = context .banks_client @@ -773,7 +773,7 @@ async fn success_with_slippage(token_program_id: Pubkey) { user_transfer_authority, user_stake_recipient, tokens_to_withdraw, - ) = setup_for_withdraw(token_program_id).await; + ) = setup_for_withdraw(token_program_id, 0).await; // Save user token balance let user_token_balance_before = get_token_balance( diff --git a/program/tests/withdraw_edge_cases.rs b/program/tests/withdraw_edge_cases.rs index 90cb5a7a..a2d1fd6c 100644 --- a/program/tests/withdraw_edge_cases.rs +++ b/program/tests/withdraw_edge_cases.rs @@ -25,11 +25,11 @@ async fn fail_remove_validator() { user_transfer_authority, user_stake_recipient, _, - ) = setup_for_withdraw(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id(), STAKE_ACCOUNT_RENT_EXEMPTION).await; // decrease a little stake, not all let error = stake_pool_accounts - .decrease_validator_stake( + .decrease_validator_stake_either( &mut context.banks_client, &context.payer, &context.last_blockhash, @@ -37,6 +37,7 @@ async fn fail_remove_validator() { &validator_stake.transient_stake_account, deposit_info.stake_lamports / 2, validator_stake.transient_stake_seed, + DecreaseInstruction::Reserve, ) .await; assert!(error.is_none(), "{:?}", error); @@ -46,7 +47,7 @@ async fn fail_remove_validator() { context.warp_to_slot(first_normal_slot + 1).unwrap(); // update to merge deactivated stake into reserve - stake_pool_accounts + let error = stake_pool_accounts .update_all( &mut context.banks_client, &context.payer, @@ -55,6 +56,7 @@ async fn fail_remove_validator() { false, ) .await; + assert!(error.is_none(), "{:?}", error); // Withdraw entire account, fail because some stake left let validator_stake_account = @@ -99,7 +101,7 @@ async fn success_remove_validator(multiple: u64) { user_transfer_authority, user_stake_recipient, _, - ) = setup_for_withdraw(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id(), STAKE_ACCOUNT_RENT_EXEMPTION).await; // make pool tokens very valuable, so it isn't possible to exactly get down to the minimum transfer( @@ -129,7 +131,7 @@ async fn success_remove_validator(multiple: u64) { // decrease all of stake except for lamports_per_pool_token lamports, must be withdrawable let error = stake_pool_accounts - .decrease_validator_stake( + .decrease_validator_stake_either( &mut context.banks_client, &context.payer, &context.last_blockhash, @@ -137,6 +139,7 @@ async fn success_remove_validator(multiple: u64) { &validator_stake.transient_stake_account, deposit_info.stake_lamports + stake_rent - lamports_per_pool_token, validator_stake.transient_stake_seed, + DecreaseInstruction::Reserve, ) .await; assert!(error.is_none(), "{:?}", error); @@ -238,11 +241,11 @@ async fn fail_with_reserve() { user_transfer_authority, user_stake_recipient, tokens_to_burn, - ) = setup_for_withdraw(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id(), STAKE_ACCOUNT_RENT_EXEMPTION).await; // decrease a little stake, not all let error = stake_pool_accounts - .decrease_validator_stake( + .decrease_validator_stake_either( &mut context.banks_client, &context.payer, &context.last_blockhash, @@ -250,6 +253,7 @@ async fn fail_with_reserve() { &validator_stake.transient_stake_account, deposit_info.stake_lamports / 2, validator_stake.transient_stake_seed, + DecreaseInstruction::Reserve, ) .await; assert!(error.is_none(), "{:?}", error); @@ -305,14 +309,14 @@ async fn success_with_reserve() { user_transfer_authority, user_stake_recipient, _, - ) = setup_for_withdraw(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id(), STAKE_ACCOUNT_RENT_EXEMPTION).await; let rent = context.banks_client.get_rent().await.unwrap(); let stake_rent = rent.minimum_balance(std::mem::size_of::()); // decrease all of stake let error = stake_pool_accounts - .decrease_validator_stake( + .decrease_validator_stake_either( &mut context.banks_client, &context.payer, &context.last_blockhash, @@ -320,6 +324,7 @@ async fn success_with_reserve() { &validator_stake.transient_stake_account, deposit_info.stake_lamports + stake_rent, validator_stake.transient_stake_seed, + DecreaseInstruction::Reserve, ) .await; assert!(error.is_none(), "{:?}", error); @@ -398,7 +403,7 @@ async fn success_with_reserve() { let stake_state = deserialize::(&reserve_stake_account.data).unwrap(); let meta = stake_state.meta().unwrap(); assert_eq!( - meta.rent_exempt_reserve + withdrawal_fee + deposit_fee, + meta.rent_exempt_reserve + withdrawal_fee + deposit_fee + stake_rent, reserve_stake_account.lamports ); @@ -421,7 +426,7 @@ async fn success_with_empty_preferred_withdraw() { user_transfer_authority, user_stake_recipient, tokens_to_burn, - ) = setup_for_withdraw(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id(), 0).await; let preferred_validator = simple_add_validator_to_pool( &mut context.banks_client, @@ -470,7 +475,7 @@ async fn success_and_fail_with_preferred_withdraw() { user_transfer_authority, user_stake_recipient, tokens_to_burn, - ) = setup_for_withdraw(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id(), 0).await; let last_blockhash = context .banks_client @@ -566,7 +571,7 @@ async fn fail_withdraw_from_transient() { user_transfer_authority, user_stake_recipient, tokens_to_withdraw, - ) = setup_for_withdraw(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id(), STAKE_ACCOUNT_RENT_EXEMPTION).await; let last_blockhash = context .banks_client @@ -605,7 +610,7 @@ async fn fail_withdraw_from_transient() { // decrease to minimum stake + 2 lamports let error = stake_pool_accounts - .decrease_validator_stake( + .decrease_validator_stake_either( &mut context.banks_client, &context.payer, &last_blockhash, @@ -613,6 +618,7 @@ async fn fail_withdraw_from_transient() { &validator_stake_account.transient_stake_account, deposit_info.stake_lamports + stake_rent - 2, validator_stake_account.transient_stake_seed, + DecreaseInstruction::Reserve, ) .await; assert!(error.is_none(), "{:?}", error); @@ -653,7 +659,7 @@ async fn success_withdraw_from_transient() { user_transfer_authority, user_stake_recipient, tokens_to_withdraw, - ) = setup_for_withdraw(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id(), STAKE_ACCOUNT_RENT_EXEMPTION).await; let last_blockhash = context .banks_client @@ -692,7 +698,7 @@ async fn success_withdraw_from_transient() { // decrease all of stake let error = stake_pool_accounts - .decrease_validator_stake( + .decrease_validator_stake_either( &mut context.banks_client, &context.payer, &last_blockhash, @@ -700,6 +706,7 @@ async fn success_withdraw_from_transient() { &validator_stake_account.transient_stake_account, deposit_info.stake_lamports + stake_rent, validator_stake_account.transient_stake_seed, + DecreaseInstruction::Reserve, ) .await; assert!(error.is_none(), "{:?}", error); @@ -733,7 +740,7 @@ async fn success_with_small_preferred_withdraw() { user_transfer_authority, user_stake_recipient, tokens_to_burn, - ) = setup_for_withdraw(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id(), 0).await; let last_blockhash = context .banks_client @@ -806,7 +813,7 @@ async fn success_with_small_preferred_withdraw() { // decrease all stake except for 1 lamport let error = stake_pool_accounts - .decrease_validator_stake( + .decrease_validator_stake_either( &mut context.banks_client, &context.payer, &last_blockhash, @@ -814,6 +821,7 @@ async fn success_with_small_preferred_withdraw() { &preferred_validator.transient_stake_account, minimum_lamports, preferred_validator.transient_stake_seed, + DecreaseInstruction::Reserve, ) .await; assert!(error.is_none(), "{:?}", error); diff --git a/program/tests/withdraw_with_fee.rs b/program/tests/withdraw_with_fee.rs index 1a2b0134..34c28b92 100644 --- a/program/tests/withdraw_with_fee.rs +++ b/program/tests/withdraw_with_fee.rs @@ -22,7 +22,7 @@ async fn success_withdraw_all_fee_tokens() { user_transfer_authority, user_stake_recipient, tokens_to_withdraw, - ) = setup_for_withdraw(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id(), 0).await; let last_blockhash = context .banks_client @@ -99,7 +99,7 @@ async fn success_empty_out_stake_with_fee() { user_transfer_authority, user_stake_recipient, tokens_to_withdraw, - ) = setup_for_withdraw(spl_token::id()).await; + ) = setup_for_withdraw(spl_token::id(), 0).await; let last_blockhash = context .banks_client From 397dc3d94c46dbe464743c604526ef3d33750b7a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Sep 2023 21:04:44 +0200 Subject: [PATCH 0515/1076] build(deps-dev): bump eslint from 8.49.0 to 8.50.0 in /stake-pool/js (#5344) Bumps [eslint](https://github.com/eslint/eslint) from 8.49.0 to 8.50.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.49.0...v8.50.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 6d2eee15..d94d9da8 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -717,9 +717,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.49.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.49.0.tgz", - "integrity": "sha512-1S8uAY/MTJqVx0SC4epBq+N2yhuwtNwLbJYNZyhL2pO1ZVKn5HFXav5T41Ryzy9K9V7ZId2JB2oy/W4aCd9/2w==", + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.50.0.tgz", + "integrity": "sha512-NCC3zz2+nvYd+Ckfh87rA47zfu2QsQpvc6k1yzTk+b9KzRj0wkGa8LSoGOXN6Zv4lRf/EIoZ80biDh9HOI+RNQ==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3223,15 +3223,15 @@ } }, "node_modules/eslint": { - "version": "8.49.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.49.0.tgz", - "integrity": "sha512-jw03ENfm6VJI0jA9U+8H5zfl5b+FvuU3YYvZRdZHOlU2ggJkxrlkJH4HcDrZpj6YwD8kuYqvQM8LyesoazrSOQ==", + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.50.0.tgz", + "integrity": "sha512-FOnOGSuFuFLv/Sa+FDVRZl4GGVAAFFi8LecRsI5a1tMO5HIE8nCm4ivAlzt4dT3ol/PaaGC0rJEEXQmHJBGoOg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.49.0", + "@eslint/js": "8.50.0", "@humanwhocodes/config-array": "^0.11.11", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -7561,9 +7561,9 @@ } }, "@eslint/js": { - "version": "8.49.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.49.0.tgz", - "integrity": "sha512-1S8uAY/MTJqVx0SC4epBq+N2yhuwtNwLbJYNZyhL2pO1ZVKn5HFXav5T41Ryzy9K9V7ZId2JB2oy/W4aCd9/2w==", + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.50.0.tgz", + "integrity": "sha512-NCC3zz2+nvYd+Ckfh87rA47zfu2QsQpvc6k1yzTk+b9KzRj0wkGa8LSoGOXN6Zv4lRf/EIoZ80biDh9HOI+RNQ==", "dev": true }, "@humanwhocodes/config-array": { @@ -9382,15 +9382,15 @@ } }, "eslint": { - "version": "8.49.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.49.0.tgz", - "integrity": "sha512-jw03ENfm6VJI0jA9U+8H5zfl5b+FvuU3YYvZRdZHOlU2ggJkxrlkJH4HcDrZpj6YwD8kuYqvQM8LyesoazrSOQ==", + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.50.0.tgz", + "integrity": "sha512-FOnOGSuFuFLv/Sa+FDVRZl4GGVAAFFi8LecRsI5a1tMO5HIE8nCm4ivAlzt4dT3ol/PaaGC0rJEEXQmHJBGoOg==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.49.0", + "@eslint/js": "8.50.0", "@humanwhocodes/config-array": "^0.11.11", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", From 08e47b4a88e8bdc52cf77dd8741b0bfee350c796 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Sep 2023 21:05:04 +0200 Subject: [PATCH 0516/1076] build(deps-dev): bump @types/node from 20.6.3 to 20.6.5 in /stake-pool/js (#5346) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.6.3 to 20.6.5. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index d94d9da8..14ea9c58 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1768,9 +1768,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.6.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.3.tgz", - "integrity": "sha512-HksnYH4Ljr4VQgEy2lTStbCKv/P590tmPe5HqOnv9Gprffgv5WXAY+Y5Gqniu0GGqeTCUdBnzC3QSrzPkBkAMA==" + "version": "20.6.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.5.tgz", + "integrity": "sha512-2qGq5LAOTh9izcc0+F+dToFigBWiK1phKPt7rNhOqJSr35y8rlIBjDwGtFSgAI6MGIhjwOVNSQZVdJsZJ2uR1w==" }, "node_modules/@types/node-fetch": { "version": "2.6.5", @@ -8341,9 +8341,9 @@ "dev": true }, "@types/node": { - "version": "20.6.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.3.tgz", - "integrity": "sha512-HksnYH4Ljr4VQgEy2lTStbCKv/P590tmPe5HqOnv9Gprffgv5WXAY+Y5Gqniu0GGqeTCUdBnzC3QSrzPkBkAMA==" + "version": "20.6.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.5.tgz", + "integrity": "sha512-2qGq5LAOTh9izcc0+F+dToFigBWiK1phKPt7rNhOqJSr35y8rlIBjDwGtFSgAI6MGIhjwOVNSQZVdJsZJ2uR1w==" }, "@types/node-fetch": { "version": "2.6.5", From 259b06269d50a44c469b92c50adc013d0ce0bc73 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Sep 2023 21:05:14 +0200 Subject: [PATCH 0517/1076] build(deps-dev): bump @types/node-fetch from 2.6.5 to 2.6.6 in /stake-pool/js (#5345) build(deps-dev): bump @types/node-fetch in /stake-pool/js Bumps [@types/node-fetch](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node-fetch) from 2.6.5 to 2.6.6. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node-fetch) --- updated-dependencies: - dependency-name: "@types/node-fetch" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 14ea9c58..71305857 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1773,9 +1773,9 @@ "integrity": "sha512-2qGq5LAOTh9izcc0+F+dToFigBWiK1phKPt7rNhOqJSr35y8rlIBjDwGtFSgAI6MGIhjwOVNSQZVdJsZJ2uR1w==" }, "node_modules/@types/node-fetch": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.5.tgz", - "integrity": "sha512-OZsUlr2nxvkqUFLSaY2ZbA+P1q22q+KrlxWOn/38RX+u5kTkYL2mTujEpzUhGkS+K/QCYp9oagfXG39XOzyySg==", + "version": "2.6.6", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.6.tgz", + "integrity": "sha512-95X8guJYhfqiuVVhRFxVQcf4hW/2bCuoPwDasMf/531STFoNoWTT7YDnWdXHEZKqAGUigmpG31r2FE70LwnzJw==", "dev": true, "dependencies": { "@types/node": "*", @@ -8346,9 +8346,9 @@ "integrity": "sha512-2qGq5LAOTh9izcc0+F+dToFigBWiK1phKPt7rNhOqJSr35y8rlIBjDwGtFSgAI6MGIhjwOVNSQZVdJsZJ2uR1w==" }, "@types/node-fetch": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.5.tgz", - "integrity": "sha512-OZsUlr2nxvkqUFLSaY2ZbA+P1q22q+KrlxWOn/38RX+u5kTkYL2mTujEpzUhGkS+K/QCYp9oagfXG39XOzyySg==", + "version": "2.6.6", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.6.tgz", + "integrity": "sha512-95X8guJYhfqiuVVhRFxVQcf4hW/2bCuoPwDasMf/531STFoNoWTT7YDnWdXHEZKqAGUigmpG31r2FE70LwnzJw==", "dev": true, "requires": { "@types/node": "*", From b7d6505fd0dc543abc0f622675a2758fc2535263 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 26 Sep 2023 17:40:25 +0200 Subject: [PATCH 0518/1076] release: Bump tlv-account-resolution and dependents (#5367) --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 8492beca..d0b2c6bf 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -23,7 +23,7 @@ solana-logger = "=1.16.13" solana-program = "=1.16.13" solana-remote-wallet = "=1.16.13" solana-sdk = "=1.16.13" -spl-associated-token-account = { version = "=2.1", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } +spl-associated-token-account = { version = "=2.2", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "=0.7.0", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "=4.0", path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" diff --git a/program/Cargo.toml b/program/Cargo.toml index 275ce9da..2d1d5a51 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -23,7 +23,7 @@ serde_derive = "1.0.103" solana-program = "1.16.13" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-pod = { version = "0.1", path = "../../libraries/pod", features = ["borsh"] } -spl-token-2022 = { version = "0.8", path = "../../token/program-2022", features = [ "no-entrypoint" ] } +spl-token-2022 = { version = "0.9", path = "../../token/program-2022", features = [ "no-entrypoint" ] } thiserror = "1.0" bincode = "1.3.1" From aee7367b5f4de3f39765b461675f7bef2ff2b61c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Sep 2023 19:38:04 +0200 Subject: [PATCH 0519/1076] build(deps-dev): bump rimraf from 5.0.1 to 5.0.4 in /stake-pool/js (#5364) Bumps [rimraf](https://github.com/isaacs/rimraf) from 5.0.1 to 5.0.4. - [Changelog](https://github.com/isaacs/rimraf/blob/main/CHANGELOG.md) - [Commits](https://github.com/isaacs/rimraf/compare/v5.0.1...v5.0.4) --- updated-dependencies: - dependency-name: rimraf dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 140 ++++++++++++++-------------- 1 file changed, 70 insertions(+), 70 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 71305857..88c7154e 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -823,9 +823,9 @@ } }, "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", - "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, "dependencies": { "ansi-regex": "^6.0.1" @@ -3712,9 +3712,9 @@ } }, "node_modules/foreground-child/node_modules/signal-exit": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz", - "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, "engines": { "node": ">=14" @@ -4343,9 +4343,9 @@ } }, "node_modules/jackspeak": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.0.tgz", - "integrity": "sha512-r5XBrqIJfwRIjRt/Xr5fv9Wh09qyhHfKnYddDlpM+ibRR20qrYActpCAgU6U+d53EOEjzkvxPMVHSlgR7leXrQ==", + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.5.tgz", + "integrity": "sha512-Ratx+B8WeXLAtRJn26hrhY8S1+Jz6pxPMrkrdkgb/NstTNiqMhX0/oFVu5wX+g5n6JlEu2LPsDJmY8nRP4+alw==", "dev": true, "dependencies": { "@isaacs/cliui": "^8.0.2" @@ -5351,9 +5351,9 @@ } }, "node_modules/minipass": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz", - "integrity": "sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.3.tgz", + "integrity": "sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==", "dev": true, "engines": { "node": ">=16 || 14 >=14.17" @@ -5623,13 +5623,13 @@ "dev": true }, "node_modules/path-scurry": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.9.2.tgz", - "integrity": "sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", "dev": true, "dependencies": { - "lru-cache": "^9.1.1", - "minipass": "^5.0.0 || ^6.0.2" + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -5639,9 +5639,9 @@ } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.1.tgz", - "integrity": "sha512-65/Jky17UwSb0BuB9V+MyDpsOtXKmYwzhyl+cOa9XUiI4uV2Ouy/2voFP3+al0BjZbJgMBD8FojMpAf+Z+qn4A==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", + "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", "dev": true, "engines": { "node": "14 || >=16.14" @@ -5913,15 +5913,15 @@ } }, "node_modules/rimraf": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.1.tgz", - "integrity": "sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.4.tgz", + "integrity": "sha512-rizQI/o/YAMM1us0Zyax0uRfIK39XR52EAjjOi0fzMolpGp0onj6CWzBAXuOx6+6Xi9Rgi0d9tUZojhJerLUmQ==", "dev": true, "dependencies": { - "glob": "^10.2.5" + "glob": "^10.3.7" }, "bin": { - "rimraf": "dist/cjs/src/bin.js" + "rimraf": "dist/esm/bin.mjs" }, "engines": { "node": ">=14" @@ -5940,19 +5940,19 @@ } }, "node_modules/rimraf/node_modules/glob": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.2.5.tgz", - "integrity": "sha512-Gj+dFYPZ5hc5dazjXzB0iHg2jKWJZYMjITXYPBRQ/xc2Buw7H0BINknRTwURJ6IC6MEFpYbLvtgVb3qD+DwyuA==", + "version": "10.3.9", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.9.tgz", + "integrity": "sha512-2tU/LKevAQvDVuVJ9pg9Yv9xcbSh+TqHuTaXTNbQwf+0kDl9Fm6bMovi4Nm5c8TVvfxo2LLcqCGtmO9KoJaGWg==", "dev": true, "dependencies": { "foreground-child": "^3.1.0", - "jackspeak": "^2.0.3", - "minimatch": "^9.0.0", - "minipass": "^5.0.0 || ^6.0.2", - "path-scurry": "^1.7.0" + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" }, "bin": { - "glob": "dist/cjs/src/bin.js" + "glob": "dist/esm/bin.mjs" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -5962,9 +5962,9 @@ } }, "node_modules/rimraf/node_modules/minimatch": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz", - "integrity": "sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -7633,9 +7633,9 @@ } }, "strip-ansi": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", - "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, "requires": { "ansi-regex": "^6.0.1" @@ -9738,9 +9738,9 @@ }, "dependencies": { "signal-exit": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz", - "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true } } @@ -10184,9 +10184,9 @@ } }, "jackspeak": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.0.tgz", - "integrity": "sha512-r5XBrqIJfwRIjRt/Xr5fv9Wh09qyhHfKnYddDlpM+ibRR20qrYActpCAgU6U+d53EOEjzkvxPMVHSlgR7leXrQ==", + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.5.tgz", + "integrity": "sha512-Ratx+B8WeXLAtRJn26hrhY8S1+Jz6pxPMrkrdkgb/NstTNiqMhX0/oFVu5wX+g5n6JlEu2LPsDJmY8nRP4+alw==", "dev": true, "requires": { "@isaacs/cliui": "^8.0.2", @@ -10965,9 +10965,9 @@ } }, "minipass": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz", - "integrity": "sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.3.tgz", + "integrity": "sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==", "dev": true }, "ms": { @@ -11169,19 +11169,19 @@ "dev": true }, "path-scurry": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.9.2.tgz", - "integrity": "sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", "dev": true, "requires": { - "lru-cache": "^9.1.1", - "minipass": "^5.0.0 || ^6.0.2" + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "dependencies": { "lru-cache": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.1.tgz", - "integrity": "sha512-65/Jky17UwSb0BuB9V+MyDpsOtXKmYwzhyl+cOa9XUiI4uV2Ouy/2voFP3+al0BjZbJgMBD8FojMpAf+Z+qn4A==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", + "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", "dev": true } } @@ -11372,12 +11372,12 @@ "dev": true }, "rimraf": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.1.tgz", - "integrity": "sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.4.tgz", + "integrity": "sha512-rizQI/o/YAMM1us0Zyax0uRfIK39XR52EAjjOi0fzMolpGp0onj6CWzBAXuOx6+6Xi9Rgi0d9tUZojhJerLUmQ==", "dev": true, "requires": { - "glob": "^10.2.5" + "glob": "^10.3.7" }, "dependencies": { "brace-expansion": { @@ -11390,22 +11390,22 @@ } }, "glob": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.2.5.tgz", - "integrity": "sha512-Gj+dFYPZ5hc5dazjXzB0iHg2jKWJZYMjITXYPBRQ/xc2Buw7H0BINknRTwURJ6IC6MEFpYbLvtgVb3qD+DwyuA==", + "version": "10.3.9", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.9.tgz", + "integrity": "sha512-2tU/LKevAQvDVuVJ9pg9Yv9xcbSh+TqHuTaXTNbQwf+0kDl9Fm6bMovi4Nm5c8TVvfxo2LLcqCGtmO9KoJaGWg==", "dev": true, "requires": { "foreground-child": "^3.1.0", - "jackspeak": "^2.0.3", - "minimatch": "^9.0.0", - "minipass": "^5.0.0 || ^6.0.2", - "path-scurry": "^1.7.0" + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" } }, "minimatch": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz", - "integrity": "sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", "dev": true, "requires": { "brace-expansion": "^2.0.1" From 5fdeab5467fc6312cf19fd60f9e311ea26065bdb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Sep 2023 19:38:13 +0200 Subject: [PATCH 0520/1076] build(deps-dev): bump @typescript-eslint/parser from 6.7.2 to 6.7.3 in /stake-pool/js (#5362) build(deps-dev): bump @typescript-eslint/parser in /stake-pool/js Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.7.2 to 6.7.3. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.7.3/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 145 +++++++++++++++++++++++++--- 1 file changed, 131 insertions(+), 14 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 88c7154e..b03a3a21 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1879,15 +1879,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.2.tgz", - "integrity": "sha512-KA3E4ox0ws+SPyxQf9iSI25R6b4Ne78ORhNHeVKrPQnoYsb9UhieoiRoJgrzgEeKGOXhcY1i8YtOeCHHTDa6Fw==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.3.tgz", + "integrity": "sha512-TlutE+iep2o7R8Lf+yoer3zU6/0EAUc8QIBB3GYBc1KGz4c4TRm83xwXUZVPlZ6YCLss4r77jbu6j3sendJoiQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.7.2", - "@typescript-eslint/types": "6.7.2", - "@typescript-eslint/typescript-estree": "6.7.2", - "@typescript-eslint/visitor-keys": "6.7.2", + "@typescript-eslint/scope-manager": "6.7.3", + "@typescript-eslint/types": "6.7.3", + "@typescript-eslint/typescript-estree": "6.7.3", + "@typescript-eslint/visitor-keys": "6.7.3", "debug": "^4.3.4" }, "engines": { @@ -1906,6 +1906,80 @@ } } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.3.tgz", + "integrity": "sha512-wOlo0QnEou9cHO2TdkJmzF7DFGvAKEnB82PuPNHpT8ZKKaZu6Bm63ugOTn9fXNJtvuDPanBc78lGUGGytJoVzQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.7.3", + "@typescript-eslint/visitor-keys": "6.7.3" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.3.tgz", + "integrity": "sha512-4g+de6roB2NFcfkZb439tigpAMnvEIg3rIjWQ+EM7IBaYt/CdJt6em9BJ4h4UpdgaBWdmx2iWsafHTrqmgIPNw==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.3.tgz", + "integrity": "sha512-YLQ3tJoS4VxLFYHTw21oe1/vIZPRqAO91z6Uv0Ss2BKm/Ag7/RVQBcXTGcXhgJMdA4U+HrKuY5gWlJlvoaKZ5g==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.7.3", + "@typescript-eslint/visitor-keys": "6.7.3", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.3.tgz", + "integrity": "sha512-HEVXkU9IB+nk9o63CeICMHxFWbHWr3E1mpilIQBe9+7L/lH97rleFLVtYsfnWB+JVMaiFnEaxvknvmIzX+CqVg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.7.3", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "6.7.2", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.2.tgz", @@ -8435,16 +8509,59 @@ } }, "@typescript-eslint/parser": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.2.tgz", - "integrity": "sha512-KA3E4ox0ws+SPyxQf9iSI25R6b4Ne78ORhNHeVKrPQnoYsb9UhieoiRoJgrzgEeKGOXhcY1i8YtOeCHHTDa6Fw==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.3.tgz", + "integrity": "sha512-TlutE+iep2o7R8Lf+yoer3zU6/0EAUc8QIBB3GYBc1KGz4c4TRm83xwXUZVPlZ6YCLss4r77jbu6j3sendJoiQ==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "6.7.2", - "@typescript-eslint/types": "6.7.2", - "@typescript-eslint/typescript-estree": "6.7.2", - "@typescript-eslint/visitor-keys": "6.7.2", + "@typescript-eslint/scope-manager": "6.7.3", + "@typescript-eslint/types": "6.7.3", + "@typescript-eslint/typescript-estree": "6.7.3", + "@typescript-eslint/visitor-keys": "6.7.3", "debug": "^4.3.4" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.3.tgz", + "integrity": "sha512-wOlo0QnEou9cHO2TdkJmzF7DFGvAKEnB82PuPNHpT8ZKKaZu6Bm63ugOTn9fXNJtvuDPanBc78lGUGGytJoVzQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.7.3", + "@typescript-eslint/visitor-keys": "6.7.3" + } + }, + "@typescript-eslint/types": { + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.3.tgz", + "integrity": "sha512-4g+de6roB2NFcfkZb439tigpAMnvEIg3rIjWQ+EM7IBaYt/CdJt6em9BJ4h4UpdgaBWdmx2iWsafHTrqmgIPNw==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.3.tgz", + "integrity": "sha512-YLQ3tJoS4VxLFYHTw21oe1/vIZPRqAO91z6Uv0Ss2BKm/Ag7/RVQBcXTGcXhgJMdA4U+HrKuY5gWlJlvoaKZ5g==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.7.3", + "@typescript-eslint/visitor-keys": "6.7.3", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.3.tgz", + "integrity": "sha512-HEVXkU9IB+nk9o63CeICMHxFWbHWr3E1mpilIQBe9+7L/lH97rleFLVtYsfnWB+JVMaiFnEaxvknvmIzX+CqVg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.7.3", + "eslint-visitor-keys": "^3.4.1" + } + } } }, "@typescript-eslint/scope-manager": { From 310e49ccf3f61306443206affe590ec1e56c1249 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Sep 2023 19:38:22 +0200 Subject: [PATCH 0521/1076] build(deps-dev): bump @rollup/plugin-typescript from 11.1.3 to 11.1.4 in /stake-pool/js (#5363) build(deps-dev): bump @rollup/plugin-typescript in /stake-pool/js Bumps [@rollup/plugin-typescript](https://github.com/rollup/plugins/tree/HEAD/packages/typescript) from 11.1.3 to 11.1.4. - [Changelog](https://github.com/rollup/plugins/blob/master/packages/typescript/CHANGELOG.md) - [Commits](https://github.com/rollup/plugins/commits/typescript-v11.1.4/packages/typescript) --- updated-dependencies: - dependency-name: "@rollup/plugin-typescript" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index b03a3a21..2383115e 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1489,9 +1489,9 @@ } }, "node_modules/@rollup/plugin-typescript": { - "version": "11.1.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.3.tgz", - "integrity": "sha512-8o6cNgN44kQBcpsUJTbTXMTtb87oR1O0zgP3Dxm71hrNgparap3VujgofEilTYJo+ivf2ke6uy3/E5QEaiRlDA==", + "version": "11.1.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.4.tgz", + "integrity": "sha512-WZRh5LBVLQXdKFICUId5J3eIpmjGURaBqntfg3GSZACgeOAFS+lOSMGTwfzDkELTaZVp/lWdMVNU3UkwCUBg/Q==", "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1", @@ -8192,9 +8192,9 @@ } }, "@rollup/plugin-typescript": { - "version": "11.1.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.3.tgz", - "integrity": "sha512-8o6cNgN44kQBcpsUJTbTXMTtb87oR1O0zgP3Dxm71hrNgparap3VujgofEilTYJo+ivf2ke6uy3/E5QEaiRlDA==", + "version": "11.1.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.4.tgz", + "integrity": "sha512-WZRh5LBVLQXdKFICUId5J3eIpmjGURaBqntfg3GSZACgeOAFS+lOSMGTwfzDkELTaZVp/lWdMVNU3UkwCUBg/Q==", "dev": true, "requires": { "@rollup/pluginutils": "^5.0.1", From 5cd6fd0ab732a8aa9c3342cb51240d0605883bff Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 27 Sep 2023 01:08:27 +0200 Subject: [PATCH 0522/1076] stake-pool-py: Add and use new decrease instruction (#5334) --- clients/py/stake_pool/actions.py | 7 +- clients/py/stake_pool/instructions.py | 78 +++++++++++++++++++++++ clients/py/tests/test_a_time_sensitive.py | 2 +- clients/py/tests/test_bot_rebalance.py | 6 +- 4 files changed, 86 insertions(+), 7 deletions(-) diff --git a/clients/py/stake_pool/actions.py b/clients/py/stake_pool/actions.py index 6e681a31..a7eff4d9 100644 --- a/clients/py/stake_pool/actions.py +++ b/clients/py/stake_pool/actions.py @@ -569,17 +569,18 @@ async def decrease_validator_stake( txn = Transaction() txn.add( - sp.decrease_validator_stake( - sp.DecreaseValidatorStakeParams( + sp.decrease_validator_stake_with_reserve( + sp.DecreaseValidatorStakeWithReserveParams( program_id=STAKE_POOL_PROGRAM_ID, stake_pool=stake_pool_address, staker=staker.public_key, withdraw_authority=withdraw_authority, validator_list=stake_pool.validator_list, + reserve_stake=stake_pool.reserve_stake, validator_stake=validator_stake, transient_stake=transient_stake, clock_sysvar=SYSVAR_CLOCK_PUBKEY, - rent_sysvar=SYSVAR_RENT_PUBKEY, + stake_history_sysvar=SYSVAR_STAKE_HISTORY_PUBKEY, system_program_id=sys.SYS_PROGRAM_ID, stake_program_id=STAKE_PROGRAM_ID, lamports=lamports, diff --git a/clients/py/stake_pool/instructions.py b/clients/py/stake_pool/instructions.py index 5152567c..de2e13fe 100644 --- a/clients/py/stake_pool/instructions.py +++ b/clients/py/stake_pool/instructions.py @@ -173,6 +173,42 @@ class DecreaseValidatorStakeParams(NamedTuple): """Seed to used to create the transient stake account.""" +class DecreaseValidatorStakeWithReserveParams(NamedTuple): + """(Staker only) Decrease active stake on a validator, eventually moving it to the reserve""" + + # Accounts + program_id: PublicKey + """SPL Stake Pool program account.""" + stake_pool: PublicKey + """`[]` Stake pool.""" + staker: PublicKey + """`[s]` Staker.""" + withdraw_authority: PublicKey + """`[]` Stake pool withdraw authority.""" + validator_list: PublicKey + """`[w]` Validator stake list storage account.""" + reserve_stake: PublicKey + """`[w]` Stake pool's reserve.""" + validator_stake: PublicKey + """`[w]` Canonical stake to split from.""" + transient_stake: PublicKey + """`[w]` Transient stake account to receive split.""" + clock_sysvar: PublicKey + """`[]` Clock sysvar.""" + stake_history_sysvar: PublicKey + """'[]' Stake history sysvar.""" + system_program_id: PublicKey + """`[]` System program.""" + stake_program_id: PublicKey + """`[]` Stake program.""" + + # Params + lamports: int + """Amount of lamports to split into the transient stake account.""" + transient_stake_seed: int + """Seed to used to create the transient stake account.""" + + class IncreaseValidatorStakeParams(NamedTuple): """(Staker only) Increase stake on a validator from the reserve account.""" @@ -529,6 +565,10 @@ class InstructionType(IntEnum): WITHDRAW_SOL = 16 CREATE_TOKEN_METADATA = 17 UPDATE_TOKEN_METADATA = 18 + INCREASE_ADDITIONAL_VALIDATOR_STAKE = 19 + DECREASE_ADDITIONAL_VALIDATOR_STAKE = 20 + DECREASE_VALIDATOR_STAKE_WITH_RESERVE = 21 + REDELEGATE = 22 INITIALIZE_LAYOUT = Struct( @@ -544,6 +584,12 @@ class InstructionType(IntEnum): "transient_stake_seed" / Int64ul, ) +MOVE_STAKE_LAYOUT_WITH_EPHEMERAL_STAKE = Struct( + "lamports" / Int64ul, + "transient_stake_seed" / Int64ul, + "ephemeral_stake_seed" / Int64ul, +) + UPDATE_VALIDATOR_LIST_BALANCE_LAYOUT = Struct( "start_index" / Int32ul, "no_merge" / Int8ul, @@ -588,6 +634,9 @@ class InstructionType(IntEnum): InstructionType.WITHDRAW_SOL: AMOUNT_LAYOUT, InstructionType.CREATE_TOKEN_METADATA: TOKEN_METADATA_LAYOUT, InstructionType.UPDATE_TOKEN_METADATA: TOKEN_METADATA_LAYOUT, + InstructionType.DECREASE_ADDITIONAL_VALIDATOR_STAKE: MOVE_STAKE_LAYOUT_WITH_EPHEMERAL_STAKE, + InstructionType.INCREASE_ADDITIONAL_VALIDATOR_STAKE: MOVE_STAKE_LAYOUT_WITH_EPHEMERAL_STAKE, + InstructionType.DECREASE_VALIDATOR_STAKE_WITH_RESERVE: MOVE_STAKE_LAYOUT, }, ), ) @@ -988,6 +1037,35 @@ def decrease_validator_stake(params: DecreaseValidatorStakeParams) -> Transactio ) +def decrease_validator_stake_with_reserve(params: DecreaseValidatorStakeWithReserveParams) -> TransactionInstruction: + """Creates instruction to decrease the stake on a validator.""" + return TransactionInstruction( + keys=[ + AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.staker, is_signer=True, is_writable=False), + AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.validator_list, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.reserve_stake, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.validator_stake, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.transient_stake, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.clock_sysvar, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.stake_history_sysvar, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.system_program_id, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.stake_program_id, is_signer=False, is_writable=False), + ], + program_id=params.program_id, + data=INSTRUCTIONS_LAYOUT.build( + dict( + instruction_type=InstructionType.DECREASE_VALIDATOR_STAKE_WITH_RESERVE, + args={ + 'lamports': params.lamports, + 'transient_stake_seed': params.transient_stake_seed + } + ) + ) + ) + + def create_token_metadata(params: CreateTokenMetadataParams) -> TransactionInstruction: """Creates an instruction to create metadata using the mpl token metadata program for the pool token.""" diff --git a/clients/py/tests/test_a_time_sensitive.py b/clients/py/tests/test_a_time_sensitive.py index 4b9164cf..78abbf47 100644 --- a/clients/py/tests/test_a_time_sensitive.py +++ b/clients/py/tests/test_a_time_sensitive.py @@ -64,7 +64,7 @@ async def test_increase_decrease_this_is_very_slow(async_client, validators, pay data = resp['result']['value']['data'] validator_list = ValidatorList.decode(data[0], data[1]) for validator in validator_list.validators: - assert validator.transient_stake_lamports == decrease_amount + assert validator.transient_stake_lamports == decrease_amount + stake_rent_exemption assert validator.active_stake_lamports == increase_amount - decrease_amount + minimum_amount print("Waiting for epoch to roll over") diff --git a/clients/py/tests/test_bot_rebalance.py b/clients/py/tests/test_bot_rebalance.py index 548a2ac7..c0283ef5 100644 --- a/clients/py/tests/test_bot_rebalance.py +++ b/clients/py/tests/test_bot_rebalance.py @@ -54,10 +54,10 @@ async def test_rebalance_this_is_very_slow(async_client, validators, payer, stak max_in_reserve = total_lamports - minimum_amount * len(validators) await rebalance(ENDPOINT, stake_pool_address, payer, max_in_reserve / LAMPORTS_PER_SOL) - # should still only have minimum left + rent exemptions from increase + # should still only have minimum left resp = await async_client.get_account_info(stake_pool.reserve_stake, commitment=Confirmed) reserve_lamports = resp['result']['value']['lamports'] - assert reserve_lamports == stake_rent_exemption * (1 + len(validator_list.validators)) + MINIMUM_RESERVE_LAMPORTS + assert reserve_lamports == stake_rent_exemption + MINIMUM_RESERVE_LAMPORTS # should all be decreasing now resp = await async_client.get_account_info(validator_list_address, commitment=Confirmed) @@ -65,7 +65,7 @@ async def test_rebalance_this_is_very_slow(async_client, validators, payer, stak validator_list = ValidatorList.decode(data[0], data[1]) for validator in validator_list.validators: assert validator.active_stake_lamports == minimum_amount - assert validator.transient_stake_lamports == max_in_reserve / len(validators) - stake_rent_exemption + assert validator.transient_stake_lamports == max_in_reserve / len(validators) # Test case 3: Do nothing print('Waiting for next epoch') From 6b35fd34333d88195e8d84d17aa1b74b5a802130 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 27 Sep 2023 01:08:36 +0200 Subject: [PATCH 0523/1076] stake-pool-js: Add new decrease instruction (#5333) stake-pool-js: Add new decrease instruction --- clients/js-legacy/src/index.ts | 3 +- clients/js-legacy/src/instructions.ts | 54 ++++++++++++++++++++- clients/js-legacy/test/instructions.test.ts | 2 +- 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/clients/js-legacy/src/index.ts b/clients/js-legacy/src/index.ts index a65274ef..faf95a5e 100644 --- a/clients/js-legacy/src/index.ts +++ b/clients/js-legacy/src/index.ts @@ -807,10 +807,11 @@ export async function decreaseValidatorStake( ); } else { instructions.push( - StakePoolInstruction.decreaseValidatorStake({ + StakePoolInstruction.decreaseValidatorStakeWithReserve({ stakePool: stakePoolAddress, staker: stakePool.account.data.staker, validatorList: stakePool.account.data.validatorList, + reserveStake: stakePool.account.data.reserveStake, transientStakeSeed: transientStakeSeed.toNumber(), withdrawAuthority, validatorStake, diff --git a/clients/js-legacy/src/instructions.ts b/clients/js-legacy/src/instructions.ts index 7c1d645a..9891f17b 100644 --- a/clients/js-legacy/src/instructions.ts +++ b/clients/js-legacy/src/instructions.ts @@ -35,6 +35,7 @@ export type StakePoolInstructionType = | 'WithdrawSol' | 'IncreaseAdditionalValidatorStake' | 'DecreaseAdditionalValidatorStake' + | 'DecreaseValidatorStakeWithReserve' | 'Redelegate'; // 'UpdateTokenMetadata' and 'CreateTokenMetadata' have dynamic layouts @@ -158,8 +159,12 @@ export const STAKE_POOL_INSTRUCTION_LAYOUTS: { BufferLayout.ns64('ephemeralStakeSeed'), ]), }, - Redelegate: { + DecreaseValidatorStakeWithReserve: { index: 21, + layout: MOVE_STAKE_LAYOUT, + }, + Redelegate: { + index: 22, layout: BufferLayout.struct([ BufferLayout.u8('instruction'), /// Amount of lamports to redelegate @@ -225,6 +230,10 @@ export type DecreaseValidatorStakeParams = { transientStakeSeed: number; }; +export interface DecreaseValidatorStakeWithReserveParams extends DecreaseValidatorStakeParams { + reserveStake: PublicKey; +} + export interface DecreaseAdditionalValidatorStakeParams extends DecreaseValidatorStakeParams { reserveStake: PublicKey; ephemeralStake: PublicKey; @@ -601,6 +610,49 @@ export class StakePoolInstruction { }); } + /** + * Creates `DecreaseValidatorStakeWithReserve` instruction (rebalance from + * validator account to transient account) + */ + static decreaseValidatorStakeWithReserve( + params: DecreaseValidatorStakeWithReserveParams, + ): TransactionInstruction { + const { + stakePool, + staker, + withdrawAuthority, + validatorList, + reserveStake, + validatorStake, + transientStake, + lamports, + transientStakeSeed, + } = params; + + const type = STAKE_POOL_INSTRUCTION_LAYOUTS.DecreaseValidatorStakeWithReserve; + const data = encodeData(type, { lamports, transientStakeSeed }); + + const keys = [ + { pubkey: stakePool, isSigner: false, isWritable: false }, + { pubkey: staker, isSigner: true, isWritable: false }, + { pubkey: withdrawAuthority, isSigner: false, isWritable: false }, + { pubkey: validatorList, isSigner: false, isWritable: true }, + { pubkey: reserveStake, isSigner: false, isWritable: true }, + { pubkey: validatorStake, isSigner: false, isWritable: true }, + { pubkey: transientStake, isSigner: false, isWritable: true }, + { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false }, + { pubkey: SYSVAR_STAKE_HISTORY_PUBKEY, isSigner: false, isWritable: false }, + { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, + { pubkey: StakeProgram.programId, isSigner: false, isWritable: false }, + ]; + + return new TransactionInstruction({ + programId: STAKE_POOL_PROGRAM_ID, + keys, + data, + }); + } + /** * Creates `DecreaseAdditionalValidatorStake` instruction (rebalance from * validator account to transient account) diff --git a/clients/js-legacy/test/instructions.test.ts b/clients/js-legacy/test/instructions.test.ts index 9941d07a..1a39ddff 100644 --- a/clients/js-legacy/test/instructions.test.ts +++ b/clients/js-legacy/test/instructions.test.ts @@ -347,7 +347,7 @@ describe('StakePoolProgram', () => { res.instructions[0].data, ); - expect(decodedData.instruction).toBe(21); + expect(decodedData.instruction).toBe(22); expect(decodedData.lamports).toBe(data.lamports); expect(decodedData.sourceTransientStakeSeed).toBe(data.sourceTransientStakeSeed); expect(decodedData.destinationTransientStakeSeed).toBe(data.destinationTransientStakeSeed); From ce202b2004a61220b66a4d450ceb527633e62cf4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 27 Sep 2023 15:30:18 +0200 Subject: [PATCH 0524/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.7.2 to 6.7.3 in /stake-pool/js (#5377) build(deps-dev): bump @typescript-eslint/eslint-plugin in /stake-pool/js Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.7.2 to 6.7.3. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.7.3/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 261 ++++++++-------------------- 1 file changed, 72 insertions(+), 189 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 2383115e..5a678ba1 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1809,9 +1809,9 @@ "dev": true }, "node_modules/@types/semver": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.2.tgz", - "integrity": "sha512-7aqorHYgdNO4DM36stTiGO3DvKoex9TQRwsJU6vMaFGyqpBA1MNZkz+PG3gaNUPpTAOYhT1WR7M1JyA3fbS9Cw==", + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw==", "dev": true }, "node_modules/@types/stack-utils": { @@ -1844,16 +1844,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.2.tgz", - "integrity": "sha512-ooaHxlmSgZTM6CHYAFRlifqh1OAr3PAQEwi7lhYhaegbnXrnh7CDcHmc3+ihhbQC7H0i4JF0psI5ehzkF6Yl6Q==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.3.tgz", + "integrity": "sha512-vntq452UHNltxsaaN+L9WyuMch8bMd9CqJ3zhzTPXXidwbf5mqqKCVXEuvRZUqLJSTLeWE65lQwyXsRGnXkCTA==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.7.2", - "@typescript-eslint/type-utils": "6.7.2", - "@typescript-eslint/utils": "6.7.2", - "@typescript-eslint/visitor-keys": "6.7.2", + "@typescript-eslint/scope-manager": "6.7.3", + "@typescript-eslint/type-utils": "6.7.3", + "@typescript-eslint/utils": "6.7.3", + "@typescript-eslint/visitor-keys": "6.7.3", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -1906,7 +1906,7 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "node_modules/@typescript-eslint/scope-manager": { "version": "6.7.3", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.3.tgz", "integrity": "sha512-wOlo0QnEou9cHO2TdkJmzF7DFGvAKEnB82PuPNHpT8ZKKaZu6Bm63ugOTn9fXNJtvuDPanBc78lGUGGytJoVzQ==", @@ -1923,88 +1923,14 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.3.tgz", - "integrity": "sha512-4g+de6roB2NFcfkZb439tigpAMnvEIg3rIjWQ+EM7IBaYt/CdJt6em9BJ4h4UpdgaBWdmx2iWsafHTrqmgIPNw==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.3.tgz", - "integrity": "sha512-YLQ3tJoS4VxLFYHTw21oe1/vIZPRqAO91z6Uv0Ss2BKm/Ag7/RVQBcXTGcXhgJMdA4U+HrKuY5gWlJlvoaKZ5g==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.7.3", - "@typescript-eslint/visitor-keys": "6.7.3", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.3.tgz", - "integrity": "sha512-HEVXkU9IB+nk9o63CeICMHxFWbHWr3E1mpilIQBe9+7L/lH97rleFLVtYsfnWB+JVMaiFnEaxvknvmIzX+CqVg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.7.3", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.2.tgz", - "integrity": "sha512-bgi6plgyZjEqapr7u2mhxGR6E8WCzKNUFWNh6fkpVe9+yzRZeYtDTbsIBzKbcxI+r1qVWt6VIoMSNZ4r2A+6Yw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.7.2", - "@typescript-eslint/visitor-keys": "6.7.2" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.2.tgz", - "integrity": "sha512-36F4fOYIROYRl0qj95dYKx6kybddLtsbmPIYNK0OBeXv2j9L5nZ17j9jmfy+bIDHKQgn2EZX+cofsqi8NPATBQ==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.3.tgz", + "integrity": "sha512-Fc68K0aTDrKIBvLnKTZ5Pf3MXK495YErrbHb1R6aTpfK5OdSFj0rVN7ib6Tx6ePrZ2gsjLqr0s98NG7l96KSQw==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.7.2", - "@typescript-eslint/utils": "6.7.2", + "@typescript-eslint/typescript-estree": "6.7.3", + "@typescript-eslint/utils": "6.7.3", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -2025,9 +1951,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.2.tgz", - "integrity": "sha512-flJYwMYgnUNDAN9/GAI3l8+wTmvTYdv64fcH8aoJK76Y+1FCZ08RtI5zDerM/FYT5DMkAc+19E4aLmd5KqdFyg==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.3.tgz", + "integrity": "sha512-4g+de6roB2NFcfkZb439tigpAMnvEIg3rIjWQ+EM7IBaYt/CdJt6em9BJ4h4UpdgaBWdmx2iWsafHTrqmgIPNw==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -2038,13 +1964,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.2.tgz", - "integrity": "sha512-kiJKVMLkoSciGyFU0TOY0fRxnp9qq1AzVOHNeN1+B9erKFCJ4Z8WdjAkKQPP+b1pWStGFqezMLltxO+308dJTQ==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.3.tgz", + "integrity": "sha512-YLQ3tJoS4VxLFYHTw21oe1/vIZPRqAO91z6Uv0Ss2BKm/Ag7/RVQBcXTGcXhgJMdA4U+HrKuY5gWlJlvoaKZ5g==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.7.2", - "@typescript-eslint/visitor-keys": "6.7.2", + "@typescript-eslint/types": "6.7.3", + "@typescript-eslint/visitor-keys": "6.7.3", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2065,17 +1991,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.2.tgz", - "integrity": "sha512-ZCcBJug/TS6fXRTsoTkgnsvyWSiXwMNiPzBUani7hDidBdj1779qwM1FIAmpH4lvlOZNF3EScsxxuGifjpLSWQ==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.3.tgz", + "integrity": "sha512-vzLkVder21GpWRrmSR9JxGZ5+ibIUSudXlW52qeKpzUEQhRSmyZiVDDj3crAth7+5tmN1ulvgKaCU2f/bPRCzg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.7.2", - "@typescript-eslint/types": "6.7.2", - "@typescript-eslint/typescript-estree": "6.7.2", + "@typescript-eslint/scope-manager": "6.7.3", + "@typescript-eslint/types": "6.7.3", + "@typescript-eslint/typescript-estree": "6.7.3", "semver": "^7.5.4" }, "engines": { @@ -2090,12 +2016,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.2.tgz", - "integrity": "sha512-uVw9VIMFBUTz8rIeaUT3fFe8xIUx8r4ywAdlQv1ifH+6acn/XF8Y6rwJ7XNmkNMDrTW+7+vxFFPIF40nJCVsMQ==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.3.tgz", + "integrity": "sha512-HEVXkU9IB+nk9o63CeICMHxFWbHWr3E1mpilIQBe9+7L/lH97rleFLVtYsfnWB+JVMaiFnEaxvknvmIzX+CqVg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.7.2", + "@typescript-eslint/types": "6.7.3", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -8455,9 +8381,9 @@ "dev": true }, "@types/semver": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.2.tgz", - "integrity": "sha512-7aqorHYgdNO4DM36stTiGO3DvKoex9TQRwsJU6vMaFGyqpBA1MNZkz+PG3gaNUPpTAOYhT1WR7M1JyA3fbS9Cw==", + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw==", "dev": true }, "@types/stack-utils": { @@ -8490,16 +8416,16 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.2.tgz", - "integrity": "sha512-ooaHxlmSgZTM6CHYAFRlifqh1OAr3PAQEwi7lhYhaegbnXrnh7CDcHmc3+ihhbQC7H0i4JF0psI5ehzkF6Yl6Q==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.3.tgz", + "integrity": "sha512-vntq452UHNltxsaaN+L9WyuMch8bMd9CqJ3zhzTPXXidwbf5mqqKCVXEuvRZUqLJSTLeWE65lQwyXsRGnXkCTA==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.7.2", - "@typescript-eslint/type-utils": "6.7.2", - "@typescript-eslint/utils": "6.7.2", - "@typescript-eslint/visitor-keys": "6.7.2", + "@typescript-eslint/scope-manager": "6.7.3", + "@typescript-eslint/type-utils": "6.7.3", + "@typescript-eslint/utils": "6.7.3", + "@typescript-eslint/visitor-keys": "6.7.3", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -8519,87 +8445,44 @@ "@typescript-eslint/typescript-estree": "6.7.3", "@typescript-eslint/visitor-keys": "6.7.3", "debug": "^4.3.4" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.3.tgz", - "integrity": "sha512-wOlo0QnEou9cHO2TdkJmzF7DFGvAKEnB82PuPNHpT8ZKKaZu6Bm63ugOTn9fXNJtvuDPanBc78lGUGGytJoVzQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.7.3", - "@typescript-eslint/visitor-keys": "6.7.3" - } - }, - "@typescript-eslint/types": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.3.tgz", - "integrity": "sha512-4g+de6roB2NFcfkZb439tigpAMnvEIg3rIjWQ+EM7IBaYt/CdJt6em9BJ4h4UpdgaBWdmx2iWsafHTrqmgIPNw==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.3.tgz", - "integrity": "sha512-YLQ3tJoS4VxLFYHTw21oe1/vIZPRqAO91z6Uv0Ss2BKm/Ag7/RVQBcXTGcXhgJMdA4U+HrKuY5gWlJlvoaKZ5g==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.7.3", - "@typescript-eslint/visitor-keys": "6.7.3", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.3.tgz", - "integrity": "sha512-HEVXkU9IB+nk9o63CeICMHxFWbHWr3E1mpilIQBe9+7L/lH97rleFLVtYsfnWB+JVMaiFnEaxvknvmIzX+CqVg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.7.3", - "eslint-visitor-keys": "^3.4.1" - } - } } }, "@typescript-eslint/scope-manager": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.2.tgz", - "integrity": "sha512-bgi6plgyZjEqapr7u2mhxGR6E8WCzKNUFWNh6fkpVe9+yzRZeYtDTbsIBzKbcxI+r1qVWt6VIoMSNZ4r2A+6Yw==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.3.tgz", + "integrity": "sha512-wOlo0QnEou9cHO2TdkJmzF7DFGvAKEnB82PuPNHpT8ZKKaZu6Bm63ugOTn9fXNJtvuDPanBc78lGUGGytJoVzQ==", "dev": true, "requires": { - "@typescript-eslint/types": "6.7.2", - "@typescript-eslint/visitor-keys": "6.7.2" + "@typescript-eslint/types": "6.7.3", + "@typescript-eslint/visitor-keys": "6.7.3" } }, "@typescript-eslint/type-utils": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.2.tgz", - "integrity": "sha512-36F4fOYIROYRl0qj95dYKx6kybddLtsbmPIYNK0OBeXv2j9L5nZ17j9jmfy+bIDHKQgn2EZX+cofsqi8NPATBQ==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.3.tgz", + "integrity": "sha512-Fc68K0aTDrKIBvLnKTZ5Pf3MXK495YErrbHb1R6aTpfK5OdSFj0rVN7ib6Tx6ePrZ2gsjLqr0s98NG7l96KSQw==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "6.7.2", - "@typescript-eslint/utils": "6.7.2", + "@typescript-eslint/typescript-estree": "6.7.3", + "@typescript-eslint/utils": "6.7.3", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" } }, "@typescript-eslint/types": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.2.tgz", - "integrity": "sha512-flJYwMYgnUNDAN9/GAI3l8+wTmvTYdv64fcH8aoJK76Y+1FCZ08RtI5zDerM/FYT5DMkAc+19E4aLmd5KqdFyg==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.3.tgz", + "integrity": "sha512-4g+de6roB2NFcfkZb439tigpAMnvEIg3rIjWQ+EM7IBaYt/CdJt6em9BJ4h4UpdgaBWdmx2iWsafHTrqmgIPNw==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.2.tgz", - "integrity": "sha512-kiJKVMLkoSciGyFU0TOY0fRxnp9qq1AzVOHNeN1+B9erKFCJ4Z8WdjAkKQPP+b1pWStGFqezMLltxO+308dJTQ==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.3.tgz", + "integrity": "sha512-YLQ3tJoS4VxLFYHTw21oe1/vIZPRqAO91z6Uv0Ss2BKm/Ag7/RVQBcXTGcXhgJMdA4U+HrKuY5gWlJlvoaKZ5g==", "dev": true, "requires": { - "@typescript-eslint/types": "6.7.2", - "@typescript-eslint/visitor-keys": "6.7.2", + "@typescript-eslint/types": "6.7.3", + "@typescript-eslint/visitor-keys": "6.7.3", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -8608,27 +8491,27 @@ } }, "@typescript-eslint/utils": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.2.tgz", - "integrity": "sha512-ZCcBJug/TS6fXRTsoTkgnsvyWSiXwMNiPzBUani7hDidBdj1779qwM1FIAmpH4lvlOZNF3EScsxxuGifjpLSWQ==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.3.tgz", + "integrity": "sha512-vzLkVder21GpWRrmSR9JxGZ5+ibIUSudXlW52qeKpzUEQhRSmyZiVDDj3crAth7+5tmN1ulvgKaCU2f/bPRCzg==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.7.2", - "@typescript-eslint/types": "6.7.2", - "@typescript-eslint/typescript-estree": "6.7.2", + "@typescript-eslint/scope-manager": "6.7.3", + "@typescript-eslint/types": "6.7.3", + "@typescript-eslint/typescript-estree": "6.7.3", "semver": "^7.5.4" } }, "@typescript-eslint/visitor-keys": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.2.tgz", - "integrity": "sha512-uVw9VIMFBUTz8rIeaUT3fFe8xIUx8r4ywAdlQv1ifH+6acn/XF8Y6rwJ7XNmkNMDrTW+7+vxFFPIF40nJCVsMQ==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.3.tgz", + "integrity": "sha512-HEVXkU9IB+nk9o63CeICMHxFWbHWr3E1mpilIQBe9+7L/lH97rleFLVtYsfnWB+JVMaiFnEaxvknvmIzX+CqVg==", "dev": true, "requires": { - "@typescript-eslint/types": "6.7.2", + "@typescript-eslint/types": "6.7.3", "eslint-visitor-keys": "^3.4.1" } }, From 28459919e4cd53e19ad5b7228fcee7bf0e624da0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 27 Sep 2023 15:30:26 +0200 Subject: [PATCH 0525/1076] build(deps-dev): bump @types/node from 20.6.5 to 20.7.0 in /stake-pool/js (#5376) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.6.5 to 20.7.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 5a678ba1..716655fd 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1768,9 +1768,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.6.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.5.tgz", - "integrity": "sha512-2qGq5LAOTh9izcc0+F+dToFigBWiK1phKPt7rNhOqJSr35y8rlIBjDwGtFSgAI6MGIhjwOVNSQZVdJsZJ2uR1w==" + "version": "20.7.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.7.0.tgz", + "integrity": "sha512-zI22/pJW2wUZOVyguFaUL1HABdmSVxpXrzIqkjsHmyUjNhPoWM1CKfvVuXfetHhIok4RY573cqS0mZ1SJEnoTg==" }, "node_modules/@types/node-fetch": { "version": "2.6.6", @@ -8341,9 +8341,9 @@ "dev": true }, "@types/node": { - "version": "20.6.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.5.tgz", - "integrity": "sha512-2qGq5LAOTh9izcc0+F+dToFigBWiK1phKPt7rNhOqJSr35y8rlIBjDwGtFSgAI6MGIhjwOVNSQZVdJsZJ2uR1w==" + "version": "20.7.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.7.0.tgz", + "integrity": "sha512-zI22/pJW2wUZOVyguFaUL1HABdmSVxpXrzIqkjsHmyUjNhPoWM1CKfvVuXfetHhIok4RY573cqS0mZ1SJEnoTg==" }, "@types/node-fetch": { "version": "2.6.6", From ef47d09948ccfa109abca53813f1c11573550a18 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 27 Sep 2023 15:30:33 +0200 Subject: [PATCH 0526/1076] build(deps-dev): bump rimraf from 5.0.4 to 5.0.5 in /stake-pool/js (#5378) Bumps [rimraf](https://github.com/isaacs/rimraf) from 5.0.4 to 5.0.5. - [Changelog](https://github.com/isaacs/rimraf/blob/main/CHANGELOG.md) - [Commits](https://github.com/isaacs/rimraf/compare/v5.0.4...v5.0.5) --- updated-dependencies: - dependency-name: rimraf dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 716655fd..c4ba3c10 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -5913,9 +5913,9 @@ } }, "node_modules/rimraf": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.4.tgz", - "integrity": "sha512-rizQI/o/YAMM1us0Zyax0uRfIK39XR52EAjjOi0fzMolpGp0onj6CWzBAXuOx6+6Xi9Rgi0d9tUZojhJerLUmQ==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", + "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", "dev": true, "dependencies": { "glob": "^10.3.7" @@ -11372,9 +11372,9 @@ "dev": true }, "rimraf": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.4.tgz", - "integrity": "sha512-rizQI/o/YAMM1us0Zyax0uRfIK39XR52EAjjOi0fzMolpGp0onj6CWzBAXuOx6+6Xi9Rgi0d9tUZojhJerLUmQ==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", + "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", "dev": true, "requires": { "glob": "^10.3.7" From 02978fe2916577ea030ce1995e8fd6a88355fa07 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 Sep 2023 14:44:44 +0200 Subject: [PATCH 0527/1076] build(deps-dev): bump @types/node from 20.7.0 to 20.7.1 in /stake-pool/js (#5391) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.7.0 to 20.7.1. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index c4ba3c10..1a8f1057 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1768,9 +1768,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.7.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.7.0.tgz", - "integrity": "sha512-zI22/pJW2wUZOVyguFaUL1HABdmSVxpXrzIqkjsHmyUjNhPoWM1CKfvVuXfetHhIok4RY573cqS0mZ1SJEnoTg==" + "version": "20.7.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.7.1.tgz", + "integrity": "sha512-LT+OIXpp2kj4E2S/p91BMe+VgGX2+lfO+XTpfXhh+bCk2LkQtHZSub8ewFBMGP5ClysPjTDFa4sMI8Q3n4T0wg==" }, "node_modules/@types/node-fetch": { "version": "2.6.6", @@ -8341,9 +8341,9 @@ "dev": true }, "@types/node": { - "version": "20.7.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.7.0.tgz", - "integrity": "sha512-zI22/pJW2wUZOVyguFaUL1HABdmSVxpXrzIqkjsHmyUjNhPoWM1CKfvVuXfetHhIok4RY573cqS0mZ1SJEnoTg==" + "version": "20.7.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.7.1.tgz", + "integrity": "sha512-LT+OIXpp2kj4E2S/p91BMe+VgGX2+lfO+XTpfXhh+bCk2LkQtHZSub8ewFBMGP5ClysPjTDFa4sMI8Q3n4T0wg==" }, "@types/node-fetch": { "version": "2.6.6", From a8aecfb416b971fe8e5746e873ae48242d13d66a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 12:49:41 -0400 Subject: [PATCH 0528/1076] build(deps): bump proptest from 1.2.0 to 1.3.1 (#5398) Bumps [proptest](https://github.com/proptest-rs/proptest) from 1.2.0 to 1.3.1. - [Release notes](https://github.com/proptest-rs/proptest/releases) - [Changelog](https://github.com/proptest-rs/proptest/blob/master/CHANGELOG.md) - [Commits](https://github.com/proptest-rs/proptest/compare/v1.2.0...v1.3.1) --- updated-dependencies: - dependency-name: proptest dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 2d1d5a51..fdfd2bac 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -29,7 +29,7 @@ bincode = "1.3.1" [dev-dependencies] assert_matches = "1.5.0" -proptest = "1.2" +proptest = "1.3" solana-program-test = "1.16.13" solana-sdk = "1.16.13" solana-vote-program = "1.16.13" From 41bf4255572cc7c322854a7bc1e0503dcd1ef2aa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 12:51:09 -0400 Subject: [PATCH 0529/1076] build(deps-dev): bump @types/node from 20.7.1 to 20.8.0 in /stake-pool/js (#5401) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.7.1 to 20.8.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 1a8f1057..6f6208bc 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1768,9 +1768,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.7.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.7.1.tgz", - "integrity": "sha512-LT+OIXpp2kj4E2S/p91BMe+VgGX2+lfO+XTpfXhh+bCk2LkQtHZSub8ewFBMGP5ClysPjTDFa4sMI8Q3n4T0wg==" + "version": "20.8.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.0.tgz", + "integrity": "sha512-LzcWltT83s1bthcvjBmiBvGJiiUe84NWRHkw+ZV6Fr41z2FbIzvc815dk2nQ3RAKMuN2fkenM/z3Xv2QzEpYxQ==" }, "node_modules/@types/node-fetch": { "version": "2.6.6", @@ -8341,9 +8341,9 @@ "dev": true }, "@types/node": { - "version": "20.7.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.7.1.tgz", - "integrity": "sha512-LT+OIXpp2kj4E2S/p91BMe+VgGX2+lfO+XTpfXhh+bCk2LkQtHZSub8ewFBMGP5ClysPjTDFa4sMI8Q3n4T0wg==" + "version": "20.8.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.0.tgz", + "integrity": "sha512-LzcWltT83s1bthcvjBmiBvGJiiUe84NWRHkw+ZV6Fr41z2FbIzvc815dk2nQ3RAKMuN2fkenM/z3Xv2QzEpYxQ==" }, "@types/node-fetch": { "version": "2.6.6", From a3ddfb9f35fbe11219f665ff7143bbaeade834ae Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Oct 2023 11:20:43 -0400 Subject: [PATCH 0530/1076] build(deps): bump urllib3 from 1.26.11 to 1.26.17 in /stake-pool/py (#5406) Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.26.11 to 1.26.17. - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst) - [Commits](https://github.com/urllib3/urllib3/compare/1.26.11...1.26.17) --- updated-dependencies: - dependency-name: urllib3 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/py/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/py/requirements.txt b/clients/py/requirements.txt index 3367e7fd..3d939426 100644 --- a/clients/py/requirements.txt +++ b/clients/py/requirements.txt @@ -16,4 +16,4 @@ rfc3986==1.5.0 sniffio==1.2.0 solana==0.18.1 typing_extensions==4.3.0 -urllib3==1.26.11 +urllib3==1.26.17 From 7cd51cdc5e8e13a297b3a873b7887a4a445fb84f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Oct 2023 11:22:15 -0400 Subject: [PATCH 0531/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.7.3 to 6.7.4 in /stake-pool/js (#5417) build(deps-dev): bump @typescript-eslint/eslint-plugin in /stake-pool/js Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.7.3 to 6.7.4. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.7.4/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 354 +++++++++++++++++++++++++--- 1 file changed, 318 insertions(+), 36 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 6f6208bc..c08806aa 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1844,16 +1844,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.3.tgz", - "integrity": "sha512-vntq452UHNltxsaaN+L9WyuMch8bMd9CqJ3zhzTPXXidwbf5mqqKCVXEuvRZUqLJSTLeWE65lQwyXsRGnXkCTA==", + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.4.tgz", + "integrity": "sha512-DAbgDXwtX+pDkAHwiGhqP3zWUGpW49B7eqmgpPtg+BKJXwdct79ut9+ifqOFPJGClGKSHXn2PTBatCnldJRUoA==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.7.3", - "@typescript-eslint/type-utils": "6.7.3", - "@typescript-eslint/utils": "6.7.3", - "@typescript-eslint/visitor-keys": "6.7.3", + "@typescript-eslint/scope-manager": "6.7.4", + "@typescript-eslint/type-utils": "6.7.4", + "@typescript-eslint/utils": "6.7.4", + "@typescript-eslint/visitor-keys": "6.7.4", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -1878,6 +1878,53 @@ } } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.4.tgz", + "integrity": "sha512-SdGqSLUPTXAXi7c3Ob7peAGVnmMoGzZ361VswK2Mqf8UOYcODiYvs8rs5ILqEdfvX1lE7wEZbLyELCW+Yrql1A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.7.4", + "@typescript-eslint/visitor-keys": "6.7.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.4.tgz", + "integrity": "sha512-o9XWK2FLW6eSS/0r/tgjAGsYasLAnOWg7hvZ/dGYSSNjCh+49k5ocPN8OmG5aZcSJ8pclSOyVKP2x03Sj+RrCA==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.4.tgz", + "integrity": "sha512-pOW37DUhlTZbvph50x5zZCkFn3xzwkGtNoJHzIM3svpiSkJzwOYr/kVBaXmf+RAQiUDs1AHEZVNPg6UJCJpwRA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.7.4", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/parser": { "version": "6.7.3", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.3.tgz", @@ -1924,13 +1971,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.3.tgz", - "integrity": "sha512-Fc68K0aTDrKIBvLnKTZ5Pf3MXK495YErrbHb1R6aTpfK5OdSFj0rVN7ib6Tx6ePrZ2gsjLqr0s98NG7l96KSQw==", + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.4.tgz", + "integrity": "sha512-n+g3zi1QzpcAdHFP9KQF+rEFxMb2KxtnJGID3teA/nxKHOVi3ylKovaqEzGBbVY2pBttU6z85gp0D00ufLzViQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.7.3", - "@typescript-eslint/utils": "6.7.3", + "@typescript-eslint/typescript-estree": "6.7.4", + "@typescript-eslint/utils": "6.7.4", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -1950,6 +1997,63 @@ } } }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.4.tgz", + "integrity": "sha512-o9XWK2FLW6eSS/0r/tgjAGsYasLAnOWg7hvZ/dGYSSNjCh+49k5ocPN8OmG5aZcSJ8pclSOyVKP2x03Sj+RrCA==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.4.tgz", + "integrity": "sha512-ty8b5qHKatlNYd9vmpHooQz3Vki3gG+3PchmtsA4TgrZBKWHNjWfkQid7K7xQogBqqc7/BhGazxMD5vr6Ha+iQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.7.4", + "@typescript-eslint/visitor-keys": "6.7.4", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.4.tgz", + "integrity": "sha512-pOW37DUhlTZbvph50x5zZCkFn3xzwkGtNoJHzIM3svpiSkJzwOYr/kVBaXmf+RAQiUDs1AHEZVNPg6UJCJpwRA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.7.4", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/types": { "version": "6.7.3", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.3.tgz", @@ -1991,17 +2095,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.3.tgz", - "integrity": "sha512-vzLkVder21GpWRrmSR9JxGZ5+ibIUSudXlW52qeKpzUEQhRSmyZiVDDj3crAth7+5tmN1ulvgKaCU2f/bPRCzg==", + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.4.tgz", + "integrity": "sha512-PRQAs+HUn85Qdk+khAxsVV+oULy3VkbH3hQ8hxLRJXWBEd7iI+GbQxH5SEUSH7kbEoTp6oT1bOwyga24ELALTA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.7.3", - "@typescript-eslint/types": "6.7.3", - "@typescript-eslint/typescript-estree": "6.7.3", + "@typescript-eslint/scope-manager": "6.7.4", + "@typescript-eslint/types": "6.7.4", + "@typescript-eslint/typescript-estree": "6.7.4", "semver": "^7.5.4" }, "engines": { @@ -2015,6 +2119,80 @@ "eslint": "^7.0.0 || ^8.0.0" } }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.4.tgz", + "integrity": "sha512-SdGqSLUPTXAXi7c3Ob7peAGVnmMoGzZ361VswK2Mqf8UOYcODiYvs8rs5ILqEdfvX1lE7wEZbLyELCW+Yrql1A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.7.4", + "@typescript-eslint/visitor-keys": "6.7.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.4.tgz", + "integrity": "sha512-o9XWK2FLW6eSS/0r/tgjAGsYasLAnOWg7hvZ/dGYSSNjCh+49k5ocPN8OmG5aZcSJ8pclSOyVKP2x03Sj+RrCA==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.4.tgz", + "integrity": "sha512-ty8b5qHKatlNYd9vmpHooQz3Vki3gG+3PchmtsA4TgrZBKWHNjWfkQid7K7xQogBqqc7/BhGazxMD5vr6Ha+iQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.7.4", + "@typescript-eslint/visitor-keys": "6.7.4", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.4.tgz", + "integrity": "sha512-pOW37DUhlTZbvph50x5zZCkFn3xzwkGtNoJHzIM3svpiSkJzwOYr/kVBaXmf+RAQiUDs1AHEZVNPg6UJCJpwRA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.7.4", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/visitor-keys": { "version": "6.7.3", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.3.tgz", @@ -8416,22 +8594,50 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.3.tgz", - "integrity": "sha512-vntq452UHNltxsaaN+L9WyuMch8bMd9CqJ3zhzTPXXidwbf5mqqKCVXEuvRZUqLJSTLeWE65lQwyXsRGnXkCTA==", + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.4.tgz", + "integrity": "sha512-DAbgDXwtX+pDkAHwiGhqP3zWUGpW49B7eqmgpPtg+BKJXwdct79ut9+ifqOFPJGClGKSHXn2PTBatCnldJRUoA==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.7.3", - "@typescript-eslint/type-utils": "6.7.3", - "@typescript-eslint/utils": "6.7.3", - "@typescript-eslint/visitor-keys": "6.7.3", + "@typescript-eslint/scope-manager": "6.7.4", + "@typescript-eslint/type-utils": "6.7.4", + "@typescript-eslint/utils": "6.7.4", + "@typescript-eslint/visitor-keys": "6.7.4", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", "natural-compare": "^1.4.0", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.4.tgz", + "integrity": "sha512-SdGqSLUPTXAXi7c3Ob7peAGVnmMoGzZ361VswK2Mqf8UOYcODiYvs8rs5ILqEdfvX1lE7wEZbLyELCW+Yrql1A==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.7.4", + "@typescript-eslint/visitor-keys": "6.7.4" + } + }, + "@typescript-eslint/types": { + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.4.tgz", + "integrity": "sha512-o9XWK2FLW6eSS/0r/tgjAGsYasLAnOWg7hvZ/dGYSSNjCh+49k5ocPN8OmG5aZcSJ8pclSOyVKP2x03Sj+RrCA==", + "dev": true + }, + "@typescript-eslint/visitor-keys": { + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.4.tgz", + "integrity": "sha512-pOW37DUhlTZbvph50x5zZCkFn3xzwkGtNoJHzIM3svpiSkJzwOYr/kVBaXmf+RAQiUDs1AHEZVNPg6UJCJpwRA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.7.4", + "eslint-visitor-keys": "^3.4.1" + } + } } }, "@typescript-eslint/parser": { @@ -8458,15 +8664,48 @@ } }, "@typescript-eslint/type-utils": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.3.tgz", - "integrity": "sha512-Fc68K0aTDrKIBvLnKTZ5Pf3MXK495YErrbHb1R6aTpfK5OdSFj0rVN7ib6Tx6ePrZ2gsjLqr0s98NG7l96KSQw==", + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.4.tgz", + "integrity": "sha512-n+g3zi1QzpcAdHFP9KQF+rEFxMb2KxtnJGID3teA/nxKHOVi3ylKovaqEzGBbVY2pBttU6z85gp0D00ufLzViQ==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "6.7.3", - "@typescript-eslint/utils": "6.7.3", + "@typescript-eslint/typescript-estree": "6.7.4", + "@typescript-eslint/utils": "6.7.4", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" + }, + "dependencies": { + "@typescript-eslint/types": { + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.4.tgz", + "integrity": "sha512-o9XWK2FLW6eSS/0r/tgjAGsYasLAnOWg7hvZ/dGYSSNjCh+49k5ocPN8OmG5aZcSJ8pclSOyVKP2x03Sj+RrCA==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.4.tgz", + "integrity": "sha512-ty8b5qHKatlNYd9vmpHooQz3Vki3gG+3PchmtsA4TgrZBKWHNjWfkQid7K7xQogBqqc7/BhGazxMD5vr6Ha+iQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.7.4", + "@typescript-eslint/visitor-keys": "6.7.4", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.4.tgz", + "integrity": "sha512-pOW37DUhlTZbvph50x5zZCkFn3xzwkGtNoJHzIM3svpiSkJzwOYr/kVBaXmf+RAQiUDs1AHEZVNPg6UJCJpwRA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.7.4", + "eslint-visitor-keys": "^3.4.1" + } + } } }, "@typescript-eslint/types": { @@ -8491,18 +8730,61 @@ } }, "@typescript-eslint/utils": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.3.tgz", - "integrity": "sha512-vzLkVder21GpWRrmSR9JxGZ5+ibIUSudXlW52qeKpzUEQhRSmyZiVDDj3crAth7+5tmN1ulvgKaCU2f/bPRCzg==", + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.4.tgz", + "integrity": "sha512-PRQAs+HUn85Qdk+khAxsVV+oULy3VkbH3hQ8hxLRJXWBEd7iI+GbQxH5SEUSH7kbEoTp6oT1bOwyga24ELALTA==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.7.3", - "@typescript-eslint/types": "6.7.3", - "@typescript-eslint/typescript-estree": "6.7.3", + "@typescript-eslint/scope-manager": "6.7.4", + "@typescript-eslint/types": "6.7.4", + "@typescript-eslint/typescript-estree": "6.7.4", "semver": "^7.5.4" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.4.tgz", + "integrity": "sha512-SdGqSLUPTXAXi7c3Ob7peAGVnmMoGzZ361VswK2Mqf8UOYcODiYvs8rs5ILqEdfvX1lE7wEZbLyELCW+Yrql1A==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.7.4", + "@typescript-eslint/visitor-keys": "6.7.4" + } + }, + "@typescript-eslint/types": { + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.4.tgz", + "integrity": "sha512-o9XWK2FLW6eSS/0r/tgjAGsYasLAnOWg7hvZ/dGYSSNjCh+49k5ocPN8OmG5aZcSJ8pclSOyVKP2x03Sj+RrCA==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.4.tgz", + "integrity": "sha512-ty8b5qHKatlNYd9vmpHooQz3Vki3gG+3PchmtsA4TgrZBKWHNjWfkQid7K7xQogBqqc7/BhGazxMD5vr6Ha+iQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.7.4", + "@typescript-eslint/visitor-keys": "6.7.4", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.4.tgz", + "integrity": "sha512-pOW37DUhlTZbvph50x5zZCkFn3xzwkGtNoJHzIM3svpiSkJzwOYr/kVBaXmf+RAQiUDs1AHEZVNPg6UJCJpwRA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.7.4", + "eslint-visitor-keys": "^3.4.1" + } + } } }, "@typescript-eslint/visitor-keys": { From 7778c65f48b5eb0aefa27b40c8fc73d810abc243 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Oct 2023 11:22:26 -0400 Subject: [PATCH 0532/1076] build(deps-dev): bump @types/node from 20.8.0 to 20.8.2 in /stake-pool/js (#5419) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.8.0 to 20.8.2. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index c08806aa..16c6d421 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1768,9 +1768,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.8.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.0.tgz", - "integrity": "sha512-LzcWltT83s1bthcvjBmiBvGJiiUe84NWRHkw+ZV6Fr41z2FbIzvc815dk2nQ3RAKMuN2fkenM/z3Xv2QzEpYxQ==" + "version": "20.8.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.2.tgz", + "integrity": "sha512-Vvycsc9FQdwhxE3y3DzeIxuEJbWGDsnrxvMADzTDF/lcdR9/K+AQIeAghTQsHtotg/q0j3WEOYS/jQgSdWue3w==" }, "node_modules/@types/node-fetch": { "version": "2.6.6", @@ -8519,9 +8519,9 @@ "dev": true }, "@types/node": { - "version": "20.8.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.0.tgz", - "integrity": "sha512-LzcWltT83s1bthcvjBmiBvGJiiUe84NWRHkw+ZV6Fr41z2FbIzvc815dk2nQ3RAKMuN2fkenM/z3Xv2QzEpYxQ==" + "version": "20.8.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.2.tgz", + "integrity": "sha512-Vvycsc9FQdwhxE3y3DzeIxuEJbWGDsnrxvMADzTDF/lcdR9/K+AQIeAghTQsHtotg/q0j3WEOYS/jQgSdWue3w==" }, "@types/node-fetch": { "version": "2.6.6", From d149ddf9a9ba993627071384438747738a6b1588 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Oct 2023 11:26:52 -0400 Subject: [PATCH 0533/1076] build(deps-dev): bump @typescript-eslint/parser from 6.7.3 to 6.7.4 in /stake-pool/js (#5418) build(deps-dev): bump @typescript-eslint/parser in /stake-pool/js Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.7.3 to 6.7.4. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.7.4/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 145 +++++++++++++++++++++++++--- 1 file changed, 131 insertions(+), 14 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 16c6d421..1def58b1 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1926,15 +1926,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.3.tgz", - "integrity": "sha512-TlutE+iep2o7R8Lf+yoer3zU6/0EAUc8QIBB3GYBc1KGz4c4TRm83xwXUZVPlZ6YCLss4r77jbu6j3sendJoiQ==", + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.4.tgz", + "integrity": "sha512-I5zVZFY+cw4IMZUeNCU7Sh2PO5O57F7Lr0uyhgCJmhN/BuTlnc55KxPonR4+EM3GBdfiCyGZye6DgMjtubQkmA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.7.3", - "@typescript-eslint/types": "6.7.3", - "@typescript-eslint/typescript-estree": "6.7.3", - "@typescript-eslint/visitor-keys": "6.7.3", + "@typescript-eslint/scope-manager": "6.7.4", + "@typescript-eslint/types": "6.7.4", + "@typescript-eslint/typescript-estree": "6.7.4", + "@typescript-eslint/visitor-keys": "6.7.4", "debug": "^4.3.4" }, "engines": { @@ -1953,6 +1953,80 @@ } } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.4.tgz", + "integrity": "sha512-SdGqSLUPTXAXi7c3Ob7peAGVnmMoGzZ361VswK2Mqf8UOYcODiYvs8rs5ILqEdfvX1lE7wEZbLyELCW+Yrql1A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.7.4", + "@typescript-eslint/visitor-keys": "6.7.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.4.tgz", + "integrity": "sha512-o9XWK2FLW6eSS/0r/tgjAGsYasLAnOWg7hvZ/dGYSSNjCh+49k5ocPN8OmG5aZcSJ8pclSOyVKP2x03Sj+RrCA==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.4.tgz", + "integrity": "sha512-ty8b5qHKatlNYd9vmpHooQz3Vki3gG+3PchmtsA4TgrZBKWHNjWfkQid7K7xQogBqqc7/BhGazxMD5vr6Ha+iQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.7.4", + "@typescript-eslint/visitor-keys": "6.7.4", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.4.tgz", + "integrity": "sha512-pOW37DUhlTZbvph50x5zZCkFn3xzwkGtNoJHzIM3svpiSkJzwOYr/kVBaXmf+RAQiUDs1AHEZVNPg6UJCJpwRA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.7.4", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "6.7.3", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.3.tgz", @@ -8641,16 +8715,59 @@ } }, "@typescript-eslint/parser": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.3.tgz", - "integrity": "sha512-TlutE+iep2o7R8Lf+yoer3zU6/0EAUc8QIBB3GYBc1KGz4c4TRm83xwXUZVPlZ6YCLss4r77jbu6j3sendJoiQ==", + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.4.tgz", + "integrity": "sha512-I5zVZFY+cw4IMZUeNCU7Sh2PO5O57F7Lr0uyhgCJmhN/BuTlnc55KxPonR4+EM3GBdfiCyGZye6DgMjtubQkmA==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "6.7.3", - "@typescript-eslint/types": "6.7.3", - "@typescript-eslint/typescript-estree": "6.7.3", - "@typescript-eslint/visitor-keys": "6.7.3", + "@typescript-eslint/scope-manager": "6.7.4", + "@typescript-eslint/types": "6.7.4", + "@typescript-eslint/typescript-estree": "6.7.4", + "@typescript-eslint/visitor-keys": "6.7.4", "debug": "^4.3.4" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.4.tgz", + "integrity": "sha512-SdGqSLUPTXAXi7c3Ob7peAGVnmMoGzZ361VswK2Mqf8UOYcODiYvs8rs5ILqEdfvX1lE7wEZbLyELCW+Yrql1A==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.7.4", + "@typescript-eslint/visitor-keys": "6.7.4" + } + }, + "@typescript-eslint/types": { + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.4.tgz", + "integrity": "sha512-o9XWK2FLW6eSS/0r/tgjAGsYasLAnOWg7hvZ/dGYSSNjCh+49k5ocPN8OmG5aZcSJ8pclSOyVKP2x03Sj+RrCA==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.4.tgz", + "integrity": "sha512-ty8b5qHKatlNYd9vmpHooQz3Vki3gG+3PchmtsA4TgrZBKWHNjWfkQid7K7xQogBqqc7/BhGazxMD5vr6Ha+iQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.7.4", + "@typescript-eslint/visitor-keys": "6.7.4", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.4.tgz", + "integrity": "sha512-pOW37DUhlTZbvph50x5zZCkFn3xzwkGtNoJHzIM3svpiSkJzwOYr/kVBaXmf+RAQiUDs1AHEZVNPg6UJCJpwRA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.7.4", + "eslint-visitor-keys": "^3.4.1" + } + } } }, "@typescript-eslint/scope-manager": { From 0f3c5d545e2dea09bfb577e785910860468f1c35 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Oct 2023 14:30:31 -0400 Subject: [PATCH 0534/1076] build(deps-dev): bump @rollup/plugin-commonjs from 25.0.4 to 25.0.5 in /stake-pool/js (#5432) build(deps-dev): bump @rollup/plugin-commonjs in /stake-pool/js Bumps [@rollup/plugin-commonjs](https://github.com/rollup/plugins/tree/HEAD/packages/commonjs) from 25.0.4 to 25.0.5. - [Changelog](https://github.com/rollup/plugins/blob/master/packages/commonjs/CHANGELOG.md) - [Commits](https://github.com/rollup/plugins/commits/HEAD/packages/commonjs) --- updated-dependencies: - dependency-name: "@rollup/plugin-commonjs" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 129 ++-------------------------- 1 file changed, 7 insertions(+), 122 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 1def58b1..a09291f2 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1346,9 +1346,9 @@ } }, "node_modules/@rollup/plugin-commonjs": { - "version": "25.0.4", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.4.tgz", - "integrity": "sha512-L92Vz9WUZXDnlQQl3EwbypJR4+DM2EbsO+/KOcEkP4Mc6Ct453EeDB2uH9lgRwj4w5yflgNpq9pHOiY8aoUXBQ==", + "version": "25.0.5", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.5.tgz", + "integrity": "sha512-xY8r/A9oisSeSuLCTfhssyDjo9Vp/eDiRLXkg1MXCcEEgEjPmLU+ZyDB20OOD0NlyDa/8SGbK5uIggF5XTx77w==", "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1", @@ -1362,7 +1362,7 @@ "node": ">=14.0.0" }, "peerDependencies": { - "rollup": "^2.68.0||^3.0.0" + "rollup": "^2.68.0||^3.0.0||^4.0.0" }, "peerDependenciesMeta": { "rollup": { @@ -2027,23 +2027,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.3.tgz", - "integrity": "sha512-wOlo0QnEou9cHO2TdkJmzF7DFGvAKEnB82PuPNHpT8ZKKaZu6Bm63ugOTn9fXNJtvuDPanBc78lGUGGytJoVzQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.7.3", - "@typescript-eslint/visitor-keys": "6.7.3" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/type-utils": { "version": "6.7.4", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.4.tgz", @@ -2128,46 +2111,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/types": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.3.tgz", - "integrity": "sha512-4g+de6roB2NFcfkZb439tigpAMnvEIg3rIjWQ+EM7IBaYt/CdJt6em9BJ4h4UpdgaBWdmx2iWsafHTrqmgIPNw==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.3.tgz", - "integrity": "sha512-YLQ3tJoS4VxLFYHTw21oe1/vIZPRqAO91z6Uv0Ss2BKm/Ag7/RVQBcXTGcXhgJMdA4U+HrKuY5gWlJlvoaKZ5g==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.7.3", - "@typescript-eslint/visitor-keys": "6.7.3", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, "node_modules/@typescript-eslint/utils": { "version": "6.7.4", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.4.tgz", @@ -2267,23 +2210,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.3.tgz", - "integrity": "sha512-HEVXkU9IB+nk9o63CeICMHxFWbHWr3E1mpilIQBe9+7L/lH97rleFLVtYsfnWB+JVMaiFnEaxvknvmIzX+CqVg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.7.3", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/abab": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", @@ -8281,9 +8207,9 @@ } }, "@rollup/plugin-commonjs": { - "version": "25.0.4", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.4.tgz", - "integrity": "sha512-L92Vz9WUZXDnlQQl3EwbypJR4+DM2EbsO+/KOcEkP4Mc6Ct453EeDB2uH9lgRwj4w5yflgNpq9pHOiY8aoUXBQ==", + "version": "25.0.5", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.5.tgz", + "integrity": "sha512-xY8r/A9oisSeSuLCTfhssyDjo9Vp/eDiRLXkg1MXCcEEgEjPmLU+ZyDB20OOD0NlyDa/8SGbK5uIggF5XTx77w==", "dev": true, "requires": { "@rollup/pluginutils": "^5.0.1", @@ -8770,16 +8696,6 @@ } } }, - "@typescript-eslint/scope-manager": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.3.tgz", - "integrity": "sha512-wOlo0QnEou9cHO2TdkJmzF7DFGvAKEnB82PuPNHpT8ZKKaZu6Bm63ugOTn9fXNJtvuDPanBc78lGUGGytJoVzQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.7.3", - "@typescript-eslint/visitor-keys": "6.7.3" - } - }, "@typescript-eslint/type-utils": { "version": "6.7.4", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.4.tgz", @@ -8825,27 +8741,6 @@ } } }, - "@typescript-eslint/types": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.3.tgz", - "integrity": "sha512-4g+de6roB2NFcfkZb439tigpAMnvEIg3rIjWQ+EM7IBaYt/CdJt6em9BJ4h4UpdgaBWdmx2iWsafHTrqmgIPNw==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.3.tgz", - "integrity": "sha512-YLQ3tJoS4VxLFYHTw21oe1/vIZPRqAO91z6Uv0Ss2BKm/Ag7/RVQBcXTGcXhgJMdA4U+HrKuY5gWlJlvoaKZ5g==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.7.3", - "@typescript-eslint/visitor-keys": "6.7.3", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, "@typescript-eslint/utils": { "version": "6.7.4", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.4.tgz", @@ -8904,16 +8799,6 @@ } } }, - "@typescript-eslint/visitor-keys": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.3.tgz", - "integrity": "sha512-HEVXkU9IB+nk9o63CeICMHxFWbHWr3E1mpilIQBe9+7L/lH97rleFLVtYsfnWB+JVMaiFnEaxvknvmIzX+CqVg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.7.3", - "eslint-visitor-keys": "^3.4.1" - } - }, "abab": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", From bcdb1ed8458e431d307770dc9ff1988ed6d086db Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Oct 2023 14:30:48 -0400 Subject: [PATCH 0535/1076] build(deps-dev): bump @rollup/plugin-alias from 5.0.0 to 5.0.1 in /stake-pool/js (#5434) build(deps-dev): bump @rollup/plugin-alias in /stake-pool/js Bumps [@rollup/plugin-alias](https://github.com/rollup/plugins/tree/HEAD/packages/alias) from 5.0.0 to 5.0.1. - [Changelog](https://github.com/rollup/plugins/blob/master/packages/alias/CHANGELOG.md) - [Commits](https://github.com/rollup/plugins/commits/url-v5.0.1/packages/alias) --- updated-dependencies: - dependency-name: "@rollup/plugin-alias" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index a09291f2..d1fbd22e 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1314,9 +1314,9 @@ } }, "node_modules/@rollup/plugin-alias": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.0.0.tgz", - "integrity": "sha512-l9hY5chSCjuFRPsnRm16twWBiSApl2uYFLsepQYwtBuAxNMQ/1dJqADld40P0Jkqm65GRTLy/AC6hnpVebtLsA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.0.1.tgz", + "integrity": "sha512-JObvbWdOHoMy9W7SU0lvGhDtWq9PllP5mjpAy+TUslZG/WzOId9u80Hsqq1vCUn9pFJ0cxpdcnAv+QzU2zFH3Q==", "dev": true, "dependencies": { "slash": "^4.0.0" @@ -1325,7 +1325,7 @@ "node": ">=14.0.0" }, "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0" + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "peerDependenciesMeta": { "rollup": { @@ -8190,9 +8190,9 @@ } }, "@rollup/plugin-alias": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.0.0.tgz", - "integrity": "sha512-l9hY5chSCjuFRPsnRm16twWBiSApl2uYFLsepQYwtBuAxNMQ/1dJqADld40P0Jkqm65GRTLy/AC6hnpVebtLsA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.0.1.tgz", + "integrity": "sha512-JObvbWdOHoMy9W7SU0lvGhDtWq9PllP5mjpAy+TUslZG/WzOId9u80Hsqq1vCUn9pFJ0cxpdcnAv+QzU2zFH3Q==", "dev": true, "requires": { "slash": "^4.0.0" From adf27d2c5cdc88dc98a0ef776e13bb288a7baa4f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Oct 2023 14:31:01 -0400 Subject: [PATCH 0536/1076] build(deps-dev): bump @rollup/plugin-json from 6.0.0 to 6.0.1 in /stake-pool/js (#5433) build(deps-dev): bump @rollup/plugin-json in /stake-pool/js Bumps [@rollup/plugin-json](https://github.com/rollup/plugins/tree/HEAD/packages/json) from 6.0.0 to 6.0.1. - [Changelog](https://github.com/rollup/plugins/blob/master/packages/json/CHANGELOG.md) - [Commits](https://github.com/rollup/plugins/commits/wasm-v6.0.1/packages/json) --- updated-dependencies: - dependency-name: "@rollup/plugin-json" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index d1fbd22e..b5743a31 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1423,9 +1423,9 @@ } }, "node_modules/@rollup/plugin-json": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.0.0.tgz", - "integrity": "sha512-i/4C5Jrdr1XUarRhVu27EEwjt4GObltD7c+MkCIpO2QIbojw8MUs+CCTqOphQi3Qtg1FLmYt+l+6YeoIf51J7w==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.0.1.tgz", + "integrity": "sha512-RgVfl5hWMkxN1h/uZj8FVESvPuBJ/uf6ly6GTj0GONnkfoBN5KC0MSz+PN2OLDgYXMhtG0mWpTrkiOjoxAIevw==", "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1" @@ -1434,7 +1434,7 @@ "node": ">=14.0.0" }, "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0" + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "peerDependenciesMeta": { "rollup": { @@ -8263,9 +8263,9 @@ } }, "@rollup/plugin-json": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.0.0.tgz", - "integrity": "sha512-i/4C5Jrdr1XUarRhVu27EEwjt4GObltD7c+MkCIpO2QIbojw8MUs+CCTqOphQi3Qtg1FLmYt+l+6YeoIf51J7w==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.0.1.tgz", + "integrity": "sha512-RgVfl5hWMkxN1h/uZj8FVESvPuBJ/uf6ly6GTj0GONnkfoBN5KC0MSz+PN2OLDgYXMhtG0mWpTrkiOjoxAIevw==", "dev": true, "requires": { "@rollup/pluginutils": "^5.0.1" From 1496766f6fcec710af42fd0b463938e62e5f810c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Oct 2023 22:27:36 -0400 Subject: [PATCH 0537/1076] build(deps): bump @solana/web3.js from 1.78.5 to 1.87.1 in /stake-pool/js (#5464) build(deps): bump @solana/web3.js in /stake-pool/js Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.78.5 to 1.87.1. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.78.5...v1.87.1) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 83 +++++++++++------------------ 1 file changed, 31 insertions(+), 52 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index b5743a31..0bc6aa41 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1224,29 +1224,26 @@ } }, "node_modules/@noble/curves": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.0.0.tgz", - "integrity": "sha512-2upgEu0iLiDVDZkNLeFV2+ht0BAVgQnEmCk6JsOch9Rp8xfkMCbvbAZlA2pBHQc73dbl+vFOXfqkf4uemdn0bw==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", "dependencies": { - "@noble/hashes": "1.3.0" + "@noble/hashes": "1.3.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, "node_modules/@noble/hashes": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.0.tgz", - "integrity": "sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ] + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", @@ -1613,12 +1610,12 @@ } }, "node_modules/@solana/web3.js": { - "version": "1.78.5", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.78.5.tgz", - "integrity": "sha512-2ZHsDNqkKdglJQrIvJ3p2DmgS3cGnary3VJyqt9C1SPrpAtLYzcElr3xyXJOznyQTU/8AMw+GoF11lFoKbicKg==", + "version": "1.87.1", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.87.1.tgz", + "integrity": "sha512-E8Y9bNlZ8TQlhOvCx1b7jG+TjA4SJLVwufmIk1+tcQctUhK5HiB1Q8ljd4yQDkFlk6OOeAlAeqvW0YntWJU94Q==", "dependencies": { "@babel/runtime": "^7.22.6", - "@noble/curves": "^1.0.0", + "@noble/curves": "^1.2.0", "@noble/hashes": "^1.3.1", "@solana/buffer-layout": "^4.0.0", "agentkeepalive": "^4.3.0", @@ -1634,17 +1631,6 @@ "superstruct": "^0.14.2" } }, - "node_modules/@solana/web3.js/node_modules/@noble/hashes": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", - "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", @@ -8130,17 +8116,17 @@ } }, "@noble/curves": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.0.0.tgz", - "integrity": "sha512-2upgEu0iLiDVDZkNLeFV2+ht0BAVgQnEmCk6JsOch9Rp8xfkMCbvbAZlA2pBHQc73dbl+vFOXfqkf4uemdn0bw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", "requires": { - "@noble/hashes": "1.3.0" + "@noble/hashes": "1.3.2" } }, "@noble/hashes": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.0.tgz", - "integrity": "sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg==" + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==" }, "@nodelib/fs.scandir": { "version": "2.1.5", @@ -8371,12 +8357,12 @@ } }, "@solana/web3.js": { - "version": "1.78.5", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.78.5.tgz", - "integrity": "sha512-2ZHsDNqkKdglJQrIvJ3p2DmgS3cGnary3VJyqt9C1SPrpAtLYzcElr3xyXJOznyQTU/8AMw+GoF11lFoKbicKg==", + "version": "1.87.1", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.87.1.tgz", + "integrity": "sha512-E8Y9bNlZ8TQlhOvCx1b7jG+TjA4SJLVwufmIk1+tcQctUhK5HiB1Q8ljd4yQDkFlk6OOeAlAeqvW0YntWJU94Q==", "requires": { "@babel/runtime": "^7.22.6", - "@noble/curves": "^1.0.0", + "@noble/curves": "^1.2.0", "@noble/hashes": "^1.3.1", "@solana/buffer-layout": "^4.0.0", "agentkeepalive": "^4.3.0", @@ -8390,13 +8376,6 @@ "node-fetch": "^2.6.12", "rpc-websockets": "^7.5.1", "superstruct": "^0.14.2" - }, - "dependencies": { - "@noble/hashes": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", - "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==" - } } }, "@tootallnate/once": { From b277b1e15422b082ee18fd62833dd4a7a3c2c245 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Oct 2023 22:28:05 -0400 Subject: [PATCH 0538/1076] build(deps-dev): bump @rollup/plugin-node-resolve from 15.2.1 to 15.2.3 in /stake-pool/js (#5465) build(deps-dev): bump @rollup/plugin-node-resolve in /stake-pool/js Bumps [@rollup/plugin-node-resolve](https://github.com/rollup/plugins/tree/HEAD/packages/node-resolve) from 15.2.1 to 15.2.3. - [Changelog](https://github.com/rollup/plugins/blob/master/packages/node-resolve/CHANGELOG.md) - [Commits](https://github.com/rollup/plugins/commits/node-resolve-v15.2.3/packages/node-resolve) --- updated-dependencies: - dependency-name: "@rollup/plugin-node-resolve" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 0bc6aa41..968c65b6 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1461,9 +1461,9 @@ } }, "node_modules/@rollup/plugin-node-resolve": { - "version": "15.2.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.1.tgz", - "integrity": "sha512-nsbUg588+GDSu8/NS8T4UAshO6xeaOfINNuXeVHcKV02LJtoRaM1SiOacClw4kws1SFiNhdLGxlbMY9ga/zs/w==", + "version": "15.2.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", + "integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==", "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1", @@ -1477,7 +1477,7 @@ "node": ">=14.0.0" }, "peerDependencies": { - "rollup": "^2.78.0||^3.0.0" + "rollup": "^2.78.0||^3.0.0||^4.0.0" }, "peerDependenciesMeta": { "rollup": { @@ -8268,9 +8268,9 @@ } }, "@rollup/plugin-node-resolve": { - "version": "15.2.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.1.tgz", - "integrity": "sha512-nsbUg588+GDSu8/NS8T4UAshO6xeaOfINNuXeVHcKV02LJtoRaM1SiOacClw4kws1SFiNhdLGxlbMY9ga/zs/w==", + "version": "15.2.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", + "integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==", "dev": true, "requires": { "@rollup/pluginutils": "^5.0.1", From ee31b56bb365e4edde86ad83af47e385c76c9562 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Oct 2023 22:29:05 -0400 Subject: [PATCH 0539/1076] build(deps-dev): bump @rollup/plugin-multi-entry from 6.0.0 to 6.0.1 in /stake-pool/js (#5446) build(deps-dev): bump @rollup/plugin-multi-entry in /stake-pool/js Bumps [@rollup/plugin-multi-entry](https://github.com/rollup/plugins/tree/HEAD/packages/multi-entry) from 6.0.0 to 6.0.1. - [Changelog](https://github.com/rollup/plugins/blob/master/packages/multi-entry/CHANGELOG.md) - [Commits](https://github.com/rollup/plugins/commits/wasm-v6.0.1/packages/multi-entry) --- updated-dependencies: - dependency-name: "@rollup/plugin-multi-entry" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 968c65b6..e50775ea 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1440,9 +1440,9 @@ } }, "node_modules/@rollup/plugin-multi-entry": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-multi-entry/-/plugin-multi-entry-6.0.0.tgz", - "integrity": "sha512-msBgVncGQwh/ahxeP/rc8MXVZNBOjoVCsBuDk6uqyFzDv/SZN7jksfAsu6DJ2w4r5PaBX3/OXOjVPeCxya2waA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-multi-entry/-/plugin-multi-entry-6.0.1.tgz", + "integrity": "sha512-AXm6toPyTSfbYZWghQGbom1Uh7dHXlrGa+HoiYNhQtDUE3Q7LqoUYdVQx9E1579QWS1uOiu+cZRSE4okO7ySgw==", "dev": true, "dependencies": { "@rollup/plugin-virtual": "^3.0.0", @@ -1452,7 +1452,7 @@ "node": ">=14.0.0" }, "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0" + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "peerDependenciesMeta": { "rollup": { @@ -8258,9 +8258,9 @@ } }, "@rollup/plugin-multi-entry": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-multi-entry/-/plugin-multi-entry-6.0.0.tgz", - "integrity": "sha512-msBgVncGQwh/ahxeP/rc8MXVZNBOjoVCsBuDk6uqyFzDv/SZN7jksfAsu6DJ2w4r5PaBX3/OXOjVPeCxya2waA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-multi-entry/-/plugin-multi-entry-6.0.1.tgz", + "integrity": "sha512-AXm6toPyTSfbYZWghQGbom1Uh7dHXlrGa+HoiYNhQtDUE3Q7LqoUYdVQx9E1579QWS1uOiu+cZRSE4okO7ySgw==", "dev": true, "requires": { "@rollup/plugin-virtual": "^3.0.0", From 3e180084b852ea3b667e0715e0871cc6a779ada8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Oct 2023 11:47:55 -0400 Subject: [PATCH 0540/1076] build(deps-dev): bump @rollup/plugin-typescript from 11.1.4 to 11.1.5 in /stake-pool/js (#5487) build(deps-dev): bump @rollup/plugin-typescript in /stake-pool/js Bumps [@rollup/plugin-typescript](https://github.com/rollup/plugins/tree/HEAD/packages/typescript) from 11.1.4 to 11.1.5. - [Changelog](https://github.com/rollup/plugins/blob/master/packages/typescript/CHANGELOG.md) - [Commits](https://github.com/rollup/plugins/commits/typescript-v11.1.5/packages/typescript) --- updated-dependencies: - dependency-name: "@rollup/plugin-typescript" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index e50775ea..9b4dc638 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1486,9 +1486,9 @@ } }, "node_modules/@rollup/plugin-typescript": { - "version": "11.1.4", - "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.4.tgz", - "integrity": "sha512-WZRh5LBVLQXdKFICUId5J3eIpmjGURaBqntfg3GSZACgeOAFS+lOSMGTwfzDkELTaZVp/lWdMVNU3UkwCUBg/Q==", + "version": "11.1.5", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.5.tgz", + "integrity": "sha512-rnMHrGBB0IUEv69Q8/JGRD/n4/n6b3nfpufUu26axhUcboUzv/twfZU8fIBbTOphRAe0v8EyxzeDpKXqGHfyDA==", "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1", @@ -1498,7 +1498,7 @@ "node": ">=14.0.0" }, "peerDependencies": { - "rollup": "^2.14.0||^3.0.0", + "rollup": "^2.14.0||^3.0.0||^4.0.0", "tslib": "*", "typescript": ">=3.7.0" }, @@ -8282,9 +8282,9 @@ } }, "@rollup/plugin-typescript": { - "version": "11.1.4", - "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.4.tgz", - "integrity": "sha512-WZRh5LBVLQXdKFICUId5J3eIpmjGURaBqntfg3GSZACgeOAFS+lOSMGTwfzDkELTaZVp/lWdMVNU3UkwCUBg/Q==", + "version": "11.1.5", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.5.tgz", + "integrity": "sha512-rnMHrGBB0IUEv69Q8/JGRD/n4/n6b3nfpufUu26axhUcboUzv/twfZU8fIBbTOphRAe0v8EyxzeDpKXqGHfyDA==", "dev": true, "requires": { "@rollup/pluginutils": "^5.0.1", From e1e49e71656de511d3f449669aaed6e8dd25b4d1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Oct 2023 13:34:53 -0400 Subject: [PATCH 0541/1076] build(deps-dev): bump @types/node from 20.8.2 to 20.8.4 in /stake-pool/js (#5486) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.8.2 to 20.8.4. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 9b4dc638..e76fd528 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1754,9 +1754,12 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.8.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.2.tgz", - "integrity": "sha512-Vvycsc9FQdwhxE3y3DzeIxuEJbWGDsnrxvMADzTDF/lcdR9/K+AQIeAghTQsHtotg/q0j3WEOYS/jQgSdWue3w==" + "version": "20.8.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.4.tgz", + "integrity": "sha512-ZVPnqU58giiCjSxjVUESDtdPk4QR5WQhhINbc9UBrKLU68MX5BF6kbQzTrkwbolyr0X8ChBpXfavr5mZFKZQ5A==", + "dependencies": { + "undici-types": "~5.25.1" + } }, "node_modules/@types/node-fetch": { "version": "2.6.6", @@ -6906,6 +6909,11 @@ "node": ">=4.2.0" } }, + "node_modules/undici-types": { + "version": "5.25.3", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz", + "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==" + }, "node_modules/universalify": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", @@ -8498,9 +8506,12 @@ "dev": true }, "@types/node": { - "version": "20.8.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.2.tgz", - "integrity": "sha512-Vvycsc9FQdwhxE3y3DzeIxuEJbWGDsnrxvMADzTDF/lcdR9/K+AQIeAghTQsHtotg/q0j3WEOYS/jQgSdWue3w==" + "version": "20.8.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.4.tgz", + "integrity": "sha512-ZVPnqU58giiCjSxjVUESDtdPk4QR5WQhhINbc9UBrKLU68MX5BF6kbQzTrkwbolyr0X8ChBpXfavr5mZFKZQ5A==", + "requires": { + "undici-types": "~5.25.1" + } }, "@types/node-fetch": { "version": "2.6.6", @@ -12213,6 +12224,11 @@ "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true }, + "undici-types": { + "version": "5.25.3", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz", + "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==" + }, "universalify": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", From eb3d7bf8c6c8aef25691c12838f818d77551d16f Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 10 Oct 2023 21:02:47 -0400 Subject: [PATCH 0542/1076] chore: Bump Solana crates to 1.16.16 (#5494) --- clients/cli/Cargo.toml | 18 +++++++++--------- program/Cargo.toml | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index d0b2c6bf..539f6b46 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -14,15 +14,15 @@ clap = "2.33.3" serde = "1.0.188" serde_derive = "1.0.130" serde_json = "1.0.107" -solana-account-decoder = "=1.16.13" -solana-clap-utils = "=1.16.13" -solana-cli-config = "=1.16.13" -solana-cli-output = "=1.16.13" -solana-client = "=1.16.13" -solana-logger = "=1.16.13" -solana-program = "=1.16.13" -solana-remote-wallet = "=1.16.13" -solana-sdk = "=1.16.13" +solana-account-decoder = "=1.16.16" +solana-clap-utils = "=1.16.16" +solana-cli-config = "=1.16.16" +solana-cli-output = "=1.16.16" +solana-client = "=1.16.16" +solana-logger = "=1.16.16" +solana-program = "=1.16.16" +solana-remote-wallet = "=1.16.16" +solana-sdk = "=1.16.16" spl-associated-token-account = { version = "=2.2", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "=0.7.0", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "=4.0", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/program/Cargo.toml b/program/Cargo.toml index fdfd2bac..d160303e 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -20,7 +20,7 @@ num-traits = "0.2" num_enum = "0.7.0" serde = "1.0.188" serde_derive = "1.0.103" -solana-program = "1.16.13" +solana-program = "1.16.16" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-pod = { version = "0.1", path = "../../libraries/pod", features = ["borsh"] } spl-token-2022 = { version = "0.9", path = "../../token/program-2022", features = [ "no-entrypoint" ] } @@ -30,9 +30,9 @@ bincode = "1.3.1" [dev-dependencies] assert_matches = "1.5.0" proptest = "1.3" -solana-program-test = "1.16.13" -solana-sdk = "1.16.13" -solana-vote-program = "1.16.13" +solana-program-test = "1.16.16" +solana-sdk = "1.16.16" +solana-vote-program = "1.16.16" spl-token = { version = "4.0", path = "../../token/program", features = [ "no-entrypoint" ] } test-case = "3.2" From d5d612d283ce2bb0a4c6b13fb63d7ed506e73667 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Oct 2023 22:55:15 -0400 Subject: [PATCH 0543/1076] build(deps-dev): bump rollup-plugin-dts from 4.2.3 to 6.1.0 in /stake-pool/js (#5485) * build(deps-dev): bump rollup-plugin-dts in /stake-pool/js Bumps [rollup-plugin-dts](https://github.com/Swatinem/rollup-plugin-dts) from 4.2.3 to 6.1.0. - [Changelog](https://github.com/Swatinem/rollup-plugin-dts/blob/master/CHANGELOG.md) - [Commits](https://github.com/Swatinem/rollup-plugin-dts/compare/v4.2.3...v6.1.0) --- updated-dependencies: - dependency-name: rollup-plugin-dts dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Bump rollup and plugin-terser * Fixup rollup file --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/js-legacy/package-lock.json | 439 ++++++++++++------ clients/js-legacy/package.json | 6 +- .../{rollup.config.js => rollup.config.mjs} | 2 +- 3 files changed, 292 insertions(+), 155 deletions(-) rename clients/js-legacy/{rollup.config.js => rollup.config.mjs} (98%) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index e76fd528..3cb06eaf 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -22,6 +22,7 @@ "@rollup/plugin-json": "^6.0.0", "@rollup/plugin-multi-entry": "^6.0.0", "@rollup/plugin-node-resolve": "^15.0.2", + "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-typescript": "^11.1.0", "@types/bn.js": "^5.1.0", "@types/jest": "^27.4.0", @@ -36,10 +37,9 @@ "jest": "^27.5.1", "prettier": "^3.0.0", "rimraf": "^5.0.0", - "rollup": "^2.66.1", - "rollup-plugin-dts": "^4.2.3", + "rollup": "^3.0.0", + "rollup-plugin-dts": "^6.1.0", "rollup-plugin-node-polyfills": "^0.2.1", - "rollup-plugin-terser": "^7.0.2", "ts-jest": "^27.1.3", "typescript": "^4.5.4" } @@ -66,17 +66,89 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", - "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dev": true, "dependencies": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/compat-data": { "version": "7.17.0", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.0.tgz", @@ -290,9 +362,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true, "engines": { "node": ">=6.9.0" @@ -322,13 +394,13 @@ } }, "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -1485,6 +1557,37 @@ } } }, + "node_modules/@rollup/plugin-terser": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", + "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", + "dev": true, + "dependencies": { + "serialize-javascript": "^6.0.1", + "smob": "^1.0.0", + "terser": "^5.17.4" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-terser/node_modules/serialize-javascript": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", + "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, "node_modules/@rollup/plugin-typescript": { "version": "11.1.5", "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.5.tgz", @@ -1512,15 +1615,15 @@ } }, "node_modules/@rollup/plugin-virtual": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-virtual/-/plugin-virtual-3.0.1.tgz", - "integrity": "sha512-fK8O0IL5+q+GrsMLuACVNk2x21g3yaw+sG2qn16SnUd3IlBsQyvWxLMGHmCmXRMecPjGRSZ/1LmZB4rjQm68og==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-virtual/-/plugin-virtual-3.0.2.tgz", + "integrity": "sha512-10monEYsBp3scM4/ND4LNH5Rxvh3e/cVeL3jWTgZ2SrQ+BmUoQcopVQvnaMcOnykb1VkxUFuDAN+0FnpTFRy2A==", "dev": true, "engines": { "node": ">=14.0.0" }, "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0" + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "peerDependenciesMeta": { "rollup": { @@ -1529,9 +1632,9 @@ } }, "node_modules/@rollup/pluginutils": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", - "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.5.tgz", + "integrity": "sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==", "dev": true, "dependencies": { "@types/estree": "^1.0.0", @@ -1542,7 +1645,7 @@ "node": ">=14.0.0" }, "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0" + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "peerDependenciesMeta": { "rollup": { @@ -6144,49 +6247,56 @@ } }, "node_modules/rollup": { - "version": "2.79.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", - "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "version": "3.29.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", + "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", "dev": true, "bin": { "rollup": "dist/bin/rollup" }, "engines": { - "node": ">=10.0.0" + "node": ">=14.18.0", + "npm": ">=8.0.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "node_modules/rollup-plugin-dts": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-4.2.3.tgz", - "integrity": "sha512-jlcpItqM2efqfIiKzDB/IKOS9E9fDvbkJSGw5GtK/PqPGS9eC3R3JKyw2VvpTktZA+TNgJRMu1NTv244aTUzzQ==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-6.1.0.tgz", + "integrity": "sha512-ijSCPICkRMDKDLBK9torss07+8dl9UpY9z1N/zTeA1cIqdzMlpkV3MOOC7zukyvQfDyxa1s3Dl2+DeiP/G6DOw==", "dev": true, "dependencies": { - "magic-string": "^0.26.6" + "magic-string": "^0.30.4" }, "engines": { - "node": ">=v12.22.12" + "node": ">=16" }, "funding": { "url": "https://github.com/sponsors/Swatinem" }, "optionalDependencies": { - "@babel/code-frame": "^7.18.6" + "@babel/code-frame": "^7.22.13" }, "peerDependencies": { - "rollup": "^2.55", - "typescript": "^4.1" + "rollup": "^3.29.4 || ^4", + "typescript": "^4.5 || ^5.0" } }, + "node_modules/rollup-plugin-dts/node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, "node_modules/rollup-plugin-dts/node_modules/magic-string": { - "version": "0.26.7", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.7.tgz", - "integrity": "sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow==", + "version": "0.30.4", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.4.tgz", + "integrity": "sha512-Q/TKtsC5BPm0kGqgBIF9oXAs/xEf2vRKiIB4wCRQTJOQIByZ1d+NnUOotvJOvNpi5RNIgVOMC3pOuaP1ZTDlVg==", "dev": true, "dependencies": { - "sourcemap-codec": "^1.4.8" + "@jridgewell/sourcemap-codec": "^1.4.15" }, "engines": { "node": ">=12" @@ -6219,35 +6329,6 @@ "rollup-plugin-inject": "^3.0.0" } }, - "node_modules/rollup-plugin-terser": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", - "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.10.4", - "jest-worker": "^26.2.1", - "serialize-javascript": "^4.0.0", - "terser": "^5.0.0" - }, - "peerDependencies": { - "rollup": "^2.0.0" - } - }, - "node_modules/rollup-plugin-terser/node_modules/jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "dev": true, - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, "node_modules/rollup-pluginutils": { "version": "2.8.2", "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", @@ -6392,15 +6473,6 @@ "node": ">=10" } }, - "node_modules/serialize-javascript": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", - "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -6443,6 +6515,12 @@ "node": ">=8" } }, + "node_modules/smob": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/smob/-/smob-1.4.1.tgz", + "integrity": "sha512-9LK+E7Hv5R9u4g4C3p+jjLstaLe11MDsL21UpYaCNmapvMkYhqCV4A/f/3gyH8QjMyh6l68q9xC85vihY9ahMQ==", + "dev": true + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -6673,13 +6751,13 @@ } }, "node_modules/terser": { - "version": "5.17.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.1.tgz", - "integrity": "sha512-hVl35zClmpisy6oaoKALOpS0rDYLxRFLHhRuDlEGTKey9qHjS1w9GMORjuwIMt70Wan4lwsLYyWDVnWgF+KUEw==", + "version": "5.21.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.21.0.tgz", + "integrity": "sha512-WtnFKrxu9kaoXuiZFSGrcAvvBqAdmKx0SFNmVNYdJamMu9yyN3I/QF0FbH4QcqJQ+y1CJnzxGIKH0cSj+FGYRw==", "dev": true, "dependencies": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, @@ -7244,12 +7322,71 @@ } }, "@babel/code-frame": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", - "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dev": true, "requires": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "@babel/compat-data": { @@ -7416,9 +7553,9 @@ } }, "@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true }, "@babel/helper-validator-option": { @@ -7439,13 +7576,13 @@ } }, "@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "dependencies": { @@ -8289,6 +8426,28 @@ "resolve": "^1.22.1" } }, + "@rollup/plugin-terser": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", + "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", + "dev": true, + "requires": { + "serialize-javascript": "^6.0.1", + "smob": "^1.0.0", + "terser": "^5.17.4" + }, + "dependencies": { + "serialize-javascript": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", + "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + } + } + }, "@rollup/plugin-typescript": { "version": "11.1.5", "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.5.tgz", @@ -8300,16 +8459,16 @@ } }, "@rollup/plugin-virtual": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-virtual/-/plugin-virtual-3.0.1.tgz", - "integrity": "sha512-fK8O0IL5+q+GrsMLuACVNk2x21g3yaw+sG2qn16SnUd3IlBsQyvWxLMGHmCmXRMecPjGRSZ/1LmZB4rjQm68og==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-virtual/-/plugin-virtual-3.0.2.tgz", + "integrity": "sha512-10monEYsBp3scM4/ND4LNH5Rxvh3e/cVeL3jWTgZ2SrQ+BmUoQcopVQvnaMcOnykb1VkxUFuDAN+0FnpTFRy2A==", "dev": true, "requires": {} }, "@rollup/pluginutils": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", - "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.5.tgz", + "integrity": "sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==", "dev": true, "requires": { "@types/estree": "^1.0.0", @@ -11688,31 +11847,37 @@ } }, "rollup": { - "version": "2.79.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", - "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "version": "3.29.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", + "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", "dev": true, "requires": { "fsevents": "~2.3.2" } }, "rollup-plugin-dts": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-4.2.3.tgz", - "integrity": "sha512-jlcpItqM2efqfIiKzDB/IKOS9E9fDvbkJSGw5GtK/PqPGS9eC3R3JKyw2VvpTktZA+TNgJRMu1NTv244aTUzzQ==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-6.1.0.tgz", + "integrity": "sha512-ijSCPICkRMDKDLBK9torss07+8dl9UpY9z1N/zTeA1cIqdzMlpkV3MOOC7zukyvQfDyxa1s3Dl2+DeiP/G6DOw==", "dev": true, "requires": { - "@babel/code-frame": "^7.18.6", - "magic-string": "^0.26.6" + "@babel/code-frame": "^7.22.13", + "magic-string": "^0.30.4" }, "dependencies": { + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, "magic-string": { - "version": "0.26.7", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.7.tgz", - "integrity": "sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow==", + "version": "0.30.4", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.4.tgz", + "integrity": "sha512-Q/TKtsC5BPm0kGqgBIF9oXAs/xEf2vRKiIB4wCRQTJOQIByZ1d+NnUOotvJOvNpi5RNIgVOMC3pOuaP1ZTDlVg==", "dev": true, "requires": { - "sourcemap-codec": "^1.4.8" + "@jridgewell/sourcemap-codec": "^1.4.15" } } } @@ -11745,31 +11910,6 @@ "rollup-plugin-inject": "^3.0.0" } }, - "rollup-plugin-terser": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", - "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "jest-worker": "^26.2.1", - "serialize-javascript": "^4.0.0", - "terser": "^5.0.0" - }, - "dependencies": { - "jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "dev": true, - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - } - } - } - }, "rollup-pluginutils": { "version": "2.8.2", "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", @@ -11855,15 +11995,6 @@ "lru-cache": "^6.0.0" } }, - "serialize-javascript": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", - "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -11897,6 +12028,12 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, + "smob": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/smob/-/smob-1.4.1.tgz", + "integrity": "sha512-9LK+E7Hv5R9u4g4C3p+jjLstaLe11MDsL21UpYaCNmapvMkYhqCV4A/f/3gyH8QjMyh6l68q9xC85vihY9ahMQ==", + "dev": true + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -12067,13 +12204,13 @@ } }, "terser": { - "version": "5.17.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.1.tgz", - "integrity": "sha512-hVl35zClmpisy6oaoKALOpS0rDYLxRFLHhRuDlEGTKey9qHjS1w9GMORjuwIMt70Wan4lwsLYyWDVnWgF+KUEw==", + "version": "5.21.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.21.0.tgz", + "integrity": "sha512-WtnFKrxu9kaoXuiZFSGrcAvvBqAdmKx0SFNmVNYdJamMu9yyN3I/QF0FbH4QcqJQ+y1CJnzxGIKH0cSj+FGYRw==", "dev": true, "requires": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", "commander": "^2.20.0", "source-map-support": "~0.5.20" } diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 61d8bcad..4059a1b7 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -57,6 +57,7 @@ "@rollup/plugin-json": "^6.0.0", "@rollup/plugin-multi-entry": "^6.0.0", "@rollup/plugin-node-resolve": "^15.0.2", + "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-typescript": "^11.1.0", "@types/bn.js": "^5.1.0", "@types/jest": "^27.4.0", @@ -71,10 +72,9 @@ "jest": "^27.5.1", "prettier": "^3.0.0", "rimraf": "^5.0.0", - "rollup": "^2.66.1", - "rollup-plugin-dts": "^4.2.3", + "rollup": "^3.0.0", + "rollup-plugin-dts": "^6.1.0", "rollup-plugin-node-polyfills": "^0.2.1", - "rollup-plugin-terser": "^7.0.2", "ts-jest": "^27.1.3", "typescript": "^4.5.4" }, diff --git a/clients/js-legacy/rollup.config.js b/clients/js-legacy/rollup.config.mjs similarity index 98% rename from clients/js-legacy/rollup.config.js rename to clients/js-legacy/rollup.config.mjs index eb4aaccb..1742dcd1 100644 --- a/clients/js-legacy/rollup.config.js +++ b/clients/js-legacy/rollup.config.mjs @@ -2,7 +2,7 @@ import typescript from '@rollup/plugin-typescript'; import commonjs from '@rollup/plugin-commonjs'; import json from '@rollup/plugin-json'; import nodeResolve from '@rollup/plugin-node-resolve'; -import { terser } from 'rollup-plugin-terser'; +import terser from '@rollup/plugin-terser'; const extensions = ['.js', '.ts']; From 46457939f37a709763bbae632ff810963ea10282 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Oct 2023 14:53:49 -0400 Subject: [PATCH 0544/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.7.4 to 6.7.5 in /stake-pool/js (#5507) build(deps-dev): bump @typescript-eslint/eslint-plugin in /stake-pool/js Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.7.4 to 6.7.5. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.7.5/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 385 ++++++++-------------------- 1 file changed, 109 insertions(+), 276 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 3cb06eaf..d5803e5d 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1936,16 +1936,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.4.tgz", - "integrity": "sha512-DAbgDXwtX+pDkAHwiGhqP3zWUGpW49B7eqmgpPtg+BKJXwdct79ut9+ifqOFPJGClGKSHXn2PTBatCnldJRUoA==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.5.tgz", + "integrity": "sha512-JhtAwTRhOUcP96D0Y6KYnwig/MRQbOoLGXTON2+LlyB/N35SP9j1boai2zzwXb7ypKELXMx3DVk9UTaEq1vHEw==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.7.4", - "@typescript-eslint/type-utils": "6.7.4", - "@typescript-eslint/utils": "6.7.4", - "@typescript-eslint/visitor-keys": "6.7.4", + "@typescript-eslint/scope-manager": "6.7.5", + "@typescript-eslint/type-utils": "6.7.5", + "@typescript-eslint/utils": "6.7.5", + "@typescript-eslint/visitor-keys": "6.7.5", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -1970,53 +1970,6 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.4.tgz", - "integrity": "sha512-SdGqSLUPTXAXi7c3Ob7peAGVnmMoGzZ361VswK2Mqf8UOYcODiYvs8rs5ILqEdfvX1lE7wEZbLyELCW+Yrql1A==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.7.4", - "@typescript-eslint/visitor-keys": "6.7.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.4.tgz", - "integrity": "sha512-o9XWK2FLW6eSS/0r/tgjAGsYasLAnOWg7hvZ/dGYSSNjCh+49k5ocPN8OmG5aZcSJ8pclSOyVKP2x03Sj+RrCA==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.4.tgz", - "integrity": "sha512-pOW37DUhlTZbvph50x5zZCkFn3xzwkGtNoJHzIM3svpiSkJzwOYr/kVBaXmf+RAQiUDs1AHEZVNPg6UJCJpwRA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.7.4", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/parser": { "version": "6.7.4", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.4.tgz", @@ -2119,14 +2072,31 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.5.tgz", + "integrity": "sha512-GAlk3eQIwWOJeb9F7MKQ6Jbah/vx1zETSDw8likab/eFcqkjSD7BI75SDAeC5N2L0MmConMoPvTsmkrg71+B1A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.7.5", + "@typescript-eslint/visitor-keys": "6.7.5" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.4.tgz", - "integrity": "sha512-n+g3zi1QzpcAdHFP9KQF+rEFxMb2KxtnJGID3teA/nxKHOVi3ylKovaqEzGBbVY2pBttU6z85gp0D00ufLzViQ==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.5.tgz", + "integrity": "sha512-Gs0qos5wqxnQrvpYv+pf3XfcRXW6jiAn9zE/K+DlmYf6FcpxeNYN0AIETaPR7rHO4K2UY+D0CIbDP9Ut0U4m1g==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.7.4", - "@typescript-eslint/utils": "6.7.4", + "@typescript-eslint/typescript-estree": "6.7.5", + "@typescript-eslint/utils": "6.7.5", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -2146,10 +2116,10 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.4.tgz", - "integrity": "sha512-o9XWK2FLW6eSS/0r/tgjAGsYasLAnOWg7hvZ/dGYSSNjCh+49k5ocPN8OmG5aZcSJ8pclSOyVKP2x03Sj+RrCA==", + "node_modules/@typescript-eslint/types": { + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.5.tgz", + "integrity": "sha512-WboQBlOXtdj1tDFPyIthpKrUb+kZf2VroLZhxKa/VlwLlLyqv/PwUNgL30BlTVZV1Wu4Asu2mMYPqarSO4L5ZQ==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -2159,14 +2129,14 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.4.tgz", - "integrity": "sha512-ty8b5qHKatlNYd9vmpHooQz3Vki3gG+3PchmtsA4TgrZBKWHNjWfkQid7K7xQogBqqc7/BhGazxMD5vr6Ha+iQ==", + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.5.tgz", + "integrity": "sha512-NhJiJ4KdtwBIxrKl0BqG1Ur+uw7FiOnOThcYx9DpOGJ/Abc9z2xNzLeirCG02Ig3vkvrc2qFLmYSSsaITbKjlg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.7.4", - "@typescript-eslint/visitor-keys": "6.7.4", + "@typescript-eslint/types": "6.7.5", + "@typescript-eslint/visitor-keys": "6.7.5", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2186,35 +2156,18 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.4.tgz", - "integrity": "sha512-pOW37DUhlTZbvph50x5zZCkFn3xzwkGtNoJHzIM3svpiSkJzwOYr/kVBaXmf+RAQiUDs1AHEZVNPg6UJCJpwRA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.7.4", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/utils": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.4.tgz", - "integrity": "sha512-PRQAs+HUn85Qdk+khAxsVV+oULy3VkbH3hQ8hxLRJXWBEd7iI+GbQxH5SEUSH7kbEoTp6oT1bOwyga24ELALTA==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.5.tgz", + "integrity": "sha512-pfRRrH20thJbzPPlPc4j0UNGvH1PjPlhlCMq4Yx7EGjV7lvEeGX0U6MJYe8+SyFutWgSHsdbJ3BXzZccYggezA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.7.4", - "@typescript-eslint/types": "6.7.4", - "@typescript-eslint/typescript-estree": "6.7.4", + "@typescript-eslint/scope-manager": "6.7.5", + "@typescript-eslint/types": "6.7.5", + "@typescript-eslint/typescript-estree": "6.7.5", "semver": "^7.5.4" }, "engines": { @@ -2228,70 +2181,13 @@ "eslint": "^7.0.0 || ^8.0.0" } }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.4.tgz", - "integrity": "sha512-SdGqSLUPTXAXi7c3Ob7peAGVnmMoGzZ361VswK2Mqf8UOYcODiYvs8rs5ILqEdfvX1lE7wEZbLyELCW+Yrql1A==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.7.4", - "@typescript-eslint/visitor-keys": "6.7.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.4.tgz", - "integrity": "sha512-o9XWK2FLW6eSS/0r/tgjAGsYasLAnOWg7hvZ/dGYSSNjCh+49k5ocPN8OmG5aZcSJ8pclSOyVKP2x03Sj+RrCA==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.4.tgz", - "integrity": "sha512-ty8b5qHKatlNYd9vmpHooQz3Vki3gG+3PchmtsA4TgrZBKWHNjWfkQid7K7xQogBqqc7/BhGazxMD5vr6Ha+iQ==", + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.5.tgz", + "integrity": "sha512-3MaWdDZtLlsexZzDSdQWsFQ9l9nL8B80Z4fImSpyllFC/KLqWQRdEcB+gGGO+N3Q2uL40EsG66wZLsohPxNXvg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.7.4", - "@typescript-eslint/visitor-keys": "6.7.4", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.4.tgz", - "integrity": "sha512-pOW37DUhlTZbvph50x5zZCkFn3xzwkGtNoJHzIM3svpiSkJzwOYr/kVBaXmf+RAQiUDs1AHEZVNPg6UJCJpwRA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.7.4", + "@typescript-eslint/types": "6.7.5", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -8743,50 +8639,22 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.4.tgz", - "integrity": "sha512-DAbgDXwtX+pDkAHwiGhqP3zWUGpW49B7eqmgpPtg+BKJXwdct79ut9+ifqOFPJGClGKSHXn2PTBatCnldJRUoA==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.5.tgz", + "integrity": "sha512-JhtAwTRhOUcP96D0Y6KYnwig/MRQbOoLGXTON2+LlyB/N35SP9j1boai2zzwXb7ypKELXMx3DVk9UTaEq1vHEw==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.7.4", - "@typescript-eslint/type-utils": "6.7.4", - "@typescript-eslint/utils": "6.7.4", - "@typescript-eslint/visitor-keys": "6.7.4", + "@typescript-eslint/scope-manager": "6.7.5", + "@typescript-eslint/type-utils": "6.7.5", + "@typescript-eslint/utils": "6.7.5", + "@typescript-eslint/visitor-keys": "6.7.5", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", "natural-compare": "^1.4.0", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.4.tgz", - "integrity": "sha512-SdGqSLUPTXAXi7c3Ob7peAGVnmMoGzZ361VswK2Mqf8UOYcODiYvs8rs5ILqEdfvX1lE7wEZbLyELCW+Yrql1A==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.7.4", - "@typescript-eslint/visitor-keys": "6.7.4" - } - }, - "@typescript-eslint/types": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.4.tgz", - "integrity": "sha512-o9XWK2FLW6eSS/0r/tgjAGsYasLAnOWg7hvZ/dGYSSNjCh+49k5ocPN8OmG5aZcSJ8pclSOyVKP2x03Sj+RrCA==", - "dev": true - }, - "@typescript-eslint/visitor-keys": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.4.tgz", - "integrity": "sha512-pOW37DUhlTZbvph50x5zZCkFn3xzwkGtNoJHzIM3svpiSkJzwOYr/kVBaXmf+RAQiUDs1AHEZVNPg6UJCJpwRA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.7.4", - "eslint-visitor-keys": "^3.4.1" - } - } } }, "@typescript-eslint/parser": { @@ -8845,107 +8713,72 @@ } } }, + "@typescript-eslint/scope-manager": { + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.5.tgz", + "integrity": "sha512-GAlk3eQIwWOJeb9F7MKQ6Jbah/vx1zETSDw8likab/eFcqkjSD7BI75SDAeC5N2L0MmConMoPvTsmkrg71+B1A==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.7.5", + "@typescript-eslint/visitor-keys": "6.7.5" + } + }, "@typescript-eslint/type-utils": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.4.tgz", - "integrity": "sha512-n+g3zi1QzpcAdHFP9KQF+rEFxMb2KxtnJGID3teA/nxKHOVi3ylKovaqEzGBbVY2pBttU6z85gp0D00ufLzViQ==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.5.tgz", + "integrity": "sha512-Gs0qos5wqxnQrvpYv+pf3XfcRXW6jiAn9zE/K+DlmYf6FcpxeNYN0AIETaPR7rHO4K2UY+D0CIbDP9Ut0U4m1g==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "6.7.4", - "@typescript-eslint/utils": "6.7.4", + "@typescript-eslint/typescript-estree": "6.7.5", + "@typescript-eslint/utils": "6.7.5", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" - }, - "dependencies": { - "@typescript-eslint/types": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.4.tgz", - "integrity": "sha512-o9XWK2FLW6eSS/0r/tgjAGsYasLAnOWg7hvZ/dGYSSNjCh+49k5ocPN8OmG5aZcSJ8pclSOyVKP2x03Sj+RrCA==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.4.tgz", - "integrity": "sha512-ty8b5qHKatlNYd9vmpHooQz3Vki3gG+3PchmtsA4TgrZBKWHNjWfkQid7K7xQogBqqc7/BhGazxMD5vr6Ha+iQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.7.4", - "@typescript-eslint/visitor-keys": "6.7.4", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.4.tgz", - "integrity": "sha512-pOW37DUhlTZbvph50x5zZCkFn3xzwkGtNoJHzIM3svpiSkJzwOYr/kVBaXmf+RAQiUDs1AHEZVNPg6UJCJpwRA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.7.4", - "eslint-visitor-keys": "^3.4.1" - } - } + } + }, + "@typescript-eslint/types": { + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.5.tgz", + "integrity": "sha512-WboQBlOXtdj1tDFPyIthpKrUb+kZf2VroLZhxKa/VlwLlLyqv/PwUNgL30BlTVZV1Wu4Asu2mMYPqarSO4L5ZQ==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.5.tgz", + "integrity": "sha512-NhJiJ4KdtwBIxrKl0BqG1Ur+uw7FiOnOThcYx9DpOGJ/Abc9z2xNzLeirCG02Ig3vkvrc2qFLmYSSsaITbKjlg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.7.5", + "@typescript-eslint/visitor-keys": "6.7.5", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" } }, "@typescript-eslint/utils": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.4.tgz", - "integrity": "sha512-PRQAs+HUn85Qdk+khAxsVV+oULy3VkbH3hQ8hxLRJXWBEd7iI+GbQxH5SEUSH7kbEoTp6oT1bOwyga24ELALTA==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.5.tgz", + "integrity": "sha512-pfRRrH20thJbzPPlPc4j0UNGvH1PjPlhlCMq4Yx7EGjV7lvEeGX0U6MJYe8+SyFutWgSHsdbJ3BXzZccYggezA==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.7.4", - "@typescript-eslint/types": "6.7.4", - "@typescript-eslint/typescript-estree": "6.7.4", + "@typescript-eslint/scope-manager": "6.7.5", + "@typescript-eslint/types": "6.7.5", + "@typescript-eslint/typescript-estree": "6.7.5", "semver": "^7.5.4" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.4.tgz", - "integrity": "sha512-SdGqSLUPTXAXi7c3Ob7peAGVnmMoGzZ361VswK2Mqf8UOYcODiYvs8rs5ILqEdfvX1lE7wEZbLyELCW+Yrql1A==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.7.4", - "@typescript-eslint/visitor-keys": "6.7.4" - } - }, - "@typescript-eslint/types": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.4.tgz", - "integrity": "sha512-o9XWK2FLW6eSS/0r/tgjAGsYasLAnOWg7hvZ/dGYSSNjCh+49k5ocPN8OmG5aZcSJ8pclSOyVKP2x03Sj+RrCA==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.4.tgz", - "integrity": "sha512-ty8b5qHKatlNYd9vmpHooQz3Vki3gG+3PchmtsA4TgrZBKWHNjWfkQid7K7xQogBqqc7/BhGazxMD5vr6Ha+iQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.7.4", - "@typescript-eslint/visitor-keys": "6.7.4", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.4.tgz", - "integrity": "sha512-pOW37DUhlTZbvph50x5zZCkFn3xzwkGtNoJHzIM3svpiSkJzwOYr/kVBaXmf+RAQiUDs1AHEZVNPg6UJCJpwRA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.7.4", - "eslint-visitor-keys": "^3.4.1" - } - } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.5.tgz", + "integrity": "sha512-3MaWdDZtLlsexZzDSdQWsFQ9l9nL8B80Z4fImSpyllFC/KLqWQRdEcB+gGGO+N3Q2uL40EsG66wZLsohPxNXvg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.7.5", + "eslint-visitor-keys": "^3.4.1" } }, "abab": { From a1ecd327657f03c5f5333b63691318d550040a89 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Oct 2023 15:33:24 -0400 Subject: [PATCH 0545/1076] build(deps-dev): bump rollup from 3.29.4 to 4.0.2 in /stake-pool/js (#5505) Bumps [rollup](https://github.com/rollup/rollup) from 3.29.4 to 4.0.2. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v3.29.4...v4.0.2) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 284 +++++++++++++++++++++++++++- clients/js-legacy/package.json | 2 +- 2 files changed, 275 insertions(+), 11 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index d5803e5d..16fc5fcf 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -37,7 +37,7 @@ "jest": "^27.5.1", "prettier": "^3.0.0", "rimraf": "^5.0.0", - "rollup": "^3.0.0", + "rollup": "^4.0.2", "rollup-plugin-dts": "^6.1.0", "rollup-plugin-node-polyfills": "^0.2.1", "ts-jest": "^27.1.3", @@ -1653,6 +1653,162 @@ } } }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.0.2.tgz", + "integrity": "sha512-xDvk1pT4vaPU2BOLy0MqHMdYZyntqpaBf8RhBiezlqG9OjY8F50TyctHo8znigYKd+QCFhCmlmXHOL/LoaOl3w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.0.2.tgz", + "integrity": "sha512-lqCglytY3E6raze27DD9VQJWohbwCxzqs9aSHcj5X/8hJpzZfNdbsr4Ja9Hqp6iPyF53+5PtPx0pKRlkSvlHZg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.0.2.tgz", + "integrity": "sha512-nkBKItS6E6CCzvRwgiKad+j+1ibmL7SIInj7oqMWmdkCjiSX6VeVZw2mLlRKIUL+JjsBgpATTfo7BiAXc1v0jA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.0.2.tgz", + "integrity": "sha512-vX2C8xvWPIbpEgQht95+dY6BReKAvtDgPDGi0XN0kWJKkm4WdNmq5dnwscv/zxvi+n6jUTBhs6GtpkkWT4q8Gg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.0.2.tgz", + "integrity": "sha512-DVFIfcHOjgmeHOAqji4xNz2wczt1Bmzy9MwBZKBa83SjBVO/i38VHDR+9ixo8QpBOiEagmNw12DucG+v55tCrg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.0.2.tgz", + "integrity": "sha512-GCK/a9ItUxPI0V5hQEJjH4JtOJO90GF2Hja7TO+EZ8rmkGvEi8/ZDMhXmcuDpQT7/PWrTT9RvnG8snMd5SrhBQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.0.2.tgz", + "integrity": "sha512-cLuBp7rOjIB1R2j/VazjCmHC7liWUur2e9mFflLJBAWCkrZ+X0+QwHLvOQakIwDymungzAKv6W9kHZnTp/Mqrg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.0.2.tgz", + "integrity": "sha512-Zqw4iVnJr2naoyQus0yLy7sLtisCQcpdMKUCeXPBjkJtpiflRime/TMojbnl8O3oxUAj92mxr+t7im/RbgA20w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.0.2.tgz", + "integrity": "sha512-jJRU9TyUD/iMqjf8aLAp7XiN3pIj5v6Qcu+cdzBfVTKDD0Fvua4oUoK8eVJ9ZuKBEQKt3WdlcwJXFkpmMLk6kg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.0.2.tgz", + "integrity": "sha512-ZkS2NixCxHKC4zbOnw64ztEGGDVIYP6nKkGBfOAxEPW71Sji9v8z3yaHNuae/JHPwXA+14oDefnOuVfxl59SmQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.0.2.tgz", + "integrity": "sha512-3SKjj+tvnZ0oZq2BKB+fI+DqYI83VrRzk7eed8tJkxeZ4zxJZcLSE8YDQLYGq1tZAnAX+H076RHHB4gTZXsQzw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.0.2.tgz", + "integrity": "sha512-MBdJIOxRauKkry7t2q+rTHa3aWjVez2eioWg+etRVS3dE4tChhmt5oqZYr48R6bPmcwEhxQr96gVRfeQrLbqng==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@sinonjs/commons": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", @@ -6143,18 +6299,30 @@ } }, "node_modules/rollup": { - "version": "3.29.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", - "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.0.2.tgz", + "integrity": "sha512-MCScu4usMPCeVFaiLcgMDaBQeYi1z6vpWxz0r0hq0Hv77Y2YuOTZldkuNJ54BdYBH3e+nkrk6j0Rre/NLDBYzg==", "dev": true, "bin": { "rollup": "dist/bin/rollup" }, "engines": { - "node": ">=14.18.0", + "node": ">=18.0.0", "npm": ">=8.0.0" }, "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.0.2", + "@rollup/rollup-android-arm64": "4.0.2", + "@rollup/rollup-darwin-arm64": "4.0.2", + "@rollup/rollup-darwin-x64": "4.0.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.0.2", + "@rollup/rollup-linux-arm64-gnu": "4.0.2", + "@rollup/rollup-linux-arm64-musl": "4.0.2", + "@rollup/rollup-linux-x64-gnu": "4.0.2", + "@rollup/rollup-linux-x64-musl": "4.0.2", + "@rollup/rollup-win32-arm64-msvc": "4.0.2", + "@rollup/rollup-win32-ia32-msvc": "4.0.2", + "@rollup/rollup-win32-x64-msvc": "4.0.2", "fsevents": "~2.3.2" } }, @@ -8372,6 +8540,90 @@ "picomatch": "^2.3.1" } }, + "@rollup/rollup-android-arm-eabi": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.0.2.tgz", + "integrity": "sha512-xDvk1pT4vaPU2BOLy0MqHMdYZyntqpaBf8RhBiezlqG9OjY8F50TyctHo8znigYKd+QCFhCmlmXHOL/LoaOl3w==", + "dev": true, + "optional": true + }, + "@rollup/rollup-android-arm64": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.0.2.tgz", + "integrity": "sha512-lqCglytY3E6raze27DD9VQJWohbwCxzqs9aSHcj5X/8hJpzZfNdbsr4Ja9Hqp6iPyF53+5PtPx0pKRlkSvlHZg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-darwin-arm64": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.0.2.tgz", + "integrity": "sha512-nkBKItS6E6CCzvRwgiKad+j+1ibmL7SIInj7oqMWmdkCjiSX6VeVZw2mLlRKIUL+JjsBgpATTfo7BiAXc1v0jA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-darwin-x64": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.0.2.tgz", + "integrity": "sha512-vX2C8xvWPIbpEgQht95+dY6BReKAvtDgPDGi0XN0kWJKkm4WdNmq5dnwscv/zxvi+n6jUTBhs6GtpkkWT4q8Gg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.0.2.tgz", + "integrity": "sha512-DVFIfcHOjgmeHOAqji4xNz2wczt1Bmzy9MwBZKBa83SjBVO/i38VHDR+9ixo8QpBOiEagmNw12DucG+v55tCrg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm64-gnu": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.0.2.tgz", + "integrity": "sha512-GCK/a9ItUxPI0V5hQEJjH4JtOJO90GF2Hja7TO+EZ8rmkGvEi8/ZDMhXmcuDpQT7/PWrTT9RvnG8snMd5SrhBQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm64-musl": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.0.2.tgz", + "integrity": "sha512-cLuBp7rOjIB1R2j/VazjCmHC7liWUur2e9mFflLJBAWCkrZ+X0+QwHLvOQakIwDymungzAKv6W9kHZnTp/Mqrg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-x64-gnu": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.0.2.tgz", + "integrity": "sha512-Zqw4iVnJr2naoyQus0yLy7sLtisCQcpdMKUCeXPBjkJtpiflRime/TMojbnl8O3oxUAj92mxr+t7im/RbgA20w==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-x64-musl": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.0.2.tgz", + "integrity": "sha512-jJRU9TyUD/iMqjf8aLAp7XiN3pIj5v6Qcu+cdzBfVTKDD0Fvua4oUoK8eVJ9ZuKBEQKt3WdlcwJXFkpmMLk6kg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-arm64-msvc": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.0.2.tgz", + "integrity": "sha512-ZkS2NixCxHKC4zbOnw64ztEGGDVIYP6nKkGBfOAxEPW71Sji9v8z3yaHNuae/JHPwXA+14oDefnOuVfxl59SmQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-ia32-msvc": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.0.2.tgz", + "integrity": "sha512-3SKjj+tvnZ0oZq2BKB+fI+DqYI83VrRzk7eed8tJkxeZ4zxJZcLSE8YDQLYGq1tZAnAX+H076RHHB4gTZXsQzw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-x64-msvc": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.0.2.tgz", + "integrity": "sha512-MBdJIOxRauKkry7t2q+rTHa3aWjVez2eioWg+etRVS3dE4tChhmt5oqZYr48R6bPmcwEhxQr96gVRfeQrLbqng==", + "dev": true, + "optional": true + }, "@sinonjs/commons": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", @@ -11680,11 +11932,23 @@ } }, "rollup": { - "version": "3.29.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", - "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", - "dev": true, - "requires": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.0.2.tgz", + "integrity": "sha512-MCScu4usMPCeVFaiLcgMDaBQeYi1z6vpWxz0r0hq0Hv77Y2YuOTZldkuNJ54BdYBH3e+nkrk6j0Rre/NLDBYzg==", + "dev": true, + "requires": { + "@rollup/rollup-android-arm-eabi": "4.0.2", + "@rollup/rollup-android-arm64": "4.0.2", + "@rollup/rollup-darwin-arm64": "4.0.2", + "@rollup/rollup-darwin-x64": "4.0.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.0.2", + "@rollup/rollup-linux-arm64-gnu": "4.0.2", + "@rollup/rollup-linux-arm64-musl": "4.0.2", + "@rollup/rollup-linux-x64-gnu": "4.0.2", + "@rollup/rollup-linux-x64-musl": "4.0.2", + "@rollup/rollup-win32-arm64-msvc": "4.0.2", + "@rollup/rollup-win32-ia32-msvc": "4.0.2", + "@rollup/rollup-win32-x64-msvc": "4.0.2", "fsevents": "~2.3.2" } }, diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 4059a1b7..b2cb5faa 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^27.5.1", "prettier": "^3.0.0", "rimraf": "^5.0.0", - "rollup": "^3.0.0", + "rollup": "^4.0.2", "rollup-plugin-dts": "^6.1.0", "rollup-plugin-node-polyfills": "^0.2.1", "ts-jest": "^27.1.3", From 1c82a9cc0562fd02b045e356462b6720263d7697 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 11 Oct 2023 15:36:41 -0400 Subject: [PATCH 0546/1076] stake-pool: Allow removal of force-destaked validator (#5439) * stake-pool: Allow removal of force-destaked validator * Update comment --- clients/py/stake_pool/instructions.py | 2 +- program/src/instruction.rs | 4 +- program/src/processor.rs | 39 +++--- program/tests/force_destake.rs | 189 ++++++++++++++++++++++---- program/tests/helpers/mod.rs | 15 +- program/tests/vsa_remove.rs | 30 ++-- 6 files changed, 213 insertions(+), 66 deletions(-) diff --git a/clients/py/stake_pool/instructions.py b/clients/py/stake_pool/instructions.py index de2e13fe..4a773a2d 100644 --- a/clients/py/stake_pool/instructions.py +++ b/clients/py/stake_pool/instructions.py @@ -749,7 +749,7 @@ def remove_validator_from_pool(params: RemoveValidatorFromPoolParams) -> Transac AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), AccountMeta(pubkey=params.validator_list, is_signer=False, is_writable=True), AccountMeta(pubkey=params.validator_stake, is_signer=False, is_writable=True), - AccountMeta(pubkey=params.transient_stake, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.transient_stake, is_signer=False, is_writable=True), AccountMeta(pubkey=params.clock_sysvar, is_signer=False, is_writable=False), AccountMeta(pubkey=params.stake_program_id, is_signer=False, is_writable=False), ], diff --git a/program/src/instruction.rs b/program/src/instruction.rs index d7e35590..fb07373c 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -112,7 +112,7 @@ pub enum StakePoolInstruction { /// 2. `[]` Stake pool withdraw authority /// 3. `[w]` Validator stake list storage account /// 4. `[w]` Stake account to remove from the pool - /// 5. `[]` Transient stake account, to check that that we're not trying to activate + /// 5. `[w]` Transient stake account, to deactivate if necessary /// 6. `[]` Sysvar clock /// 7. `[]` Stake program id, RemoveValidatorFromPool, @@ -777,7 +777,7 @@ pub fn remove_validator_from_pool( AccountMeta::new_readonly(*stake_pool_withdraw, false), AccountMeta::new(*validator_list, false), AccountMeta::new(*stake_account, false), - AccountMeta::new_readonly(*transient_stake_account, false), + AccountMeta::new(*transient_stake_account, false), AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(stake::program::id(), false), ]; diff --git a/program/src/processor.rs b/program/src/processor.rs index aeb40520..abf5a67c 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -1193,16 +1193,16 @@ impl Processor { ) => { if stake.delegation.deactivation_epoch == Epoch::MAX { - msg!( - "Transient stake {} activating, can't remove stake {} on validator {}", - transient_stake_account_info.key, - stake_account_info.key, - vote_account_address - ); - return Err(StakePoolError::WrongStakeState.into()); - } else { - StakeStatus::DeactivatingAll + Self::stake_deactivate( + transient_stake_account_info.clone(), + clock_info.clone(), + withdraw_authority_info.clone(), + stake_pool_info.key, + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + )?; } + StakeStatus::DeactivatingAll } _ => StakeStatus::DeactivatingValidator, } @@ -1210,15 +1210,18 @@ impl Processor { StakeStatus::DeactivatingValidator }; - // deactivate stake - Self::stake_deactivate( - stake_account_info.clone(), - clock_info.clone(), - withdraw_authority_info.clone(), - stake_pool_info.key, - AUTHORITY_WITHDRAW, - stake_pool.stake_withdraw_bump_seed, - )?; + // If the stake was force-deactivated through deactivate-delinquent or + // some other means, we *do not* need to deactivate it again + if stake.delegation.deactivation_epoch == Epoch::MAX { + Self::stake_deactivate( + stake_account_info.clone(), + clock_info.clone(), + withdraw_authority_info.clone(), + stake_pool_info.key, + AUTHORITY_WITHDRAW, + stake_pool.stake_withdraw_bump_seed, + )?; + } validator_stake_info.status = new_status.into(); diff --git a/program/tests/force_destake.rs b/program/tests/force_destake.rs index 99d3fe97..b3dffe94 100644 --- a/program/tests/force_destake.rs +++ b/program/tests/force_destake.rs @@ -5,7 +5,15 @@ mod helpers; use { helpers::*, - solana_program::{instruction::InstructionError, pubkey::Pubkey, stake}, + solana_program::{ + borsh0_10::try_from_slice_unchecked, + instruction::InstructionError, + pubkey::Pubkey, + stake::{ + self, + state::{Authorized, Delegation, Lockup, Meta, Stake, StakeState}, + }, + }, solana_program_test::*, solana_sdk::{ account::{Account, WritableAccount}, @@ -16,40 +24,27 @@ use { spl_stake_pool::{ error::StakePoolError, find_stake_program_address, find_transient_stake_program_address, id, - state::{StakeStatus, ValidatorStakeInfo}, + state::{AccountType, StakeStatus, ValidatorList, ValidatorListHeader, ValidatorStakeInfo}, MINIMUM_ACTIVE_STAKE, }, std::num::NonZeroU32, }; -async fn setup() -> ( - ProgramTestContext, - StakePoolAccounts, - Pubkey, - Option, -) { +async fn setup( + stake_pool_accounts: &StakePoolAccounts, + forced_stake: &StakeState, + voter_pubkey: &Pubkey, +) -> (ProgramTestContext, Option) { let mut program_test = program_test(); - let stake_pool_accounts = StakePoolAccounts::default(); let stake_pool_pubkey = stake_pool_accounts.stake_pool.pubkey(); let (mut stake_pool, mut validator_list) = stake_pool_accounts.state(); - let voter_pubkey = add_vote_account(&mut program_test); - let meta = stake::state::Meta { - rent_exempt_reserve: STAKE_ACCOUNT_RENT_EXEMPTION, - authorized: stake::state::Authorized { - staker: stake_pool_accounts.withdraw_authority, - withdrawer: stake_pool_accounts.withdraw_authority, - }, - lockup: stake_pool.lockup, - }; + let _ = add_vote_account_with_pubkey(voter_pubkey, &mut program_test); let stake_account = Account::create( TEST_STAKE_AMOUNT + STAKE_ACCOUNT_RENT_EXEMPTION, - bincode::serialize::(&stake::state::StakeState::Initialized( - meta, - )) - .unwrap(), + bincode::serialize::(forced_stake).unwrap(), stake::program::id(), false, Epoch::default(), @@ -58,13 +53,13 @@ async fn setup() -> ( let raw_validator_seed = 42; let validator_seed = NonZeroU32::new(raw_validator_seed); let (stake_address, _) = - find_stake_program_address(&id(), &voter_pubkey, &stake_pool_pubkey, validator_seed); + find_stake_program_address(&id(), voter_pubkey, &stake_pool_pubkey, validator_seed); program_test.add_account(stake_address, stake_account); let active_stake_lamports = TEST_STAKE_AMOUNT - MINIMUM_ACTIVE_STAKE; // add to validator list validator_list.validators.push(ValidatorStakeInfo { status: StakeStatus::Active.into(), - vote_account_address: voter_pubkey, + vote_account_address: *voter_pubkey, active_stake_lamports: active_stake_lamports.into(), transient_stake_lamports: 0.into(), last_update_epoch: 0.into(), @@ -110,12 +105,27 @@ async fn setup() -> ( ); let context = program_test.start_with_context().await; - (context, stake_pool_accounts, voter_pubkey, validator_seed) + (context, validator_seed) } #[tokio::test] async fn success_update() { - let (mut context, stake_pool_accounts, voter_pubkey, validator_seed) = setup().await; + let stake_pool_accounts = StakePoolAccounts::default(); + let meta = Meta { + rent_exempt_reserve: STAKE_ACCOUNT_RENT_EXEMPTION, + authorized: Authorized { + staker: stake_pool_accounts.withdraw_authority, + withdrawer: stake_pool_accounts.withdraw_authority, + }, + lockup: Lockup::default(), + }; + let voter_pubkey = Pubkey::new_unique(); + let (mut context, validator_seed) = setup( + &stake_pool_accounts, + &StakeState::Initialized(meta), + &voter_pubkey, + ) + .await; let pre_reserve_lamports = context .banks_client .get_account(stake_pool_accounts.reserve_stake.pubkey()) @@ -169,7 +179,22 @@ async fn success_update() { #[tokio::test] async fn fail_increase() { - let (mut context, stake_pool_accounts, voter_pubkey, validator_seed) = setup().await; + let stake_pool_accounts = StakePoolAccounts::default(); + let meta = Meta { + rent_exempt_reserve: STAKE_ACCOUNT_RENT_EXEMPTION, + authorized: Authorized { + staker: stake_pool_accounts.withdraw_authority, + withdrawer: stake_pool_accounts.withdraw_authority, + }, + lockup: Lockup::default(), + }; + let voter_pubkey = Pubkey::new_unique(); + let (mut context, validator_seed) = setup( + &stake_pool_accounts, + &StakeState::Initialized(meta), + &voter_pubkey, + ) + .await; let (stake_address, _) = find_stake_program_address( &id(), &voter_pubkey, @@ -206,3 +231,113 @@ async fn fail_increase() { ) ); } + +#[tokio::test] +async fn success_remove_validator() { + let stake_pool_accounts = StakePoolAccounts::default(); + let meta = Meta { + rent_exempt_reserve: STAKE_ACCOUNT_RENT_EXEMPTION, + authorized: Authorized { + staker: stake_pool_accounts.withdraw_authority, + withdrawer: stake_pool_accounts.withdraw_authority, + }, + lockup: Lockup::default(), + }; + let voter_pubkey = Pubkey::new_unique(); + let stake = Stake { + delegation: Delegation { + voter_pubkey, + stake: TEST_STAKE_AMOUNT, + activation_epoch: 0, + deactivation_epoch: 0, + ..Delegation::default() + }, + credits_observed: 1, + }; + let (mut context, validator_seed) = setup( + &stake_pool_accounts, + &StakeState::Stake(meta, stake), + &voter_pubkey, + ) + .await; + + // move forward to after deactivation + let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; + context.warp_to_slot(first_normal_slot + 1).unwrap(); + stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &[voter_pubkey], + false, + ) + .await; + + let (stake_address, _) = find_stake_program_address( + &id(), + &voter_pubkey, + &stake_pool_accounts.stake_pool.pubkey(), + validator_seed, + ); + let transient_stake_seed = 0; + let transient_stake_address = find_transient_stake_program_address( + &id(), + &voter_pubkey, + &stake_pool_accounts.stake_pool.pubkey(), + transient_stake_seed, + ) + .0; + + let error = stake_pool_accounts + .remove_validator_from_pool( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &stake_address, + &transient_stake_address, + ) + .await; + assert!(error.is_none(), "{:?}", error); + + // Get a new blockhash for the next update to work + context.get_new_latest_blockhash().await.unwrap(); + + let error = stake_pool_accounts + .update_all( + &mut context.banks_client, + &context.payer, + &context.last_blockhash, + &[voter_pubkey], + false, + ) + .await; + assert!(error.is_none(), "{:?}", error); + + // Check if account was removed from the list of stake accounts + let validator_list = get_account( + &mut context.banks_client, + &stake_pool_accounts.validator_list.pubkey(), + ) + .await; + let validator_list = + try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); + assert_eq!( + validator_list, + ValidatorList { + header: ValidatorListHeader { + account_type: AccountType::ValidatorList, + max_validators: stake_pool_accounts.max_validators, + }, + validators: vec![] + } + ); + + // Check stake account no longer exists + let account = context + .banks_client + .get_account(stake_address) + .await + .unwrap(); + assert!(account.is_none()); +} diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 4f001295..a72c6cb2 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -2384,13 +2384,15 @@ pub async fn get_validator_list_sum( validator_sum + reserve_stake.lamports - rent - MINIMUM_RESERVE_LAMPORTS } -pub fn add_vote_account(program_test: &mut ProgramTest) -> Pubkey { +pub fn add_vote_account_with_pubkey( + voter_pubkey: &Pubkey, + program_test: &mut ProgramTest, +) -> Pubkey { let authorized_voter = Pubkey::new_unique(); let authorized_withdrawer = Pubkey::new_unique(); let commission = 1; // create vote account - let vote_pubkey = Pubkey::new_unique(); let node_pubkey = Pubkey::new_unique(); let vote_state = VoteStateVersions::new_current(VoteState::new( &VoteInit { @@ -2408,8 +2410,13 @@ pub fn add_vote_account(program_test: &mut ProgramTest) -> Pubkey { false, Epoch::default(), ); - program_test.add_account(vote_pubkey, vote_account); - vote_pubkey + program_test.add_account(*voter_pubkey, vote_account); + *voter_pubkey +} + +pub fn add_vote_account(program_test: &mut ProgramTest) -> Pubkey { + let voter_pubkey = Pubkey::new_unique(); + add_vote_account_with_pubkey(&voter_pubkey, program_test) } #[allow(clippy::too_many_arguments)] diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index b305052f..80e87851 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -4,6 +4,7 @@ mod helpers; use { + bincode::deserialize, borsh::BorshSerialize, helpers::*, solana_program::{ @@ -389,7 +390,7 @@ async fn fail_no_signature() { } #[tokio::test] -async fn fail_with_activating_transient_stake() { +async fn success_with_activating_transient_stake() { let (mut context, stake_pool_accounts, validator_stake) = setup().await; // increase the validator stake @@ -415,19 +416,20 @@ async fn fail_with_activating_transient_stake() { &validator_stake.stake_account, &validator_stake.transient_stake_account, ) - .await - .unwrap() - .unwrap(); - match error { - TransactionError::InstructionError( - _, - InstructionError::Custom(error_index), - ) => { - let program_error = StakePoolError::WrongStakeState as u32; - assert_eq!(error_index, program_error); - } - _ => panic!("Wrong error occurs while removing validator stake account while transient stake is activating"), - } + .await; + assert!(error.is_none(), "{:?}", error); + + // transient stake should be inactive now + let stake = get_account( + &mut context.banks_client, + &validator_stake.transient_stake_account, + ) + .await; + let stake_state = deserialize::(&stake.data).unwrap(); + assert_ne!( + stake_state.stake().unwrap().delegation.deactivation_epoch, + u64::MAX + ); } #[tokio::test] From 2bda6b64581dc088f81e0e2d99c639b9fd0c9eb9 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 11 Oct 2023 23:48:04 -0400 Subject: [PATCH 0547/1076] stake-pool: Ignore test that fails in downstream (#5513) --- program/tests/force_destake.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/program/tests/force_destake.rs b/program/tests/force_destake.rs index b3dffe94..38645872 100644 --- a/program/tests/force_destake.rs +++ b/program/tests/force_destake.rs @@ -233,6 +233,7 @@ async fn fail_increase() { } #[tokio::test] +#[ignore] async fn success_remove_validator() { let stake_pool_accounts = StakePoolAccounts::default(); let meta = Meta { From f2eb267ee2e13b1951d804699e92898e4689cb25 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Oct 2023 23:53:44 -0400 Subject: [PATCH 0548/1076] build(deps-dev): bump eslint-plugin-prettier from 5.0.0 to 5.0.1 in /stake-pool/js (#5506) build(deps-dev): bump eslint-plugin-prettier in /stake-pool/js Bumps [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) from 5.0.0 to 5.0.1. - [Release notes](https://github.com/prettier/eslint-plugin-prettier/releases) - [Changelog](https://github.com/prettier/eslint-plugin-prettier/blob/master/CHANGELOG.md) - [Commits](https://github.com/prettier/eslint-plugin-prettier/compare/v5.0.0...v5.0.1) --- updated-dependencies: - dependency-name: eslint-plugin-prettier dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 16fc5fcf..f2ac8150 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -3611,9 +3611,9 @@ } }, "node_modules/eslint-plugin-prettier": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.0.tgz", - "integrity": "sha512-AgaZCVuYDXHUGxj/ZGu1u8H8CYgDY3iG6w5kUFw4AzMVXzB7VvbKgYR4nATIN+OvUrghMbiDLeimVjVY5ilq3w==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.1.tgz", + "integrity": "sha512-m3u5RnR56asrwV/lDC4GHorlW75DsFfmUcjfCYylTUs85dBRnB7VM6xG8eCMJdeDRnppzmxZVf1GEPJvl1JmNg==", "dev": true, "dependencies": { "prettier-linter-helpers": "^1.0.0", @@ -9991,9 +9991,9 @@ "requires": {} }, "eslint-plugin-prettier": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.0.tgz", - "integrity": "sha512-AgaZCVuYDXHUGxj/ZGu1u8H8CYgDY3iG6w5kUFw4AzMVXzB7VvbKgYR4nATIN+OvUrghMbiDLeimVjVY5ilq3w==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.1.tgz", + "integrity": "sha512-m3u5RnR56asrwV/lDC4GHorlW75DsFfmUcjfCYylTUs85dBRnB7VM6xG8eCMJdeDRnppzmxZVf1GEPJvl1JmNg==", "dev": true, "requires": { "prettier-linter-helpers": "^1.0.0", From 582747f2a1ff629bfadd60bc086d3313e6cfeac8 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 12 Oct 2023 11:35:45 -0400 Subject: [PATCH 0549/1076] stake-pool: Fix test for monorepo downstream job (#5514) --- program/tests/force_destake.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/program/tests/force_destake.rs b/program/tests/force_destake.rs index 38645872..5becdbe8 100644 --- a/program/tests/force_destake.rs +++ b/program/tests/force_destake.rs @@ -41,10 +41,12 @@ async fn setup( let (mut stake_pool, mut validator_list) = stake_pool_accounts.state(); let _ = add_vote_account_with_pubkey(voter_pubkey, &mut program_test); + let mut data = vec![0; std::mem::size_of::()]; + bincode::serialize_into(&mut data[..], forced_stake).unwrap(); let stake_account = Account::create( TEST_STAKE_AMOUNT + STAKE_ACCOUNT_RENT_EXEMPTION, - bincode::serialize::(forced_stake).unwrap(), + data, stake::program::id(), false, Epoch::default(), @@ -233,7 +235,6 @@ async fn fail_increase() { } #[tokio::test] -#[ignore] async fn success_remove_validator() { let stake_pool_accounts = StakePoolAccounts::default(); let meta = Meta { From 990d35e02f380fb3f92686068aec48aa47c1ba80 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Oct 2023 10:30:42 -0400 Subject: [PATCH 0550/1076] build(deps-dev): bump eslint from 8.50.0 to 8.51.0 in /stake-pool/js (#5519) Bumps [eslint](https://github.com/eslint/eslint) from 8.50.0 to 8.51.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.50.0...v8.51.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index f2ac8150..b4145296 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -789,9 +789,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.50.0.tgz", - "integrity": "sha512-NCC3zz2+nvYd+Ckfh87rA47zfu2QsQpvc6k1yzTk+b9KzRj0wkGa8LSoGOXN6Zv4lRf/EIoZ80biDh9HOI+RNQ==", + "version": "8.51.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.51.0.tgz", + "integrity": "sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3545,15 +3545,15 @@ } }, "node_modules/eslint": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.50.0.tgz", - "integrity": "sha512-FOnOGSuFuFLv/Sa+FDVRZl4GGVAAFFi8LecRsI5a1tMO5HIE8nCm4ivAlzt4dT3ol/PaaGC0rJEEXQmHJBGoOg==", + "version": "8.51.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.51.0.tgz", + "integrity": "sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.50.0", + "@eslint/js": "8.51.0", "@humanwhocodes/config-array": "^0.11.11", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -7934,9 +7934,9 @@ } }, "@eslint/js": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.50.0.tgz", - "integrity": "sha512-NCC3zz2+nvYd+Ckfh87rA47zfu2QsQpvc6k1yzTk+b9KzRj0wkGa8LSoGOXN6Zv4lRf/EIoZ80biDh9HOI+RNQ==", + "version": "8.51.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.51.0.tgz", + "integrity": "sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==", "dev": true }, "@humanwhocodes/config-array": { @@ -9900,15 +9900,15 @@ } }, "eslint": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.50.0.tgz", - "integrity": "sha512-FOnOGSuFuFLv/Sa+FDVRZl4GGVAAFFi8LecRsI5a1tMO5HIE8nCm4ivAlzt4dT3ol/PaaGC0rJEEXQmHJBGoOg==", + "version": "8.51.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.51.0.tgz", + "integrity": "sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.50.0", + "@eslint/js": "8.51.0", "@humanwhocodes/config-array": "^0.11.11", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", From 89ec36047b211ff146923cb31871f18937b41720 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Oct 2023 10:30:52 -0400 Subject: [PATCH 0551/1076] build(deps-dev): bump @typescript-eslint/parser from 6.7.4 to 6.7.5 in /stake-pool/js (#5520) build(deps-dev): bump @typescript-eslint/parser in /stake-pool/js Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.7.4 to 6.7.5. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.7.5/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 145 +++------------------------- 1 file changed, 14 insertions(+), 131 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index b4145296..e416f241 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -2127,15 +2127,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.4.tgz", - "integrity": "sha512-I5zVZFY+cw4IMZUeNCU7Sh2PO5O57F7Lr0uyhgCJmhN/BuTlnc55KxPonR4+EM3GBdfiCyGZye6DgMjtubQkmA==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.5.tgz", + "integrity": "sha512-bIZVSGx2UME/lmhLcjdVc7ePBwn7CLqKarUBL4me1C5feOd663liTGjMBGVcGr+BhnSLeP4SgwdvNnnkbIdkCw==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.7.4", - "@typescript-eslint/types": "6.7.4", - "@typescript-eslint/typescript-estree": "6.7.4", - "@typescript-eslint/visitor-keys": "6.7.4", + "@typescript-eslint/scope-manager": "6.7.5", + "@typescript-eslint/types": "6.7.5", + "@typescript-eslint/typescript-estree": "6.7.5", + "@typescript-eslint/visitor-keys": "6.7.5", "debug": "^4.3.4" }, "engines": { @@ -2154,80 +2154,6 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.4.tgz", - "integrity": "sha512-SdGqSLUPTXAXi7c3Ob7peAGVnmMoGzZ361VswK2Mqf8UOYcODiYvs8rs5ILqEdfvX1lE7wEZbLyELCW+Yrql1A==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.7.4", - "@typescript-eslint/visitor-keys": "6.7.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.4.tgz", - "integrity": "sha512-o9XWK2FLW6eSS/0r/tgjAGsYasLAnOWg7hvZ/dGYSSNjCh+49k5ocPN8OmG5aZcSJ8pclSOyVKP2x03Sj+RrCA==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.4.tgz", - "integrity": "sha512-ty8b5qHKatlNYd9vmpHooQz3Vki3gG+3PchmtsA4TgrZBKWHNjWfkQid7K7xQogBqqc7/BhGazxMD5vr6Ha+iQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.7.4", - "@typescript-eslint/visitor-keys": "6.7.4", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.4.tgz", - "integrity": "sha512-pOW37DUhlTZbvph50x5zZCkFn3xzwkGtNoJHzIM3svpiSkJzwOYr/kVBaXmf+RAQiUDs1AHEZVNPg6UJCJpwRA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.7.4", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/scope-manager": { "version": "6.7.5", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.5.tgz", @@ -8910,59 +8836,16 @@ } }, "@typescript-eslint/parser": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.4.tgz", - "integrity": "sha512-I5zVZFY+cw4IMZUeNCU7Sh2PO5O57F7Lr0uyhgCJmhN/BuTlnc55KxPonR4+EM3GBdfiCyGZye6DgMjtubQkmA==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.5.tgz", + "integrity": "sha512-bIZVSGx2UME/lmhLcjdVc7ePBwn7CLqKarUBL4me1C5feOd663liTGjMBGVcGr+BhnSLeP4SgwdvNnnkbIdkCw==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "6.7.4", - "@typescript-eslint/types": "6.7.4", - "@typescript-eslint/typescript-estree": "6.7.4", - "@typescript-eslint/visitor-keys": "6.7.4", + "@typescript-eslint/scope-manager": "6.7.5", + "@typescript-eslint/types": "6.7.5", + "@typescript-eslint/typescript-estree": "6.7.5", + "@typescript-eslint/visitor-keys": "6.7.5", "debug": "^4.3.4" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.4.tgz", - "integrity": "sha512-SdGqSLUPTXAXi7c3Ob7peAGVnmMoGzZ361VswK2Mqf8UOYcODiYvs8rs5ILqEdfvX1lE7wEZbLyELCW+Yrql1A==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.7.4", - "@typescript-eslint/visitor-keys": "6.7.4" - } - }, - "@typescript-eslint/types": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.4.tgz", - "integrity": "sha512-o9XWK2FLW6eSS/0r/tgjAGsYasLAnOWg7hvZ/dGYSSNjCh+49k5ocPN8OmG5aZcSJ8pclSOyVKP2x03Sj+RrCA==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.4.tgz", - "integrity": "sha512-ty8b5qHKatlNYd9vmpHooQz3Vki3gG+3PchmtsA4TgrZBKWHNjWfkQid7K7xQogBqqc7/BhGazxMD5vr6Ha+iQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.7.4", - "@typescript-eslint/visitor-keys": "6.7.4", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.4.tgz", - "integrity": "sha512-pOW37DUhlTZbvph50x5zZCkFn3xzwkGtNoJHzIM3svpiSkJzwOYr/kVBaXmf+RAQiUDs1AHEZVNPg6UJCJpwRA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.7.4", - "eslint-visitor-keys": "^3.4.1" - } - } } }, "@typescript-eslint/scope-manager": { From fa88fb952082a1e77f8e8485c8939bf1e9d24cb9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Oct 2023 10:31:28 -0400 Subject: [PATCH 0552/1076] build(deps): bump serde from 1.0.188 to 1.0.189 (#5523) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.188 to 1.0.189. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.188...v1.0.189) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 539f6b46..4674b6b1 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "0.7.0" [dependencies] borsh = "0.10" clap = "2.33.3" -serde = "1.0.188" +serde = "1.0.189" serde_derive = "1.0.130" serde_json = "1.0.107" solana-account-decoder = "=1.16.16" diff --git a/program/Cargo.toml b/program/Cargo.toml index d160303e..0832372d 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,7 +18,7 @@ bytemuck = "1.13" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.0" -serde = "1.0.188" +serde = "1.0.189" serde_derive = "1.0.103" solana-program = "1.16.16" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } From 16795da1a7e329188a7f75814957fe1cec53c1aa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Oct 2023 10:32:22 -0400 Subject: [PATCH 0553/1076] build(deps-dev): bump @types/node from 20.8.4 to 20.8.5 in /stake-pool/js (#5528) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.8.4 to 20.8.5. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index e416f241..cbd28a34 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -2013,9 +2013,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.8.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.4.tgz", - "integrity": "sha512-ZVPnqU58giiCjSxjVUESDtdPk4QR5WQhhINbc9UBrKLU68MX5BF6kbQzTrkwbolyr0X8ChBpXfavr5mZFKZQ5A==", + "version": "20.8.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.5.tgz", + "integrity": "sha512-SPlobFgbidfIeOYlzXiEjSYeIJiOCthv+9tSQVpvk4PAdIIc+2SmjNVzWXk9t0Y7dl73Zdf+OgXKHX9XtkqUpw==", "dependencies": { "undici-types": "~5.25.1" } @@ -8739,9 +8739,9 @@ "dev": true }, "@types/node": { - "version": "20.8.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.4.tgz", - "integrity": "sha512-ZVPnqU58giiCjSxjVUESDtdPk4QR5WQhhINbc9UBrKLU68MX5BF6kbQzTrkwbolyr0X8ChBpXfavr5mZFKZQ5A==", + "version": "20.8.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.5.tgz", + "integrity": "sha512-SPlobFgbidfIeOYlzXiEjSYeIJiOCthv+9tSQVpvk4PAdIIc+2SmjNVzWXk9t0Y7dl73Zdf+OgXKHX9XtkqUpw==", "requires": { "undici-types": "~5.25.1" } From 2f7097bc49fa97017e46135050d1532520372381 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 17:11:18 +0200 Subject: [PATCH 0554/1076] build(deps-dev): bump @babel/traverse from 7.17.0 to 7.23.2 in /stake-pool/js (#5555) build(deps-dev): bump @babel/traverse in /stake-pool/js Bumps [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) from 7.17.0 to 7.23.2. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.23.2/packages/babel-traverse) --- updated-dependencies: - dependency-name: "@babel/traverse" dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 251 +++++++++++++--------------- 1 file changed, 112 insertions(+), 139 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index cbd28a34..6cc779ea 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -198,28 +198,20 @@ } }, "node_modules/@babel/generator": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.0.tgz", - "integrity": "sha512-I3Omiv6FGOC29dtlZhkfXO6pgkmukJSlT26QjVvS1DGZe/NzSVCPG41X0tS21oZkJYlovfj9qDWgKP+Cn4bXxw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", "dev": true, "dependencies": { - "@babel/types": "^7.17.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" + "@babel/types": "^7.23.0", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/generator/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/@babel/helper-compilation-targets": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", @@ -248,50 +240,34 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", - "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true, - "dependencies": { - "@babel/types": "^7.16.7" - }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", - "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", - "dev": true, - "dependencies": { - "@babel/helper-get-function-arity": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/types": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-get-function-arity": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", - "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "dependencies": { - "@babel/types": "^7.16.7" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", - "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dev": true, "dependencies": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -350,17 +326,26 @@ } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", - "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, "dependencies": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/helper-string-parser": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-validator-identifier": { "version": "7.22.20", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", @@ -479,9 +464,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.0.tgz", - "integrity": "sha512-VKXSCQx5D8S04ej+Dqsr1CzYvvWgf20jIw2D+YhQCrIlr2UZGaDds23Y0xg75/skOxpLCRpUZvk/1EAVkGoDOw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -664,33 +649,33 @@ } }, "node_modules/@babel/template": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", - "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.16.7", - "@babel/parser": "^7.16.7", - "@babel/types": "^7.16.7" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.0.tgz", - "integrity": "sha512-fpFIXvqD6kC7c7PUNnZ0Z8cQXlarCLtCUpt2S1Dx7PjoRtCFffvOkHHSom+m5HIxMZn5bIBVb71lhabcmjEsqg==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.0", - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", - "@babel/helper-hoist-variables": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.17.0", - "@babel/types": "^7.17.0", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -708,12 +693,13 @@ } }, "node_modules/@babel/types": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", - "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.16.7", + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { @@ -7417,22 +7403,15 @@ } }, "@babel/generator": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.0.tgz", - "integrity": "sha512-I3Omiv6FGOC29dtlZhkfXO6pgkmukJSlT26QjVvS1DGZe/NzSVCPG41X0tS21oZkJYlovfj9qDWgKP+Cn4bXxw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", "dev": true, "requires": { - "@babel/types": "^7.17.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } + "@babel/types": "^7.23.0", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" } }, "@babel/helper-compilation-targets": { @@ -7456,41 +7435,28 @@ } }, "@babel/helper-environment-visitor": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", - "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" - } + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "dev": true }, "@babel/helper-function-name": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", - "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", - "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "requires": { - "@babel/types": "^7.16.7" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" } }, "@babel/helper-hoist-variables": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", - "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dev": true, "requires": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.22.5" } }, "@babel/helper-module-imports": { @@ -7534,14 +7500,20 @@ } }, "@babel/helper-split-export-declaration": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", - "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, "requires": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.22.5" } }, + "@babel/helper-string-parser": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "dev": true + }, "@babel/helper-validator-identifier": { "version": "7.22.20", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", @@ -7635,9 +7607,9 @@ } }, "@babel/parser": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.0.tgz", - "integrity": "sha512-VKXSCQx5D8S04ej+Dqsr1CzYvvWgf20jIw2D+YhQCrIlr2UZGaDds23Y0xg75/skOxpLCRpUZvk/1EAVkGoDOw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", "dev": true }, "@babel/plugin-syntax-async-generators": { @@ -7766,30 +7738,30 @@ } }, "@babel/template": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", - "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, "requires": { - "@babel/code-frame": "^7.16.7", - "@babel/parser": "^7.16.7", - "@babel/types": "^7.16.7" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" } }, "@babel/traverse": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.0.tgz", - "integrity": "sha512-fpFIXvqD6kC7c7PUNnZ0Z8cQXlarCLtCUpt2S1Dx7PjoRtCFffvOkHHSom+m5HIxMZn5bIBVb71lhabcmjEsqg==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", "dev": true, "requires": { - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.0", - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", - "@babel/helper-hoist-variables": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.17.0", - "@babel/types": "^7.17.0", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -7803,12 +7775,13 @@ } }, "@babel/types": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", - "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.16.7", + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" } }, From 0333009a4d61231eb62db0ac8c5c82c2b2fb50de Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 17:12:00 +0200 Subject: [PATCH 0555/1076] build(deps-dev): bump @types/node from 20.8.5 to 20.8.6 in /stake-pool/js (#5552) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.8.5 to 20.8.6. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 6cc779ea..90d2a66d 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1999,9 +1999,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.8.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.5.tgz", - "integrity": "sha512-SPlobFgbidfIeOYlzXiEjSYeIJiOCthv+9tSQVpvk4PAdIIc+2SmjNVzWXk9t0Y7dl73Zdf+OgXKHX9XtkqUpw==", + "version": "20.8.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.6.tgz", + "integrity": "sha512-eWO4K2Ji70QzKUqRy6oyJWUeB7+g2cRagT3T/nxYibYcT4y2BDL8lqolRXjTHmkZCdJfIPaY73KbJAZmcryxTQ==", "dependencies": { "undici-types": "~5.25.1" } @@ -8712,9 +8712,9 @@ "dev": true }, "@types/node": { - "version": "20.8.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.5.tgz", - "integrity": "sha512-SPlobFgbidfIeOYlzXiEjSYeIJiOCthv+9tSQVpvk4PAdIIc+2SmjNVzWXk9t0Y7dl73Zdf+OgXKHX9XtkqUpw==", + "version": "20.8.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.6.tgz", + "integrity": "sha512-eWO4K2Ji70QzKUqRy6oyJWUeB7+g2cRagT3T/nxYibYcT4y2BDL8lqolRXjTHmkZCdJfIPaY73KbJAZmcryxTQ==", "requires": { "undici-types": "~5.25.1" } From e87e1d51bbbe8704ac94171394c837e1aac18ee3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 17:12:51 +0200 Subject: [PATCH 0556/1076] build(deps-dev): bump rollup from 4.0.2 to 4.1.4 in /stake-pool/js (#5551) Bumps [rollup](https://github.com/rollup/rollup) from 4.0.2 to 4.1.4. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.0.2...v4.1.4) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 208 ++++++++++++++-------------- 1 file changed, 104 insertions(+), 104 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 90d2a66d..0c30dba3 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1640,9 +1640,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.0.2.tgz", - "integrity": "sha512-xDvk1pT4vaPU2BOLy0MqHMdYZyntqpaBf8RhBiezlqG9OjY8F50TyctHo8znigYKd+QCFhCmlmXHOL/LoaOl3w==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.1.4.tgz", + "integrity": "sha512-WlzkuFvpKl6CLFdc3V6ESPt7gq5Vrimd2Yv9IzKXdOpgbH4cdDSS1JLiACX8toygihtH5OlxyQzhXOph7Ovlpw==", "cpu": [ "arm" ], @@ -1653,9 +1653,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.0.2.tgz", - "integrity": "sha512-lqCglytY3E6raze27DD9VQJWohbwCxzqs9aSHcj5X/8hJpzZfNdbsr4Ja9Hqp6iPyF53+5PtPx0pKRlkSvlHZg==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.1.4.tgz", + "integrity": "sha512-D1e+ABe56T9Pq2fD+R3ybe1ylCDzu3tY4Qm2Mj24R9wXNCq35+JbFbOpc2yrroO2/tGhTobmEl2Bm5xfE/n8RA==", "cpu": [ "arm64" ], @@ -1666,9 +1666,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.0.2.tgz", - "integrity": "sha512-nkBKItS6E6CCzvRwgiKad+j+1ibmL7SIInj7oqMWmdkCjiSX6VeVZw2mLlRKIUL+JjsBgpATTfo7BiAXc1v0jA==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.1.4.tgz", + "integrity": "sha512-7vTYrgEiOrjxnjsgdPB+4i7EMxbVp7XXtS+50GJYj695xYTTEMn3HZVEvgtwjOUkAP/Q4HDejm4fIAjLeAfhtg==", "cpu": [ "arm64" ], @@ -1679,9 +1679,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.0.2.tgz", - "integrity": "sha512-vX2C8xvWPIbpEgQht95+dY6BReKAvtDgPDGi0XN0kWJKkm4WdNmq5dnwscv/zxvi+n6jUTBhs6GtpkkWT4q8Gg==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.1.4.tgz", + "integrity": "sha512-eGJVZScKSLZkYjhTAESCtbyTBq9SXeW9+TX36ki5gVhDqJtnQ5k0f9F44jNK5RhAMgIj0Ht9+n6HAgH0gUUyWQ==", "cpu": [ "x64" ], @@ -1692,9 +1692,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.0.2.tgz", - "integrity": "sha512-DVFIfcHOjgmeHOAqji4xNz2wczt1Bmzy9MwBZKBa83SjBVO/i38VHDR+9ixo8QpBOiEagmNw12DucG+v55tCrg==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.1.4.tgz", + "integrity": "sha512-HnigYSEg2hOdX1meROecbk++z1nVJDpEofw9V2oWKqOWzTJlJf1UXVbDE6Hg30CapJxZu5ga4fdAQc/gODDkKg==", "cpu": [ "arm" ], @@ -1705,9 +1705,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.0.2.tgz", - "integrity": "sha512-GCK/a9ItUxPI0V5hQEJjH4JtOJO90GF2Hja7TO+EZ8rmkGvEi8/ZDMhXmcuDpQT7/PWrTT9RvnG8snMd5SrhBQ==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.1.4.tgz", + "integrity": "sha512-TzJ+N2EoTLWkaClV2CUhBlj6ljXofaYzF/R9HXqQ3JCMnCHQZmQnbnZllw7yTDp0OG5whP4gIPozR4QiX+00MQ==", "cpu": [ "arm64" ], @@ -1718,9 +1718,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.0.2.tgz", - "integrity": "sha512-cLuBp7rOjIB1R2j/VazjCmHC7liWUur2e9mFflLJBAWCkrZ+X0+QwHLvOQakIwDymungzAKv6W9kHZnTp/Mqrg==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.1.4.tgz", + "integrity": "sha512-aVPmNMdp6Dlo2tWkAduAD/5TL/NT5uor290YvjvFvCv0Q3L7tVdlD8MOGDL+oRSw5XKXKAsDzHhUOPUNPRHVTQ==", "cpu": [ "arm64" ], @@ -1731,9 +1731,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.0.2.tgz", - "integrity": "sha512-Zqw4iVnJr2naoyQus0yLy7sLtisCQcpdMKUCeXPBjkJtpiflRime/TMojbnl8O3oxUAj92mxr+t7im/RbgA20w==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.1.4.tgz", + "integrity": "sha512-77Fb79ayiDad0grvVsz4/OB55wJRyw9Ao+GdOBA9XywtHpuq5iRbVyHToGxWquYWlEf6WHFQQnFEttsAzboyKg==", "cpu": [ "x64" ], @@ -1744,9 +1744,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.0.2.tgz", - "integrity": "sha512-jJRU9TyUD/iMqjf8aLAp7XiN3pIj5v6Qcu+cdzBfVTKDD0Fvua4oUoK8eVJ9ZuKBEQKt3WdlcwJXFkpmMLk6kg==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.1.4.tgz", + "integrity": "sha512-/t6C6niEQTqmQTVTD9TDwUzxG91Mlk69/v0qodIPUnjjB3wR4UA3klg+orR2SU3Ux2Cgf2pWPL9utK80/1ek8g==", "cpu": [ "x64" ], @@ -1757,9 +1757,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.0.2.tgz", - "integrity": "sha512-ZkS2NixCxHKC4zbOnw64ztEGGDVIYP6nKkGBfOAxEPW71Sji9v8z3yaHNuae/JHPwXA+14oDefnOuVfxl59SmQ==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.1.4.tgz", + "integrity": "sha512-ZY5BHHrOPkMbCuGWFNpJH0t18D2LU6GMYKGaqaWTQ3CQOL57Fem4zE941/Ek5pIsVt70HyDXssVEFQXlITI5Gg==", "cpu": [ "arm64" ], @@ -1770,9 +1770,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.0.2.tgz", - "integrity": "sha512-3SKjj+tvnZ0oZq2BKB+fI+DqYI83VrRzk7eed8tJkxeZ4zxJZcLSE8YDQLYGq1tZAnAX+H076RHHB4gTZXsQzw==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.1.4.tgz", + "integrity": "sha512-XG2mcRfFrJvYyYaQmvCIvgfkaGinfXrpkBuIbJrTl9SaIQ8HumheWTIwkNz2mktCKwZfXHQNpO7RgXLIGQ7HXA==", "cpu": [ "ia32" ], @@ -1783,9 +1783,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.0.2.tgz", - "integrity": "sha512-MBdJIOxRauKkry7t2q+rTHa3aWjVez2eioWg+etRVS3dE4tChhmt5oqZYr48R6bPmcwEhxQr96gVRfeQrLbqng==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.1.4.tgz", + "integrity": "sha512-ANFqWYPwkhIqPmXw8vm0GpBEHiPpqcm99jiiAp71DbCSqLDhrtr019C5vhD0Bw4My+LmMvciZq6IsWHqQpl2ZQ==", "cpu": [ "x64" ], @@ -6211,9 +6211,9 @@ } }, "node_modules/rollup": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.0.2.tgz", - "integrity": "sha512-MCScu4usMPCeVFaiLcgMDaBQeYi1z6vpWxz0r0hq0Hv77Y2YuOTZldkuNJ54BdYBH3e+nkrk6j0Rre/NLDBYzg==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.1.4.tgz", + "integrity": "sha512-U8Yk1lQRKqCkDBip/pMYT+IKaN7b7UesK3fLSTuHBoBJacCE+oBqo/dfG/gkUdQNNB2OBmRP98cn2C2bkYZkyw==", "dev": true, "bin": { "rollup": "dist/bin/rollup" @@ -6223,18 +6223,18 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.0.2", - "@rollup/rollup-android-arm64": "4.0.2", - "@rollup/rollup-darwin-arm64": "4.0.2", - "@rollup/rollup-darwin-x64": "4.0.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.0.2", - "@rollup/rollup-linux-arm64-gnu": "4.0.2", - "@rollup/rollup-linux-arm64-musl": "4.0.2", - "@rollup/rollup-linux-x64-gnu": "4.0.2", - "@rollup/rollup-linux-x64-musl": "4.0.2", - "@rollup/rollup-win32-arm64-msvc": "4.0.2", - "@rollup/rollup-win32-ia32-msvc": "4.0.2", - "@rollup/rollup-win32-x64-msvc": "4.0.2", + "@rollup/rollup-android-arm-eabi": "4.1.4", + "@rollup/rollup-android-arm64": "4.1.4", + "@rollup/rollup-darwin-arm64": "4.1.4", + "@rollup/rollup-darwin-x64": "4.1.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.1.4", + "@rollup/rollup-linux-arm64-gnu": "4.1.4", + "@rollup/rollup-linux-arm64-musl": "4.1.4", + "@rollup/rollup-linux-x64-gnu": "4.1.4", + "@rollup/rollup-linux-x64-musl": "4.1.4", + "@rollup/rollup-win32-arm64-msvc": "4.1.4", + "@rollup/rollup-win32-ia32-msvc": "4.1.4", + "@rollup/rollup-win32-x64-msvc": "4.1.4", "fsevents": "~2.3.2" } }, @@ -8440,86 +8440,86 @@ } }, "@rollup/rollup-android-arm-eabi": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.0.2.tgz", - "integrity": "sha512-xDvk1pT4vaPU2BOLy0MqHMdYZyntqpaBf8RhBiezlqG9OjY8F50TyctHo8znigYKd+QCFhCmlmXHOL/LoaOl3w==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.1.4.tgz", + "integrity": "sha512-WlzkuFvpKl6CLFdc3V6ESPt7gq5Vrimd2Yv9IzKXdOpgbH4cdDSS1JLiACX8toygihtH5OlxyQzhXOph7Ovlpw==", "dev": true, "optional": true }, "@rollup/rollup-android-arm64": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.0.2.tgz", - "integrity": "sha512-lqCglytY3E6raze27DD9VQJWohbwCxzqs9aSHcj5X/8hJpzZfNdbsr4Ja9Hqp6iPyF53+5PtPx0pKRlkSvlHZg==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.1.4.tgz", + "integrity": "sha512-D1e+ABe56T9Pq2fD+R3ybe1ylCDzu3tY4Qm2Mj24R9wXNCq35+JbFbOpc2yrroO2/tGhTobmEl2Bm5xfE/n8RA==", "dev": true, "optional": true }, "@rollup/rollup-darwin-arm64": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.0.2.tgz", - "integrity": "sha512-nkBKItS6E6CCzvRwgiKad+j+1ibmL7SIInj7oqMWmdkCjiSX6VeVZw2mLlRKIUL+JjsBgpATTfo7BiAXc1v0jA==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.1.4.tgz", + "integrity": "sha512-7vTYrgEiOrjxnjsgdPB+4i7EMxbVp7XXtS+50GJYj695xYTTEMn3HZVEvgtwjOUkAP/Q4HDejm4fIAjLeAfhtg==", "dev": true, "optional": true }, "@rollup/rollup-darwin-x64": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.0.2.tgz", - "integrity": "sha512-vX2C8xvWPIbpEgQht95+dY6BReKAvtDgPDGi0XN0kWJKkm4WdNmq5dnwscv/zxvi+n6jUTBhs6GtpkkWT4q8Gg==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.1.4.tgz", + "integrity": "sha512-eGJVZScKSLZkYjhTAESCtbyTBq9SXeW9+TX36ki5gVhDqJtnQ5k0f9F44jNK5RhAMgIj0Ht9+n6HAgH0gUUyWQ==", "dev": true, "optional": true }, "@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.0.2.tgz", - "integrity": "sha512-DVFIfcHOjgmeHOAqji4xNz2wczt1Bmzy9MwBZKBa83SjBVO/i38VHDR+9ixo8QpBOiEagmNw12DucG+v55tCrg==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.1.4.tgz", + "integrity": "sha512-HnigYSEg2hOdX1meROecbk++z1nVJDpEofw9V2oWKqOWzTJlJf1UXVbDE6Hg30CapJxZu5ga4fdAQc/gODDkKg==", "dev": true, "optional": true }, "@rollup/rollup-linux-arm64-gnu": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.0.2.tgz", - "integrity": "sha512-GCK/a9ItUxPI0V5hQEJjH4JtOJO90GF2Hja7TO+EZ8rmkGvEi8/ZDMhXmcuDpQT7/PWrTT9RvnG8snMd5SrhBQ==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.1.4.tgz", + "integrity": "sha512-TzJ+N2EoTLWkaClV2CUhBlj6ljXofaYzF/R9HXqQ3JCMnCHQZmQnbnZllw7yTDp0OG5whP4gIPozR4QiX+00MQ==", "dev": true, "optional": true }, "@rollup/rollup-linux-arm64-musl": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.0.2.tgz", - "integrity": "sha512-cLuBp7rOjIB1R2j/VazjCmHC7liWUur2e9mFflLJBAWCkrZ+X0+QwHLvOQakIwDymungzAKv6W9kHZnTp/Mqrg==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.1.4.tgz", + "integrity": "sha512-aVPmNMdp6Dlo2tWkAduAD/5TL/NT5uor290YvjvFvCv0Q3L7tVdlD8MOGDL+oRSw5XKXKAsDzHhUOPUNPRHVTQ==", "dev": true, "optional": true }, "@rollup/rollup-linux-x64-gnu": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.0.2.tgz", - "integrity": "sha512-Zqw4iVnJr2naoyQus0yLy7sLtisCQcpdMKUCeXPBjkJtpiflRime/TMojbnl8O3oxUAj92mxr+t7im/RbgA20w==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.1.4.tgz", + "integrity": "sha512-77Fb79ayiDad0grvVsz4/OB55wJRyw9Ao+GdOBA9XywtHpuq5iRbVyHToGxWquYWlEf6WHFQQnFEttsAzboyKg==", "dev": true, "optional": true }, "@rollup/rollup-linux-x64-musl": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.0.2.tgz", - "integrity": "sha512-jJRU9TyUD/iMqjf8aLAp7XiN3pIj5v6Qcu+cdzBfVTKDD0Fvua4oUoK8eVJ9ZuKBEQKt3WdlcwJXFkpmMLk6kg==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.1.4.tgz", + "integrity": "sha512-/t6C6niEQTqmQTVTD9TDwUzxG91Mlk69/v0qodIPUnjjB3wR4UA3klg+orR2SU3Ux2Cgf2pWPL9utK80/1ek8g==", "dev": true, "optional": true }, "@rollup/rollup-win32-arm64-msvc": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.0.2.tgz", - "integrity": "sha512-ZkS2NixCxHKC4zbOnw64ztEGGDVIYP6nKkGBfOAxEPW71Sji9v8z3yaHNuae/JHPwXA+14oDefnOuVfxl59SmQ==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.1.4.tgz", + "integrity": "sha512-ZY5BHHrOPkMbCuGWFNpJH0t18D2LU6GMYKGaqaWTQ3CQOL57Fem4zE941/Ek5pIsVt70HyDXssVEFQXlITI5Gg==", "dev": true, "optional": true }, "@rollup/rollup-win32-ia32-msvc": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.0.2.tgz", - "integrity": "sha512-3SKjj+tvnZ0oZq2BKB+fI+DqYI83VrRzk7eed8tJkxeZ4zxJZcLSE8YDQLYGq1tZAnAX+H076RHHB4gTZXsQzw==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.1.4.tgz", + "integrity": "sha512-XG2mcRfFrJvYyYaQmvCIvgfkaGinfXrpkBuIbJrTl9SaIQ8HumheWTIwkNz2mktCKwZfXHQNpO7RgXLIGQ7HXA==", "dev": true, "optional": true }, "@rollup/rollup-win32-x64-msvc": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.0.2.tgz", - "integrity": "sha512-MBdJIOxRauKkry7t2q+rTHa3aWjVez2eioWg+etRVS3dE4tChhmt5oqZYr48R6bPmcwEhxQr96gVRfeQrLbqng==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.1.4.tgz", + "integrity": "sha512-ANFqWYPwkhIqPmXw8vm0GpBEHiPpqcm99jiiAp71DbCSqLDhrtr019C5vhD0Bw4My+LmMvciZq6IsWHqQpl2ZQ==", "dev": true, "optional": true }, @@ -11788,23 +11788,23 @@ } }, "rollup": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.0.2.tgz", - "integrity": "sha512-MCScu4usMPCeVFaiLcgMDaBQeYi1z6vpWxz0r0hq0Hv77Y2YuOTZldkuNJ54BdYBH3e+nkrk6j0Rre/NLDBYzg==", - "dev": true, - "requires": { - "@rollup/rollup-android-arm-eabi": "4.0.2", - "@rollup/rollup-android-arm64": "4.0.2", - "@rollup/rollup-darwin-arm64": "4.0.2", - "@rollup/rollup-darwin-x64": "4.0.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.0.2", - "@rollup/rollup-linux-arm64-gnu": "4.0.2", - "@rollup/rollup-linux-arm64-musl": "4.0.2", - "@rollup/rollup-linux-x64-gnu": "4.0.2", - "@rollup/rollup-linux-x64-musl": "4.0.2", - "@rollup/rollup-win32-arm64-msvc": "4.0.2", - "@rollup/rollup-win32-ia32-msvc": "4.0.2", - "@rollup/rollup-win32-x64-msvc": "4.0.2", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.1.4.tgz", + "integrity": "sha512-U8Yk1lQRKqCkDBip/pMYT+IKaN7b7UesK3fLSTuHBoBJacCE+oBqo/dfG/gkUdQNNB2OBmRP98cn2C2bkYZkyw==", + "dev": true, + "requires": { + "@rollup/rollup-android-arm-eabi": "4.1.4", + "@rollup/rollup-android-arm64": "4.1.4", + "@rollup/rollup-darwin-arm64": "4.1.4", + "@rollup/rollup-darwin-x64": "4.1.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.1.4", + "@rollup/rollup-linux-arm64-gnu": "4.1.4", + "@rollup/rollup-linux-arm64-musl": "4.1.4", + "@rollup/rollup-linux-x64-gnu": "4.1.4", + "@rollup/rollup-linux-x64-musl": "4.1.4", + "@rollup/rollup-win32-arm64-msvc": "4.1.4", + "@rollup/rollup-win32-ia32-msvc": "4.1.4", + "@rollup/rollup-win32-x64-msvc": "4.1.4", "fsevents": "~2.3.2" } }, From 22498406f10d76738eeb76fcab46269f19484046 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 17:13:00 +0200 Subject: [PATCH 0557/1076] build(deps-dev): bump @rollup/plugin-commonjs from 25.0.5 to 25.0.7 in /stake-pool/js (#5553) build(deps-dev): bump @rollup/plugin-commonjs in /stake-pool/js Bumps [@rollup/plugin-commonjs](https://github.com/rollup/plugins/tree/HEAD/packages/commonjs) from 25.0.5 to 25.0.7. - [Changelog](https://github.com/rollup/plugins/blob/master/packages/commonjs/CHANGELOG.md) - [Commits](https://github.com/rollup/plugins/commits/commonjs-v25.0.7/packages/commonjs) --- updated-dependencies: - dependency-name: "@rollup/plugin-commonjs" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 44 ++++++++++++++++++----------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 0c30dba3..88f90431 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1401,9 +1401,9 @@ } }, "node_modules/@rollup/plugin-commonjs": { - "version": "25.0.5", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.5.tgz", - "integrity": "sha512-xY8r/A9oisSeSuLCTfhssyDjo9Vp/eDiRLXkg1MXCcEEgEjPmLU+ZyDB20OOD0NlyDa/8SGbK5uIggF5XTx77w==", + "version": "25.0.7", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.7.tgz", + "integrity": "sha512-nEvcR+LRjEjsaSsc4x3XZfCCvZIaSMenZu/OiwOKGN2UhQpAYI7ru7czFvyWbErlpoGjnSX3D5Ch5FcMA3kRWQ==", "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1", @@ -1411,7 +1411,7 @@ "estree-walker": "^2.0.2", "glob": "^8.0.3", "is-reference": "1.2.1", - "magic-string": "^0.27.0" + "magic-string": "^0.30.3" }, "engines": { "node": ">=14.0.0" @@ -1425,6 +1425,12 @@ } } }, + "node_modules/@rollup/plugin-commonjs/node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, "node_modules/@rollup/plugin-commonjs/node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -1454,12 +1460,12 @@ } }, "node_modules/@rollup/plugin-commonjs/node_modules/magic-string": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", - "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", + "version": "0.30.5", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", + "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", "dev": true, "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.13" + "@jridgewell/sourcemap-codec": "^1.4.15" }, "engines": { "node": ">=12" @@ -8301,9 +8307,9 @@ } }, "@rollup/plugin-commonjs": { - "version": "25.0.5", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.5.tgz", - "integrity": "sha512-xY8r/A9oisSeSuLCTfhssyDjo9Vp/eDiRLXkg1MXCcEEgEjPmLU+ZyDB20OOD0NlyDa/8SGbK5uIggF5XTx77w==", + "version": "25.0.7", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.7.tgz", + "integrity": "sha512-nEvcR+LRjEjsaSsc4x3XZfCCvZIaSMenZu/OiwOKGN2UhQpAYI7ru7czFvyWbErlpoGjnSX3D5Ch5FcMA3kRWQ==", "dev": true, "requires": { "@rollup/pluginutils": "^5.0.1", @@ -8311,9 +8317,15 @@ "estree-walker": "^2.0.2", "glob": "^8.0.3", "is-reference": "1.2.1", - "magic-string": "^0.27.0" + "magic-string": "^0.30.3" }, "dependencies": { + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, "brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -8337,12 +8349,12 @@ } }, "magic-string": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", - "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", + "version": "0.30.5", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", + "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", "dev": true, "requires": { - "@jridgewell/sourcemap-codec": "^1.4.13" + "@jridgewell/sourcemap-codec": "^1.4.15" } }, "minimatch": { From 5b9e54477d92c07852e6fee5a8f18d1c9b506897 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 19:05:11 +0200 Subject: [PATCH 0558/1076] build(deps-dev): bump @typescript-eslint/parser from 6.7.5 to 6.8.0 in /stake-pool/js (#5570) build(deps-dev): bump @typescript-eslint/parser in /stake-pool/js Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.7.5 to 6.8.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.8.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 145 +++++++++++++++++++++++++--- 1 file changed, 131 insertions(+), 14 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 88f90431..66e2425b 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -2119,15 +2119,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.5.tgz", - "integrity": "sha512-bIZVSGx2UME/lmhLcjdVc7ePBwn7CLqKarUBL4me1C5feOd663liTGjMBGVcGr+BhnSLeP4SgwdvNnnkbIdkCw==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.8.0.tgz", + "integrity": "sha512-5tNs6Bw0j6BdWuP8Fx+VH4G9fEPDxnVI7yH1IAPkQH5RUtvKwRoqdecAPdQXv4rSOADAaz1LFBZvZG7VbXivSg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.7.5", - "@typescript-eslint/types": "6.7.5", - "@typescript-eslint/typescript-estree": "6.7.5", - "@typescript-eslint/visitor-keys": "6.7.5", + "@typescript-eslint/scope-manager": "6.8.0", + "@typescript-eslint/types": "6.8.0", + "@typescript-eslint/typescript-estree": "6.8.0", + "@typescript-eslint/visitor-keys": "6.8.0", "debug": "^4.3.4" }, "engines": { @@ -2146,6 +2146,80 @@ } } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.8.0.tgz", + "integrity": "sha512-xe0HNBVwCph7rak+ZHcFD6A+q50SMsFwcmfdjs9Kz4qDh5hWhaPhFjRs/SODEhroBI5Ruyvyz9LfwUJ624O40g==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.8.0", + "@typescript-eslint/visitor-keys": "6.8.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.8.0.tgz", + "integrity": "sha512-p5qOxSum7W3k+llc7owEStXlGmSl8FcGvhYt8Vjy7FqEnmkCVlM3P57XQEGj58oqaBWDQXbJDZxwUWMS/EAPNQ==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.8.0.tgz", + "integrity": "sha512-ISgV0lQ8XgW+mvv5My/+iTUdRmGspducmQcDw5JxznasXNnZn3SKNrTRuMsEXv+V/O+Lw9AGcQCfVaOPCAk/Zg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.8.0", + "@typescript-eslint/visitor-keys": "6.8.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.8.0.tgz", + "integrity": "sha512-oqAnbA7c+pgOhW2OhGvxm0t1BULX5peQI/rLsNDpGM78EebV3C9IGbX5HNZabuZ6UQrYveCLjKo8Iy/lLlBkkg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.8.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "6.7.5", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.5.tgz", @@ -8821,16 +8895,59 @@ } }, "@typescript-eslint/parser": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.5.tgz", - "integrity": "sha512-bIZVSGx2UME/lmhLcjdVc7ePBwn7CLqKarUBL4me1C5feOd663liTGjMBGVcGr+BhnSLeP4SgwdvNnnkbIdkCw==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.8.0.tgz", + "integrity": "sha512-5tNs6Bw0j6BdWuP8Fx+VH4G9fEPDxnVI7yH1IAPkQH5RUtvKwRoqdecAPdQXv4rSOADAaz1LFBZvZG7VbXivSg==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "6.7.5", - "@typescript-eslint/types": "6.7.5", - "@typescript-eslint/typescript-estree": "6.7.5", - "@typescript-eslint/visitor-keys": "6.7.5", + "@typescript-eslint/scope-manager": "6.8.0", + "@typescript-eslint/types": "6.8.0", + "@typescript-eslint/typescript-estree": "6.8.0", + "@typescript-eslint/visitor-keys": "6.8.0", "debug": "^4.3.4" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.8.0.tgz", + "integrity": "sha512-xe0HNBVwCph7rak+ZHcFD6A+q50SMsFwcmfdjs9Kz4qDh5hWhaPhFjRs/SODEhroBI5Ruyvyz9LfwUJ624O40g==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.8.0", + "@typescript-eslint/visitor-keys": "6.8.0" + } + }, + "@typescript-eslint/types": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.8.0.tgz", + "integrity": "sha512-p5qOxSum7W3k+llc7owEStXlGmSl8FcGvhYt8Vjy7FqEnmkCVlM3P57XQEGj58oqaBWDQXbJDZxwUWMS/EAPNQ==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.8.0.tgz", + "integrity": "sha512-ISgV0lQ8XgW+mvv5My/+iTUdRmGspducmQcDw5JxznasXNnZn3SKNrTRuMsEXv+V/O+Lw9AGcQCfVaOPCAk/Zg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.8.0", + "@typescript-eslint/visitor-keys": "6.8.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.8.0.tgz", + "integrity": "sha512-oqAnbA7c+pgOhW2OhGvxm0t1BULX5peQI/rLsNDpGM78EebV3C9IGbX5HNZabuZ6UQrYveCLjKo8Iy/lLlBkkg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.8.0", + "eslint-visitor-keys": "^3.4.1" + } + } } }, "@typescript-eslint/scope-manager": { From f374ca5b75b35c1cba99d70f4dd4889d2425dd5f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 19:07:05 +0200 Subject: [PATCH 0559/1076] build(deps): bump @coral-xyz/borsh from 0.28.0 to 0.29.0 in /stake-pool/js (#5572) build(deps): bump @coral-xyz/borsh in /stake-pool/js Bumps @coral-xyz/borsh from 0.28.0 to 0.29.0. --- updated-dependencies: - dependency-name: "@coral-xyz/borsh" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 14 +++++++------- clients/js-legacy/package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 66e2425b..169804aa 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -9,7 +9,7 @@ "version": "0.7.0", "license": "ISC", "dependencies": { - "@coral-xyz/borsh": "^0.28.0", + "@coral-xyz/borsh": "^0.29.0", "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "^0.3.7", "@solana/web3.js": "^1.76.0", @@ -713,9 +713,9 @@ "dev": true }, "node_modules/@coral-xyz/borsh": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.28.0.tgz", - "integrity": "sha512-/u1VTzw7XooK7rqeD7JLUSwOyRSesPUk0U37BV9zK0axJc1q0nRbKFGFLYCQ16OtdOJTTwGfGp11Lx9B45bRCQ==", + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.29.0.tgz", + "integrity": "sha512-s7VFVa3a0oqpkuRloWVPdCK7hMbAMY270geZOGfCnaqexrP5dTIpbEHL33req6IYPPJ0hYa71cdvJ1h6V55/oQ==", "dependencies": { "bn.js": "^5.1.2", "buffer-layout": "^1.2.0" @@ -7872,9 +7872,9 @@ "dev": true }, "@coral-xyz/borsh": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.28.0.tgz", - "integrity": "sha512-/u1VTzw7XooK7rqeD7JLUSwOyRSesPUk0U37BV9zK0axJc1q0nRbKFGFLYCQ16OtdOJTTwGfGp11Lx9B45bRCQ==", + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.29.0.tgz", + "integrity": "sha512-s7VFVa3a0oqpkuRloWVPdCK7hMbAMY270geZOGfCnaqexrP5dTIpbEHL33req6IYPPJ0hYa71cdvJ1h6V55/oQ==", "requires": { "bn.js": "^5.1.2", "buffer-layout": "^1.2.0" diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index b2cb5faa..86391ce3 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -44,7 +44,7 @@ ], "license": "ISC", "dependencies": { - "@coral-xyz/borsh": "^0.28.0", + "@coral-xyz/borsh": "^0.29.0", "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "^0.3.7", "@solana/web3.js": "^1.76.0", From 1f0dd97335a730088d37823e6a11625d55c15891 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 19:59:53 +0200 Subject: [PATCH 0560/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.7.5 to 6.8.0 in /stake-pool/js (#5571) build(deps-dev): bump @typescript-eslint/eslint-plugin in /stake-pool/js Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.7.5 to 6.8.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.8.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 249 ++++++++-------------------- 1 file changed, 66 insertions(+), 183 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 169804aa..ab2fa47e 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -2084,16 +2084,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.5.tgz", - "integrity": "sha512-JhtAwTRhOUcP96D0Y6KYnwig/MRQbOoLGXTON2+LlyB/N35SP9j1boai2zzwXb7ypKELXMx3DVk9UTaEq1vHEw==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.8.0.tgz", + "integrity": "sha512-GosF4238Tkes2SHPQ1i8f6rMtG6zlKwMEB0abqSJ3Npvos+doIlc/ATG+vX1G9coDF3Ex78zM3heXHLyWEwLUw==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.7.5", - "@typescript-eslint/type-utils": "6.7.5", - "@typescript-eslint/utils": "6.7.5", - "@typescript-eslint/visitor-keys": "6.7.5", + "@typescript-eslint/scope-manager": "6.8.0", + "@typescript-eslint/type-utils": "6.8.0", + "@typescript-eslint/utils": "6.8.0", + "@typescript-eslint/visitor-keys": "6.8.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -2146,7 +2146,7 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "node_modules/@typescript-eslint/scope-manager": { "version": "6.8.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.8.0.tgz", "integrity": "sha512-xe0HNBVwCph7rak+ZHcFD6A+q50SMsFwcmfdjs9Kz4qDh5hWhaPhFjRs/SODEhroBI5Ruyvyz9LfwUJ624O40g==", @@ -2163,88 +2163,14 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.8.0.tgz", - "integrity": "sha512-p5qOxSum7W3k+llc7owEStXlGmSl8FcGvhYt8Vjy7FqEnmkCVlM3P57XQEGj58oqaBWDQXbJDZxwUWMS/EAPNQ==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.8.0.tgz", - "integrity": "sha512-ISgV0lQ8XgW+mvv5My/+iTUdRmGspducmQcDw5JxznasXNnZn3SKNrTRuMsEXv+V/O+Lw9AGcQCfVaOPCAk/Zg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.8.0", - "@typescript-eslint/visitor-keys": "6.8.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.8.0.tgz", - "integrity": "sha512-oqAnbA7c+pgOhW2OhGvxm0t1BULX5peQI/rLsNDpGM78EebV3C9IGbX5HNZabuZ6UQrYveCLjKo8Iy/lLlBkkg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.8.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.5.tgz", - "integrity": "sha512-GAlk3eQIwWOJeb9F7MKQ6Jbah/vx1zETSDw8likab/eFcqkjSD7BI75SDAeC5N2L0MmConMoPvTsmkrg71+B1A==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.7.5", - "@typescript-eslint/visitor-keys": "6.7.5" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.5.tgz", - "integrity": "sha512-Gs0qos5wqxnQrvpYv+pf3XfcRXW6jiAn9zE/K+DlmYf6FcpxeNYN0AIETaPR7rHO4K2UY+D0CIbDP9Ut0U4m1g==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.8.0.tgz", + "integrity": "sha512-RYOJdlkTJIXW7GSldUIHqc/Hkto8E+fZN96dMIFhuTJcQwdRoGN2rEWA8U6oXbLo0qufH7NPElUb+MceHtz54g==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.7.5", - "@typescript-eslint/utils": "6.7.5", + "@typescript-eslint/typescript-estree": "6.8.0", + "@typescript-eslint/utils": "6.8.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -2265,9 +2191,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.5.tgz", - "integrity": "sha512-WboQBlOXtdj1tDFPyIthpKrUb+kZf2VroLZhxKa/VlwLlLyqv/PwUNgL30BlTVZV1Wu4Asu2mMYPqarSO4L5ZQ==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.8.0.tgz", + "integrity": "sha512-p5qOxSum7W3k+llc7owEStXlGmSl8FcGvhYt8Vjy7FqEnmkCVlM3P57XQEGj58oqaBWDQXbJDZxwUWMS/EAPNQ==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -2278,13 +2204,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.5.tgz", - "integrity": "sha512-NhJiJ4KdtwBIxrKl0BqG1Ur+uw7FiOnOThcYx9DpOGJ/Abc9z2xNzLeirCG02Ig3vkvrc2qFLmYSSsaITbKjlg==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.8.0.tgz", + "integrity": "sha512-ISgV0lQ8XgW+mvv5My/+iTUdRmGspducmQcDw5JxznasXNnZn3SKNrTRuMsEXv+V/O+Lw9AGcQCfVaOPCAk/Zg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.7.5", - "@typescript-eslint/visitor-keys": "6.7.5", + "@typescript-eslint/types": "6.8.0", + "@typescript-eslint/visitor-keys": "6.8.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2305,17 +2231,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.5.tgz", - "integrity": "sha512-pfRRrH20thJbzPPlPc4j0UNGvH1PjPlhlCMq4Yx7EGjV7lvEeGX0U6MJYe8+SyFutWgSHsdbJ3BXzZccYggezA==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.8.0.tgz", + "integrity": "sha512-dKs1itdE2qFG4jr0dlYLQVppqTE+Itt7GmIf/vX6CSvsW+3ov8PbWauVKyyfNngokhIO9sKZeRGCUo1+N7U98Q==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.7.5", - "@typescript-eslint/types": "6.7.5", - "@typescript-eslint/typescript-estree": "6.7.5", + "@typescript-eslint/scope-manager": "6.8.0", + "@typescript-eslint/types": "6.8.0", + "@typescript-eslint/typescript-estree": "6.8.0", "semver": "^7.5.4" }, "engines": { @@ -2330,12 +2256,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.5.tgz", - "integrity": "sha512-3MaWdDZtLlsexZzDSdQWsFQ9l9nL8B80Z4fImSpyllFC/KLqWQRdEcB+gGGO+N3Q2uL40EsG66wZLsohPxNXvg==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.8.0.tgz", + "integrity": "sha512-oqAnbA7c+pgOhW2OhGvxm0t1BULX5peQI/rLsNDpGM78EebV3C9IGbX5HNZabuZ6UQrYveCLjKo8Iy/lLlBkkg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.7.5", + "@typescript-eslint/types": "6.8.0", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -8876,16 +8802,16 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.5.tgz", - "integrity": "sha512-JhtAwTRhOUcP96D0Y6KYnwig/MRQbOoLGXTON2+LlyB/N35SP9j1boai2zzwXb7ypKELXMx3DVk9UTaEq1vHEw==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.8.0.tgz", + "integrity": "sha512-GosF4238Tkes2SHPQ1i8f6rMtG6zlKwMEB0abqSJ3Npvos+doIlc/ATG+vX1G9coDF3Ex78zM3heXHLyWEwLUw==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.7.5", - "@typescript-eslint/type-utils": "6.7.5", - "@typescript-eslint/utils": "6.7.5", - "@typescript-eslint/visitor-keys": "6.7.5", + "@typescript-eslint/scope-manager": "6.8.0", + "@typescript-eslint/type-utils": "6.8.0", + "@typescript-eslint/utils": "6.8.0", + "@typescript-eslint/visitor-keys": "6.8.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -8905,87 +8831,44 @@ "@typescript-eslint/typescript-estree": "6.8.0", "@typescript-eslint/visitor-keys": "6.8.0", "debug": "^4.3.4" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.8.0.tgz", - "integrity": "sha512-xe0HNBVwCph7rak+ZHcFD6A+q50SMsFwcmfdjs9Kz4qDh5hWhaPhFjRs/SODEhroBI5Ruyvyz9LfwUJ624O40g==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.8.0", - "@typescript-eslint/visitor-keys": "6.8.0" - } - }, - "@typescript-eslint/types": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.8.0.tgz", - "integrity": "sha512-p5qOxSum7W3k+llc7owEStXlGmSl8FcGvhYt8Vjy7FqEnmkCVlM3P57XQEGj58oqaBWDQXbJDZxwUWMS/EAPNQ==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.8.0.tgz", - "integrity": "sha512-ISgV0lQ8XgW+mvv5My/+iTUdRmGspducmQcDw5JxznasXNnZn3SKNrTRuMsEXv+V/O+Lw9AGcQCfVaOPCAk/Zg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.8.0", - "@typescript-eslint/visitor-keys": "6.8.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.8.0.tgz", - "integrity": "sha512-oqAnbA7c+pgOhW2OhGvxm0t1BULX5peQI/rLsNDpGM78EebV3C9IGbX5HNZabuZ6UQrYveCLjKo8Iy/lLlBkkg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.8.0", - "eslint-visitor-keys": "^3.4.1" - } - } } }, "@typescript-eslint/scope-manager": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.5.tgz", - "integrity": "sha512-GAlk3eQIwWOJeb9F7MKQ6Jbah/vx1zETSDw8likab/eFcqkjSD7BI75SDAeC5N2L0MmConMoPvTsmkrg71+B1A==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.8.0.tgz", + "integrity": "sha512-xe0HNBVwCph7rak+ZHcFD6A+q50SMsFwcmfdjs9Kz4qDh5hWhaPhFjRs/SODEhroBI5Ruyvyz9LfwUJ624O40g==", "dev": true, "requires": { - "@typescript-eslint/types": "6.7.5", - "@typescript-eslint/visitor-keys": "6.7.5" + "@typescript-eslint/types": "6.8.0", + "@typescript-eslint/visitor-keys": "6.8.0" } }, "@typescript-eslint/type-utils": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.5.tgz", - "integrity": "sha512-Gs0qos5wqxnQrvpYv+pf3XfcRXW6jiAn9zE/K+DlmYf6FcpxeNYN0AIETaPR7rHO4K2UY+D0CIbDP9Ut0U4m1g==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.8.0.tgz", + "integrity": "sha512-RYOJdlkTJIXW7GSldUIHqc/Hkto8E+fZN96dMIFhuTJcQwdRoGN2rEWA8U6oXbLo0qufH7NPElUb+MceHtz54g==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "6.7.5", - "@typescript-eslint/utils": "6.7.5", + "@typescript-eslint/typescript-estree": "6.8.0", + "@typescript-eslint/utils": "6.8.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" } }, "@typescript-eslint/types": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.5.tgz", - "integrity": "sha512-WboQBlOXtdj1tDFPyIthpKrUb+kZf2VroLZhxKa/VlwLlLyqv/PwUNgL30BlTVZV1Wu4Asu2mMYPqarSO4L5ZQ==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.8.0.tgz", + "integrity": "sha512-p5qOxSum7W3k+llc7owEStXlGmSl8FcGvhYt8Vjy7FqEnmkCVlM3P57XQEGj58oqaBWDQXbJDZxwUWMS/EAPNQ==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.5.tgz", - "integrity": "sha512-NhJiJ4KdtwBIxrKl0BqG1Ur+uw7FiOnOThcYx9DpOGJ/Abc9z2xNzLeirCG02Ig3vkvrc2qFLmYSSsaITbKjlg==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.8.0.tgz", + "integrity": "sha512-ISgV0lQ8XgW+mvv5My/+iTUdRmGspducmQcDw5JxznasXNnZn3SKNrTRuMsEXv+V/O+Lw9AGcQCfVaOPCAk/Zg==", "dev": true, "requires": { - "@typescript-eslint/types": "6.7.5", - "@typescript-eslint/visitor-keys": "6.7.5", + "@typescript-eslint/types": "6.8.0", + "@typescript-eslint/visitor-keys": "6.8.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -8994,27 +8877,27 @@ } }, "@typescript-eslint/utils": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.5.tgz", - "integrity": "sha512-pfRRrH20thJbzPPlPc4j0UNGvH1PjPlhlCMq4Yx7EGjV7lvEeGX0U6MJYe8+SyFutWgSHsdbJ3BXzZccYggezA==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.8.0.tgz", + "integrity": "sha512-dKs1itdE2qFG4jr0dlYLQVppqTE+Itt7GmIf/vX6CSvsW+3ov8PbWauVKyyfNngokhIO9sKZeRGCUo1+N7U98Q==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.7.5", - "@typescript-eslint/types": "6.7.5", - "@typescript-eslint/typescript-estree": "6.7.5", + "@typescript-eslint/scope-manager": "6.8.0", + "@typescript-eslint/types": "6.8.0", + "@typescript-eslint/typescript-estree": "6.8.0", "semver": "^7.5.4" } }, "@typescript-eslint/visitor-keys": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.5.tgz", - "integrity": "sha512-3MaWdDZtLlsexZzDSdQWsFQ9l9nL8B80Z4fImSpyllFC/KLqWQRdEcB+gGGO+N3Q2uL40EsG66wZLsohPxNXvg==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.8.0.tgz", + "integrity": "sha512-oqAnbA7c+pgOhW2OhGvxm0t1BULX5peQI/rLsNDpGM78EebV3C9IGbX5HNZabuZ6UQrYveCLjKo8Iy/lLlBkkg==", "dev": true, "requires": { - "@typescript-eslint/types": "6.7.5", + "@typescript-eslint/types": "6.8.0", "eslint-visitor-keys": "^3.4.1" } }, From c8edfae96f3332b9a8588735cc17056d82dd31cb Mon Sep 17 00:00:00 2001 From: hanako mumei <81144685+2501babe@users.noreply.github.com> Date: Mon, 16 Oct 2023 07:38:06 -0700 Subject: [PATCH 0561/1076] single-pool: rename program to spl_single_pool --- program/src/inline_mpl_token_metadata.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/src/inline_mpl_token_metadata.rs b/program/src/inline_mpl_token_metadata.rs index ab42602e..4de593e3 100644 --- a/program/src/inline_mpl_token_metadata.rs +++ b/program/src/inline_mpl_token_metadata.rs @@ -1,5 +1,5 @@ //! Inlined MPL metadata types to avoid a direct dependency on `mpl-token-metadata' -//! NOTE: this file is sym-linked in `spl-single-validator-pool`, so be careful +//! NOTE: this file is sym-linked in `spl-single-pool`, so be careful //! with changes! solana_program::declare_id!("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"); From 8668a2bd930ba722061a619d2d0fe20e3dec5a7f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Oct 2023 02:34:40 +0200 Subject: [PATCH 0562/1076] build(deps): bump urllib3 from 1.26.17 to 1.26.18 in /stake-pool/py (#5577) Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.26.17 to 1.26.18. - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst) - [Commits](https://github.com/urllib3/urllib3/compare/1.26.17...1.26.18) --- updated-dependencies: - dependency-name: urllib3 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/py/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/py/requirements.txt b/clients/py/requirements.txt index 3d939426..b14e6920 100644 --- a/clients/py/requirements.txt +++ b/clients/py/requirements.txt @@ -16,4 +16,4 @@ rfc3986==1.5.0 sniffio==1.2.0 solana==0.18.1 typing_extensions==4.3.0 -urllib3==1.26.17 +urllib3==1.26.18 From dadc81674ff401d92b391e862c11925eb032fdce Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Oct 2023 17:10:57 +0200 Subject: [PATCH 0563/1076] build(deps-dev): bump @types/bn.js from 5.1.2 to 5.1.3 in /stake-pool/js (#5591) Bumps [@types/bn.js](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/bn.js) from 5.1.2 to 5.1.3. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/bn.js) --- updated-dependencies: - dependency-name: "@types/bn.js" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index ab2fa47e..c8fd1daf 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1933,9 +1933,9 @@ } }, "node_modules/@types/bn.js": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.2.tgz", - "integrity": "sha512-dkpZu0szUtn9UXTmw+e0AJFd4D2XAxDnsCLdc05SfqpqzPEBft8eQr8uaFitfo/dUUOZERaLec2hHMG87A4Dxg==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.3.tgz", + "integrity": "sha512-wT1B4iIO82ecXkdN6waCK8Ou7E71WU+mP1osDA5Q8c6Ur+ozU2vIKUIhSpUr6uE5L2YHocKS1Z2jG2fBC1YVeg==", "dev": true, "dependencies": { "@types/node": "*" @@ -8652,9 +8652,9 @@ } }, "@types/bn.js": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.2.tgz", - "integrity": "sha512-dkpZu0szUtn9UXTmw+e0AJFd4D2XAxDnsCLdc05SfqpqzPEBft8eQr8uaFitfo/dUUOZERaLec2hHMG87A4Dxg==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.3.tgz", + "integrity": "sha512-wT1B4iIO82ecXkdN6waCK8Ou7E71WU+mP1osDA5Q8c6Ur+ozU2vIKUIhSpUr6uE5L2YHocKS1Z2jG2fBC1YVeg==", "dev": true, "requires": { "@types/node": "*" From 5964d90fe295108fce3105a746928ad7a2bcb8d8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Oct 2023 21:46:54 +0200 Subject: [PATCH 0564/1076] build(deps-dev): bump @types/node-fetch from 2.6.6 to 2.6.7 in /stake-pool/js (#5590) build(deps-dev): bump @types/node-fetch in /stake-pool/js Bumps [@types/node-fetch](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node-fetch) from 2.6.6 to 2.6.7. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node-fetch) --- updated-dependencies: - dependency-name: "@types/node-fetch" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index c8fd1daf..a93e5f3d 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -2013,9 +2013,9 @@ } }, "node_modules/@types/node-fetch": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.6.tgz", - "integrity": "sha512-95X8guJYhfqiuVVhRFxVQcf4hW/2bCuoPwDasMf/531STFoNoWTT7YDnWdXHEZKqAGUigmpG31r2FE70LwnzJw==", + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-lX17GZVpJ/fuCjguZ5b3TjEbSENxmEk1B2z02yoXSK9WMEWRivhdSY73wWMn6bpcCDAOh6qAdktpKHIlkDk2lg==", "dev": true, "dependencies": { "@types/node": "*", @@ -8732,9 +8732,9 @@ } }, "@types/node-fetch": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.6.tgz", - "integrity": "sha512-95X8guJYhfqiuVVhRFxVQcf4hW/2bCuoPwDasMf/531STFoNoWTT7YDnWdXHEZKqAGUigmpG31r2FE70LwnzJw==", + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-lX17GZVpJ/fuCjguZ5b3TjEbSENxmEk1B2z02yoXSK9WMEWRivhdSY73wWMn6bpcCDAOh6qAdktpKHIlkDk2lg==", "dev": true, "requires": { "@types/node": "*", From 43fbfb5b21da9430c9756b585f7fd740c0aba02b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Oct 2023 21:47:08 +0200 Subject: [PATCH 0565/1076] build(deps-dev): bump @types/node from 20.8.6 to 20.8.7 in /stake-pool/js (#5592) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.8.6 to 20.8.7. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index a93e5f3d..e80e90fc 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -2005,9 +2005,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.8.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.6.tgz", - "integrity": "sha512-eWO4K2Ji70QzKUqRy6oyJWUeB7+g2cRagT3T/nxYibYcT4y2BDL8lqolRXjTHmkZCdJfIPaY73KbJAZmcryxTQ==", + "version": "20.8.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.7.tgz", + "integrity": "sha512-21TKHHh3eUHIi2MloeptJWALuCu5H7HQTdTrWIFReA8ad+aggoX+lRes3ex7/FtpC+sVUpFMQ+QTfYr74mruiQ==", "dependencies": { "undici-types": "~5.25.1" } @@ -8724,9 +8724,9 @@ "dev": true }, "@types/node": { - "version": "20.8.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.6.tgz", - "integrity": "sha512-eWO4K2Ji70QzKUqRy6oyJWUeB7+g2cRagT3T/nxYibYcT4y2BDL8lqolRXjTHmkZCdJfIPaY73KbJAZmcryxTQ==", + "version": "20.8.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.7.tgz", + "integrity": "sha512-21TKHHh3eUHIi2MloeptJWALuCu5H7HQTdTrWIFReA8ad+aggoX+lRes3ex7/FtpC+sVUpFMQ+QTfYr74mruiQ==", "requires": { "undici-types": "~5.25.1" } From 6915da1405f3068671ae047f4adb9f9e8fb9f90f Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 19 Oct 2023 18:04:18 +0200 Subject: [PATCH 0566/1076] ci: Bump repo to Solana 1.17 (#5575) * Update workspace for new cargo resolver, remove ntapi patch * Update Rust versions * Update dependencies with `./update-solana-dependencies.sh 1.17.2` * Update lockfile * Fix build errors * Run clippy with `--fix` * concurrent-merkle-tree: Fix function to not use mutable ref * Replace StakeState with StakeStateV2 * governance: Fix clippy lint * governance: Fix unnecessary mut * Allow `clippy::items_after_module` * token: Make error tests clearer * token-2022: Fix private glob re-export * token-upgrade-cli: Replace validator with parser * single-pool-cli: Fix parsers * ci: Update clippy command * Update anchor version * token-metadata: Use `no-entrypoint` feature in token-2022 * ci: Add protobuf-compiler to build deps * discriminator-syn: *Don't* specify type of lib to build * ci: Blast directories in cargo-build-test * account-compression: Update build and lockfile * Update token-group and feature-gate * single-pool: revert WrongStakeStateV2 * stake-pool: revert WrongStakeStateV2 * stake-pool-py: revert StakeStateV2 --------- Co-authored-by: hanako mumei <81144685+2501babe@users.noreply.github.com> --- clients/cli/Cargo.toml | 18 +-- clients/cli/src/client.rs | 2 +- clients/cli/src/main.rs | 19 +-- clients/py/stake/state.py | 14 +-- .../py/tests/test_deposit_withdraw_stake.py | 4 +- program/Cargo.toml | 8 +- program/src/big_vec.rs | 6 +- program/src/error.rs | 4 +- program/src/processor.rs | 119 +++++++++--------- program/src/state.rs | 2 +- program/tests/create_pool_token_metadata.rs | 3 +- program/tests/decrease.rs | 23 ++-- program/tests/deposit.rs | 8 +- program/tests/deposit_authority.rs | 2 +- program/tests/deposit_edge_cases.rs | 4 +- program/tests/deposit_sol.rs | 2 +- program/tests/force_destake.rs | 17 +-- program/tests/helpers/mod.rs | 21 ++-- program/tests/huge_pool.rs | 2 +- program/tests/increase.rs | 21 ++-- program/tests/initialize.rs | 15 +-- program/tests/redelegate.rs | 22 ++-- program/tests/set_deposit_fee.rs | 2 +- program/tests/set_epoch_fee.rs | 2 +- program/tests/set_funding_authority.rs | 2 +- program/tests/set_manager.rs | 2 +- program/tests/set_preferred.rs | 2 +- program/tests/set_referral_fee.rs | 2 +- program/tests/set_staker.rs | 2 +- program/tests/set_withdrawal_fee.rs | 2 +- program/tests/update_pool_token_metadata.rs | 2 +- program/tests/update_stake_pool_balance.rs | 4 +- .../tests/update_validator_list_balance.rs | 10 +- .../update_validator_list_balance_hijack.rs | 8 +- program/tests/vsa_add.rs | 16 +-- program/tests/vsa_remove.rs | 8 +- program/tests/withdraw.rs | 2 +- program/tests/withdraw_edge_cases.rs | 16 +-- program/tests/withdraw_sol.rs | 4 +- program/tests/withdraw_with_fee.rs | 6 +- 40 files changed, 223 insertions(+), 205 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 4674b6b1..3aa8ab0d 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -14,15 +14,15 @@ clap = "2.33.3" serde = "1.0.189" serde_derive = "1.0.130" serde_json = "1.0.107" -solana-account-decoder = "=1.16.16" -solana-clap-utils = "=1.16.16" -solana-cli-config = "=1.16.16" -solana-cli-output = "=1.16.16" -solana-client = "=1.16.16" -solana-logger = "=1.16.16" -solana-program = "=1.16.16" -solana-remote-wallet = "=1.16.16" -solana-sdk = "=1.16.16" +solana-account-decoder = "=1.17.2" +solana-clap-utils = "=1.17.2" +solana-cli-config = "=1.17.2" +solana-cli-output = "=1.17.2" +solana-client = "=1.17.2" +solana-logger = "=1.17.2" +solana-program = "=1.17.2" +solana-remote-wallet = "=1.17.2" +solana-sdk = "=1.17.2" spl-associated-token-account = { version = "=2.2", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "=0.7.0", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "=4.0", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/clients/cli/src/client.rs b/clients/cli/src/client.rs index 444e4608..9deae1a8 100644 --- a/clients/cli/src/client.rs +++ b/clients/cli/src/client.rs @@ -73,7 +73,7 @@ pub fn get_token_mint( pub(crate) fn get_stake_state( rpc_client: &RpcClient, stake_address: &Pubkey, -) -> Result { +) -> Result { let account_data = rpc_client.get_account_data(stake_address)?; let stake_state = deserialize(account_data.as_slice()) .map_err(|err| format!("Invalid stake account {}: {}", stake_address, err))?; diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 37c8cb50..0edaafbc 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -1,4 +1,4 @@ -#![allow(clippy::integer_arithmetic)] +#![allow(clippy::arithmetic_side_effects)] mod client; mod output; @@ -51,7 +51,7 @@ use { MINIMUM_RESERVE_LAMPORTS, }, std::cmp::Ordering, - std::{num::NonZeroU32, process::exit, sync::Arc}, + std::{num::NonZeroU32, process::exit, rc::Rc}, }; // use instruction::create_associated_token_account once ATA 1.0.5 is released #[allow(deprecated)] @@ -127,7 +127,7 @@ fn get_signer( matches: &ArgMatches<'_>, keypair_name: &str, keypair_path: &str, - wallet_manager: &mut Option>, + wallet_manager: &mut Option>, signer_from_path_config: SignerFromPathConfig, ) -> Box { signer_from_path_with_config( @@ -683,7 +683,7 @@ fn command_deposit_stake( println!("Depositing stake account {:?}", stake_state); } let vote_account = match stake_state { - stake::state::StakeState::Stake(_, stake) => Ok(stake.delegation.voter_pubkey), + stake::state::StakeStateV2::Stake(_, stake, _) => Ok(stake.delegation.voter_pubkey), _ => Err("Wrong stake account state, must be delegated to validator"), }?; @@ -865,7 +865,7 @@ fn command_deposit_all_stake( let stake_state = get_stake_state(&config.rpc_client, &stake_address)?; let vote_account = match stake_state { - stake::state::StakeState::Stake(_, stake) => Ok(stake.delegation.voter_pubkey), + stake::state::StakeStateV2::Stake(_, stake, _) => Ok(stake.delegation.voter_pubkey), _ => Err("Wrong stake account state, must be delegated to validator"), }?; @@ -1399,9 +1399,12 @@ fn command_withdraw_stake( let maybe_stake_receiver_state = stake_receiver_param .map(|stake_receiver_pubkey| { let stake_account = config.rpc_client.get_account(&stake_receiver_pubkey).ok()?; - let stake_state: stake::state::StakeState = deserialize(stake_account.data.as_slice()) - .map_err(|err| format!("Invalid stake account {}: {}", stake_receiver_pubkey, err)) - .ok()?; + let stake_state: stake::state::StakeStateV2 = + deserialize(stake_account.data.as_slice()) + .map_err(|err| { + format!("Invalid stake account {}: {}", stake_receiver_pubkey, err) + }) + .ok()?; if stake_state.delegation().is_some() && stake_account.owner == stake::program::id() { Some(stake_state) } else { diff --git a/clients/py/stake/state.py b/clients/py/stake/state.py index 9ff48d34..8d8ac81f 100644 --- a/clients/py/stake/state.py +++ b/clients/py/stake/state.py @@ -48,7 +48,7 @@ class StakeAuthorize(IntEnum): WITHDRAWER = 1 -class StakeStateType(IntEnum): +class StakeStakeType(IntEnum): """Stake State Types.""" UNINITIALIZED = 0 INITIALIZED = 1 @@ -56,8 +56,8 @@ class StakeStateType(IntEnum): REWARDS_POOL = 3 -class StakeState(NamedTuple): - state_type: StakeStateType +class StakeStake(NamedTuple): + state_type: StakeStakeType state: Container """Stake state.""" @@ -65,7 +65,7 @@ class StakeState(NamedTuple): def decode(cls, data: str, encoding: str): data_bytes = decode_byte_string(data, encoding) parsed = STAKE_STATE_LAYOUT.parse(data_bytes) - return StakeState( + return StakeStake( state_type=parsed['state_type'], state=parsed['state'], ) @@ -122,9 +122,9 @@ def decode(cls, data: str, encoding: str): # Switch( # lambda this: this.state, # { - # StakeStateType.UNINITIALIZED: Pass, - # StakeStateType.INITIALIZED: META_LAYOUT, - # StakeStateType.STAKE: STAKE_AND_META_LAYOUT, + # StakeStakeType.UNINITIALIZED: Pass, + # StakeStakeType.INITIALIZED: META_LAYOUT, + # StakeStakeType.STAKE: STAKE_AND_META_LAYOUT, # } # ), # diff --git a/clients/py/tests/test_deposit_withdraw_stake.py b/clients/py/tests/test_deposit_withdraw_stake.py index 1580db24..890fb9d1 100644 --- a/clients/py/tests/test_deposit_withdraw_stake.py +++ b/clients/py/tests/test_deposit_withdraw_stake.py @@ -5,7 +5,7 @@ from stake.actions import create_stake, delegate_stake from stake.constants import STAKE_LEN -from stake.state import StakeState +from stake.state import StakeStake from stake_pool.actions import deposit_stake, withdraw_stake, update_stake_pool from stake_pool.constants import MINIMUM_ACTIVE_STAKE from stake_pool.state import StakePool @@ -25,7 +25,7 @@ async def test_deposit_withdraw_stake(async_client, validators, payer, stake_poo await delegate_stake(async_client, payer, payer, stake, validator) resp = await async_client.get_account_info(stake, commitment=Confirmed) data = resp['result']['value']['data'] - stake_state = StakeState.decode(data[0], data[1]) + stake_state = StakeStake.decode(data[0], data[1]) token_account = get_associated_token_address(payer.public_key, stake_pool.pool_mint) pre_pool_token_balance = await async_client.get_token_account_balance(token_account, Confirmed) pre_pool_token_balance = int(pre_pool_token_balance['result']['value']['amount']) diff --git a/program/Cargo.toml b/program/Cargo.toml index 0832372d..31f02250 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -20,7 +20,7 @@ num-traits = "0.2" num_enum = "0.7.0" serde = "1.0.189" serde_derive = "1.0.103" -solana-program = "1.16.16" +solana-program = "1.17.2" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-pod = { version = "0.1", path = "../../libraries/pod", features = ["borsh"] } spl-token-2022 = { version = "0.9", path = "../../token/program-2022", features = [ "no-entrypoint" ] } @@ -30,9 +30,9 @@ bincode = "1.3.1" [dev-dependencies] assert_matches = "1.5.0" proptest = "1.3" -solana-program-test = "1.16.16" -solana-sdk = "1.16.16" -solana-vote-program = "1.16.16" +solana-program-test = "1.17.2" +solana-sdk = "1.17.2" +solana-vote-program = "1.17.2" spl-token = { version = "4.0", path = "../../token/program", features = [ "no-entrypoint" ] } test-case = "3.2" diff --git a/program/src/big_vec.rs b/program/src/big_vec.rs index 3ba5afce..0d05f0ae 100644 --- a/program/src/big_vec.rs +++ b/program/src/big_vec.rs @@ -1,5 +1,5 @@ //! Big vector type, used with vectors that can't be serde'd -#![allow(clippy::integer_arithmetic)] // checked math involves too many compute units +#![allow(clippy::arithmetic_side_effects)] // checked math involves too many compute units use { arrayref::array_ref, @@ -271,7 +271,7 @@ mod tests { fn find_mut() { let mut data = [0u8; 4 + 8 * 4]; let mut v = from_slice(&mut data, &[1, 2, 3, 4]); - let mut test_struct = v + let test_struct = v .find_mut::(|x| find_predicate(x, 1)) .unwrap(); test_struct.value = [0; 8]; @@ -283,7 +283,7 @@ mod tests { fn deserialize_mut_slice() { let mut data = [0u8; 4 + 8 * 4]; let mut v = from_slice(&mut data, &[1, 2, 3, 4]); - let mut slice = v.deserialize_mut_slice::(1, 2).unwrap(); + let slice = v.deserialize_mut_slice::(1, 2).unwrap(); slice[0].value[0] = 10; slice[1].value[0] = 11; check_big_vec_eq(&v, &[1, 10, 11, 4]); diff --git a/program/src/error.rs b/program/src/error.rs index 83bcb1a0..afeaeaf4 100644 --- a/program/src/error.rs +++ b/program/src/error.rs @@ -48,8 +48,8 @@ pub enum StakePoolError { #[error("WrongPoolMint")] WrongPoolMint, /// Stake account is not in the state expected by the program. - #[error("WrongStakeState")] - WrongStakeState, + #[error("WrongStakeStake")] + WrongStakeStake, /// User stake is not active #[error("UserStakeNotActive")] UserStakeNotActive, diff --git a/program/src/processor.rs b/program/src/processor.rs index abf5a67c..b25ec780 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -50,10 +50,10 @@ fn get_stake_state( stake_account_info: &AccountInfo, ) -> Result<(stake::state::Meta, stake::state::Stake), ProgramError> { let stake_state = - try_from_slice_unchecked::(&stake_account_info.data.borrow())?; + try_from_slice_unchecked::(&stake_account_info.data.borrow())?; match stake_state { - stake::state::StakeState::Stake(meta, stake) => Ok((meta, stake)), - _ => Err(StakePoolError::WrongStakeState.into()), + stake::state::StakeStateV2::Stake(meta, stake, _) => Ok((meta, stake)), + _ => Err(StakePoolError::WrongStakeStake.into()), } } @@ -224,7 +224,7 @@ fn check_if_stake_deactivating( vote_account_address, epoch, ); - Err(StakePoolError::WrongStakeState.into()) + Err(StakePoolError::WrongStakeStake.into()) } else { Ok(()) } @@ -246,7 +246,7 @@ fn check_if_stake_activating( vote_account_address, epoch, ); - Err(StakePoolError::WrongStakeState.into()) + Err(StakePoolError::WrongStakeStake.into()) } else { Ok(()) } @@ -266,7 +266,7 @@ fn check_stake_state( "Validator stake for {} not usable by pool, must be owned by withdraw authority", vote_account_address ); - return Err(StakePoolError::WrongStakeState.into()); + return Err(StakePoolError::WrongStakeStake.into()); } if stake.delegation.voter_pubkey != *vote_account_address { msg!( @@ -274,7 +274,7 @@ fn check_stake_state( stake_account_info.key, vote_account_address ); - return Err(StakePoolError::WrongStakeState.into()); + return Err(StakePoolError::WrongStakeStake.into()); } Ok(()) } @@ -863,13 +863,13 @@ impl Processor { msg!("Reserve stake account not owned by stake program"); return Err(ProgramError::IncorrectProgramId); } - let stake_state = try_from_slice_unchecked::( + let stake_state = try_from_slice_unchecked::( &reserve_stake_info.data.borrow(), )?; - let total_lamports = if let stake::state::StakeState::Initialized(meta) = stake_state { + let total_lamports = if let stake::state::StakeStateV2::Initialized(meta) = stake_state { if meta.lockup != stake::state::Lockup::default() { msg!("Reserve stake account has some lockup"); - return Err(StakePoolError::WrongStakeState.into()); + return Err(StakePoolError::WrongStakeStake.into()); } if meta.authorized.staker != withdraw_authority_key { @@ -878,7 +878,7 @@ impl Processor { meta.authorized.staker, withdraw_authority_key ); - return Err(StakePoolError::WrongStakeState.into()); + return Err(StakePoolError::WrongStakeStake.into()); } if meta.authorized.withdrawer != withdraw_authority_key { @@ -887,7 +887,7 @@ impl Processor { meta.authorized.staker, withdraw_authority_key ); - return Err(StakePoolError::WrongStakeState.into()); + return Err(StakePoolError::WrongStakeStake.into()); } reserve_stake_info .lamports() @@ -895,7 +895,7 @@ impl Processor { .ok_or(StakePoolError::CalculationFailure)? } else { msg!("Reserve stake account not in intialized state"); - return Err(StakePoolError::WrongStakeState.into()); + return Err(StakePoolError::WrongStakeStake.into()); }; if total_lamports > 0 { @@ -1036,18 +1036,18 @@ impl Processor { ]; // Fund the stake account with the minimum + rent-exempt balance - let stake_space = std::mem::size_of::(); + let stake_space = std::mem::size_of::(); let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; let required_lamports = minimum_delegation(stake_minimum_delegation) .saturating_add(rent.minimum_balance(stake_space)); // Check that we're not draining the reserve totally - let reserve_stake = try_from_slice_unchecked::( + let reserve_stake = try_from_slice_unchecked::( &reserve_stake_info.data.borrow(), )?; let reserve_meta = reserve_stake .meta() - .ok_or(StakePoolError::WrongStakeState)?; + .ok_or(StakePoolError::WrongStakeStake)?; let minimum_lamports = minimum_reserve_lamports(&reserve_meta); let reserve_lamports = reserve_stake_info.lamports(); if reserve_lamports.saturating_sub(required_lamports) < minimum_lamports { @@ -1161,7 +1161,7 @@ impl Processor { ); return Err(StakePoolError::ValidatorNotFound.into()); } - let mut validator_stake_info = maybe_validator_stake_info.unwrap(); + let validator_stake_info = maybe_validator_stake_info.unwrap(); check_validator_stake_address( program_id, stake_pool_info.key, @@ -1319,7 +1319,7 @@ impl Processor { ); return Err(StakePoolError::ValidatorNotFound.into()); } - let mut validator_stake_info = maybe_validator_stake_info.unwrap(); + let validator_stake_info = maybe_validator_stake_info.unwrap(); check_validator_stake_address( program_id, stake_pool_info.key, @@ -1346,7 +1346,7 @@ impl Processor { )?; } - let stake_space = std::mem::size_of::(); + let stake_space = std::mem::size_of::(); let stake_rent = rent.minimum_balance(stake_space); let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; @@ -1633,7 +1633,7 @@ impl Processor { ); return Err(StakePoolError::ValidatorNotFound.into()); } - let mut validator_stake_info = maybe_validator_stake_info.unwrap(); + let validator_stake_info = maybe_validator_stake_info.unwrap(); if u64::from(validator_stake_info.transient_stake_lamports) > 0 { if maybe_ephemeral_stake_seed.is_none() { msg!("Attempting to increase stake on a validator with pending transient stake, use IncreaseAdditionalValidatorStake with the existing seed"); @@ -1668,7 +1668,7 @@ impl Processor { return Err(StakePoolError::ValidatorNotFound.into()); } - let stake_space = std::mem::size_of::(); + let stake_space = std::mem::size_of::(); let stake_rent = rent.minimum_balance(stake_space); let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; let current_minimum_delegation = minimum_delegation(stake_minimum_delegation); @@ -1805,12 +1805,12 @@ impl Processor { )?; // Activate transient stake to validator if necessary - let stake_state = try_from_slice_unchecked::( + let stake_state = try_from_slice_unchecked::( &transient_stake_account_info.data.borrow(), )?; match stake_state { // if it was delegated on or before this epoch, we're good - stake::state::StakeState::Stake(_, stake) + stake::state::StakeStateV2::Stake(_, stake, _) if stake.delegation.activation_epoch <= clock.epoch => {} // all other situations, delegate! _ => { @@ -1901,7 +1901,7 @@ impl Processor { } let rent = Rent::get()?; - let stake_space = std::mem::size_of::(); + let stake_space = std::mem::size_of::(); let stake_rent = rent.minimum_balance(stake_space); let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; let current_minimum_delegation = minimum_delegation(stake_minimum_delegation); @@ -1957,7 +1957,7 @@ impl Processor { ); return Err(StakePoolError::ValidatorNotFound.into()); } - let mut validator_stake_info = maybe_validator_stake_info.unwrap(); + let validator_stake_info = maybe_validator_stake_info.unwrap(); check_validator_stake_address( program_id, stake_pool_info.key, @@ -2080,7 +2080,7 @@ impl Processor { ); return Err(StakePoolError::ValidatorNotFound.into()); } - let mut validator_stake_info = maybe_validator_stake_info.unwrap(); + let validator_stake_info = maybe_validator_stake_info.unwrap(); check_validator_stake_account( destination_validator_stake_account_info, program_id, @@ -2333,11 +2333,11 @@ impl Processor { let mut active_stake_lamports = 0; let mut transient_stake_lamports = 0; - let validator_stake_state = try_from_slice_unchecked::( + let validator_stake_state = try_from_slice_unchecked::( &validator_stake_info.data.borrow(), ) .ok(); - let transient_stake_state = try_from_slice_unchecked::( + let transient_stake_state = try_from_slice_unchecked::( &transient_stake_info.data.borrow(), ) .ok(); @@ -2349,7 +2349,7 @@ impl Processor { // * inactive -> merge into reserve stake // * not a stake -> ignore match transient_stake_state { - Some(stake::state::StakeState::Initialized(meta)) => { + Some(stake::state::StakeStateV2::Initialized(meta)) => { if stake_is_usable_by_pool( &meta, withdraw_authority_info.key, @@ -2373,7 +2373,7 @@ impl Processor { } } } - Some(stake::state::StakeState::Stake(meta, stake)) => { + Some(stake::state::StakeStateV2::Stake(meta, stake, _)) => { if stake_is_usable_by_pool( &meta, withdraw_authority_info.key, @@ -2395,7 +2395,7 @@ impl Processor { )?; validator_stake_record.status.remove_transient_stake()?; } else if stake.delegation.activation_epoch < clock.epoch { - if let Some(stake::state::StakeState::Stake(_, validator_stake)) = + if let Some(stake::state::StakeStateV2::Stake(_, validator_stake, _)) = validator_stake_state { if validator_stake.delegation.activation_epoch < clock.epoch { @@ -2424,19 +2424,19 @@ impl Processor { } } None - | Some(stake::state::StakeState::Uninitialized) - | Some(stake::state::StakeState::RewardsPool) => {} // do nothing + | Some(stake::state::StakeStateV2::Uninitialized) + | Some(stake::state::StakeStateV2::RewardsPool) => {} // do nothing } // Status for validator stake // * active -> do everything // * any other state / not a stake -> error state, but account for transient stake - let validator_stake_state = try_from_slice_unchecked::( + let validator_stake_state = try_from_slice_unchecked::( &validator_stake_info.data.borrow(), ) .ok(); match validator_stake_state { - Some(stake::state::StakeState::Stake(meta, stake)) => { + Some(stake::state::StakeStateV2::Stake(meta, stake, _)) => { let additional_lamports = validator_stake_info .lamports() .saturating_sub(stake.delegation.stake) @@ -2494,7 +2494,7 @@ impl Processor { } } } - Some(stake::state::StakeState::Initialized(meta)) + Some(stake::state::StakeStateV2::Initialized(meta)) if stake_is_usable_by_pool( &meta, withdraw_authority_info.key, @@ -2517,9 +2517,9 @@ impl Processor { )?; validator_stake_record.status.remove_validator_stake()?; } - Some(stake::state::StakeState::Initialized(_)) - | Some(stake::state::StakeState::Uninitialized) - | Some(stake::state::StakeState::RewardsPool) + Some(stake::state::StakeStateV2::Initialized(_)) + | Some(stake::state::StakeStateV2::Uninitialized) + | Some(stake::state::StakeStateV2::RewardsPool) | None => { msg!("Validator stake account no longer part of the pool, ignoring"); } @@ -2578,19 +2578,19 @@ impl Processor { let previous_lamports = stake_pool.total_lamports; let previous_pool_token_supply = stake_pool.pool_token_supply; - let reserve_stake = try_from_slice_unchecked::( + let reserve_stake = try_from_slice_unchecked::( &reserve_stake_info.data.borrow(), )?; - let mut total_lamports = if let stake::state::StakeState::Initialized(meta) = reserve_stake - { - reserve_stake_info - .lamports() - .checked_sub(minimum_reserve_lamports(&meta)) - .ok_or(StakePoolError::CalculationFailure)? - } else { - msg!("Reserve stake account in unknown state, aborting"); - return Err(StakePoolError::WrongStakeState.into()); - }; + let mut total_lamports = + if let stake::state::StakeStateV2::Initialized(meta) = reserve_stake { + reserve_stake_info + .lamports() + .checked_sub(minimum_reserve_lamports(&meta)) + .ok_or(StakePoolError::CalculationFailure)? + } else { + msg!("Reserve stake account in unknown state, aborting"); + return Err(StakePoolError::WrongStakeStake.into()); + }; for validator_stake_record in validator_list .deserialize_slice::(0, validator_list.len() as usize)? { @@ -2767,7 +2767,7 @@ impl Processor { } } - let mut validator_stake_info = validator_list + let validator_stake_info = validator_list .find_mut::(|x| { ValidatorStakeInfo::memcmp_pubkey(x, &vote_account_address) }) @@ -3188,9 +3188,10 @@ impl Processor { } let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; - let stake_state = - try_from_slice_unchecked::(&stake_split_from.data.borrow())?; - let meta = stake_state.meta().ok_or(StakePoolError::WrongStakeState)?; + let stake_state = try_from_slice_unchecked::( + &stake_split_from.data.borrow(), + )?; + let meta = stake_state.meta().ok_or(StakePoolError::WrongStakeStake)?; let required_lamports = minimum_stake_lamports(&meta, stake_minimum_delegation); let lamports_per_pool_token = stake_pool @@ -3232,7 +3233,7 @@ impl Processor { } else { let delegation = stake_state .delegation() - .ok_or(StakePoolError::WrongStakeState)?; + .ok_or(StakePoolError::WrongStakeStake)?; let vote_account_address = delegation.voter_pubkey; if let Some(preferred_withdraw_validator) = @@ -3498,10 +3499,10 @@ impl Processor { let new_reserve_lamports = reserve_stake_info .lamports() .saturating_sub(withdraw_lamports); - let stake_state = try_from_slice_unchecked::( + let stake_state = try_from_slice_unchecked::( &reserve_stake_info.data.borrow(), )?; - if let stake::state::StakeState::Initialized(meta) = stake_state { + if let stake::state::StakeStateV2::Initialized(meta) = stake_state { let minimum_reserve_lamports = minimum_reserve_lamports(&meta); if new_reserve_lamports < minimum_reserve_lamports { msg!("Attempting to withdraw {} lamports, maximum possible SOL withdrawal is {} lamports", @@ -3512,7 +3513,7 @@ impl Processor { } } else { msg!("Reserve stake account not in intialized state"); - return Err(StakePoolError::WrongStakeState.into()); + return Err(StakePoolError::WrongStakeStake.into()); }; Self::token_burn( @@ -4083,7 +4084,7 @@ impl PrintProgramError for StakePoolError { StakePoolError::InvalidValidatorStakeList => msg!("Error: Invalid validator stake list account"), StakePoolError::InvalidFeeAccount => msg!("Error: Invalid manager fee account"), StakePoolError::WrongPoolMint => msg!("Error: Specified pool mint account is wrong"), - StakePoolError::WrongStakeState => msg!("Error: Stake account is not in the state expected by the program"), + StakePoolError::WrongStakeStake => msg!("Error: Stake account is not in the state expected by the program"), StakePoolError::UserStakeNotActive => msg!("Error: User stake is not active"), StakePoolError::ValidatorAlreadyAdded => msg!("Error: Stake account voting for this validator already exists in the pool"), StakePoolError::ValidatorNotFound => msg!("Error: Stake account for this validator not found in the pool"), diff --git a/program/src/state.rs b/program/src/state.rs index 7d12add0..b218cecd 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -1030,7 +1030,7 @@ impl FeeType { #[cfg(test)] mod test { - #![allow(clippy::integer_arithmetic)] + #![allow(clippy::arithmetic_side_effects)] use { super::*, proptest::prelude::*, diff --git a/program/tests/create_pool_token_metadata.rs b/program/tests/create_pool_token_metadata.rs index 7734c785..147e3928 100644 --- a/program/tests/create_pool_token_metadata.rs +++ b/program/tests/create_pool_token_metadata.rs @@ -1,4 +1,5 @@ -#![allow(clippy::integer_arithmetic)] +#![allow(clippy::arithmetic_side_effects)] +#![allow(clippy::items_after_test_module)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/decrease.rs b/program/tests/decrease.rs index c6ea4542..fe6398ae 100644 --- a/program/tests/decrease.rs +++ b/program/tests/decrease.rs @@ -1,4 +1,5 @@ -#![allow(clippy::integer_arithmetic)] +#![allow(clippy::arithmetic_side_effects)] +#![allow(clippy::items_after_test_module)] #![cfg(feature = "test-sbf")] mod helpers; @@ -30,7 +31,7 @@ async fn setup() -> ( ) { let mut context = program_test().start_with_context().await; let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let current_minimum_delegation = stake_pool_get_minimum_delegation( &mut context.banks_client, &context.payer, @@ -125,7 +126,7 @@ async fn success(instruction_type: DecreaseInstruction) { let validator_stake_account = get_account(&mut context.banks_client, &validator_stake.stake_account).await; let validator_stake_state = - deserialize::(&validator_stake_account.data).unwrap(); + deserialize::(&validator_stake_account.data).unwrap(); assert_eq!( pre_validator_stake_account.lamports - decrease_lamports, validator_stake_account.lamports @@ -140,7 +141,7 @@ async fn success(instruction_type: DecreaseInstruction) { // Check transient stake account state and balance let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let transient_stake_account = get_account( &mut context.banks_client, @@ -148,7 +149,7 @@ async fn success(instruction_type: DecreaseInstruction) { ) .await; let transient_stake_state = - deserialize::(&transient_stake_account.data).unwrap(); + deserialize::(&transient_stake_account.data).unwrap(); let transient_lamports = decrease_lamports + stake_rent; assert_eq!(transient_stake_account.lamports, transient_lamports); let reserve_lamports = if instruction_type == DecreaseInstruction::Deprecated { @@ -390,7 +391,7 @@ async fn twice( get_account(&mut context.banks_client, &validator_stake.stake_account).await; let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let first_decrease = decrease_lamports / 3; let second_decrease = decrease_lamports / 2; @@ -441,7 +442,7 @@ async fn twice( // Check validator stake account balance let stake_account = get_account(&mut context.banks_client, &validator_stake.stake_account).await; - let stake_state = deserialize::(&stake_account.data).unwrap(); + let stake_state = deserialize::(&stake_account.data).unwrap(); assert_eq!( pre_stake_account.lamports - total_decrease, stake_account.lamports @@ -458,7 +459,7 @@ async fn twice( ) .await; let transient_stake_state = - deserialize::(&transient_stake_account.data).unwrap(); + deserialize::(&transient_stake_account.data).unwrap(); let mut transient_lamports = total_decrease + stake_rent; if second_instruction == DecreaseInstruction::Additional { transient_lamports += stake_rent; @@ -514,7 +515,7 @@ async fn fail_with_small_lamport_amount(instruction_type: DecreaseInstruction) { setup().await; let rent = context.banks_client.get_rent().await.unwrap(); - let lamports = rent.minimum_balance(std::mem::size_of::()); + let lamports = rent.minimum_balance(std::mem::size_of::()); let error = stake_pool_accounts .decrease_validator_stake_either( @@ -575,7 +576,7 @@ async fn fail_overdraw(instruction_type: DecreaseInstruction) { setup().await; let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let error = stake_pool_accounts .decrease_validator_stake_either( @@ -662,6 +663,6 @@ async fn fail_additional_with_increasing() { TransactionError::InstructionError( _, InstructionError::Custom(code) - ) if code == StakePoolError::WrongStakeState as u32 + ) if code == StakePoolError::WrongStakeStake as u32 ); } diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 2bd29b40..74e96194 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -1,4 +1,4 @@ -#![allow(clippy::integer_arithmetic)] +#![allow(clippy::arithmetic_side_effects)] #![cfg(feature = "test-sbf")] mod helpers; @@ -140,7 +140,7 @@ async fn success(token_program_id: Pubkey) { ) = setup(token_program_id).await; let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); // Save stake pool state before depositing let pre_stake_pool = get_account( @@ -312,7 +312,7 @@ async fn success_with_extra_stake_lamports() { .await; let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); // Save stake pool state before depositing let pre_stake_pool = get_account( @@ -821,7 +821,7 @@ async fn success_with_slippage(token_program_id: Pubkey) { ) = setup(token_program_id).await; let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); // Save stake pool state before depositing let pre_stake_pool = get_account( diff --git a/program/tests/deposit_authority.rs b/program/tests/deposit_authority.rs index 55665572..9d64f6da 100644 --- a/program/tests/deposit_authority.rs +++ b/program/tests/deposit_authority.rs @@ -1,4 +1,4 @@ -#![allow(clippy::integer_arithmetic)] +#![allow(clippy::arithmetic_side_effects)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/deposit_edge_cases.rs b/program/tests/deposit_edge_cases.rs index bd549805..86ae9c27 100644 --- a/program/tests/deposit_edge_cases.rs +++ b/program/tests/deposit_edge_cases.rs @@ -1,4 +1,4 @@ -#![allow(clippy::integer_arithmetic)] +#![allow(clippy::arithmetic_side_effects)] #![cfg(feature = "test-sbf")] mod helpers; @@ -274,7 +274,7 @@ async fn success_with_referral_fee() { let stake_pool = try_from_slice_unchecked::(stake_pool.data.as_slice()).unwrap(); let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let fee_tokens = stake_pool .calc_pool_tokens_sol_deposit_fee(stake_rent) .unwrap() diff --git a/program/tests/deposit_sol.rs b/program/tests/deposit_sol.rs index 7fefde70..bc983520 100644 --- a/program/tests/deposit_sol.rs +++ b/program/tests/deposit_sol.rs @@ -1,4 +1,4 @@ -#![allow(clippy::integer_arithmetic)] +#![allow(clippy::arithmetic_side_effects)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/force_destake.rs b/program/tests/force_destake.rs index 5becdbe8..f54bd02d 100644 --- a/program/tests/force_destake.rs +++ b/program/tests/force_destake.rs @@ -1,4 +1,4 @@ -#![allow(clippy::integer_arithmetic)] +#![allow(clippy::arithmetic_side_effects)] #![cfg(feature = "test-sbf")] mod helpers; @@ -11,7 +11,8 @@ use { pubkey::Pubkey, stake::{ self, - state::{Authorized, Delegation, Lockup, Meta, Stake, StakeState}, + stake_flags::StakeFlags, + state::{Authorized, Delegation, Lockup, Meta, Stake, StakeStateV2}, }, }, solana_program_test::*, @@ -32,7 +33,7 @@ use { async fn setup( stake_pool_accounts: &StakePoolAccounts, - forced_stake: &StakeState, + forced_stake: &StakeStateV2, voter_pubkey: &Pubkey, ) -> (ProgramTestContext, Option) { let mut program_test = program_test(); @@ -41,7 +42,7 @@ async fn setup( let (mut stake_pool, mut validator_list) = stake_pool_accounts.state(); let _ = add_vote_account_with_pubkey(voter_pubkey, &mut program_test); - let mut data = vec![0; std::mem::size_of::()]; + let mut data = vec![0; std::mem::size_of::()]; bincode::serialize_into(&mut data[..], forced_stake).unwrap(); let stake_account = Account::create( @@ -124,7 +125,7 @@ async fn success_update() { let voter_pubkey = Pubkey::new_unique(); let (mut context, validator_seed) = setup( &stake_pool_accounts, - &StakeState::Initialized(meta), + &StakeStateV2::Initialized(meta), &voter_pubkey, ) .await; @@ -193,7 +194,7 @@ async fn fail_increase() { let voter_pubkey = Pubkey::new_unique(); let (mut context, validator_seed) = setup( &stake_pool_accounts, - &StakeState::Initialized(meta), + &StakeStateV2::Initialized(meta), &voter_pubkey, ) .await; @@ -229,7 +230,7 @@ async fn fail_increase() { error, TransactionError::InstructionError( 0, - InstructionError::Custom(StakePoolError::WrongStakeState as u32) + InstructionError::Custom(StakePoolError::WrongStakeStake as u32) ) ); } @@ -258,7 +259,7 @@ async fn success_remove_validator() { }; let (mut context, validator_seed) = setup( &stake_pool_accounts, - &StakeState::Stake(meta, stake), + &StakeStateV2::Stake(meta, stake, StakeFlags::empty()), &voter_pubkey, ) .await; diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index a72c6cb2..0bf6c1e1 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -651,7 +651,7 @@ pub async fn create_independent_stake_account( ) -> u64 { let rent = banks_client.get_rent().await.unwrap(); let lamports = - rent.minimum_balance(std::mem::size_of::()) + stake_amount; + rent.minimum_balance(std::mem::size_of::()) + stake_amount; let transaction = Transaction::new_signed_with_payer( &stake::instruction::create_account( @@ -677,14 +677,14 @@ pub async fn create_blank_stake_account( stake: &Keypair, ) -> u64 { let rent = banks_client.get_rent().await.unwrap(); - let lamports = rent.minimum_balance(std::mem::size_of::()); + let lamports = rent.minimum_balance(std::mem::size_of::()); let transaction = Transaction::new_signed_with_payer( &[system_instruction::create_account( &payer.pubkey(), &stake.pubkey(), lamports, - std::mem::size_of::() as u64, + std::mem::size_of::() as u64, &stake::program::id(), )], Some(&payer.pubkey()), @@ -2122,7 +2122,7 @@ pub async fn simple_add_validator_to_pool( ); let rent = banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let current_minimum_delegation = stake_pool_get_minimum_delegation(banks_client, payer, recent_blockhash).await; @@ -2380,7 +2380,7 @@ pub async fn get_validator_list_sum( .map(|info| info.stake_lamports().unwrap()) .sum(); let rent = banks_client.get_rent().await.unwrap(); - let rent = rent.minimum_balance(std::mem::size_of::()); + let rent = rent.minimum_balance(std::mem::size_of::()); validator_sum + reserve_stake.lamports - rent - MINIMUM_RESERVE_LAMPORTS } @@ -2451,8 +2451,13 @@ pub fn add_validator_stake_account( credits_observed: 0, }; - let mut data = vec![0u8; std::mem::size_of::()]; - let stake_data = bincode::serialize(&stake::state::StakeState::Stake(meta, stake)).unwrap(); + let mut data = vec![0u8; std::mem::size_of::()]; + let stake_data = bincode::serialize(&stake::state::StakeStateV2::Stake( + meta, + stake, + stake::stake_flags::StakeFlags::empty(), + )) + .unwrap(); data[..stake_data.len()].copy_from_slice(&stake_data); let stake_account = SolanaAccount::create( stake_amount + STAKE_ACCOUNT_RENT_EXEMPTION, @@ -2505,7 +2510,7 @@ pub fn add_reserve_stake_account( }; let reserve_stake_account = SolanaAccount::create( stake_amount + STAKE_ACCOUNT_RENT_EXEMPTION, - bincode::serialize::(&stake::state::StakeState::Initialized( + bincode::serialize::(&stake::state::StakeStateV2::Initialized( meta, )) .unwrap(), diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index 1fd94683..ccfa5370 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -1,4 +1,4 @@ -#![allow(clippy::integer_arithmetic)] +#![allow(clippy::arithmetic_side_effects)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/increase.rs b/program/tests/increase.rs index 22612372..bd83885e 100644 --- a/program/tests/increase.rs +++ b/program/tests/increase.rs @@ -1,4 +1,5 @@ -#![allow(clippy::integer_arithmetic)] +#![allow(clippy::arithmetic_side_effects)] +#![allow(clippy::items_after_test_module)] #![cfg(feature = "test-sbf")] mod helpers; @@ -55,7 +56,7 @@ async fn setup() -> ( ) .await; let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let _deposit_info = simple_deposit_stake( &mut context.banks_client, @@ -98,7 +99,7 @@ async fn success(use_additional_instruction: bool) { assert!(transient_account.is_none()); let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let increase_amount = reserve_lamports - stake_rent - MINIMUM_RESERVE_LAMPORTS; let error = stake_pool_accounts .increase_validator_stake_either( @@ -122,7 +123,7 @@ async fn success(use_additional_instruction: bool) { ) .await; let reserve_stake_state = - deserialize::(&reserve_stake_account.data).unwrap(); + deserialize::(&reserve_stake_account.data).unwrap(); assert_eq!( pre_reserve_stake_account.lamports - increase_amount - stake_rent, reserve_stake_account.lamports @@ -136,7 +137,7 @@ async fn success(use_additional_instruction: bool) { ) .await; let transient_stake_state = - deserialize::(&transient_stake_account.data).unwrap(); + deserialize::(&transient_stake_account.data).unwrap(); assert_eq!( transient_stake_account.lamports, increase_amount + stake_rent @@ -389,7 +390,7 @@ async fn twice(success: bool, use_additional_first_time: bool, use_additional_se if success { assert!(error.is_none(), "{:?}", error); let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); // no ephemeral account let ephemeral_stake = find_ephemeral_stake_program_address( &id(), @@ -410,7 +411,7 @@ async fn twice(success: bool, use_additional_first_time: bool, use_additional_se ) .await; let reserve_stake_state = - deserialize::(&reserve_stake_account.data).unwrap(); + deserialize::(&reserve_stake_account.data).unwrap(); assert_eq!( pre_reserve_stake_account.lamports - total_increase - stake_rent * 2, reserve_stake_account.lamports @@ -424,7 +425,7 @@ async fn twice(success: bool, use_additional_first_time: bool, use_additional_se ) .await; let transient_stake_state = - deserialize::(&transient_stake_account.data).unwrap(); + deserialize::(&transient_stake_account.data).unwrap(); assert_eq!( transient_stake_account.lamports, total_increase + stake_rent * 2 @@ -532,7 +533,7 @@ async fn fail_additional_with_decreasing() { ) .await; let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); // warp forward to activation let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot; @@ -586,7 +587,7 @@ async fn fail_additional_with_decreasing() { error, TransactionError::InstructionError( 0, - InstructionError::Custom(StakePoolError::WrongStakeState as u32) + InstructionError::Custom(StakePoolError::WrongStakeStake as u32) ) ); } diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index 5d0baba6..109d5273 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -1,4 +1,5 @@ -#![allow(clippy::integer_arithmetic)] +#![allow(clippy::arithmetic_side_effects)] +#![allow(clippy::items_after_test_module)] #![cfg(feature = "test-sbf")] mod helpers; @@ -1412,7 +1413,7 @@ async fn fail_with_bad_reserve() { error, TransactionError::InstructionError( 2, - InstructionError::Custom(error::StakePoolError::WrongStakeState as u32), + InstructionError::Custom(error::StakePoolError::WrongStakeStake as u32), ) ); } @@ -1464,7 +1465,7 @@ async fn fail_with_bad_reserve() { error, TransactionError::InstructionError( 2, - InstructionError::Custom(error::StakePoolError::WrongStakeState as u32), + InstructionError::Custom(error::StakePoolError::WrongStakeStake as u32), ) ); } @@ -1519,7 +1520,7 @@ async fn fail_with_bad_reserve() { error, TransactionError::InstructionError( 2, - InstructionError::Custom(error::StakePoolError::WrongStakeState as u32), + InstructionError::Custom(error::StakePoolError::WrongStakeStake as u32), ) ); } @@ -1527,7 +1528,7 @@ async fn fail_with_bad_reserve() { { let bad_stake = Keypair::new(); let rent = banks_client.get_rent().await.unwrap(); - let lamports = rent.minimum_balance(std::mem::size_of::()) + let lamports = rent.minimum_balance(std::mem::size_of::()) + MINIMUM_RESERVE_LAMPORTS; let transaction = Transaction::new_signed_with_payer( @@ -1535,7 +1536,7 @@ async fn fail_with_bad_reserve() { &payer.pubkey(), &bad_stake.pubkey(), lamports, - std::mem::size_of::() as u64, + std::mem::size_of::() as u64, &stake::program::id(), )], Some(&payer.pubkey()), @@ -1575,7 +1576,7 @@ async fn fail_with_bad_reserve() { error, TransactionError::InstructionError( 2, - InstructionError::Custom(error::StakePoolError::WrongStakeState as u32), + InstructionError::Custom(error::StakePoolError::WrongStakeStake as u32), ) ); } diff --git a/program/tests/redelegate.rs b/program/tests/redelegate.rs index 0fc70db6..47dc08a4 100644 --- a/program/tests/redelegate.rs +++ b/program/tests/redelegate.rs @@ -1,4 +1,4 @@ -#![allow(clippy::integer_arithmetic)] +#![allow(clippy::arithmetic_side_effects)] #![cfg(feature = "test-sbf")] mod helpers; @@ -34,7 +34,7 @@ async fn setup( ) { let mut context = program_test().start_with_context().await; let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let current_minimum_delegation = stake_pool_get_minimum_delegation( &mut context.banks_client, &context.payer, @@ -185,7 +185,7 @@ async fn success() { ) .await; let validator_stake_state = - deserialize::(&validator_stake_account.data).unwrap(); + deserialize::(&validator_stake_account.data).unwrap(); assert_eq!( pre_validator_stake_account.lamports - redelegate_lamports, validator_stake_account.lamports @@ -200,7 +200,7 @@ async fn success() { // Check source transient stake account state and balance let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let source_transient_stake_account = get_account( &mut context.banks_client, @@ -208,7 +208,7 @@ async fn success() { ) .await; let transient_stake_state = - deserialize::(&source_transient_stake_account.data).unwrap(); + deserialize::(&source_transient_stake_account.data).unwrap(); assert_eq!(source_transient_stake_account.lamports, stake_rent); let transient_delegation = transient_stake_state.delegation().unwrap(); assert_ne!(transient_delegation.deactivation_epoch, Epoch::MAX); @@ -244,7 +244,8 @@ async fn success() { ) .await; let transient_stake_state = - deserialize::(&destination_transient_stake_account.data).unwrap(); + deserialize::(&destination_transient_stake_account.data) + .unwrap(); assert_eq!( destination_transient_stake_account.lamports, redelegate_lamports @@ -386,7 +387,7 @@ async fn success_with_increasing_stake() { ) .await; let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let error = stake_pool_accounts .increase_validator_stake( @@ -499,7 +500,8 @@ async fn success_with_increasing_stake() { ) .await; let transient_stake_state = - deserialize::(&destination_transient_stake_account.data).unwrap(); + deserialize::(&destination_transient_stake_account.data) + .unwrap(); assert_eq!( destination_transient_stake_account.lamports, redelegate_lamports + current_minimum_delegation + stake_rent @@ -615,7 +617,7 @@ async fn fail_with_decreasing_stake() { ) .await; let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let minimum_decrease_lamports = current_minimum_delegation + stake_rent; simple_deposit_stake( @@ -695,7 +697,7 @@ async fn fail_with_decreasing_stake() { error, TransactionError::InstructionError( 0, - InstructionError::Custom(StakePoolError::WrongStakeState as u32) + InstructionError::Custom(StakePoolError::WrongStakeStake as u32) ) ); } diff --git a/program/tests/set_deposit_fee.rs b/program/tests/set_deposit_fee.rs index b8cbd286..6cd6f63d 100644 --- a/program/tests/set_deposit_fee.rs +++ b/program/tests/set_deposit_fee.rs @@ -1,4 +1,4 @@ -#![allow(clippy::integer_arithmetic)] +#![allow(clippy::arithmetic_side_effects)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/set_epoch_fee.rs b/program/tests/set_epoch_fee.rs index ccdb6b8d..db3b039a 100644 --- a/program/tests/set_epoch_fee.rs +++ b/program/tests/set_epoch_fee.rs @@ -1,4 +1,4 @@ -#![allow(clippy::integer_arithmetic)] +#![allow(clippy::arithmetic_side_effects)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/set_funding_authority.rs b/program/tests/set_funding_authority.rs index 6e091562..e8729691 100644 --- a/program/tests/set_funding_authority.rs +++ b/program/tests/set_funding_authority.rs @@ -1,4 +1,4 @@ -#![allow(clippy::integer_arithmetic)] +#![allow(clippy::arithmetic_side_effects)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/set_manager.rs b/program/tests/set_manager.rs index 0e3416e0..e0163e84 100644 --- a/program/tests/set_manager.rs +++ b/program/tests/set_manager.rs @@ -1,4 +1,4 @@ -#![allow(clippy::integer_arithmetic)] +#![allow(clippy::arithmetic_side_effects)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/set_preferred.rs b/program/tests/set_preferred.rs index fffd9bc2..13a93ace 100644 --- a/program/tests/set_preferred.rs +++ b/program/tests/set_preferred.rs @@ -1,4 +1,4 @@ -#![allow(clippy::integer_arithmetic)] +#![allow(clippy::arithmetic_side_effects)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/set_referral_fee.rs b/program/tests/set_referral_fee.rs index 93c22560..45d3ced9 100644 --- a/program/tests/set_referral_fee.rs +++ b/program/tests/set_referral_fee.rs @@ -1,4 +1,4 @@ -#![allow(clippy::integer_arithmetic)] +#![allow(clippy::arithmetic_side_effects)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/set_staker.rs b/program/tests/set_staker.rs index f2a72fe3..30d3d491 100644 --- a/program/tests/set_staker.rs +++ b/program/tests/set_staker.rs @@ -1,4 +1,4 @@ -#![allow(clippy::integer_arithmetic)] +#![allow(clippy::arithmetic_side_effects)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/set_withdrawal_fee.rs b/program/tests/set_withdrawal_fee.rs index 1d510636..5c548b0a 100644 --- a/program/tests/set_withdrawal_fee.rs +++ b/program/tests/set_withdrawal_fee.rs @@ -1,4 +1,4 @@ -#![allow(clippy::integer_arithmetic)] +#![allow(clippy::arithmetic_side_effects)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/update_pool_token_metadata.rs b/program/tests/update_pool_token_metadata.rs index cfa5a3b9..efe30a96 100644 --- a/program/tests/update_pool_token_metadata.rs +++ b/program/tests/update_pool_token_metadata.rs @@ -1,4 +1,4 @@ -#![allow(clippy::integer_arithmetic)] +#![allow(clippy::arithmetic_side_effects)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/update_stake_pool_balance.rs b/program/tests/update_stake_pool_balance.rs index 77612bf2..50f9c3ee 100644 --- a/program/tests/update_stake_pool_balance.rs +++ b/program/tests/update_stake_pool_balance.rs @@ -1,4 +1,4 @@ -#![allow(clippy::integer_arithmetic)] +#![allow(clippy::arithmetic_side_effects)] #![cfg(feature = "test-sbf")] mod helpers; @@ -42,7 +42,7 @@ async fn setup( .unwrap(); let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let current_minimum_delegation = stake_pool_get_minimum_delegation( &mut context.banks_client, &context.payer, diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index 831ad30d..bfc6b7e0 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -1,4 +1,4 @@ -#![allow(clippy::integer_arithmetic)] +#![allow(clippy::arithmetic_side_effects)] #![cfg(feature = "test-sbf")] mod helpers; @@ -7,7 +7,7 @@ use { helpers::*, solana_program::{borsh0_10::try_from_slice_unchecked, program_pack::Pack, pubkey::Pubkey}, solana_program_test::*, - solana_sdk::{hash::Hash, signature::Signer, stake::state::StakeState}, + solana_sdk::{hash::Hash, signature::Signer, stake::state::StakeStateV2}, spl_stake_pool::{ state::{StakePool, StakeStatus, ValidatorList}, MAX_VALIDATORS_TO_UPDATE, MINIMUM_RESERVE_LAMPORTS, @@ -183,7 +183,7 @@ async fn success_with_normal() { // Check current balance in the list let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let stake_pool_info = get_account( &mut context.banks_client, &stake_pool_accounts.stake_pool.pubkey(), @@ -395,7 +395,7 @@ async fn merge_into_validator_stake() { .await; // Increase stake to all validators - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let current_minimum_delegation = stake_pool_get_minimum_delegation( &mut context.banks_client, &context.payer, @@ -544,7 +544,7 @@ async fn merge_transient_stake_after_remove() { ) = setup(1).await; let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let current_minimum_delegation = stake_pool_get_minimum_delegation( &mut context.banks_client, &context.payer, diff --git a/program/tests/update_validator_list_balance_hijack.rs b/program/tests/update_validator_list_balance_hijack.rs index feb05248..ad444b20 100644 --- a/program/tests/update_validator_list_balance_hijack.rs +++ b/program/tests/update_validator_list_balance_hijack.rs @@ -1,4 +1,4 @@ -#![allow(clippy::integer_arithmetic)] +#![allow(clippy::arithmetic_side_effects)] #![cfg(feature = "test-sbf")] mod helpers; @@ -11,7 +11,7 @@ use { hash::Hash, instruction::InstructionError, signature::Signer, - stake::state::{Authorized, Lockup, StakeState}, + stake::state::{Authorized, Lockup, StakeStateV2}, system_instruction, transaction::{Transaction, TransactionError}, }, @@ -206,7 +206,7 @@ async fn check_ignored_hijacked_transient_stake( ) = setup(num_validators).await; let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let pre_lamports = get_validator_list_sum( &mut context.banks_client, @@ -372,7 +372,7 @@ async fn check_ignored_hijacked_validator_stake( ) = setup(num_validators).await; let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let pre_lamports = get_validator_list_sum( &mut context.banks_client, diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index 36eb0490..e32a7623 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -1,4 +1,4 @@ -#![allow(clippy::integer_arithmetic)] +#![allow(clippy::arithmetic_side_effects)] #![cfg(feature = "test-sbf")] mod helpers; @@ -37,7 +37,7 @@ async fn setup( ) { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let rent = banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let current_minimum_delegation = stake_pool_get_minimum_delegation(&mut banks_client, &payer, &recent_blockhash).await; let minimum_for_validator = stake_rent + current_minimum_delegation; @@ -99,7 +99,7 @@ async fn success() { let validator_list = try_from_slice_unchecked::(validator_list.data.as_slice()).unwrap(); let rent = banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let current_minimum_delegation = stake_pool_get_minimum_delegation(&mut banks_client, &payer, &recent_blockhash).await; assert_eq!( @@ -128,9 +128,9 @@ async fn success() { // Check stake account existence and authority let stake = get_account(&mut banks_client, &validator_stake.stake_account).await; - let stake_state = deserialize::(&stake.data).unwrap(); + let stake_state = deserialize::(&stake.data).unwrap(); match stake_state { - stake::state::StakeState::Stake(meta, _) => { + stake::state::StakeStateV2::Stake(meta, _, _) => { assert_eq!( &meta.authorized.staker, &stake_pool_accounts.withdraw_authority @@ -434,7 +434,7 @@ async fn fail_with_wrong_system_program_id() { async fn fail_add_too_many_validator_stake_accounts() { let (mut banks_client, payer, recent_blockhash) = program_test().start().await; let rent = banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let current_minimum_delegation = stake_pool_get_minimum_delegation(&mut banks_client, &payer, &recent_blockhash).await; let minimum_for_validator = stake_rent + current_minimum_delegation; @@ -597,9 +597,9 @@ async fn success_with_lamports_in_account() { // Check stake account existence and authority let stake = get_account(&mut banks_client, &validator_stake.stake_account).await; - let stake_state = deserialize::(&stake.data).unwrap(); + let stake_state = deserialize::(&stake.data).unwrap(); match stake_state { - stake::state::StakeState::Stake(meta, _) => { + stake::state::StakeStateV2::Stake(meta, _, _) => { assert_eq!( &meta.authorized.staker, &stake_pool_accounts.withdraw_authority diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 80e87851..febada59 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -1,4 +1,4 @@ -#![allow(clippy::integer_arithmetic)] +#![allow(clippy::arithmetic_side_effects)] #![cfg(feature = "test-sbf")] mod helpers; @@ -425,7 +425,7 @@ async fn success_with_activating_transient_stake() { &validator_stake.transient_stake_account, ) .await; - let stake_state = deserialize::(&stake.data).unwrap(); + let stake_state = deserialize::(&stake.data).unwrap(); assert_ne!( stake_state.stake().unwrap().delegation.deactivation_epoch, u64::MAX @@ -437,7 +437,7 @@ async fn success_with_deactivating_transient_stake() { let (mut context, stake_pool_accounts, validator_stake) = setup().await; let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let current_minimum_delegation = stake_pool_get_minimum_delegation( &mut context.banks_client, &context.payer, @@ -667,7 +667,7 @@ async fn success_resets_preferred_validator() { async fn success_with_hijacked_transient_account() { let (mut context, stake_pool_accounts, validator_stake) = setup().await; let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let current_minimum_delegation = stake_pool_get_minimum_delegation( &mut context.banks_client, &context.payer, diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 1baddb17..c0154cbd 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -1,4 +1,4 @@ -#![allow(clippy::integer_arithmetic)] +#![allow(clippy::arithmetic_side_effects)] #![cfg(feature = "test-sbf")] mod helpers; diff --git a/program/tests/withdraw_edge_cases.rs b/program/tests/withdraw_edge_cases.rs index a2d1fd6c..4af70cba 100644 --- a/program/tests/withdraw_edge_cases.rs +++ b/program/tests/withdraw_edge_cases.rs @@ -1,4 +1,5 @@ -#![allow(clippy::integer_arithmetic)] +#![allow(clippy::arithmetic_side_effects)] +#![allow(clippy::items_after_test_module)] #![cfg(feature = "test-sbf")] mod helpers; @@ -123,7 +124,7 @@ async fn success_remove_validator(multiple: u64) { .await; let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let stake_pool = stake_pool_accounts .get_stake_pool(&mut context.banks_client) .await; @@ -312,7 +313,7 @@ async fn success_with_reserve() { ) = setup_for_withdraw(spl_token::id(), STAKE_ACCOUNT_RENT_EXEMPTION).await; let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); // decrease all of stake let error = stake_pool_accounts @@ -400,7 +401,8 @@ async fn success_with_reserve() { &stake_pool_accounts.reserve_stake.pubkey(), ) .await; - let stake_state = deserialize::(&reserve_stake_account.data).unwrap(); + let stake_state = + deserialize::(&reserve_stake_account.data).unwrap(); let meta = stake_state.meta().unwrap(); assert_eq!( meta.rent_exempt_reserve + withdrawal_fee + deposit_fee + stake_rent, @@ -606,7 +608,7 @@ async fn fail_withdraw_from_transient() { .unwrap(); let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); // decrease to minimum stake + 2 lamports let error = stake_pool_accounts @@ -688,7 +690,7 @@ async fn success_withdraw_from_transient() { .await; let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let last_blockhash = context .banks_client @@ -794,7 +796,7 @@ async fn success_with_small_preferred_withdraw() { // add a tiny bit of stake, less than lamports per pool token to preferred validator let rent = context.banks_client.get_rent().await.unwrap(); - let rent_exempt = rent.minimum_balance(std::mem::size_of::()); + let rent_exempt = rent.minimum_balance(std::mem::size_of::()); let stake_minimum_delegation = stake_get_minimum_delegation(&mut context.banks_client, &context.payer, &last_blockhash) .await; diff --git a/program/tests/withdraw_sol.rs b/program/tests/withdraw_sol.rs index 75c6594f..67b60a7a 100644 --- a/program/tests/withdraw_sol.rs +++ b/program/tests/withdraw_sol.rs @@ -1,4 +1,4 @@ -#![allow(clippy::integer_arithmetic)] +#![allow(clippy::arithmetic_side_effects)] #![cfg(feature = "test-sbf")] mod helpers; @@ -199,7 +199,7 @@ async fn fail_overdraw_reserve() { .await; let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); + let stake_rent = rent.minimum_balance(std::mem::size_of::()); let error = stake_pool_accounts .increase_validator_stake( &mut context.banks_client, diff --git a/program/tests/withdraw_with_fee.rs b/program/tests/withdraw_with_fee.rs index 34c28b92..b55283fb 100644 --- a/program/tests/withdraw_with_fee.rs +++ b/program/tests/withdraw_with_fee.rs @@ -1,4 +1,4 @@ -#![allow(clippy::integer_arithmetic)] +#![allow(clippy::arithmetic_side_effects)] #![cfg(feature = "test-sbf")] mod helpers; @@ -176,7 +176,7 @@ async fn success_empty_out_stake_with_fee() { ) .await; let stake_state = - deserialize::(&validator_stake_account.data).unwrap(); + deserialize::(&validator_stake_account.data).unwrap(); let meta = stake_state.meta().unwrap(); let stake_minimum_delegation = stake_get_minimum_delegation(&mut context.banks_client, &context.payer, &last_blockhash) @@ -226,7 +226,7 @@ async fn success_empty_out_stake_with_fee() { ) .await; let stake_state = - deserialize::(&validator_stake_account.data).unwrap(); + deserialize::(&validator_stake_account.data).unwrap(); let meta = stake_state.meta().unwrap(); assert_eq!( validator_stake_account.lamports, From a5bd796c5d22fbb45d82af3d1a260eeb3f59cd2c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Oct 2023 15:12:36 +0200 Subject: [PATCH 0567/1076] build(deps): bump @solana/web3.js from 1.87.1 to 1.87.2 in /stake-pool/js (#5623) build(deps): bump @solana/web3.js in /stake-pool/js Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.87.1 to 1.87.2. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.87.1...v1.87.2) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index e80e90fc..36f0581b 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1861,9 +1861,9 @@ } }, "node_modules/@solana/web3.js": { - "version": "1.87.1", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.87.1.tgz", - "integrity": "sha512-E8Y9bNlZ8TQlhOvCx1b7jG+TjA4SJLVwufmIk1+tcQctUhK5HiB1Q8ljd4yQDkFlk6OOeAlAeqvW0YntWJU94Q==", + "version": "1.87.2", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.87.2.tgz", + "integrity": "sha512-TZNhS+tvJbYjm0LAvIkUy/3Aqgt2l6/3X6XsVUpvj5MGOl2Q6Ch8hYSxcUUtMbAFNN3sUXmV8NhhMLNJEvI6TA==", "dependencies": { "@babel/runtime": "^7.22.6", "@noble/curves": "^1.2.0", @@ -8583,9 +8583,9 @@ } }, "@solana/web3.js": { - "version": "1.87.1", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.87.1.tgz", - "integrity": "sha512-E8Y9bNlZ8TQlhOvCx1b7jG+TjA4SJLVwufmIk1+tcQctUhK5HiB1Q8ljd4yQDkFlk6OOeAlAeqvW0YntWJU94Q==", + "version": "1.87.2", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.87.2.tgz", + "integrity": "sha512-TZNhS+tvJbYjm0LAvIkUy/3Aqgt2l6/3X6XsVUpvj5MGOl2Q6Ch8hYSxcUUtMbAFNN3sUXmV8NhhMLNJEvI6TA==", "requires": { "@babel/runtime": "^7.22.6", "@noble/curves": "^1.2.0", From d14c6bffb8dd289ceb15df6d87ea95c91ceab1d8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Oct 2023 15:28:01 +0200 Subject: [PATCH 0568/1076] build(deps-dev): bump eslint from 8.51.0 to 8.52.0 in /stake-pool/js (#5636) Bumps [eslint](https://github.com/eslint/eslint) from 8.51.0 to 8.52.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.51.0...v8.52.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 74 +++++++++++++++++------------ 1 file changed, 44 insertions(+), 30 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 36f0581b..772d46bb 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -775,21 +775,21 @@ } }, "node_modules/@eslint/js": { - "version": "8.51.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.51.0.tgz", - "integrity": "sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==", + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.52.0.tgz", + "integrity": "sha512-mjZVbpaeMZludF2fsWLD0Z9gCref1Tk4i9+wddjRvpUNqqcndPkBD09N/Mapey0b3jaXbLm2kICwFv2E64QinA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.11", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", - "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", + "@humanwhocodes/object-schema": "^2.0.1", "debug": "^4.1.1", "minimatch": "^3.0.5" }, @@ -811,9 +811,9 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", "dev": true }, "node_modules/@isaacs/cliui": { @@ -2272,6 +2272,12 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "node_modules/abab": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", @@ -3463,18 +3469,19 @@ } }, "node_modules/eslint": { - "version": "8.51.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.51.0.tgz", - "integrity": "sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==", + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.52.0.tgz", + "integrity": "sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.51.0", - "@humanwhocodes/config-array": "^0.11.11", + "@eslint/js": "8.52.0", + "@humanwhocodes/config-array": "^0.11.13", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -7839,18 +7846,18 @@ } }, "@eslint/js": { - "version": "8.51.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.51.0.tgz", - "integrity": "sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==", + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.52.0.tgz", + "integrity": "sha512-mjZVbpaeMZludF2fsWLD0Z9gCref1Tk4i9+wddjRvpUNqqcndPkBD09N/Mapey0b3jaXbLm2kICwFv2E64QinA==", "dev": true }, "@humanwhocodes/config-array": { - "version": "0.11.11", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", - "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", "dev": true, "requires": { - "@humanwhocodes/object-schema": "^1.2.1", + "@humanwhocodes/object-schema": "^2.0.1", "debug": "^4.1.1", "minimatch": "^3.0.5" } @@ -7862,9 +7869,9 @@ "dev": true }, "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", "dev": true }, "@isaacs/cliui": { @@ -8901,6 +8908,12 @@ "eslint-visitor-keys": "^3.4.1" } }, + "@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "abab": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", @@ -9768,18 +9781,19 @@ } }, "eslint": { - "version": "8.51.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.51.0.tgz", - "integrity": "sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==", + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.52.0.tgz", + "integrity": "sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.51.0", - "@humanwhocodes/config-array": "^0.11.11", + "@eslint/js": "8.52.0", + "@humanwhocodes/config-array": "^0.11.13", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", From 3fa8c230d8b39598c7f7c977966d244e795d54c2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Oct 2023 18:03:58 +0200 Subject: [PATCH 0569/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.8.0 to 6.9.0 in /stake-pool/js (#5652) build(deps-dev): bump @typescript-eslint/eslint-plugin in /stake-pool/js Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.8.0 to 6.9.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.9.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 378 ++++++++++++++++++++++++---- 1 file changed, 330 insertions(+), 48 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 772d46bb..5bf31914 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1999,9 +1999,9 @@ } }, "node_modules/@types/json-schema": { - "version": "7.0.13", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.13.tgz", - "integrity": "sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==", + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.14.tgz", + "integrity": "sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw==", "dev": true }, "node_modules/@types/node": { @@ -2049,9 +2049,9 @@ "dev": true }, "node_modules/@types/semver": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.3.tgz", - "integrity": "sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==", "dev": true }, "node_modules/@types/stack-utils": { @@ -2084,16 +2084,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.8.0.tgz", - "integrity": "sha512-GosF4238Tkes2SHPQ1i8f6rMtG6zlKwMEB0abqSJ3Npvos+doIlc/ATG+vX1G9coDF3Ex78zM3heXHLyWEwLUw==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.9.0.tgz", + "integrity": "sha512-lgX7F0azQwRPB7t7WAyeHWVfW1YJ9NIgd9mvGhfQpRY56X6AVf8mwM8Wol+0z4liE7XX3QOt8MN1rUKCfSjRIA==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.8.0", - "@typescript-eslint/type-utils": "6.8.0", - "@typescript-eslint/utils": "6.8.0", - "@typescript-eslint/visitor-keys": "6.8.0", + "@typescript-eslint/scope-manager": "6.9.0", + "@typescript-eslint/type-utils": "6.9.0", + "@typescript-eslint/utils": "6.9.0", + "@typescript-eslint/visitor-keys": "6.9.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -2118,6 +2118,53 @@ } } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.0.tgz", + "integrity": "sha512-1R8A9Mc39n4pCCz9o79qRO31HGNDvC7UhPhv26TovDsWPBDx+Sg3rOZdCELIA3ZmNoWAuxaMOT7aWtGRSYkQxw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.9.0", + "@typescript-eslint/visitor-keys": "6.9.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.0.tgz", + "integrity": "sha512-+KB0lbkpxBkBSiVCuQvduqMJy+I1FyDbdwSpM3IoBS7APl4Bu15lStPjgBIdykdRqQNYqYNMa8Kuidax6phaEw==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.0.tgz", + "integrity": "sha512-dGtAfqjV6RFOtIP8I0B4ZTBRrlTT8NHHlZZSchQx3qReaoDeXhYM++M4So2AgFK9ZB0emRPA6JI1HkafzA2Ibg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.9.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/parser": { "version": "6.8.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.8.0.tgz", @@ -2164,13 +2211,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.8.0.tgz", - "integrity": "sha512-RYOJdlkTJIXW7GSldUIHqc/Hkto8E+fZN96dMIFhuTJcQwdRoGN2rEWA8U6oXbLo0qufH7NPElUb+MceHtz54g==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.9.0.tgz", + "integrity": "sha512-XXeahmfbpuhVbhSOROIzJ+b13krFmgtc4GlEuu1WBT+RpyGPIA4Y/eGnXzjbDj5gZLzpAXO/sj+IF/x2GtTMjQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.8.0", - "@typescript-eslint/utils": "6.8.0", + "@typescript-eslint/typescript-estree": "6.9.0", + "@typescript-eslint/utils": "6.9.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -2190,6 +2237,63 @@ } } }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.0.tgz", + "integrity": "sha512-+KB0lbkpxBkBSiVCuQvduqMJy+I1FyDbdwSpM3IoBS7APl4Bu15lStPjgBIdykdRqQNYqYNMa8Kuidax6phaEw==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.0.tgz", + "integrity": "sha512-NJM2BnJFZBEAbCfBP00zONKXvMqihZCrmwCaik0UhLr0vAgb6oguXxLX1k00oQyD+vZZ+CJn3kocvv2yxm4awQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.9.0", + "@typescript-eslint/visitor-keys": "6.9.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.0.tgz", + "integrity": "sha512-dGtAfqjV6RFOtIP8I0B4ZTBRrlTT8NHHlZZSchQx3qReaoDeXhYM++M4So2AgFK9ZB0emRPA6JI1HkafzA2Ibg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.9.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/types": { "version": "6.8.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.8.0.tgz", @@ -2231,17 +2335,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.8.0.tgz", - "integrity": "sha512-dKs1itdE2qFG4jr0dlYLQVppqTE+Itt7GmIf/vX6CSvsW+3ov8PbWauVKyyfNngokhIO9sKZeRGCUo1+N7U98Q==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.9.0.tgz", + "integrity": "sha512-5Wf+Jsqya7WcCO8me504FBigeQKVLAMPmUzYgDbWchINNh1KJbxCgVya3EQ2MjvJMVeXl3pofRmprqX6mfQkjQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.8.0", - "@typescript-eslint/types": "6.8.0", - "@typescript-eslint/typescript-estree": "6.8.0", + "@typescript-eslint/scope-manager": "6.9.0", + "@typescript-eslint/types": "6.9.0", + "@typescript-eslint/typescript-estree": "6.9.0", "semver": "^7.5.4" }, "engines": { @@ -2255,6 +2359,80 @@ "eslint": "^7.0.0 || ^8.0.0" } }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.0.tgz", + "integrity": "sha512-1R8A9Mc39n4pCCz9o79qRO31HGNDvC7UhPhv26TovDsWPBDx+Sg3rOZdCELIA3ZmNoWAuxaMOT7aWtGRSYkQxw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.9.0", + "@typescript-eslint/visitor-keys": "6.9.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.0.tgz", + "integrity": "sha512-+KB0lbkpxBkBSiVCuQvduqMJy+I1FyDbdwSpM3IoBS7APl4Bu15lStPjgBIdykdRqQNYqYNMa8Kuidax6phaEw==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.0.tgz", + "integrity": "sha512-NJM2BnJFZBEAbCfBP00zONKXvMqihZCrmwCaik0UhLr0vAgb6oguXxLX1k00oQyD+vZZ+CJn3kocvv2yxm4awQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.9.0", + "@typescript-eslint/visitor-keys": "6.9.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.0.tgz", + "integrity": "sha512-dGtAfqjV6RFOtIP8I0B4ZTBRrlTT8NHHlZZSchQx3qReaoDeXhYM++M4So2AgFK9ZB0emRPA6JI1HkafzA2Ibg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.9.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/visitor-keys": { "version": "6.8.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.8.0.tgz", @@ -8725,9 +8903,9 @@ } }, "@types/json-schema": { - "version": "7.0.13", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.13.tgz", - "integrity": "sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==", + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.14.tgz", + "integrity": "sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw==", "dev": true }, "@types/node": { @@ -8774,9 +8952,9 @@ "dev": true }, "@types/semver": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.3.tgz", - "integrity": "sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==", "dev": true }, "@types/stack-utils": { @@ -8809,22 +8987,50 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.8.0.tgz", - "integrity": "sha512-GosF4238Tkes2SHPQ1i8f6rMtG6zlKwMEB0abqSJ3Npvos+doIlc/ATG+vX1G9coDF3Ex78zM3heXHLyWEwLUw==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.9.0.tgz", + "integrity": "sha512-lgX7F0azQwRPB7t7WAyeHWVfW1YJ9NIgd9mvGhfQpRY56X6AVf8mwM8Wol+0z4liE7XX3QOt8MN1rUKCfSjRIA==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.8.0", - "@typescript-eslint/type-utils": "6.8.0", - "@typescript-eslint/utils": "6.8.0", - "@typescript-eslint/visitor-keys": "6.8.0", + "@typescript-eslint/scope-manager": "6.9.0", + "@typescript-eslint/type-utils": "6.9.0", + "@typescript-eslint/utils": "6.9.0", + "@typescript-eslint/visitor-keys": "6.9.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", "natural-compare": "^1.4.0", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.0.tgz", + "integrity": "sha512-1R8A9Mc39n4pCCz9o79qRO31HGNDvC7UhPhv26TovDsWPBDx+Sg3rOZdCELIA3ZmNoWAuxaMOT7aWtGRSYkQxw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.9.0", + "@typescript-eslint/visitor-keys": "6.9.0" + } + }, + "@typescript-eslint/types": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.0.tgz", + "integrity": "sha512-+KB0lbkpxBkBSiVCuQvduqMJy+I1FyDbdwSpM3IoBS7APl4Bu15lStPjgBIdykdRqQNYqYNMa8Kuidax6phaEw==", + "dev": true + }, + "@typescript-eslint/visitor-keys": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.0.tgz", + "integrity": "sha512-dGtAfqjV6RFOtIP8I0B4ZTBRrlTT8NHHlZZSchQx3qReaoDeXhYM++M4So2AgFK9ZB0emRPA6JI1HkafzA2Ibg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.9.0", + "eslint-visitor-keys": "^3.4.1" + } + } } }, "@typescript-eslint/parser": { @@ -8851,15 +9057,48 @@ } }, "@typescript-eslint/type-utils": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.8.0.tgz", - "integrity": "sha512-RYOJdlkTJIXW7GSldUIHqc/Hkto8E+fZN96dMIFhuTJcQwdRoGN2rEWA8U6oXbLo0qufH7NPElUb+MceHtz54g==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.9.0.tgz", + "integrity": "sha512-XXeahmfbpuhVbhSOROIzJ+b13krFmgtc4GlEuu1WBT+RpyGPIA4Y/eGnXzjbDj5gZLzpAXO/sj+IF/x2GtTMjQ==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "6.8.0", - "@typescript-eslint/utils": "6.8.0", + "@typescript-eslint/typescript-estree": "6.9.0", + "@typescript-eslint/utils": "6.9.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" + }, + "dependencies": { + "@typescript-eslint/types": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.0.tgz", + "integrity": "sha512-+KB0lbkpxBkBSiVCuQvduqMJy+I1FyDbdwSpM3IoBS7APl4Bu15lStPjgBIdykdRqQNYqYNMa8Kuidax6phaEw==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.0.tgz", + "integrity": "sha512-NJM2BnJFZBEAbCfBP00zONKXvMqihZCrmwCaik0UhLr0vAgb6oguXxLX1k00oQyD+vZZ+CJn3kocvv2yxm4awQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.9.0", + "@typescript-eslint/visitor-keys": "6.9.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.0.tgz", + "integrity": "sha512-dGtAfqjV6RFOtIP8I0B4ZTBRrlTT8NHHlZZSchQx3qReaoDeXhYM++M4So2AgFK9ZB0emRPA6JI1HkafzA2Ibg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.9.0", + "eslint-visitor-keys": "^3.4.1" + } + } } }, "@typescript-eslint/types": { @@ -8884,18 +9123,61 @@ } }, "@typescript-eslint/utils": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.8.0.tgz", - "integrity": "sha512-dKs1itdE2qFG4jr0dlYLQVppqTE+Itt7GmIf/vX6CSvsW+3ov8PbWauVKyyfNngokhIO9sKZeRGCUo1+N7U98Q==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.9.0.tgz", + "integrity": "sha512-5Wf+Jsqya7WcCO8me504FBigeQKVLAMPmUzYgDbWchINNh1KJbxCgVya3EQ2MjvJMVeXl3pofRmprqX6mfQkjQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.8.0", - "@typescript-eslint/types": "6.8.0", - "@typescript-eslint/typescript-estree": "6.8.0", + "@typescript-eslint/scope-manager": "6.9.0", + "@typescript-eslint/types": "6.9.0", + "@typescript-eslint/typescript-estree": "6.9.0", "semver": "^7.5.4" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.0.tgz", + "integrity": "sha512-1R8A9Mc39n4pCCz9o79qRO31HGNDvC7UhPhv26TovDsWPBDx+Sg3rOZdCELIA3ZmNoWAuxaMOT7aWtGRSYkQxw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.9.0", + "@typescript-eslint/visitor-keys": "6.9.0" + } + }, + "@typescript-eslint/types": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.0.tgz", + "integrity": "sha512-+KB0lbkpxBkBSiVCuQvduqMJy+I1FyDbdwSpM3IoBS7APl4Bu15lStPjgBIdykdRqQNYqYNMa8Kuidax6phaEw==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.0.tgz", + "integrity": "sha512-NJM2BnJFZBEAbCfBP00zONKXvMqihZCrmwCaik0UhLr0vAgb6oguXxLX1k00oQyD+vZZ+CJn3kocvv2yxm4awQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.9.0", + "@typescript-eslint/visitor-keys": "6.9.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.0.tgz", + "integrity": "sha512-dGtAfqjV6RFOtIP8I0B4ZTBRrlTT8NHHlZZSchQx3qReaoDeXhYM++M4So2AgFK9ZB0emRPA6JI1HkafzA2Ibg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.9.0", + "eslint-visitor-keys": "^3.4.1" + } + } } }, "@typescript-eslint/visitor-keys": { From 9d97d7b048bb88458bcc0e4b3bf85dd9eab0615e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Oct 2023 18:04:11 +0200 Subject: [PATCH 0570/1076] build(deps-dev): bump @types/node from 20.8.7 to 20.8.8 in /stake-pool/js (#5654) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.8.7 to 20.8.8. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 5bf31914..6a5539d5 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -2005,9 +2005,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.8.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.7.tgz", - "integrity": "sha512-21TKHHh3eUHIi2MloeptJWALuCu5H7HQTdTrWIFReA8ad+aggoX+lRes3ex7/FtpC+sVUpFMQ+QTfYr74mruiQ==", + "version": "20.8.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.8.tgz", + "integrity": "sha512-YRsdVxq6OaLfmR9Hy816IMp33xOBjfyOgUd77ehqg96CFywxAPbDbXvAsuN2KVg2HOT8Eh6uAfU+l4WffwPVrQ==", "dependencies": { "undici-types": "~5.25.1" } @@ -8909,9 +8909,9 @@ "dev": true }, "@types/node": { - "version": "20.8.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.7.tgz", - "integrity": "sha512-21TKHHh3eUHIi2MloeptJWALuCu5H7HQTdTrWIFReA8ad+aggoX+lRes3ex7/FtpC+sVUpFMQ+QTfYr74mruiQ==", + "version": "20.8.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.8.tgz", + "integrity": "sha512-YRsdVxq6OaLfmR9Hy816IMp33xOBjfyOgUd77ehqg96CFywxAPbDbXvAsuN2KVg2HOT8Eh6uAfU+l4WffwPVrQ==", "requires": { "undici-types": "~5.25.1" } From f782d109e34380be9c19412cdff2032f7b312dd6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Oct 2023 19:04:20 +0200 Subject: [PATCH 0571/1076] build(deps-dev): bump @typescript-eslint/parser from 6.8.0 to 6.9.0 in /stake-pool/js (#5653) build(deps-dev): bump @typescript-eslint/parser in /stake-pool/js Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.8.0 to 6.9.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.9.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 358 +++------------------------- 1 file changed, 38 insertions(+), 320 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 6a5539d5..9963acf9 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -2118,63 +2118,16 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.0.tgz", - "integrity": "sha512-1R8A9Mc39n4pCCz9o79qRO31HGNDvC7UhPhv26TovDsWPBDx+Sg3rOZdCELIA3ZmNoWAuxaMOT7aWtGRSYkQxw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.9.0", - "@typescript-eslint/visitor-keys": "6.9.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.0.tgz", - "integrity": "sha512-+KB0lbkpxBkBSiVCuQvduqMJy+I1FyDbdwSpM3IoBS7APl4Bu15lStPjgBIdykdRqQNYqYNMa8Kuidax6phaEw==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "node_modules/@typescript-eslint/parser": { "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.0.tgz", - "integrity": "sha512-dGtAfqjV6RFOtIP8I0B4ZTBRrlTT8NHHlZZSchQx3qReaoDeXhYM++M4So2AgFK9ZB0emRPA6JI1HkafzA2Ibg==", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.9.0.tgz", + "integrity": "sha512-GZmjMh4AJ/5gaH4XF2eXA8tMnHWP+Pm1mjQR2QN4Iz+j/zO04b9TOvJYOX2sCNIQHtRStKTxRY1FX7LhpJT4Gw==", "dev": true, "dependencies": { + "@typescript-eslint/scope-manager": "6.9.0", "@typescript-eslint/types": "6.9.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.8.0.tgz", - "integrity": "sha512-5tNs6Bw0j6BdWuP8Fx+VH4G9fEPDxnVI7yH1IAPkQH5RUtvKwRoqdecAPdQXv4rSOADAaz1LFBZvZG7VbXivSg==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "6.8.0", - "@typescript-eslint/types": "6.8.0", - "@typescript-eslint/typescript-estree": "6.8.0", - "@typescript-eslint/visitor-keys": "6.8.0", + "@typescript-eslint/typescript-estree": "6.9.0", + "@typescript-eslint/visitor-keys": "6.9.0", "debug": "^4.3.4" }, "engines": { @@ -2194,13 +2147,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.8.0.tgz", - "integrity": "sha512-xe0HNBVwCph7rak+ZHcFD6A+q50SMsFwcmfdjs9Kz4qDh5hWhaPhFjRs/SODEhroBI5Ruyvyz9LfwUJ624O40g==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.0.tgz", + "integrity": "sha512-1R8A9Mc39n4pCCz9o79qRO31HGNDvC7UhPhv26TovDsWPBDx+Sg3rOZdCELIA3ZmNoWAuxaMOT7aWtGRSYkQxw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.8.0", - "@typescript-eslint/visitor-keys": "6.8.0" + "@typescript-eslint/types": "6.9.0", + "@typescript-eslint/visitor-keys": "6.9.0" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -2237,7 +2190,7 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "node_modules/@typescript-eslint/types": { "version": "6.9.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.0.tgz", "integrity": "sha512-+KB0lbkpxBkBSiVCuQvduqMJy+I1FyDbdwSpM3IoBS7APl4Bu15lStPjgBIdykdRqQNYqYNMa8Kuidax6phaEw==", @@ -2250,7 +2203,7 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "node_modules/@typescript-eslint/typescript-estree": { "version": "6.9.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.0.tgz", "integrity": "sha512-NJM2BnJFZBEAbCfBP00zONKXvMqihZCrmwCaik0UhLr0vAgb6oguXxLX1k00oQyD+vZZ+CJn3kocvv2yxm4awQ==", @@ -2277,63 +2230,6 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.0.tgz", - "integrity": "sha512-dGtAfqjV6RFOtIP8I0B4ZTBRrlTT8NHHlZZSchQx3qReaoDeXhYM++M4So2AgFK9ZB0emRPA6JI1HkafzA2Ibg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.9.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.8.0.tgz", - "integrity": "sha512-p5qOxSum7W3k+llc7owEStXlGmSl8FcGvhYt8Vjy7FqEnmkCVlM3P57XQEGj58oqaBWDQXbJDZxwUWMS/EAPNQ==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.8.0.tgz", - "integrity": "sha512-ISgV0lQ8XgW+mvv5My/+iTUdRmGspducmQcDw5JxznasXNnZn3SKNrTRuMsEXv+V/O+Lw9AGcQCfVaOPCAk/Zg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.8.0", - "@typescript-eslint/visitor-keys": "6.8.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, "node_modules/@typescript-eslint/utils": { "version": "6.9.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.9.0.tgz", @@ -2359,64 +2255,7 @@ "eslint": "^7.0.0 || ^8.0.0" } }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.0.tgz", - "integrity": "sha512-1R8A9Mc39n4pCCz9o79qRO31HGNDvC7UhPhv26TovDsWPBDx+Sg3rOZdCELIA3ZmNoWAuxaMOT7aWtGRSYkQxw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.9.0", - "@typescript-eslint/visitor-keys": "6.9.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.0.tgz", - "integrity": "sha512-+KB0lbkpxBkBSiVCuQvduqMJy+I1FyDbdwSpM3IoBS7APl4Bu15lStPjgBIdykdRqQNYqYNMa8Kuidax6phaEw==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.0.tgz", - "integrity": "sha512-NJM2BnJFZBEAbCfBP00zONKXvMqihZCrmwCaik0UhLr0vAgb6oguXxLX1k00oQyD+vZZ+CJn3kocvv2yxm4awQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.9.0", - "@typescript-eslint/visitor-keys": "6.9.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "node_modules/@typescript-eslint/visitor-keys": { "version": "6.9.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.0.tgz", "integrity": "sha512-dGtAfqjV6RFOtIP8I0B4ZTBRrlTT8NHHlZZSchQx3qReaoDeXhYM++M4So2AgFK9ZB0emRPA6JI1HkafzA2Ibg==", @@ -2433,23 +2272,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.8.0.tgz", - "integrity": "sha512-oqAnbA7c+pgOhW2OhGvxm0t1BULX5peQI/rLsNDpGM78EebV3C9IGbX5HNZabuZ6UQrYveCLjKo8Iy/lLlBkkg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.8.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", @@ -9003,57 +8825,29 @@ "natural-compare": "^1.4.0", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.0.tgz", - "integrity": "sha512-1R8A9Mc39n4pCCz9o79qRO31HGNDvC7UhPhv26TovDsWPBDx+Sg3rOZdCELIA3ZmNoWAuxaMOT7aWtGRSYkQxw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.9.0", - "@typescript-eslint/visitor-keys": "6.9.0" - } - }, - "@typescript-eslint/types": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.0.tgz", - "integrity": "sha512-+KB0lbkpxBkBSiVCuQvduqMJy+I1FyDbdwSpM3IoBS7APl4Bu15lStPjgBIdykdRqQNYqYNMa8Kuidax6phaEw==", - "dev": true - }, - "@typescript-eslint/visitor-keys": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.0.tgz", - "integrity": "sha512-dGtAfqjV6RFOtIP8I0B4ZTBRrlTT8NHHlZZSchQx3qReaoDeXhYM++M4So2AgFK9ZB0emRPA6JI1HkafzA2Ibg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.9.0", - "eslint-visitor-keys": "^3.4.1" - } - } } }, "@typescript-eslint/parser": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.8.0.tgz", - "integrity": "sha512-5tNs6Bw0j6BdWuP8Fx+VH4G9fEPDxnVI7yH1IAPkQH5RUtvKwRoqdecAPdQXv4rSOADAaz1LFBZvZG7VbXivSg==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.9.0.tgz", + "integrity": "sha512-GZmjMh4AJ/5gaH4XF2eXA8tMnHWP+Pm1mjQR2QN4Iz+j/zO04b9TOvJYOX2sCNIQHtRStKTxRY1FX7LhpJT4Gw==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "6.8.0", - "@typescript-eslint/types": "6.8.0", - "@typescript-eslint/typescript-estree": "6.8.0", - "@typescript-eslint/visitor-keys": "6.8.0", + "@typescript-eslint/scope-manager": "6.9.0", + "@typescript-eslint/types": "6.9.0", + "@typescript-eslint/typescript-estree": "6.9.0", + "@typescript-eslint/visitor-keys": "6.9.0", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.8.0.tgz", - "integrity": "sha512-xe0HNBVwCph7rak+ZHcFD6A+q50SMsFwcmfdjs9Kz4qDh5hWhaPhFjRs/SODEhroBI5Ruyvyz9LfwUJ624O40g==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.0.tgz", + "integrity": "sha512-1R8A9Mc39n4pCCz9o79qRO31HGNDvC7UhPhv26TovDsWPBDx+Sg3rOZdCELIA3ZmNoWAuxaMOT7aWtGRSYkQxw==", "dev": true, "requires": { - "@typescript-eslint/types": "6.8.0", - "@typescript-eslint/visitor-keys": "6.8.0" + "@typescript-eslint/types": "6.9.0", + "@typescript-eslint/visitor-keys": "6.9.0" } }, "@typescript-eslint/type-utils": { @@ -9066,55 +8860,22 @@ "@typescript-eslint/utils": "6.9.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" - }, - "dependencies": { - "@typescript-eslint/types": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.0.tgz", - "integrity": "sha512-+KB0lbkpxBkBSiVCuQvduqMJy+I1FyDbdwSpM3IoBS7APl4Bu15lStPjgBIdykdRqQNYqYNMa8Kuidax6phaEw==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.0.tgz", - "integrity": "sha512-NJM2BnJFZBEAbCfBP00zONKXvMqihZCrmwCaik0UhLr0vAgb6oguXxLX1k00oQyD+vZZ+CJn3kocvv2yxm4awQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.9.0", - "@typescript-eslint/visitor-keys": "6.9.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.0.tgz", - "integrity": "sha512-dGtAfqjV6RFOtIP8I0B4ZTBRrlTT8NHHlZZSchQx3qReaoDeXhYM++M4So2AgFK9ZB0emRPA6JI1HkafzA2Ibg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.9.0", - "eslint-visitor-keys": "^3.4.1" - } - } } }, "@typescript-eslint/types": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.8.0.tgz", - "integrity": "sha512-p5qOxSum7W3k+llc7owEStXlGmSl8FcGvhYt8Vjy7FqEnmkCVlM3P57XQEGj58oqaBWDQXbJDZxwUWMS/EAPNQ==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.0.tgz", + "integrity": "sha512-+KB0lbkpxBkBSiVCuQvduqMJy+I1FyDbdwSpM3IoBS7APl4Bu15lStPjgBIdykdRqQNYqYNMa8Kuidax6phaEw==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.8.0.tgz", - "integrity": "sha512-ISgV0lQ8XgW+mvv5My/+iTUdRmGspducmQcDw5JxznasXNnZn3SKNrTRuMsEXv+V/O+Lw9AGcQCfVaOPCAk/Zg==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.0.tgz", + "integrity": "sha512-NJM2BnJFZBEAbCfBP00zONKXvMqihZCrmwCaik0UhLr0vAgb6oguXxLX1k00oQyD+vZZ+CJn3kocvv2yxm4awQ==", "dev": true, "requires": { - "@typescript-eslint/types": "6.8.0", - "@typescript-eslint/visitor-keys": "6.8.0", + "@typescript-eslint/types": "6.9.0", + "@typescript-eslint/visitor-keys": "6.9.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -9135,58 +8896,15 @@ "@typescript-eslint/types": "6.9.0", "@typescript-eslint/typescript-estree": "6.9.0", "semver": "^7.5.4" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.0.tgz", - "integrity": "sha512-1R8A9Mc39n4pCCz9o79qRO31HGNDvC7UhPhv26TovDsWPBDx+Sg3rOZdCELIA3ZmNoWAuxaMOT7aWtGRSYkQxw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.9.0", - "@typescript-eslint/visitor-keys": "6.9.0" - } - }, - "@typescript-eslint/types": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.0.tgz", - "integrity": "sha512-+KB0lbkpxBkBSiVCuQvduqMJy+I1FyDbdwSpM3IoBS7APl4Bu15lStPjgBIdykdRqQNYqYNMa8Kuidax6phaEw==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.0.tgz", - "integrity": "sha512-NJM2BnJFZBEAbCfBP00zONKXvMqihZCrmwCaik0UhLr0vAgb6oguXxLX1k00oQyD+vZZ+CJn3kocvv2yxm4awQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.9.0", - "@typescript-eslint/visitor-keys": "6.9.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.0.tgz", - "integrity": "sha512-dGtAfqjV6RFOtIP8I0B4ZTBRrlTT8NHHlZZSchQx3qReaoDeXhYM++M4So2AgFK9ZB0emRPA6JI1HkafzA2Ibg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.9.0", - "eslint-visitor-keys": "^3.4.1" - } - } } }, "@typescript-eslint/visitor-keys": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.8.0.tgz", - "integrity": "sha512-oqAnbA7c+pgOhW2OhGvxm0t1BULX5peQI/rLsNDpGM78EebV3C9IGbX5HNZabuZ6UQrYveCLjKo8Iy/lLlBkkg==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.0.tgz", + "integrity": "sha512-dGtAfqjV6RFOtIP8I0B4ZTBRrlTT8NHHlZZSchQx3qReaoDeXhYM++M4So2AgFK9ZB0emRPA6JI1HkafzA2Ibg==", "dev": true, "requires": { - "@typescript-eslint/types": "6.8.0", + "@typescript-eslint/types": "6.9.0", "eslint-visitor-keys": "^3.4.1" } }, From 78513654d799dc47dc7630ac0a56a08ce1bf5ce6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Oct 2023 13:20:49 +0200 Subject: [PATCH 0572/1076] build(deps): bump serde from 1.0.189 to 1.0.190 (#5665) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.189 to 1.0.190. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.189...v1.0.190) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 3aa8ab0d..c061821f 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "0.7.0" [dependencies] borsh = "0.10" clap = "2.33.3" -serde = "1.0.189" +serde = "1.0.190" serde_derive = "1.0.130" serde_json = "1.0.107" solana-account-decoder = "=1.17.2" diff --git a/program/Cargo.toml b/program/Cargo.toml index 31f02250..f1a2488e 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,7 +18,7 @@ bytemuck = "1.13" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.0" -serde = "1.0.189" +serde = "1.0.190" serde_derive = "1.0.103" solana-program = "1.17.2" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } From 3f86c41e3542a40a84d9ae4f40387af84063d70f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Oct 2023 14:54:14 +0200 Subject: [PATCH 0573/1076] build(deps-dev): bump @types/node from 20.8.8 to 20.8.9 in /stake-pool/js (#5669) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.8.8 to 20.8.9. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 9963acf9..de5e309a 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -2005,11 +2005,11 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.8.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.8.tgz", - "integrity": "sha512-YRsdVxq6OaLfmR9Hy816IMp33xOBjfyOgUd77ehqg96CFywxAPbDbXvAsuN2KVg2HOT8Eh6uAfU+l4WffwPVrQ==", + "version": "20.8.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.9.tgz", + "integrity": "sha512-UzykFsT3FhHb1h7yD4CA4YhBHq545JC0YnEz41xkipN88eKQtL6rSgocL5tbAP6Ola9Izm/Aw4Ora8He4x0BHg==", "dependencies": { - "undici-types": "~5.25.1" + "undici-types": "~5.26.4" } }, "node_modules/@types/node-fetch": { @@ -6977,9 +6977,9 @@ } }, "node_modules/undici-types": { - "version": "5.25.3", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz", - "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==" + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" }, "node_modules/universalify": { "version": "0.2.0", @@ -8731,11 +8731,11 @@ "dev": true }, "@types/node": { - "version": "20.8.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.8.tgz", - "integrity": "sha512-YRsdVxq6OaLfmR9Hy816IMp33xOBjfyOgUd77ehqg96CFywxAPbDbXvAsuN2KVg2HOT8Eh6uAfU+l4WffwPVrQ==", + "version": "20.8.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.9.tgz", + "integrity": "sha512-UzykFsT3FhHb1h7yD4CA4YhBHq545JC0YnEz41xkipN88eKQtL6rSgocL5tbAP6Ola9Izm/Aw4Ora8He4x0BHg==", "requires": { - "undici-types": "~5.25.1" + "undici-types": "~5.26.4" } }, "@types/node-fetch": { @@ -12341,9 +12341,9 @@ "dev": true }, "undici-types": { - "version": "5.25.3", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz", - "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==" + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" }, "universalify": { "version": "0.2.0", From 9d8cd341890e27f95a5cac40d3dcf74bb5cdb1b5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 28 Oct 2023 22:03:03 +0200 Subject: [PATCH 0574/1076] build(deps): bump @solana/web3.js from 1.87.2 to 1.87.3 in /stake-pool/js (#5681) build(deps): bump @solana/web3.js in /stake-pool/js Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.87.2 to 1.87.3. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.87.2...v1.87.3) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 44 ++++++++++++++--------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index de5e309a..c6bdde79 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -638,11 +638,11 @@ } }, "node_modules/@babel/runtime": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz", - "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz", + "integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==", "dependencies": { - "regenerator-runtime": "^0.13.11" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" @@ -1861,11 +1861,11 @@ } }, "node_modules/@solana/web3.js": { - "version": "1.87.2", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.87.2.tgz", - "integrity": "sha512-TZNhS+tvJbYjm0LAvIkUy/3Aqgt2l6/3X6XsVUpvj5MGOl2Q6Ch8hYSxcUUtMbAFNN3sUXmV8NhhMLNJEvI6TA==", + "version": "1.87.3", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.87.3.tgz", + "integrity": "sha512-WGLzTZpi00vP443qGK3gL+LZXQJwaWkh6bzNXYpMTCAH2Z102y3YbPWOoQzJUeRSZWSXKh7MFkA3vDMFlMvGZQ==", "dependencies": { - "@babel/runtime": "^7.22.6", + "@babel/runtime": "^7.23.2", "@noble/curves": "^1.2.0", "@noble/hashes": "^1.3.1", "@solana/buffer-layout": "^4.0.0", @@ -6074,9 +6074,9 @@ "dev": true }, "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" }, "node_modules/require-directory": { "version": "2.1.1", @@ -7743,11 +7743,11 @@ } }, "@babel/runtime": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz", - "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz", + "integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==", "requires": { - "regenerator-runtime": "^0.13.11" + "regenerator-runtime": "^0.14.0" } }, "@babel/template": { @@ -8590,11 +8590,11 @@ } }, "@solana/web3.js": { - "version": "1.87.2", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.87.2.tgz", - "integrity": "sha512-TZNhS+tvJbYjm0LAvIkUy/3Aqgt2l6/3X6XsVUpvj5MGOl2Q6Ch8hYSxcUUtMbAFNN3sUXmV8NhhMLNJEvI6TA==", + "version": "1.87.3", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.87.3.tgz", + "integrity": "sha512-WGLzTZpi00vP443qGK3gL+LZXQJwaWkh6bzNXYpMTCAH2Z102y3YbPWOoQzJUeRSZWSXKh7MFkA3vDMFlMvGZQ==", "requires": { - "@babel/runtime": "^7.22.6", + "@babel/runtime": "^7.23.2", "@noble/curves": "^1.2.0", "@noble/hashes": "^1.3.1", "@solana/buffer-layout": "^4.0.0", @@ -11709,9 +11709,9 @@ "dev": true }, "regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" }, "require-directory": { "version": "2.1.1", From 68cb2a22d68ef04b24c2255035699fbbb82bd724 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 28 Oct 2023 22:03:45 +0200 Subject: [PATCH 0575/1076] build(deps): bump num_enum from 0.7.0 to 0.7.1 (#5687) Bumps [num_enum](https://github.com/illicitonion/num_enum) from 0.7.0 to 0.7.1. - [Commits](https://github.com/illicitonion/num_enum/commits) --- updated-dependencies: - dependency-name: num_enum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index f1a2488e..f2bdc7e5 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,7 +17,7 @@ borsh = "0.10" bytemuck = "1.13" num-derive = "0.4" num-traits = "0.2" -num_enum = "0.7.0" +num_enum = "0.7.1" serde = "1.0.190" serde_derive = "1.0.103" solana-program = "1.17.2" From 333d03744870dbc8b576b272dafc11ae92221eec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 19:44:46 +0100 Subject: [PATCH 0576/1076] build(deps): bump serde_json from 1.0.107 to 1.0.108 (#5696) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.107 to 1.0.108. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.107...v1.0.108) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index c061821f..f559672d 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ borsh = "0.10" clap = "2.33.3" serde = "1.0.190" serde_derive = "1.0.130" -serde_json = "1.0.107" +serde_json = "1.0.108" solana-account-decoder = "=1.17.2" solana-clap-utils = "=1.17.2" solana-cli-config = "=1.17.2" From 837a4b3349a854c69f198fdca48bfc1501f08121 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 19:46:40 +0100 Subject: [PATCH 0577/1076] build(deps-dev): bump @typescript-eslint/parser from 6.9.0 to 6.9.1 in /stake-pool/js (#5708) build(deps-dev): bump @typescript-eslint/parser in /stake-pool/js Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.9.0 to 6.9.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.9.1/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 145 +++++++++++++++++++++++++--- 1 file changed, 131 insertions(+), 14 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index c6bdde79..8198562c 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -2119,15 +2119,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.9.0.tgz", - "integrity": "sha512-GZmjMh4AJ/5gaH4XF2eXA8tMnHWP+Pm1mjQR2QN4Iz+j/zO04b9TOvJYOX2sCNIQHtRStKTxRY1FX7LhpJT4Gw==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.9.1.tgz", + "integrity": "sha512-C7AK2wn43GSaCUZ9do6Ksgi2g3mwFkMO3Cis96kzmgudoVaKyt62yNzJOktP0HDLb/iO2O0n2lBOzJgr6Q/cyg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.9.0", - "@typescript-eslint/types": "6.9.0", - "@typescript-eslint/typescript-estree": "6.9.0", - "@typescript-eslint/visitor-keys": "6.9.0", + "@typescript-eslint/scope-manager": "6.9.1", + "@typescript-eslint/types": "6.9.1", + "@typescript-eslint/typescript-estree": "6.9.1", + "@typescript-eslint/visitor-keys": "6.9.1", "debug": "^4.3.4" }, "engines": { @@ -2146,6 +2146,80 @@ } } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.1.tgz", + "integrity": "sha512-38IxvKB6NAne3g/+MyXMs2Cda/Sz+CEpmm+KLGEM8hx/CvnSRuw51i8ukfwB/B/sESdeTGet1NH1Wj7I0YXswg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.9.1", + "@typescript-eslint/visitor-keys": "6.9.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.1.tgz", + "integrity": "sha512-BUGslGOb14zUHOUmDB2FfT6SI1CcZEJYfF3qFwBeUrU6srJfzANonwRYHDpLBuzbq3HaoF2XL2hcr01c8f8OaQ==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.1.tgz", + "integrity": "sha512-U+mUylTHfcqeO7mLWVQ5W/tMLXqVpRv61wm9ZtfE5egz7gtnmqVIw9ryh0mgIlkKk9rZLY3UHygsBSdB9/ftyw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.9.1", + "@typescript-eslint/visitor-keys": "6.9.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.1.tgz", + "integrity": "sha512-MUaPUe/QRLEffARsmNfmpghuQkW436DvESW+h+M52w0coICHRfD6Np9/K6PdACwnrq1HmuLl+cSPZaJmeVPkSw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.9.1", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "6.9.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.0.tgz", @@ -8828,16 +8902,59 @@ } }, "@typescript-eslint/parser": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.9.0.tgz", - "integrity": "sha512-GZmjMh4AJ/5gaH4XF2eXA8tMnHWP+Pm1mjQR2QN4Iz+j/zO04b9TOvJYOX2sCNIQHtRStKTxRY1FX7LhpJT4Gw==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.9.1.tgz", + "integrity": "sha512-C7AK2wn43GSaCUZ9do6Ksgi2g3mwFkMO3Cis96kzmgudoVaKyt62yNzJOktP0HDLb/iO2O0n2lBOzJgr6Q/cyg==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "6.9.0", - "@typescript-eslint/types": "6.9.0", - "@typescript-eslint/typescript-estree": "6.9.0", - "@typescript-eslint/visitor-keys": "6.9.0", + "@typescript-eslint/scope-manager": "6.9.1", + "@typescript-eslint/types": "6.9.1", + "@typescript-eslint/typescript-estree": "6.9.1", + "@typescript-eslint/visitor-keys": "6.9.1", "debug": "^4.3.4" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.1.tgz", + "integrity": "sha512-38IxvKB6NAne3g/+MyXMs2Cda/Sz+CEpmm+KLGEM8hx/CvnSRuw51i8ukfwB/B/sESdeTGet1NH1Wj7I0YXswg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.9.1", + "@typescript-eslint/visitor-keys": "6.9.1" + } + }, + "@typescript-eslint/types": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.1.tgz", + "integrity": "sha512-BUGslGOb14zUHOUmDB2FfT6SI1CcZEJYfF3qFwBeUrU6srJfzANonwRYHDpLBuzbq3HaoF2XL2hcr01c8f8OaQ==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.1.tgz", + "integrity": "sha512-U+mUylTHfcqeO7mLWVQ5W/tMLXqVpRv61wm9ZtfE5egz7gtnmqVIw9ryh0mgIlkKk9rZLY3UHygsBSdB9/ftyw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.9.1", + "@typescript-eslint/visitor-keys": "6.9.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.1.tgz", + "integrity": "sha512-MUaPUe/QRLEffARsmNfmpghuQkW436DvESW+h+M52w0coICHRfD6Np9/K6PdACwnrq1HmuLl+cSPZaJmeVPkSw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.9.1", + "eslint-visitor-keys": "^3.4.1" + } + } } }, "@typescript-eslint/scope-manager": { From 584a4883948c1e35fceed149a25019087b1e014c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 19:48:15 +0100 Subject: [PATCH 0578/1076] build(deps-dev): bump @types/bn.js from 5.1.3 to 5.1.4 in /stake-pool/js (#5707) Bumps [@types/bn.js](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/bn.js) from 5.1.3 to 5.1.4. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/bn.js) --- updated-dependencies: - dependency-name: "@types/bn.js" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 8198562c..2c694566 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1933,9 +1933,9 @@ } }, "node_modules/@types/bn.js": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.3.tgz", - "integrity": "sha512-wT1B4iIO82ecXkdN6waCK8Ou7E71WU+mP1osDA5Q8c6Ur+ozU2vIKUIhSpUr6uE5L2YHocKS1Z2jG2fBC1YVeg==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.4.tgz", + "integrity": "sha512-ZtBd9L8hVtoBpPMSWfbwjC4dhQtJdlPS+e1A0Rydb7vg7bDcUwiRklPx24sMYtXcmAMST/k0Wze7JLbNU/5SkA==", "dev": true, "dependencies": { "@types/node": "*" @@ -8733,9 +8733,9 @@ } }, "@types/bn.js": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.3.tgz", - "integrity": "sha512-wT1B4iIO82ecXkdN6waCK8Ou7E71WU+mP1osDA5Q8c6Ur+ozU2vIKUIhSpUr6uE5L2YHocKS1Z2jG2fBC1YVeg==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.4.tgz", + "integrity": "sha512-ZtBd9L8hVtoBpPMSWfbwjC4dhQtJdlPS+e1A0Rydb7vg7bDcUwiRklPx24sMYtXcmAMST/k0Wze7JLbNU/5SkA==", "dev": true, "requires": { "@types/node": "*" From 1c4dca9e54a6a9c17878a16289a64d7c2194746d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 19:48:42 +0100 Subject: [PATCH 0579/1076] build(deps-dev): bump rollup from 4.1.4 to 4.2.0 in /stake-pool/js (#5709) Bumps [rollup](https://github.com/rollup/rollup) from 4.1.4 to 4.2.0. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.1.4...v4.2.0) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 208 ++++++++++++++-------------- 1 file changed, 104 insertions(+), 104 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 2c694566..b449e8bd 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1646,9 +1646,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.1.4.tgz", - "integrity": "sha512-WlzkuFvpKl6CLFdc3V6ESPt7gq5Vrimd2Yv9IzKXdOpgbH4cdDSS1JLiACX8toygihtH5OlxyQzhXOph7Ovlpw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.2.0.tgz", + "integrity": "sha512-8PlggAxGxavr+pkCNeV1TM2wTb2o+cUWDg9M1cm9nR27Dsn287uZtSLYXoQqQcmq+sYfF7lHfd3sWJJinH9GmA==", "cpu": [ "arm" ], @@ -1659,9 +1659,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.1.4.tgz", - "integrity": "sha512-D1e+ABe56T9Pq2fD+R3ybe1ylCDzu3tY4Qm2Mj24R9wXNCq35+JbFbOpc2yrroO2/tGhTobmEl2Bm5xfE/n8RA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.2.0.tgz", + "integrity": "sha512-+71T85hbMFrJI+zKQULNmSYBeIhru55PYoF/u75MyeN2FcxE4HSPw20319b+FcZ4lWx2Nx/Ql9tN+hoaD3GH/A==", "cpu": [ "arm64" ], @@ -1672,9 +1672,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.1.4.tgz", - "integrity": "sha512-7vTYrgEiOrjxnjsgdPB+4i7EMxbVp7XXtS+50GJYj695xYTTEMn3HZVEvgtwjOUkAP/Q4HDejm4fIAjLeAfhtg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.2.0.tgz", + "integrity": "sha512-IIIQLuG43QIElT1JZqUP/zqIdiJl4t9U/boa0GZnQTw9m1X0k3mlBuysbgYXeloLT1RozdL7bgw4lpSaI8GOXw==", "cpu": [ "arm64" ], @@ -1685,9 +1685,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.1.4.tgz", - "integrity": "sha512-eGJVZScKSLZkYjhTAESCtbyTBq9SXeW9+TX36ki5gVhDqJtnQ5k0f9F44jNK5RhAMgIj0Ht9+n6HAgH0gUUyWQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.2.0.tgz", + "integrity": "sha512-BXcXvnLaea1Xz900omrGJhxHFJfH9jZ0CpJuVsbjjhpniJ6qiLXz3xA8Lekaa4MuhFcJd4f0r+Ky1G4VFbYhWw==", "cpu": [ "x64" ], @@ -1698,9 +1698,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.1.4.tgz", - "integrity": "sha512-HnigYSEg2hOdX1meROecbk++z1nVJDpEofw9V2oWKqOWzTJlJf1UXVbDE6Hg30CapJxZu5ga4fdAQc/gODDkKg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.2.0.tgz", + "integrity": "sha512-f4K3MKw9Y4AKi4ANGnmPIglr+S+8tO858YrGVuqAHXxJdVghBmz9CPU9kDpOnGvT4g4vg5uNyIFpOOFvffXyMA==", "cpu": [ "arm" ], @@ -1711,9 +1711,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.1.4.tgz", - "integrity": "sha512-TzJ+N2EoTLWkaClV2CUhBlj6ljXofaYzF/R9HXqQ3JCMnCHQZmQnbnZllw7yTDp0OG5whP4gIPozR4QiX+00MQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.2.0.tgz", + "integrity": "sha512-bNsTYQBgp4H7w6cT7FZhesxpcUPahsSIy4NgdZjH1ZwEoZHxi4XKglj+CsSEkhsKi+x6toVvMylhjRKhEMYfnA==", "cpu": [ "arm64" ], @@ -1724,9 +1724,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.1.4.tgz", - "integrity": "sha512-aVPmNMdp6Dlo2tWkAduAD/5TL/NT5uor290YvjvFvCv0Q3L7tVdlD8MOGDL+oRSw5XKXKAsDzHhUOPUNPRHVTQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.2.0.tgz", + "integrity": "sha512-Jp1NxBJpGLuxRU2ihrQk4IZ+ia5nffobG6sOFUPW5PMYkF0kQtxEbeDuCa69Xif211vUOcxlOnf5IOEIpTEySA==", "cpu": [ "arm64" ], @@ -1737,9 +1737,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.1.4.tgz", - "integrity": "sha512-77Fb79ayiDad0grvVsz4/OB55wJRyw9Ao+GdOBA9XywtHpuq5iRbVyHToGxWquYWlEf6WHFQQnFEttsAzboyKg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.2.0.tgz", + "integrity": "sha512-3p3iRtQmv2aXw+vtKNyZMLOQ+LSRsqArXjKAh2Oj9cqwfIRe7OXvdkOzWfZOIp1F/x5KJzVAxGxnniF4cMbnsQ==", "cpu": [ "x64" ], @@ -1750,9 +1750,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.1.4.tgz", - "integrity": "sha512-/t6C6niEQTqmQTVTD9TDwUzxG91Mlk69/v0qodIPUnjjB3wR4UA3klg+orR2SU3Ux2Cgf2pWPL9utK80/1ek8g==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.2.0.tgz", + "integrity": "sha512-atih7IF/reUZe4LBLC5Izd44hth2tfDIG8LaPp4/cQXdHh9jabcZEvIeRPrpDq0i/Uu487Qu5gl5KwyAnWajnw==", "cpu": [ "x64" ], @@ -1763,9 +1763,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.1.4.tgz", - "integrity": "sha512-ZY5BHHrOPkMbCuGWFNpJH0t18D2LU6GMYKGaqaWTQ3CQOL57Fem4zE941/Ek5pIsVt70HyDXssVEFQXlITI5Gg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.2.0.tgz", + "integrity": "sha512-vYxF3tKJeUE4ceYzpNe2p84RXk/fGK30I8frpRfv/MyPStej/mRlojztkN7Jtd1014HHVeq/tYaMBz/3IxkxZw==", "cpu": [ "arm64" ], @@ -1776,9 +1776,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.1.4.tgz", - "integrity": "sha512-XG2mcRfFrJvYyYaQmvCIvgfkaGinfXrpkBuIbJrTl9SaIQ8HumheWTIwkNz2mktCKwZfXHQNpO7RgXLIGQ7HXA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.2.0.tgz", + "integrity": "sha512-1LZJ6zpl93SaPQvas618bMFarVwufWTaczH4ESAbFcwiC4OtznA6Ym+hFPyIGaJaGEB8uMWWac0uXGPXOg5FGA==", "cpu": [ "ia32" ], @@ -1789,9 +1789,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.1.4.tgz", - "integrity": "sha512-ANFqWYPwkhIqPmXw8vm0GpBEHiPpqcm99jiiAp71DbCSqLDhrtr019C5vhD0Bw4My+LmMvciZq6IsWHqQpl2ZQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.2.0.tgz", + "integrity": "sha512-dgQfFdHCNg08nM5zBmqxqc9vrm0DVzhWotpavbPa0j4//MAOKZEB75yGAfzQE9fUJ+4pvM1239Y4IhL8f6sSog==", "cpu": [ "x64" ], @@ -6298,9 +6298,9 @@ } }, "node_modules/rollup": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.1.4.tgz", - "integrity": "sha512-U8Yk1lQRKqCkDBip/pMYT+IKaN7b7UesK3fLSTuHBoBJacCE+oBqo/dfG/gkUdQNNB2OBmRP98cn2C2bkYZkyw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.2.0.tgz", + "integrity": "sha512-deaMa9Z+jPVeBD2dKXv+h7EbdKte9++V2potc/ADqvVgEr6DEJ3ia9u0joarjC2lX/ubaCRYz3QVx0TzuVqAJA==", "dev": true, "bin": { "rollup": "dist/bin/rollup" @@ -6310,18 +6310,18 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.1.4", - "@rollup/rollup-android-arm64": "4.1.4", - "@rollup/rollup-darwin-arm64": "4.1.4", - "@rollup/rollup-darwin-x64": "4.1.4", - "@rollup/rollup-linux-arm-gnueabihf": "4.1.4", - "@rollup/rollup-linux-arm64-gnu": "4.1.4", - "@rollup/rollup-linux-arm64-musl": "4.1.4", - "@rollup/rollup-linux-x64-gnu": "4.1.4", - "@rollup/rollup-linux-x64-musl": "4.1.4", - "@rollup/rollup-win32-arm64-msvc": "4.1.4", - "@rollup/rollup-win32-ia32-msvc": "4.1.4", - "@rollup/rollup-win32-x64-msvc": "4.1.4", + "@rollup/rollup-android-arm-eabi": "4.2.0", + "@rollup/rollup-android-arm64": "4.2.0", + "@rollup/rollup-darwin-arm64": "4.2.0", + "@rollup/rollup-darwin-x64": "4.2.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.2.0", + "@rollup/rollup-linux-arm64-gnu": "4.2.0", + "@rollup/rollup-linux-arm64-musl": "4.2.0", + "@rollup/rollup-linux-x64-gnu": "4.2.0", + "@rollup/rollup-linux-x64-musl": "4.2.0", + "@rollup/rollup-win32-arm64-msvc": "4.2.0", + "@rollup/rollup-win32-ia32-msvc": "4.2.0", + "@rollup/rollup-win32-x64-msvc": "4.2.0", "fsevents": "~2.3.2" } }, @@ -8533,86 +8533,86 @@ } }, "@rollup/rollup-android-arm-eabi": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.1.4.tgz", - "integrity": "sha512-WlzkuFvpKl6CLFdc3V6ESPt7gq5Vrimd2Yv9IzKXdOpgbH4cdDSS1JLiACX8toygihtH5OlxyQzhXOph7Ovlpw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.2.0.tgz", + "integrity": "sha512-8PlggAxGxavr+pkCNeV1TM2wTb2o+cUWDg9M1cm9nR27Dsn287uZtSLYXoQqQcmq+sYfF7lHfd3sWJJinH9GmA==", "dev": true, "optional": true }, "@rollup/rollup-android-arm64": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.1.4.tgz", - "integrity": "sha512-D1e+ABe56T9Pq2fD+R3ybe1ylCDzu3tY4Qm2Mj24R9wXNCq35+JbFbOpc2yrroO2/tGhTobmEl2Bm5xfE/n8RA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.2.0.tgz", + "integrity": "sha512-+71T85hbMFrJI+zKQULNmSYBeIhru55PYoF/u75MyeN2FcxE4HSPw20319b+FcZ4lWx2Nx/Ql9tN+hoaD3GH/A==", "dev": true, "optional": true }, "@rollup/rollup-darwin-arm64": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.1.4.tgz", - "integrity": "sha512-7vTYrgEiOrjxnjsgdPB+4i7EMxbVp7XXtS+50GJYj695xYTTEMn3HZVEvgtwjOUkAP/Q4HDejm4fIAjLeAfhtg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.2.0.tgz", + "integrity": "sha512-IIIQLuG43QIElT1JZqUP/zqIdiJl4t9U/boa0GZnQTw9m1X0k3mlBuysbgYXeloLT1RozdL7bgw4lpSaI8GOXw==", "dev": true, "optional": true }, "@rollup/rollup-darwin-x64": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.1.4.tgz", - "integrity": "sha512-eGJVZScKSLZkYjhTAESCtbyTBq9SXeW9+TX36ki5gVhDqJtnQ5k0f9F44jNK5RhAMgIj0Ht9+n6HAgH0gUUyWQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.2.0.tgz", + "integrity": "sha512-BXcXvnLaea1Xz900omrGJhxHFJfH9jZ0CpJuVsbjjhpniJ6qiLXz3xA8Lekaa4MuhFcJd4f0r+Ky1G4VFbYhWw==", "dev": true, "optional": true }, "@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.1.4.tgz", - "integrity": "sha512-HnigYSEg2hOdX1meROecbk++z1nVJDpEofw9V2oWKqOWzTJlJf1UXVbDE6Hg30CapJxZu5ga4fdAQc/gODDkKg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.2.0.tgz", + "integrity": "sha512-f4K3MKw9Y4AKi4ANGnmPIglr+S+8tO858YrGVuqAHXxJdVghBmz9CPU9kDpOnGvT4g4vg5uNyIFpOOFvffXyMA==", "dev": true, "optional": true }, "@rollup/rollup-linux-arm64-gnu": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.1.4.tgz", - "integrity": "sha512-TzJ+N2EoTLWkaClV2CUhBlj6ljXofaYzF/R9HXqQ3JCMnCHQZmQnbnZllw7yTDp0OG5whP4gIPozR4QiX+00MQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.2.0.tgz", + "integrity": "sha512-bNsTYQBgp4H7w6cT7FZhesxpcUPahsSIy4NgdZjH1ZwEoZHxi4XKglj+CsSEkhsKi+x6toVvMylhjRKhEMYfnA==", "dev": true, "optional": true }, "@rollup/rollup-linux-arm64-musl": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.1.4.tgz", - "integrity": "sha512-aVPmNMdp6Dlo2tWkAduAD/5TL/NT5uor290YvjvFvCv0Q3L7tVdlD8MOGDL+oRSw5XKXKAsDzHhUOPUNPRHVTQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.2.0.tgz", + "integrity": "sha512-Jp1NxBJpGLuxRU2ihrQk4IZ+ia5nffobG6sOFUPW5PMYkF0kQtxEbeDuCa69Xif211vUOcxlOnf5IOEIpTEySA==", "dev": true, "optional": true }, "@rollup/rollup-linux-x64-gnu": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.1.4.tgz", - "integrity": "sha512-77Fb79ayiDad0grvVsz4/OB55wJRyw9Ao+GdOBA9XywtHpuq5iRbVyHToGxWquYWlEf6WHFQQnFEttsAzboyKg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.2.0.tgz", + "integrity": "sha512-3p3iRtQmv2aXw+vtKNyZMLOQ+LSRsqArXjKAh2Oj9cqwfIRe7OXvdkOzWfZOIp1F/x5KJzVAxGxnniF4cMbnsQ==", "dev": true, "optional": true }, "@rollup/rollup-linux-x64-musl": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.1.4.tgz", - "integrity": "sha512-/t6C6niEQTqmQTVTD9TDwUzxG91Mlk69/v0qodIPUnjjB3wR4UA3klg+orR2SU3Ux2Cgf2pWPL9utK80/1ek8g==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.2.0.tgz", + "integrity": "sha512-atih7IF/reUZe4LBLC5Izd44hth2tfDIG8LaPp4/cQXdHh9jabcZEvIeRPrpDq0i/Uu487Qu5gl5KwyAnWajnw==", "dev": true, "optional": true }, "@rollup/rollup-win32-arm64-msvc": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.1.4.tgz", - "integrity": "sha512-ZY5BHHrOPkMbCuGWFNpJH0t18D2LU6GMYKGaqaWTQ3CQOL57Fem4zE941/Ek5pIsVt70HyDXssVEFQXlITI5Gg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.2.0.tgz", + "integrity": "sha512-vYxF3tKJeUE4ceYzpNe2p84RXk/fGK30I8frpRfv/MyPStej/mRlojztkN7Jtd1014HHVeq/tYaMBz/3IxkxZw==", "dev": true, "optional": true }, "@rollup/rollup-win32-ia32-msvc": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.1.4.tgz", - "integrity": "sha512-XG2mcRfFrJvYyYaQmvCIvgfkaGinfXrpkBuIbJrTl9SaIQ8HumheWTIwkNz2mktCKwZfXHQNpO7RgXLIGQ7HXA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.2.0.tgz", + "integrity": "sha512-1LZJ6zpl93SaPQvas618bMFarVwufWTaczH4ESAbFcwiC4OtznA6Ym+hFPyIGaJaGEB8uMWWac0uXGPXOg5FGA==", "dev": true, "optional": true }, "@rollup/rollup-win32-x64-msvc": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.1.4.tgz", - "integrity": "sha512-ANFqWYPwkhIqPmXw8vm0GpBEHiPpqcm99jiiAp71DbCSqLDhrtr019C5vhD0Bw4My+LmMvciZq6IsWHqQpl2ZQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.2.0.tgz", + "integrity": "sha512-dgQfFdHCNg08nM5zBmqxqc9vrm0DVzhWotpavbPa0j4//MAOKZEB75yGAfzQE9fUJ+4pvM1239Y4IhL8f6sSog==", "dev": true, "optional": true }, @@ -11931,23 +11931,23 @@ } }, "rollup": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.1.4.tgz", - "integrity": "sha512-U8Yk1lQRKqCkDBip/pMYT+IKaN7b7UesK3fLSTuHBoBJacCE+oBqo/dfG/gkUdQNNB2OBmRP98cn2C2bkYZkyw==", - "dev": true, - "requires": { - "@rollup/rollup-android-arm-eabi": "4.1.4", - "@rollup/rollup-android-arm64": "4.1.4", - "@rollup/rollup-darwin-arm64": "4.1.4", - "@rollup/rollup-darwin-x64": "4.1.4", - "@rollup/rollup-linux-arm-gnueabihf": "4.1.4", - "@rollup/rollup-linux-arm64-gnu": "4.1.4", - "@rollup/rollup-linux-arm64-musl": "4.1.4", - "@rollup/rollup-linux-x64-gnu": "4.1.4", - "@rollup/rollup-linux-x64-musl": "4.1.4", - "@rollup/rollup-win32-arm64-msvc": "4.1.4", - "@rollup/rollup-win32-ia32-msvc": "4.1.4", - "@rollup/rollup-win32-x64-msvc": "4.1.4", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.2.0.tgz", + "integrity": "sha512-deaMa9Z+jPVeBD2dKXv+h7EbdKte9++V2potc/ADqvVgEr6DEJ3ia9u0joarjC2lX/ubaCRYz3QVx0TzuVqAJA==", + "dev": true, + "requires": { + "@rollup/rollup-android-arm-eabi": "4.2.0", + "@rollup/rollup-android-arm64": "4.2.0", + "@rollup/rollup-darwin-arm64": "4.2.0", + "@rollup/rollup-darwin-x64": "4.2.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.2.0", + "@rollup/rollup-linux-arm64-gnu": "4.2.0", + "@rollup/rollup-linux-arm64-musl": "4.2.0", + "@rollup/rollup-linux-x64-gnu": "4.2.0", + "@rollup/rollup-linux-x64-musl": "4.2.0", + "@rollup/rollup-win32-arm64-msvc": "4.2.0", + "@rollup/rollup-win32-ia32-msvc": "4.2.0", + "@rollup/rollup-win32-x64-msvc": "4.2.0", "fsevents": "~2.3.2" } }, From 63b96598aeade190f1ecd9ed8ebb8e05a2fcfcd4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Nov 2023 19:14:50 +0100 Subject: [PATCH 0580/1076] build(deps-dev): bump @types/node-fetch from 2.6.7 to 2.6.8 in /stake-pool/js (#5717) build(deps-dev): bump @types/node-fetch in /stake-pool/js Bumps [@types/node-fetch](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node-fetch) from 2.6.7 to 2.6.8. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node-fetch) --- updated-dependencies: - dependency-name: "@types/node-fetch" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index b449e8bd..bfe96b9e 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -2013,9 +2013,9 @@ } }, "node_modules/@types/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-lX17GZVpJ/fuCjguZ5b3TjEbSENxmEk1B2z02yoXSK9WMEWRivhdSY73wWMn6bpcCDAOh6qAdktpKHIlkDk2lg==", + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.8.tgz", + "integrity": "sha512-nnH5lV9QCMPsbEVdTb5Y+F3GQxLSw1xQgIydrb2gSfEavRPs50FnMr+KUaa+LoPSqibm2N+ZZxH7lavZlAT4GA==", "dev": true, "dependencies": { "@types/node": "*", @@ -8813,9 +8813,9 @@ } }, "@types/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-lX17GZVpJ/fuCjguZ5b3TjEbSENxmEk1B2z02yoXSK9WMEWRivhdSY73wWMn6bpcCDAOh6qAdktpKHIlkDk2lg==", + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.8.tgz", + "integrity": "sha512-nnH5lV9QCMPsbEVdTb5Y+F3GQxLSw1xQgIydrb2gSfEavRPs50FnMr+KUaa+LoPSqibm2N+ZZxH7lavZlAT4GA==", "dev": true, "requires": { "@types/node": "*", From b921648464d0b235d7c4a831992893640e6d3706 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Nov 2023 19:14:56 +0100 Subject: [PATCH 0581/1076] build(deps-dev): bump @types/node from 20.8.9 to 20.8.10 in /stake-pool/js (#5718) build(deps-dev): bump @types/node in /stake-pool/js Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.8.9 to 20.8.10. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index bfe96b9e..e6fcf0df 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -2005,9 +2005,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.8.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.9.tgz", - "integrity": "sha512-UzykFsT3FhHb1h7yD4CA4YhBHq545JC0YnEz41xkipN88eKQtL6rSgocL5tbAP6Ola9Izm/Aw4Ora8He4x0BHg==", + "version": "20.8.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.10.tgz", + "integrity": "sha512-TlgT8JntpcbmKUFzjhsyhGfP2fsiz1Mv56im6enJ905xG1DAYesxJaeSbGqQmAw8OWPdhyJGhGSQGKRNJ45u9w==", "dependencies": { "undici-types": "~5.26.4" } @@ -8805,9 +8805,9 @@ "dev": true }, "@types/node": { - "version": "20.8.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.9.tgz", - "integrity": "sha512-UzykFsT3FhHb1h7yD4CA4YhBHq545JC0YnEz41xkipN88eKQtL6rSgocL5tbAP6Ola9Izm/Aw4Ora8He4x0BHg==", + "version": "20.8.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.10.tgz", + "integrity": "sha512-TlgT8JntpcbmKUFzjhsyhGfP2fsiz1Mv56im6enJ905xG1DAYesxJaeSbGqQmAw8OWPdhyJGhGSQGKRNJ45u9w==", "requires": { "undici-types": "~5.26.4" } From 5f0bff959eff304d606ffa41eaa6c4f89af149cb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Nov 2023 19:15:04 +0100 Subject: [PATCH 0582/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.9.0 to 6.9.1 in /stake-pool/js (#5719) build(deps-dev): bump @typescript-eslint/eslint-plugin in /stake-pool/js Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.9.0 to 6.9.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.9.1/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 249 ++++++++-------------------- 1 file changed, 66 insertions(+), 183 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index e6fcf0df..602e3415 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -2084,16 +2084,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.9.0.tgz", - "integrity": "sha512-lgX7F0azQwRPB7t7WAyeHWVfW1YJ9NIgd9mvGhfQpRY56X6AVf8mwM8Wol+0z4liE7XX3QOt8MN1rUKCfSjRIA==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.9.1.tgz", + "integrity": "sha512-w0tiiRc9I4S5XSXXrMHOWgHgxbrBn1Ro+PmiYhSg2ZVdxrAJtQgzU5o2m1BfP6UOn7Vxcc6152vFjQfmZR4xEg==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.9.0", - "@typescript-eslint/type-utils": "6.9.0", - "@typescript-eslint/utils": "6.9.0", - "@typescript-eslint/visitor-keys": "6.9.0", + "@typescript-eslint/scope-manager": "6.9.1", + "@typescript-eslint/type-utils": "6.9.1", + "@typescript-eslint/utils": "6.9.1", + "@typescript-eslint/visitor-keys": "6.9.1", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -2146,7 +2146,7 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "node_modules/@typescript-eslint/scope-manager": { "version": "6.9.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.1.tgz", "integrity": "sha512-38IxvKB6NAne3g/+MyXMs2Cda/Sz+CEpmm+KLGEM8hx/CvnSRuw51i8ukfwB/B/sESdeTGet1NH1Wj7I0YXswg==", @@ -2163,88 +2163,14 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.1.tgz", - "integrity": "sha512-BUGslGOb14zUHOUmDB2FfT6SI1CcZEJYfF3qFwBeUrU6srJfzANonwRYHDpLBuzbq3HaoF2XL2hcr01c8f8OaQ==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.1.tgz", - "integrity": "sha512-U+mUylTHfcqeO7mLWVQ5W/tMLXqVpRv61wm9ZtfE5egz7gtnmqVIw9ryh0mgIlkKk9rZLY3UHygsBSdB9/ftyw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.9.1", - "@typescript-eslint/visitor-keys": "6.9.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.1.tgz", - "integrity": "sha512-MUaPUe/QRLEffARsmNfmpghuQkW436DvESW+h+M52w0coICHRfD6Np9/K6PdACwnrq1HmuLl+cSPZaJmeVPkSw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.9.1", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.0.tgz", - "integrity": "sha512-1R8A9Mc39n4pCCz9o79qRO31HGNDvC7UhPhv26TovDsWPBDx+Sg3rOZdCELIA3ZmNoWAuxaMOT7aWtGRSYkQxw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.9.0", - "@typescript-eslint/visitor-keys": "6.9.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.9.0.tgz", - "integrity": "sha512-XXeahmfbpuhVbhSOROIzJ+b13krFmgtc4GlEuu1WBT+RpyGPIA4Y/eGnXzjbDj5gZLzpAXO/sj+IF/x2GtTMjQ==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.9.1.tgz", + "integrity": "sha512-eh2oHaUKCK58qIeYp19F5V5TbpM52680sB4zNSz29VBQPTWIlE/hCj5P5B1AChxECe/fmZlspAWFuRniep1Skg==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.9.0", - "@typescript-eslint/utils": "6.9.0", + "@typescript-eslint/typescript-estree": "6.9.1", + "@typescript-eslint/utils": "6.9.1", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -2265,9 +2191,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.0.tgz", - "integrity": "sha512-+KB0lbkpxBkBSiVCuQvduqMJy+I1FyDbdwSpM3IoBS7APl4Bu15lStPjgBIdykdRqQNYqYNMa8Kuidax6phaEw==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.1.tgz", + "integrity": "sha512-BUGslGOb14zUHOUmDB2FfT6SI1CcZEJYfF3qFwBeUrU6srJfzANonwRYHDpLBuzbq3HaoF2XL2hcr01c8f8OaQ==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -2278,13 +2204,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.0.tgz", - "integrity": "sha512-NJM2BnJFZBEAbCfBP00zONKXvMqihZCrmwCaik0UhLr0vAgb6oguXxLX1k00oQyD+vZZ+CJn3kocvv2yxm4awQ==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.1.tgz", + "integrity": "sha512-U+mUylTHfcqeO7mLWVQ5W/tMLXqVpRv61wm9ZtfE5egz7gtnmqVIw9ryh0mgIlkKk9rZLY3UHygsBSdB9/ftyw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.9.0", - "@typescript-eslint/visitor-keys": "6.9.0", + "@typescript-eslint/types": "6.9.1", + "@typescript-eslint/visitor-keys": "6.9.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2305,17 +2231,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.9.0.tgz", - "integrity": "sha512-5Wf+Jsqya7WcCO8me504FBigeQKVLAMPmUzYgDbWchINNh1KJbxCgVya3EQ2MjvJMVeXl3pofRmprqX6mfQkjQ==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.9.1.tgz", + "integrity": "sha512-L1T0A5nFdQrMVunpZgzqPL6y2wVreSyHhKGZryS6jrEN7bD9NplVAyMryUhXsQ4TWLnZmxc2ekar/lSGIlprCA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.9.0", - "@typescript-eslint/types": "6.9.0", - "@typescript-eslint/typescript-estree": "6.9.0", + "@typescript-eslint/scope-manager": "6.9.1", + "@typescript-eslint/types": "6.9.1", + "@typescript-eslint/typescript-estree": "6.9.1", "semver": "^7.5.4" }, "engines": { @@ -2330,12 +2256,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.0.tgz", - "integrity": "sha512-dGtAfqjV6RFOtIP8I0B4ZTBRrlTT8NHHlZZSchQx3qReaoDeXhYM++M4So2AgFK9ZB0emRPA6JI1HkafzA2Ibg==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.1.tgz", + "integrity": "sha512-MUaPUe/QRLEffARsmNfmpghuQkW436DvESW+h+M52w0coICHRfD6Np9/K6PdACwnrq1HmuLl+cSPZaJmeVPkSw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.9.0", + "@typescript-eslint/types": "6.9.1", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -8883,16 +8809,16 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.9.0.tgz", - "integrity": "sha512-lgX7F0azQwRPB7t7WAyeHWVfW1YJ9NIgd9mvGhfQpRY56X6AVf8mwM8Wol+0z4liE7XX3QOt8MN1rUKCfSjRIA==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.9.1.tgz", + "integrity": "sha512-w0tiiRc9I4S5XSXXrMHOWgHgxbrBn1Ro+PmiYhSg2ZVdxrAJtQgzU5o2m1BfP6UOn7Vxcc6152vFjQfmZR4xEg==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.9.0", - "@typescript-eslint/type-utils": "6.9.0", - "@typescript-eslint/utils": "6.9.0", - "@typescript-eslint/visitor-keys": "6.9.0", + "@typescript-eslint/scope-manager": "6.9.1", + "@typescript-eslint/type-utils": "6.9.1", + "@typescript-eslint/utils": "6.9.1", + "@typescript-eslint/visitor-keys": "6.9.1", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -8912,87 +8838,44 @@ "@typescript-eslint/typescript-estree": "6.9.1", "@typescript-eslint/visitor-keys": "6.9.1", "debug": "^4.3.4" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.1.tgz", - "integrity": "sha512-38IxvKB6NAne3g/+MyXMs2Cda/Sz+CEpmm+KLGEM8hx/CvnSRuw51i8ukfwB/B/sESdeTGet1NH1Wj7I0YXswg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.9.1", - "@typescript-eslint/visitor-keys": "6.9.1" - } - }, - "@typescript-eslint/types": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.1.tgz", - "integrity": "sha512-BUGslGOb14zUHOUmDB2FfT6SI1CcZEJYfF3qFwBeUrU6srJfzANonwRYHDpLBuzbq3HaoF2XL2hcr01c8f8OaQ==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.1.tgz", - "integrity": "sha512-U+mUylTHfcqeO7mLWVQ5W/tMLXqVpRv61wm9ZtfE5egz7gtnmqVIw9ryh0mgIlkKk9rZLY3UHygsBSdB9/ftyw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.9.1", - "@typescript-eslint/visitor-keys": "6.9.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.1.tgz", - "integrity": "sha512-MUaPUe/QRLEffARsmNfmpghuQkW436DvESW+h+M52w0coICHRfD6Np9/K6PdACwnrq1HmuLl+cSPZaJmeVPkSw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.9.1", - "eslint-visitor-keys": "^3.4.1" - } - } } }, "@typescript-eslint/scope-manager": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.0.tgz", - "integrity": "sha512-1R8A9Mc39n4pCCz9o79qRO31HGNDvC7UhPhv26TovDsWPBDx+Sg3rOZdCELIA3ZmNoWAuxaMOT7aWtGRSYkQxw==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.1.tgz", + "integrity": "sha512-38IxvKB6NAne3g/+MyXMs2Cda/Sz+CEpmm+KLGEM8hx/CvnSRuw51i8ukfwB/B/sESdeTGet1NH1Wj7I0YXswg==", "dev": true, "requires": { - "@typescript-eslint/types": "6.9.0", - "@typescript-eslint/visitor-keys": "6.9.0" + "@typescript-eslint/types": "6.9.1", + "@typescript-eslint/visitor-keys": "6.9.1" } }, "@typescript-eslint/type-utils": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.9.0.tgz", - "integrity": "sha512-XXeahmfbpuhVbhSOROIzJ+b13krFmgtc4GlEuu1WBT+RpyGPIA4Y/eGnXzjbDj5gZLzpAXO/sj+IF/x2GtTMjQ==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.9.1.tgz", + "integrity": "sha512-eh2oHaUKCK58qIeYp19F5V5TbpM52680sB4zNSz29VBQPTWIlE/hCj5P5B1AChxECe/fmZlspAWFuRniep1Skg==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "6.9.0", - "@typescript-eslint/utils": "6.9.0", + "@typescript-eslint/typescript-estree": "6.9.1", + "@typescript-eslint/utils": "6.9.1", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" } }, "@typescript-eslint/types": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.0.tgz", - "integrity": "sha512-+KB0lbkpxBkBSiVCuQvduqMJy+I1FyDbdwSpM3IoBS7APl4Bu15lStPjgBIdykdRqQNYqYNMa8Kuidax6phaEw==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.1.tgz", + "integrity": "sha512-BUGslGOb14zUHOUmDB2FfT6SI1CcZEJYfF3qFwBeUrU6srJfzANonwRYHDpLBuzbq3HaoF2XL2hcr01c8f8OaQ==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.0.tgz", - "integrity": "sha512-NJM2BnJFZBEAbCfBP00zONKXvMqihZCrmwCaik0UhLr0vAgb6oguXxLX1k00oQyD+vZZ+CJn3kocvv2yxm4awQ==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.1.tgz", + "integrity": "sha512-U+mUylTHfcqeO7mLWVQ5W/tMLXqVpRv61wm9ZtfE5egz7gtnmqVIw9ryh0mgIlkKk9rZLY3UHygsBSdB9/ftyw==", "dev": true, "requires": { - "@typescript-eslint/types": "6.9.0", - "@typescript-eslint/visitor-keys": "6.9.0", + "@typescript-eslint/types": "6.9.1", + "@typescript-eslint/visitor-keys": "6.9.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -9001,27 +8884,27 @@ } }, "@typescript-eslint/utils": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.9.0.tgz", - "integrity": "sha512-5Wf+Jsqya7WcCO8me504FBigeQKVLAMPmUzYgDbWchINNh1KJbxCgVya3EQ2MjvJMVeXl3pofRmprqX6mfQkjQ==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.9.1.tgz", + "integrity": "sha512-L1T0A5nFdQrMVunpZgzqPL6y2wVreSyHhKGZryS6jrEN7bD9NplVAyMryUhXsQ4TWLnZmxc2ekar/lSGIlprCA==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.9.0", - "@typescript-eslint/types": "6.9.0", - "@typescript-eslint/typescript-estree": "6.9.0", + "@typescript-eslint/scope-manager": "6.9.1", + "@typescript-eslint/types": "6.9.1", + "@typescript-eslint/typescript-estree": "6.9.1", "semver": "^7.5.4" } }, "@typescript-eslint/visitor-keys": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.0.tgz", - "integrity": "sha512-dGtAfqjV6RFOtIP8I0B4ZTBRrlTT8NHHlZZSchQx3qReaoDeXhYM++M4So2AgFK9ZB0emRPA6JI1HkafzA2Ibg==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.1.tgz", + "integrity": "sha512-MUaPUe/QRLEffARsmNfmpghuQkW436DvESW+h+M52w0coICHRfD6Np9/K6PdACwnrq1HmuLl+cSPZaJmeVPkSw==", "dev": true, "requires": { - "@typescript-eslint/types": "6.9.0", + "@typescript-eslint/types": "6.9.1", "eslint-visitor-keys": "^3.4.1" } }, From aa3e56b9eca075fe207bf67f2107ba39f0b4b8a3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Nov 2023 22:48:28 +0100 Subject: [PATCH 0583/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.9.1 to 6.10.0 in /stake-pool/js (#5753) build(deps-dev): bump @typescript-eslint/eslint-plugin in /stake-pool/js Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.9.1 to 6.10.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.10.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 366 ++++++++++++++++++++++++---- 1 file changed, 324 insertions(+), 42 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 602e3415..187bf738 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -1999,9 +1999,9 @@ } }, "node_modules/@types/json-schema": { - "version": "7.0.14", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.14.tgz", - "integrity": "sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw==", + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, "node_modules/@types/node": { @@ -2084,16 +2084,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.9.1.tgz", - "integrity": "sha512-w0tiiRc9I4S5XSXXrMHOWgHgxbrBn1Ro+PmiYhSg2ZVdxrAJtQgzU5o2m1BfP6UOn7Vxcc6152vFjQfmZR4xEg==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.10.0.tgz", + "integrity": "sha512-uoLj4g2OTL8rfUQVx2AFO1hp/zja1wABJq77P6IclQs6I/m9GLrm7jCdgzZkvWdDCQf1uEvoa8s8CupsgWQgVg==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.9.1", - "@typescript-eslint/type-utils": "6.9.1", - "@typescript-eslint/utils": "6.9.1", - "@typescript-eslint/visitor-keys": "6.9.1", + "@typescript-eslint/scope-manager": "6.10.0", + "@typescript-eslint/type-utils": "6.10.0", + "@typescript-eslint/utils": "6.10.0", + "@typescript-eslint/visitor-keys": "6.10.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -2118,6 +2118,53 @@ } } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.10.0.tgz", + "integrity": "sha512-TN/plV7dzqqC2iPNf1KrxozDgZs53Gfgg5ZHyw8erd6jd5Ta/JIEcdCheXFt9b1NYb93a1wmIIVW/2gLkombDg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.10.0", + "@typescript-eslint/visitor-keys": "6.10.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.10.0.tgz", + "integrity": "sha512-36Fq1PWh9dusgo3vH7qmQAj5/AZqARky1Wi6WpINxB6SkQdY5vQoT2/7rW7uBIsPDcvvGCLi4r10p0OJ7ITAeg==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.10.0.tgz", + "integrity": "sha512-xMGluxQIEtOM7bqFCo+rCMh5fqI+ZxV5RUUOa29iVPz1OgCZrtc7rFnz5cLUazlkPKYqX+75iuDq7m0HQ48nCg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.10.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/parser": { "version": "6.9.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.9.1.tgz", @@ -2164,13 +2211,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.9.1.tgz", - "integrity": "sha512-eh2oHaUKCK58qIeYp19F5V5TbpM52680sB4zNSz29VBQPTWIlE/hCj5P5B1AChxECe/fmZlspAWFuRniep1Skg==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.10.0.tgz", + "integrity": "sha512-wYpPs3hgTFblMYwbYWPT3eZtaDOjbLyIYuqpwuLBBqhLiuvJ+9sEp2gNRJEtR5N/c9G1uTtQQL5AhV0fEPJYcg==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.9.1", - "@typescript-eslint/utils": "6.9.1", + "@typescript-eslint/typescript-estree": "6.10.0", + "@typescript-eslint/utils": "6.10.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -2190,6 +2237,63 @@ } } }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.10.0.tgz", + "integrity": "sha512-36Fq1PWh9dusgo3vH7qmQAj5/AZqARky1Wi6WpINxB6SkQdY5vQoT2/7rW7uBIsPDcvvGCLi4r10p0OJ7ITAeg==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.10.0.tgz", + "integrity": "sha512-ek0Eyuy6P15LJVeghbWhSrBCj/vJpPXXR+EpaRZqou7achUWL8IdYnMSC5WHAeTWswYQuP2hAZgij/bC9fanBg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.10.0", + "@typescript-eslint/visitor-keys": "6.10.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.10.0.tgz", + "integrity": "sha512-xMGluxQIEtOM7bqFCo+rCMh5fqI+ZxV5RUUOa29iVPz1OgCZrtc7rFnz5cLUazlkPKYqX+75iuDq7m0HQ48nCg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.10.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/types": { "version": "6.9.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.1.tgz", @@ -2231,17 +2335,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.9.1.tgz", - "integrity": "sha512-L1T0A5nFdQrMVunpZgzqPL6y2wVreSyHhKGZryS6jrEN7bD9NplVAyMryUhXsQ4TWLnZmxc2ekar/lSGIlprCA==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.10.0.tgz", + "integrity": "sha512-v+pJ1/RcVyRc0o4wAGux9x42RHmAjIGzPRo538Z8M1tVx6HOnoQBCX/NoadHQlZeC+QO2yr4nNSFWOoraZCAyg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.9.1", - "@typescript-eslint/types": "6.9.1", - "@typescript-eslint/typescript-estree": "6.9.1", + "@typescript-eslint/scope-manager": "6.10.0", + "@typescript-eslint/types": "6.10.0", + "@typescript-eslint/typescript-estree": "6.10.0", "semver": "^7.5.4" }, "engines": { @@ -2255,6 +2359,80 @@ "eslint": "^7.0.0 || ^8.0.0" } }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.10.0.tgz", + "integrity": "sha512-TN/plV7dzqqC2iPNf1KrxozDgZs53Gfgg5ZHyw8erd6jd5Ta/JIEcdCheXFt9b1NYb93a1wmIIVW/2gLkombDg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.10.0", + "@typescript-eslint/visitor-keys": "6.10.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.10.0.tgz", + "integrity": "sha512-36Fq1PWh9dusgo3vH7qmQAj5/AZqARky1Wi6WpINxB6SkQdY5vQoT2/7rW7uBIsPDcvvGCLi4r10p0OJ7ITAeg==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.10.0.tgz", + "integrity": "sha512-ek0Eyuy6P15LJVeghbWhSrBCj/vJpPXXR+EpaRZqou7achUWL8IdYnMSC5WHAeTWswYQuP2hAZgij/bC9fanBg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.10.0", + "@typescript-eslint/visitor-keys": "6.10.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.10.0.tgz", + "integrity": "sha512-xMGluxQIEtOM7bqFCo+rCMh5fqI+ZxV5RUUOa29iVPz1OgCZrtc7rFnz5cLUazlkPKYqX+75iuDq7m0HQ48nCg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.10.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/visitor-keys": { "version": "6.9.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.1.tgz", @@ -8725,9 +8903,9 @@ } }, "@types/json-schema": { - "version": "7.0.14", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.14.tgz", - "integrity": "sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw==", + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, "@types/node": { @@ -8809,22 +8987,50 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.9.1.tgz", - "integrity": "sha512-w0tiiRc9I4S5XSXXrMHOWgHgxbrBn1Ro+PmiYhSg2ZVdxrAJtQgzU5o2m1BfP6UOn7Vxcc6152vFjQfmZR4xEg==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.10.0.tgz", + "integrity": "sha512-uoLj4g2OTL8rfUQVx2AFO1hp/zja1wABJq77P6IclQs6I/m9GLrm7jCdgzZkvWdDCQf1uEvoa8s8CupsgWQgVg==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.9.1", - "@typescript-eslint/type-utils": "6.9.1", - "@typescript-eslint/utils": "6.9.1", - "@typescript-eslint/visitor-keys": "6.9.1", + "@typescript-eslint/scope-manager": "6.10.0", + "@typescript-eslint/type-utils": "6.10.0", + "@typescript-eslint/utils": "6.10.0", + "@typescript-eslint/visitor-keys": "6.10.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", "natural-compare": "^1.4.0", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.10.0.tgz", + "integrity": "sha512-TN/plV7dzqqC2iPNf1KrxozDgZs53Gfgg5ZHyw8erd6jd5Ta/JIEcdCheXFt9b1NYb93a1wmIIVW/2gLkombDg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.10.0", + "@typescript-eslint/visitor-keys": "6.10.0" + } + }, + "@typescript-eslint/types": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.10.0.tgz", + "integrity": "sha512-36Fq1PWh9dusgo3vH7qmQAj5/AZqARky1Wi6WpINxB6SkQdY5vQoT2/7rW7uBIsPDcvvGCLi4r10p0OJ7ITAeg==", + "dev": true + }, + "@typescript-eslint/visitor-keys": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.10.0.tgz", + "integrity": "sha512-xMGluxQIEtOM7bqFCo+rCMh5fqI+ZxV5RUUOa29iVPz1OgCZrtc7rFnz5cLUazlkPKYqX+75iuDq7m0HQ48nCg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.10.0", + "eslint-visitor-keys": "^3.4.1" + } + } } }, "@typescript-eslint/parser": { @@ -8851,15 +9057,48 @@ } }, "@typescript-eslint/type-utils": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.9.1.tgz", - "integrity": "sha512-eh2oHaUKCK58qIeYp19F5V5TbpM52680sB4zNSz29VBQPTWIlE/hCj5P5B1AChxECe/fmZlspAWFuRniep1Skg==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.10.0.tgz", + "integrity": "sha512-wYpPs3hgTFblMYwbYWPT3eZtaDOjbLyIYuqpwuLBBqhLiuvJ+9sEp2gNRJEtR5N/c9G1uTtQQL5AhV0fEPJYcg==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "6.9.1", - "@typescript-eslint/utils": "6.9.1", + "@typescript-eslint/typescript-estree": "6.10.0", + "@typescript-eslint/utils": "6.10.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" + }, + "dependencies": { + "@typescript-eslint/types": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.10.0.tgz", + "integrity": "sha512-36Fq1PWh9dusgo3vH7qmQAj5/AZqARky1Wi6WpINxB6SkQdY5vQoT2/7rW7uBIsPDcvvGCLi4r10p0OJ7ITAeg==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.10.0.tgz", + "integrity": "sha512-ek0Eyuy6P15LJVeghbWhSrBCj/vJpPXXR+EpaRZqou7achUWL8IdYnMSC5WHAeTWswYQuP2hAZgij/bC9fanBg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.10.0", + "@typescript-eslint/visitor-keys": "6.10.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.10.0.tgz", + "integrity": "sha512-xMGluxQIEtOM7bqFCo+rCMh5fqI+ZxV5RUUOa29iVPz1OgCZrtc7rFnz5cLUazlkPKYqX+75iuDq7m0HQ48nCg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.10.0", + "eslint-visitor-keys": "^3.4.1" + } + } } }, "@typescript-eslint/types": { @@ -8884,18 +9123,61 @@ } }, "@typescript-eslint/utils": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.9.1.tgz", - "integrity": "sha512-L1T0A5nFdQrMVunpZgzqPL6y2wVreSyHhKGZryS6jrEN7bD9NplVAyMryUhXsQ4TWLnZmxc2ekar/lSGIlprCA==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.10.0.tgz", + "integrity": "sha512-v+pJ1/RcVyRc0o4wAGux9x42RHmAjIGzPRo538Z8M1tVx6HOnoQBCX/NoadHQlZeC+QO2yr4nNSFWOoraZCAyg==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.9.1", - "@typescript-eslint/types": "6.9.1", - "@typescript-eslint/typescript-estree": "6.9.1", + "@typescript-eslint/scope-manager": "6.10.0", + "@typescript-eslint/types": "6.10.0", + "@typescript-eslint/typescript-estree": "6.10.0", "semver": "^7.5.4" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.10.0.tgz", + "integrity": "sha512-TN/plV7dzqqC2iPNf1KrxozDgZs53Gfgg5ZHyw8erd6jd5Ta/JIEcdCheXFt9b1NYb93a1wmIIVW/2gLkombDg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.10.0", + "@typescript-eslint/visitor-keys": "6.10.0" + } + }, + "@typescript-eslint/types": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.10.0.tgz", + "integrity": "sha512-36Fq1PWh9dusgo3vH7qmQAj5/AZqARky1Wi6WpINxB6SkQdY5vQoT2/7rW7uBIsPDcvvGCLi4r10p0OJ7ITAeg==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.10.0.tgz", + "integrity": "sha512-ek0Eyuy6P15LJVeghbWhSrBCj/vJpPXXR+EpaRZqou7achUWL8IdYnMSC5WHAeTWswYQuP2hAZgij/bC9fanBg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.10.0", + "@typescript-eslint/visitor-keys": "6.10.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.10.0.tgz", + "integrity": "sha512-xMGluxQIEtOM7bqFCo+rCMh5fqI+ZxV5RUUOa29iVPz1OgCZrtc7rFnz5cLUazlkPKYqX+75iuDq7m0HQ48nCg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.10.0", + "eslint-visitor-keys": "^3.4.1" + } + } } }, "@typescript-eslint/visitor-keys": { From a1f2f1683c97c73b83d35a8a03e9d36772273a0d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Nov 2023 22:48:35 +0100 Subject: [PATCH 0584/1076] build(deps-dev): bump @typescript-eslint/parser from 6.9.1 to 6.10.0 in /stake-pool/js (#5754) build(deps-dev): bump @typescript-eslint/parser in /stake-pool/js Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.9.1 to 6.10.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.10.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 145 +++++++++++++++++++++++++--- 1 file changed, 131 insertions(+), 14 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 187bf738..4cd4f458 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -2166,15 +2166,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.9.1.tgz", - "integrity": "sha512-C7AK2wn43GSaCUZ9do6Ksgi2g3mwFkMO3Cis96kzmgudoVaKyt62yNzJOktP0HDLb/iO2O0n2lBOzJgr6Q/cyg==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.10.0.tgz", + "integrity": "sha512-+sZwIj+s+io9ozSxIWbNB5873OSdfeBEH/FR0re14WLI6BaKuSOnnwCJ2foUiu8uXf4dRp1UqHP0vrZ1zXGrog==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.9.1", - "@typescript-eslint/types": "6.9.1", - "@typescript-eslint/typescript-estree": "6.9.1", - "@typescript-eslint/visitor-keys": "6.9.1", + "@typescript-eslint/scope-manager": "6.10.0", + "@typescript-eslint/types": "6.10.0", + "@typescript-eslint/typescript-estree": "6.10.0", + "@typescript-eslint/visitor-keys": "6.10.0", "debug": "^4.3.4" }, "engines": { @@ -2193,6 +2193,80 @@ } } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.10.0.tgz", + "integrity": "sha512-TN/plV7dzqqC2iPNf1KrxozDgZs53Gfgg5ZHyw8erd6jd5Ta/JIEcdCheXFt9b1NYb93a1wmIIVW/2gLkombDg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.10.0", + "@typescript-eslint/visitor-keys": "6.10.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.10.0.tgz", + "integrity": "sha512-36Fq1PWh9dusgo3vH7qmQAj5/AZqARky1Wi6WpINxB6SkQdY5vQoT2/7rW7uBIsPDcvvGCLi4r10p0OJ7ITAeg==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.10.0.tgz", + "integrity": "sha512-ek0Eyuy6P15LJVeghbWhSrBCj/vJpPXXR+EpaRZqou7achUWL8IdYnMSC5WHAeTWswYQuP2hAZgij/bC9fanBg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.10.0", + "@typescript-eslint/visitor-keys": "6.10.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.10.0.tgz", + "integrity": "sha512-xMGluxQIEtOM7bqFCo+rCMh5fqI+ZxV5RUUOa29iVPz1OgCZrtc7rFnz5cLUazlkPKYqX+75iuDq7m0HQ48nCg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.10.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "6.9.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.1.tgz", @@ -9034,16 +9108,59 @@ } }, "@typescript-eslint/parser": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.9.1.tgz", - "integrity": "sha512-C7AK2wn43GSaCUZ9do6Ksgi2g3mwFkMO3Cis96kzmgudoVaKyt62yNzJOktP0HDLb/iO2O0n2lBOzJgr6Q/cyg==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.10.0.tgz", + "integrity": "sha512-+sZwIj+s+io9ozSxIWbNB5873OSdfeBEH/FR0re14WLI6BaKuSOnnwCJ2foUiu8uXf4dRp1UqHP0vrZ1zXGrog==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "6.9.1", - "@typescript-eslint/types": "6.9.1", - "@typescript-eslint/typescript-estree": "6.9.1", - "@typescript-eslint/visitor-keys": "6.9.1", + "@typescript-eslint/scope-manager": "6.10.0", + "@typescript-eslint/types": "6.10.0", + "@typescript-eslint/typescript-estree": "6.10.0", + "@typescript-eslint/visitor-keys": "6.10.0", "debug": "^4.3.4" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.10.0.tgz", + "integrity": "sha512-TN/plV7dzqqC2iPNf1KrxozDgZs53Gfgg5ZHyw8erd6jd5Ta/JIEcdCheXFt9b1NYb93a1wmIIVW/2gLkombDg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.10.0", + "@typescript-eslint/visitor-keys": "6.10.0" + } + }, + "@typescript-eslint/types": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.10.0.tgz", + "integrity": "sha512-36Fq1PWh9dusgo3vH7qmQAj5/AZqARky1Wi6WpINxB6SkQdY5vQoT2/7rW7uBIsPDcvvGCLi4r10p0OJ7ITAeg==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.10.0.tgz", + "integrity": "sha512-ek0Eyuy6P15LJVeghbWhSrBCj/vJpPXXR+EpaRZqou7achUWL8IdYnMSC5WHAeTWswYQuP2hAZgij/bC9fanBg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.10.0", + "@typescript-eslint/visitor-keys": "6.10.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.10.0.tgz", + "integrity": "sha512-xMGluxQIEtOM7bqFCo+rCMh5fqI+ZxV5RUUOa29iVPz1OgCZrtc7rFnz5cLUazlkPKYqX+75iuDq7m0HQ48nCg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.10.0", + "eslint-visitor-keys": "^3.4.1" + } + } } }, "@typescript-eslint/scope-manager": { From ecb62cd2162009f7d28919c45ca80d884df3e0d5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Nov 2023 22:48:44 +0100 Subject: [PATCH 0585/1076] build(deps-dev): bump @types/node-fetch from 2.6.8 to 2.6.9 in /stake-pool/js (#5755) build(deps-dev): bump @types/node-fetch in /stake-pool/js Bumps [@types/node-fetch](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node-fetch) from 2.6.8 to 2.6.9. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node-fetch) --- updated-dependencies: - dependency-name: "@types/node-fetch" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json index 4cd4f458..38212424 100644 --- a/clients/js-legacy/package-lock.json +++ b/clients/js-legacy/package-lock.json @@ -2013,9 +2013,9 @@ } }, "node_modules/@types/node-fetch": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.8.tgz", - "integrity": "sha512-nnH5lV9QCMPsbEVdTb5Y+F3GQxLSw1xQgIydrb2gSfEavRPs50FnMr+KUaa+LoPSqibm2N+ZZxH7lavZlAT4GA==", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.9.tgz", + "integrity": "sha512-bQVlnMLFJ2d35DkPNjEPmd9ueO/rh5EiaZt2bhqiSarPjZIuIV6bPQVqcrEyvNo+AfTrRGVazle1tl597w3gfA==", "dev": true, "dependencies": { "@types/node": "*", @@ -8991,9 +8991,9 @@ } }, "@types/node-fetch": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.8.tgz", - "integrity": "sha512-nnH5lV9QCMPsbEVdTb5Y+F3GQxLSw1xQgIydrb2gSfEavRPs50FnMr+KUaa+LoPSqibm2N+ZZxH7lavZlAT4GA==", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.9.tgz", + "integrity": "sha512-bQVlnMLFJ2d35DkPNjEPmd9ueO/rh5EiaZt2bhqiSarPjZIuIV6bPQVqcrEyvNo+AfTrRGVazle1tl597w3gfA==", "dev": true, "requires": { "@types/node": "*", From 701b7d62dd23fb0b609bb758235859f4aa38102d Mon Sep 17 00:00:00 2001 From: Joe C Date: Wed, 8 Nov 2023 20:36:07 +0000 Subject: [PATCH 0586/1076] rustfmt: use entrypoint full path This PR swaps any calls to the `entrypoint!` macro with the full path, ie: `solana_program::entrypoint!`. This will play a role in the effort to introduce a linting standard to SPL. --- program/src/entrypoint.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/program/src/entrypoint.rs b/program/src/entrypoint.rs index a809d7f2..92e3ea5a 100644 --- a/program/src/entrypoint.rs +++ b/program/src/entrypoint.rs @@ -5,12 +5,12 @@ use { crate::{error::StakePoolError, processor::Processor}, solana_program::{ - account_info::AccountInfo, entrypoint, entrypoint::ProgramResult, - program_error::PrintProgramError, pubkey::Pubkey, + account_info::AccountInfo, entrypoint::ProgramResult, program_error::PrintProgramError, + pubkey::Pubkey, }, }; -entrypoint!(process_instruction); +solana_program::entrypoint!(process_instruction); fn process_instruction( program_id: &Pubkey, accounts: &[AccountInfo], From b52f9e4b9b21e7a5dcdd151700f10e1ffb102d82 Mon Sep 17 00:00:00 2001 From: Joe C Date: Wed, 8 Nov 2023 20:38:31 +0000 Subject: [PATCH 0587/1076] rustfmt: format imports This PR adds import formatting configurations to the repository's `rustfmt.toml` file, and the associated changes from `cargo +nightly fmt --all`. --- clients/cli/src/main.rs | 12 +++++------- clients/cli/src/output.rs | 3 +-- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 0edaafbc..bc3b443f 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -2,6 +2,9 @@ mod client; mod output; +// use instruction::create_associated_token_account once ATA 1.0.5 is released +#[allow(deprecated)] +use spl_associated_token_account::create_associated_token_account; use { crate::{ client::*, @@ -41,21 +44,16 @@ use { transaction::Transaction, }, spl_associated_token_account::get_associated_token_address, - spl_stake_pool::state::ValidatorStakeInfo, spl_stake_pool::{ self, find_stake_program_address, find_transient_stake_program_address, find_withdraw_authority_program_address, instruction::{FundingType, PreferredValidatorType}, minimum_delegation, - state::{Fee, FeeType, StakePool, ValidatorList}, + state::{Fee, FeeType, StakePool, ValidatorList, ValidatorStakeInfo}, MINIMUM_RESERVE_LAMPORTS, }, - std::cmp::Ordering, - std::{num::NonZeroU32, process::exit, rc::Rc}, + std::{cmp::Ordering, num::NonZeroU32, process::exit, rc::Rc}, }; -// use instruction::create_associated_token_account once ATA 1.0.5 is released -#[allow(deprecated)] -use spl_associated_token_account::create_associated_token_account; pub(crate) struct Config { rpc_client: RpcClient, diff --git a/clients/cli/src/output.rs b/clients/cli/src/output.rs index f1305245..5eeb81bc 100644 --- a/clients/cli/src/output.rs +++ b/clients/cli/src/output.rs @@ -1,8 +1,7 @@ use { serde::{Deserialize, Serialize}, solana_cli_output::{QuietDisplay, VerboseDisplay}, - solana_sdk::native_token::Sol, - solana_sdk::{pubkey::Pubkey, stake::state::Lockup}, + solana_sdk::{native_token::Sol, pubkey::Pubkey, stake::state::Lockup}, spl_stake_pool::state::{ Fee, PodStakeStatus, StakePool, StakeStatus, ValidatorList, ValidatorStakeInfo, }, From 89c793835fafd65bba2fdb8e3de160c5a3fc0eff Mon Sep 17 00:00:00 2001 From: Joe C Date: Wed, 8 Nov 2023 20:41:36 +0000 Subject: [PATCH 0588/1076] rustfmt: format comments This PR adds comment formatting configurations to the repository's `rustfmt.toml` file, and the associated changes from `cargo +nightly fmt --all`. Comment width 80. --- clients/cli/src/main.rs | 3 +- program/src/big_vec.rs | 5 +- program/src/error.rs | 27 +- program/src/inline_mpl_token_metadata.rs | 9 +- program/src/instruction.rs | 275 +++++++++++------- program/src/lib.rs | 7 +- program/src/processor.rs | 35 ++- program/src/state.rs | 63 ++-- program/tests/huge_pool.rs | 4 +- program/tests/redelegate.rs | 4 +- .../tests/update_validator_list_balance.rs | 3 +- program/tests/withdraw_edge_cases.rs | 15 +- 12 files changed, 274 insertions(+), 176 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index bc3b443f..60ab61c6 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -1761,7 +1761,8 @@ fn command_set_manager( let new_fee_receiver = match new_fee_receiver { None => stake_pool.manager_fee_account, Some(value) => { - // Check for fee receiver being a valid token account and have to same mint as the stake pool + // Check for fee receiver being a valid token account and have to same mint as + // the stake pool let token_account = get_token_account(&config.rpc_client, value, &stake_pool.pool_mint)?; if token_account.mint != stake_pool.pool_mint { diff --git a/program/src/big_vec.rs b/program/src/big_vec.rs index 0d05f0ae..8cf99f80 100644 --- a/program/src/big_vec.rs +++ b/program/src/big_vec.rs @@ -70,7 +70,10 @@ impl<'data> BigVec<'data> { let gap = removals_found * mem::size_of::(); // In case the compute budget is ever bumped up, allowing us // to use this safe code instead: - //self.data.copy_within(dst_start_index + gap..data_end_index, dst_start_index); + // self.data.copy_within( + // dst_start_index + gap..data_end_index, + // dst_start_index, + // ); unsafe { sol_memmove( self.data[dst_start_index..data_end_index - gap].as_mut_ptr(), diff --git a/program/src/error.rs b/program/src/error.rs index afeaeaf4..74a7885f 100644 --- a/program/src/error.rs +++ b/program/src/error.rs @@ -13,7 +13,8 @@ pub enum StakePoolError { /// The account cannot be initialized because it is already being used. #[error("AlreadyInUse")] AlreadyInUse, - /// The program address provided doesn't match the value generated by the program. + /// The program address provided doesn't match the value generated by the + /// program. #[error("InvalidProgramAddress")] InvalidProgramAddress, /// The stake pool state is invalid. @@ -67,7 +68,8 @@ pub enum StakePoolError { /// Identify validator stake accounts with old balances and update them. #[error("StakeListOutOfDate")] StakeListOutOfDate, - /// First update old validator stake account balances and then pool stake balance. + /// First update old validator stake account balances and then pool stake + /// balance. #[error("StakeListAndPoolOutOfDate")] StakeListAndPoolOutOfDate, /// Validator stake account is not found in the list storage. @@ -78,7 +80,8 @@ pub enum StakePoolError { WrongMintingAuthority, // 20. - /// The size of the given validator stake list does match the expected amount + /// The size of the given validator stake list does match the expected + /// amount #[error("UnexpectedValidatorListAccountSize")] UnexpectedValidatorListAccountSize, /// Wrong pool staker account. @@ -90,12 +93,14 @@ pub enum StakePoolError { /// The lamports in the validator stake account is not equal to the minimum #[error("StakeLamportsNotEqualToMinimum")] StakeLamportsNotEqualToMinimum, - /// The provided deposit stake account is not delegated to the preferred deposit vote account + /// The provided deposit stake account is not delegated to the preferred + /// deposit vote account #[error("IncorrectDepositVoteAddress")] IncorrectDepositVoteAddress, // 25. - /// The provided withdraw stake account is not the preferred deposit vote account + /// The provided withdraw stake account is not the preferred deposit vote + /// account #[error("IncorrectWithdrawVoteAddress")] IncorrectWithdrawVoteAddress, /// The mint has an invalid freeze authority @@ -121,7 +126,8 @@ pub enum StakePoolError { /// Provided preferred validator is invalid #[error("InvalidPreferredValidator")] InvalidPreferredValidator, - /// Provided validator stake account already has a transient stake account in use + /// Provided validator stake account already has a transient stake account + /// in use #[error("TransientAccountInUse")] TransientAccountInUse, /// Provided sol withdraw authority does not match the program's @@ -132,7 +138,8 @@ pub enum StakePoolError { /// Too much SOL withdrawn from the stake pool's reserve account #[error("SolWithdrawalTooLarge")] SolWithdrawalTooLarge, - /// Provided metadata account does not match metadata account derived for pool mint + /// Provided metadata account does not match metadata account derived for + /// pool mint #[error("InvalidMetadataAccount")] InvalidMetadataAccount, /// The mint has an unsupported extension @@ -149,9 +156,9 @@ pub enum StakePoolError { /// Provided mint does not have 9 decimals to match SOL #[error("IncorrectMintDecimals")] IncorrectMintDecimals, - /// Pool reserve does not have enough lamports to fund rent-exempt reserve in split - /// destination. Deposit more SOL in reserve, or pre-fund split destination with - /// the rent-exempt reserve for a stake account. + /// Pool reserve does not have enough lamports to fund rent-exempt reserve + /// in split destination. Deposit more SOL in reserve, or pre-fund split + /// destination with the rent-exempt reserve for a stake account. #[error("ReserveDepleted")] ReserveDepleted, /// Missing required sysvar account diff --git a/program/src/inline_mpl_token_metadata.rs b/program/src/inline_mpl_token_metadata.rs index 4de593e3..b7697a29 100644 --- a/program/src/inline_mpl_token_metadata.rs +++ b/program/src/inline_mpl_token_metadata.rs @@ -1,6 +1,6 @@ -//! Inlined MPL metadata types to avoid a direct dependency on `mpl-token-metadata' -//! NOTE: this file is sym-linked in `spl-single-pool`, so be careful -//! with changes! +//! Inlined MPL metadata types to avoid a direct dependency on +//! `mpl-token-metadata' NOTE: this file is sym-linked in `spl-single-pool`, so +//! be careful with changes! solana_program::declare_id!("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"); @@ -127,7 +127,8 @@ pub(crate) mod state { pub symbol: String, /// URI pointing to JSON representing the asset pub uri: String, - /// Royalty basis points that goes to creators in secondary sales (0-10000) + /// Royalty basis points that goes to creators in secondary sales + /// (0-10000) pub seller_fee_basis_points: u16, /// UNUSED Array of creators, optional pub creators: Option, diff --git a/program/src/instruction.rs b/program/src/instruction.rs index fb07373c..8bc41e87 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -56,13 +56,15 @@ pub enum StakePoolInstruction { /// 3. `[]` Stake pool withdraw authority /// 4. `[w]` Uninitialized validator stake list storage account /// 5. `[]` Reserve stake account must be initialized, have zero balance, - /// and staker / withdrawer authority set to pool withdraw authority. - /// 6. `[]` Pool token mint. Must have zero supply, owned by withdraw authority. + /// and staker / withdrawer authority set to pool withdraw authority. + /// 6. `[]` Pool token mint. Must have zero supply, owned by withdraw + /// authority. /// 7. `[]` Pool account to deposit the generated fee for manager. /// 8. `[]` Token program id /// 9. `[]` (Optional) Deposit authority that must sign all deposits. /// Defaults to the program address generated using - /// `find_deposit_authority_program_address`, making deposits permissionless. + /// `find_deposit_authority_program_address`, making deposits + /// permissionless. Initialize { /// Fee assessed as percentage of perceived rewards fee: Fee, @@ -80,7 +82,10 @@ pub enum StakePoolInstruction { /// list of managed validators. /// /// The stake account will have the rent-exempt amount plus - /// `max(crate::MINIMUM_ACTIVE_STAKE, solana_program::stake::tools::get_minimum_delegation())`. + /// `max( + /// crate::MINIMUM_ACTIVE_STAKE, + /// solana_program::stake::tools::get_minimum_delegation() + /// )`. /// It is funded from the stake pool reserve. /// /// 0. `[w]` Stake pool @@ -104,8 +109,9 @@ pub enum StakePoolInstruction { /// (Staker only) Removes validator from the pool, deactivating its stake /// /// Only succeeds if the validator stake account has the minimum of - /// `max(crate::MINIMUM_ACTIVE_STAKE, solana_program::stake::tools::get_minimum_delegation())`. - /// plus the rent-exempt amount. + /// `max(crate::MINIMUM_ACTIVE_STAKE, + /// solana_program::stake::tools::get_minimum_delegation())`. plus the + /// rent-exempt amount. /// /// 0. `[w]` Stake pool /// 1. `[s]` Staker @@ -120,19 +126,22 @@ pub enum StakePoolInstruction { /// NOTE: This instruction has been deprecated since version 0.7.0. Please /// use `DecreaseValidatorStakeWithReserve` instead. /// - /// (Staker only) Decrease active stake on a validator, eventually moving it to the reserve + /// (Staker only) Decrease active stake on a validator, eventually moving it + /// to the reserve /// /// Internally, this instruction splits a validator stake account into its /// corresponding transient stake account and deactivates it. /// /// In order to rebalance the pool without taking custody, the staker needs /// a way of reducing the stake on a stake account. This instruction splits - /// some amount of stake, up to the total activated stake, from the canonical - /// validator stake account, into its "transient" stake account. + /// some amount of stake, up to the total activated stake, from the + /// canonical validator stake account, into its "transient" stake + /// account. /// /// The instruction only succeeds if the transient stake account does not - /// exist. The amount of lamports to move must be at least rent-exemption plus - /// `max(crate::MINIMUM_ACTIVE_STAKE, solana_program::stake::tools::get_minimum_delegation())`. + /// exist. The amount of lamports to move must be at least rent-exemption + /// plus `max(crate::MINIMUM_ACTIVE_STAKE, + /// solana_program::stake::tools::get_minimum_delegation())`. /// /// 0. `[]` Stake pool /// 1. `[s]` Stake pool staker @@ -154,12 +163,14 @@ pub enum StakePoolInstruction { /// (Staker only) Increase stake on a validator from the reserve account /// /// Internally, this instruction splits reserve stake into a transient stake - /// account and delegate to the appropriate validator. `UpdateValidatorListBalance` - /// will do the work of merging once it's ready. + /// account and delegate to the appropriate validator. + /// `UpdateValidatorListBalance` will do the work of merging once it's + /// ready. /// - /// This instruction only succeeds if the transient stake account does not exist. - /// The minimum amount to move is rent-exemption plus - /// `max(crate::MINIMUM_ACTIVE_STAKE, solana_program::stake::tools::get_minimum_delegation())`. + /// This instruction only succeeds if the transient stake account does not + /// exist. The minimum amount to move is rent-exemption plus + /// `max(crate::MINIMUM_ACTIVE_STAKE, + /// solana_program::stake::tools::get_minimum_delegation())`. /// /// 0. `[]` Stake pool /// 1. `[s]` Stake pool staker @@ -178,8 +189,8 @@ pub enum StakePoolInstruction { /// userdata: amount of lamports to increase on the given validator. /// The actual amount split into the transient stake account is: /// `lamports + stake_rent_exemption` - /// The rent-exemption of the stake account is withdrawn back to the reserve - /// after it is merged. + /// The rent-exemption of the stake account is withdrawn back to the + /// reserve after it is merged. IncreaseValidatorStake { /// amount of lamports to increase on the given validator lamports: u64, @@ -187,12 +198,13 @@ pub enum StakePoolInstruction { transient_stake_seed: u64, }, - /// (Staker only) Set the preferred deposit or withdraw stake account for the - /// stake pool + /// (Staker only) Set the preferred deposit or withdraw stake account for + /// the stake pool /// /// In order to avoid users abusing the stake pool as a free conversion /// between SOL staked on different validators, the staker can force all - /// deposits and/or withdraws to go to one chosen account, or unset that account. + /// deposits and/or withdraws to go to one chosen account, or unset that + /// account. /// /// 0. `[w]` Stake pool /// 1. `[s]` Stake pool staker @@ -209,12 +221,12 @@ pub enum StakePoolInstruction { /// Updates balances of validator and transient stake accounts in the pool /// - /// While going through the pairs of validator and transient stake accounts, - /// if the transient stake is inactive, it is merged into the reserve stake - /// account. If the transient stake is active and has matching credits - /// observed, it is merged into the canonical validator stake account. In - /// all other states, nothing is done, and the balance is simply added to - /// the canonical stake account balance. + /// While going through the pairs of validator and transient stake + /// accounts, if the transient stake is inactive, it is merged into the + /// reserve stake account. If the transient stake is active and has + /// matching credits observed, it is merged into the canonical + /// validator stake account. In all other states, nothing is done, and + /// the balance is simply added to the canonical stake account balance. /// /// 0. `[]` Stake pool /// 1. `[]` Stake pool withdraw authority @@ -227,13 +239,15 @@ pub enum StakePoolInstruction { UpdateValidatorListBalance { /// Index to start updating on the validator list start_index: u32, - /// If true, don't try merging transient stake accounts into the reserve or - /// validator stake account. Useful for testing or if a particular stake - /// account is in a bad state, but we still want to update + /// If true, don't try merging transient stake accounts into the reserve + /// or validator stake account. Useful for testing or if a + /// particular stake account is in a bad state, but we still + /// want to update no_merge: bool, }, - /// Updates total pool balance based on balances in the reserve and validator list + /// Updates total pool balance based on balances in the reserve and + /// validator list /// /// 0. `[w]` Stake pool /// 1. `[]` Stake pool withdraw authority @@ -250,19 +264,24 @@ pub enum StakePoolInstruction { /// 1. `[w]` Validator stake list storage account CleanupRemovedValidatorEntries, - /// Deposit some stake into the pool. The output is a "pool" token representing ownership - /// into the pool. Inputs are converted to the current ratio. + /// Deposit some stake into the pool. The output is a "pool" token + /// representing ownership into the pool. Inputs are converted to the + /// current ratio. /// /// 0. `[w]` Stake pool /// 1. `[w]` Validator stake list storage account /// 2. `[s]/[]` Stake pool deposit authority /// 3. `[]` Stake pool withdraw authority - /// 4. `[w]` Stake account to join the pool (withdraw authority for the stake account should be first set to the stake pool deposit authority) - /// 5. `[w]` Validator stake account for the stake account to be merged with + /// 4. `[w]` Stake account to join the pool (withdraw authority for the + /// stake account should be first set to the stake pool deposit + /// authority) + /// 5. `[w]` Validator stake account for the stake account to be merged + /// with /// 6. `[w]` Reserve stake account, to withdraw rent exempt reserve /// 7. `[w]` User account to receive pool tokens /// 8. `[w]` Account to receive pool fee tokens - /// 9. `[w]` Account to receive a portion of pool fee tokens as referral fees + /// 9. `[w]` Account to receive a portion of pool fee tokens as referral + /// fees /// 10. `[w]` Pool token mint account /// 11. '[]' Sysvar clock account /// 12. '[]' Sysvar stake history account @@ -272,10 +291,12 @@ pub enum StakePoolInstruction { /// Withdraw the token from the pool at the current ratio. /// - /// Succeeds if the stake account has enough SOL to cover the desired amount - /// of pool tokens, and if the withdrawal keeps the total staked amount - /// above the minimum of rent-exempt amount + - /// `max(crate::MINIMUM_ACTIVE_STAKE, solana_program::stake::tools::get_minimum_delegation())`. + /// Succeeds if the stake account has enough SOL to cover the desired + /// amount of pool tokens, and if the withdrawal keeps the total + /// staked amount above the minimum of rent-exempt amount + `max( + /// crate::MINIMUM_ACTIVE_STAKE, + /// solana_program::stake::tools::get_minimum_delegation() + /// )`. /// /// When allowing withdrawals, the order of priority goes: /// @@ -329,8 +350,9 @@ pub enum StakePoolInstruction { /// 2. '[]` New staker pubkey SetStaker, - /// Deposit SOL directly into the pool's reserve account. The output is a "pool" token - /// representing ownership into the pool. Inputs are converted to the current ratio. + /// Deposit SOL directly into the pool's reserve account. The output is a + /// "pool" token representing ownership into the pool. Inputs are + /// converted to the current ratio. /// /// 0. `[w]` Stake pool /// 1. `[]` Stake pool withdraw authority @@ -345,7 +367,8 @@ pub enum StakePoolInstruction { /// 10. `[s]` (Optional) Stake pool sol deposit authority. DepositSol(u64), - /// (Manager only) Update SOL deposit, stake deposit, or SOL withdrawal authority. + /// (Manager only) Update SOL deposit, stake deposit, or SOL withdrawal + /// authority. /// /// 0. `[w]` StakePool /// 1. `[s]` Manager @@ -360,7 +383,8 @@ pub enum StakePoolInstruction { /// 2. `[s]` User transfer authority, for pool token account /// 3. `[w]` User account to burn pool tokens /// 4. `[w]` Reserve stake account, to withdraw SOL - /// 5. `[w]` Account receiving the lamports from the reserve, must be a system account + /// 5. `[w]` Account receiving the lamports from the reserve, must be a + /// system account /// 6. `[w]` Account to receive pool fee tokens /// 7. `[w]` Pool token mint account /// 8. '[]' Clock sysvar @@ -409,13 +433,15 @@ pub enum StakePoolInstruction { /// /// Works regardless if the transient stake account exists. /// - /// Internally, this instruction splits reserve stake into an ephemeral stake - /// account, activates it, then merges or splits it into the transient stake - /// account delegated to the appropriate validator. `UpdateValidatorListBalance` - /// will do the work of merging once it's ready. + /// Internally, this instruction splits reserve stake into an ephemeral + /// stake account, activates it, then merges or splits it into the + /// transient stake account delegated to the appropriate validator. + /// `UpdateValidatorListBalance` will do the work of merging once it's + /// ready. /// /// The minimum amount to move is rent-exemption plus - /// `max(crate::MINIMUM_ACTIVE_STAKE, solana_program::stake::tools::get_minimum_delegation())`. + /// `max(crate::MINIMUM_ACTIVE_STAKE, + /// solana_program::stake::tools::get_minimum_delegation())`. /// /// 0. `[]` Stake pool /// 1. `[s]` Stake pool staker @@ -434,8 +460,8 @@ pub enum StakePoolInstruction { /// userdata: amount of lamports to increase on the given validator. /// The actual amount split into the transient stake account is: /// `lamports + stake_rent_exemption` - /// The rent-exemption of the stake account is withdrawn back to the reserve - /// after it is merged. + /// The rent-exemption of the stake account is withdrawn back to the + /// reserve after it is merged. IncreaseAdditionalValidatorStake { /// amount of lamports to increase on the given validator lamports: u64, @@ -445,19 +471,22 @@ pub enum StakePoolInstruction { ephemeral_stake_seed: u64, }, - /// (Staker only) Decrease active stake again from a validator, eventually moving it to the reserve + /// (Staker only) Decrease active stake again from a validator, eventually + /// moving it to the reserve /// /// Works regardless if the transient stake account already exists. /// /// Internally, this instruction: - /// * withdraws rent-exempt reserve lamports from the reserve into the ephemeral stake + /// * withdraws rent-exempt reserve lamports from the reserve into the + /// ephemeral stake /// * splits a validator stake account into an ephemeral stake account /// * deactivates the ephemeral account - /// * merges or splits the ephemeral account into the transient stake account - /// delegated to the appropriate validator + /// * merges or splits the ephemeral account into the transient stake + /// account delegated to the appropriate validator /// /// The amount of lamports to move must be at least - /// `max(crate::MINIMUM_ACTIVE_STAKE, solana_program::stake::tools::get_minimum_delegation())`. + /// `max(crate::MINIMUM_ACTIVE_STAKE, + /// solana_program::stake::tools::get_minimum_delegation())`. /// /// 0. `[]` Stake pool /// 1. `[s]` Stake pool staker @@ -480,7 +509,8 @@ pub enum StakePoolInstruction { ephemeral_stake_seed: u64, }, - /// (Staker only) Decrease active stake on a validator, eventually moving it to the reserve + /// (Staker only) Decrease active stake on a validator, eventually moving it + /// to the reserve /// /// Internally, this instruction: /// * withdraws enough lamports to make the transient account rent-exempt @@ -489,12 +519,14 @@ pub enum StakePoolInstruction { /// /// In order to rebalance the pool without taking custody, the staker needs /// a way of reducing the stake on a stake account. This instruction splits - /// some amount of stake, up to the total activated stake, from the canonical - /// validator stake account, into its "transient" stake account. + /// some amount of stake, up to the total activated stake, from the + /// canonical validator stake account, into its "transient" stake + /// account. /// /// The instruction only succeeds if the transient stake account does not - /// exist. The amount of lamports to move must be at least rent-exemption plus - /// `max(crate::MINIMUM_ACTIVE_STAKE, solana_program::stake::tools::get_minimum_delegation())`. + /// exist. The amount of lamports to move must be at least rent-exemption + /// plus `max(crate::MINIMUM_ACTIVE_STAKE, + /// solana_program::stake::tools::get_minimum_delegation())`. /// /// 0. `[]` Stake pool /// 1. `[s]` Stake pool staker @@ -514,16 +546,19 @@ pub enum StakePoolInstruction { transient_stake_seed: u64, }, - /// (Staker only) Redelegate active stake on a validator, eventually moving it to another + /// (Staker only) Redelegate active stake on a validator, eventually moving + /// it to another /// /// Internally, this instruction splits a validator stake account into its - /// corresponding transient stake account, redelegates it to an ephemeral stake - /// account, then merges that stake into the destination transient stake account. + /// corresponding transient stake account, redelegates it to an ephemeral + /// stake account, then merges that stake into the destination transient + /// stake account. /// /// In order to rebalance the pool without taking custody, the staker needs /// a way of reducing the stake on a stake account. This instruction splits - /// some amount of stake, up to the total activated stake, from the canonical - /// validator stake account, into its "transient" stake account. + /// some amount of stake, up to the total activated stake, from the + /// canonical validator stake account, into its "transient" stake + /// account. /// /// The instruction only succeeds if the source transient stake account and /// ephemeral stake account do not exist. @@ -548,10 +583,13 @@ pub enum StakePoolInstruction { /// 3. `[w]` Validator list /// 4. `[w]` Reserve stake account, to withdraw rent exempt reserve /// 5. `[w]` Source canonical stake account to split from - /// 6. `[w]` Source transient stake account to receive split and be redelegated + /// 6. `[w]` Source transient stake account to receive split and be + /// redelegated /// 7. `[w]` Uninitialized ephemeral stake account to receive redelegation - /// 8. `[w]` Destination transient stake account to receive ephemeral stake by merge - /// 9. `[]` Destination stake account to receive transient stake after activation + /// 8. `[w]` Destination transient stake account to receive ephemeral stake + /// by merge + /// 9. `[]` Destination stake account to receive transient stake after + /// activation /// 10. `[]` Destination validator vote account /// 11. `[]` Clock sysvar /// 12. `[]` Stake History sysvar @@ -575,20 +613,24 @@ pub enum StakePoolInstruction { destination_transient_stake_seed: u64, }, - /// Deposit some stake into the pool, with a specified slippage constraint. - /// The output is a "pool" token representing ownership into the pool. - /// Inputs are converted at the current ratio. + /// Deposit some stake into the pool, with a specified slippage + /// constraint. The output is a "pool" token representing ownership + /// into the pool. Inputs are converted at the current ratio. /// /// 0. `[w]` Stake pool /// 1. `[w]` Validator stake list storage account /// 2. `[s]/[]` Stake pool deposit authority /// 3. `[]` Stake pool withdraw authority - /// 4. `[w]` Stake account to join the pool (withdraw authority for the stake account should be first set to the stake pool deposit authority) - /// 5. `[w]` Validator stake account for the stake account to be merged with + /// 4. `[w]` Stake account to join the pool (withdraw authority for the + /// stake account should be first set to the stake pool deposit + /// authority) + /// 5. `[w]` Validator stake account for the stake account to be merged + /// with /// 6. `[w]` Reserve stake account, to withdraw rent exempt reserve /// 7. `[w]` User account to receive pool tokens /// 8. `[w]` Account to receive pool fee tokens - /// 9. `[w]` Account to receive a portion of pool fee tokens as referral fees + /// 9. `[w]` Account to receive a portion of pool fee tokens as referral + /// fees /// 10. `[w]` Pool token mint account /// 11. '[]' Sysvar clock account /// 12. '[]' Sysvar stake history account @@ -602,10 +644,12 @@ pub enum StakePoolInstruction { /// Withdraw the token from the pool at the current ratio, specifying a /// minimum expected output lamport amount. /// - /// Succeeds if the stake account has enough SOL to cover the desired amount - /// of pool tokens, and if the withdrawal keeps the total staked amount - /// above the minimum of rent-exempt amount + - /// `max(crate::MINIMUM_ACTIVE_STAKE, solana_program::stake::tools::get_minimum_delegation())`. + /// Succeeds if the stake account has enough SOL to cover the desired + /// amount of pool tokens, and if the withdrawal keeps the total + /// staked amount above the minimum of rent-exempt amount + `max( + /// crate::MINIMUM_ACTIVE_STAKE, + /// solana_program::stake::tools::get_minimum_delegation() + /// )`. /// /// 0. `[w]` Stake pool /// 1. `[w]` Validator stake list storage account @@ -628,9 +672,10 @@ pub enum StakePoolInstruction { minimum_lamports_out: u64, }, - /// Deposit SOL directly into the pool's reserve account, with a specified - /// slippage constraint. The output is a "pool" token representing ownership - /// into the pool. Inputs are converted at the current ratio. + /// Deposit SOL directly into the pool's reserve account, with a + /// specified slippage constraint. The output is a "pool" token + /// representing ownership into the pool. Inputs are converted at the + /// current ratio. /// /// 0. `[w]` Stake pool /// 1. `[]` Stake pool withdraw authority @@ -659,7 +704,8 @@ pub enum StakePoolInstruction { /// 2. `[s]` User transfer authority, for pool token account /// 3. `[w]` User account to burn pool tokens /// 4. `[w]` Reserve stake account, to withdraw SOL - /// 5. `[w]` Account receiving the lamports from the reserve, must be a system account + /// 5. `[w]` Account receiving the lamports from the reserve, must be a + /// system account /// 6. `[w]` Account to receive pool fee tokens /// 7. `[w]` Pool token mint account /// 8. '[]' Clock sysvar @@ -723,7 +769,8 @@ pub fn initialize( } } -/// Creates `AddValidatorToPool` instruction (add new validator stake account to the pool) +/// Creates `AddValidatorToPool` instruction (add new validator stake account to +/// the pool) pub fn add_validator_to_pool( program_id: &Pubkey, stake_pool: &Pubkey, @@ -761,7 +808,8 @@ pub fn add_validator_to_pool( } } -/// Creates `RemoveValidatorFromPool` instruction (remove validator stake account from the pool) +/// Creates `RemoveValidatorFromPool` instruction (remove validator stake +/// account from the pool) pub fn remove_validator_from_pool( program_id: &Pubkey, stake_pool: &Pubkey, @@ -790,8 +838,8 @@ pub fn remove_validator_from_pool( } } -/// Creates `DecreaseValidatorStake` instruction (rebalance from validator account to -/// transient account) +/// Creates `DecreaseValidatorStake` instruction (rebalance from validator +/// account to transient account) #[deprecated( since = "0.7.0", note = "please use `decrease_validator_stake_with_reserve`" @@ -913,8 +961,8 @@ pub fn decrease_validator_stake_with_reserve( } } -/// Creates `IncreaseValidatorStake` instruction (rebalance from reserve account to -/// transient account) +/// Creates `IncreaseValidatorStake` instruction (rebalance from reserve account +/// to transient account) pub fn increase_validator_stake( program_id: &Pubkey, stake_pool: &Pubkey, @@ -957,8 +1005,8 @@ pub fn increase_validator_stake( } } -/// Creates `IncreaseAdditionalValidatorStake` instruction (rebalance from reserve account to -/// transient account) +/// Creates `IncreaseAdditionalValidatorStake` instruction (rebalance from +/// reserve account to transient account) pub fn increase_additional_validator_stake( program_id: &Pubkey, stake_pool: &Pubkey, @@ -1004,7 +1052,8 @@ pub fn increase_additional_validator_stake( } } -/// Creates `Redelegate` instruction (rebalance from one validator account to another) +/// Creates `Redelegate` instruction (rebalance from one validator account to +/// another) pub fn redelegate( program_id: &Pubkey, stake_pool: &Pubkey, @@ -1107,8 +1156,8 @@ pub fn add_validator_to_pool_with_vote( ) } -/// Create an `RemoveValidatorFromPool` instruction given an existing stake pool and -/// vote account +/// Create an `RemoveValidatorFromPool` instruction given an existing stake pool +/// and vote account pub fn remove_validator_from_pool_with_vote( program_id: &Pubkey, stake_pool: &StakePool, @@ -1142,8 +1191,8 @@ pub fn remove_validator_from_pool_with_vote( ) } -/// Create an `IncreaseValidatorStake` instruction given an existing stake pool and -/// vote account +/// Create an `IncreaseValidatorStake` instruction given an existing stake pool +/// and vote account pub fn increase_validator_stake_with_vote( program_id: &Pubkey, stake_pool: &StakePool, @@ -1229,8 +1278,8 @@ pub fn increase_additional_validator_stake_with_vote( ) } -/// Create a `DecreaseValidatorStake` instruction given an existing stake pool and -/// vote account +/// Create a `DecreaseValidatorStake` instruction given an existing stake pool +/// and vote account pub fn decrease_validator_stake_with_vote( program_id: &Pubkey, stake_pool: &StakePool, @@ -1312,7 +1361,8 @@ pub fn decrease_additional_validator_stake_with_vote( ) } -/// Creates `UpdateValidatorListBalance` instruction (update validator stake account balances) +/// Creates `UpdateValidatorListBalance` instruction (update validator stake +/// account balances) pub fn update_validator_list_balance( program_id: &Pubkey, stake_pool: &Pubkey, @@ -1373,7 +1423,8 @@ pub fn update_validator_list_balance( } } -/// Creates `UpdateStakePoolBalance` instruction (pool balance from the stake account list balances) +/// Creates `UpdateStakePoolBalance` instruction (pool balance from the stake +/// account list balances) pub fn update_stake_pool_balance( program_id: &Pubkey, stake_pool: &Pubkey, @@ -1402,7 +1453,8 @@ pub fn update_stake_pool_balance( } } -/// Creates `CleanupRemovedValidatorEntries` instruction (removes entries from the validator list) +/// Creates `CleanupRemovedValidatorEntries` instruction (removes entries from +/// the validator list) pub fn cleanup_removed_validator_entries( program_id: &Pubkey, stake_pool: &Pubkey, @@ -1690,9 +1742,10 @@ pub fn deposit_stake_with_authority( ) } -/// Creates instructions required to deposit into a stake pool with slippage, given -/// a stake account owned by the user. The difference with `deposit()` is that a deposit -/// authority must sign this instruction, which is required for private pools. +/// Creates instructions required to deposit into a stake pool with slippage, +/// given a stake account owned by the user. The difference with `deposit()` is +/// that a deposit authority must sign this instruction, which is required for +/// private pools. pub fn deposit_stake_with_authority_and_slippage( program_id: &Pubkey, stake_pool: &Pubkey, @@ -1813,7 +1866,8 @@ pub fn deposit_sol( ) } -/// Creates instruction to deposit SOL directly into a stake pool with slippage constraint. +/// Creates instruction to deposit SOL directly into a stake pool with slippage +/// constraint. pub fn deposit_sol_with_slippage( program_id: &Pubkey, stake_pool: &Pubkey, @@ -1879,7 +1933,8 @@ pub fn deposit_sol_with_authority( ) } -/// Creates instruction to deposit SOL directly into a stake pool with slippage constraint. +/// Creates instruction to deposit SOL directly into a stake pool with slippage +/// constraint. pub fn deposit_sol_with_authority_and_slippage( program_id: &Pubkey, stake_pool: &Pubkey, @@ -2304,8 +2359,8 @@ pub fn set_funding_authority( } } -/// Creates an instruction to update metadata in the mpl token metadata program account for -/// the pool token +/// Creates an instruction to update metadata in the mpl token metadata program +/// account for the pool token pub fn update_token_metadata( program_id: &Pubkey, stake_pool: &Pubkey, @@ -2336,8 +2391,8 @@ pub fn update_token_metadata( } } -/// Creates an instruction to create metadata using the mpl token metadata program for -/// the pool token +/// Creates an instruction to create metadata using the mpl token metadata +/// program for the pool token pub fn create_token_metadata( program_id: &Pubkey, stake_pool: &Pubkey, diff --git a/program/src/lib.rs b/program/src/lib.rs index 8ef0193f..fe48880b 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -12,7 +12,8 @@ pub mod state; #[cfg(not(feature = "no-entrypoint"))] pub mod entrypoint; -// Export current sdk types for downstream users building with a different sdk version +// Export current sdk types for downstream users building with a different sdk +// version pub use solana_program; use { crate::state::Fee, @@ -32,8 +33,8 @@ const TRANSIENT_STAKE_SEED_PREFIX: &[u8] = b"transient"; /// Seed for ephemeral stake account const EPHEMERAL_STAKE_SEED_PREFIX: &[u8] = b"ephemeral"; -/// Minimum amount of staked lamports required in a validator stake account to allow -/// for merges without a mismatch on credits observed +/// Minimum amount of staked lamports required in a validator stake account to +/// allow for merges without a mismatch on credits observed pub const MINIMUM_ACTIVE_STAKE: u64 = 1_000_000; /// Minimum amount of lamports in the reserve diff --git a/program/src/processor.rs b/program/src/processor.rs index b25ec780..6f5ef75f 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -279,9 +279,9 @@ fn check_stake_state( Ok(()) } -/// Checks if a validator stake account is valid, which means that it's usable by -/// the pool and delegated to the expected validator. These conditions can be violated -/// if a validator was force destaked during a cluster restart. +/// Checks if a validator stake account is valid, which means that it's usable +/// by the pool and delegated to the expected validator. These conditions can be +/// violated if a validator was force destaked during a cluster restart. fn check_validator_stake_account( stake_account_info: &AccountInfo, program_id: &Pubkey, @@ -308,9 +308,9 @@ fn check_validator_stake_account( Ok(()) } -/// Checks if a transient stake account is valid, which means that it's usable by -/// the pool and delegated to the expected validator. These conditions can be violated -/// if a validator was force destaked during a cluster restart. +/// Checks if a transient stake account is valid, which means that it's usable +/// by the pool and delegated to the expected validator. These conditions can be +/// violated if a validator was force destaked during a cluster restart. fn check_transient_stake_account( stake_account_info: &AccountInfo, program_id: &Pubkey, @@ -467,7 +467,8 @@ impl Processor { ) } - /// Issue stake::instruction::authorize instructions to update both authorities + /// Issue stake::instruction::authorize instructions to update both + /// authorities fn stake_authorize<'a>( stake_account: AccountInfo<'a>, stake_authority: AccountInfo<'a>, @@ -505,7 +506,8 @@ impl Processor { ) } - /// Issue stake::instruction::authorize instructions to update both authorities + /// Issue stake::instruction::authorize instructions to update both + /// authorities #[allow(clippy::too_many_arguments)] fn stake_authorize_signed<'a>( stake_pool: &Pubkey, @@ -551,7 +553,8 @@ impl Processor { ) } - /// Issue stake::instruction::withdraw instruction to move additional lamports + /// Issue stake::instruction::withdraw instruction to move additional + /// lamports #[allow(clippy::too_many_arguments)] fn stake_withdraw<'a>( stake_pool: &Pubkey, @@ -1908,8 +1911,9 @@ impl Processor { // check that we're redelegating enough { - // redelegation requires that the source account maintains rent exemption and that - // the destination account has rent-exemption and minimum delegation + // redelegation requires that the source account maintains rent exemption and + // that the destination account has rent-exemption and minimum + // delegation let minimum_redelegation_lamports = current_minimum_delegation.saturating_add(stake_rent); if lamports < minimum_redelegation_lamports { @@ -2430,7 +2434,8 @@ impl Processor { // Status for validator stake // * active -> do everything - // * any other state / not a stake -> error state, but account for transient stake + // * any other state / not a stake -> error state, but account for transient + // stake let validator_stake_state = try_from_slice_unchecked::( &validator_stake_info.data.borrow(), ) @@ -3159,7 +3164,8 @@ impl Processor { } // To prevent a faulty manager fee account from preventing withdrawals - // if the token program does not own the account, or if the account is not initialized + // if the token program does not own the account, or if the account is not + // initialized let pool_tokens_fee = if stake_pool.manager_fee_account == *burn_from_pool_info.key || stake_pool.check_manager_fee_info(manager_fee_info).is_err() { @@ -3468,7 +3474,8 @@ impl Processor { } // To prevent a faulty manager fee account from preventing withdrawals - // if the token program does not own the account, or if the account is not initialized + // if the token program does not own the account, or if the account is not + // initialized let pool_tokens_fee = if stake_pool.manager_fee_account == *burn_from_pool_info.key || stake_pool.check_manager_fee_info(manager_fee_info).is_err() { diff --git a/program/src/state.rs b/program/src/state.rs index b218cecd..f35dd508 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -46,17 +46,18 @@ pub struct StakePool { /// Account type, must be StakePool currently pub account_type: AccountType, - /// Manager authority, allows for updating the staker, manager, and fee account + /// Manager authority, allows for updating the staker, manager, and fee + /// account pub manager: Pubkey, - /// Staker authority, allows for adding and removing validators, and managing stake - /// distribution + /// Staker authority, allows for adding and removing validators, and + /// managing stake distribution pub staker: Pubkey, /// Stake deposit authority /// - /// If a depositor pubkey is specified on initialization, then deposits must be - /// signed by this authority. If no deposit authority is specified, + /// If a depositor pubkey is specified on initialization, then deposits must + /// be signed by this authority. If no deposit authority is specified, /// then the stake pool will default to the result of: /// `Pubkey::find_program_address( /// &[&stake_pool_address.as_ref(), b"deposit"], @@ -88,7 +89,8 @@ pub struct StakePool { /// this field may not be accurate pub total_lamports: u64, - /// Total supply of pool tokens (should always match the supply in the Pool Mint) + /// Total supply of pool tokens (should always match the supply in the Pool + /// Mint) pub pool_token_supply: u64, /// Last epoch the `total_lamports` field was updated @@ -120,8 +122,9 @@ pub struct StakePool { /// Fees paid out to referrers on referred stake deposits. /// Expressed as a percentage (0 - 100) of deposit fees. - /// i.e. `stake_deposit_fee`% of stake deposited is collected as deposit fees for every deposit - /// and `stake_referral_fee`% of the collected stake deposit fees is paid out to the referrer + /// i.e. `stake_deposit_fee`% of stake deposited is collected as deposit + /// fees for every deposit and `stake_referral_fee`% of the collected + /// stake deposit fees is paid out to the referrer pub stake_referral_fee: u8, /// Toggles whether the `DepositSol` instruction requires a signature from @@ -133,8 +136,9 @@ pub struct StakePool { /// Fees paid out to referrers on referred SOL deposits. /// Expressed as a percentage (0 - 100) of SOL deposit fees. - /// i.e. `sol_deposit_fee`% of SOL deposited is collected as deposit fees for every deposit - /// and `sol_referral_fee`% of the collected SOL deposit fees is paid out to the referrer + /// i.e. `sol_deposit_fee`% of SOL deposited is collected as deposit fees + /// for every deposit and `sol_referral_fee`% of the collected SOL + /// deposit fees is paid out to the referrer pub sol_referral_fee: u8, /// Toggles whether the `WithdrawSol` instruction requires a signature from @@ -154,7 +158,8 @@ pub struct StakePool { pub last_epoch_total_lamports: u64, } impl StakePool { - /// calculate the pool tokens that should be minted for a deposit of `stake_lamports` + /// calculate the pool tokens that should be minted for a deposit of + /// `stake_lamports` #[inline] pub fn calc_pool_tokens_for_deposit(&self, stake_lamports: u64) -> Option { if self.total_lamports == 0 || self.pool_token_supply == 0 { @@ -218,7 +223,8 @@ impl StakePool { u64::try_from(self.sol_deposit_fee.apply(pool_tokens_minted)?).ok() } - /// calculate pool tokens to be deducted from SOL deposit fees as referral fees + /// calculate pool tokens to be deducted from SOL deposit fees as referral + /// fees #[inline] pub fn calc_pool_tokens_sol_referral_fee(&self, sol_deposit_fee: u64) -> Option { u64::try_from( @@ -537,7 +543,8 @@ pub fn is_extension_supported_for_fee_account(extension_type: &ExtensionType) -> #[repr(C)] #[derive(Clone, Debug, Default, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)] pub struct ValidatorList { - /// Data outside of the validator list, separated out for cheaper deserializations + /// Data outside of the validator list, separated out for cheaper + /// deserializations pub header: ValidatorListHeader, /// List of stake info for each validator in the pool @@ -606,7 +613,8 @@ impl Default for StakeStatus { )] pub struct PodStakeStatus(u8); impl PodStakeStatus { - /// Downgrade the status towards ready for removal by removing the validator stake + /// Downgrade the status towards ready for removal by removing the validator + /// stake pub fn remove_validator_stake(&mut self) -> Result<(), ProgramError> { let status = StakeStatus::try_from(*self)?; let new_self = match status { @@ -619,7 +627,8 @@ impl PodStakeStatus { *self = new_self.into(); Ok(()) } - /// Downgrade the status towards ready for removal by removing the transient stake + /// Downgrade the status towards ready for removal by removing the transient + /// stake pub fn remove_transient_stake(&mut self) -> Result<(), ProgramError> { let status = StakeStatus::try_from(*self)?; let new_self = match status { @@ -695,7 +704,8 @@ pub struct ValidatorStakeInfo { /// Last epoch the active and transient stake lamports fields were updated pub last_update_epoch: PodU64, - /// Transient account seed suffix, used to derive the transient stake account address + /// Transient account seed suffix, used to derive the transient stake + /// account address pub transient_seed_suffix: PodU64, /// Unused space, initially meant to specify the end of seed suffixes @@ -766,7 +776,8 @@ impl Pack for ValidatorStakeInfo { } impl ValidatorList { - /// Create an empty instance containing space for `max_validators` and preferred validator keys + /// Create an empty instance containing space for `max_validators` and + /// preferred validator keys pub fn new(max_validators: u32) -> Self { Self { header: ValidatorListHeader { @@ -777,7 +788,8 @@ impl ValidatorList { } } - /// Calculate the number of validator entries that fit in the provided length + /// Calculate the number of validator entries that fit in the provided + /// length pub fn calculate_max_validators(buffer_length: usize) -> usize { let header_size = ValidatorListHeader::LEN.saturating_add(4); buffer_length @@ -816,7 +828,8 @@ impl ValidatorList { impl ValidatorListHeader { const LEN: usize = 1 + 4; - /// Check if validator stake list is actually initialized as a validator stake list + /// Check if validator stake list is actually initialized as a validator + /// stake list pub fn is_valid(&self) -> bool { self.account_type == AccountType::ValidatorList } @@ -907,7 +920,8 @@ impl From> for Option { /// Fee rate as a ratio, minted on `UpdateStakePoolBalance` as a proportion of /// the rewards -/// If either the numerator or the denominator is 0, the fee is considered to be 0 +/// If either the numerator or the denominator is 0, the fee is considered to be +/// 0 #[repr(C)] #[derive(Clone, Copy, Debug, Default, PartialEq, BorshSerialize, BorshDeserialize, BorshSchema)] pub struct Fee { @@ -949,7 +963,8 @@ impl Fee { }; // Check that new_fee / old_fee <= MAX_WITHDRAWAL_FEE_INCREASE - // Program fails if provided numerator or denominator is too large, resulting in overflow + // Program fails if provided numerator or denominator is too large, resulting in + // overflow if (old_num as u128) .checked_mul(self.denominator as u128) .map(|x| x.checked_mul(MAX_WITHDRAWAL_FEE_INCREASE.numerator as u128)) @@ -1018,7 +1033,8 @@ impl FeeType { Ok(()) } - /// Returns if the contained fee can only be updated earliest on the next epoch + /// Returns if the contained fee can only be updated earliest on the next + /// epoch #[inline] pub fn can_only_change_next_epoch(&self) -> bool { matches!( @@ -1250,7 +1266,8 @@ mod test { let fee_lamports = stake_pool .calc_lamports_withdraw_amount(pool_token_fee) .unwrap(); - assert_eq!(fee_lamports, LAMPORTS_PER_SOL - 1); // off-by-one due to truncation + assert_eq!(fee_lamports, LAMPORTS_PER_SOL - 1); // off-by-one due to + // truncation } #[test] diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index ccfa5370..e87d3339 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -21,8 +21,8 @@ use { test_case::test_case, }; -// Note: this is not the real max! The testing framework starts to blow out because -// the test require so many helper accounts. +// Note: this is not the real max! The testing framework starts to blow out +// because the test require so many helper accounts. // 20k is also a very safe number for the current upper bound of the network. const MAX_POOL_SIZE_WITH_REQUESTED_COMPUTE_UNITS: u32 = 20_000; const MAX_POOL_SIZE: u32 = 3_000; diff --git a/program/tests/redelegate.rs b/program/tests/redelegate.rs index 47dc08a4..a9f12f5f 100644 --- a/program/tests/redelegate.rs +++ b/program/tests/redelegate.rs @@ -572,8 +572,8 @@ async fn success_with_increasing_stake() { .find(&destination_validator_stake.vote.pubkey()) .unwrap(); assert_eq!(u64::from(destination_item.transient_stake_lamports), 0); - // redelegate is smart enough to activate *everything*, so there's no rent-exemption - // worth of inactive stake! + // redelegate is smart enough to activate *everything*, so there's no + // rent-exemption worth of inactive stake! assert_eq!( u64::from(destination_item.active_stake_lamports), pre_validator_stake_account.lamports + redelegate_lamports + current_minimum_delegation diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index bfc6b7e0..89d6b5f6 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -509,7 +509,8 @@ async fn merge_into_validator_stake() { } // Check validator stake accounts have the expected balance now: - // validator stake account minimum + deposited lamports + rents + increased lamports + // validator stake account minimum + deposited lamports + rents + increased + // lamports let expected_lamports = current_minimum_delegation + lamports + increase_amount + stake_rent; for stake_account in &stake_accounts { let validator_stake = diff --git a/program/tests/withdraw_edge_cases.rs b/program/tests/withdraw_edge_cases.rs index 4af70cba..5390bce5 100644 --- a/program/tests/withdraw_edge_cases.rs +++ b/program/tests/withdraw_edge_cases.rs @@ -104,7 +104,8 @@ async fn success_remove_validator(multiple: u64) { _, ) = setup_for_withdraw(spl_token::id(), STAKE_ACCOUNT_RENT_EXEMPTION).await; - // make pool tokens very valuable, so it isn't possible to exactly get down to the minimum + // make pool tokens very valuable, so it isn't possible to exactly get down to + // the minimum transfer( &mut context.banks_client, &context.payer, @@ -130,7 +131,8 @@ async fn success_remove_validator(multiple: u64) { .await; let lamports_per_pool_token = stake_pool.get_lamports_per_pool_token().unwrap(); - // decrease all of stake except for lamports_per_pool_token lamports, must be withdrawable + // decrease all of stake except for lamports_per_pool_token lamports, must be + // withdrawable let error = stake_pool_accounts .decrease_validator_stake_either( &mut context.banks_client, @@ -625,7 +627,8 @@ async fn fail_withdraw_from_transient() { .await; assert!(error.is_none(), "{:?}", error); - // fail withdrawing from transient, still a lamport in the validator stake account + // fail withdrawing from transient, still a lamport in the validator stake + // account let new_user_authority = Pubkey::new_unique(); let error = stake_pool_accounts .withdraw_stake( @@ -750,7 +753,8 @@ async fn success_with_small_preferred_withdraw() { .await .unwrap(); - // make pool tokens very valuable, so it isn't possible to exactly get down to the minimum + // make pool tokens very valuable, so it isn't possible to exactly get down to + // the minimum transfer( &mut context.banks_client, &context.payer, @@ -794,7 +798,8 @@ async fn success_with_small_preferred_withdraw() { .await .unwrap(); - // add a tiny bit of stake, less than lamports per pool token to preferred validator + // add a tiny bit of stake, less than lamports per pool token to preferred + // validator let rent = context.banks_client.get_rent().await.unwrap(); let rent_exempt = rent.minimum_balance(std::mem::size_of::()); let stake_minimum_delegation = From 8abdb9b80249c117852801b8d7992ad9f57e71b0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Nov 2023 12:54:18 +0100 Subject: [PATCH 0589/1076] build(deps): bump serde from 1.0.190 to 1.0.192 (#5790) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.190 to 1.0.192. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.190...v1.0.192) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index f559672d..2a4bee9a 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "0.7.0" [dependencies] borsh = "0.10" clap = "2.33.3" -serde = "1.0.190" +serde = "1.0.192" serde_derive = "1.0.130" serde_json = "1.0.108" solana-account-decoder = "=1.17.2" diff --git a/program/Cargo.toml b/program/Cargo.toml index f2bdc7e5..2e45fecf 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,7 +18,7 @@ bytemuck = "1.13" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.1" -serde = "1.0.190" +serde = "1.0.192" serde_derive = "1.0.103" solana-program = "1.17.2" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } From f2ac4e7f3dfd7309afd17aa6d8b43ded4b20fbe9 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 9 Nov 2023 13:03:24 +0100 Subject: [PATCH 0590/1076] js: Move everything to pnpm (#5775) * Add workspace file and lockfile after install * Update tlv library to pnpm * Update memo to newer jest / pnpm * name-service: Update to pnpm, fix old deps * stake-pool: Update to pnpm * token: Update to pnpm * token-lending: Update to pnpm and some new packages * token-swap: Update to pnpm * token-metadata: Update to pnpm * single-pool: Add to same workspace * CI: Use pnpm everywhere * Use workspace versions of internal packages * Build dependent packages in CI * Update lockfile, remove some unused packages * Move token-swap tests to mocha * Move tests into test file, maybe that'll do it? * Update token-swap js build * Use updated eslint in token-swap * Fixup token ci build to include memo * ci: Trigger on changes to pnpm-lock.yaml * Refresh pnpm lock file --- clients/js-legacy/package-lock.json | 12983 -------------------------- clients/js-legacy/package.json | 6 +- 2 files changed, 3 insertions(+), 12986 deletions(-) delete mode 100644 clients/js-legacy/package-lock.json diff --git a/clients/js-legacy/package-lock.json b/clients/js-legacy/package-lock.json deleted file mode 100644 index 38212424..00000000 --- a/clients/js-legacy/package-lock.json +++ /dev/null @@ -1,12983 +0,0 @@ -{ - "name": "@solana/spl-stake-pool", - "version": "0.7.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "@solana/spl-stake-pool", - "version": "0.7.0", - "license": "ISC", - "dependencies": { - "@coral-xyz/borsh": "^0.29.0", - "@solana/buffer-layout": "^4.0.1", - "@solana/spl-token": "^0.3.7", - "@solana/web3.js": "^1.76.0", - "bn.js": "^5.2.0", - "buffer": "^6.0.3" - }, - "devDependencies": { - "@rollup/plugin-alias": "^5.0.0", - "@rollup/plugin-commonjs": "^25.0.0", - "@rollup/plugin-json": "^6.0.0", - "@rollup/plugin-multi-entry": "^6.0.0", - "@rollup/plugin-node-resolve": "^15.0.2", - "@rollup/plugin-terser": "^0.4.4", - "@rollup/plugin-typescript": "^11.1.0", - "@types/bn.js": "^5.1.0", - "@types/jest": "^27.4.0", - "@types/node": "^20.1.2", - "@types/node-fetch": "^2.6.3", - "@typescript-eslint/eslint-plugin": "^6.0.0", - "@typescript-eslint/parser": "^6.0.0", - "cross-env": "^7.0.3", - "eslint": "^8.40.0", - "eslint-config-prettier": "^9.0.0", - "eslint-plugin-prettier": "^5.0.0", - "jest": "^27.5.1", - "prettier": "^3.0.0", - "rimraf": "^5.0.0", - "rollup": "^4.0.2", - "rollup-plugin-dts": "^6.1.0", - "rollup-plugin-node-polyfills": "^0.2.1", - "ts-jest": "^27.1.3", - "typescript": "^4.5.4" - } - }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.0.tgz", - "integrity": "sha512-d5RysTlJ7hmw5Tw4UxgxcY3lkMe92n8sXCcuLPAyIAHK6j8DefDwtGnVVDgOnv+RnEosulDJ9NPKQL27bDId0g==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", - "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.22.13", - "chalk": "^2.4.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/code-frame/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/code-frame/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/code-frame/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.0.tgz", - "integrity": "sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.17.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.2.tgz", - "integrity": "sha512-R3VH5G42VSDolRHyUO4V2cfag8WHcZyxdq5Z/m8Xyb92lW/Erm/6kM+XtRFGf3Mulre3mveni2NHfEUws8wSvw==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.0.0", - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.0", - "@babel/helper-compilation-targets": "^7.16.7", - "@babel/helper-module-transforms": "^7.16.7", - "@babel/helpers": "^7.17.2", - "@babel/parser": "^7.17.0", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.0", - "@babel/types": "^7.17.0", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", - "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", - "dev": true, - "dependencies": { - "@babel/types": "^7.23.0", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", - "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.16.4", - "@babel/helper-validator-option": "^7.16.7", - "browserslist": "^4.17.5", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", - "dev": true, - "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", - "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz", - "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-simple-access": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/helper-validator-identifier": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.16.7", - "@babel/types": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", - "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", - "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", - "dev": true, - "dependencies": { - "@babel/types": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", - "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.17.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.2.tgz", - "integrity": "sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ==", - "dev": true, - "dependencies": { - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.0", - "@babel/types": "^7.17.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", - "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", - "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz", - "integrity": "sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz", - "integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", - "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.23.0", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.0", - "@babel/types": "^7.23.0", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/types": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", - "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", - "dev": true, - "dependencies": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "node_modules/@coral-xyz/borsh": { - "version": "0.29.0", - "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.29.0.tgz", - "integrity": "sha512-s7VFVa3a0oqpkuRloWVPdCK7hMbAMY270geZOGfCnaqexrP5dTIpbEHL33req6IYPPJ0hYa71cdvJ1h6V55/oQ==", - "dependencies": { - "bn.js": "^5.1.2", - "buffer-layout": "^1.2.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@solana/web3.js": "^1.68.0" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.2.tgz", - "integrity": "sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/js": { - "version": "8.52.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.52.0.tgz", - "integrity": "sha512-mjZVbpaeMZludF2fsWLD0Z9gCref1Tk4i9+wddjRvpUNqqcndPkBD09N/Mapey0b3jaXbLm2kICwFv2E64QinA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.13", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", - "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", - "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", - "dev": true - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "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" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", - "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/core": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", - "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", - "dev": true, - "dependencies": { - "@jest/console": "^27.5.1", - "@jest/reporters": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^27.5.1", - "jest-config": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-resolve-dependencies": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "jest-watcher": "^27.5.1", - "micromatch": "^4.0.4", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/core/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@jest/environment": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", - "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", - "dev": true, - "dependencies": { - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/fake-timers": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", - "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "@sinonjs/fake-timers": "^8.0.1", - "@types/node": "*", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/globals": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", - "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", - "dev": true, - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/types": "^27.5.1", - "expect": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/reporters": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", - "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", - "dev": true, - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-haste-map": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^8.1.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/source-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", - "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9", - "source-map": "^0.6.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/test-result": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", - "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", - "dev": true, - "dependencies": { - "@jest/console": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/test-sequencer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", - "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", - "dev": true, - "dependencies": { - "@jest/test-result": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-runtime": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/transform": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", - "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", - "dev": true, - "dependencies": { - "@babel/core": "^7.1.0", - "@jest/types": "^27.5.1", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-util": "^27.5.1", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.3.tgz", - "integrity": "sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", - "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - } - }, - "node_modules/@noble/curves": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", - "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", - "dependencies": { - "@noble/hashes": "1.3.2" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@noble/hashes": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", - "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@pkgr/utils": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.1.tgz", - "integrity": "sha512-JOqwkgFEyi+OROIyq7l4Jy28h/WwhDnG/cPkXG2Z1iFbubB6jsHW1NDvmyOzTBxHr3yg68YGirmh1JUgMqa+9w==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "fast-glob": "^3.2.12", - "is-glob": "^4.0.3", - "open": "^9.1.0", - "picocolors": "^1.0.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, - "node_modules/@rollup/plugin-alias": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.0.1.tgz", - "integrity": "sha512-JObvbWdOHoMy9W7SU0lvGhDtWq9PllP5mjpAy+TUslZG/WzOId9u80Hsqq1vCUn9pFJ0cxpdcnAv+QzU2zFH3Q==", - "dev": true, - "dependencies": { - "slash": "^4.0.0" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-alias/node_modules/slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@rollup/plugin-commonjs": { - "version": "25.0.7", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.7.tgz", - "integrity": "sha512-nEvcR+LRjEjsaSsc4x3XZfCCvZIaSMenZu/OiwOKGN2UhQpAYI7ru7czFvyWbErlpoGjnSX3D5Ch5FcMA3kRWQ==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "commondir": "^1.0.1", - "estree-walker": "^2.0.2", - "glob": "^8.0.3", - "is-reference": "1.2.1", - "magic-string": "^0.30.3" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^2.68.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-commonjs/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "node_modules/@rollup/plugin-commonjs/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@rollup/plugin-commonjs/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@rollup/plugin-commonjs/node_modules/magic-string": { - "version": "0.30.5", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", - "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@rollup/plugin-commonjs/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@rollup/plugin-json": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.0.1.tgz", - "integrity": "sha512-RgVfl5hWMkxN1h/uZj8FVESvPuBJ/uf6ly6GTj0GONnkfoBN5KC0MSz+PN2OLDgYXMhtG0mWpTrkiOjoxAIevw==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^5.0.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-multi-entry": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-multi-entry/-/plugin-multi-entry-6.0.1.tgz", - "integrity": "sha512-AXm6toPyTSfbYZWghQGbom1Uh7dHXlrGa+HoiYNhQtDUE3Q7LqoUYdVQx9E1579QWS1uOiu+cZRSE4okO7ySgw==", - "dev": true, - "dependencies": { - "@rollup/plugin-virtual": "^3.0.0", - "matched": "^5.0.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-node-resolve": { - "version": "15.2.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", - "integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "@types/resolve": "1.20.2", - "deepmerge": "^4.2.2", - "is-builtin-module": "^3.2.1", - "is-module": "^1.0.0", - "resolve": "^1.22.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^2.78.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-terser": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", - "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", - "dev": true, - "dependencies": { - "serialize-javascript": "^6.0.1", - "smob": "^1.0.0", - "terser": "^5.17.4" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-terser/node_modules/serialize-javascript": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", - "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/@rollup/plugin-typescript": { - "version": "11.1.5", - "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.5.tgz", - "integrity": "sha512-rnMHrGBB0IUEv69Q8/JGRD/n4/n6b3nfpufUu26axhUcboUzv/twfZU8fIBbTOphRAe0v8EyxzeDpKXqGHfyDA==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "resolve": "^1.22.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^2.14.0||^3.0.0||^4.0.0", - "tslib": "*", - "typescript": ">=3.7.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - }, - "tslib": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-virtual": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-virtual/-/plugin-virtual-3.0.2.tgz", - "integrity": "sha512-10monEYsBp3scM4/ND4LNH5Rxvh3e/cVeL3jWTgZ2SrQ+BmUoQcopVQvnaMcOnykb1VkxUFuDAN+0FnpTFRy2A==", - "dev": true, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/pluginutils": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.5.tgz", - "integrity": "sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==", - "dev": true, - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.2.0.tgz", - "integrity": "sha512-8PlggAxGxavr+pkCNeV1TM2wTb2o+cUWDg9M1cm9nR27Dsn287uZtSLYXoQqQcmq+sYfF7lHfd3sWJJinH9GmA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.2.0.tgz", - "integrity": "sha512-+71T85hbMFrJI+zKQULNmSYBeIhru55PYoF/u75MyeN2FcxE4HSPw20319b+FcZ4lWx2Nx/Ql9tN+hoaD3GH/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.2.0.tgz", - "integrity": "sha512-IIIQLuG43QIElT1JZqUP/zqIdiJl4t9U/boa0GZnQTw9m1X0k3mlBuysbgYXeloLT1RozdL7bgw4lpSaI8GOXw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.2.0.tgz", - "integrity": "sha512-BXcXvnLaea1Xz900omrGJhxHFJfH9jZ0CpJuVsbjjhpniJ6qiLXz3xA8Lekaa4MuhFcJd4f0r+Ky1G4VFbYhWw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.2.0.tgz", - "integrity": "sha512-f4K3MKw9Y4AKi4ANGnmPIglr+S+8tO858YrGVuqAHXxJdVghBmz9CPU9kDpOnGvT4g4vg5uNyIFpOOFvffXyMA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.2.0.tgz", - "integrity": "sha512-bNsTYQBgp4H7w6cT7FZhesxpcUPahsSIy4NgdZjH1ZwEoZHxi4XKglj+CsSEkhsKi+x6toVvMylhjRKhEMYfnA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.2.0.tgz", - "integrity": "sha512-Jp1NxBJpGLuxRU2ihrQk4IZ+ia5nffobG6sOFUPW5PMYkF0kQtxEbeDuCa69Xif211vUOcxlOnf5IOEIpTEySA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.2.0.tgz", - "integrity": "sha512-3p3iRtQmv2aXw+vtKNyZMLOQ+LSRsqArXjKAh2Oj9cqwfIRe7OXvdkOzWfZOIp1F/x5KJzVAxGxnniF4cMbnsQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.2.0.tgz", - "integrity": "sha512-atih7IF/reUZe4LBLC5Izd44hth2tfDIG8LaPp4/cQXdHh9jabcZEvIeRPrpDq0i/Uu487Qu5gl5KwyAnWajnw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.2.0.tgz", - "integrity": "sha512-vYxF3tKJeUE4ceYzpNe2p84RXk/fGK30I8frpRfv/MyPStej/mRlojztkN7Jtd1014HHVeq/tYaMBz/3IxkxZw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.2.0.tgz", - "integrity": "sha512-1LZJ6zpl93SaPQvas618bMFarVwufWTaczH4ESAbFcwiC4OtznA6Ym+hFPyIGaJaGEB8uMWWac0uXGPXOg5FGA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.2.0.tgz", - "integrity": "sha512-dgQfFdHCNg08nM5zBmqxqc9vrm0DVzhWotpavbPa0j4//MAOKZEB75yGAfzQE9fUJ+4pvM1239Y4IhL8f6sSog==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", - "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, - "node_modules/@solana/buffer-layout": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz", - "integrity": "sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==", - "dependencies": { - "buffer": "~6.0.3" - }, - "engines": { - "node": ">=5.10" - } - }, - "node_modules/@solana/buffer-layout-utils": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@solana/buffer-layout-utils/-/buffer-layout-utils-0.2.0.tgz", - "integrity": "sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==", - "dependencies": { - "@solana/buffer-layout": "^4.0.0", - "@solana/web3.js": "^1.32.0", - "bigint-buffer": "^1.1.5", - "bignumber.js": "^9.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/@solana/spl-token": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.3.8.tgz", - "integrity": "sha512-ogwGDcunP9Lkj+9CODOWMiVJEdRtqHAtX2rWF62KxnnSWtMZtV9rDhTrZFshiyJmxDnRL/1nKE1yJHg4jjs3gg==", - "dependencies": { - "@solana/buffer-layout": "^4.0.0", - "@solana/buffer-layout-utils": "^0.2.0", - "buffer": "^6.0.3" - }, - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "@solana/web3.js": "^1.47.4" - } - }, - "node_modules/@solana/web3.js": { - "version": "1.87.3", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.87.3.tgz", - "integrity": "sha512-WGLzTZpi00vP443qGK3gL+LZXQJwaWkh6bzNXYpMTCAH2Z102y3YbPWOoQzJUeRSZWSXKh7MFkA3vDMFlMvGZQ==", - "dependencies": { - "@babel/runtime": "^7.23.2", - "@noble/curves": "^1.2.0", - "@noble/hashes": "^1.3.1", - "@solana/buffer-layout": "^4.0.0", - "agentkeepalive": "^4.3.0", - "bigint-buffer": "^1.1.5", - "bn.js": "^5.2.1", - "borsh": "^0.7.0", - "bs58": "^4.0.1", - "buffer": "6.0.3", - "fast-stable-stringify": "^1.0.0", - "jayson": "^4.1.0", - "node-fetch": "^2.6.12", - "rpc-websockets": "^7.5.1", - "superstruct": "^0.14.2" - } - }, - "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@types/babel__core": { - "version": "7.1.18", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.18.tgz", - "integrity": "sha512-S7unDjm/C7z2A2R9NzfKCK1I+BAALDtxEmsJBwlB3EzNfb929ykjL++1CK9LO++EIp2fQrC8O+BwjKvz6UeDyQ==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", - "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", - "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.3.0" - } - }, - "node_modules/@types/bn.js": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.4.tgz", - "integrity": "sha512-ZtBd9L8hVtoBpPMSWfbwjC4dhQtJdlPS+e1A0Rydb7vg7bDcUwiRklPx24sMYtXcmAMST/k0Wze7JLbNU/5SkA==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", - "dev": true - }, - "node_modules/@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", - "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", - "dev": true - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/jest": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.0.tgz", - "integrity": "sha512-gHl8XuC1RZ8H2j5sHv/JqsaxXkDDM9iDOgu0Wp8sjs4u/snb2PVehyWXJPr+ORA0RPpgw231mnutWI1+0hgjIQ==", - "dev": true, - "dependencies": { - "jest-diff": "^27.0.0", - "pretty-format": "^27.0.0" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true - }, - "node_modules/@types/node": { - "version": "20.8.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.10.tgz", - "integrity": "sha512-TlgT8JntpcbmKUFzjhsyhGfP2fsiz1Mv56im6enJ905xG1DAYesxJaeSbGqQmAw8OWPdhyJGhGSQGKRNJ45u9w==", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/node-fetch": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.9.tgz", - "integrity": "sha512-bQVlnMLFJ2d35DkPNjEPmd9ueO/rh5EiaZt2bhqiSarPjZIuIV6bPQVqcrEyvNo+AfTrRGVazle1tl597w3gfA==", - "dev": true, - "dependencies": { - "@types/node": "*", - "form-data": "^4.0.0" - } - }, - "node_modules/@types/node-fetch/node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@types/prettier": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.4.tgz", - "integrity": "sha512-ReVR2rLTV1kvtlWFyuot+d1pkpG2Fw/XKE3PDAdj57rbM97ttSp9JZ2UsP+2EHTylra9cUf6JA7tGwW1INzUrA==", - "dev": true - }, - "node_modules/@types/resolve": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", - "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", - "dev": true - }, - "node_modules/@types/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==", - "dev": true - }, - "node_modules/@types/stack-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", - "dev": true - }, - "node_modules/@types/ws": { - "version": "7.4.7", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", - "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/yargs": { - "version": "16.0.4", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", - "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", - "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", - "dev": true - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.10.0.tgz", - "integrity": "sha512-uoLj4g2OTL8rfUQVx2AFO1hp/zja1wABJq77P6IclQs6I/m9GLrm7jCdgzZkvWdDCQf1uEvoa8s8CupsgWQgVg==", - "dev": true, - "dependencies": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.10.0", - "@typescript-eslint/type-utils": "6.10.0", - "@typescript-eslint/utils": "6.10.0", - "@typescript-eslint/visitor-keys": "6.10.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.4", - "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.10.0.tgz", - "integrity": "sha512-TN/plV7dzqqC2iPNf1KrxozDgZs53Gfgg5ZHyw8erd6jd5Ta/JIEcdCheXFt9b1NYb93a1wmIIVW/2gLkombDg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.10.0", - "@typescript-eslint/visitor-keys": "6.10.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.10.0.tgz", - "integrity": "sha512-36Fq1PWh9dusgo3vH7qmQAj5/AZqARky1Wi6WpINxB6SkQdY5vQoT2/7rW7uBIsPDcvvGCLi4r10p0OJ7ITAeg==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.10.0.tgz", - "integrity": "sha512-xMGluxQIEtOM7bqFCo+rCMh5fqI+ZxV5RUUOa29iVPz1OgCZrtc7rFnz5cLUazlkPKYqX+75iuDq7m0HQ48nCg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.10.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.10.0.tgz", - "integrity": "sha512-+sZwIj+s+io9ozSxIWbNB5873OSdfeBEH/FR0re14WLI6BaKuSOnnwCJ2foUiu8uXf4dRp1UqHP0vrZ1zXGrog==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "6.10.0", - "@typescript-eslint/types": "6.10.0", - "@typescript-eslint/typescript-estree": "6.10.0", - "@typescript-eslint/visitor-keys": "6.10.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.10.0.tgz", - "integrity": "sha512-TN/plV7dzqqC2iPNf1KrxozDgZs53Gfgg5ZHyw8erd6jd5Ta/JIEcdCheXFt9b1NYb93a1wmIIVW/2gLkombDg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.10.0", - "@typescript-eslint/visitor-keys": "6.10.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.10.0.tgz", - "integrity": "sha512-36Fq1PWh9dusgo3vH7qmQAj5/AZqARky1Wi6WpINxB6SkQdY5vQoT2/7rW7uBIsPDcvvGCLi4r10p0OJ7ITAeg==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.10.0.tgz", - "integrity": "sha512-ek0Eyuy6P15LJVeghbWhSrBCj/vJpPXXR+EpaRZqou7achUWL8IdYnMSC5WHAeTWswYQuP2hAZgij/bC9fanBg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.10.0", - "@typescript-eslint/visitor-keys": "6.10.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.10.0.tgz", - "integrity": "sha512-xMGluxQIEtOM7bqFCo+rCMh5fqI+ZxV5RUUOa29iVPz1OgCZrtc7rFnz5cLUazlkPKYqX+75iuDq7m0HQ48nCg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.10.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.1.tgz", - "integrity": "sha512-38IxvKB6NAne3g/+MyXMs2Cda/Sz+CEpmm+KLGEM8hx/CvnSRuw51i8ukfwB/B/sESdeTGet1NH1Wj7I0YXswg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.9.1", - "@typescript-eslint/visitor-keys": "6.9.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.10.0.tgz", - "integrity": "sha512-wYpPs3hgTFblMYwbYWPT3eZtaDOjbLyIYuqpwuLBBqhLiuvJ+9sEp2gNRJEtR5N/c9G1uTtQQL5AhV0fEPJYcg==", - "dev": true, - "dependencies": { - "@typescript-eslint/typescript-estree": "6.10.0", - "@typescript-eslint/utils": "6.10.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.10.0.tgz", - "integrity": "sha512-36Fq1PWh9dusgo3vH7qmQAj5/AZqARky1Wi6WpINxB6SkQdY5vQoT2/7rW7uBIsPDcvvGCLi4r10p0OJ7ITAeg==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.10.0.tgz", - "integrity": "sha512-ek0Eyuy6P15LJVeghbWhSrBCj/vJpPXXR+EpaRZqou7achUWL8IdYnMSC5WHAeTWswYQuP2hAZgij/bC9fanBg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.10.0", - "@typescript-eslint/visitor-keys": "6.10.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.10.0.tgz", - "integrity": "sha512-xMGluxQIEtOM7bqFCo+rCMh5fqI+ZxV5RUUOa29iVPz1OgCZrtc7rFnz5cLUazlkPKYqX+75iuDq7m0HQ48nCg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.10.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.1.tgz", - "integrity": "sha512-BUGslGOb14zUHOUmDB2FfT6SI1CcZEJYfF3qFwBeUrU6srJfzANonwRYHDpLBuzbq3HaoF2XL2hcr01c8f8OaQ==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.1.tgz", - "integrity": "sha512-U+mUylTHfcqeO7mLWVQ5W/tMLXqVpRv61wm9ZtfE5egz7gtnmqVIw9ryh0mgIlkKk9rZLY3UHygsBSdB9/ftyw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.9.1", - "@typescript-eslint/visitor-keys": "6.9.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.10.0.tgz", - "integrity": "sha512-v+pJ1/RcVyRc0o4wAGux9x42RHmAjIGzPRo538Z8M1tVx6HOnoQBCX/NoadHQlZeC+QO2yr4nNSFWOoraZCAyg==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.10.0", - "@typescript-eslint/types": "6.10.0", - "@typescript-eslint/typescript-estree": "6.10.0", - "semver": "^7.5.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.10.0.tgz", - "integrity": "sha512-TN/plV7dzqqC2iPNf1KrxozDgZs53Gfgg5ZHyw8erd6jd5Ta/JIEcdCheXFt9b1NYb93a1wmIIVW/2gLkombDg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.10.0", - "@typescript-eslint/visitor-keys": "6.10.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.10.0.tgz", - "integrity": "sha512-36Fq1PWh9dusgo3vH7qmQAj5/AZqARky1Wi6WpINxB6SkQdY5vQoT2/7rW7uBIsPDcvvGCLi4r10p0OJ7ITAeg==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.10.0.tgz", - "integrity": "sha512-ek0Eyuy6P15LJVeghbWhSrBCj/vJpPXXR+EpaRZqou7achUWL8IdYnMSC5WHAeTWswYQuP2hAZgij/bC9fanBg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.10.0", - "@typescript-eslint/visitor-keys": "6.10.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.10.0.tgz", - "integrity": "sha512-xMGluxQIEtOM7bqFCo+rCMh5fqI+ZxV5RUUOa29iVPz1OgCZrtc7rFnz5cLUazlkPKYqX+75iuDq7m0HQ48nCg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.10.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.1.tgz", - "integrity": "sha512-MUaPUe/QRLEffARsmNfmpghuQkW436DvESW+h+M52w0coICHRfD6Np9/K6PdACwnrq1HmuLl+cSPZaJmeVPkSw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.9.1", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, - "node_modules/abab": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", - "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", - "dev": true - }, - "node_modules/acorn": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz", - "integrity": "sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "dev": true, - "dependencies": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } - }, - "node_modules/acorn-globals/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/agentkeepalive": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.3.0.tgz", - "integrity": "sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg==", - "dependencies": { - "debug": "^4.1.0", - "depd": "^2.0.0", - "humanize-ms": "^1.2.1" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "node_modules/babel-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", - "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", - "dev": true, - "dependencies": { - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.8.0" - } - }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-jest-hoist": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", - "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", - "dev": true, - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dev": true, - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-preset-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", - "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", - "dev": true, - "dependencies": { - "babel-plugin-jest-hoist": "^27.5.1", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/base-x": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", - "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/big-integer": { - "version": "1.6.51", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", - "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/bigint-buffer": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/bigint-buffer/-/bigint-buffer-1.1.5.tgz", - "integrity": "sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==", - "hasInstallScript": true, - "dependencies": { - "bindings": "^1.3.0" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/bignumber.js": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.1.tgz", - "integrity": "sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig==", - "engines": { - "node": "*" - } - }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" - }, - "node_modules/borsh": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/borsh/-/borsh-0.7.0.tgz", - "integrity": "sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==", - "dependencies": { - "bn.js": "^5.2.0", - "bs58": "^4.0.0", - "text-encoding-utf-8": "^1.0.2" - } - }, - "node_modules/bplist-parser": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz", - "integrity": "sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==", - "dev": true, - "dependencies": { - "big-integer": "^1.6.44" - }, - "engines": { - "node": ">= 5.10.0" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true - }, - "node_modules/browserslist": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", - "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==", - "dev": true, - "dependencies": { - "caniuse-lite": "^1.0.30001286", - "electron-to-chromium": "^1.4.17", - "escalade": "^3.1.1", - "node-releases": "^2.0.1", - "picocolors": "^1.0.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - } - }, - "node_modules/bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "dev": true, - "dependencies": { - "fast-json-stable-stringify": "2.x" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", - "dependencies": { - "base-x": "^3.0.2" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "dependencies": { - "node-int64": "^0.4.0" - } - }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/buffer-layout": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/buffer-layout/-/buffer-layout-1.2.2.tgz", - "integrity": "sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==", - "engines": { - "node": ">=4.5" - } - }, - "node_modules/bufferutil": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.6.tgz", - "integrity": "sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw==", - "hasInstallScript": true, - "optional": true, - "dependencies": { - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">=6.14.2" - } - }, - "node_modules/builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/bundle-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", - "integrity": "sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==", - "dev": true, - "dependencies": { - "run-applescript": "^5.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001311", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001311.tgz", - "integrity": "sha512-mleTFtFKfykEeW34EyfhGIFjGCqzhh38Y0LhdQ9aWF+HorZTtdgKV/1hEE0NlFkG2ubvisPV6l400tlbPys98A==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/ci-info": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", - "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", - "dev": true - }, - "node_modules/cjs-module-lexer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", - "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", - "dev": true - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true, - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", - "dev": true - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "node_modules/convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.1" - } - }, - "node_modules/convert-source-map/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/cross-env": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", - "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "bin": { - "cross-env": "src/bin/cross-env.js", - "cross-env-shell": "src/bin/cross-env-shell.js" - }, - "engines": { - "node": ">=10.14", - "npm": ">=6", - "yarn": ">=1" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", - "dev": true - }, - "node_modules/cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dev": true, - "dependencies": { - "cssom": "~0.3.6" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cssstyle/node_modules/cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true - }, - "node_modules/data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dev": true, - "dependencies": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decimal.js": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", - "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", - "dev": true - }, - "node_modules/dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", - "dev": true - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/default-browser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz", - "integrity": "sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==", - "dev": true, - "dependencies": { - "bundle-name": "^3.0.0", - "default-browser-id": "^3.0.0", - "execa": "^7.1.1", - "titleize": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser-id": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz", - "integrity": "sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==", - "dev": true, - "dependencies": { - "bplist-parser": "^0.2.0", - "untildify": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser/node_modules/execa": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-7.1.1.tgz", - "integrity": "sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.1", - "human-signals": "^4.3.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^3.0.7", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": "^14.18.0 || ^16.14.0 || >=18.0.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/default-browser/node_modules/human-signals": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", - "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", - "dev": true, - "engines": { - "node": ">=14.18.0" - } - }, - "node_modules/default-browser/node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser/node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser/node_modules/npm-run-path": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", - "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", - "dev": true, - "dependencies": { - "path-key": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser/node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser/node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/define-lazy-prop": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", - "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/delay": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", - "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/diff-sequences": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", - "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", - "dev": true, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", - "dev": true, - "dependencies": { - "webidl-conversions": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/domexception/node_modules/webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true - }, - "node_modules/electron-to-chromium": { - "version": "1.4.68", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.68.tgz", - "integrity": "sha512-cId+QwWrV8R1UawO6b9BR1hnkJ4EJPCPAr4h315vliHUtVUJDk39Sg1PMNnaWKfj5x+93ssjeJ9LKL6r8LaMiA==", - "dev": true - }, - "node_modules/emittery": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", - "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "node_modules/es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", - "dependencies": { - "es6-promise": "^4.0.3" - } - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/escodegen": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", - "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", - "dev": true, - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/escodegen/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/eslint": { - "version": "8.52.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.52.0.tgz", - "integrity": "sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.52.0", - "@humanwhocodes/config-array": "^0.11.13", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-prettier": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz", - "integrity": "sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==", - "dev": true, - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-plugin-prettier": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.1.tgz", - "integrity": "sha512-m3u5RnR56asrwV/lDC4GHorlW75DsFfmUcjfCYylTUs85dBRnB7VM6xG8eCMJdeDRnppzmxZVf1GEPJvl1JmNg==", - "dev": true, - "dependencies": { - "prettier-linter-helpers": "^1.0.0", - "synckit": "^0.8.5" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/prettier" - }, - "peerDependencies": { - "@types/eslint": ">=8.0.0", - "eslint": ">=8.0.0", - "prettier": ">=3.0.0" - }, - "peerDependenciesMeta": { - "@types/eslint": { - "optional": true - }, - "eslint-config-prettier": { - "optional": true - } - } - }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" - }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/expect": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", - "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/eyes": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", - "integrity": "sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==", - "engines": { - "node": "> 0.1.90" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.0.tgz", - "integrity": "sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "node_modules/fast-stable-stringify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz", - "integrity": "sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==" - }, - "node_modules/fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", - "dev": true, - "dependencies": { - "bser": "2.1.1" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/flatted": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", - "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", - "dev": true - }, - "node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/foreground-child/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "13.21.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", - "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", - "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", - "dev": true - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "dev": true, - "dependencies": { - "whatwg-encoding": "^1.0.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dev": true, - "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "dev": true, - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/humanize-ms": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", - "dependencies": { - "ms": "^2.0.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "dev": true, - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "node_modules/is-builtin-module": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", - "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", - "dev": true, - "dependencies": { - "builtin-modules": "^3.3.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-core-module": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.0.tgz", - "integrity": "sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-docker": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", - "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", - "dev": true, - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-inside-container": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", - "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", - "dev": true, - "dependencies": { - "is-docker": "^3.0.0" - }, - "bin": { - "is-inside-container": "cli.js" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", - "dev": true - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true - }, - "node_modules/is-reference": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", - "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", - "dev": true, - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-wsl/node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true, - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "node_modules/isomorphic-ws": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", - "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", - "peerDependencies": { - "ws": "*" - } - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", - "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", - "dev": true, - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-reports": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz", - "integrity": "sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==", - "dev": true, - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jackspeak": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.5.tgz", - "integrity": "sha512-Ratx+B8WeXLAtRJn26hrhY8S1+Jz6pxPMrkrdkgb/NstTNiqMhX0/oFVu5wX+g5n6JlEu2LPsDJmY8nRP4+alw==", - "dev": true, - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/jayson": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/jayson/-/jayson-4.1.0.tgz", - "integrity": "sha512-R6JlbyLN53Mjku329XoRT2zJAE6ZgOQ8f91ucYdMCD4nkGCF9kZSrcGXpHIU4jeKj58zUZke2p+cdQchU7Ly7A==", - "dependencies": { - "@types/connect": "^3.4.33", - "@types/node": "^12.12.54", - "@types/ws": "^7.4.4", - "commander": "^2.20.3", - "delay": "^5.0.0", - "es6-promisify": "^5.0.0", - "eyes": "^0.1.8", - "isomorphic-ws": "^4.0.1", - "json-stringify-safe": "^5.0.1", - "JSONStream": "^1.3.5", - "uuid": "^8.3.2", - "ws": "^7.4.5" - }, - "bin": { - "jayson": "bin/jayson.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jayson/node_modules/@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==" - }, - "node_modules/jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", - "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", - "dev": true, - "dependencies": { - "@jest/core": "^27.5.1", - "import-local": "^3.0.2", - "jest-cli": "^27.5.1" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-changed-files": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", - "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "execa": "^5.0.0", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-circus": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", - "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", - "dev": true, - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-cli": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", - "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", - "dev": true, - "dependencies": { - "@jest/core": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "import-local": "^3.0.2", - "jest-config": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "prompts": "^2.0.1", - "yargs": "^16.2.0" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-config": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", - "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", - "dev": true, - "dependencies": { - "@babel/core": "^7.8.0", - "@jest/test-sequencer": "^27.5.1", - "@jest/types": "^27.5.1", - "babel-jest": "^27.5.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.9", - "jest-circus": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-jasmine2": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - } - } - }, - "node_modules/jest-diff": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", - "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-docblock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", - "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", - "dev": true, - "dependencies": { - "detect-newline": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-each": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", - "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-environment-jsdom": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", - "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", - "dev": true, - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1", - "jsdom": "^16.6.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-environment-node": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", - "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", - "dev": true, - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-get-type": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", - "dev": true, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-haste-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", - "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^27.5.1", - "jest-serializer": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "micromatch": "^4.0.4", - "walker": "^1.0.7" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - } - }, - "node_modules/jest-jasmine2": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", - "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", - "dev": true, - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-leak-detector": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", - "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", - "dev": true, - "dependencies": { - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-matcher-utils": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", - "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-message-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", - "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.5.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-mock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", - "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true, - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } - } - }, - "node_modules/jest-regex-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", - "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", - "dev": true, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-resolve": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", - "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-resolve-dependencies": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", - "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-snapshot": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-runner": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", - "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", - "dev": true, - "dependencies": { - "@jest/console": "^27.5.1", - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-leak-detector": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "source-map-support": "^0.5.6", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-runtime": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", - "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", - "dev": true, - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/globals": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "execa": "^5.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-serializer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", - "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", - "dev": true, - "dependencies": { - "@types/node": "*", - "graceful-fs": "^4.2.9" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-snapshot": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", - "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", - "dev": true, - "dependencies": { - "@babel/core": "^7.7.2", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.0.0", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "natural-compare": "^1.4.0", - "pretty-format": "^27.5.1", - "semver": "^7.3.2" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-validate": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", - "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "leven": "^3.1.0", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-watcher": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", - "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", - "dev": true, - "dependencies": { - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^27.5.1", - "string-length": "^4.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dev": true, - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", - "dev": true, - "dependencies": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "canvas": "^2.5.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", - "engines": [ - "node >= 0.2.0" - ] - }, - "node_modules/JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "dependencies": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - }, - "bin": { - "JSONStream": "bin.js" - }, - "engines": { - "node": "*" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", - "dev": true - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/magic-string": { - "version": "0.25.7", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", - "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", - "dev": true, - "dependencies": { - "sourcemap-codec": "^1.4.4" - } - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, - "dependencies": { - "tmpl": "1.0.5" - } - }, - "node_modules/matched": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/matched/-/matched-5.0.1.tgz", - "integrity": "sha512-E1fhSTPRyhAlNaNvGXAgZQlq1hL0bgYMTk/6bktVlIhzUnX/SZs7296ACdVeNJE8xFNGSuvd9IpI7vSnmcqLvw==", - "dev": true, - "dependencies": { - "glob": "^7.1.6", - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", - "dev": true, - "dependencies": { - "mime-db": "1.51.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minipass": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.3.tgz", - "integrity": "sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==", - "dev": true, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "node_modules/node-fetch": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", - "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-fetch/node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "node_modules/node-fetch/node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "node_modules/node-fetch/node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/node-gyp-build": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", - "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==", - "optional": true, - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", - "dev": true - }, - "node_modules/node-releases": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", - "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", - "dev": true - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nwsapi": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", - "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", - "dev": true - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/open": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/open/-/open-9.1.0.tgz", - "integrity": "sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==", - "dev": true, - "dependencies": { - "default-browser": "^4.0.0", - "define-lazy-prop": "^3.0.0", - "is-inside-container": "^1.0.0", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", - "dev": true, - "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/path-scurry": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", - "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", - "dev": true, - "dependencies": { - "lru-cache": "^9.1.1 || ^10.0.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", - "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", - "dev": true, - "engines": { - "node": "14 || >=16.14" - } - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pirates": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", - "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz", - "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==", - "dev": true, - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dev": true, - "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true - }, - "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "node_modules/regenerator-runtime": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", - "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true - }, - "node_modules/resolve": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", - "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", - "dev": true, - "dependencies": { - "is-core-module": "^2.11.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-cwd/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve.exports": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", - "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", - "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", - "dev": true, - "dependencies": { - "glob": "^10.3.7" - }, - "bin": { - "rimraf": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "10.3.9", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.9.tgz", - "integrity": "sha512-2tU/LKevAQvDVuVJ9pg9Yv9xcbSh+TqHuTaXTNbQwf+0kDl9Fm6bMovi4Nm5c8TVvfxo2LLcqCGtmO9KoJaGWg==", - "dev": true, - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rollup": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.2.0.tgz", - "integrity": "sha512-deaMa9Z+jPVeBD2dKXv+h7EbdKte9++V2potc/ADqvVgEr6DEJ3ia9u0joarjC2lX/ubaCRYz3QVx0TzuVqAJA==", - "dev": true, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.2.0", - "@rollup/rollup-android-arm64": "4.2.0", - "@rollup/rollup-darwin-arm64": "4.2.0", - "@rollup/rollup-darwin-x64": "4.2.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.2.0", - "@rollup/rollup-linux-arm64-gnu": "4.2.0", - "@rollup/rollup-linux-arm64-musl": "4.2.0", - "@rollup/rollup-linux-x64-gnu": "4.2.0", - "@rollup/rollup-linux-x64-musl": "4.2.0", - "@rollup/rollup-win32-arm64-msvc": "4.2.0", - "@rollup/rollup-win32-ia32-msvc": "4.2.0", - "@rollup/rollup-win32-x64-msvc": "4.2.0", - "fsevents": "~2.3.2" - } - }, - "node_modules/rollup-plugin-dts": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-6.1.0.tgz", - "integrity": "sha512-ijSCPICkRMDKDLBK9torss07+8dl9UpY9z1N/zTeA1cIqdzMlpkV3MOOC7zukyvQfDyxa1s3Dl2+DeiP/G6DOw==", - "dev": true, - "dependencies": { - "magic-string": "^0.30.4" - }, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/Swatinem" - }, - "optionalDependencies": { - "@babel/code-frame": "^7.22.13" - }, - "peerDependencies": { - "rollup": "^3.29.4 || ^4", - "typescript": "^4.5 || ^5.0" - } - }, - "node_modules/rollup-plugin-dts/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "node_modules/rollup-plugin-dts/node_modules/magic-string": { - "version": "0.30.4", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.4.tgz", - "integrity": "sha512-Q/TKtsC5BPm0kGqgBIF9oXAs/xEf2vRKiIB4wCRQTJOQIByZ1d+NnUOotvJOvNpi5RNIgVOMC3pOuaP1ZTDlVg==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/rollup-plugin-inject": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rollup-plugin-inject/-/rollup-plugin-inject-3.0.2.tgz", - "integrity": "sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==", - "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject.", - "dev": true, - "dependencies": { - "estree-walker": "^0.6.1", - "magic-string": "^0.25.3", - "rollup-pluginutils": "^2.8.1" - } - }, - "node_modules/rollup-plugin-inject/node_modules/estree-walker": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", - "dev": true - }, - "node_modules/rollup-plugin-node-polyfills": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/rollup-plugin-node-polyfills/-/rollup-plugin-node-polyfills-0.2.1.tgz", - "integrity": "sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==", - "dev": true, - "dependencies": { - "rollup-plugin-inject": "^3.0.0" - } - }, - "node_modules/rollup-pluginutils": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", - "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", - "dev": true, - "dependencies": { - "estree-walker": "^0.6.1" - } - }, - "node_modules/rollup-pluginutils/node_modules/estree-walker": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", - "dev": true - }, - "node_modules/rpc-websockets": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.5.1.tgz", - "integrity": "sha512-kGFkeTsmd37pHPMaHIgN1LVKXMi0JD782v4Ds9ZKtLlwdTKjn+CxM9A9/gLT2LaOuEcEFGL98h1QWQtlOIdW0w==", - "dependencies": { - "@babel/runtime": "^7.17.2", - "eventemitter3": "^4.0.7", - "uuid": "^8.3.2", - "ws": "^8.5.0" - }, - "funding": { - "type": "paypal", - "url": "https://paypal.me/kozjak" - }, - "optionalDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - } - }, - "node_modules/rpc-websockets/node_modules/ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/run-applescript": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz", - "integrity": "sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==", - "dev": true, - "dependencies": { - "execa": "^5.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "node_modules/saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dev": true, - "dependencies": { - "xmlchars": "^2.2.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/smob": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/smob/-/smob-1.4.1.tgz", - "integrity": "sha512-9LK+E7Hv5R9u4g4C3p+jjLstaLe11MDsL21UpYaCNmapvMkYhqCV4A/f/3gyH8QjMyh6l68q9xC85vihY9ahMQ==", - "dev": true - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", - "dev": true - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "node_modules/stack-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dev": true, - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/superstruct": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-0.14.2.tgz", - "integrity": "sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==" - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", - "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true - }, - "node_modules/synckit": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.5.tgz", - "integrity": "sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==", - "dev": true, - "dependencies": { - "@pkgr/utils": "^2.3.1", - "tslib": "^2.5.0" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, - "node_modules/terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dev": true, - "dependencies": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/terser": { - "version": "5.21.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.21.0.tgz", - "integrity": "sha512-WtnFKrxu9kaoXuiZFSGrcAvvBqAdmKx0SFNmVNYdJamMu9yyN3I/QF0FbH4QcqJQ+y1CJnzxGIKH0cSj+FGYRw==", - "dev": true, - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-encoding-utf-8": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz", - "integrity": "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==" - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "node_modules/throat": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", - "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", - "dev": true - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" - }, - "node_modules/titleize": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz", - "integrity": "sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/tough-cookie": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", - "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", - "dev": true, - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "dev": true, - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ts-api-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.1.tgz", - "integrity": "sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==", - "dev": true, - "engines": { - "node": ">=16.13.0" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } - }, - "node_modules/ts-jest": { - "version": "27.1.3", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.3.tgz", - "integrity": "sha512-6Nlura7s6uM9BVUAoqLH7JHyMXjz8gluryjpPXxr3IxZdAXnU6FhjvVLHFtfd1vsE1p8zD1OJfskkc0jhTSnkA==", - "dev": true, - "dependencies": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^27.0.0", - "json5": "2.x", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "7.x", - "yargs-parser": "20.x" - }, - "bin": { - "ts-jest": "cli.js" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "@babel/core": ">=7.0.0-beta.0 <8", - "@types/jest": "^27.0.0", - "babel-jest": ">=27.0.0 <28", - "esbuild": "~0.14.0", - "jest": "^27.0.0", - "typescript": ">=3.8 <5.0" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "@types/jest": { - "optional": true - }, - "babel-jest": { - "optional": true - }, - "esbuild": { - "optional": true - } - } - }, - "node_modules/tslib": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", - "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", - "dev": true - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" - }, - "node_modules/universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/untildify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", - "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dev": true, - "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "node_modules/utf-8-validate": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.8.tgz", - "integrity": "sha512-k4dW/Qja1BYDl2qD4tOMB9PFVha/UJtxTc1cXYOe3WwA/2m0Yn4qB7wLMpJyLJ/7DR0XnTut3HsCSzDT4ZvKgA==", - "hasInstallScript": true, - "optional": true, - "dependencies": { - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">=6.14.2" - } - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/v8-to-istanbul": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", - "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" - }, - "engines": { - "node": ">=10.12.0" - } - }, - "node_modules/v8-to-istanbul/node_modules/source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "dev": true, - "dependencies": { - "browser-process-hrtime": "^1.0.0" - } - }, - "node_modules/w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", - "dev": true, - "dependencies": { - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, - "dependencies": { - "makeerror": "1.0.12" - } - }, - "node_modules/webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "dev": true, - "engines": { - "node": ">=10.4" - } - }, - "node_modules/whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dev": true, - "dependencies": { - "iconv-lite": "0.4.24" - } - }, - "node_modules/whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "dev": true - }, - "node_modules/whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", - "dev": true, - "dependencies": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", - "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/ws": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", - "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "dev": true - }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "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" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - }, - "dependencies": { - "@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true - }, - "@ampproject/remapping": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.0.tgz", - "integrity": "sha512-d5RysTlJ7hmw5Tw4UxgxcY3lkMe92n8sXCcuLPAyIAHK6j8DefDwtGnVVDgOnv+RnEosulDJ9NPKQL27bDId0g==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "^0.3.0" - } - }, - "@babel/code-frame": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", - "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", - "dev": true, - "requires": { - "@babel/highlight": "^7.22.13", - "chalk": "^2.4.2" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/compat-data": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.0.tgz", - "integrity": "sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng==", - "dev": true - }, - "@babel/core": { - "version": "7.17.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.2.tgz", - "integrity": "sha512-R3VH5G42VSDolRHyUO4V2cfag8WHcZyxdq5Z/m8Xyb92lW/Erm/6kM+XtRFGf3Mulre3mveni2NHfEUws8wSvw==", - "dev": true, - "requires": { - "@ampproject/remapping": "^2.0.0", - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.0", - "@babel/helper-compilation-targets": "^7.16.7", - "@babel/helper-module-transforms": "^7.16.7", - "@babel/helpers": "^7.17.2", - "@babel/parser": "^7.17.0", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.0", - "@babel/types": "^7.17.0", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "@babel/generator": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", - "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", - "dev": true, - "requires": { - "@babel/types": "^7.23.0", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", - "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.16.4", - "@babel/helper-validator-option": "^7.16.7", - "browserslist": "^4.17.5", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "dev": true - }, - "@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", - "dev": true, - "requires": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "dev": true, - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-module-imports": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", - "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-module-transforms": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz", - "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-simple-access": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/helper-validator-identifier": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.16.7", - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", - "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", - "dev": true - }, - "@babel/helper-simple-access": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", - "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", - "dev": true, - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-string-parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", - "dev": true - }, - "@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", - "dev": true - }, - "@babel/helper-validator-option": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", - "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", - "dev": true - }, - "@babel/helpers": { - "version": "7.17.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.2.tgz", - "integrity": "sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ==", - "dev": true, - "requires": { - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.0", - "@babel/types": "^7.17.0" - } - }, - "@babel/highlight": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", - "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", - "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", - "dev": true - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-typescript": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz", - "integrity": "sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/runtime": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz", - "integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==", - "requires": { - "regenerator-runtime": "^0.14.0" - } - }, - "@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" - } - }, - "@babel/traverse": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", - "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.23.0", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.0", - "@babel/types": "^7.23.0", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "dependencies": { - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - } - } - }, - "@babel/types": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", - "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", - "dev": true, - "requires": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" - } - }, - "@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "@coral-xyz/borsh": { - "version": "0.29.0", - "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.29.0.tgz", - "integrity": "sha512-s7VFVa3a0oqpkuRloWVPdCK7hMbAMY270geZOGfCnaqexrP5dTIpbEHL33req6IYPPJ0hYa71cdvJ1h6V55/oQ==", - "requires": { - "bn.js": "^5.1.2", - "buffer-layout": "^1.2.0" - } - }, - "@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^3.3.0" - } - }, - "@eslint-community/regexpp": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.2.tgz", - "integrity": "sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==", - "dev": true - }, - "@eslint/eslintrc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - } - }, - "@eslint/js": { - "version": "8.52.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.52.0.tgz", - "integrity": "sha512-mjZVbpaeMZludF2fsWLD0Z9gCref1Tk4i9+wddjRvpUNqqcndPkBD09N/Mapey0b3jaXbLm2kICwFv2E64QinA==", - "dev": true - }, - "@humanwhocodes/config-array": { - "version": "0.11.13", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", - "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^2.0.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - } - }, - "@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true - }, - "@humanwhocodes/object-schema": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", - "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", - "dev": true - }, - "@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true - }, - "ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true - }, - "emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "requires": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - } - }, - "strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "requires": { - "ansi-regex": "^6.0.1" - } - }, - "wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "requires": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - } - } - } - }, - "@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "dependencies": { - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } - } - }, - "@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true - }, - "@jest/console": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", - "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0" - } - }, - "@jest/core": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", - "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", - "dev": true, - "requires": { - "@jest/console": "^27.5.1", - "@jest/reporters": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^27.5.1", - "jest-config": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-resolve-dependencies": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "jest-watcher": "^27.5.1", - "micromatch": "^4.0.4", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "@jest/environment": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", - "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", - "dev": true, - "requires": { - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1" - } - }, - "@jest/fake-timers": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", - "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "@sinonjs/fake-timers": "^8.0.1", - "@types/node": "*", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - } - }, - "@jest/globals": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", - "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/types": "^27.5.1", - "expect": "^27.5.1" - } - }, - "@jest/reporters": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", - "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", - "dev": true, - "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-haste-map": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^8.1.0" - } - }, - "@jest/source-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", - "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", - "dev": true, - "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9", - "source-map": "^0.6.0" - } - }, - "@jest/test-result": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", - "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", - "dev": true, - "requires": { - "@jest/console": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/test-sequencer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", - "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", - "dev": true, - "requires": { - "@jest/test-result": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-runtime": "^27.5.1" - } - }, - "@jest/transform": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", - "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^27.5.1", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-util": "^27.5.1", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - } - }, - "@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - } - }, - "@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true - }, - "@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true - }, - "@jridgewell/source-map": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.3.tgz", - "integrity": "sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, - "@jridgewell/trace-mapping": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", - "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - } - }, - "@noble/curves": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", - "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", - "requires": { - "@noble/hashes": "1.3.2" - } - }, - "@noble/hashes": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", - "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==" - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "optional": true - }, - "@pkgr/utils": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.1.tgz", - "integrity": "sha512-JOqwkgFEyi+OROIyq7l4Jy28h/WwhDnG/cPkXG2Z1iFbubB6jsHW1NDvmyOzTBxHr3yg68YGirmh1JUgMqa+9w==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "fast-glob": "^3.2.12", - "is-glob": "^4.0.3", - "open": "^9.1.0", - "picocolors": "^1.0.0", - "tslib": "^2.5.0" - } - }, - "@rollup/plugin-alias": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.0.1.tgz", - "integrity": "sha512-JObvbWdOHoMy9W7SU0lvGhDtWq9PllP5mjpAy+TUslZG/WzOId9u80Hsqq1vCUn9pFJ0cxpdcnAv+QzU2zFH3Q==", - "dev": true, - "requires": { - "slash": "^4.0.0" - }, - "dependencies": { - "slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", - "dev": true - } - } - }, - "@rollup/plugin-commonjs": { - "version": "25.0.7", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.7.tgz", - "integrity": "sha512-nEvcR+LRjEjsaSsc4x3XZfCCvZIaSMenZu/OiwOKGN2UhQpAYI7ru7czFvyWbErlpoGjnSX3D5Ch5FcMA3kRWQ==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^5.0.1", - "commondir": "^1.0.1", - "estree-walker": "^2.0.2", - "glob": "^8.0.3", - "is-reference": "1.2.1", - "magic-string": "^0.30.3" - }, - "dependencies": { - "@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - } - }, - "magic-string": { - "version": "0.30.5", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", - "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", - "dev": true, - "requires": { - "@jridgewell/sourcemap-codec": "^1.4.15" - } - }, - "minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, - "@rollup/plugin-json": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.0.1.tgz", - "integrity": "sha512-RgVfl5hWMkxN1h/uZj8FVESvPuBJ/uf6ly6GTj0GONnkfoBN5KC0MSz+PN2OLDgYXMhtG0mWpTrkiOjoxAIevw==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^5.0.1" - } - }, - "@rollup/plugin-multi-entry": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-multi-entry/-/plugin-multi-entry-6.0.1.tgz", - "integrity": "sha512-AXm6toPyTSfbYZWghQGbom1Uh7dHXlrGa+HoiYNhQtDUE3Q7LqoUYdVQx9E1579QWS1uOiu+cZRSE4okO7ySgw==", - "dev": true, - "requires": { - "@rollup/plugin-virtual": "^3.0.0", - "matched": "^5.0.1" - } - }, - "@rollup/plugin-node-resolve": { - "version": "15.2.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", - "integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^5.0.1", - "@types/resolve": "1.20.2", - "deepmerge": "^4.2.2", - "is-builtin-module": "^3.2.1", - "is-module": "^1.0.0", - "resolve": "^1.22.1" - } - }, - "@rollup/plugin-terser": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", - "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", - "dev": true, - "requires": { - "serialize-javascript": "^6.0.1", - "smob": "^1.0.0", - "terser": "^5.17.4" - }, - "dependencies": { - "serialize-javascript": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", - "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - } - } - }, - "@rollup/plugin-typescript": { - "version": "11.1.5", - "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.5.tgz", - "integrity": "sha512-rnMHrGBB0IUEv69Q8/JGRD/n4/n6b3nfpufUu26axhUcboUzv/twfZU8fIBbTOphRAe0v8EyxzeDpKXqGHfyDA==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^5.0.1", - "resolve": "^1.22.1" - } - }, - "@rollup/plugin-virtual": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-virtual/-/plugin-virtual-3.0.2.tgz", - "integrity": "sha512-10monEYsBp3scM4/ND4LNH5Rxvh3e/cVeL3jWTgZ2SrQ+BmUoQcopVQvnaMcOnykb1VkxUFuDAN+0FnpTFRy2A==", - "dev": true, - "requires": {} - }, - "@rollup/pluginutils": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.5.tgz", - "integrity": "sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==", - "dev": true, - "requires": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" - } - }, - "@rollup/rollup-android-arm-eabi": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.2.0.tgz", - "integrity": "sha512-8PlggAxGxavr+pkCNeV1TM2wTb2o+cUWDg9M1cm9nR27Dsn287uZtSLYXoQqQcmq+sYfF7lHfd3sWJJinH9GmA==", - "dev": true, - "optional": true - }, - "@rollup/rollup-android-arm64": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.2.0.tgz", - "integrity": "sha512-+71T85hbMFrJI+zKQULNmSYBeIhru55PYoF/u75MyeN2FcxE4HSPw20319b+FcZ4lWx2Nx/Ql9tN+hoaD3GH/A==", - "dev": true, - "optional": true - }, - "@rollup/rollup-darwin-arm64": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.2.0.tgz", - "integrity": "sha512-IIIQLuG43QIElT1JZqUP/zqIdiJl4t9U/boa0GZnQTw9m1X0k3mlBuysbgYXeloLT1RozdL7bgw4lpSaI8GOXw==", - "dev": true, - "optional": true - }, - "@rollup/rollup-darwin-x64": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.2.0.tgz", - "integrity": "sha512-BXcXvnLaea1Xz900omrGJhxHFJfH9jZ0CpJuVsbjjhpniJ6qiLXz3xA8Lekaa4MuhFcJd4f0r+Ky1G4VFbYhWw==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.2.0.tgz", - "integrity": "sha512-f4K3MKw9Y4AKi4ANGnmPIglr+S+8tO858YrGVuqAHXxJdVghBmz9CPU9kDpOnGvT4g4vg5uNyIFpOOFvffXyMA==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-arm64-gnu": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.2.0.tgz", - "integrity": "sha512-bNsTYQBgp4H7w6cT7FZhesxpcUPahsSIy4NgdZjH1ZwEoZHxi4XKglj+CsSEkhsKi+x6toVvMylhjRKhEMYfnA==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-arm64-musl": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.2.0.tgz", - "integrity": "sha512-Jp1NxBJpGLuxRU2ihrQk4IZ+ia5nffobG6sOFUPW5PMYkF0kQtxEbeDuCa69Xif211vUOcxlOnf5IOEIpTEySA==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-x64-gnu": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.2.0.tgz", - "integrity": "sha512-3p3iRtQmv2aXw+vtKNyZMLOQ+LSRsqArXjKAh2Oj9cqwfIRe7OXvdkOzWfZOIp1F/x5KJzVAxGxnniF4cMbnsQ==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-x64-musl": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.2.0.tgz", - "integrity": "sha512-atih7IF/reUZe4LBLC5Izd44hth2tfDIG8LaPp4/cQXdHh9jabcZEvIeRPrpDq0i/Uu487Qu5gl5KwyAnWajnw==", - "dev": true, - "optional": true - }, - "@rollup/rollup-win32-arm64-msvc": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.2.0.tgz", - "integrity": "sha512-vYxF3tKJeUE4ceYzpNe2p84RXk/fGK30I8frpRfv/MyPStej/mRlojztkN7Jtd1014HHVeq/tYaMBz/3IxkxZw==", - "dev": true, - "optional": true - }, - "@rollup/rollup-win32-ia32-msvc": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.2.0.tgz", - "integrity": "sha512-1LZJ6zpl93SaPQvas618bMFarVwufWTaczH4ESAbFcwiC4OtznA6Ym+hFPyIGaJaGEB8uMWWac0uXGPXOg5FGA==", - "dev": true, - "optional": true - }, - "@rollup/rollup-win32-x64-msvc": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.2.0.tgz", - "integrity": "sha512-dgQfFdHCNg08nM5zBmqxqc9vrm0DVzhWotpavbPa0j4//MAOKZEB75yGAfzQE9fUJ+4pvM1239Y4IhL8f6sSog==", - "dev": true, - "optional": true - }, - "@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", - "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, - "@solana/buffer-layout": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz", - "integrity": "sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==", - "requires": { - "buffer": "~6.0.3" - } - }, - "@solana/buffer-layout-utils": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@solana/buffer-layout-utils/-/buffer-layout-utils-0.2.0.tgz", - "integrity": "sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==", - "requires": { - "@solana/buffer-layout": "^4.0.0", - "@solana/web3.js": "^1.32.0", - "bigint-buffer": "^1.1.5", - "bignumber.js": "^9.0.1" - } - }, - "@solana/spl-token": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.3.8.tgz", - "integrity": "sha512-ogwGDcunP9Lkj+9CODOWMiVJEdRtqHAtX2rWF62KxnnSWtMZtV9rDhTrZFshiyJmxDnRL/1nKE1yJHg4jjs3gg==", - "requires": { - "@solana/buffer-layout": "^4.0.0", - "@solana/buffer-layout-utils": "^0.2.0", - "buffer": "^6.0.3" - } - }, - "@solana/web3.js": { - "version": "1.87.3", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.87.3.tgz", - "integrity": "sha512-WGLzTZpi00vP443qGK3gL+LZXQJwaWkh6bzNXYpMTCAH2Z102y3YbPWOoQzJUeRSZWSXKh7MFkA3vDMFlMvGZQ==", - "requires": { - "@babel/runtime": "^7.23.2", - "@noble/curves": "^1.2.0", - "@noble/hashes": "^1.3.1", - "@solana/buffer-layout": "^4.0.0", - "agentkeepalive": "^4.3.0", - "bigint-buffer": "^1.1.5", - "bn.js": "^5.2.1", - "borsh": "^0.7.0", - "bs58": "^4.0.1", - "buffer": "6.0.3", - "fast-stable-stringify": "^1.0.0", - "jayson": "^4.1.0", - "node-fetch": "^2.6.12", - "rpc-websockets": "^7.5.1", - "superstruct": "^0.14.2" - } - }, - "@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "dev": true - }, - "@types/babel__core": { - "version": "7.1.18", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.18.tgz", - "integrity": "sha512-S7unDjm/C7z2A2R9NzfKCK1I+BAALDtxEmsJBwlB3EzNfb929ykjL++1CK9LO++EIp2fQrC8O+BwjKvz6UeDyQ==", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "@types/babel__generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", - "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@types/babel__traverse": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", - "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", - "dev": true, - "requires": { - "@babel/types": "^7.3.0" - } - }, - "@types/bn.js": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.4.tgz", - "integrity": "sha512-ZtBd9L8hVtoBpPMSWfbwjC4dhQtJdlPS+e1A0Rydb7vg7bDcUwiRklPx24sMYtXcmAMST/k0Wze7JLbNU/5SkA==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", - "requires": { - "@types/node": "*" - } - }, - "@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", - "dev": true - }, - "@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", - "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", - "dev": true - }, - "@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "*" - } - }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "@types/jest": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.0.tgz", - "integrity": "sha512-gHl8XuC1RZ8H2j5sHv/JqsaxXkDDM9iDOgu0Wp8sjs4u/snb2PVehyWXJPr+ORA0RPpgw231mnutWI1+0hgjIQ==", - "dev": true, - "requires": { - "jest-diff": "^27.0.0", - "pretty-format": "^27.0.0" - } - }, - "@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true - }, - "@types/node": { - "version": "20.8.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.10.tgz", - "integrity": "sha512-TlgT8JntpcbmKUFzjhsyhGfP2fsiz1Mv56im6enJ905xG1DAYesxJaeSbGqQmAw8OWPdhyJGhGSQGKRNJ45u9w==", - "requires": { - "undici-types": "~5.26.4" - } - }, - "@types/node-fetch": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.9.tgz", - "integrity": "sha512-bQVlnMLFJ2d35DkPNjEPmd9ueO/rh5EiaZt2bhqiSarPjZIuIV6bPQVqcrEyvNo+AfTrRGVazle1tl597w3gfA==", - "dev": true, - "requires": { - "@types/node": "*", - "form-data": "^4.0.0" - }, - "dependencies": { - "form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - } - } - }, - "@types/prettier": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.4.tgz", - "integrity": "sha512-ReVR2rLTV1kvtlWFyuot+d1pkpG2Fw/XKE3PDAdj57rbM97ttSp9JZ2UsP+2EHTylra9cUf6JA7tGwW1INzUrA==", - "dev": true - }, - "@types/resolve": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", - "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", - "dev": true - }, - "@types/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==", - "dev": true - }, - "@types/stack-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", - "dev": true - }, - "@types/ws": { - "version": "7.4.7", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", - "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", - "requires": { - "@types/node": "*" - } - }, - "@types/yargs": { - "version": "16.0.4", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", - "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "@types/yargs-parser": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", - "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", - "dev": true - }, - "@typescript-eslint/eslint-plugin": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.10.0.tgz", - "integrity": "sha512-uoLj4g2OTL8rfUQVx2AFO1hp/zja1wABJq77P6IclQs6I/m9GLrm7jCdgzZkvWdDCQf1uEvoa8s8CupsgWQgVg==", - "dev": true, - "requires": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.10.0", - "@typescript-eslint/type-utils": "6.10.0", - "@typescript-eslint/utils": "6.10.0", - "@typescript-eslint/visitor-keys": "6.10.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.4", - "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.10.0.tgz", - "integrity": "sha512-TN/plV7dzqqC2iPNf1KrxozDgZs53Gfgg5ZHyw8erd6jd5Ta/JIEcdCheXFt9b1NYb93a1wmIIVW/2gLkombDg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.10.0", - "@typescript-eslint/visitor-keys": "6.10.0" - } - }, - "@typescript-eslint/types": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.10.0.tgz", - "integrity": "sha512-36Fq1PWh9dusgo3vH7qmQAj5/AZqARky1Wi6WpINxB6SkQdY5vQoT2/7rW7uBIsPDcvvGCLi4r10p0OJ7ITAeg==", - "dev": true - }, - "@typescript-eslint/visitor-keys": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.10.0.tgz", - "integrity": "sha512-xMGluxQIEtOM7bqFCo+rCMh5fqI+ZxV5RUUOa29iVPz1OgCZrtc7rFnz5cLUazlkPKYqX+75iuDq7m0HQ48nCg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.10.0", - "eslint-visitor-keys": "^3.4.1" - } - } - } - }, - "@typescript-eslint/parser": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.10.0.tgz", - "integrity": "sha512-+sZwIj+s+io9ozSxIWbNB5873OSdfeBEH/FR0re14WLI6BaKuSOnnwCJ2foUiu8uXf4dRp1UqHP0vrZ1zXGrog==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "6.10.0", - "@typescript-eslint/types": "6.10.0", - "@typescript-eslint/typescript-estree": "6.10.0", - "@typescript-eslint/visitor-keys": "6.10.0", - "debug": "^4.3.4" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.10.0.tgz", - "integrity": "sha512-TN/plV7dzqqC2iPNf1KrxozDgZs53Gfgg5ZHyw8erd6jd5Ta/JIEcdCheXFt9b1NYb93a1wmIIVW/2gLkombDg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.10.0", - "@typescript-eslint/visitor-keys": "6.10.0" - } - }, - "@typescript-eslint/types": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.10.0.tgz", - "integrity": "sha512-36Fq1PWh9dusgo3vH7qmQAj5/AZqARky1Wi6WpINxB6SkQdY5vQoT2/7rW7uBIsPDcvvGCLi4r10p0OJ7ITAeg==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.10.0.tgz", - "integrity": "sha512-ek0Eyuy6P15LJVeghbWhSrBCj/vJpPXXR+EpaRZqou7achUWL8IdYnMSC5WHAeTWswYQuP2hAZgij/bC9fanBg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.10.0", - "@typescript-eslint/visitor-keys": "6.10.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.10.0.tgz", - "integrity": "sha512-xMGluxQIEtOM7bqFCo+rCMh5fqI+ZxV5RUUOa29iVPz1OgCZrtc7rFnz5cLUazlkPKYqX+75iuDq7m0HQ48nCg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.10.0", - "eslint-visitor-keys": "^3.4.1" - } - } - } - }, - "@typescript-eslint/scope-manager": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.1.tgz", - "integrity": "sha512-38IxvKB6NAne3g/+MyXMs2Cda/Sz+CEpmm+KLGEM8hx/CvnSRuw51i8ukfwB/B/sESdeTGet1NH1Wj7I0YXswg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.9.1", - "@typescript-eslint/visitor-keys": "6.9.1" - } - }, - "@typescript-eslint/type-utils": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.10.0.tgz", - "integrity": "sha512-wYpPs3hgTFblMYwbYWPT3eZtaDOjbLyIYuqpwuLBBqhLiuvJ+9sEp2gNRJEtR5N/c9G1uTtQQL5AhV0fEPJYcg==", - "dev": true, - "requires": { - "@typescript-eslint/typescript-estree": "6.10.0", - "@typescript-eslint/utils": "6.10.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" - }, - "dependencies": { - "@typescript-eslint/types": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.10.0.tgz", - "integrity": "sha512-36Fq1PWh9dusgo3vH7qmQAj5/AZqARky1Wi6WpINxB6SkQdY5vQoT2/7rW7uBIsPDcvvGCLi4r10p0OJ7ITAeg==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.10.0.tgz", - "integrity": "sha512-ek0Eyuy6P15LJVeghbWhSrBCj/vJpPXXR+EpaRZqou7achUWL8IdYnMSC5WHAeTWswYQuP2hAZgij/bC9fanBg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.10.0", - "@typescript-eslint/visitor-keys": "6.10.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.10.0.tgz", - "integrity": "sha512-xMGluxQIEtOM7bqFCo+rCMh5fqI+ZxV5RUUOa29iVPz1OgCZrtc7rFnz5cLUazlkPKYqX+75iuDq7m0HQ48nCg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.10.0", - "eslint-visitor-keys": "^3.4.1" - } - } - } - }, - "@typescript-eslint/types": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.1.tgz", - "integrity": "sha512-BUGslGOb14zUHOUmDB2FfT6SI1CcZEJYfF3qFwBeUrU6srJfzANonwRYHDpLBuzbq3HaoF2XL2hcr01c8f8OaQ==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.1.tgz", - "integrity": "sha512-U+mUylTHfcqeO7mLWVQ5W/tMLXqVpRv61wm9ZtfE5egz7gtnmqVIw9ryh0mgIlkKk9rZLY3UHygsBSdB9/ftyw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.9.1", - "@typescript-eslint/visitor-keys": "6.9.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/utils": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.10.0.tgz", - "integrity": "sha512-v+pJ1/RcVyRc0o4wAGux9x42RHmAjIGzPRo538Z8M1tVx6HOnoQBCX/NoadHQlZeC+QO2yr4nNSFWOoraZCAyg==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.10.0", - "@typescript-eslint/types": "6.10.0", - "@typescript-eslint/typescript-estree": "6.10.0", - "semver": "^7.5.4" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.10.0.tgz", - "integrity": "sha512-TN/plV7dzqqC2iPNf1KrxozDgZs53Gfgg5ZHyw8erd6jd5Ta/JIEcdCheXFt9b1NYb93a1wmIIVW/2gLkombDg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.10.0", - "@typescript-eslint/visitor-keys": "6.10.0" - } - }, - "@typescript-eslint/types": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.10.0.tgz", - "integrity": "sha512-36Fq1PWh9dusgo3vH7qmQAj5/AZqARky1Wi6WpINxB6SkQdY5vQoT2/7rW7uBIsPDcvvGCLi4r10p0OJ7ITAeg==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.10.0.tgz", - "integrity": "sha512-ek0Eyuy6P15LJVeghbWhSrBCj/vJpPXXR+EpaRZqou7achUWL8IdYnMSC5WHAeTWswYQuP2hAZgij/bC9fanBg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.10.0", - "@typescript-eslint/visitor-keys": "6.10.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.10.0.tgz", - "integrity": "sha512-xMGluxQIEtOM7bqFCo+rCMh5fqI+ZxV5RUUOa29iVPz1OgCZrtc7rFnz5cLUazlkPKYqX+75iuDq7m0HQ48nCg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.10.0", - "eslint-visitor-keys": "^3.4.1" - } - } - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.1.tgz", - "integrity": "sha512-MUaPUe/QRLEffARsmNfmpghuQkW436DvESW+h+M52w0coICHRfD6Np9/K6PdACwnrq1HmuLl+cSPZaJmeVPkSw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.9.1", - "eslint-visitor-keys": "^3.4.1" - } - }, - "@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, - "abab": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", - "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", - "dev": true - }, - "acorn": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz", - "integrity": "sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==", - "dev": true - }, - "acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "dev": true, - "requires": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - }, - "dependencies": { - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - } - } - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} - }, - "acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "dev": true - }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "requires": { - "debug": "4" - } - }, - "agentkeepalive": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.3.0.tgz", - "integrity": "sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg==", - "requires": { - "debug": "^4.1.0", - "depd": "^2.0.0", - "humanize-ms": "^1.2.1" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "requires": { - "type-fest": "^0.21.3" - }, - "dependencies": { - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true - } - } - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "babel-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", - "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", - "dev": true, - "requires": { - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - } - }, - "babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - } - }, - "babel-plugin-jest-hoist": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", - "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", - "dev": true, - "requires": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" - } - }, - "babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dev": true, - "requires": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - } - }, - "babel-preset-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", - "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", - "dev": true, - "requires": { - "babel-plugin-jest-hoist": "^27.5.1", - "babel-preset-current-node-syntax": "^1.0.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "base-x": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", - "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "big-integer": { - "version": "1.6.51", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", - "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", - "dev": true - }, - "bigint-buffer": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/bigint-buffer/-/bigint-buffer-1.1.5.tgz", - "integrity": "sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==", - "requires": { - "bindings": "^1.3.0" - } - }, - "bignumber.js": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.1.tgz", - "integrity": "sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig==" - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" - }, - "borsh": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/borsh/-/borsh-0.7.0.tgz", - "integrity": "sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==", - "requires": { - "bn.js": "^5.2.0", - "bs58": "^4.0.0", - "text-encoding-utf-8": "^1.0.2" - } - }, - "bplist-parser": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz", - "integrity": "sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==", - "dev": true, - "requires": { - "big-integer": "^1.6.44" - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true - }, - "browserslist": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", - "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001286", - "electron-to-chromium": "^1.4.17", - "escalade": "^3.1.1", - "node-releases": "^2.0.1", - "picocolors": "^1.0.0" - } - }, - "bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "dev": true, - "requires": { - "fast-json-stable-stringify": "2.x" - } - }, - "bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", - "requires": { - "base-x": "^3.0.2" - } - }, - "bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "requires": { - "node-int64": "^0.4.0" - } - }, - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "buffer-layout": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/buffer-layout/-/buffer-layout-1.2.2.tgz", - "integrity": "sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==" - }, - "bufferutil": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.6.tgz", - "integrity": "sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw==", - "optional": true, - "requires": { - "node-gyp-build": "^4.3.0" - } - }, - "builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", - "dev": true - }, - "bundle-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", - "integrity": "sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==", - "dev": true, - "requires": { - "run-applescript": "^5.0.0" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caniuse-lite": { - "version": "1.0.30001311", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001311.tgz", - "integrity": "sha512-mleTFtFKfykEeW34EyfhGIFjGCqzhh38Y0LhdQ9aWF+HorZTtdgKV/1hEE0NlFkG2ubvisPV6l400tlbPys98A==", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true - }, - "ci-info": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", - "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", - "dev": true - }, - "cjs-module-lexer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", - "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", - "dev": true - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true - }, - "collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", - "dev": true - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } - } - }, - "cross-env": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", - "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.1" - } - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", - "dev": true - }, - "cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dev": true, - "requires": { - "cssom": "~0.3.6" - }, - "dependencies": { - "cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true - } - } - }, - "data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dev": true, - "requires": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - } - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "requires": { - "ms": "2.1.2" - } - }, - "decimal.js": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", - "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", - "dev": true - }, - "dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", - "dev": true - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true - }, - "default-browser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz", - "integrity": "sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==", - "dev": true, - "requires": { - "bundle-name": "^3.0.0", - "default-browser-id": "^3.0.0", - "execa": "^7.1.1", - "titleize": "^3.0.0" - }, - "dependencies": { - "execa": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-7.1.1.tgz", - "integrity": "sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.1", - "human-signals": "^4.3.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^3.0.7", - "strip-final-newline": "^3.0.0" - } - }, - "human-signals": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", - "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", - "dev": true - }, - "is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true - }, - "mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true - }, - "npm-run-path": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", - "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", - "dev": true, - "requires": { - "path-key": "^4.0.0" - } - }, - "onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "requires": { - "mimic-fn": "^4.0.0" - } - }, - "path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true - }, - "strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true - } - } - }, - "default-browser-id": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz", - "integrity": "sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==", - "dev": true, - "requires": { - "bplist-parser": "^0.2.0", - "untildify": "^4.0.0" - } - }, - "define-lazy-prop": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", - "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", - "dev": true - }, - "delay": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", - "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==" - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" - }, - "detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true - }, - "diff-sequences": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", - "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", - "dev": true - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", - "dev": true, - "requires": { - "webidl-conversions": "^5.0.0" - }, - "dependencies": { - "webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "dev": true - } - } - }, - "eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true - }, - "electron-to-chromium": { - "version": "1.4.68", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.68.tgz", - "integrity": "sha512-cId+QwWrV8R1UawO6b9BR1hnkJ4EJPCPAr4h315vliHUtVUJDk39Sg1PMNnaWKfj5x+93ssjeJ9LKL6r8LaMiA==", - "dev": true - }, - "emittery": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", - "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "escodegen": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", - "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", - "dev": true, - "requires": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" - }, - "dependencies": { - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - } - } - }, - "eslint": { - "version": "8.52.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.52.0.tgz", - "integrity": "sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.52.0", - "@humanwhocodes/config-array": "^0.11.13", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "dependencies": { - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - } - } - }, - "eslint-config-prettier": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz", - "integrity": "sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==", - "dev": true, - "requires": {} - }, - "eslint-plugin-prettier": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.1.tgz", - "integrity": "sha512-m3u5RnR56asrwV/lDC4GHorlW75DsFfmUcjfCYylTUs85dBRnB7VM6xG8eCMJdeDRnppzmxZVf1GEPJvl1JmNg==", - "dev": true, - "requires": { - "prettier-linter-helpers": "^1.0.0", - "synckit": "^0.8.5" - } - }, - "eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true - }, - "espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "requires": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, - "estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" - }, - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true - }, - "expect": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", - "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1" - } - }, - "eyes": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", - "integrity": "sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==" - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", - "dev": true - }, - "fast-glob": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.0.tgz", - "integrity": "sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - } - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "fast-stable-stringify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz", - "integrity": "sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==" - }, - "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", - "dev": true, - "requires": { - "bser": "2.1.1" - } - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "dependencies": { - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "flatted": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", - "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", - "dev": true - }, - "foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "dependencies": { - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true - } - } - }, - "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true - }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "globals": { - "version": "13.21.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", - "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - } - }, - "graceful-fs": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", - "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", - "dev": true - }, - "graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "dev": true, - "requires": { - "whatwg-encoding": "^1.0.5" - } - }, - "html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dev": true, - "requires": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - } - }, - "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true - }, - "humanize-ms": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", - "requires": { - "ms": "^2.0.0" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, - "ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "dev": true, - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-builtin-module": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", - "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", - "dev": true, - "requires": { - "builtin-modules": "^3.3.0" - } - }, - "is-core-module": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.0.tgz", - "integrity": "sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-docker": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", - "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-inside-container": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", - "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", - "dev": true, - "requires": { - "is-docker": "^3.0.0" - } - }, - "is-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", - "dev": true - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true - }, - "is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true - }, - "is-reference": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", - "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", - "dev": true, - "requires": { - "@types/estree": "*" - } - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "requires": { - "is-docker": "^2.0.0" - }, - "dependencies": { - "is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true - } - } - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isomorphic-ws": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", - "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", - "requires": {} - }, - "istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", - "dev": true - }, - "istanbul-lib-instrument": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", - "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", - "dev": true, - "requires": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - } - }, - "istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - } - }, - "istanbul-reports": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz", - "integrity": "sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "jackspeak": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.5.tgz", - "integrity": "sha512-Ratx+B8WeXLAtRJn26hrhY8S1+Jz6pxPMrkrdkgb/NstTNiqMhX0/oFVu5wX+g5n6JlEu2LPsDJmY8nRP4+alw==", - "dev": true, - "requires": { - "@isaacs/cliui": "^8.0.2", - "@pkgjs/parseargs": "^0.11.0" - } - }, - "jayson": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/jayson/-/jayson-4.1.0.tgz", - "integrity": "sha512-R6JlbyLN53Mjku329XoRT2zJAE6ZgOQ8f91ucYdMCD4nkGCF9kZSrcGXpHIU4jeKj58zUZke2p+cdQchU7Ly7A==", - "requires": { - "@types/connect": "^3.4.33", - "@types/node": "^12.12.54", - "@types/ws": "^7.4.4", - "commander": "^2.20.3", - "delay": "^5.0.0", - "es6-promisify": "^5.0.0", - "eyes": "^0.1.8", - "isomorphic-ws": "^4.0.1", - "json-stringify-safe": "^5.0.1", - "JSONStream": "^1.3.5", - "uuid": "^8.3.2", - "ws": "^7.4.5" - }, - "dependencies": { - "@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==" - } - } - }, - "jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", - "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", - "dev": true, - "requires": { - "@jest/core": "^27.5.1", - "import-local": "^3.0.2", - "jest-cli": "^27.5.1" - } - }, - "jest-changed-files": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", - "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "execa": "^5.0.0", - "throat": "^6.0.1" - } - }, - "jest-circus": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", - "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" - } - }, - "jest-cli": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", - "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", - "dev": true, - "requires": { - "@jest/core": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "import-local": "^3.0.2", - "jest-config": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "prompts": "^2.0.1", - "yargs": "^16.2.0" - } - }, - "jest-config": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", - "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", - "dev": true, - "requires": { - "@babel/core": "^7.8.0", - "@jest/test-sequencer": "^27.5.1", - "@jest/types": "^27.5.1", - "babel-jest": "^27.5.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.9", - "jest-circus": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-jasmine2": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - } - }, - "jest-diff": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", - "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - } - }, - "jest-docblock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", - "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", - "dev": true, - "requires": { - "detect-newline": "^3.0.0" - } - }, - "jest-each": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", - "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1" - } - }, - "jest-environment-jsdom": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", - "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1", - "jsdom": "^16.6.0" - } - }, - "jest-environment-node": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", - "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - } - }, - "jest-get-type": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", - "dev": true - }, - "jest-haste-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", - "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.3.2", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^27.5.1", - "jest-serializer": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "micromatch": "^4.0.4", - "walker": "^1.0.7" - } - }, - "jest-jasmine2": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", - "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "throat": "^6.0.1" - } - }, - "jest-leak-detector": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", - "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", - "dev": true, - "requires": { - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - } - }, - "jest-matcher-utils": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", - "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - } - }, - "jest-message-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", - "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.5.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-mock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", - "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "@types/node": "*" - } - }, - "jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true, - "requires": {} - }, - "jest-regex-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", - "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", - "dev": true - }, - "jest-resolve": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", - "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", - "slash": "^3.0.0" - } - }, - "jest-resolve-dependencies": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", - "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-snapshot": "^27.5.1" - } - }, - "jest-runner": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", - "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", - "dev": true, - "requires": { - "@jest/console": "^27.5.1", - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-leak-detector": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "source-map-support": "^0.5.6", - "throat": "^6.0.1" - } - }, - "jest-runtime": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", - "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/globals": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "execa": "^5.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - } - }, - "jest-serializer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", - "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", - "dev": true, - "requires": { - "@types/node": "*", - "graceful-fs": "^4.2.9" - } - }, - "jest-snapshot": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", - "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", - "dev": true, - "requires": { - "@babel/core": "^7.7.2", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.0.0", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "natural-compare": "^1.4.0", - "pretty-format": "^27.5.1", - "semver": "^7.3.2" - } - }, - "jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - }, - "jest-validate": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", - "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "leven": "^3.1.0", - "pretty-format": "^27.5.1" - }, - "dependencies": { - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - } - } - }, - "jest-watcher": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", - "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", - "dev": true, - "requires": { - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^27.5.1", - "string-length": "^4.0.1" - } - }, - "jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dev": true, - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "dependencies": { - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", - "dev": true, - "requires": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" - } - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" - }, - "json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true - }, - "jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==" - }, - "JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "requires": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - } - }, - "kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true - }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", - "dev": true - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "magic-string": { - "version": "0.25.7", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", - "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", - "dev": true, - "requires": { - "sourcemap-codec": "^1.4.4" - } - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, - "requires": { - "tmpl": "1.0.5" - } - }, - "matched": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/matched/-/matched-5.0.1.tgz", - "integrity": "sha512-E1fhSTPRyhAlNaNvGXAgZQlq1hL0bgYMTk/6bktVlIhzUnX/SZs7296ACdVeNJE8xFNGSuvd9IpI7vSnmcqLvw==", - "dev": true, - "requires": { - "glob": "^7.1.6", - "picomatch": "^2.2.1" - } - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", - "dev": true - }, - "mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", - "dev": true, - "requires": { - "mime-db": "1.51.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minipass": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.3.tgz", - "integrity": "sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "node-fetch": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", - "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==", - "requires": { - "whatwg-url": "^5.0.0" - }, - "dependencies": { - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - } - } - }, - "node-gyp-build": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", - "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==", - "optional": true - }, - "node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", - "dev": true - }, - "node-releases": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", - "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", - "dev": true - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "requires": { - "path-key": "^3.0.0" - } - }, - "nwsapi": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", - "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "open": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/open/-/open-9.1.0.tgz", - "integrity": "sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==", - "dev": true, - "requires": { - "default-browser": "^4.0.0", - "define-lazy-prop": "^3.0.0", - "is-inside-container": "^1.0.0", - "is-wsl": "^2.2.0" - } - }, - "optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", - "dev": true, - "requires": { - "@aashutoshrathi/word-wrap": "^1.2.3", - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "path-scurry": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", - "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", - "dev": true, - "requires": { - "lru-cache": "^9.1.1 || ^10.0.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", - "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", - "dev": true - } - } - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - }, - "pirates": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", - "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", - "dev": true - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "prettier": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz", - "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==", - "dev": true - }, - "prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dev": true, - "requires": { - "fast-diff": "^1.1.2" - } - }, - "pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - } - } - }, - "prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "requires": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - } - }, - "psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "regenerator-runtime": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", - "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true - }, - "resolve": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", - "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", - "dev": true, - "requires": { - "is-core-module": "^2.11.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "requires": { - "resolve-from": "^5.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "resolve.exports": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", - "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", - "dev": true - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rimraf": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", - "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", - "dev": true, - "requires": { - "glob": "^10.3.7" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "glob": { - "version": "10.3.9", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.9.tgz", - "integrity": "sha512-2tU/LKevAQvDVuVJ9pg9Yv9xcbSh+TqHuTaXTNbQwf+0kDl9Fm6bMovi4Nm5c8TVvfxo2LLcqCGtmO9KoJaGWg==", - "dev": true, - "requires": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" - } - }, - "minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, - "rollup": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.2.0.tgz", - "integrity": "sha512-deaMa9Z+jPVeBD2dKXv+h7EbdKte9++V2potc/ADqvVgEr6DEJ3ia9u0joarjC2lX/ubaCRYz3QVx0TzuVqAJA==", - "dev": true, - "requires": { - "@rollup/rollup-android-arm-eabi": "4.2.0", - "@rollup/rollup-android-arm64": "4.2.0", - "@rollup/rollup-darwin-arm64": "4.2.0", - "@rollup/rollup-darwin-x64": "4.2.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.2.0", - "@rollup/rollup-linux-arm64-gnu": "4.2.0", - "@rollup/rollup-linux-arm64-musl": "4.2.0", - "@rollup/rollup-linux-x64-gnu": "4.2.0", - "@rollup/rollup-linux-x64-musl": "4.2.0", - "@rollup/rollup-win32-arm64-msvc": "4.2.0", - "@rollup/rollup-win32-ia32-msvc": "4.2.0", - "@rollup/rollup-win32-x64-msvc": "4.2.0", - "fsevents": "~2.3.2" - } - }, - "rollup-plugin-dts": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-6.1.0.tgz", - "integrity": "sha512-ijSCPICkRMDKDLBK9torss07+8dl9UpY9z1N/zTeA1cIqdzMlpkV3MOOC7zukyvQfDyxa1s3Dl2+DeiP/G6DOw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.22.13", - "magic-string": "^0.30.4" - }, - "dependencies": { - "@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "magic-string": { - "version": "0.30.4", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.4.tgz", - "integrity": "sha512-Q/TKtsC5BPm0kGqgBIF9oXAs/xEf2vRKiIB4wCRQTJOQIByZ1d+NnUOotvJOvNpi5RNIgVOMC3pOuaP1ZTDlVg==", - "dev": true, - "requires": { - "@jridgewell/sourcemap-codec": "^1.4.15" - } - } - } - }, - "rollup-plugin-inject": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rollup-plugin-inject/-/rollup-plugin-inject-3.0.2.tgz", - "integrity": "sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==", - "dev": true, - "requires": { - "estree-walker": "^0.6.1", - "magic-string": "^0.25.3", - "rollup-pluginutils": "^2.8.1" - }, - "dependencies": { - "estree-walker": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", - "dev": true - } - } - }, - "rollup-plugin-node-polyfills": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/rollup-plugin-node-polyfills/-/rollup-plugin-node-polyfills-0.2.1.tgz", - "integrity": "sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==", - "dev": true, - "requires": { - "rollup-plugin-inject": "^3.0.0" - } - }, - "rollup-pluginutils": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", - "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", - "dev": true, - "requires": { - "estree-walker": "^0.6.1" - }, - "dependencies": { - "estree-walker": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", - "dev": true - } - } - }, - "rpc-websockets": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.5.1.tgz", - "integrity": "sha512-kGFkeTsmd37pHPMaHIgN1LVKXMi0JD782v4Ds9ZKtLlwdTKjn+CxM9A9/gLT2LaOuEcEFGL98h1QWQtlOIdW0w==", - "requires": { - "@babel/runtime": "^7.17.2", - "bufferutil": "^4.0.1", - "eventemitter3": "^4.0.7", - "utf-8-validate": "^5.0.2", - "uuid": "^8.3.2", - "ws": "^8.5.0" - }, - "dependencies": { - "ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", - "requires": {} - } - } - }, - "run-applescript": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz", - "integrity": "sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==", - "dev": true, - "requires": { - "execa": "^5.0.0" - } - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dev": true, - "requires": { - "xmlchars": "^2.2.0" - } - }, - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "smob": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/smob/-/smob-1.4.1.tgz", - "integrity": "sha512-9LK+E7Hv5R9u4g4C3p+jjLstaLe11MDsL21UpYaCNmapvMkYhqCV4A/f/3gyH8QjMyh6l68q9xC85vihY9ahMQ==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", - "dev": true - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "stack-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - } - } - }, - "string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dev": true, - "requires": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "string-width-cjs": { - "version": "npm:string-width@4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-ansi-cjs": { - "version": "npm:strip-ansi@6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "superstruct": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-0.14.2.tgz", - "integrity": "sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "supports-hyperlinks": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", - "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", - "dev": true, - "requires": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true - }, - "symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true - }, - "synckit": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.5.tgz", - "integrity": "sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==", - "dev": true, - "requires": { - "@pkgr/utils": "^2.3.1", - "tslib": "^2.5.0" - } - }, - "terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - } - }, - "terser": { - "version": "5.21.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.21.0.tgz", - "integrity": "sha512-WtnFKrxu9kaoXuiZFSGrcAvvBqAdmKx0SFNmVNYdJamMu9yyN3I/QF0FbH4QcqJQ+y1CJnzxGIKH0cSj+FGYRw==", - "dev": true, - "requires": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - } - }, - "test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "requires": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - } - }, - "text-encoding-utf-8": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz", - "integrity": "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==" - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "throat": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", - "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" - }, - "titleize": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz", - "integrity": "sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==", - "dev": true - }, - "tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "tough-cookie": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", - "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", - "dev": true, - "requires": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" - } - }, - "tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "dev": true, - "requires": { - "punycode": "^2.1.1" - } - }, - "ts-api-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.1.tgz", - "integrity": "sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==", - "dev": true, - "requires": {} - }, - "ts-jest": { - "version": "27.1.3", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.3.tgz", - "integrity": "sha512-6Nlura7s6uM9BVUAoqLH7JHyMXjz8gluryjpPXxr3IxZdAXnU6FhjvVLHFtfd1vsE1p8zD1OJfskkc0jhTSnkA==", - "dev": true, - "requires": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^27.0.0", - "json5": "2.x", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "7.x", - "yargs-parser": "20.x" - } - }, - "tslib": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", - "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", - "dev": true - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "dev": true - }, - "undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" - }, - "universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "dev": true - }, - "untildify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", - "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", - "dev": true - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "utf-8-validate": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.8.tgz", - "integrity": "sha512-k4dW/Qja1BYDl2qD4tOMB9PFVha/UJtxTc1cXYOe3WwA/2m0Yn4qB7wLMpJyLJ/7DR0XnTut3HsCSzDT4ZvKgA==", - "optional": true, - "requires": { - "node-gyp-build": "^4.3.0" - } - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" - }, - "v8-to-istanbul": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", - "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" - }, - "dependencies": { - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true - } - } - }, - "w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "dev": true, - "requires": { - "browser-process-hrtime": "^1.0.0" - } - }, - "w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", - "dev": true, - "requires": { - "xml-name-validator": "^3.0.0" - } - }, - "walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, - "requires": { - "makeerror": "1.0.12" - } - }, - "webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "dev": true - }, - "whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dev": true, - "requires": { - "iconv-lite": "0.4.24" - } - }, - "whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "dev": true - }, - "whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", - "dev": true, - "requires": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "word-wrap": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", - "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", - "dev": true - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "wrap-ansi-cjs": { - "version": "npm:wrap-ansi@7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "ws": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", - "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==", - "requires": {} - }, - "xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "dev": true - }, - "xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "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-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true - } - } -} diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 86391ce3..f95433ac 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -46,10 +46,11 @@ "dependencies": { "@coral-xyz/borsh": "^0.29.0", "@solana/buffer-layout": "^4.0.1", - "@solana/spl-token": "^0.3.7", + "@solana/spl-token": "workspace:*", "@solana/web3.js": "^1.76.0", "bn.js": "^5.2.0", - "buffer": "^6.0.3" + "buffer": "^6.0.3", + "superstruct": "^0.14.2" }, "devDependencies": { "@rollup/plugin-alias": "^5.0.0", @@ -74,7 +75,6 @@ "rimraf": "^5.0.0", "rollup": "^4.0.2", "rollup-plugin-dts": "^6.1.0", - "rollup-plugin-node-polyfills": "^0.2.1", "ts-jest": "^27.1.3", "typescript": "^4.5.4" }, From f2f7b816b5c99d3a11b093dd21ddce40fae59f5a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Nov 2023 14:56:41 +0100 Subject: [PATCH 0591/1076] build(deps-dev): bump typescript from 4.9.5 to 5.2.2 in /stake-pool/js (#5792) * build(deps-dev): bump typescript from 4.9.5 to 5.2.2 in /stake-pool/js Bumps [typescript](https://github.com/Microsoft/TypeScript) from 4.9.5 to 5.2.2. - [Release notes](https://github.com/Microsoft/TypeScript/releases) - [Commits](https://github.com/Microsoft/TypeScript/compare/v4.9.5...v5.2.2) --- updated-dependencies: - dependency-name: typescript dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Update lockfile --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index f95433ac..0375d914 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -76,7 +76,7 @@ "rollup": "^4.0.2", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^27.1.3", - "typescript": "^4.5.4" + "typescript": "^5.2.2" }, "jest": { "moduleFileExtensions": [ From 293ef9df8c033fe723c4f7131ca7aadabfbbd697 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Nov 2023 15:05:02 +0100 Subject: [PATCH 0592/1076] build(deps-dev): bump @types/jest from 27.5.2 to 29.5.8 in /stake-pool/js (#5794) * build(deps-dev): bump @types/jest in /stake-pool/js Bumps [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) from 27.5.2 to 29.5.8. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest) --- updated-dependencies: - dependency-name: "@types/jest" dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Fix merge conflict --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/js-legacy/package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 0375d914..3b778596 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-typescript": "^11.1.0", "@types/bn.js": "^5.1.0", - "@types/jest": "^27.4.0", + "@types/jest": "^29.5.8", "@types/node": "^20.1.2", "@types/node-fetch": "^2.6.3", "@typescript-eslint/eslint-plugin": "^6.0.0", @@ -70,12 +70,12 @@ "eslint": "^8.40.0", "eslint-config-prettier": "^9.0.0", "eslint-plugin-prettier": "^5.0.0", - "jest": "^27.5.1", + "jest": "^29.0.0", "prettier": "^3.0.0", "rimraf": "^5.0.0", "rollup": "^4.0.2", "rollup-plugin-dts": "^6.1.0", - "ts-jest": "^27.1.3", + "ts-jest": "^29.0.0", "typescript": "^5.2.2" }, "jest": { From 67d1def4c2dd80bc150251cc18a417e319da1411 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Nov 2023 15:15:24 +0100 Subject: [PATCH 0593/1076] build(deps): bump superstruct from 0.14.2 to 1.0.3 in /stake-pool/js (#5793) * build(deps): bump superstruct from 0.14.2 to 1.0.3 in /stake-pool/js Bumps [superstruct](https://github.com/ianstormtaylor/superstruct) from 0.14.2 to 1.0.3. - [Changelog](https://github.com/ianstormtaylor/superstruct/blob/main/Changelog.md) - [Commits](https://github.com/ianstormtaylor/superstruct/compare/v0.14.2...v1.0.3) --- updated-dependencies: - dependency-name: superstruct dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Update lockfile --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 3b778596..a132de6f 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -50,7 +50,7 @@ "@solana/web3.js": "^1.76.0", "bn.js": "^5.2.0", "buffer": "^6.0.3", - "superstruct": "^0.14.2" + "superstruct": "^1.0.3" }, "devDependencies": { "@rollup/plugin-alias": "^5.0.0", From f671302217b0f7af2e1d4df42c71edda3d25c3ac Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Thu, 9 Nov 2023 15:51:26 +0100 Subject: [PATCH 0594/1076] stake-pool: Allow mints with confidential transfer fee (#5610) --- program/src/state.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/program/src/state.rs b/program/src/state.rs index f35dd508..31c2ef94 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -500,10 +500,11 @@ impl StakePool { /// Checks if the given extension is supported for the stake pool mint pub fn is_extension_supported_for_mint(extension_type: &ExtensionType) -> bool { - const SUPPORTED_EXTENSIONS: [ExtensionType; 7] = [ + const SUPPORTED_EXTENSIONS: [ExtensionType; 8] = [ ExtensionType::Uninitialized, ExtensionType::TransferFeeConfig, ExtensionType::ConfidentialTransferMint, + ExtensionType::ConfidentialTransferFeeConfig, ExtensionType::DefaultAccountState, // ok, but a freeze authority is not ExtensionType::InterestBearingConfig, ExtensionType::MetadataPointer, From 472bea3e046b23fa1e80930aec7bdeca6aa0ca22 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Nov 2023 20:55:40 +0100 Subject: [PATCH 0595/1076] build(deps): bump proptest from 1.3.1 to 1.4.0 (#5812) Bumps [proptest](https://github.com/proptest-rs/proptest) from 1.3.1 to 1.4.0. - [Release notes](https://github.com/proptest-rs/proptest/releases) - [Changelog](https://github.com/proptest-rs/proptest/blob/master/CHANGELOG.md) - [Commits](https://github.com/proptest-rs/proptest/compare/v1.3.1...v1.4.0) --- updated-dependencies: - dependency-name: proptest dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 2e45fecf..29064f76 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -29,7 +29,7 @@ bincode = "1.3.1" [dev-dependencies] assert_matches = "1.5.0" -proptest = "1.3" +proptest = "1.4" solana-program-test = "1.17.2" solana-sdk = "1.17.2" solana-vote-program = "1.17.2" From 7fb02b2a17da886c2319d4cfb3f47cf7762c6feb Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 14 Nov 2023 00:43:33 +0100 Subject: [PATCH 0596/1076] js: Add top-level package.json and turbo build (#5819) --- clients/js-legacy/package.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index a132de6f..a3ee5662 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -3,12 +3,10 @@ "version": "0.7.0", "description": "SPL Stake Pool Program JS API", "scripts": { - "build": "npm run clean && tsc && cross-env NODE_ENV=production rollup -c", + "build": "tsc && cross-env NODE_ENV=production rollup -c", "lint": "eslint --max-warnings 0 .", "lint:fix": "eslint . --fix", "test": "jest", - "test:watch": "jest --watch", - "test:cov": "jest --coverage", "clean": "rimraf ./dist" }, "keywords": [], From 6a4ca0f836aad5785222cd47a75a4ea08e7bc52a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Nov 2023 14:02:47 +0100 Subject: [PATCH 0597/1076] build(deps-dev): bump prettier from 3.0.3 to 3.1.0 (#5827) Bumps [prettier](https://github.com/prettier/prettier) from 3.0.3 to 3.1.0. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/3.0.3...3.1.0) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index a3ee5662..1f637765 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -69,7 +69,7 @@ "eslint-config-prettier": "^9.0.0", "eslint-plugin-prettier": "^5.0.0", "jest": "^29.0.0", - "prettier": "^3.0.0", + "prettier": "^3.1.0", "rimraf": "^5.0.0", "rollup": "^4.0.2", "rollup-plugin-dts": "^6.1.0", From 0887247fe792f45d4283bf7553ef61acba9a0473 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Nov 2023 14:02:59 +0100 Subject: [PATCH 0598/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.10.0 to 6.11.0 (#5828) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.10.0 to 6.11.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.11.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 1f637765..8fda1b36 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -62,7 +62,7 @@ "@types/jest": "^29.5.8", "@types/node": "^20.1.2", "@types/node-fetch": "^2.6.3", - "@typescript-eslint/eslint-plugin": "^6.0.0", + "@typescript-eslint/eslint-plugin": "^6.11.0", "@typescript-eslint/parser": "^6.0.0", "cross-env": "^7.0.3", "eslint": "^8.40.0", From b89101df1bc73a9511c1973551263e97ca1cbfd8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Nov 2023 15:30:10 +0100 Subject: [PATCH 0599/1076] build(deps-dev): bump @typescript-eslint/parser from 6.10.0 to 6.11.0 (#5834) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.10.0 to 6.11.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.11.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 8fda1b36..fe7858a3 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/node": "^20.1.2", "@types/node-fetch": "^2.6.3", "@typescript-eslint/eslint-plugin": "^6.11.0", - "@typescript-eslint/parser": "^6.0.0", + "@typescript-eslint/parser": "^6.11.0", "cross-env": "^7.0.3", "eslint": "^8.40.0", "eslint-config-prettier": "^9.0.0", From 338dc2efc02b71ea19aa90709821e9cbe0b06c28 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Nov 2023 15:30:21 +0100 Subject: [PATCH 0600/1076] build(deps-dev): bump rollup from 4.3.0 to 4.4.1 (#5830) Bumps [rollup](https://github.com/rollup/rollup) from 4.3.0 to 4.4.1. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.3.0...v4.4.1) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index fe7858a3..a394f6a9 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -71,7 +71,7 @@ "jest": "^29.0.0", "prettier": "^3.1.0", "rimraf": "^5.0.0", - "rollup": "^4.0.2", + "rollup": "^4.4.1", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.0.0", "typescript": "^5.2.2" From 15b3c5011e5a297a16a9ae7861c3d1394f58b860 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 15 Nov 2023 01:59:56 +0100 Subject: [PATCH 0601/1076] ci: Refactor JS tests to avoid running so often (#5841) --- clients/js-legacy/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index a394f6a9..d2dbae8f 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -4,6 +4,7 @@ "description": "SPL Stake Pool Program JS API", "scripts": { "build": "tsc && cross-env NODE_ENV=production rollup -c", + "build:program": "cargo build-sbf --manifest-path=../program/Cargo.toml", "lint": "eslint --max-warnings 0 .", "lint:fix": "eslint . --fix", "test": "jest", From f522d37a3284e89043f2dda3111f8820870343ed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Nov 2023 14:27:06 +0100 Subject: [PATCH 0602/1076] build(deps): bump @solana/web3.js from 1.87.5 to 1.87.6 (#5824) * build(deps): bump @solana/web3.js from 1.87.5 to 1.87.6 Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.87.5 to 1.87.6. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.87.5...v1.87.6) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Revert change to modern single-pool --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index d2dbae8f..bd745c4e 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -46,7 +46,7 @@ "@coral-xyz/borsh": "^0.29.0", "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "workspace:*", - "@solana/web3.js": "^1.76.0", + "@solana/web3.js": "^1.87.6", "bn.js": "^5.2.0", "buffer": "^6.0.3", "superstruct": "^1.0.3" From a78dba72eb4ee6427a32db108a5e1249434f6a7e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Nov 2023 12:21:35 +0100 Subject: [PATCH 0603/1076] build(deps-dev): bump @types/node from 20.9.0 to 20.9.1 (#5851) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.9.0 to 20.9.1. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index bd745c4e..a380ce0b 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.0", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.8", - "@types/node": "^20.1.2", + "@types/node": "^20.9.1", "@types/node-fetch": "^2.6.3", "@typescript-eslint/eslint-plugin": "^6.11.0", "@typescript-eslint/parser": "^6.11.0", From acd7ae258a09defba777a659775ee7496e87916c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 12:38:08 +0100 Subject: [PATCH 0604/1076] build(deps): bump test-case from 3.2.1 to 3.3.1 (#5856) Bumps [test-case](https://github.com/frondeus/test-case) from 3.2.1 to 3.3.1. - [Release notes](https://github.com/frondeus/test-case/releases) - [Changelog](https://github.com/frondeus/test-case/blob/master/CHANGELOG.md) - [Commits](https://github.com/frondeus/test-case/compare/v3.2.1...v3.3.1) --- updated-dependencies: - dependency-name: test-case dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 29064f76..f1d2978b 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -34,7 +34,7 @@ solana-program-test = "1.17.2" solana-sdk = "1.17.2" solana-vote-program = "1.17.2" spl-token = { version = "4.0", path = "../../token/program", features = [ "no-entrypoint" ] } -test-case = "3.2" +test-case = "3.3" [lib] crate-type = ["cdylib", "lib"] From bd3cab20259a5e00baa0c78f030064fe8248cffc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 12:38:18 +0100 Subject: [PATCH 0605/1076] build(deps-dev): bump @types/node from 20.9.1 to 20.9.2 (#5857) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.9.1 to 20.9.2. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index a380ce0b..c39d0da0 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.0", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.8", - "@types/node": "^20.9.1", + "@types/node": "^20.9.2", "@types/node-fetch": "^2.6.3", "@typescript-eslint/eslint-plugin": "^6.11.0", "@typescript-eslint/parser": "^6.11.0", From 56ac515fc195a94afc6e768790ac43d111e3cd83 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 12:38:36 +0100 Subject: [PATCH 0606/1076] build(deps-dev): bump rollup from 4.4.1 to 4.5.0 (#5859) Bumps [rollup](https://github.com/rollup/rollup) from 4.4.1 to 4.5.0. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.4.1...v4.5.0) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index c39d0da0..8aa11fa6 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.1.0", "rimraf": "^5.0.0", - "rollup": "^4.4.1", + "rollup": "^4.5.0", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.0.0", "typescript": "^5.2.2" From dc95f588a75401fd850ed4e30e640003c4f95768 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 12:38:44 +0100 Subject: [PATCH 0607/1076] build(deps-dev): bump eslint from 8.53.0 to 8.54.0 (#5860) Bumps [eslint](https://github.com/eslint/eslint) from 8.53.0 to 8.54.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.53.0...v8.54.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 8aa11fa6..19a02a4f 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -66,7 +66,7 @@ "@typescript-eslint/eslint-plugin": "^6.11.0", "@typescript-eslint/parser": "^6.11.0", "cross-env": "^7.0.3", - "eslint": "^8.40.0", + "eslint": "^8.54.0", "eslint-config-prettier": "^9.0.0", "eslint-plugin-prettier": "^5.0.0", "jest": "^29.0.0", From c1b9bb9cd5f239ce630122416a9d0fdf78d803f7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Nov 2023 12:12:10 +0100 Subject: [PATCH 0608/1076] build(deps): bump serde from 1.0.192 to 1.0.193 (#5866) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.192 to 1.0.193. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.192...v1.0.193) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 2a4bee9a..0ebc7b5d 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "0.7.0" [dependencies] borsh = "0.10" clap = "2.33.3" -serde = "1.0.192" +serde = "1.0.193" serde_derive = "1.0.130" serde_json = "1.0.108" solana-account-decoder = "=1.17.2" diff --git a/program/Cargo.toml b/program/Cargo.toml index f1d2978b..a48b42bb 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,7 +18,7 @@ bytemuck = "1.13" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.1" -serde = "1.0.192" +serde = "1.0.193" serde_derive = "1.0.103" solana-program = "1.17.2" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } From 3e42b5161701ca4abd97533baddfc8c4d6730f3f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Nov 2023 12:12:26 +0100 Subject: [PATCH 0609/1076] build(deps-dev): bump @typescript-eslint/parser from 6.11.0 to 6.12.0 (#5868) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.11.0 to 6.12.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.12.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 19a02a4f..e0c8efb7 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.9.2", "@types/node-fetch": "^2.6.3", "@typescript-eslint/eslint-plugin": "^6.11.0", - "@typescript-eslint/parser": "^6.11.0", + "@typescript-eslint/parser": "^6.12.0", "cross-env": "^7.0.3", "eslint": "^8.54.0", "eslint-config-prettier": "^9.0.0", From 157f4c48a51d2d71081726a84ed2469a4e8430a5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Nov 2023 12:12:44 +0100 Subject: [PATCH 0610/1076] build(deps-dev): bump @types/jest from 29.5.8 to 29.5.9 (#5870) Bumps [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) from 29.5.8 to 29.5.9. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest) --- updated-dependencies: - dependency-name: "@types/jest" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index e0c8efb7..4f583f5f 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -60,7 +60,7 @@ "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-typescript": "^11.1.0", "@types/bn.js": "^5.1.0", - "@types/jest": "^29.5.8", + "@types/jest": "^29.5.9", "@types/node": "^20.9.2", "@types/node-fetch": "^2.6.3", "@typescript-eslint/eslint-plugin": "^6.11.0", From 42144546f387f7f09bc4994c388ab3bbd65c84a0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Nov 2023 13:20:16 +0100 Subject: [PATCH 0611/1076] build(deps-dev): bump @types/node from 20.9.2 to 20.9.3 (#5874) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.9.2 to 20.9.3. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 4f583f5f..e932e679 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.0", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.9", - "@types/node": "^20.9.2", + "@types/node": "^20.9.3", "@types/node-fetch": "^2.6.3", "@typescript-eslint/eslint-plugin": "^6.11.0", "@typescript-eslint/parser": "^6.12.0", From 8d24e38ba4c24aac2c92cdf1299ff25cdd1e3a0a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Nov 2023 13:38:30 +0100 Subject: [PATCH 0612/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.11.0 to 6.12.0 (#5869) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.11.0 to 6.12.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.12.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index e932e679..1c717dac 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.9", "@types/node": "^20.9.3", "@types/node-fetch": "^2.6.3", - "@typescript-eslint/eslint-plugin": "^6.11.0", + "@typescript-eslint/eslint-plugin": "^6.12.0", "@typescript-eslint/parser": "^6.12.0", "cross-env": "^7.0.3", "eslint": "^8.54.0", From c276ec973768f353d90aaa61ea143afe09f38935 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Nov 2023 14:07:33 +0100 Subject: [PATCH 0613/1076] build(deps-dev): bump typescript from 5.2.2 to 5.3.2 (#5871) * build(deps-dev): bump typescript from 5.2.2 to 5.3.2 Bumps [typescript](https://github.com/Microsoft/TypeScript) from 5.2.2 to 5.3.2. - [Release notes](https://github.com/Microsoft/TypeScript/releases) - [Commits](https://github.com/Microsoft/TypeScript/compare/v5.2.2...v5.3.2) --- updated-dependencies: - dependency-name: typescript dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Remove tsconfig/recommended dependency --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 1c717dac..dbdf0f81 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -75,7 +75,7 @@ "rollup": "^4.5.0", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.0.0", - "typescript": "^5.2.2" + "typescript": "^5.3.2" }, "jest": { "moduleFileExtensions": [ From 5e8032e7369f4da62af06dcb258fb0ca1e12f372 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Nov 2023 14:18:46 +0100 Subject: [PATCH 0614/1076] build(deps-dev): bump @types/node from 20.9.3 to 20.9.4 (#5878) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.9.3 to 20.9.4. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index dbdf0f81..b4cd80f8 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.0", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.9", - "@types/node": "^20.9.3", + "@types/node": "^20.9.4", "@types/node-fetch": "^2.6.3", "@typescript-eslint/eslint-plugin": "^6.12.0", "@typescript-eslint/parser": "^6.12.0", From 330a04e1991d7b8e4a4f1956aed8c9ab87ef4aa0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Nov 2023 14:18:56 +0100 Subject: [PATCH 0615/1076] build(deps-dev): bump rollup from 4.5.0 to 4.5.1 (#5879) Bumps [rollup](https://github.com/rollup/rollup) from 4.5.0 to 4.5.1. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.5.0...v4.5.1) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index b4cd80f8..66f49a3d 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.1.0", "rimraf": "^5.0.0", - "rollup": "^4.5.0", + "rollup": "^4.5.1", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.0.0", "typescript": "^5.3.2" From fb63f3ca5bc5ee246c59510699afffff478abad7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Nov 2023 15:10:23 +0100 Subject: [PATCH 0616/1076] build(deps-dev): bump @types/jest from 29.5.9 to 29.5.10 (#5881) Bumps [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) from 29.5.9 to 29.5.10. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest) --- updated-dependencies: - dependency-name: "@types/jest" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 66f49a3d..58ccbf67 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -60,7 +60,7 @@ "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-typescript": "^11.1.0", "@types/bn.js": "^5.1.0", - "@types/jest": "^29.5.9", + "@types/jest": "^29.5.10", "@types/node": "^20.9.4", "@types/node-fetch": "^2.6.3", "@typescript-eslint/eslint-plugin": "^6.12.0", From f4bfc17dccc27f2d4ff6e26173081d4b76a385bd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 25 Nov 2023 14:48:21 +0100 Subject: [PATCH 0617/1076] build(deps-dev): bump rollup from 4.5.1 to 4.5.2 (#5889) Bumps [rollup](https://github.com/rollup/rollup) from 4.5.1 to 4.5.2. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.5.1...v4.5.2) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 58ccbf67..5782087a 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.1.0", "rimraf": "^5.0.0", - "rollup": "^4.5.1", + "rollup": "^4.5.2", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.0.0", "typescript": "^5.3.2" From d708fab109fe6a56546f0301ce91878bb63e2b4a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 25 Nov 2023 14:48:30 +0100 Subject: [PATCH 0618/1076] build(deps-dev): bump @types/node from 20.9.4 to 20.10.0 (#5892) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.9.4 to 20.10.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 5782087a..5cc5cbaa 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.0", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.10", - "@types/node": "^20.9.4", + "@types/node": "^20.10.0", "@types/node-fetch": "^2.6.3", "@typescript-eslint/eslint-plugin": "^6.12.0", "@typescript-eslint/parser": "^6.12.0", From 4e1552a13b37d139d2f940afbbec493aaca1beac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Nov 2023 12:38:33 +0100 Subject: [PATCH 0619/1076] build(deps-dev): bump @rollup/plugin-alias from 5.0.1 to 5.1.0 (#5897) Bumps [@rollup/plugin-alias](https://github.com/rollup/plugins/tree/HEAD/packages/alias) from 5.0.1 to 5.1.0. - [Changelog](https://github.com/rollup/plugins/blob/master/packages/alias/CHANGELOG.md) - [Commits](https://github.com/rollup/plugins/commits/wasm-v5.1.0/packages/alias) --- updated-dependencies: - dependency-name: "@rollup/plugin-alias" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 5cc5cbaa..39f970bf 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -52,7 +52,7 @@ "superstruct": "^1.0.3" }, "devDependencies": { - "@rollup/plugin-alias": "^5.0.0", + "@rollup/plugin-alias": "^5.1.0", "@rollup/plugin-commonjs": "^25.0.0", "@rollup/plugin-json": "^6.0.0", "@rollup/plugin-multi-entry": "^6.0.0", From a9be59ef999e024457e22b6ce528cf1e3ed2624e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Nov 2023 14:06:40 +0100 Subject: [PATCH 0620/1076] build(deps-dev): bump rollup from 4.5.2 to 4.6.0 (#5898) Bumps [rollup](https://github.com/rollup/rollup) from 4.5.2 to 4.6.0. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.5.2...v4.6.0) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 39f970bf..147e2f37 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.1.0", "rimraf": "^5.0.0", - "rollup": "^4.5.2", + "rollup": "^4.6.0", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.0.0", "typescript": "^5.3.2" From 7f59ef665f85da70829bd23267bf2fffb22d4644 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Nov 2023 12:23:56 +0100 Subject: [PATCH 0621/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.12.0 to 6.13.1 (#5907) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.12.0 to 6.13.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.13.1/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 147e2f37..cfa80ee7 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.10", "@types/node": "^20.10.0", "@types/node-fetch": "^2.6.3", - "@typescript-eslint/eslint-plugin": "^6.12.0", + "@typescript-eslint/eslint-plugin": "^6.13.1", "@typescript-eslint/parser": "^6.12.0", "cross-env": "^7.0.3", "eslint": "^8.54.0", From 28941887438e585351443fd1bc27cb0dc3ee1a42 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Nov 2023 12:41:23 +0100 Subject: [PATCH 0622/1076] build(deps-dev): bump @typescript-eslint/parser from 6.12.0 to 6.13.1 (#5906) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.12.0 to 6.13.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.13.1/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index cfa80ee7..fd3a5f3c 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.10.0", "@types/node-fetch": "^2.6.3", "@typescript-eslint/eslint-plugin": "^6.13.1", - "@typescript-eslint/parser": "^6.12.0", + "@typescript-eslint/parser": "^6.13.1", "cross-env": "^7.0.3", "eslint": "^8.54.0", "eslint-config-prettier": "^9.0.0", From 92d70318cc55b65e26ab5597a3e98d246601a272 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 29 Nov 2023 12:55:07 +0100 Subject: [PATCH 0623/1076] repo: Update to 1.17.6 (#5863) * repo: Update to 1.17.6 with script * Update lockfile * Remove disabling feature in token-cli tests --- clients/cli/Cargo.toml | 18 +++++++++--------- program/Cargo.toml | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 0ebc7b5d..ab3eae76 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -14,15 +14,15 @@ clap = "2.33.3" serde = "1.0.193" serde_derive = "1.0.130" serde_json = "1.0.108" -solana-account-decoder = "=1.17.2" -solana-clap-utils = "=1.17.2" -solana-cli-config = "=1.17.2" -solana-cli-output = "=1.17.2" -solana-client = "=1.17.2" -solana-logger = "=1.17.2" -solana-program = "=1.17.2" -solana-remote-wallet = "=1.17.2" -solana-sdk = "=1.17.2" +solana-account-decoder = "=1.17.6" +solana-clap-utils = "=1.17.6" +solana-cli-config = "=1.17.6" +solana-cli-output = "=1.17.6" +solana-client = "=1.17.6" +solana-logger = "=1.17.6" +solana-program = "=1.17.6" +solana-remote-wallet = "=1.17.6" +solana-sdk = "=1.17.6" spl-associated-token-account = { version = "=2.2", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "=0.7.0", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "=4.0", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/program/Cargo.toml b/program/Cargo.toml index a48b42bb..0abf6c5c 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -20,7 +20,7 @@ num-traits = "0.2" num_enum = "0.7.1" serde = "1.0.193" serde_derive = "1.0.103" -solana-program = "1.17.2" +solana-program = "1.17.6" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-pod = { version = "0.1", path = "../../libraries/pod", features = ["borsh"] } spl-token-2022 = { version = "0.9", path = "../../token/program-2022", features = [ "no-entrypoint" ] } @@ -30,9 +30,9 @@ bincode = "1.3.1" [dev-dependencies] assert_matches = "1.5.0" proptest = "1.4" -solana-program-test = "1.17.2" -solana-sdk = "1.17.2" -solana-vote-program = "1.17.2" +solana-program-test = "1.17.6" +solana-sdk = "1.17.6" +solana-vote-program = "1.17.6" spl-token = { version = "4.0", path = "../../token/program", features = [ "no-entrypoint" ] } test-case = "3.3" From d3a8129f066d57239d9f9bef39362365358264c3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 29 Nov 2023 13:40:50 +0100 Subject: [PATCH 0624/1076] build(deps-dev): bump eslint-plugin-prettier from 4.2.1 to 5.0.1 (#5925) Bumps [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) from 4.2.1 to 5.0.1. - [Release notes](https://github.com/prettier/eslint-plugin-prettier/releases) - [Changelog](https://github.com/prettier/eslint-plugin-prettier/blob/master/CHANGELOG.md) - [Commits](https://github.com/prettier/eslint-plugin-prettier/compare/v4.2.1...v5.0.1) --- updated-dependencies: - dependency-name: eslint-plugin-prettier dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index fd3a5f3c..d7d8700e 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -68,7 +68,7 @@ "cross-env": "^7.0.3", "eslint": "^8.54.0", "eslint-config-prettier": "^9.0.0", - "eslint-plugin-prettier": "^5.0.0", + "eslint-plugin-prettier": "^5.0.1", "jest": "^29.0.0", "prettier": "^3.1.0", "rimraf": "^5.0.0", From e72e05bee6c82c567a6072bb43d65884347fab82 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Wed, 29 Nov 2023 22:54:01 +0100 Subject: [PATCH 0625/1076] stake-pool: Add security.txt (#5929) * stake-pool: Add security.txt * Update stake-pool/program/src/entrypoint.rs Co-authored-by: Trent Nelson --------- Co-authored-by: Trent Nelson --- program/Cargo.toml | 1 + program/src/entrypoint.rs | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/program/Cargo.toml b/program/Cargo.toml index 0abf6c5c..cfa20fdd 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -21,6 +21,7 @@ num_enum = "0.7.1" serde = "1.0.193" serde_derive = "1.0.103" solana-program = "1.17.6" +solana-security-txt = "1.1.1" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-pod = { version = "0.1", path = "../../libraries/pod", features = ["borsh"] } spl-token-2022 = { version = "0.9", path = "../../token/program-2022", features = [ "no-entrypoint" ] } diff --git a/program/src/entrypoint.rs b/program/src/entrypoint.rs index 92e3ea5a..1b07392e 100644 --- a/program/src/entrypoint.rs +++ b/program/src/entrypoint.rs @@ -8,6 +8,7 @@ use { account_info::AccountInfo, entrypoint::ProgramResult, program_error::PrintProgramError, pubkey::Pubkey, }, + solana_security_txt::security_txt, }; solana_program::entrypoint!(process_instruction); @@ -24,3 +25,18 @@ fn process_instruction( Ok(()) } } + +security_txt! { + // Required fields + name: "SPL Stake Pool", + project_url: "https://spl.solana.com/stake-pool", + contacts: "link:https://github.com/solana-labs/solana-program-library/security/advisories/new,mailto:security@solana.com,discord:https://solana.com/discord", + policy: "https://github.com/solana-labs/solana-program-library/blob/master/SECURITY.md", + + // Optional Fields + preferred_languages: "en", + source_code: "https://github.com/solana-labs/solana-program-library/tree/master/stake-pool/program", + source_revision: "58c1226a513d3d8bb2de8ec67586a679be7fd2d4", + source_release: "stake-pool-v0.6.4", + auditors: "https://github.com/solana-labs/security-audits#stake-pool" +} From 65520cb6ce40c819bd87c468353b6b5f202de164 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 30 Nov 2023 12:36:31 +0100 Subject: [PATCH 0626/1076] build(deps-dev): bump rollup from 4.6.0 to 4.6.1 (#5932) Bumps [rollup](https://github.com/rollup/rollup) from 4.6.0 to 4.6.1. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.6.0...v4.6.1) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index d7d8700e..e04c9271 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.1.0", "rimraf": "^5.0.0", - "rollup": "^4.6.0", + "rollup": "^4.6.1", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.0.0", "typescript": "^5.3.2" From 13378954ebedb1b22d0be0a1c6cd775f00606e64 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 30 Nov 2023 12:37:07 +0100 Subject: [PATCH 0627/1076] build(deps-dev): bump @types/node from 20.10.0 to 20.10.1 (#5936) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.10.0 to 20.10.1. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index e04c9271..854f9cc2 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.0", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.10", - "@types/node": "^20.10.0", + "@types/node": "^20.10.1", "@types/node-fetch": "^2.6.3", "@typescript-eslint/eslint-plugin": "^6.13.1", "@typescript-eslint/parser": "^6.13.1", From 42605a31558aeda7b72d6876d33e8c40e370c8f8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Dec 2023 11:42:16 +0100 Subject: [PATCH 0628/1076] build(deps-dev): bump @types/node from 20.10.1 to 20.10.3 (#5940) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.10.1 to 20.10.3. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 854f9cc2..729a0592 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.0", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.10", - "@types/node": "^20.10.1", + "@types/node": "^20.10.3", "@types/node-fetch": "^2.6.3", "@typescript-eslint/eslint-plugin": "^6.13.1", "@typescript-eslint/parser": "^6.13.1", From cf63d06756ee880a01f48d1eae165c3aa5dbfde6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Dec 2023 11:42:28 +0100 Subject: [PATCH 0629/1076] build(deps-dev): bump eslint-config-prettier from 9.0.0 to 9.1.0 (#5942) Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 9.0.0 to 9.1.0. - [Changelog](https://github.com/prettier/eslint-config-prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/eslint-config-prettier/compare/v9.0.0...v9.1.0) --- updated-dependencies: - dependency-name: eslint-config-prettier dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 729a0592..dfdb4618 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -67,7 +67,7 @@ "@typescript-eslint/parser": "^6.13.1", "cross-env": "^7.0.3", "eslint": "^8.54.0", - "eslint-config-prettier": "^9.0.0", + "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.0.1", "jest": "^29.0.0", "prettier": "^3.1.0", From 7e75aa4f67aa25e31fed842c396284831bb2719f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Dec 2023 12:18:07 +0100 Subject: [PATCH 0630/1076] build(deps-dev): bump eslint from 8.54.0 to 8.55.0 (#5941) Bumps [eslint](https://github.com/eslint/eslint) from 8.54.0 to 8.55.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.54.0...v8.55.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index dfdb4618..58f50898 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -66,7 +66,7 @@ "@typescript-eslint/eslint-plugin": "^6.13.1", "@typescript-eslint/parser": "^6.13.1", "cross-env": "^7.0.3", - "eslint": "^8.54.0", + "eslint": "^8.55.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.0.1", "jest": "^29.0.0", From 1966a9dcbf2a700f98c82ef13b7a36593c1417f2 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Mon, 4 Dec 2023 19:17:01 +0100 Subject: [PATCH 0631/1076] stake-pool: Upgrade to version 1.0.0 to tag release (#5943) --- clients/cli/Cargo.toml | 4 ++-- clients/js-legacy/package.json | 2 +- program/Cargo.toml | 2 +- program/src/entrypoint.rs | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index ab3eae76..ade78048 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -6,7 +6,7 @@ homepage = "https://spl.solana.com/stake-pool" license = "Apache-2.0" name = "spl-stake-pool-cli" repository = "https://github.com/solana-labs/solana-program-library" -version = "0.7.0" +version = "1.0.0" [dependencies] borsh = "0.10" @@ -24,7 +24,7 @@ solana-program = "=1.17.6" solana-remote-wallet = "=1.17.6" solana-sdk = "=1.17.6" spl-associated-token-account = { version = "=2.2", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } -spl-stake-pool = { version = "=0.7.0", path="../program", features = [ "no-entrypoint" ] } +spl-stake-pool = { version = "=1.0.0", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "=4.0", path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" bincode = "1.3.1" diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 58f50898..0418fd57 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-stake-pool", - "version": "0.7.0", + "version": "1.0.0", "description": "SPL Stake Pool Program JS API", "scripts": { "build": "tsc && cross-env NODE_ENV=production rollup -c", diff --git a/program/Cargo.toml b/program/Cargo.toml index cfa20fdd..a65d0144 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "spl-stake-pool" -version = "0.7.0" +version = "1.0.0" description = "Solana Program Library Stake Pool" authors = ["Solana Labs Maintainers "] repository = "https://github.com/solana-labs/solana-program-library" diff --git a/program/src/entrypoint.rs b/program/src/entrypoint.rs index 1b07392e..087280a3 100644 --- a/program/src/entrypoint.rs +++ b/program/src/entrypoint.rs @@ -36,7 +36,7 @@ security_txt! { // Optional Fields preferred_languages: "en", source_code: "https://github.com/solana-labs/solana-program-library/tree/master/stake-pool/program", - source_revision: "58c1226a513d3d8bb2de8ec67586a679be7fd2d4", - source_release: "stake-pool-v0.6.4", + source_revision: "", // fill in after v1.0.0 bump lands + source_release: "stake-pool-v1.0.0", auditors: "https://github.com/solana-labs/security-audits#stake-pool" } From af29e594b0c8e713ccb4e687252fe046bb7e13a1 Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Mon, 4 Dec 2023 20:30:32 +0100 Subject: [PATCH 0632/1076] stake-pool: Update security and audit info (#5945) --- program/src/entrypoint.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/src/entrypoint.rs b/program/src/entrypoint.rs index 087280a3..b616b219 100644 --- a/program/src/entrypoint.rs +++ b/program/src/entrypoint.rs @@ -36,7 +36,7 @@ security_txt! { // Optional Fields preferred_languages: "en", source_code: "https://github.com/solana-labs/solana-program-library/tree/master/stake-pool/program", - source_revision: "", // fill in after v1.0.0 bump lands + source_revision: "b7dd8fee93815b486fce98d3d43d1d0934980226", source_release: "stake-pool-v1.0.0", auditors: "https://github.com/solana-labs/security-audits#stake-pool" } From dc6d78c23a35a2ea07cb90f7159c57784f4c503f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Dec 2023 11:44:40 +0100 Subject: [PATCH 0633/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.13.1 to 6.13.2 (#5947) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.13.1 to 6.13.2. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.13.2/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 0418fd57..aad46766 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.10", "@types/node": "^20.10.3", "@types/node-fetch": "^2.6.3", - "@typescript-eslint/eslint-plugin": "^6.13.1", + "@typescript-eslint/eslint-plugin": "^6.13.2", "@typescript-eslint/parser": "^6.13.1", "cross-env": "^7.0.3", "eslint": "^8.55.0", From 0978fc6046eb1fcc96aafac0819cac641f1633c6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Dec 2023 12:21:15 +0100 Subject: [PATCH 0634/1076] build(deps-dev): bump @typescript-eslint/parser from 6.13.1 to 6.13.2 (#5948) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.13.1 to 6.13.2. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.13.2/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index aad46766..37ec7f81 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.10.3", "@types/node-fetch": "^2.6.3", "@typescript-eslint/eslint-plugin": "^6.13.2", - "@typescript-eslint/parser": "^6.13.1", + "@typescript-eslint/parser": "^6.13.2", "cross-env": "^7.0.3", "eslint": "^8.55.0", "eslint-config-prettier": "^9.1.0", From 6dc5b6241721b8a51d81bba1c971a7a9967da1c5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Dec 2023 13:03:34 +0100 Subject: [PATCH 0635/1076] build(deps-dev): bump @types/jest from 29.5.10 to 29.5.11 (#5953) Bumps [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) from 29.5.10 to 29.5.11. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest) --- updated-dependencies: - dependency-name: "@types/jest" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 37ec7f81..c7d654b4 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -60,7 +60,7 @@ "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-typescript": "^11.1.0", "@types/bn.js": "^5.1.0", - "@types/jest": "^29.5.10", + "@types/jest": "^29.5.11", "@types/node": "^20.10.3", "@types/node-fetch": "^2.6.3", "@typescript-eslint/eslint-plugin": "^6.13.2", From de695182c68ee22a50f45e79af46c2ba87ce1fbf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Dec 2023 13:03:30 +0100 Subject: [PATCH 0636/1076] build(deps-dev): bump @types/node from 20.10.3 to 20.10.4 (#5960) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.10.3 to 20.10.4. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index c7d654b4..f73ffae1 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.0", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.11", - "@types/node": "^20.10.3", + "@types/node": "^20.10.4", "@types/node-fetch": "^2.6.3", "@typescript-eslint/eslint-plugin": "^6.13.2", "@typescript-eslint/parser": "^6.13.2", From a56d862140796a679bffa5085d8edcf4d2ace6d5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Dec 2023 13:17:45 +0100 Subject: [PATCH 0637/1076] build(deps-dev): bump typescript from 5.3.2 to 5.3.3 (#5961) Bumps [typescript](https://github.com/Microsoft/TypeScript) from 5.3.2 to 5.3.3. - [Release notes](https://github.com/Microsoft/TypeScript/releases) - [Commits](https://github.com/Microsoft/TypeScript/compare/v5.3.2...v5.3.3) --- updated-dependencies: - dependency-name: typescript dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index f73ffae1..cd405e9f 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -75,7 +75,7 @@ "rollup": "^4.6.1", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.0.0", - "typescript": "^5.3.2" + "typescript": "^5.3.3" }, "jest": { "moduleFileExtensions": [ From 7d518a400834a5a189659b4668082be353a7f1cb Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Fri, 8 Dec 2023 12:49:09 +0100 Subject: [PATCH 0638/1076] token-2022: Bump to 1.0.0 for prod release (#5954) * token-2022: Bump to 1.0.0 for first prod release * Update security.txt --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index a65d0144..15db4c53 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -24,7 +24,7 @@ solana-program = "1.17.6" solana-security-txt = "1.1.1" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-pod = { version = "0.1", path = "../../libraries/pod", features = ["borsh"] } -spl-token-2022 = { version = "0.9", path = "../../token/program-2022", features = [ "no-entrypoint" ] } +spl-token-2022 = { version = "1.0", path = "../../token/program-2022", features = [ "no-entrypoint" ] } thiserror = "1.0" bincode = "1.3.1" From 09a26e941964a9a78d9980ce5ee7b9574bf1365a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 Dec 2023 12:49:51 +0100 Subject: [PATCH 0639/1076] build(deps-dev): bump rollup from 4.6.1 to 4.7.0 (#5965) Bumps [rollup](https://github.com/rollup/rollup) from 4.6.1 to 4.7.0. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.6.1...v4.7.0) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index cd405e9f..f229b97f 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.1.0", "rimraf": "^5.0.0", - "rollup": "^4.6.1", + "rollup": "^4.7.0", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.0.0", "typescript": "^5.3.3" From c0f4a88496e5825e64486e19d28cc032436d1669 Mon Sep 17 00:00:00 2001 From: Joe C Date: Fri, 8 Dec 2023 18:59:47 -0600 Subject: [PATCH 0640/1076] js: remove workspace paths (#5969) --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index f229b97f..5e94312d 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -45,7 +45,7 @@ "dependencies": { "@coral-xyz/borsh": "^0.29.0", "@solana/buffer-layout": "^4.0.1", - "@solana/spl-token": "workspace:*", + "@solana/spl-token": "0.3.9", "@solana/web3.js": "^1.87.6", "bn.js": "^5.2.0", "buffer": "^6.0.3", From eae05730c73c32d92a5f15f8c5c045f6091fa791 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Dec 2023 12:31:26 +0100 Subject: [PATCH 0641/1076] build(deps-dev): bump prettier from 3.1.0 to 3.1.1 (#5981) Bumps [prettier](https://github.com/prettier/prettier) from 3.1.0 to 3.1.1. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/3.1.0...3.1.1) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 5e94312d..260975db 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -70,7 +70,7 @@ "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.0.1", "jest": "^29.0.0", - "prettier": "^3.1.0", + "prettier": "^3.1.1", "rimraf": "^5.0.0", "rollup": "^4.7.0", "rollup-plugin-dts": "^6.1.0", From 7535e7bfb10cc0551d85b9c81ef5e93379bcc0a7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Dec 2023 12:55:01 +0100 Subject: [PATCH 0642/1076] build(deps-dev): bump rollup from 4.7.0 to 4.8.0 (#5977) Bumps [rollup](https://github.com/rollup/rollup) from 4.7.0 to 4.8.0. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.7.0...v4.8.0) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 260975db..873f4a54 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.1.1", "rimraf": "^5.0.0", - "rollup": "^4.7.0", + "rollup": "^4.8.0", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.0.0", "typescript": "^5.3.3" From 22a135676e2050ae871ddf1e4327a732a365583e Mon Sep 17 00:00:00 2001 From: Jon Cinque Date: Tue, 12 Dec 2023 02:35:21 +0100 Subject: [PATCH 0643/1076] associated-token-account: Bump to use token-2022 v1 (#5987) --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index ade78048..4af29aa3 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -23,7 +23,7 @@ solana-logger = "=1.17.6" solana-program = "=1.17.6" solana-remote-wallet = "=1.17.6" solana-sdk = "=1.17.6" -spl-associated-token-account = { version = "=2.2", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } +spl-associated-token-account = { version = "=2.3", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "=1.0.0", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "=4.0", path="../../token/program", features = [ "no-entrypoint" ] } bs58 = "0.4.0" From 341a1c8b4ba5211dea6b99e89f1f04202ac5e885 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Dec 2023 12:15:38 +0100 Subject: [PATCH 0644/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.13.2 to 6.14.0 (#5988) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.13.2 to 6.14.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.14.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 873f4a54..1a420181 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.11", "@types/node": "^20.10.4", "@types/node-fetch": "^2.6.3", - "@typescript-eslint/eslint-plugin": "^6.13.2", + "@typescript-eslint/eslint-plugin": "^6.14.0", "@typescript-eslint/parser": "^6.13.2", "cross-env": "^7.0.3", "eslint": "^8.55.0", From d980823ba57c6a58a15cf45eee65cc9a12bda35c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Dec 2023 12:28:08 +0100 Subject: [PATCH 0645/1076] build(deps-dev): bump @typescript-eslint/parser from 6.13.2 to 6.14.0 (#5989) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.13.2 to 6.14.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.14.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 1a420181..ea64f200 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.10.4", "@types/node-fetch": "^2.6.3", "@typescript-eslint/eslint-plugin": "^6.14.0", - "@typescript-eslint/parser": "^6.13.2", + "@typescript-eslint/parser": "^6.14.0", "cross-env": "^7.0.3", "eslint": "^8.55.0", "eslint-config-prettier": "^9.1.0", From f7679045e77865bc5c98f489ee740198b71edc1a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Dec 2023 12:32:36 +0100 Subject: [PATCH 0646/1076] build(deps-dev): bump @rollup/plugin-json from 6.0.1 to 6.1.0 (#5993) Bumps [@rollup/plugin-json](https://github.com/rollup/plugins/tree/HEAD/packages/json) from 6.0.1 to 6.1.0. - [Changelog](https://github.com/rollup/plugins/blob/master/packages/json/CHANGELOG.md) - [Commits](https://github.com/rollup/plugins/commits/url-v6.1.0/packages/json) --- updated-dependencies: - dependency-name: "@rollup/plugin-json" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index ea64f200..fd06cd86 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -54,7 +54,7 @@ "devDependencies": { "@rollup/plugin-alias": "^5.1.0", "@rollup/plugin-commonjs": "^25.0.0", - "@rollup/plugin-json": "^6.0.0", + "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-multi-entry": "^6.0.0", "@rollup/plugin-node-resolve": "^15.0.2", "@rollup/plugin-terser": "^0.4.4", From 53f71cd0f54cae5b94c8fba595b6e1eaaa9987c8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Dec 2023 12:43:16 +0100 Subject: [PATCH 0647/1076] build(deps-dev): bump rollup from 4.8.0 to 4.9.0 (#5994) Bumps [rollup](https://github.com/rollup/rollup) from 4.8.0 to 4.9.0. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.8.0...v4.9.0) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index fd06cd86..faf32189 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.1.1", "rimraf": "^5.0.0", - "rollup": "^4.8.0", + "rollup": "^4.9.0", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.0.0", "typescript": "^5.3.3" From 9393a6d8d08f429765db688928ab2b9cdedffa17 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Dec 2023 19:26:52 -0500 Subject: [PATCH 0648/1076] build(deps-dev): bump rollup from 4.9.0 to 4.9.1 (#6002) Bumps [rollup](https://github.com/rollup/rollup) from 4.9.0 to 4.9.1. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.9.0...v4.9.1) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index faf32189..06765546 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.1.1", "rimraf": "^5.0.0", - "rollup": "^4.9.0", + "rollup": "^4.9.1", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.0.0", "typescript": "^5.3.3" From 60d5364f7694b5f0bc2d488dfc5d5d72813c312d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Dec 2023 19:27:03 -0500 Subject: [PATCH 0649/1076] build(deps-dev): bump @types/node from 20.10.4 to 20.10.5 (#6003) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.10.4 to 20.10.5. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 06765546..d3e5aadd 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.0", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.11", - "@types/node": "^20.10.4", + "@types/node": "^20.10.5", "@types/node-fetch": "^2.6.3", "@typescript-eslint/eslint-plugin": "^6.14.0", "@typescript-eslint/parser": "^6.14.0", From 7cbe770d3b98ad143fbea0be9aa315f15814e5fe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Dec 2023 19:27:29 -0500 Subject: [PATCH 0650/1076] build(deps-dev): bump @typescript-eslint/parser from 6.14.0 to 6.15.0 (#6009) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.14.0 to 6.15.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.15.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index d3e5aadd..e554dd75 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.10.5", "@types/node-fetch": "^2.6.3", "@typescript-eslint/eslint-plugin": "^6.14.0", - "@typescript-eslint/parser": "^6.14.0", + "@typescript-eslint/parser": "^6.15.0", "cross-env": "^7.0.3", "eslint": "^8.55.0", "eslint-config-prettier": "^9.1.0", From 9cb5489ea19ffafc9b8d5f27f4e5a5687020fe09 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Dec 2023 19:27:54 -0500 Subject: [PATCH 0651/1076] build(deps-dev): bump eslint-plugin-prettier from 5.0.1 to 5.1.0 (#6012) Bumps [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) from 5.0.1 to 5.1.0. - [Release notes](https://github.com/prettier/eslint-plugin-prettier/releases) - [Changelog](https://github.com/prettier/eslint-plugin-prettier/blob/master/CHANGELOG.md) - [Commits](https://github.com/prettier/eslint-plugin-prettier/compare/v5.0.1...v5.1.0) --- updated-dependencies: - dependency-name: eslint-plugin-prettier dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index e554dd75..94d59000 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -68,7 +68,7 @@ "cross-env": "^7.0.3", "eslint": "^8.55.0", "eslint-config-prettier": "^9.1.0", - "eslint-plugin-prettier": "^5.0.1", + "eslint-plugin-prettier": "^5.1.0", "jest": "^29.0.0", "prettier": "^3.1.1", "rimraf": "^5.0.0", From ab933fb3dc4f1751e09f65bdba65b07dab6abdfd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Dec 2023 20:02:53 -0500 Subject: [PATCH 0652/1076] build(deps-dev): bump eslint and @types/eslint (#6016) Bumps [eslint](https://github.com/eslint/eslint) and [@types/eslint](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/eslint). These dependencies needed to be updated together. Updates `eslint` from 8.55.0 to 8.56.0 - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.55.0...v8.56.0) Updates `@types/eslint` from 8.44.9 to 8.56.0 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/eslint) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor - dependency-name: "@types/eslint" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 94d59000..1ca27d96 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -66,7 +66,7 @@ "@typescript-eslint/eslint-plugin": "^6.14.0", "@typescript-eslint/parser": "^6.15.0", "cross-env": "^7.0.3", - "eslint": "^8.55.0", + "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.0", "jest": "^29.0.0", From d1a8cba109f38a223b911e0352a5a32b8dec66f8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Dec 2023 20:13:23 -0500 Subject: [PATCH 0653/1076] build(deps-dev): bump eslint-plugin-prettier from 5.0.1 to 5.1.1 (#6021) Bumps [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) from 5.0.1 to 5.1.1. - [Release notes](https://github.com/prettier/eslint-plugin-prettier/releases) - [Changelog](https://github.com/prettier/eslint-plugin-prettier/blob/master/CHANGELOG.md) - [Commits](https://github.com/prettier/eslint-plugin-prettier/compare/v5.0.1...v5.1.1) --- updated-dependencies: - dependency-name: eslint-plugin-prettier dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 1ca27d96..85abaef5 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -68,7 +68,7 @@ "cross-env": "^7.0.3", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", - "eslint-plugin-prettier": "^5.1.0", + "eslint-plugin-prettier": "^5.1.1", "jest": "^29.0.0", "prettier": "^3.1.1", "rimraf": "^5.0.0", From 9d64c6b45f58f18eee5bae1e564cae160b417a70 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Dec 2023 20:13:46 -0500 Subject: [PATCH 0654/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.14.0 to 6.15.0 (#6010) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.14.0 to 6.15.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.15.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 85abaef5..6122a130 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.11", "@types/node": "^20.10.5", "@types/node-fetch": "^2.6.3", - "@typescript-eslint/eslint-plugin": "^6.14.0", + "@typescript-eslint/eslint-plugin": "^6.15.0", "@typescript-eslint/parser": "^6.15.0", "cross-env": "^7.0.3", "eslint": "^8.56.0", From 6bae600fb28ff4ea39d313a8437ed909e4113086 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Dec 2023 03:09:35 +0100 Subject: [PATCH 0655/1076] build(deps-dev): bump eslint-plugin-prettier from 5.1.1 to 5.1.2 (#6025) Bumps [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) from 5.1.1 to 5.1.2. - [Release notes](https://github.com/prettier/eslint-plugin-prettier/releases) - [Changelog](https://github.com/prettier/eslint-plugin-prettier/blob/master/CHANGELOG.md) - [Commits](https://github.com/prettier/eslint-plugin-prettier/compare/v5.1.1...v5.1.2) --- updated-dependencies: - dependency-name: eslint-plugin-prettier dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 6122a130..4e69518a 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -68,7 +68,7 @@ "cross-env": "^7.0.3", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", - "eslint-plugin-prettier": "^5.1.1", + "eslint-plugin-prettier": "^5.1.2", "jest": "^29.0.0", "prettier": "^3.1.1", "rimraf": "^5.0.0", From e17a6466c3eed23e835822f092dc1fbf4e077d47 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Dec 2023 16:52:12 +0100 Subject: [PATCH 0656/1076] build(deps-dev): bump @typescript-eslint/parser from 6.15.0 to 6.16.0 (#6029) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.15.0 to 6.16.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.16.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 4e69518a..cb1402bd 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.10.5", "@types/node-fetch": "^2.6.3", "@typescript-eslint/eslint-plugin": "^6.15.0", - "@typescript-eslint/parser": "^6.15.0", + "@typescript-eslint/parser": "^6.16.0", "cross-env": "^7.0.3", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", From eb98375474c2dbbd40b7b15b5a875e5a1579915e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Dec 2023 17:49:29 +0100 Subject: [PATCH 0657/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.15.0 to 6.16.0 (#6030) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.15.0 to 6.16.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.16.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index cb1402bd..d2542082 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.11", "@types/node": "^20.10.5", "@types/node-fetch": "^2.6.3", - "@typescript-eslint/eslint-plugin": "^6.15.0", + "@typescript-eslint/eslint-plugin": "^6.16.0", "@typescript-eslint/parser": "^6.16.0", "cross-env": "^7.0.3", "eslint": "^8.56.0", From b050359f4f8ada68177c871824eaa10873026db3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 Dec 2023 13:23:39 +0100 Subject: [PATCH 0658/1076] build(deps-dev): bump @types/node-fetch from 2.6.9 to 2.6.10 (#6034) Bumps [@types/node-fetch](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node-fetch) from 2.6.9 to 2.6.10. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node-fetch) --- updated-dependencies: - dependency-name: "@types/node-fetch" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index d2542082..f00425d3 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -62,7 +62,7 @@ "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.11", "@types/node": "^20.10.5", - "@types/node-fetch": "^2.6.3", + "@types/node-fetch": "^2.6.10", "@typescript-eslint/eslint-plugin": "^6.16.0", "@typescript-eslint/parser": "^6.16.0", "cross-env": "^7.0.3", From 185c1e26dab901aea36d9ca8223f5eb12016395b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 01:18:44 +0100 Subject: [PATCH 0659/1076] build(deps): bump serde_json from 1.0.108 to 1.0.109 (#6039) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.108 to 1.0.109. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.108...v1.0.109) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 4af29aa3..7c5d3bf0 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ borsh = "0.10" clap = "2.33.3" serde = "1.0.193" serde_derive = "1.0.130" -serde_json = "1.0.108" +serde_json = "1.0.109" solana-account-decoder = "=1.17.6" solana-clap-utils = "=1.17.6" solana-cli-config = "=1.17.6" From 55787abc012c3bb888a8c4e74263375c4ee7c8ba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 01:19:16 +0100 Subject: [PATCH 0660/1076] build(deps-dev): bump rollup from 4.9.1 to 4.9.2 (#6043) Bumps [rollup](https://github.com/rollup/rollup) from 4.9.1 to 4.9.2. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.9.1...v4.9.2) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index f00425d3..4c64c647 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.1.1", "rimraf": "^5.0.0", - "rollup": "^4.9.1", + "rollup": "^4.9.2", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.0.0", "typescript": "^5.3.3" From fa29391d818d2e27c56d6adee0aa9474e635ccc4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 01:19:22 +0100 Subject: [PATCH 0661/1076] build(deps-dev): bump @types/node from 20.10.5 to 20.10.6 (#6044) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.10.5 to 20.10.6. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 4c64c647..6555f579 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.0", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.11", - "@types/node": "^20.10.5", + "@types/node": "^20.10.6", "@types/node-fetch": "^2.6.10", "@typescript-eslint/eslint-plugin": "^6.16.0", "@typescript-eslint/parser": "^6.16.0", From 67cc0e45ffdfef6a1f9b18d50198b089b113f967 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 12:20:25 +0100 Subject: [PATCH 0662/1076] build(deps): bump serde from 1.0.193 to 1.0.194 (#6047) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.193 to 1.0.194. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.193...v1.0.194) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 7c5d3bf0..7c0a6dc5 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "1.0.0" [dependencies] borsh = "0.10" clap = "2.33.3" -serde = "1.0.193" +serde = "1.0.194" serde_derive = "1.0.130" serde_json = "1.0.109" solana-account-decoder = "=1.17.6" diff --git a/program/Cargo.toml b/program/Cargo.toml index 15db4c53..b6452ba0 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,7 +18,7 @@ bytemuck = "1.13" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.1" -serde = "1.0.193" +serde = "1.0.194" serde_derive = "1.0.103" solana-program = "1.17.6" solana-security-txt = "1.1.1" From b31bcacefdf6aba89fda95502260231f4959acec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 12:20:40 +0100 Subject: [PATCH 0663/1076] build(deps-dev): bump @typescript-eslint/parser from 6.16.0 to 6.17.0 (#6049) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.16.0 to 6.17.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.17.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 6555f579..c470ee3a 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.10.6", "@types/node-fetch": "^2.6.10", "@typescript-eslint/eslint-plugin": "^6.16.0", - "@typescript-eslint/parser": "^6.16.0", + "@typescript-eslint/parser": "^6.17.0", "cross-env": "^7.0.3", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", From 549a40ea15d7ca68a27bbc0cdc9a01a8d60f018f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 12:44:14 +0100 Subject: [PATCH 0664/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.16.0 to 6.17.0 (#6051) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.16.0 to 6.17.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.17.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index c470ee3a..cda2998b 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.11", "@types/node": "^20.10.6", "@types/node-fetch": "^2.6.10", - "@typescript-eslint/eslint-plugin": "^6.16.0", + "@typescript-eslint/eslint-plugin": "^6.17.0", "@typescript-eslint/parser": "^6.17.0", "cross-env": "^7.0.3", "eslint": "^8.56.0", From 8d8907f087ffb9eb528165decb1ca267a5d715cd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Jan 2024 12:58:12 +0100 Subject: [PATCH 0665/1076] build(deps): bump serde_json from 1.0.109 to 1.0.110 (#6053) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.109 to 1.0.110. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.109...v1.0.110) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 7c0a6dc5..843ee784 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ borsh = "0.10" clap = "2.33.3" serde = "1.0.194" serde_derive = "1.0.130" -serde_json = "1.0.109" +serde_json = "1.0.110" solana-account-decoder = "=1.17.6" solana-clap-utils = "=1.17.6" solana-cli-config = "=1.17.6" From 787da40a735bd2ba196a1589cdbe253dca98b745 Mon Sep 17 00:00:00 2001 From: Joe C Date: Wed, 3 Jan 2024 10:00:34 -0500 Subject: [PATCH 0666/1076] token js: bump to 0.3.10 (#6018) * token js: bump to 0.3.10 * bump token js in other packages --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index cda2998b..d0b4b935 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -45,7 +45,7 @@ "dependencies": { "@coral-xyz/borsh": "^0.29.0", "@solana/buffer-layout": "^4.0.1", - "@solana/spl-token": "0.3.9", + "@solana/spl-token": "0.3.10", "@solana/web3.js": "^1.87.6", "bn.js": "^5.2.0", "buffer": "^6.0.3", From a69765d57b726171324e61cc5c3555110b843a53 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Jan 2024 13:12:00 +0100 Subject: [PATCH 0667/1076] build(deps): bump serde_json from 1.0.110 to 1.0.111 (#6060) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.110 to 1.0.111. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.110...v1.0.111) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 843ee784..cc7bda80 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ borsh = "0.10" clap = "2.33.3" serde = "1.0.194" serde_derive = "1.0.130" -serde_json = "1.0.110" +serde_json = "1.0.111" solana-account-decoder = "=1.17.6" solana-clap-utils = "=1.17.6" solana-cli-config = "=1.17.6" From 9edb3d26f2ff3fb5ab95292f27e3f1b32aa56cf9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 Jan 2024 22:06:31 +0100 Subject: [PATCH 0668/1076] build(deps-dev): bump rollup from 4.9.2 to 4.9.3 (#6067) Bumps [rollup](https://github.com/rollup/rollup) from 4.9.2 to 4.9.3. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.9.2...v4.9.3) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index d0b4b935..0cc6725e 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.1.1", "rimraf": "^5.0.0", - "rollup": "^4.9.2", + "rollup": "^4.9.3", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.0.0", "typescript": "^5.3.3" From 7cd74227479fa6b4f5ff249dd999d77e6699df20 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 13:02:56 +0100 Subject: [PATCH 0669/1076] build(deps): bump num_enum from 0.7.1 to 0.7.2 (#6072) Bumps [num_enum](https://github.com/illicitonion/num_enum) from 0.7.1 to 0.7.2. - [Commits](https://github.com/illicitonion/num_enum/compare/0.7.1...0.7.2) --- updated-dependencies: - dependency-name: num_enum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index b6452ba0..055b78a4 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,7 +17,7 @@ borsh = "0.10" bytemuck = "1.13" num-derive = "0.4" num-traits = "0.2" -num_enum = "0.7.1" +num_enum = "0.7.2" serde = "1.0.194" serde_derive = "1.0.103" solana-program = "1.17.6" From b9aad5e616b2cbdd77658211a91458092c41f443 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 13:03:56 +0100 Subject: [PATCH 0670/1076] build(deps-dev): bump @types/node from 20.10.6 to 20.10.7 (#6077) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.10.6 to 20.10.7. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 0cc6725e..9cc2d4f8 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.0", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.11", - "@types/node": "^20.10.6", + "@types/node": "^20.10.7", "@types/node-fetch": "^2.6.10", "@typescript-eslint/eslint-plugin": "^6.17.0", "@typescript-eslint/parser": "^6.17.0", From 3554bbc7bd0067b21aff181cd60da3b58de8b909 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 13:04:05 +0100 Subject: [PATCH 0671/1076] build(deps-dev): bump rollup from 4.9.3 to 4.9.4 (#6078) Bumps [rollup](https://github.com/rollup/rollup) from 4.9.3 to 4.9.4. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.9.3...v4.9.4) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 9cc2d4f8..ef17b478 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.1.1", "rimraf": "^5.0.0", - "rollup": "^4.9.3", + "rollup": "^4.9.4", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.0.0", "typescript": "^5.3.3" From 6a3c6d9fc79bb8c1c6138c46ee8055ac867c5009 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 13:04:14 +0100 Subject: [PATCH 0672/1076] build(deps-dev): bump @typescript-eslint/parser from 6.17.0 to 6.18.0 (#6079) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.17.0 to 6.18.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.18.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index ef17b478..6200cd3a 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.10.7", "@types/node-fetch": "^2.6.10", "@typescript-eslint/eslint-plugin": "^6.17.0", - "@typescript-eslint/parser": "^6.17.0", + "@typescript-eslint/parser": "^6.18.0", "cross-env": "^7.0.3", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", From 512635b41924b6b37f9200d76b428d6fb7d9aedc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 13:56:39 +0100 Subject: [PATCH 0673/1076] build(deps): bump serde from 1.0.194 to 1.0.195 (#6075) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.194 to 1.0.195. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.194...v1.0.195) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index cc7bda80..fa1940ea 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "1.0.0" [dependencies] borsh = "0.10" clap = "2.33.3" -serde = "1.0.194" +serde = "1.0.195" serde_derive = "1.0.130" serde_json = "1.0.111" solana-account-decoder = "=1.17.6" diff --git a/program/Cargo.toml b/program/Cargo.toml index 055b78a4..874a55be 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,7 +18,7 @@ bytemuck = "1.13" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.2" -serde = "1.0.194" +serde = "1.0.195" serde_derive = "1.0.103" solana-program = "1.17.6" solana-security-txt = "1.1.1" From 88b803c0097ddea13620e51f738954c0d4212b7c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 13:56:55 +0100 Subject: [PATCH 0674/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.17.0 to 6.18.0 (#6080) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.17.0 to 6.18.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.18.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 6200cd3a..f11d7046 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.11", "@types/node": "^20.10.7", "@types/node-fetch": "^2.6.10", - "@typescript-eslint/eslint-plugin": "^6.17.0", + "@typescript-eslint/eslint-plugin": "^6.18.0", "@typescript-eslint/parser": "^6.18.0", "cross-env": "^7.0.3", "eslint": "^8.56.0", From aa6f404f4f87b145f35a8928075b8ee589bc2403 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 18:50:55 +0100 Subject: [PATCH 0675/1076] build(deps): bump @solana/web3.js from 1.87.6 to 1.88.0 (#6083) * build(deps): bump @solana/web3.js from 1.87.6 to 1.88.0 Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.87.6 to 1.88.0. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.87.6...v1.88.0) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Update account-compression and undo single-pool update --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index f11d7046..7fb7af5c 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -46,7 +46,7 @@ "@coral-xyz/borsh": "^0.29.0", "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "0.3.10", - "@solana/web3.js": "^1.87.6", + "@solana/web3.js": "^1.88.0", "bn.js": "^5.2.0", "buffer": "^6.0.3", "superstruct": "^1.0.3" From 6c003739ba194c6a676beb684aa9497a3f50873b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 12:59:21 +0100 Subject: [PATCH 0676/1076] build(deps-dev): bump @typescript-eslint/parser from 6.18.0 to 6.18.1 (#6092) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.18.0 to 6.18.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.18.1/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 7fb7af5c..7fe82006 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.10.7", "@types/node-fetch": "^2.6.10", "@typescript-eslint/eslint-plugin": "^6.18.0", - "@typescript-eslint/parser": "^6.18.0", + "@typescript-eslint/parser": "^6.18.1", "cross-env": "^7.0.3", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", From 348ba79775f939ab4477579b7b133bd5c839c9c3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 13:23:43 +0100 Subject: [PATCH 0677/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.18.0 to 6.18.1 (#6093) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.18.0 to 6.18.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.18.1/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 7fe82006..2b450ef2 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.11", "@types/node": "^20.10.7", "@types/node-fetch": "^2.6.10", - "@typescript-eslint/eslint-plugin": "^6.18.0", + "@typescript-eslint/eslint-plugin": "^6.18.1", "@typescript-eslint/parser": "^6.18.1", "cross-env": "^7.0.3", "eslint": "^8.56.0", From dc00b62523120073cef558ae67357e1322a48606 Mon Sep 17 00:00:00 2001 From: Joe C Date: Tue, 9 Jan 2024 15:07:14 -0600 Subject: [PATCH 0678/1076] token-js: bump to 0.3.11 (#6096) --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 2b450ef2..75f1f495 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -45,7 +45,7 @@ "dependencies": { "@coral-xyz/borsh": "^0.29.0", "@solana/buffer-layout": "^4.0.1", - "@solana/spl-token": "0.3.10", + "@solana/spl-token": "0.3.11", "@solana/web3.js": "^1.88.0", "bn.js": "^5.2.0", "buffer": "^6.0.3", From 0812dcf050195dc3d8ea47f4e2d31aa41753aca5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Jan 2024 12:07:32 +0100 Subject: [PATCH 0679/1076] build(deps-dev): bump @types/node from 20.10.7 to 20.10.8 (#6102) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.10.7 to 20.10.8. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 75f1f495..ad4a7ec0 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.0", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.11", - "@types/node": "^20.10.7", + "@types/node": "^20.10.8", "@types/node-fetch": "^2.6.10", "@typescript-eslint/eslint-plugin": "^6.18.1", "@typescript-eslint/parser": "^6.18.1", From 0c3d98def5d6351bbea393503c949c67d84aa28c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Jan 2024 12:07:42 +0100 Subject: [PATCH 0680/1076] build(deps-dev): bump @rollup/plugin-typescript from 11.1.5 to 11.1.6 (#6103) Bumps [@rollup/plugin-typescript](https://github.com/rollup/plugins/tree/HEAD/packages/typescript) from 11.1.5 to 11.1.6. - [Changelog](https://github.com/rollup/plugins/blob/master/packages/typescript/CHANGELOG.md) - [Commits](https://github.com/rollup/plugins/commits/typescript-v11.1.6/packages/typescript) --- updated-dependencies: - dependency-name: "@rollup/plugin-typescript" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index ad4a7ec0..29d92e1b 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -58,7 +58,7 @@ "@rollup/plugin-multi-entry": "^6.0.0", "@rollup/plugin-node-resolve": "^15.0.2", "@rollup/plugin-terser": "^0.4.4", - "@rollup/plugin-typescript": "^11.1.0", + "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.11", "@types/node": "^20.10.8", From 1a81d0be58ff400fd99900ace4f9be1ad6e6870c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Jan 2024 12:08:14 +0100 Subject: [PATCH 0681/1076] build(deps-dev): bump eslint-plugin-prettier from 5.1.2 to 5.1.3 (#6104) Bumps [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) from 5.1.2 to 5.1.3. - [Release notes](https://github.com/prettier/eslint-plugin-prettier/releases) - [Changelog](https://github.com/prettier/eslint-plugin-prettier/blob/master/CHANGELOG.md) - [Commits](https://github.com/prettier/eslint-plugin-prettier/compare/v5.1.2...v5.1.3) --- updated-dependencies: - dependency-name: eslint-plugin-prettier dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 29d92e1b..a72270b8 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -68,7 +68,7 @@ "cross-env": "^7.0.3", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", - "eslint-plugin-prettier": "^5.1.2", + "eslint-plugin-prettier": "^5.1.3", "jest": "^29.0.0", "prettier": "^3.1.1", "rimraf": "^5.0.0", From ddcb44d4301481f68ce1162676cbc78b4562f97b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 12:27:18 +0100 Subject: [PATCH 0682/1076] build(deps-dev): bump @types/node from 20.10.8 to 20.11.0 (#6117) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.10.8 to 20.11.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index a72270b8..3c56b774 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.11", - "@types/node": "^20.10.8", + "@types/node": "^20.11.0", "@types/node-fetch": "^2.6.10", "@typescript-eslint/eslint-plugin": "^6.18.1", "@typescript-eslint/parser": "^6.18.1", From d68e6e1a1aa283f620ef6254bb7e32aedefa3a5c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 12:51:54 +0100 Subject: [PATCH 0683/1076] build(deps): bump @solana/web3.js from 1.88.0 to 1.89.0 (#6115) * build(deps): bump @solana/web3.js from 1.88.0 to 1.89.0 Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.88.0 to 1.89.0. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.88.0...v1.89.0) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Properly update packages --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 3c56b774..c86a2127 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -46,7 +46,7 @@ "@coral-xyz/borsh": "^0.29.0", "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "0.3.11", - "@solana/web3.js": "^1.88.0", + "@solana/web3.js": "^1.89.0", "bn.js": "^5.2.0", "buffer": "^6.0.3", "superstruct": "^1.0.3" From 6111b35632bd215b63369fd5063504b79d7b02c0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 12 Jan 2024 13:44:09 +0100 Subject: [PATCH 0684/1076] build(deps-dev): bump rollup from 4.9.4 to 4.9.5 (#6125) Bumps [rollup](https://github.com/rollup/rollup) from 4.9.4 to 4.9.5. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.9.4...v4.9.5) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index c86a2127..73ff3621 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.1.1", "rimraf": "^5.0.0", - "rollup": "^4.9.4", + "rollup": "^4.9.5", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.0.0", "typescript": "^5.3.3" From 7ab6d08543c21a4e7d8a0d54d65884fbdc3e6120 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jan 2024 18:14:57 +0100 Subject: [PATCH 0685/1076] build(deps-dev): bump @types/node from 20.11.0 to 20.11.1 (#6132) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.0 to 20.11.1. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 73ff3621..76bb7d6c 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.11", - "@types/node": "^20.11.0", + "@types/node": "^20.11.1", "@types/node-fetch": "^2.6.10", "@typescript-eslint/eslint-plugin": "^6.18.1", "@typescript-eslint/parser": "^6.18.1", From 77917e251ce627c20ac94733cd14cd52f70f6f78 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jan 2024 18:15:06 +0100 Subject: [PATCH 0686/1076] build(deps-dev): bump prettier from 3.1.1 to 3.2.2 (#6133) Bumps [prettier](https://github.com/prettier/prettier) from 3.1.1 to 3.2.2. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/3.1.1...3.2.2) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 76bb7d6c..7d8383f6 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -70,7 +70,7 @@ "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", "jest": "^29.0.0", - "prettier": "^3.1.1", + "prettier": "^3.2.2", "rimraf": "^5.0.0", "rollup": "^4.9.5", "rollup-plugin-dts": "^6.1.0", From 2b9bb31861bdb058880719f8c9fb0c538eae0942 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Jan 2024 15:20:39 +0100 Subject: [PATCH 0687/1076] build(deps-dev): bump @types/node from 20.11.1 to 20.11.4 (#6139) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.1 to 20.11.4. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 7d8383f6..b0c20340 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.11", - "@types/node": "^20.11.1", + "@types/node": "^20.11.4", "@types/node-fetch": "^2.6.10", "@typescript-eslint/eslint-plugin": "^6.18.1", "@typescript-eslint/parser": "^6.18.1", From 1c1d71da59c453a3df90da87596fccf82e2266eb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Jan 2024 15:20:48 +0100 Subject: [PATCH 0688/1076] build(deps-dev): bump @typescript-eslint/parser from 6.18.1 to 6.19.0 (#6138) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.18.1 to 6.19.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.19.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index b0c20340..5571d9c4 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.11.4", "@types/node-fetch": "^2.6.10", "@typescript-eslint/eslint-plugin": "^6.18.1", - "@typescript-eslint/parser": "^6.18.1", + "@typescript-eslint/parser": "^6.19.0", "cross-env": "^7.0.3", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", From f736d93961b76b24867519d84e6bf09b515856ad Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Jan 2024 15:38:18 +0100 Subject: [PATCH 0689/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.18.1 to 6.19.0 (#6136) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.18.1 to 6.19.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.19.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 5571d9c4..74591b7a 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.11", "@types/node": "^20.11.4", "@types/node-fetch": "^2.6.10", - "@typescript-eslint/eslint-plugin": "^6.18.1", + "@typescript-eslint/eslint-plugin": "^6.19.0", "@typescript-eslint/parser": "^6.19.0", "cross-env": "^7.0.3", "eslint": "^8.56.0", From 3e36788d605e2557dec49bb8130dee50babbf44e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Jan 2024 20:56:16 +0100 Subject: [PATCH 0690/1076] build(deps): bump @solana/web3.js from 1.89.0 to 1.89.1 (#6137) * build(deps): bump @solana/web3.js from 1.89.0 to 1.89.1 Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.89.0 to 1.89.1. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.89.0...v1.89.1) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Fix update --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 74591b7a..677bfe9f 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -46,7 +46,7 @@ "@coral-xyz/borsh": "^0.29.0", "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "0.3.11", - "@solana/web3.js": "^1.89.0", + "@solana/web3.js": "^1.89.1", "bn.js": "^5.2.0", "buffer": "^6.0.3", "superstruct": "^1.0.3" From 3379ed2cd2d59e2c0ae72575c5778ea6521a9c23 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 12:38:09 +0100 Subject: [PATCH 0691/1076] build(deps-dev): bump @types/node from 20.11.4 to 20.11.5 (#6142) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.4 to 20.11.5. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 677bfe9f..04318305 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.11", - "@types/node": "^20.11.4", + "@types/node": "^20.11.5", "@types/node-fetch": "^2.6.10", "@typescript-eslint/eslint-plugin": "^6.19.0", "@typescript-eslint/parser": "^6.19.0", From 698d77b999966215a04ad77dacf90979703c932d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 12:53:02 +0100 Subject: [PATCH 0692/1076] build(deps-dev): bump @types/node-fetch from 2.6.10 to 2.6.11 (#6144) Bumps [@types/node-fetch](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node-fetch) from 2.6.10 to 2.6.11. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node-fetch) --- updated-dependencies: - dependency-name: "@types/node-fetch" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 04318305..2efa5b57 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -62,7 +62,7 @@ "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.11", "@types/node": "^20.11.5", - "@types/node-fetch": "^2.6.10", + "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^6.19.0", "@typescript-eslint/parser": "^6.19.0", "cross-env": "^7.0.3", From 14f870c02b6b247f75174fe6f4c3b8290a4a3bfd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 13:30:28 +0100 Subject: [PATCH 0693/1076] build(deps-dev): bump prettier from 3.2.2 to 3.2.4 (#6143) * build(deps-dev): bump prettier from 3.2.2 to 3.2.4 Bumps [prettier](https://github.com/prettier/prettier) from 3.2.2 to 3.2.4. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/3.2.2...3.2.4) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Run prettier:fix on all packages * Fixup error type --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 2efa5b57..68a650fa 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -70,7 +70,7 @@ "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", "jest": "^29.0.0", - "prettier": "^3.2.2", + "prettier": "^3.2.4", "rimraf": "^5.0.0", "rollup": "^4.9.5", "rollup-plugin-dts": "^6.1.0", From 71049a152b2f21afc348f423728756a5a5ac7439 Mon Sep 17 00:00:00 2001 From: Emanuele Cesena Date: Wed, 17 Jan 2024 17:03:22 -0800 Subject: [PATCH 0694/1076] token 2022: upgrade sdk to 1.17.13 (#6147) * token 2022: upgrade sdk to 1.17.13 * Upgrade all remaining packages --------- Co-authored-by: Jon C --- clients/cli/Cargo.toml | 18 +++++++++--------- program/Cargo.toml | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index fa1940ea..74f321c5 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -14,15 +14,15 @@ clap = "2.33.3" serde = "1.0.195" serde_derive = "1.0.130" serde_json = "1.0.111" -solana-account-decoder = "=1.17.6" -solana-clap-utils = "=1.17.6" -solana-cli-config = "=1.17.6" -solana-cli-output = "=1.17.6" -solana-client = "=1.17.6" -solana-logger = "=1.17.6" -solana-program = "=1.17.6" -solana-remote-wallet = "=1.17.6" -solana-sdk = "=1.17.6" +solana-account-decoder = "=1.17.13" +solana-clap-utils = "=1.17.13" +solana-cli-config = "=1.17.13" +solana-cli-output = "=1.17.13" +solana-client = "=1.17.13" +solana-logger = "=1.17.13" +solana-program = "=1.17.13" +solana-remote-wallet = "=1.17.13" +solana-sdk = "=1.17.13" spl-associated-token-account = { version = "=2.3", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "=1.0.0", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "=4.0", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/program/Cargo.toml b/program/Cargo.toml index 874a55be..38b53280 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -20,7 +20,7 @@ num-traits = "0.2" num_enum = "0.7.2" serde = "1.0.195" serde_derive = "1.0.103" -solana-program = "1.17.6" +solana-program = "1.17.13" solana-security-txt = "1.1.1" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-pod = { version = "0.1", path = "../../libraries/pod", features = ["borsh"] } @@ -31,9 +31,9 @@ bincode = "1.3.1" [dev-dependencies] assert_matches = "1.5.0" proptest = "1.4" -solana-program-test = "1.17.6" -solana-sdk = "1.17.6" -solana-vote-program = "1.17.6" +solana-program-test = "1.17.13" +solana-sdk = "1.17.13" +solana-vote-program = "1.17.13" spl-token = { version = "4.0", path = "../../token/program", features = [ "no-entrypoint" ] } test-case = "3.3" From d0a34bff0419d005876d8186c7a2c84ebda9445d Mon Sep 17 00:00:00 2001 From: Han Yang Date: Fri, 19 Jan 2024 03:37:07 +0800 Subject: [PATCH 0695/1076] stake-pool: make `update_validator_list_balance()` more ergonomic (#6058) * remove unnecessary vote acc slice * nightly fmt * fix clippy * remove redundant check * restore deprecated update_validator_list_balance, rename update_validator_list_balance_chunk * fix tests * option -> result * fmt --- program/src/instruction.rs | 117 ++++++++++++++---- program/tests/decrease.rs | 1 - program/tests/deposit.rs | 1 - program/tests/deposit_edge_cases.rs | 1 - program/tests/force_destake.rs | 3 - program/tests/helpers/mod.rs | 48 ++++--- program/tests/huge_pool.rs | 24 ++-- program/tests/increase.rs | 1 - program/tests/redelegate.rs | 20 --- program/tests/set_epoch_fee.rs | 2 - program/tests/set_withdrawal_fee.rs | 7 -- program/tests/update_stake_pool_balance.rs | 14 +-- .../tests/update_validator_list_balance.rs | 65 +--------- .../update_validator_list_balance_hijack.rs | 39 ++---- program/tests/vsa_remove.rs | 13 +- program/tests/withdraw_edge_cases.rs | 10 -- 16 files changed, 156 insertions(+), 210 deletions(-) diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 8bc41e87..68b09469 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -8,12 +8,13 @@ use { find_stake_program_address, find_transient_stake_program_address, find_withdraw_authority_program_address, inline_mpl_token_metadata::{self, pda::find_metadata_account}, - state::{Fee, FeeType, StakePool, ValidatorList}, + state::{Fee, FeeType, StakePool, ValidatorList, ValidatorStakeInfo}, MAX_VALIDATORS_TO_UPDATE, }, borsh::{BorshDeserialize, BorshSchema, BorshSerialize}, solana_program::{ instruction::{AccountMeta, Instruction}, + program_error::ProgramError, pubkey::Pubkey, stake, system_program, sysvar, }, @@ -1363,6 +1364,10 @@ pub fn decrease_additional_validator_stake_with_vote( /// Creates `UpdateValidatorListBalance` instruction (update validator stake /// account balances) +#[deprecated( + since = "1.1.0", + note = "please use `update_validator_list_balance_chunk`" +)] pub fn update_validator_list_balance( program_id: &Pubkey, stake_pool: &Pubkey, @@ -1423,6 +1428,74 @@ pub fn update_validator_list_balance( } } +/// Creates an `UpdateValidatorListBalance` instruction (update validator stake +/// account balances) to update `validator_list[start_index..start_index + +/// len]`. +/// +/// Returns `Err(ProgramError::InvalidInstructionData)` if: +/// - `start_index..start_index + len` is out of bounds for +/// `validator_list.validators` +pub fn update_validator_list_balance_chunk( + program_id: &Pubkey, + stake_pool: &Pubkey, + stake_pool_withdraw_authority: &Pubkey, + validator_list_address: &Pubkey, + reserve_stake: &Pubkey, + validator_list: &ValidatorList, + len: usize, + start_index: usize, + no_merge: bool, +) -> Result { + let mut accounts = vec![ + AccountMeta::new_readonly(*stake_pool, false), + AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), + AccountMeta::new(*validator_list_address, false), + AccountMeta::new(*reserve_stake, false), + AccountMeta::new_readonly(sysvar::clock::id(), false), + AccountMeta::new_readonly(sysvar::stake_history::id(), false), + AccountMeta::new_readonly(stake::program::id(), false), + ]; + let validator_list_subslice = validator_list + .validators + .get(start_index..start_index.saturating_add(len)) + .ok_or(ProgramError::InvalidInstructionData)?; + accounts.extend(validator_list_subslice.iter().flat_map( + |ValidatorStakeInfo { + vote_account_address, + validator_seed_suffix, + transient_seed_suffix, + .. + }| { + let (validator_stake_account, _) = find_stake_program_address( + program_id, + vote_account_address, + stake_pool, + NonZeroU32::new((*validator_seed_suffix).into()), + ); + let (transient_stake_account, _) = find_transient_stake_program_address( + program_id, + vote_account_address, + stake_pool, + (*transient_seed_suffix).into(), + ); + [ + AccountMeta::new(validator_stake_account, false), + AccountMeta::new(transient_stake_account, false), + ] + }, + )); + Ok(Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::UpdateValidatorListBalance { + start_index: start_index.try_into().unwrap(), + no_merge, + } + .try_to_vec() + .unwrap(), + }) +} + /// Creates `UpdateStakePoolBalance` instruction (pool balance from the stake /// account list balances) pub fn update_stake_pool_balance( @@ -1482,31 +1555,29 @@ pub fn update_stake_pool( stake_pool_address: &Pubkey, no_merge: bool, ) -> (Vec, Vec) { - let vote_accounts: Vec = validator_list - .validators - .iter() - .map(|item| item.vote_account_address) - .collect(); - let (withdraw_authority, _) = find_withdraw_authority_program_address(program_id, stake_pool_address); - let mut update_list_instructions: Vec = vec![]; - let mut start_index = 0; - for accounts_chunk in vote_accounts.chunks(MAX_VALIDATORS_TO_UPDATE) { - update_list_instructions.push(update_validator_list_balance( - program_id, - stake_pool_address, - &withdraw_authority, - &stake_pool.validator_list, - &stake_pool.reserve_stake, - validator_list, - accounts_chunk, - start_index, - no_merge, - )); - start_index = start_index.saturating_add(MAX_VALIDATORS_TO_UPDATE as u32); - } + let update_list_instructions = validator_list + .validators + .chunks(MAX_VALIDATORS_TO_UPDATE) + .enumerate() + .map(|(i, chunk)| { + // unwrap-safety: chunk len and offset are derived + update_validator_list_balance_chunk( + program_id, + stake_pool_address, + &withdraw_authority, + &stake_pool.validator_list, + &stake_pool.reserve_stake, + validator_list, + chunk.len(), + i.saturating_mul(MAX_VALIDATORS_TO_UPDATE), + no_merge, + ) + .unwrap() + }) + .collect(); let final_instructions = vec![ update_stake_pool_balance( diff --git a/program/tests/decrease.rs b/program/tests/decrease.rs index fe6398ae..2e31c644 100644 --- a/program/tests/decrease.rs +++ b/program/tests/decrease.rs @@ -624,7 +624,6 @@ async fn fail_additional_with_increasing() { &mut context.banks_client, &context.payer, &last_blockhash, - &[validator_stake.vote.pubkey()], false, ) .await; diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 74e96194..23bb69dc 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -94,7 +94,6 @@ async fn setup( &mut context.banks_client, &context.payer, &context.last_blockhash, - &[validator_stake_account.vote.pubkey()], false, ) .await; diff --git a/program/tests/deposit_edge_cases.rs b/program/tests/deposit_edge_cases.rs index 86ae9c27..c893e0ce 100644 --- a/program/tests/deposit_edge_cases.rs +++ b/program/tests/deposit_edge_cases.rs @@ -87,7 +87,6 @@ async fn setup( &mut context.banks_client, &context.payer, &context.last_blockhash, - &[validator_stake_account.vote.pubkey()], false, ) .await; diff --git a/program/tests/force_destake.rs b/program/tests/force_destake.rs index f54bd02d..0b86a91f 100644 --- a/program/tests/force_destake.rs +++ b/program/tests/force_destake.rs @@ -155,7 +155,6 @@ async fn success_update() { &mut context.banks_client, &context.payer, &context.last_blockhash, - &[voter_pubkey], false, ) .await; @@ -272,7 +271,6 @@ async fn success_remove_validator() { &mut context.banks_client, &context.payer, &context.last_blockhash, - &[voter_pubkey], false, ) .await; @@ -311,7 +309,6 @@ async fn success_remove_validator() { &mut context.banks_client, &context.payer, &context.last_blockhash, - &[voter_pubkey], false, ) .await; diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 0bf6c1e1..d82dbe5a 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -32,7 +32,7 @@ use { instruction, minimum_delegation, processor::Processor, state::{self, FeeType, FutureEpoch, StakePool, ValidatorList}, - MINIMUM_RESERVE_LAMPORTS, + MAX_VALIDATORS_TO_UPDATE, MINIMUM_RESERVE_LAMPORTS, }, spl_token_2022::{ extension::{ExtensionType, StateWithExtensionsOwned}, @@ -1412,21 +1412,22 @@ impl StakePoolAccounts { banks_client: &mut BanksClient, payer: &Keypair, recent_blockhash: &Hash, - validator_vote_accounts: &[Pubkey], + len: usize, no_merge: bool, ) -> Option { let validator_list = self.get_validator_list(banks_client).await; - let mut instructions = vec![instruction::update_validator_list_balance( + let mut instructions = vec![instruction::update_validator_list_balance_chunk( &id(), &self.stake_pool.pubkey(), &self.withdraw_authority, &self.validator_list.pubkey(), &self.reserve_stake.pubkey(), &validator_list, - validator_vote_accounts, + len, 0, no_merge, - )]; + ) + .unwrap()]; self.maybe_add_compute_budget_instruction(&mut instructions); let transaction = Transaction::new_signed_with_payer( &instructions, @@ -1501,22 +1502,31 @@ impl StakePoolAccounts { banks_client: &mut BanksClient, payer: &Keypair, recent_blockhash: &Hash, - validator_vote_accounts: &[Pubkey], no_merge: bool, ) -> Option { let validator_list = self.get_validator_list(banks_client).await; - let mut instructions = vec![ - instruction::update_validator_list_balance( - &id(), - &self.stake_pool.pubkey(), - &self.withdraw_authority, - &self.validator_list.pubkey(), - &self.reserve_stake.pubkey(), - &validator_list, - validator_vote_accounts, - 0, - no_merge, - ), + let mut instructions = vec![]; + for (i, chunk) in validator_list + .validators + .chunks(MAX_VALIDATORS_TO_UPDATE) + .enumerate() + { + instructions.push( + instruction::update_validator_list_balance_chunk( + &id(), + &self.stake_pool.pubkey(), + &self.withdraw_authority, + &self.validator_list.pubkey(), + &self.reserve_stake.pubkey(), + &validator_list, + chunk.len(), + i * MAX_VALIDATORS_TO_UPDATE, + no_merge, + ) + .unwrap(), + ); + } + instructions.extend([ instruction::update_stake_pool_balance( &id(), &self.stake_pool.pubkey(), @@ -1532,7 +1542,7 @@ impl StakePoolAccounts { &self.stake_pool.pubkey(), &self.validator_list.pubkey(), ), - ]; + ]); self.maybe_add_compute_budget_instruction(&mut instructions); let transaction = Transaction::new_signed_with_payer( &instructions, diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index e87d3339..f9c44b53 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -172,7 +172,7 @@ async fn setup( #[test_case(MAX_POOL_SIZE; "no-compute-budget")] #[tokio::test] async fn update(max_validators: u32) { - let (mut context, stake_pool_accounts, vote_account_pubkeys, _, _, _, _) = + let (mut context, stake_pool_accounts, _, _, _, _, _) = setup(max_validators, max_validators, STAKE_AMOUNT).await; let error = stake_pool_accounts @@ -180,7 +180,7 @@ async fn update(max_validators: u32) { &mut context.banks_client, &context.payer, &context.last_blockhash, - &vote_account_pubkeys[0..MAX_VALIDATORS_TO_UPDATE], + MAX_VALIDATORS_TO_UPDATE, false, /* no_merge */ ) .await; @@ -335,23 +335,24 @@ async fn remove_validator_from_pool(max_validators: u32) { &mut context.banks_client, &context.payer, &context.last_blockhash, - &[first_vote], + 1, false, /* no_merge */ ) .await; assert!(error.is_none(), "{:?}", error); - let mut instructions = vec![instruction::update_validator_list_balance( + let mut instructions = vec![instruction::update_validator_list_balance_chunk( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.withdraw_authority, &stake_pool_accounts.validator_list.pubkey(), &stake_pool_accounts.reserve_stake.pubkey(), &validator_list, - &[middle_vote], - middle_index as u32, + 1, + middle_index, /* no_merge = */ false, - )]; + ) + .unwrap()]; stake_pool_accounts.maybe_add_compute_budget_instruction(&mut instructions); let transaction = Transaction::new_signed_with_payer( &instructions, @@ -366,17 +367,18 @@ async fn remove_validator_from_pool(max_validators: u32) { .err(); assert!(error.is_none(), "{:?}", error); - let mut instructions = vec![instruction::update_validator_list_balance( + let mut instructions = vec![instruction::update_validator_list_balance_chunk( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.withdraw_authority, &stake_pool_accounts.validator_list.pubkey(), &stake_pool_accounts.reserve_stake.pubkey(), &validator_list, - &[last_vote], - last_index as u32, + 1, + last_index, /* no_merge = */ false, - )]; + ) + .unwrap()]; stake_pool_accounts.maybe_add_compute_budget_instruction(&mut instructions); let transaction = Transaction::new_signed_with_payer( &instructions, diff --git a/program/tests/increase.rs b/program/tests/increase.rs index bd83885e..67fac5f1 100644 --- a/program/tests/increase.rs +++ b/program/tests/increase.rs @@ -548,7 +548,6 @@ async fn fail_additional_with_decreasing() { &mut context.banks_client, &context.payer, &last_blockhash, - &[validator_stake.vote.pubkey()], false, ) .await; diff --git a/program/tests/redelegate.rs b/program/tests/redelegate.rs index a9f12f5f..3256eef1 100644 --- a/program/tests/redelegate.rs +++ b/program/tests/redelegate.rs @@ -92,10 +92,6 @@ async fn setup( &mut context.banks_client, &context.payer, &context.last_blockhash, - &[ - source_validator_stake.vote.pubkey(), - destination_validator_stake.vote.pubkey(), - ], false, ) .await; @@ -296,10 +292,6 @@ async fn success() { &mut context.banks_client, &context.payer, &last_blockhash, - &[ - source_validator_stake.vote.pubkey(), - destination_validator_stake.vote.pubkey(), - ], false, ) .await; @@ -548,10 +540,6 @@ async fn success_with_increasing_stake() { &mut context.banks_client, &context.payer, &last_blockhash, - &[ - source_validator_stake.vote.pubkey(), - destination_validator_stake.vote.pubkey(), - ], false, ) .await; @@ -638,10 +626,6 @@ async fn fail_with_decreasing_stake() { &mut context.banks_client, &context.payer, &last_blockhash, - &[ - source_validator_stake.vote.pubkey(), - destination_validator_stake.vote.pubkey(), - ], false, ) .await; @@ -1059,10 +1043,6 @@ async fn fail_redelegate_twice() { &mut context.banks_client, &context.payer, &last_blockhash, - &[ - source_validator_stake.vote.pubkey(), - destination_validator_stake.vote.pubkey(), - ], false, ) .await; diff --git a/program/tests/set_epoch_fee.rs b/program/tests/set_epoch_fee.rs index db3b039a..533cad88 100644 --- a/program/tests/set_epoch_fee.rs +++ b/program/tests/set_epoch_fee.rs @@ -87,7 +87,6 @@ async fn success() { &mut context.banks_client, &context.payer, &context.last_blockhash, - &[], false, ) .await; @@ -112,7 +111,6 @@ async fn success() { &mut context.banks_client, &context.payer, &last_blockhash, - &[], false, ) .await; diff --git a/program/tests/set_withdrawal_fee.rs b/program/tests/set_withdrawal_fee.rs index 5c548b0a..a88a9ecc 100644 --- a/program/tests/set_withdrawal_fee.rs +++ b/program/tests/set_withdrawal_fee.rs @@ -117,7 +117,6 @@ async fn success() { &mut context.banks_client, &context.payer, &context.last_blockhash, - &[], false, ) .await; @@ -150,7 +149,6 @@ async fn success() { &mut context.banks_client, &context.payer, &last_blockhash, - &[], false, ) .await; @@ -242,7 +240,6 @@ async fn success_fee_cannot_increase_more_than_once() { &mut context.banks_client, &context.payer, &context.last_blockhash, - &[], false, ) .await; @@ -275,7 +272,6 @@ async fn success_fee_cannot_increase_more_than_once() { &mut context.banks_client, &context.payer, &last_blockhash, - &[], false, ) .await; @@ -443,7 +439,6 @@ async fn success_reset_fee_after_one_epoch() { &mut context.banks_client, &context.payer, &context.last_blockhash, - &[], false, ) .await; @@ -600,7 +595,6 @@ async fn success_increase_fee_from_0() { &mut context.banks_client, &context.payer, &context.last_blockhash, - &[], false, ) .await; @@ -633,7 +627,6 @@ async fn success_increase_fee_from_0() { &mut context.banks_client, &context.payer, &last_blockhash, - &[], false, ) .await; diff --git a/program/tests/update_stake_pool_balance.rs b/program/tests/update_stake_pool_balance.rs index 50f9c3ee..92dd797e 100644 --- a/program/tests/update_stake_pool_balance.rs +++ b/program/tests/update_stake_pool_balance.rs @@ -5,9 +5,7 @@ mod helpers; use { helpers::*, - solana_program::{ - borsh0_10::try_from_slice_unchecked, instruction::InstructionError, pubkey::Pubkey, - }, + solana_program::{borsh0_10::try_from_slice_unchecked, instruction::InstructionError}, solana_program_test::*, solana_sdk::{ hash::Hash, @@ -180,11 +178,6 @@ async fn success() { &mut context.banks_client, &context.payer, &last_blockhash, - stake_accounts - .iter() - .map(|v| v.vote.pubkey()) - .collect::>() - .as_slice(), false, ) .await; @@ -293,11 +286,6 @@ async fn success_absorbing_extra_lamports() { &mut context.banks_client, &context.payer, &last_blockhash, - stake_accounts - .iter() - .map(|v| v.vote.pubkey()) - .collect::>() - .as_slice(), false, ) .await; diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index 89d6b5f6..9a604359 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -5,7 +5,7 @@ mod helpers; use { helpers::*, - solana_program::{borsh0_10::try_from_slice_unchecked, program_pack::Pack, pubkey::Pubkey}, + solana_program::{borsh0_10::try_from_slice_unchecked, program_pack::Pack}, solana_program_test::*, solana_sdk::{hash::Hash, signature::Signer, stake::state::StakeStateV2}, spl_stake_pool::{ @@ -107,11 +107,6 @@ async fn setup( &mut context.banks_client, &context.payer, &context.last_blockhash, - stake_accounts - .iter() - .map(|v| v.vote.pubkey()) - .collect::>() - .as_slice(), false, ) .await; @@ -140,11 +135,6 @@ async fn setup( &mut context.banks_client, &context.payer, &last_blockhash, - stake_accounts - .iter() - .map(|v| v.vote.pubkey()) - .collect::>() - .as_slice(), false, ) .await; @@ -223,11 +213,6 @@ async fn success_with_normal() { &mut context.banks_client, &context.payer, &last_blockhash, - stake_accounts - .iter() - .map(|v| v.vote.pubkey()) - .collect::>() - .as_slice(), false, ) .await; @@ -299,11 +284,6 @@ async fn merge_into_reserve() { &mut context.banks_client, &context.payer, &last_blockhash, - stake_accounts - .iter() - .map(|v| v.vote.pubkey()) - .collect::>() - .as_slice(), false, ) .await; @@ -339,11 +319,6 @@ async fn merge_into_reserve() { &mut context.banks_client, &context.payer, &last_blockhash, - stake_accounts - .iter() - .map(|v| v.vote.pubkey()) - .collect::>() - .as_slice(), false, ) .await; @@ -435,11 +410,6 @@ async fn merge_into_validator_stake() { &mut context.banks_client, &context.payer, &last_blockhash, - stake_accounts - .iter() - .map(|v| v.vote.pubkey()) - .collect::>() - .as_slice(), false, ) .await; @@ -475,11 +445,6 @@ async fn merge_into_validator_stake() { &mut context.banks_client, &context.payer, &last_blockhash, - stake_accounts - .iter() - .map(|v| v.vote.pubkey()) - .collect::>() - .as_slice(), false, ) .await; @@ -591,11 +556,6 @@ async fn merge_transient_stake_after_remove() { &mut context.banks_client, &context.payer, &last_blockhash, - stake_accounts - .iter() - .map(|v| v.vote.pubkey()) - .collect::>() - .as_slice(), true, ) .await; @@ -628,11 +588,7 @@ async fn merge_transient_stake_after_remove() { &mut context.banks_client, &context.payer, &last_blockhash, - stake_accounts - .iter() - .map(|v| v.vote.pubkey()) - .collect::>() - .as_slice(), + validator_list.validators.len(), false, ) .await; @@ -706,16 +662,8 @@ async fn merge_transient_stake_after_remove() { #[tokio::test] async fn success_with_burned_tokens() { let num_validators = 5; - let ( - mut context, - last_blockhash, - stake_pool_accounts, - stake_accounts, - deposit_accounts, - _, - _, - mut slot, - ) = setup(num_validators).await; + let (mut context, last_blockhash, stake_pool_accounts, _, deposit_accounts, _, _, mut slot) = + setup(num_validators).await; let mint_info = get_account( &mut context.banks_client, @@ -762,11 +710,6 @@ async fn success_with_burned_tokens() { &mut context.banks_client, &context.payer, &last_blockhash, - stake_accounts - .iter() - .map(|v| v.vote.pubkey()) - .collect::>() - .as_slice(), false, ) .await; diff --git a/program/tests/update_validator_list_balance_hijack.rs b/program/tests/update_validator_list_balance_hijack.rs index ad444b20..973dc59c 100644 --- a/program/tests/update_validator_list_balance_hijack.rs +++ b/program/tests/update_validator_list_balance_hijack.rs @@ -1,6 +1,8 @@ #![allow(clippy::arithmetic_side_effects)] #![cfg(feature = "test-sbf")] +use spl_stake_pool::instruction; + mod helpers; use { @@ -17,8 +19,7 @@ use { }, spl_stake_pool::{ error::StakePoolError, find_stake_program_address, find_transient_stake_program_address, - find_withdraw_authority_program_address, id, instruction, state::StakePool, - MINIMUM_RESERVE_LAMPORTS, + find_withdraw_authority_program_address, id, state::StakePool, MINIMUM_RESERVE_LAMPORTS, }, std::num::NonZeroU32, }; @@ -109,11 +110,6 @@ async fn setup( &mut context.banks_client, &context.payer, &context.last_blockhash, - stake_accounts - .iter() - .map(|v| v.vote.pubkey()) - .collect::>() - .as_slice(), false, ) .await; @@ -143,11 +139,6 @@ async fn setup( &mut context.banks_client, &context.payer, &last_blockhash, - stake_accounts - .iter() - .map(|v| v.vote.pubkey()) - .collect::>() - .as_slice(), false, ) .await; @@ -251,17 +242,18 @@ async fn check_ignored_hijacked_transient_stake( .0; let transaction = Transaction::new_signed_with_payer( &[ - instruction::update_validator_list_balance( + instruction::update_validator_list_balance_chunk( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.withdraw_authority, &stake_pool_accounts.validator_list.pubkey(), &stake_pool_accounts.reserve_stake.pubkey(), &validator_list, - &[stake_account.vote.pubkey()], + 1, 0, /* no_merge = */ false, - ), + ) + .unwrap(), system_instruction::transfer( &context.payer.pubkey(), &transient_stake_address, @@ -310,11 +302,6 @@ async fn check_ignored_hijacked_transient_stake( &mut context.banks_client, &context.payer, &last_blockhash, - stake_accounts - .iter() - .map(|v| v.vote.pubkey()) - .collect::>() - .as_slice(), false, ) .await; @@ -420,17 +407,18 @@ async fn check_ignored_hijacked_validator_stake( .await; let transaction = Transaction::new_signed_with_payer( &[ - instruction::update_validator_list_balance( + instruction::update_validator_list_balance_chunk( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.withdraw_authority, &stake_pool_accounts.validator_list.pubkey(), &stake_pool_accounts.reserve_stake.pubkey(), &validator_list, - &[stake_account.vote.pubkey()], + 1, 0, /* no_merge = */ false, - ), + ) + .unwrap(), system_instruction::transfer( &context.payer.pubkey(), &stake_account.stake_account, @@ -479,11 +467,6 @@ async fn check_ignored_hijacked_validator_stake( &mut context.banks_client, &context.payer, &last_blockhash, - stake_accounts - .iter() - .map(|v| v.vote.pubkey()) - .collect::>() - .as_slice(), false, ) .await; diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index febada59..0a90f344 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -87,7 +87,6 @@ async fn success() { &mut context.banks_client, &context.payer, &context.last_blockhash, - &[validator_stake.vote.pubkey()], false, ) .await; @@ -267,7 +266,6 @@ async fn fail_double_remove() { &mut context.banks_client, &context.payer, &context.last_blockhash, - &[validator_stake.vote.pubkey()], false, ) .await; @@ -567,7 +565,6 @@ async fn success_with_deactivating_transient_stake() { &mut context.banks_client, &context.payer, &context.last_blockhash, - &[validator_stake.vote.pubkey()], false, ) .await; @@ -629,7 +626,6 @@ async fn success_resets_preferred_validator() { &mut context.banks_client, &context.payer, &context.last_blockhash, - &[validator_stake.vote.pubkey()], false, ) .await; @@ -701,7 +697,6 @@ async fn success_with_hijacked_transient_account() { &mut context.banks_client, &context.payer, &context.last_blockhash, - &[validator_stake.vote.pubkey()], false, ) .await; @@ -739,17 +734,18 @@ async fn success_with_hijacked_transient_account() { .0; let transaction = Transaction::new_signed_with_payer( &[ - instruction::update_validator_list_balance( + instruction::update_validator_list_balance_chunk( &id(), &stake_pool_accounts.stake_pool.pubkey(), &stake_pool_accounts.withdraw_authority, &stake_pool_accounts.validator_list.pubkey(), &stake_pool_accounts.reserve_stake.pubkey(), &validator_list, - &[validator_stake.vote.pubkey()], + 1, 0, /* no_merge = */ false, - ), + ) + .unwrap(), system_instruction::transfer( &context.payer.pubkey(), &transient_stake_address, @@ -822,7 +818,6 @@ async fn success_with_hijacked_transient_account() { &mut context.banks_client, &context.payer, &context.last_blockhash, - &[validator_stake.vote.pubkey()], false, ) .await; diff --git a/program/tests/withdraw_edge_cases.rs b/program/tests/withdraw_edge_cases.rs index 5390bce5..919d2107 100644 --- a/program/tests/withdraw_edge_cases.rs +++ b/program/tests/withdraw_edge_cases.rs @@ -53,7 +53,6 @@ async fn fail_remove_validator() { &mut context.banks_client, &context.payer, &context.last_blockhash, - &[validator_stake.vote.pubkey()], false, ) .await; @@ -119,7 +118,6 @@ async fn success_remove_validator(multiple: u64) { &mut context.banks_client, &context.payer, &context.last_blockhash, - &[validator_stake.vote.pubkey()], false, ) .await; @@ -163,7 +161,6 @@ async fn success_remove_validator(multiple: u64) { &mut context.banks_client, &context.payer, &last_blockhash, - &[validator_stake.vote.pubkey()], false, ) .await; @@ -271,7 +268,6 @@ async fn fail_with_reserve() { &mut context.banks_client, &context.payer, &context.last_blockhash, - &[validator_stake.vote.pubkey()], false, ) .await; @@ -342,7 +338,6 @@ async fn success_with_reserve() { &mut context.banks_client, &context.payer, &context.last_blockhash, - &[validator_stake.vote.pubkey()], false, ) .await; @@ -768,7 +763,6 @@ async fn success_with_small_preferred_withdraw() { &mut context.banks_client, &context.payer, &last_blockhash, - &[validator_stake.vote.pubkey()], false, ) .await; @@ -843,10 +837,6 @@ async fn success_with_small_preferred_withdraw() { &mut context.banks_client, &context.payer, &last_blockhash, - &[ - validator_stake.vote.pubkey(), - preferred_validator.vote.pubkey(), - ], false, ) .await; From 3e6d032f76a289192802599251214689992c0ac5 Mon Sep 17 00:00:00 2001 From: Jon C Date: Fri, 19 Jan 2024 13:57:45 +0100 Subject: [PATCH 0696/1076] stake-pool: Fix flaky test (#6151) --- program/tests/update_validator_list_balance.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index 9a604359..dc339203 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -661,7 +661,7 @@ async fn merge_transient_stake_after_remove() { #[tokio::test] async fn success_with_burned_tokens() { - let num_validators = 5; + let num_validators = 1; let (mut context, last_blockhash, stake_pool_accounts, _, deposit_accounts, _, _, mut slot) = setup(num_validators).await; @@ -693,6 +693,10 @@ async fn success_with_burned_tokens() { .await .unwrap(); + let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; + slot += slots_per_epoch; + context.warp_to_slot(slot).unwrap(); + let mint_info = get_account( &mut context.banks_client, &stake_pool_accounts.pool_mint.pubkey(), @@ -701,10 +705,6 @@ async fn success_with_burned_tokens() { let mint = Mint::unpack(&mint_info.data).unwrap(); assert_ne!(mint.supply, stake_pool.pool_token_supply); - let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; - slot += slots_per_epoch; - context.warp_to_slot(slot).unwrap(); - stake_pool_accounts .update_all( &mut context.banks_client, From a66d3f06937ca5951fd98a2bd7f26e4b03d7518a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jan 2024 12:59:14 +0100 Subject: [PATCH 0697/1076] build(deps-dev): bump ts-jest from 29.1.1 to 29.1.2 (#6157) Bumps [ts-jest](https://github.com/kulshekhar/ts-jest) from 29.1.1 to 29.1.2. - [Release notes](https://github.com/kulshekhar/ts-jest/releases) - [Changelog](https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md) - [Commits](https://github.com/kulshekhar/ts-jest/compare/v29.1.1...v29.1.2) --- updated-dependencies: - dependency-name: ts-jest dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 68a650fa..91062774 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -74,7 +74,7 @@ "rimraf": "^5.0.0", "rollup": "^4.9.5", "rollup-plugin-dts": "^6.1.0", - "ts-jest": "^29.0.0", + "ts-jest": "^29.1.2", "typescript": "^5.3.3" }, "jest": { From ff6730857b3d88ba9cd6f5219dd3c4fcbcb0d291 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jan 2024 12:59:52 +0100 Subject: [PATCH 0698/1076] build(deps-dev): bump rollup from 4.9.5 to 4.9.6 (#6158) Bumps [rollup](https://github.com/rollup/rollup) from 4.9.5 to 4.9.6. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.9.5...v4.9.6) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 91062774..6e8bbec3 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.2.4", "rimraf": "^5.0.0", - "rollup": "^4.9.5", + "rollup": "^4.9.6", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.1.2", "typescript": "^5.3.3" From 944ce9d7ea92f1e7393a4a92549527da743e0803 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jan 2024 12:29:43 +0100 Subject: [PATCH 0699/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.19.0 to 6.19.1 (#6167) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.19.0 to 6.19.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.19.1/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 6e8bbec3..3e5eb84e 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.11", "@types/node": "^20.11.5", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^6.19.0", + "@typescript-eslint/eslint-plugin": "^6.19.1", "@typescript-eslint/parser": "^6.19.0", "cross-env": "^7.0.3", "eslint": "^8.56.0", From 48ad10ddf431bc02a6599f0beb1c5f73c20a9e32 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jan 2024 12:46:06 +0100 Subject: [PATCH 0700/1076] build(deps-dev): bump @typescript-eslint/parser from 6.19.0 to 6.19.1 (#6168) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.19.0 to 6.19.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.19.1/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 3e5eb84e..8c0bbdee 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.11.5", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^6.19.1", - "@typescript-eslint/parser": "^6.19.0", + "@typescript-eslint/parser": "^6.19.1", "cross-env": "^7.0.3", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", From 7484d0675e9ef7b2d039d4f82f1f999ccb8c5539 Mon Sep 17 00:00:00 2001 From: Jon C Date: Tue, 23 Jan 2024 14:32:17 +0100 Subject: [PATCH 0701/1076] stake-pool-test: Fix updating blockhash, force a new one (#6169) --- program/tests/update_validator_list_balance.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index dc339203..31b4e484 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -141,7 +141,7 @@ async fn setup( let last_blockhash = context .banks_client - .get_new_latest_blockhash(&context.last_blockhash) + .get_new_latest_blockhash(&last_blockhash) .await .unwrap(); @@ -697,6 +697,12 @@ async fn success_with_burned_tokens() { slot += slots_per_epoch; context.warp_to_slot(slot).unwrap(); + let last_blockhash = context + .banks_client + .get_new_latest_blockhash(&last_blockhash) + .await + .unwrap(); + let mint_info = get_account( &mut context.banks_client, &stake_pool_accounts.pool_mint.pubkey(), From fcefb7a86bbd1a47271a94ae10cba428bd86f1e2 Mon Sep 17 00:00:00 2001 From: Han Yang Date: Wed, 24 Jan 2024 14:12:06 +0800 Subject: [PATCH 0702/1076] stake-pool-cli: don't send `UpdateValidatorListBalance` transactions for subslices of validator list that have already been updated (#6059) * remove unnecessary vote acc slice * nightly fmt * fix clippy * update stale validator_list_balance only if not force * merge * fmt * merge conflict * restore stale ixs, add fresh flag to update * fmt * fresh -> stale_only, update --force help --- clients/cli/src/main.rs | 52 +++++++++++++------ program/src/instruction.rs | 104 ++++++++++++++++++++++++++++++++++++- 2 files changed, 138 insertions(+), 18 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 60ab61c6..bb20ffde 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -430,7 +430,7 @@ fn command_vsa_add( } if !config.no_update { - command_update(config, stake_pool_address, false, false)?; + command_update(config, stake_pool_address, false, false, false)?; } // iterate until a free account is found @@ -488,7 +488,7 @@ fn command_vsa_remove( vote_account: &Pubkey, ) -> CommandResult { if !config.no_update { - command_update(config, stake_pool_address, false, false)?; + command_update(config, stake_pool_address, false, false, false)?; } let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; @@ -535,7 +535,7 @@ fn command_increase_validator_stake( ) -> CommandResult { let lamports = native_token::sol_to_lamports(amount); if !config.no_update { - command_update(config, stake_pool_address, false, false)?; + command_update(config, stake_pool_address, false, false, false)?; } let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; @@ -574,7 +574,7 @@ fn command_decrease_validator_stake( ) -> CommandResult { let lamports = native_token::sol_to_lamports(amount); if !config.no_update { - command_update(config, stake_pool_address, false, false)?; + command_update(config, stake_pool_address, false, false, false)?; } let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; @@ -671,7 +671,7 @@ fn command_deposit_stake( referrer_token_account: &Option, ) -> CommandResult { if !config.no_update { - command_update(config, stake_pool_address, false, false)?; + command_update(config, stake_pool_address, false, false, false)?; } let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; @@ -802,7 +802,7 @@ fn command_deposit_all_stake( referrer_token_account: &Option, ) -> CommandResult { if !config.no_update { - command_update(config, stake_pool_address, false, false)?; + command_update(config, stake_pool_address, false, false, false)?; } let stake_addresses = get_all_stake(&config.rpc_client, stake_authority)?; @@ -945,7 +945,7 @@ fn command_deposit_sol( amount: f64, ) -> CommandResult { if !config.no_update { - command_update(config, stake_pool_address, false, false)?; + command_update(config, stake_pool_address, false, false, false)?; } let amount = native_token::sol_to_lamports(amount); @@ -1139,6 +1139,7 @@ fn command_update( stake_pool_address: &Pubkey, force: bool, no_merge: bool, + stale_only: bool, ) -> CommandResult { if config.no_update { println!("Update requested, but --no-update flag specified, so doing nothing"); @@ -1158,14 +1159,24 @@ fn command_update( let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?; - let (mut update_list_instructions, final_instructions) = + let (mut update_list_instructions, final_instructions) = if stale_only { + spl_stake_pool::instruction::update_stale_stake_pool( + &spl_stake_pool::id(), + &stake_pool, + &validator_list, + stake_pool_address, + no_merge, + epoch_info.epoch, + ) + } else { spl_stake_pool::instruction::update_stake_pool( &spl_stake_pool::id(), &stake_pool, &validator_list, stake_pool_address, no_merge, - ); + ) + }; let update_list_instructions_len = update_list_instructions.len(); if update_list_instructions_len > 0 { @@ -1360,7 +1371,7 @@ fn command_withdraw_stake( pool_amount: f64, ) -> CommandResult { if !config.no_update { - command_update(config, stake_pool_address, false, false)?; + command_update(config, stake_pool_address, false, false, false)?; } let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; @@ -1631,7 +1642,7 @@ fn command_withdraw_sol( pool_amount: f64, ) -> CommandResult { if !config.no_update { - command_update(config, stake_pool_address, false, false)?; + command_update(config, stake_pool_address, false, false, false)?; } let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; @@ -1748,7 +1759,7 @@ fn command_set_manager( new_fee_receiver: &Option, ) -> CommandResult { if !config.no_update { - command_update(config, stake_pool_address, false, false)?; + command_update(config, stake_pool_address, false, false, false)?; } let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; @@ -1800,7 +1811,7 @@ fn command_set_staker( new_staker: &Pubkey, ) -> CommandResult { if !config.no_update { - command_update(config, stake_pool_address, false, false)?; + command_update(config, stake_pool_address, false, false, false)?; } let mut signers = vec![config.fee_payer.as_ref(), config.manager.as_ref()]; unique_signers!(signers); @@ -1825,7 +1836,7 @@ fn command_set_funding_authority( funding_type: FundingType, ) -> CommandResult { if !config.no_update { - command_update(config, stake_pool_address, false, false)?; + command_update(config, stake_pool_address, false, false, false)?; } let mut signers = vec![config.fee_payer.as_ref(), config.manager.as_ref()]; unique_signers!(signers); @@ -1850,7 +1861,7 @@ fn command_set_fee( new_fee: FeeType, ) -> CommandResult { if !config.no_update { - command_update(config, stake_pool_address, false, false)?; + command_update(config, stake_pool_address, false, false, false)?; } let mut signers = vec![config.fee_payer.as_ref(), config.manager.as_ref()]; unique_signers!(signers); @@ -2418,7 +2429,7 @@ fn main() { Arg::with_name("force") .long("force") .takes_value(false) - .help("Update all balances, even if it has already been performed this epoch."), + .help("Update balances, even if it has already been performed this epoch."), ) .arg( Arg::with_name("no_merge") @@ -2426,6 +2437,12 @@ fn main() { .takes_value(false) .help("Do not automatically merge transient stakes. Useful if the stake pool is in an expected state, but the balances still need to be updated."), ) + .arg( + Arg::with_name("stale_only") + .long("stale-only") + .takes_value(false) + .help("If set, only updates validator list balances that have not been updated for this epoch. Otherwise, updates all validator balances on the validator list."), + ) ) .subcommand(SubCommand::with_name("withdraw-stake") .about("Withdraw active stake from the stake pool in exchange for pool tokens") @@ -2903,7 +2920,8 @@ fn main() { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); let no_merge = arg_matches.is_present("no_merge"); let force = arg_matches.is_present("force"); - command_update(&config, &stake_pool_address, force, no_merge) + let stale_only = arg_matches.is_present("stale_only"); + command_update(&config, &stake_pool_address, force, no_merge, stale_only) } ("withdraw-stake", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 68b09469..4b8afd8e 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -16,7 +16,9 @@ use { instruction::{AccountMeta, Instruction}, program_error::ProgramError, pubkey::Pubkey, - stake, system_program, sysvar, + stake, + stake_history::Epoch, + system_program, sysvar, }, std::num::NonZeroU32, }; @@ -1496,6 +1498,47 @@ pub fn update_validator_list_balance_chunk( }) } +/// Creates `UpdateValidatorListBalance` instruction (update validator stake +/// account balances) +/// +/// Returns `None` if all validators in the given chunk has already been updated +/// for this epoch, returns the required instruction otherwise. +pub fn update_stale_validator_list_balance_chunk( + program_id: &Pubkey, + stake_pool: &Pubkey, + stake_pool_withdraw_authority: &Pubkey, + validator_list_address: &Pubkey, + reserve_stake: &Pubkey, + validator_list: &ValidatorList, + len: usize, + start_index: usize, + no_merge: bool, + current_epoch: Epoch, +) -> Result, ProgramError> { + let validator_list_subslice = validator_list + .validators + .get(start_index..start_index.saturating_add(len)) + .ok_or(ProgramError::InvalidInstructionData)?; + if validator_list_subslice.iter().all(|info| { + let last_update_epoch: u64 = info.last_update_epoch.into(); + last_update_epoch >= current_epoch + }) { + return Ok(None); + } + update_validator_list_balance_chunk( + program_id, + stake_pool, + stake_pool_withdraw_authority, + validator_list_address, + reserve_stake, + validator_list, + len, + start_index, + no_merge, + ) + .map(Some) +} + /// Creates `UpdateStakePoolBalance` instruction (pool balance from the stake /// account list balances) pub fn update_stake_pool_balance( @@ -1599,6 +1642,65 @@ pub fn update_stake_pool( (update_list_instructions, final_instructions) } +/// Creates the `UpdateValidatorListBalance` instructions only for validators on +/// `validator_list` that have not been updated for this epoch, and the +/// `UpdateStakePoolBalance` instruction for fully updating the stake pool. +/// +/// Basically same as [`update_stake_pool`], but skips validators that are +/// already updated for this epoch +pub fn update_stale_stake_pool( + program_id: &Pubkey, + stake_pool: &StakePool, + validator_list: &ValidatorList, + stake_pool_address: &Pubkey, + no_merge: bool, + current_epoch: Epoch, +) -> (Vec, Vec) { + let (withdraw_authority, _) = + find_withdraw_authority_program_address(program_id, stake_pool_address); + + let update_list_instructions = validator_list + .validators + .chunks(MAX_VALIDATORS_TO_UPDATE) + .enumerate() + .filter_map(|(i, chunk)| { + // unwrap-safety: chunk len and offset are derived + update_stale_validator_list_balance_chunk( + program_id, + stake_pool_address, + &withdraw_authority, + &stake_pool.validator_list, + &stake_pool.reserve_stake, + validator_list, + chunk.len(), + i.saturating_mul(MAX_VALIDATORS_TO_UPDATE), + no_merge, + current_epoch, + ) + .unwrap() + }) + .collect(); + + let final_instructions = vec![ + update_stake_pool_balance( + program_id, + stake_pool_address, + &withdraw_authority, + &stake_pool.validator_list, + &stake_pool.reserve_stake, + &stake_pool.manager_fee_account, + &stake_pool.pool_mint, + &stake_pool.token_program_id, + ), + cleanup_removed_validator_entries( + program_id, + stake_pool_address, + &stake_pool.validator_list, + ), + ]; + (update_list_instructions, final_instructions) +} + fn deposit_stake_internal( program_id: &Pubkey, stake_pool: &Pubkey, From a4cd4475d5bcc69f5c013c681638f013efac333d Mon Sep 17 00:00:00 2001 From: Jon C Date: Wed, 24 Jan 2024 12:33:48 +0100 Subject: [PATCH 0703/1076] stake-pool: Ceiling all fee calculations (HAL-01) (#6153) stake-pool: Ceiling all fee calculations --- program/src/state.rs | 10 +++++++--- program/tests/helpers/mod.rs | 11 +++++++---- program/tests/withdraw_sol.rs | 4 ++-- program/tests/withdraw_with_fee.rs | 18 +++--------------- 4 files changed, 19 insertions(+), 24 deletions(-) diff --git a/program/src/state.rs b/program/src/state.rs index 31c2ef94..b453b1b5 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -942,9 +942,13 @@ impl Fee { if self.denominator == 0 { return Some(0); } - (amt as u128) - .checked_mul(self.numerator as u128)? - .checked_div(self.denominator as u128) + let numerator = (amt as u128).checked_mul(self.numerator as u128)?; + // ceiling the calculation by adding (denominator - 1) to the numerator + let denominator = self.denominator as u128; + numerator + .checked_add(denominator)? + .checked_sub(1)? + .checked_div(denominator) } /// Withdrawal fees have some additional restrictions, diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index d82dbe5a..23f14657 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -897,15 +897,17 @@ impl StakePoolAccounts { } pub fn calculate_fee(&self, amount: u64) -> u64 { - amount * self.epoch_fee.numerator / self.epoch_fee.denominator + (amount * self.epoch_fee.numerator + self.epoch_fee.denominator - 1) + / self.epoch_fee.denominator } pub fn calculate_withdrawal_fee(&self, pool_tokens: u64) -> u64 { - pool_tokens * self.withdrawal_fee.numerator / self.withdrawal_fee.denominator + (pool_tokens * self.withdrawal_fee.numerator + self.withdrawal_fee.denominator - 1) + / self.withdrawal_fee.denominator } pub fn calculate_inverse_withdrawal_fee(&self, pool_tokens: u64) -> u64 { - pool_tokens * self.withdrawal_fee.denominator + (pool_tokens * self.withdrawal_fee.denominator + self.withdrawal_fee.denominator - 1) / (self.withdrawal_fee.denominator - self.withdrawal_fee.numerator) } @@ -914,7 +916,8 @@ impl StakePoolAccounts { } pub fn calculate_sol_deposit_fee(&self, pool_tokens: u64) -> u64 { - pool_tokens * self.sol_deposit_fee.numerator / self.sol_deposit_fee.denominator + (pool_tokens * self.sol_deposit_fee.numerator + self.sol_deposit_fee.denominator - 1) + / self.sol_deposit_fee.denominator } pub fn calculate_sol_referral_fee(&self, deposit_fee_collected: u64) -> u64 { diff --git a/program/tests/withdraw_sol.rs b/program/tests/withdraw_sol.rs index 67b60a7a..e8eb2423 100644 --- a/program/tests/withdraw_sol.rs +++ b/program/tests/withdraw_sol.rs @@ -214,7 +214,7 @@ async fn fail_overdraw_reserve() { .await; assert!(error.is_none(), "{:?}", error); - // try to withdraw one lamport, will overdraw + // try to withdraw one lamport after fees, will overdraw let error = stake_pool_accounts .withdraw_sol( &mut context.banks_client, @@ -222,7 +222,7 @@ async fn fail_overdraw_reserve() { &context.last_blockhash, &user, &pool_token_account, - 1, + 2, None, ) .await diff --git a/program/tests/withdraw_with_fee.rs b/program/tests/withdraw_with_fee.rs index b55283fb..7a8e000c 100644 --- a/program/tests/withdraw_with_fee.rs +++ b/program/tests/withdraw_with_fee.rs @@ -6,10 +6,10 @@ mod helpers; use { bincode::deserialize, helpers::*, - solana_program::{borsh0_10::try_from_slice_unchecked, pubkey::Pubkey, stake}, + solana_program::{pubkey::Pubkey, stake}, solana_program_test::*, solana_sdk::signature::{Keypair, Signer}, - spl_stake_pool::{minimum_stake_lamports, state}, + spl_stake_pool::minimum_stake_lamports, }; #[tokio::test] @@ -183,20 +183,8 @@ async fn success_empty_out_stake_with_fee() { .await; let lamports_to_withdraw = validator_stake_account.lamports - minimum_stake_lamports(&meta, stake_minimum_delegation); - let stake_pool_account = get_account( - &mut context.banks_client, - &stake_pool_accounts.stake_pool.pubkey(), - ) - .await; - let stake_pool = - try_from_slice_unchecked::(stake_pool_account.data.as_slice()).unwrap(); - let fee = stake_pool.stake_withdrawal_fee; - let inverse_fee = state::Fee { - numerator: fee.denominator - fee.numerator, - denominator: fee.denominator, - }; let pool_tokens_to_withdraw = - lamports_to_withdraw * inverse_fee.denominator / inverse_fee.numerator; + stake_pool_accounts.calculate_inverse_withdrawal_fee(lamports_to_withdraw); let last_blockhash = context .banks_client From 0049bca095442912ec057bfb8046097609055330 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 Jan 2024 12:34:20 +0100 Subject: [PATCH 0704/1076] build(deps-dev): bump @types/node from 20.11.5 to 20.11.6 (#6172) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.5 to 20.11.6. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 8c0bbdee..9a775858 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.11", - "@types/node": "^20.11.5", + "@types/node": "^20.11.6", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^6.19.1", "@typescript-eslint/parser": "^6.19.1", From d1a72fd54f9758353c6e150613f262e2ac36fb5d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Jan 2024 11:58:50 +0100 Subject: [PATCH 0705/1076] build(deps): bump bytemuck from 1.14.0 to 1.14.1 (#6179) Bumps [bytemuck](https://github.com/Lokathor/bytemuck) from 1.14.0 to 1.14.1. - [Changelog](https://github.com/Lokathor/bytemuck/blob/main/changelog.md) - [Commits](https://github.com/Lokathor/bytemuck/compare/v1.14.0...v1.14.1) --- updated-dependencies: - dependency-name: bytemuck dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 38b53280..f5e86905 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -14,7 +14,7 @@ test-sbf = [] [dependencies] arrayref = "0.3.7" borsh = "0.10" -bytemuck = "1.13" +bytemuck = "1.14" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.2" From c31ed29d990f17a059dab089ba243bdbe839695a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 26 Jan 2024 13:11:14 +0100 Subject: [PATCH 0706/1076] build(deps-dev): bump @types/node from 20.11.6 to 20.11.7 (#6186) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.6 to 20.11.7. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 9a775858..bcdb744f 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.11", - "@types/node": "^20.11.6", + "@types/node": "^20.11.7", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^6.19.1", "@typescript-eslint/parser": "^6.19.1", From 7ce48ece43ac593eb7bf9fe4a7a4a27fc34c1f7f Mon Sep 17 00:00:00 2001 From: Will Hickey Date: Fri, 26 Jan 2024 15:31:55 -0600 Subject: [PATCH 0707/1076] Update solana dependency version to allow 2.0.0 (#6182) * Update solana dependency version to allow 2.0.0 * Fix version number in solana-version.sh * Fix version numbers * Revert solana-version.sh with note * Revert Anchor version change * Relax dependency version upper bound to 2 --- clients/cli/Cargo.toml | 18 +++++++++--------- program/Cargo.toml | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 74f321c5..4e4f7aca 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -14,15 +14,15 @@ clap = "2.33.3" serde = "1.0.195" serde_derive = "1.0.130" serde_json = "1.0.111" -solana-account-decoder = "=1.17.13" -solana-clap-utils = "=1.17.13" -solana-cli-config = "=1.17.13" -solana-cli-output = "=1.17.13" -solana-client = "=1.17.13" -solana-logger = "=1.17.13" -solana-program = "=1.17.13" -solana-remote-wallet = "=1.17.13" -solana-sdk = "=1.17.13" +solana-account-decoder = ">=1.17.13,<=2" +solana-clap-utils = ">=1.17.13,<=2" +solana-cli-config = ">=1.17.13,<=2" +solana-cli-output = ">=1.17.13,<=2" +solana-client = ">=1.17.13,<=2" +solana-logger = ">=1.17.13,<=2" +solana-program = ">=1.17.13,<=2" +solana-remote-wallet = ">=1.17.13,<=2" +solana-sdk = ">=1.17.13,<=2" spl-associated-token-account = { version = "=2.3", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } spl-stake-pool = { version = "=1.0.0", path="../program", features = [ "no-entrypoint" ] } spl-token = { version = "=4.0", path="../../token/program", features = [ "no-entrypoint" ] } diff --git a/program/Cargo.toml b/program/Cargo.toml index f5e86905..27af4783 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -20,7 +20,7 @@ num-traits = "0.2" num_enum = "0.7.2" serde = "1.0.195" serde_derive = "1.0.103" -solana-program = "1.17.13" +solana-program = ">=1.17.13,<=2" solana-security-txt = "1.1.1" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-pod = { version = "0.1", path = "../../libraries/pod", features = ["borsh"] } @@ -31,9 +31,9 @@ bincode = "1.3.1" [dev-dependencies] assert_matches = "1.5.0" proptest = "1.4" -solana-program-test = "1.17.13" -solana-sdk = "1.17.13" -solana-vote-program = "1.17.13" +solana-program-test = ">=1.17.13,<=2" +solana-sdk = ">=1.17.13,<=2" +solana-vote-program = ">=1.17.13,<=2" spl-token = { version = "4.0", path = "../../token/program", features = [ "no-entrypoint" ] } test-case = "3.3" From 62a66c67f12fd24353421db92fe6f6fcec3090f5 Mon Sep 17 00:00:00 2001 From: Jon C Date: Fri, 26 Jan 2024 23:19:53 +0100 Subject: [PATCH 0708/1076] token-2022: Bump to v2 (#6187) --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 27af4783..ab4e77be 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -24,7 +24,7 @@ solana-program = ">=1.17.13,<=2" solana-security-txt = "1.1.1" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-pod = { version = "0.1", path = "../../libraries/pod", features = ["borsh"] } -spl-token-2022 = { version = "1.0", path = "../../token/program-2022", features = [ "no-entrypoint" ] } +spl-token-2022 = { version = "2.0", path = "../../token/program-2022", features = [ "no-entrypoint" ] } thiserror = "1.0" bincode = "1.3.1" From f75e4c05d1d86cde832f71330c55892d16d6a234 Mon Sep 17 00:00:00 2001 From: kagren Date: Sat, 27 Jan 2024 13:52:32 +0100 Subject: [PATCH 0709/1076] reduce cluttering by removing debug print command (#6191) --- clients/py/stake_pool/state.py | 1 - 1 file changed, 1 deletion(-) diff --git a/clients/py/stake_pool/state.py b/clients/py/stake_pool/state.py index b963e7a2..36be8a11 100644 --- a/clients/py/stake_pool/state.py +++ b/clients/py/stake_pool/state.py @@ -179,7 +179,6 @@ def calculate_validator_list_size(max_validators: int) -> int: def decode(cls, data: str, encoding: str): data_bytes = decode_byte_string(data, encoding) parsed = DECODE_VALIDATOR_LIST_LAYOUT.parse(data_bytes) - print(parsed) return ValidatorList( max_validators=parsed['max_validators'], validators=[ValidatorStakeInfo.decode_container(container) for container in parsed['validators']], From 2c15687c6e6f7c9ddeddd09bff356c8de3e6b682 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jan 2024 13:27:41 +0100 Subject: [PATCH 0710/1076] build(deps): bump serde from 1.0.195 to 1.0.196 (#6193) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.195 to 1.0.196. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.195...v1.0.196) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 4e4f7aca..830764e6 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "1.0.0" [dependencies] borsh = "0.10" clap = "2.33.3" -serde = "1.0.195" +serde = "1.0.196" serde_derive = "1.0.130" serde_json = "1.0.111" solana-account-decoder = ">=1.17.13,<=2" diff --git a/program/Cargo.toml b/program/Cargo.toml index ab4e77be..865e2928 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,7 +18,7 @@ bytemuck = "1.14" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.2" -serde = "1.0.195" +serde = "1.0.196" serde_derive = "1.0.103" solana-program = ">=1.17.13,<=2" solana-security-txt = "1.1.1" From 9444d8435bd0d6b7d49bd1572c27fd705e11e70e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jan 2024 14:04:29 +0100 Subject: [PATCH 0711/1076] build(deps): bump serde_json from 1.0.111 to 1.0.113 (#6195) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.111 to 1.0.113. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.111...v1.0.113) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 830764e6..92521248 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ borsh = "0.10" clap = "2.33.3" serde = "1.0.196" serde_derive = "1.0.130" -serde_json = "1.0.111" +serde_json = "1.0.113" solana-account-decoder = ">=1.17.13,<=2" solana-clap-utils = ">=1.17.13,<=2" solana-cli-config = ">=1.17.13,<=2" From e148b3f40f915a74e385594a9aa5747d34ddcb76 Mon Sep 17 00:00:00 2001 From: Joe C Date: Mon, 29 Jan 2024 14:50:07 -0600 Subject: [PATCH 0712/1076] token js: bump to 0.4.0 (#6188) --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index bcdb744f..5dbd22d9 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -45,7 +45,7 @@ "dependencies": { "@coral-xyz/borsh": "^0.29.0", "@solana/buffer-layout": "^4.0.1", - "@solana/spl-token": "0.3.11", + "@solana/spl-token": "0.4.0", "@solana/web3.js": "^1.89.1", "bn.js": "^5.2.0", "buffer": "^6.0.3", From 02a78635a9baa712f406c6b6ab07d2b716434133 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Jan 2024 01:51:58 +0100 Subject: [PATCH 0713/1076] build(deps-dev): bump @types/node from 20.11.7 to 20.11.10 (#6198) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.7 to 20.11.10. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 5dbd22d9..6752f15d 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.11", - "@types/node": "^20.11.7", + "@types/node": "^20.11.10", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^6.19.1", "@typescript-eslint/parser": "^6.19.1", From d86d9bdaaab39b17e4e94c627e94debe97567a13 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Jan 2024 12:15:05 +0100 Subject: [PATCH 0714/1076] build(deps-dev): bump @typescript-eslint/parser from 6.19.1 to 6.20.0 (#6202) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.19.1 to 6.20.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.20.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 6752f15d..881ec06b 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.11.10", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^6.19.1", - "@typescript-eslint/parser": "^6.19.1", + "@typescript-eslint/parser": "^6.20.0", "cross-env": "^7.0.3", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", From 97f1212e2441bdac46f1364a0f95241055a6555e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Jan 2024 12:33:15 +0100 Subject: [PATCH 0715/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.19.1 to 6.20.0 (#6203) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.19.1 to 6.20.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.20.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 881ec06b..c55eecf0 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.11", "@types/node": "^20.11.10", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^6.19.1", + "@typescript-eslint/eslint-plugin": "^6.20.0", "@typescript-eslint/parser": "^6.20.0", "cross-env": "^7.0.3", "eslint": "^8.56.0", From cf9d7ac2079a2ebb85c7cf07c0dc733f50886e8f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 31 Jan 2024 14:48:14 +0100 Subject: [PATCH 0716/1076] build(deps-dev): bump @types/node from 20.11.10 to 20.11.13 (#6209) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.10 to 20.11.13. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index c55eecf0..09c65276 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.11", - "@types/node": "^20.11.10", + "@types/node": "^20.11.13", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^6.20.0", "@typescript-eslint/parser": "^6.20.0", From 3eac349163494fe07d9d3afc94bf696ad7ba2d25 Mon Sep 17 00:00:00 2001 From: kagren Date: Wed, 31 Jan 2024 15:53:44 +0100 Subject: [PATCH 0717/1076] stake-pool-js: Fix not adding `increaseAdditionalValidatorStake` instruction to array (#6211) bug fix, increaseAdditionalValidatorStake instruction not added to array --- clients/js-legacy/src/index.ts | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/clients/js-legacy/src/index.ts b/clients/js-legacy/src/index.ts index faf95a5e..a2b28281 100644 --- a/clients/js-legacy/src/index.ts +++ b/clients/js-legacy/src/index.ts @@ -702,20 +702,22 @@ export async function increaseValidatorStake( stakePoolAddress, new BN(ephemeralStakeSeed), ); - StakePoolInstruction.increaseAdditionalValidatorStake({ - stakePool: stakePoolAddress, - staker: stakePool.account.data.staker, - validatorList: stakePool.account.data.validatorList, - reserveStake: stakePool.account.data.reserveStake, - transientStakeSeed: transientStakeSeed.toNumber(), - withdrawAuthority, - transientStake, - validatorStake, - validatorVote, - lamports, - ephemeralStake, - ephemeralStakeSeed, - }); + instructions.push( + StakePoolInstruction.increaseAdditionalValidatorStake({ + stakePool: stakePoolAddress, + staker: stakePool.account.data.staker, + validatorList: stakePool.account.data.validatorList, + reserveStake: stakePool.account.data.reserveStake, + transientStakeSeed: transientStakeSeed.toNumber(), + withdrawAuthority, + transientStake, + validatorStake, + validatorVote, + lamports, + ephemeralStake, + ephemeralStakeSeed, + }), + ); } else { instructions.push( StakePoolInstruction.increaseValidatorStake({ From 9d29babc133e101cb7a433975c6e6e1802dd1d05 Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Thu, 1 Feb 2024 10:09:45 +0900 Subject: [PATCH 0718/1076] Upgrade to solana 1.17.17 (#6189) * upgrade to solana version 1.17.17 * add display for the group extensions * upgrade to solana version 1.17.17 * update cargo lock --- clients/cli/Cargo.toml | 30 ++++++++++++++++++------------ program/Cargo.toml | 8 ++++---- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 92521248..35a3dbc3 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -14,18 +14,24 @@ clap = "2.33.3" serde = "1.0.196" serde_derive = "1.0.130" serde_json = "1.0.113" -solana-account-decoder = ">=1.17.13,<=2" -solana-clap-utils = ">=1.17.13,<=2" -solana-cli-config = ">=1.17.13,<=2" -solana-cli-output = ">=1.17.13,<=2" -solana-client = ">=1.17.13,<=2" -solana-logger = ">=1.17.13,<=2" -solana-program = ">=1.17.13,<=2" -solana-remote-wallet = ">=1.17.13,<=2" -solana-sdk = ">=1.17.13,<=2" -spl-associated-token-account = { version = "=2.3", path="../../associated-token-account/program", features = [ "no-entrypoint" ] } -spl-stake-pool = { version = "=1.0.0", path="../program", features = [ "no-entrypoint" ] } -spl-token = { version = "=4.0", path="../../token/program", features = [ "no-entrypoint" ] } +solana-account-decoder = ">=1.17.17,<=2" +solana-clap-utils = ">=1.17.17,<=2" +solana-cli-config = ">=1.17.17,<=2" +solana-cli-output = ">=1.17.17,<=2" +solana-client = ">=1.17.17,<=2" +solana-logger = ">=1.17.17,<=2" +solana-program = ">=1.17.17,<=2" +solana-remote-wallet = ">=1.17.17,<=2" +solana-sdk = ">=1.17.17,<=2" +spl-associated-token-account = { version = "=2.3", path = "../../associated-token-account/program", features = [ + "no-entrypoint", +] } +spl-stake-pool = { version = "=1.0.0", path = "../program", features = [ + "no-entrypoint", +] } +spl-token = { version = "=4.0", path = "../../token/program", features = [ + "no-entrypoint", +] } bs58 = "0.4.0" bincode = "1.3.1" diff --git a/program/Cargo.toml b/program/Cargo.toml index 865e2928..944686a8 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -20,7 +20,7 @@ num-traits = "0.2" num_enum = "0.7.2" serde = "1.0.196" serde_derive = "1.0.103" -solana-program = ">=1.17.13,<=2" +solana-program = ">=1.17.17,<=2" solana-security-txt = "1.1.1" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } spl-pod = { version = "0.1", path = "../../libraries/pod", features = ["borsh"] } @@ -31,9 +31,9 @@ bincode = "1.3.1" [dev-dependencies] assert_matches = "1.5.0" proptest = "1.4" -solana-program-test = ">=1.17.13,<=2" -solana-sdk = ">=1.17.13,<=2" -solana-vote-program = ">=1.17.13,<=2" +solana-program-test = ">=1.17.17,<=2" +solana-sdk = ">=1.17.17,<=2" +solana-vote-program = ">=1.17.17,<=2" spl-token = { version = "4.0", path = "../../token/program", features = [ "no-entrypoint" ] } test-case = "3.3" From 084883f9b3db5949115710095393c036cc172573 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 12:55:24 +0100 Subject: [PATCH 0719/1076] build(deps-dev): bump @types/node from 20.11.13 to 20.11.15 (#6212) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.13 to 20.11.15. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 09c65276..0db2a608 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.11", - "@types/node": "^20.11.13", + "@types/node": "^20.11.15", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^6.20.0", "@typescript-eslint/parser": "^6.20.0", From 8683dd564c6c9ce3da5d60d478dfcdcbfc02fa8e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 2 Feb 2024 13:52:31 +0100 Subject: [PATCH 0720/1076] build(deps-dev): bump @types/node from 20.11.15 to 20.11.16 (#6216) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.15 to 20.11.16. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 0db2a608..764f973b 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.11", - "@types/node": "^20.11.15", + "@types/node": "^20.11.16", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^6.20.0", "@typescript-eslint/parser": "^6.20.0", From dfe1b5c59ab8d4c5604b12a8fd7bc988b286d8ea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 2 Feb 2024 14:10:26 +0100 Subject: [PATCH 0721/1076] build(deps-dev): bump @types/jest from 29.5.11 to 29.5.12 (#6217) Bumps [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) from 29.5.11 to 29.5.12. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest) --- updated-dependencies: - dependency-name: "@types/jest" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 764f973b..c2814858 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -60,7 +60,7 @@ "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", - "@types/jest": "^29.5.11", + "@types/jest": "^29.5.12", "@types/node": "^20.11.16", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^6.20.0", From 4a15ceec237a3652795badaefb96cf160f04c1e7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 12:59:25 -0500 Subject: [PATCH 0722/1076] build(deps-dev): bump prettier from 3.2.4 to 3.2.5 (#6223) * build(deps-dev): bump prettier from 3.2.4 to 3.2.5 Bumps [prettier](https://github.com/prettier/prettier) from 3.2.4 to 3.2.5. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/3.2.4...3.2.5) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Fixup everywhere --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index c2814858..110c1db9 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -70,7 +70,7 @@ "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", "jest": "^29.0.0", - "prettier": "^3.2.4", + "prettier": "^3.2.5", "rimraf": "^5.0.0", "rollup": "^4.9.6", "rollup-plugin-dts": "^6.1.0", From af905af1c7e61448abddd88b415e27213556e883 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 09:56:23 -0500 Subject: [PATCH 0723/1076] build(deps-dev): bump @typescript-eslint/parser from 6.20.0 to 6.21.0 (#6229) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.20.0 to 6.21.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.21.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 110c1db9..2e0ddb50 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.11.16", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^6.20.0", - "@typescript-eslint/parser": "^6.20.0", + "@typescript-eslint/parser": "^6.21.0", "cross-env": "^7.0.3", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", From cb35e9eba9df338b3c850e7872678b0539412a26 Mon Sep 17 00:00:00 2001 From: kagren Date: Tue, 6 Feb 2024 16:01:24 +0100 Subject: [PATCH 0724/1076] Replace BN.toBuffer with BN.toArrayLike (#6226) replace BN.toBuffer with BN.toArrayLike BN.toBuffer is not available in the browser. Replaced with .toArrayLike which provides the same functionality and works consistently both in nodejs and browser. --- clients/js-legacy/src/utils/program-address.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/js-legacy/src/utils/program-address.ts b/clients/js-legacy/src/utils/program-address.ts index 49d106b1..5b95ca18 100644 --- a/clients/js-legacy/src/utils/program-address.ts +++ b/clients/js-legacy/src/utils/program-address.ts @@ -50,7 +50,7 @@ export async function findTransientStakeProgramAddress( TRANSIENT_STAKE_SEED_PREFIX, voteAccountAddress.toBuffer(), stakePoolAddress.toBuffer(), - seed.toBuffer('le', 8), + seed.toArrayLike(Buffer, 'le', 8), ], programId, ); @@ -66,7 +66,7 @@ export async function findEphemeralStakeProgramAddress( seed: BN, ) { const [publicKey] = await PublicKey.findProgramAddress( - [EPHEMERAL_STAKE_SEED_PREFIX, stakePoolAddress.toBuffer(), seed.toBuffer('le', 8)], + [EPHEMERAL_STAKE_SEED_PREFIX, stakePoolAddress.toBuffer(), seed.toArrayLike(Buffer, 'le', 8)], programId, ); return publicKey; From 6a07b7c7f2050dd8aa5ec8a340e618962f0a773d Mon Sep 17 00:00:00 2001 From: kagren Date: Tue, 6 Feb 2024 16:02:19 +0100 Subject: [PATCH 0725/1076] Bugfix JS client stake pool code increaseValidatorStake and decreaseValidatorStake (#6224) * when ephemeralStakeSeed is supplied, transient stake seed needs to be unchanged * eslint, prettier fix --- clients/js-legacy/src/index.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/clients/js-legacy/src/index.ts b/clients/js-legacy/src/index.ts index a2b28281..702bbd18 100644 --- a/clients/js-legacy/src/index.ts +++ b/clients/js-legacy/src/index.ts @@ -679,7 +679,11 @@ export async function increaseValidatorStake( stakePoolAddress, ); - const transientStakeSeed = validatorInfo.transientSeedSuffixStart.addn(1); // bump up by one to avoid reuse + // Bump transient seed suffix by one to avoid reuse when not using the increaseAdditionalStake instruction + const transientStakeSeed = + ephemeralStakeSeed == undefined + ? validatorInfo.transientSeedSuffixStart.addn(1) + : validatorInfo.transientSeedSuffixStart; const transientStake = await findTransientStakeProgramAddress( STAKE_POOL_PROGRAM_ID, @@ -775,7 +779,11 @@ export async function decreaseValidatorStake( stakePoolAddress, ); - const transientStakeSeed = validatorInfo.transientSeedSuffixStart.addn(1); // bump up by one to avoid reuse + // Bump transient seed suffix by one to avoid reuse when not using the decreaseAdditionalStake instruction + const transientStakeSeed = + ephemeralStakeSeed == undefined + ? validatorInfo.transientSeedSuffixStart.addn(1) + : validatorInfo.transientSeedSuffixStart; const transientStake = await findTransientStakeProgramAddress( STAKE_POOL_PROGRAM_ID, From 4b9c2372b02ac873fd317996db2a5d4d0f6c17b8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 10:14:57 -0500 Subject: [PATCH 0726/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.20.0 to 6.21.0 (#6230) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.20.0 to 6.21.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.21.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 2e0ddb50..6b6dfd67 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.12", "@types/node": "^20.11.16", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^6.20.0", + "@typescript-eslint/eslint-plugin": "^6.21.0", "@typescript-eslint/parser": "^6.21.0", "cross-env": "^7.0.3", "eslint": "^8.56.0", From 02a52bf2ff81cc85fa9afde2159dd3da6e1afd75 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 Feb 2024 19:30:26 -0500 Subject: [PATCH 0727/1076] build(deps): bump @solana/web3.js from 1.89.1 to 1.90.0 (#6233) * build(deps): bump @solana/web3.js from 1.89.1 to 1.90.0 Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.89.1 to 1.90.0. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.89.1...v1.90.0) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Do the update properly --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 6b6dfd67..0b905af8 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -46,7 +46,7 @@ "@coral-xyz/borsh": "^0.29.0", "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "0.4.0", - "@solana/web3.js": "^1.89.1", + "@solana/web3.js": "^1.90.0", "bn.js": "^5.2.0", "buffer": "^6.0.3", "superstruct": "^1.0.3" From 7d307d3fae29133e9538636cc7220a7dd7da777b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 9 Feb 2024 19:02:08 -0500 Subject: [PATCH 0728/1076] build(deps-dev): bump @types/node from 20.11.16 to 20.11.17 (#6244) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.16 to 20.11.17. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 0b905af8..dccd8175 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.11.16", + "@types/node": "^20.11.17", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^6.21.0", "@typescript-eslint/parser": "^6.21.0", From f4f429228a21c7457003a9f3b0d39d25b4719ede Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Feb 2024 17:00:37 -0700 Subject: [PATCH 0729/1076] build(deps-dev): bump rollup from 4.9.6 to 4.10.0 (#6249) Bumps [rollup](https://github.com/rollup/rollup) from 4.9.6 to 4.10.0. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.9.6...v4.10.0) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index dccd8175..8b140668 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.2.5", "rimraf": "^5.0.0", - "rollup": "^4.9.6", + "rollup": "^4.10.0", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.1.2", "typescript": "^5.3.3" From 29053d98415dab6a70b8603a67b0285480fb894a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Feb 2024 22:11:53 -0700 Subject: [PATCH 0730/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.21.0 to 7.0.1 (#6253) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.21.0 to 7.0.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.0.1/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 8b140668..6c83b845 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.12", "@types/node": "^20.11.17", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/eslint-plugin": "^7.0.1", "@typescript-eslint/parser": "^6.21.0", "cross-env": "^7.0.3", "eslint": "^8.56.0", From e4134e443fba1337f1eeb9d4251bbfd015ebfadc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Feb 2024 22:28:18 -0700 Subject: [PATCH 0731/1076] build(deps-dev): bump @typescript-eslint/parser from 6.21.0 to 7.0.1 (#6251) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.21.0 to 7.0.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.0.1/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 6c83b845..06905771 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.11.17", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.0.1", - "@typescript-eslint/parser": "^6.21.0", + "@typescript-eslint/parser": "^7.0.1", "cross-env": "^7.0.3", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", From fd00b82346c32b815fbd82ad9f4acf7d21d6edd2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Feb 2024 12:43:58 -0700 Subject: [PATCH 0732/1076] build(deps-dev): bump @types/node from 20.11.17 to 20.11.18 (#6256) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.17 to 20.11.18. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 06905771..f3f31733 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.11.17", + "@types/node": "^20.11.18", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.0.1", "@typescript-eslint/parser": "^7.0.1", From ecf476c9c2aef3db9a6b77dd11881af5ea8dd33f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Feb 2024 12:44:22 -0700 Subject: [PATCH 0733/1076] build(deps-dev): bump rollup from 4.10.0 to 4.11.0 (#6259) Bumps [rollup](https://github.com/rollup/rollup) from 4.10.0 to 4.11.0. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.10.0...v4.11.0) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index f3f31733..7b0bcfaa 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.2.5", "rimraf": "^5.0.0", - "rollup": "^4.10.0", + "rollup": "^4.11.0", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.1.2", "typescript": "^5.3.3" From da21428b6306ab807784d4fc15ce42c5c5dd65dd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Feb 2024 16:03:44 +0100 Subject: [PATCH 0734/1076] build(deps-dev): bump @types/node from 20.11.18 to 20.11.19 (#6262) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.18 to 20.11.19. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 7b0bcfaa..6fecc628 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.11.18", + "@types/node": "^20.11.19", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.0.1", "@typescript-eslint/parser": "^7.0.1", From de09ce6167df9e81dabecdc4c3dca07ecee9e528 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Feb 2024 14:47:19 +0100 Subject: [PATCH 0735/1076] build(deps-dev): bump rollup from 4.11.0 to 4.12.0 (#6268) Bumps [rollup](https://github.com/rollup/rollup) from 4.11.0 to 4.12.0. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.11.0...v4.12.0) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 6fecc628..ba270e9f 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.2.5", "rimraf": "^5.0.0", - "rollup": "^4.11.0", + "rollup": "^4.12.0", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.1.2", "typescript": "^5.3.3" From 0659dff1fb20914c53cfc0b6533040bd235f40f6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Feb 2024 12:08:58 +0100 Subject: [PATCH 0736/1076] build(deps): bump serde from 1.0.196 to 1.0.197 (#6270) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.196 to 1.0.197. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.196...v1.0.197) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 35a3dbc3..b74db012 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "1.0.0" [dependencies] borsh = "0.10" clap = "2.33.3" -serde = "1.0.196" +serde = "1.0.197" serde_derive = "1.0.130" serde_json = "1.0.113" solana-account-decoder = ">=1.17.17,<=2" diff --git a/program/Cargo.toml b/program/Cargo.toml index 944686a8..dd75117c 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,7 +18,7 @@ bytemuck = "1.14" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.2" -serde = "1.0.196" +serde = "1.0.197" serde_derive = "1.0.103" solana-program = ">=1.17.17,<=2" solana-security-txt = "1.1.1" From 9c2bdb501a83df405163e9e64e0d01bc7a6905cc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Feb 2024 12:09:21 +0100 Subject: [PATCH 0737/1076] build(deps-dev): bump @typescript-eslint/parser from 7.0.1 to 7.0.2 (#6273) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.0.1 to 7.0.2. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.0.2/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index ba270e9f..b4875539 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.11.19", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.0.1", - "@typescript-eslint/parser": "^7.0.1", + "@typescript-eslint/parser": "^7.0.2", "cross-env": "^7.0.3", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", From a81fab5f04f96cb2ad2f05d1fca14d4512d36e84 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Feb 2024 12:41:57 +0100 Subject: [PATCH 0738/1076] build(deps): bump serde_json from 1.0.113 to 1.0.114 (#6272) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.113 to 1.0.114. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.113...v1.0.114) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index b74db012..b62d5a0c 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ borsh = "0.10" clap = "2.33.3" serde = "1.0.197" serde_derive = "1.0.130" -serde_json = "1.0.113" +serde_json = "1.0.114" solana-account-decoder = ">=1.17.17,<=2" solana-clap-utils = ">=1.17.17,<=2" solana-cli-config = ">=1.17.17,<=2" From 7f1d2ca1cc6443e8461853ffc61cc1c3fab28993 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Feb 2024 12:42:16 +0100 Subject: [PATCH 0739/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 7.0.1 to 7.0.2 (#6274) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.0.1 to 7.0.2. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.0.2/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index b4875539..a54a0474 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.12", "@types/node": "^20.11.19", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^7.0.1", + "@typescript-eslint/eslint-plugin": "^7.0.2", "@typescript-eslint/parser": "^7.0.2", "cross-env": "^7.0.3", "eslint": "^8.56.0", From 193dc12eabe8a202c62abc65d917a2fb6f549de5 Mon Sep 17 00:00:00 2001 From: Jon C Date: Tue, 20 Feb 2024 14:10:36 +0100 Subject: [PATCH 0740/1076] stake-pool-js: Bump to 1.0.1 for release (#6276) --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index a54a0474..0d9ba035 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-stake-pool", - "version": "1.0.0", + "version": "1.0.1", "description": "SPL Stake Pool Program JS API", "scripts": { "build": "tsc && cross-env NODE_ENV=production rollup -c", From 692180b1906dc8952765bc532edddc95207da6a9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 13:07:31 +0100 Subject: [PATCH 0741/1076] build(deps-dev): bump @types/node from 20.11.19 to 20.11.20 (#6286) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.19 to 20.11.20. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 0d9ba035..828e6286 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.11.19", + "@types/node": "^20.11.20", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.0.2", "@typescript-eslint/parser": "^7.0.2", From 3b4b49d9069233dd0c314671468c90f2a8122fcf Mon Sep 17 00:00:00 2001 From: kagren Date: Fri, 23 Feb 2024 20:26:58 +0100 Subject: [PATCH 0742/1076] Added support for the increase/decrease additional stake instructions in the Python client library (#6205) * Added support for the increase/decrease additional stake instructions Following the JS implementation * fixed code style issues reported by CI/CD * code style fix * Removed duplicate reserve_stake member in DecreaseAdditionalValidatorStakeParams * stake_history_sysvar not needed for decrease additional validator stake * added stake history * added support for increase/decrease additional instruction using an optional ephemeral seed parameter * updated test to also test the new variations of the increase/decrease methods * updated test to also test the new variations of the increase/decrease methods * updated test to also test the new variations of the increase/decrease methods * fixes as suggested * fixed assert criteria * fixed assert criteria * fixed assert criteria * fixed assert criteria * added an epoch boundary between decrease validator and decrease additional validator * removed test for DecreaseAdditionalValidatorStake as the method does not work * nit fixing --- clients/py/stake_pool/actions.py | 187 ++++++++++++++++------ clients/py/stake_pool/constants.py | 19 +++ clients/py/stake_pool/instructions.py | 156 ++++++++++++++++++ clients/py/tests/test_a_time_sensitive.py | 34 +++- 4 files changed, 344 insertions(+), 52 deletions(-) diff --git a/clients/py/stake_pool/actions.py b/clients/py/stake_pool/actions.py index a7eff4d9..e44afba4 100644 --- a/clients/py/stake_pool/actions.py +++ b/clients/py/stake_pool/actions.py @@ -1,4 +1,4 @@ -from typing import Tuple +from typing import Optional, Tuple from solana.keypair import Keypair from solana.publickey import PublicKey @@ -22,7 +22,8 @@ find_stake_program_address, \ find_transient_stake_program_address, \ find_withdraw_authority_program_address, \ - find_metadata_account + find_metadata_account, \ + find_ephemeral_stake_program_address from stake_pool.state import STAKE_POOL_LAYOUT, ValidatorList, Fee, StakePool import stake_pool.instructions as sp @@ -480,8 +481,13 @@ async def update_stake_pool(client: AsyncClient, payer: Keypair, stake_pool_addr async def increase_validator_stake( - client: AsyncClient, payer: Keypair, staker: Keypair, stake_pool_address: PublicKey, - validator_vote: PublicKey, lamports: int + client: AsyncClient, + payer: Keypair, + staker: Keypair, + stake_pool_address: PublicKey, + validator_vote: PublicKey, + lamports: int, + ephemeral_stake_seed: Optional[int] = None ): resp = await client.get_account_info(stake_pool_address, commitment=Confirmed) data = resp['result']['value']['data'] @@ -493,7 +499,13 @@ async def increase_validator_stake( (withdraw_authority, seed) = find_withdraw_authority_program_address(STAKE_POOL_PROGRAM_ID, stake_pool_address) validator_info = next(x for x in validator_list.validators if x.vote_account_address == validator_vote) - transient_stake_seed = validator_info.transient_seed_suffix + 1 # bump up by one to avoid reuse + + if ephemeral_stake_seed is None: + transient_stake_seed = validator_info.transient_seed_suffix + 1 # bump up by one to avoid reuse + else: + # we are updating an existing transient stake account, so we must use the same seed + transient_stake_seed = validator_info.transient_seed_suffix + validator_stake_seed = validator_info.validator_seed_suffix or None (transient_stake, _) = find_transient_stake_program_address( STAKE_POOL_PROGRAM_ID, @@ -509,29 +521,64 @@ async def increase_validator_stake( ) txn = Transaction() - txn.add( - sp.increase_validator_stake( - sp.IncreaseValidatorStakeParams( - program_id=STAKE_POOL_PROGRAM_ID, - stake_pool=stake_pool_address, - staker=staker.public_key, - withdraw_authority=withdraw_authority, - validator_list=stake_pool.validator_list, - reserve_stake=stake_pool.reserve_stake, - transient_stake=transient_stake, - validator_stake=validator_stake, - validator_vote=validator_vote, - clock_sysvar=SYSVAR_CLOCK_PUBKEY, - rent_sysvar=SYSVAR_RENT_PUBKEY, - stake_history_sysvar=SYSVAR_STAKE_HISTORY_PUBKEY, - stake_config_sysvar=SYSVAR_STAKE_CONFIG_ID, - system_program_id=sys.SYS_PROGRAM_ID, - stake_program_id=STAKE_PROGRAM_ID, - lamports=lamports, - transient_stake_seed=transient_stake_seed, + if ephemeral_stake_seed is not None: + + # We assume there is an existing transient account that we will update + (ephemeral_stake, _) = find_ephemeral_stake_program_address( + STAKE_POOL_PROGRAM_ID, + stake_pool_address, + ephemeral_stake_seed) + + txn.add( + sp.increase_additional_validator_stake( + sp.IncreaseAdditionalValidatorStakeParams( + program_id=STAKE_POOL_PROGRAM_ID, + stake_pool=stake_pool_address, + staker=staker.public_key, + withdraw_authority=withdraw_authority, + validator_list=stake_pool.validator_list, + reserve_stake=stake_pool.reserve_stake, + transient_stake=transient_stake, + validator_stake=validator_stake, + validator_vote=validator_vote, + clock_sysvar=SYSVAR_CLOCK_PUBKEY, + rent_sysvar=SYSVAR_RENT_PUBKEY, + stake_history_sysvar=SYSVAR_STAKE_HISTORY_PUBKEY, + stake_config_sysvar=SYSVAR_STAKE_CONFIG_ID, + system_program_id=sys.SYS_PROGRAM_ID, + stake_program_id=STAKE_PROGRAM_ID, + lamports=lamports, + transient_stake_seed=transient_stake_seed, + ephemeral_stake=ephemeral_stake, + ephemeral_stake_seed=ephemeral_stake_seed + ) + ) + ) + + else: + txn.add( + sp.increase_validator_stake( + sp.IncreaseValidatorStakeParams( + program_id=STAKE_POOL_PROGRAM_ID, + stake_pool=stake_pool_address, + staker=staker.public_key, + withdraw_authority=withdraw_authority, + validator_list=stake_pool.validator_list, + reserve_stake=stake_pool.reserve_stake, + transient_stake=transient_stake, + validator_stake=validator_stake, + validator_vote=validator_vote, + clock_sysvar=SYSVAR_CLOCK_PUBKEY, + rent_sysvar=SYSVAR_RENT_PUBKEY, + stake_history_sysvar=SYSVAR_STAKE_HISTORY_PUBKEY, + stake_config_sysvar=SYSVAR_STAKE_CONFIG_ID, + system_program_id=sys.SYS_PROGRAM_ID, + stake_program_id=STAKE_PROGRAM_ID, + lamports=lamports, + transient_stake_seed=transient_stake_seed, + ) ) ) - ) signers = [payer, staker] if payer != staker else [payer] await client.send_transaction( @@ -539,8 +586,13 @@ async def increase_validator_stake( async def decrease_validator_stake( - client: AsyncClient, payer: Keypair, staker: Keypair, stake_pool_address: PublicKey, - validator_vote: PublicKey, lamports: int + client: AsyncClient, + payer: Keypair, + staker: Keypair, + stake_pool_address: PublicKey, + validator_vote: PublicKey, + lamports: int, + ephemeral_stake_seed: Optional[int] = None ): resp = await client.get_account_info(stake_pool_address, commitment=Confirmed) data = resp['result']['value']['data'] @@ -559,7 +611,13 @@ async def decrease_validator_stake( stake_pool_address, validator_stake_seed, ) - transient_stake_seed = validator_info.transient_seed_suffix + 1 # bump up by one to avoid reuse + + if ephemeral_stake_seed is None: + transient_stake_seed = validator_info.transient_seed_suffix + 1 # bump up by one to avoid reuse + else: + # we are updating an existing transient stake account, so we must use the same seed + transient_stake_seed = validator_info.transient_seed_suffix + (transient_stake, _) = find_transient_stake_program_address( STAKE_POOL_PROGRAM_ID, validator_info.vote_account_address, @@ -568,26 +626,61 @@ async def decrease_validator_stake( ) txn = Transaction() - txn.add( - sp.decrease_validator_stake_with_reserve( - sp.DecreaseValidatorStakeWithReserveParams( - program_id=STAKE_POOL_PROGRAM_ID, - stake_pool=stake_pool_address, - staker=staker.public_key, - withdraw_authority=withdraw_authority, - validator_list=stake_pool.validator_list, - reserve_stake=stake_pool.reserve_stake, - validator_stake=validator_stake, - transient_stake=transient_stake, - clock_sysvar=SYSVAR_CLOCK_PUBKEY, - stake_history_sysvar=SYSVAR_STAKE_HISTORY_PUBKEY, - system_program_id=sys.SYS_PROGRAM_ID, - stake_program_id=STAKE_PROGRAM_ID, - lamports=lamports, - transient_stake_seed=transient_stake_seed, + + if ephemeral_stake_seed is not None: + + # We assume there is an existing transient account that we will update + (ephemeral_stake, _) = find_ephemeral_stake_program_address( + STAKE_POOL_PROGRAM_ID, + stake_pool_address, + ephemeral_stake_seed) + + txn.add( + sp.decrease_additional_validator_stake( + sp.DecreaseAdditionalValidatorStakeParams( + program_id=STAKE_POOL_PROGRAM_ID, + stake_pool=stake_pool_address, + staker=staker.public_key, + withdraw_authority=withdraw_authority, + validator_list=stake_pool.validator_list, + reserve_stake=stake_pool.reserve_stake, + validator_stake=validator_stake, + transient_stake=transient_stake, + clock_sysvar=SYSVAR_CLOCK_PUBKEY, + rent_sysvar=SYSVAR_RENT_PUBKEY, + stake_history_sysvar=SYSVAR_STAKE_HISTORY_PUBKEY, + system_program_id=sys.SYS_PROGRAM_ID, + stake_program_id=STAKE_PROGRAM_ID, + lamports=lamports, + transient_stake_seed=transient_stake_seed, + ephemeral_stake=ephemeral_stake, + ephemeral_stake_seed=ephemeral_stake_seed + ) + ) + ) + + else: + + txn.add( + sp.decrease_validator_stake_with_reserve( + sp.DecreaseValidatorStakeWithReserveParams( + program_id=STAKE_POOL_PROGRAM_ID, + stake_pool=stake_pool_address, + staker=staker.public_key, + withdraw_authority=withdraw_authority, + validator_list=stake_pool.validator_list, + reserve_stake=stake_pool.reserve_stake, + validator_stake=validator_stake, + transient_stake=transient_stake, + clock_sysvar=SYSVAR_CLOCK_PUBKEY, + stake_history_sysvar=SYSVAR_STAKE_HISTORY_PUBKEY, + system_program_id=sys.SYS_PROGRAM_ID, + stake_program_id=STAKE_PROGRAM_ID, + lamports=lamports, + transient_stake_seed=transient_stake_seed, + ) ) ) - ) signers = [payer, staker] if payer != staker else [payer] await client.send_transaction( diff --git a/clients/py/stake_pool/constants.py b/clients/py/stake_pool/constants.py index f6c278e2..ff1f1dbe 100644 --- a/clients/py/stake_pool/constants.py +++ b/clients/py/stake_pool/constants.py @@ -78,6 +78,23 @@ def find_transient_stake_program_address( ) +def find_ephemeral_stake_program_address( + program_id: PublicKey, + stake_pool_address: PublicKey, + seed: int +) -> Tuple[PublicKey, int]: + + """Generates the ephemeral program address for stake pool redelegation""" + return PublicKey.find_program_address( + [ + EPHEMERAL_STAKE_SEED_PREFIX, + bytes(stake_pool_address), + seed.to_bytes(8, 'little'), + ], + program_id, + ) + + def find_metadata_account( mint_key: PublicKey ) -> Tuple[PublicKey, int]: @@ -100,3 +117,5 @@ def find_metadata_account( """Seed used to derive transient stake accounts.""" METADATA_SEED_PREFIX = b"metadata" """Seed used to avoid certain collision attacks.""" +EPHEMERAL_STAKE_SEED_PREFIX = b'ephemeral' +"""Seed for ephemeral stake account""" diff --git a/clients/py/stake_pool/instructions.py b/clients/py/stake_pool/instructions.py index 4a773a2d..8a3ae4cf 100644 --- a/clients/py/stake_pool/instructions.py +++ b/clients/py/stake_pool/instructions.py @@ -543,6 +543,94 @@ class UpdateTokenMetadataParams(NamedTuple): """URI of the uploaded metadata of the spl-token.""" +class IncreaseAdditionalValidatorStakeParams(NamedTuple): + """(Staker only) Increase stake on a validator from the reserve account.""" + + # Accounts + program_id: PublicKey + """SPL Stake Pool program account.""" + stake_pool: PublicKey + """`[]` Stake pool.""" + staker: PublicKey + """`[s]` Staker.""" + withdraw_authority: PublicKey + """`[]` Stake pool withdraw authority.""" + validator_list: PublicKey + """`[w]` Validator stake list storage account.""" + reserve_stake: PublicKey + """`[w]` Stake pool's reserve.""" + ephemeral_stake: PublicKey + """The ephemeral stake account used during the operation.""" + transient_stake: PublicKey + """`[w]` Transient stake account to receive split.""" + validator_stake: PublicKey + """`[]` Canonical stake account to check.""" + validator_vote: PublicKey + """`[]` Validator vote account to delegate to.""" + clock_sysvar: PublicKey + """`[]` Clock sysvar.""" + rent_sysvar: PublicKey + """`[]` Rent sysvar.""" + stake_history_sysvar: PublicKey + """'[]' Stake history sysvar.""" + stake_config_sysvar: PublicKey + """'[]' Stake config sysvar.""" + system_program_id: PublicKey + """`[]` System program.""" + stake_program_id: PublicKey + """`[]` Stake program.""" + + # Params + lamports: int + """Amount of lamports to increase on the given validator.""" + transient_stake_seed: int + """Seed to used to create the transient stake account.""" + ephemeral_stake_seed: int + """The seed used to generate the ephemeral stake account""" + + +class DecreaseAdditionalValidatorStakeParams(NamedTuple): + """(Staker only) Decrease active stake on a validator, eventually moving it to the reserve""" + + # Accounts + program_id: PublicKey + """SPL Stake Pool program account.""" + stake_pool: PublicKey + """`[]` Stake pool.""" + staker: PublicKey + """`[s]` Staker.""" + withdraw_authority: PublicKey + """`[]` Stake pool withdraw authority.""" + validator_list: PublicKey + """`[w]` Validator stake list storage account.""" + reserve_stake: PublicKey + """The reserve stake account to move the stake to.""" + validator_stake: PublicKey + """`[w]` Canonical stake to split from.""" + ephemeral_stake: PublicKey + """The ephemeral stake account used during the operation.""" + transient_stake: PublicKey + """`[w]` Transient stake account to receive split.""" + clock_sysvar: PublicKey + """`[]` Clock sysvar.""" + rent_sysvar: PublicKey + """`[]` Rent sysvar.""" + stake_history_sysvar: PublicKey + """'[]' Stake history sysvar.""" + system_program_id: PublicKey + """`[]` System program.""" + stake_program_id: PublicKey + """`[]` Stake program.""" + + # Params + lamports: int + """Amount of lamports to split into the transient stake account.""" + transient_stake_seed: int + """Seed to used to create the transient stake account.""" + ephemeral_stake_seed: int + """The seed used to generate the ephemeral stake account""" + + class InstructionType(IntEnum): """Stake Pool Instruction Types.""" @@ -1009,6 +1097,42 @@ def increase_validator_stake(params: IncreaseValidatorStakeParams) -> Transactio ) +def increase_additional_validator_stake( + params: IncreaseAdditionalValidatorStakeParams, + ) -> TransactionInstruction: + + """Creates `IncreaseAdditionalValidatorStake` instruction (rebalance from reserve account to transient account)""" + return TransactionInstruction( + keys=[ + AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.staker, is_signer=True, is_writable=False), + AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.validator_list, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.reserve_stake, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.ephemeral_stake, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.transient_stake, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.validator_stake, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.validator_vote, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.clock_sysvar, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.stake_history_sysvar, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.stake_config_sysvar, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.system_program_id, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.stake_program_id, is_signer=False, is_writable=False), + ], + program_id=params.program_id, + data=INSTRUCTIONS_LAYOUT.build( + dict( + instruction_type=InstructionType.INCREASE_ADDITIONAL_VALIDATOR_STAKE, + args={ + 'lamports': params.lamports, + 'transient_stake_seed': params.transient_stake_seed, + 'ephemeral_stake_seed': params.ephemeral_stake_seed + } + ) + ) + ) + + def decrease_validator_stake(params: DecreaseValidatorStakeParams) -> TransactionInstruction: """Creates instruction to decrease the stake on a validator.""" return TransactionInstruction( @@ -1037,6 +1161,38 @@ def decrease_validator_stake(params: DecreaseValidatorStakeParams) -> Transactio ) +def decrease_additional_validator_stake(params: DecreaseAdditionalValidatorStakeParams) -> TransactionInstruction: + """ Creates `DecreaseAdditionalValidatorStake` instruction (rebalance from validator account to + transient account).""" + return TransactionInstruction( + keys=[ + AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.staker, is_signer=True, is_writable=False), + AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.validator_list, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.reserve_stake, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.validator_stake, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.ephemeral_stake, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.transient_stake, is_signer=False, is_writable=True), + AccountMeta(pubkey=params.clock_sysvar, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.stake_history_sysvar, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.system_program_id, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.stake_program_id, is_signer=False, is_writable=False), + ], + program_id=params.program_id, + data=INSTRUCTIONS_LAYOUT.build( + dict( + instruction_type=InstructionType.DECREASE_ADDITIONAL_VALIDATOR_STAKE, + args={ + 'lamports': params.lamports, + 'transient_stake_seed': params.transient_stake_seed, + 'ephemeral_stake_seed': params.ephemeral_stake_seed + } + ) + ) + ) + + def decrease_validator_stake_with_reserve(params: DecreaseValidatorStakeWithReserveParams) -> TransactionInstruction: """Creates instruction to decrease the stake on a validator.""" return TransactionInstruction( diff --git a/clients/py/tests/test_a_time_sensitive.py b/clients/py/tests/test_a_time_sensitive.py index 78abbf47..682d1202 100644 --- a/clients/py/tests/test_a_time_sensitive.py +++ b/clients/py/tests/test_a_time_sensitive.py @@ -29,16 +29,33 @@ async def test_increase_decrease_this_is_very_slow(async_client, validators, pay # increase to all futures = [ - increase_validator_stake(async_client, payer, payer, stake_pool_address, validator, increase_amount) + increase_validator_stake(async_client, payer, payer, stake_pool_address, validator, increase_amount // 2) for validator in validators ] await asyncio.gather(*futures) + # validate the increase is now on the transient account resp = await async_client.get_account_info(validator_list_address, commitment=Confirmed) data = resp['result']['value']['data'] validator_list = ValidatorList.decode(data[0], data[1]) for validator in validator_list.validators: - assert validator.transient_stake_lamports == increase_amount + stake_rent_exemption + assert validator.transient_stake_lamports == increase_amount // 2 + stake_rent_exemption + assert validator.active_stake_lamports == minimum_amount + + # increase the same amount to test the increase additional instruction + futures = [ + increase_validator_stake(async_client, payer, payer, stake_pool_address, validator, increase_amount // 2, + ephemeral_stake_seed=0) + for validator in validators + ] + await asyncio.gather(*futures) + + # validate the additional increase is now on the transient account + resp = await async_client.get_account_info(validator_list_address, commitment=Confirmed) + data = resp['result']['value']['data'] + validator_list = ValidatorList.decode(data[0], data[1]) + for validator in validator_list.validators: + assert validator.transient_stake_lamports == increase_amount + stake_rent_exemption * 2 assert validator.active_stake_lamports == minimum_amount print("Waiting for epoch to roll over") @@ -51,7 +68,7 @@ async def test_increase_decrease_this_is_very_slow(async_client, validators, pay for validator in validator_list.validators: assert validator.last_update_epoch != 0 assert validator.transient_stake_lamports == 0 - assert validator.active_stake_lamports == increase_amount + minimum_amount + assert validator.active_stake_lamports == increase_amount + minimum_amount + stake_rent_exemption # decrease from all futures = [ @@ -60,12 +77,19 @@ async def test_increase_decrease_this_is_very_slow(async_client, validators, pay ] await asyncio.gather(*futures) + # validate the decrease is now on the transient account resp = await async_client.get_account_info(validator_list_address, commitment=Confirmed) data = resp['result']['value']['data'] validator_list = ValidatorList.decode(data[0], data[1]) for validator in validator_list.validators: assert validator.transient_stake_lamports == decrease_amount + stake_rent_exemption - assert validator.active_stake_lamports == increase_amount - decrease_amount + minimum_amount + assert validator.active_stake_lamports == increase_amount - decrease_amount + minimum_amount + \ + stake_rent_exemption + + # DO NOT test decrese additional instruction as it is confirmed NOT to be working as advertised + + # roll over one epoch and verify we have the balances that we expect + expected_active_stake_lamports = increase_amount - decrease_amount + minimum_amount + stake_rent_exemption print("Waiting for epoch to roll over") await waiter.wait_for_next_epoch(async_client) @@ -76,4 +100,4 @@ async def test_increase_decrease_this_is_very_slow(async_client, validators, pay validator_list = ValidatorList.decode(data[0], data[1]) for validator in validator_list.validators: assert validator.transient_stake_lamports == 0 - assert validator.active_stake_lamports == increase_amount - decrease_amount + minimum_amount + assert validator.active_stake_lamports == expected_active_stake_lamports From 32d3b68155f2e563726c51f209bac263b1898a3a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Feb 2024 14:19:01 +0100 Subject: [PATCH 0743/1076] build(deps-dev): bump eslint from 8.56.0 to 8.57.0 (#6296) Bumps [eslint](https://github.com/eslint/eslint) from 8.56.0 to 8.57.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.56.0...v8.57.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 828e6286..359d610e 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -66,7 +66,7 @@ "@typescript-eslint/eslint-plugin": "^7.0.2", "@typescript-eslint/parser": "^7.0.2", "cross-env": "^7.0.3", - "eslint": "^8.56.0", + "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", "jest": "^29.0.0", From 376e9e77958a2ca1c4bd5436641f868c75a2dd91 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Feb 2024 12:23:26 +0100 Subject: [PATCH 0744/1076] build(deps-dev): bump @typescript-eslint/parser from 7.0.2 to 7.1.0 (#6303) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.0.2 to 7.1.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.1.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 359d610e..decd0d4b 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.11.20", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.0.2", - "@typescript-eslint/parser": "^7.0.2", + "@typescript-eslint/parser": "^7.1.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", From c642bef53748839bdd2c9c7a3fd313641cf31703 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Feb 2024 12:43:47 +0100 Subject: [PATCH 0745/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 7.0.2 to 7.1.0 (#6304) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.0.2 to 7.1.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.1.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index decd0d4b..282aec5c 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.12", "@types/node": "^20.11.20", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^7.0.2", + "@typescript-eslint/eslint-plugin": "^7.1.0", "@typescript-eslint/parser": "^7.1.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", From 634cfda074744ed2da2d413f2e80752adabdc12c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Feb 2024 13:19:19 +0100 Subject: [PATCH 0746/1076] build(deps-dev): bump @types/node from 20.11.20 to 20.11.21 (#6309) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.20 to 20.11.21. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 282aec5c..3fda1d3c 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.11.20", + "@types/node": "^20.11.21", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.1.0", "@typescript-eslint/parser": "^7.1.0", From 968ff5b690baa2443d76c79e5f645579cf4ee5fd Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Thu, 29 Feb 2024 10:06:27 +0900 Subject: [PATCH 0747/1076] Upgrade to Solana 1.18.2 (#6278) * upgrade to solana 1.18.2 * upgrade rust version to 1.76.0 * update borsh to 1.2.1 * replace deprecated `try_to_vec` with `borsh::to_vec` * temporarily allow deprecated functions in cli that uses clap-v3 * use `repr(u32)` for enums in token lending --- clients/cli/Cargo.toml | 20 +-- clients/cli/src/client.rs | 4 +- clients/cli/src/main.rs | 2 +- program/Cargo.toml | 26 ++-- program/src/inline_mpl_token_metadata.rs | 10 +- program/src/instruction.rs | 116 +++++++----------- program/src/processor.rs | 2 +- program/src/state.rs | 8 +- program/tests/deposit.rs | 7 +- program/tests/deposit_authority.rs | 2 +- program/tests/deposit_edge_cases.rs | 2 +- program/tests/deposit_sol.rs | 2 +- program/tests/force_destake.rs | 2 +- program/tests/helpers/mod.rs | 10 +- program/tests/huge_pool.rs | 2 +- program/tests/initialize.rs | 5 +- program/tests/set_deposit_fee.rs | 2 +- program/tests/set_epoch_fee.rs | 2 +- program/tests/set_funding_authority.rs | 10 +- program/tests/set_manager.rs | 11 +- program/tests/set_preferred.rs | 2 +- program/tests/set_referral_fee.rs | 2 +- program/tests/set_staker.rs | 7 +- program/tests/set_withdrawal_fee.rs | 2 +- program/tests/update_stake_pool_balance.rs | 2 +- .../tests/update_validator_list_balance.rs | 2 +- .../update_validator_list_balance_hijack.rs | 2 +- program/tests/vsa_add.rs | 18 ++- program/tests/vsa_remove.rs | 11 +- program/tests/withdraw.rs | 10 +- program/tests/withdraw_edge_cases.rs | 2 +- program/tests/withdraw_sol.rs | 2 +- 32 files changed, 131 insertions(+), 176 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index b62d5a0c..e7dd84f0 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -9,20 +9,20 @@ repository = "https://github.com/solana-labs/solana-program-library" version = "1.0.0" [dependencies] -borsh = "0.10" +borsh = "1.2.1" clap = "2.33.3" serde = "1.0.197" serde_derive = "1.0.130" serde_json = "1.0.114" -solana-account-decoder = ">=1.17.17,<=2" -solana-clap-utils = ">=1.17.17,<=2" -solana-cli-config = ">=1.17.17,<=2" -solana-cli-output = ">=1.17.17,<=2" -solana-client = ">=1.17.17,<=2" -solana-logger = ">=1.17.17,<=2" -solana-program = ">=1.17.17,<=2" -solana-remote-wallet = ">=1.17.17,<=2" -solana-sdk = ">=1.17.17,<=2" +solana-account-decoder = ">=1.18.2,<=2" +solana-clap-utils = ">=1.18.2,<=2" +solana-cli-config = ">=1.18.2,<=2" +solana-cli-output = ">=1.18.2,<=2" +solana-client = ">=1.18.2,<=2" +solana-logger = ">=1.18.2,<=2" +solana-program = ">=1.18.2,<=2" +solana-remote-wallet = ">=1.18.2,<=2" +solana-sdk = ">=1.18.2,<=2" spl-associated-token-account = { version = "=2.3", path = "../../associated-token-account/program", features = [ "no-entrypoint", ] } diff --git a/clients/cli/src/client.rs b/clients/cli/src/client.rs index 9deae1a8..62916d5d 100644 --- a/clients/cli/src/client.rs +++ b/clients/cli/src/client.rs @@ -7,9 +7,7 @@ use { rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig}, rpc_filter::{Memcmp, RpcFilterType}, }, - solana_program::{ - borsh0_10::try_from_slice_unchecked, program_pack::Pack, pubkey::Pubkey, stake, - }, + solana_program::{borsh1::try_from_slice_unchecked, program_pack::Pack, pubkey::Pubkey, stake}, spl_stake_pool::{ find_withdraw_authority_program_address, state::{StakePool, ValidatorList}, diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index bb20ffde..c764dc9d 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -26,7 +26,7 @@ use { solana_cli_output::OutputFormat, solana_client::rpc_client::RpcClient, solana_program::{ - borsh0_10::{get_instance_packed_len, get_packed_len}, + borsh1::{get_instance_packed_len, get_packed_len}, instruction::Instruction, program_pack::Pack, pubkey::Pubkey, diff --git a/program/Cargo.toml b/program/Cargo.toml index dd75117c..cf9a13fe 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -13,28 +13,36 @@ test-sbf = [] [dependencies] arrayref = "0.3.7" -borsh = "0.10" +borsh = "1.2.1" bytemuck = "1.14" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.2" serde = "1.0.197" serde_derive = "1.0.103" -solana-program = ">=1.17.17,<=2" +solana-program = ">=1.18.2,<=2" solana-security-txt = "1.1.1" -spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint" ] } -spl-pod = { version = "0.1", path = "../../libraries/pod", features = ["borsh"] } -spl-token-2022 = { version = "2.0", path = "../../token/program-2022", features = [ "no-entrypoint" ] } +spl-math = { version = "0.2", path = "../../libraries/math", features = [ + "no-entrypoint", +] } +spl-pod = { version = "0.1", path = "../../libraries/pod", features = [ + "borsh", +] } +spl-token-2022 = { version = "2.0", path = "../../token/program-2022", features = [ + "no-entrypoint", +] } thiserror = "1.0" bincode = "1.3.1" [dev-dependencies] assert_matches = "1.5.0" proptest = "1.4" -solana-program-test = ">=1.17.17,<=2" -solana-sdk = ">=1.17.17,<=2" -solana-vote-program = ">=1.17.17,<=2" -spl-token = { version = "4.0", path = "../../token/program", features = [ "no-entrypoint" ] } +solana-program-test = ">=1.18.2,<=2" +solana-sdk = ">=1.18.2,<=2" +solana-vote-program = ">=1.18.2,<=2" +spl-token = { version = "4.0", path = "../../token/program", features = [ + "no-entrypoint", +] } test-case = "3.3" [lib] diff --git a/program/src/inline_mpl_token_metadata.rs b/program/src/inline_mpl_token_metadata.rs index b7697a29..a5d0836b 100644 --- a/program/src/inline_mpl_token_metadata.rs +++ b/program/src/inline_mpl_token_metadata.rs @@ -38,7 +38,7 @@ pub(crate) mod instruction { ) -> Instruction { let mut data = vec![33]; // CreateMetadataAccountV3 data.append( - &mut CreateMetadataAccountArgsV3 { + &mut borsh::to_vec(&CreateMetadataAccountArgsV3 { data: DataV2 { name, symbol, @@ -50,8 +50,7 @@ pub(crate) mod instruction { }, is_mutable: true, collection_details: None, - } - .try_to_vec() + }) .unwrap(), ); Instruction { @@ -86,13 +85,12 @@ pub(crate) mod instruction { ) -> Instruction { let mut data = vec![15]; // UpdateMetadataAccountV2 data.append( - &mut UpdateMetadataAccountArgsV2 { + &mut borsh::to_vec(&UpdateMetadataAccountArgsV2 { data: metadata, update_authority: new_update_authority, primary_sale_happened, is_mutable, - } - .try_to_vec() + }) .unwrap(), ); Instruction { diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 4b8afd8e..313afd93 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -750,7 +750,7 @@ pub fn initialize( referral_fee, max_validators, }; - let data = init_data.try_to_vec().unwrap(); + let data = borsh::to_vec(&init_data).unwrap(); let mut accounts = vec![ AccountMeta::new(*stake_pool, false), AccountMeta::new_readonly(*manager, true), @@ -801,9 +801,10 @@ pub fn add_validator_to_pool( AccountMeta::new_readonly(system_program::id(), false), AccountMeta::new_readonly(stake::program::id(), false), ]; - let data = StakePoolInstruction::AddValidatorToPool(seed.map(|s| s.get()).unwrap_or(0)) - .try_to_vec() - .unwrap(); + let data = borsh::to_vec(&StakePoolInstruction::AddValidatorToPool( + seed.map(|s| s.get()).unwrap_or(0), + )) + .unwrap(); Instruction { program_id: *program_id, accounts, @@ -835,9 +836,7 @@ pub fn remove_validator_from_pool( Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::RemoveValidatorFromPool - .try_to_vec() - .unwrap(), + data: borsh::to_vec(&StakePoolInstruction::RemoveValidatorFromPool).unwrap(), } } @@ -873,11 +872,10 @@ pub fn decrease_validator_stake( Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::DecreaseValidatorStake { + data: borsh::to_vec(&StakePoolInstruction::DecreaseValidatorStake { lamports, transient_stake_seed, - } - .try_to_vec() + }) .unwrap(), } } @@ -915,12 +913,11 @@ pub fn decrease_additional_validator_stake( Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::DecreaseAdditionalValidatorStake { + data: borsh::to_vec(&StakePoolInstruction::DecreaseAdditionalValidatorStake { lamports, transient_stake_seed, ephemeral_stake_seed, - } - .try_to_vec() + }) .unwrap(), } } @@ -955,11 +952,10 @@ pub fn decrease_validator_stake_with_reserve( Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::DecreaseValidatorStakeWithReserve { + data: borsh::to_vec(&StakePoolInstruction::DecreaseValidatorStakeWithReserve { lamports, transient_stake_seed, - } - .try_to_vec() + }) .unwrap(), } } @@ -999,11 +995,10 @@ pub fn increase_validator_stake( Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::IncreaseValidatorStake { + data: borsh::to_vec(&StakePoolInstruction::IncreaseValidatorStake { lamports, transient_stake_seed, - } - .try_to_vec() + }) .unwrap(), } } @@ -1045,12 +1040,11 @@ pub fn increase_additional_validator_stake( Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::IncreaseAdditionalValidatorStake { + data: borsh::to_vec(&StakePoolInstruction::IncreaseAdditionalValidatorStake { lamports, transient_stake_seed, ephemeral_stake_seed, - } - .try_to_vec() + }) .unwrap(), } } @@ -1097,13 +1091,12 @@ pub fn redelegate( Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::Redelegate { + data: borsh::to_vec(&StakePoolInstruction::Redelegate { lamports, source_transient_stake_seed, ephemeral_stake_seed, destination_transient_stake_seed, - } - .try_to_vec() + }) .unwrap(), } } @@ -1124,11 +1117,10 @@ pub fn set_preferred_validator( AccountMeta::new_readonly(*staker, true), AccountMeta::new_readonly(*validator_list_address, false), ], - data: StakePoolInstruction::SetPreferredValidator { + data: borsh::to_vec(&StakePoolInstruction::SetPreferredValidator { validator_type, validator_vote_address, - } - .try_to_vec() + }) .unwrap(), } } @@ -1421,11 +1413,10 @@ pub fn update_validator_list_balance( Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::UpdateValidatorListBalance { + data: borsh::to_vec(&StakePoolInstruction::UpdateValidatorListBalance { start_index, no_merge, - } - .try_to_vec() + }) .unwrap(), } } @@ -1489,11 +1480,10 @@ pub fn update_validator_list_balance_chunk( Ok(Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::UpdateValidatorListBalance { + data: borsh::to_vec(&StakePoolInstruction::UpdateValidatorListBalance { start_index: start_index.try_into().unwrap(), no_merge, - } - .try_to_vec() + }) .unwrap(), }) } @@ -1563,9 +1553,7 @@ pub fn update_stake_pool_balance( Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::UpdateStakePoolBalance - .try_to_vec() - .unwrap(), + data: borsh::to_vec(&StakePoolInstruction::UpdateStakePoolBalance).unwrap(), } } @@ -1583,9 +1571,7 @@ pub fn cleanup_removed_validator_entries( Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::CleanupRemovedValidatorEntries - .try_to_vec() - .unwrap(), + data: borsh::to_vec(&StakePoolInstruction::CleanupRemovedValidatorEntries).unwrap(), } } @@ -1788,17 +1774,16 @@ fn deposit_stake_internal( Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::DepositStakeWithSlippage { + data: borsh::to_vec(&StakePoolInstruction::DepositStakeWithSlippage { minimum_pool_tokens_out, - } - .try_to_vec() + }) .unwrap(), } } else { Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::DepositStake.try_to_vec().unwrap(), + data: borsh::to_vec(&StakePoolInstruction::DepositStake).unwrap(), } }, ); @@ -1990,20 +1975,17 @@ fn deposit_sol_internal( Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::DepositSolWithSlippage { + data: borsh::to_vec(&StakePoolInstruction::DepositSolWithSlippage { lamports_in, minimum_pool_tokens_out, - } - .try_to_vec() + }) .unwrap(), } } else { Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::DepositSol(lamports_in) - .try_to_vec() - .unwrap(), + data: borsh::to_vec(&StakePoolInstruction::DepositSol(lamports_in)).unwrap(), } } } @@ -2175,20 +2157,17 @@ fn withdraw_stake_internal( Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::WithdrawStakeWithSlippage { + data: borsh::to_vec(&StakePoolInstruction::WithdrawStakeWithSlippage { pool_tokens_in, minimum_lamports_out, - } - .try_to_vec() + }) .unwrap(), } } else { Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::WithdrawStake(pool_tokens_in) - .try_to_vec() - .unwrap(), + data: borsh::to_vec(&StakePoolInstruction::WithdrawStake(pool_tokens_in)).unwrap(), } } } @@ -2298,20 +2277,17 @@ fn withdraw_sol_internal( Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::WithdrawSolWithSlippage { + data: borsh::to_vec(&StakePoolInstruction::WithdrawSolWithSlippage { pool_tokens_in, minimum_lamports_out, - } - .try_to_vec() + }) .unwrap(), } } else { Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::WithdrawSol(pool_tokens_in) - .try_to_vec() - .unwrap(), + data: borsh::to_vec(&StakePoolInstruction::WithdrawSol(pool_tokens_in)).unwrap(), } } } @@ -2467,7 +2443,7 @@ pub fn set_manager( Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::SetManager.try_to_vec().unwrap(), + data: borsh::to_vec(&StakePoolInstruction::SetManager).unwrap(), } } @@ -2485,7 +2461,7 @@ pub fn set_fee( Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::SetFee { fee }.try_to_vec().unwrap(), + data: borsh::to_vec(&StakePoolInstruction::SetFee { fee }).unwrap(), } } @@ -2504,7 +2480,7 @@ pub fn set_staker( Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::SetStaker.try_to_vec().unwrap(), + data: borsh::to_vec(&StakePoolInstruction::SetStaker).unwrap(), } } @@ -2526,9 +2502,7 @@ pub fn set_funding_authority( Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::SetFundingAuthority(funding_type) - .try_to_vec() - .unwrap(), + data: borsh::to_vec(&StakePoolInstruction::SetFundingAuthority(funding_type)).unwrap(), } } @@ -2558,8 +2532,7 @@ pub fn update_token_metadata( Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::UpdateTokenMetadata { name, symbol, uri } - .try_to_vec() + data: borsh::to_vec(&StakePoolInstruction::UpdateTokenMetadata { name, symbol, uri }) .unwrap(), } } @@ -2594,8 +2567,7 @@ pub fn create_token_metadata( Instruction { program_id: *program_id, accounts, - data: StakePoolInstruction::CreateTokenMetadata { name, symbol, uri } - .try_to_vec() + data: borsh::to_vec(&StakePoolInstruction::CreateTokenMetadata { name, symbol, uri }) .unwrap(), } } diff --git a/program/src/processor.rs b/program/src/processor.rs index 6f5ef75f..893346eb 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -24,7 +24,7 @@ use { num_traits::FromPrimitive, solana_program::{ account_info::{next_account_info, AccountInfo}, - borsh0_10::try_from_slice_unchecked, + borsh1::try_from_slice_unchecked, clock::{Clock, Epoch}, decode_error::DecodeError, entrypoint::ProgramResult, diff --git a/program/src/state.rs b/program/src/state.rs index b453b1b5..e2b79d53 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -11,7 +11,7 @@ use { num_traits::{FromPrimitive, ToPrimitive}, solana_program::{ account_info::AccountInfo, - borsh0_10::get_instance_packed_len, + borsh1::get_instance_packed_len, msg, program_error::ProgramError, program_memory::sol_memcmp, @@ -1056,7 +1056,7 @@ mod test { super::*, proptest::prelude::*, solana_program::{ - borsh0_10::{get_packed_len, try_from_slice_unchecked}, + borsh1::{get_packed_len, try_from_slice_unchecked}, clock::{DEFAULT_SLOTS_PER_EPOCH, DEFAULT_S_PER_SLOT, SECONDS_PER_DAY}, native_token::LAMPORTS_PER_SOL, }, @@ -1162,7 +1162,7 @@ mod test { fn validator_list_deserialize_mut_slice() { let max_validators = 10; let stake_list = test_validator_list(max_validators); - let mut serialized = stake_list.try_to_vec().unwrap(); + let mut serialized = borsh::to_vec(&stake_list).unwrap(); let (header, mut big_vec) = ValidatorListHeader::deserialize_vec(&mut serialized).unwrap(); let list = ValidatorListHeader::deserialize_mut_slice( &mut big_vec, @@ -1207,7 +1207,7 @@ mod test { fn validator_list_iter() { let max_validators = 10; let stake_list = test_validator_list(max_validators); - let mut serialized = stake_list.try_to_vec().unwrap(); + let mut serialized = borsh::to_vec(&stake_list).unwrap(); let (_, big_vec) = ValidatorListHeader::deserialize_vec(&mut serialized).unwrap(); for (a, b) in big_vec .deserialize_slice::(0, big_vec.len() as usize) diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 23bb69dc..0b333e47 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -4,10 +4,9 @@ mod helpers; use { - borsh::BorshSerialize, helpers::*, solana_program::{ - borsh0_10::try_from_slice_unchecked, + borsh1::try_from_slice_unchecked, instruction::{AccountMeta, Instruction, InstructionError}, pubkey::Pubkey, stake, sysvar, @@ -498,9 +497,7 @@ async fn fail_with_wrong_stake_program_id() { let instruction = Instruction { program_id: id(), accounts, - data: instruction::StakePoolInstruction::DepositStake - .try_to_vec() - .unwrap(), + data: borsh::to_vec(&instruction::StakePoolInstruction::DepositStake).unwrap(), }; let mut transaction = diff --git a/program/tests/deposit_authority.rs b/program/tests/deposit_authority.rs index 9d64f6da..e5e46a7e 100644 --- a/program/tests/deposit_authority.rs +++ b/program/tests/deposit_authority.rs @@ -8,7 +8,7 @@ use { solana_program::{instruction::InstructionError, stake}, solana_program_test::*, solana_sdk::{ - borsh0_10::try_from_slice_unchecked, + borsh1::try_from_slice_unchecked, signature::{Keypair, Signer}, transaction::TransactionError, }, diff --git a/program/tests/deposit_edge_cases.rs b/program/tests/deposit_edge_cases.rs index c893e0ce..510e2f94 100644 --- a/program/tests/deposit_edge_cases.rs +++ b/program/tests/deposit_edge_cases.rs @@ -6,7 +6,7 @@ mod helpers; use { helpers::*, solana_program::{ - borsh0_10::try_from_slice_unchecked, instruction::InstructionError, pubkey::Pubkey, stake, + borsh1::try_from_slice_unchecked, instruction::InstructionError, pubkey::Pubkey, stake, }, solana_program_test::*, solana_sdk::{ diff --git a/program/tests/deposit_sol.rs b/program/tests/deposit_sol.rs index bc983520..fa7ef355 100644 --- a/program/tests/deposit_sol.rs +++ b/program/tests/deposit_sol.rs @@ -6,7 +6,7 @@ mod helpers; use { helpers::*, solana_program::{ - borsh0_10::try_from_slice_unchecked, instruction::InstructionError, pubkey::Pubkey, + borsh1::try_from_slice_unchecked, instruction::InstructionError, pubkey::Pubkey, }, solana_program_test::*, solana_sdk::{ diff --git a/program/tests/force_destake.rs b/program/tests/force_destake.rs index 0b86a91f..bab4003a 100644 --- a/program/tests/force_destake.rs +++ b/program/tests/force_destake.rs @@ -6,7 +6,7 @@ mod helpers; use { helpers::*, solana_program::{ - borsh0_10::try_from_slice_unchecked, + borsh1::try_from_slice_unchecked, instruction::InstructionError, pubkey::Pubkey, stake::{ diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index 23f14657..b68d7c8c 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -1,9 +1,9 @@ #![allow(dead_code)] use { - borsh::{BorshDeserialize, BorshSerialize}, + borsh::BorshDeserialize, solana_program::{ - borsh0_10::{get_instance_packed_len, get_packed_len, try_from_slice_unchecked}, + borsh1::{get_instance_packed_len, get_packed_len, try_from_slice_unchecked}, hash::Hash, instruction::Instruction, program_option::COption, @@ -2539,7 +2539,7 @@ pub fn add_stake_pool_account( stake_pool_pubkey: &Pubkey, stake_pool: &state::StakePool, ) { - let mut stake_pool_bytes = stake_pool.try_to_vec().unwrap(); + let mut stake_pool_bytes = borsh::to_vec(&stake_pool).unwrap(); // more room for optionals stake_pool_bytes.extend_from_slice(Pubkey::default().as_ref()); stake_pool_bytes.extend_from_slice(Pubkey::default().as_ref()); @@ -2559,11 +2559,11 @@ pub fn add_validator_list_account( validator_list: &state::ValidatorList, max_validators: u32, ) { - let mut validator_list_bytes = validator_list.try_to_vec().unwrap(); + let mut validator_list_bytes = borsh::to_vec(&validator_list).unwrap(); // add extra room if needed for _ in validator_list.validators.len()..max_validators as usize { validator_list_bytes - .append(&mut state::ValidatorStakeInfo::default().try_to_vec().unwrap()); + .append(&mut borsh::to_vec(&state::ValidatorStakeInfo::default()).unwrap()); } let validator_list_account = SolanaAccount::create( ACCOUNT_RENT_EXEMPTION, diff --git a/program/tests/huge_pool.rs b/program/tests/huge_pool.rs index f9c44b53..52662095 100644 --- a/program/tests/huge_pool.rs +++ b/program/tests/huge_pool.rs @@ -5,7 +5,7 @@ mod helpers; use { helpers::*, - solana_program::{borsh0_10::try_from_slice_unchecked, pubkey::Pubkey, stake}, + solana_program::{borsh1::try_from_slice_unchecked, pubkey::Pubkey, stake}, solana_program_test::*, solana_sdk::{ native_token::LAMPORTS_PER_SOL, diff --git a/program/tests/initialize.rs b/program/tests/initialize.rs index 109d5273..fa65c709 100644 --- a/program/tests/initialize.rs +++ b/program/tests/initialize.rs @@ -5,10 +5,9 @@ mod helpers; use { - borsh::BorshSerialize, helpers::*, solana_program::{ - borsh0_10::{get_instance_packed_len, get_packed_len, try_from_slice_unchecked}, + borsh1::{get_instance_packed_len, get_packed_len, try_from_slice_unchecked}, hash::Hash, instruction::{AccountMeta, Instruction}, program_pack::Pack, @@ -1200,7 +1199,7 @@ async fn fail_without_manager_signature() { referral_fee: stake_pool_accounts.referral_fee, max_validators: stake_pool_accounts.max_validators, }; - let data = init_data.try_to_vec().unwrap(); + let data = borsh::to_vec(&init_data).unwrap(); let accounts = vec![ AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), true), AccountMeta::new_readonly(stake_pool_accounts.manager.pubkey(), false), diff --git a/program/tests/set_deposit_fee.rs b/program/tests/set_deposit_fee.rs index 6cd6f63d..ba628384 100644 --- a/program/tests/set_deposit_fee.rs +++ b/program/tests/set_deposit_fee.rs @@ -7,7 +7,7 @@ use { helpers::*, solana_program_test::*, solana_sdk::{ - borsh0_10::try_from_slice_unchecked, + borsh1::try_from_slice_unchecked, instruction::InstructionError, signature::{Keypair, Signer}, transaction::{Transaction, TransactionError}, diff --git a/program/tests/set_epoch_fee.rs b/program/tests/set_epoch_fee.rs index 533cad88..c510a813 100644 --- a/program/tests/set_epoch_fee.rs +++ b/program/tests/set_epoch_fee.rs @@ -7,7 +7,7 @@ use { helpers::*, solana_program_test::*, solana_sdk::{ - borsh0_10::try_from_slice_unchecked, + borsh1::try_from_slice_unchecked, instruction::InstructionError, signature::{Keypair, Signer}, transaction::{Transaction, TransactionError}, diff --git a/program/tests/set_funding_authority.rs b/program/tests/set_funding_authority.rs index e8729691..ee2722d8 100644 --- a/program/tests/set_funding_authority.rs +++ b/program/tests/set_funding_authority.rs @@ -4,10 +4,9 @@ mod helpers; use { - borsh::BorshSerialize, helpers::*, solana_program::{ - borsh0_10::try_from_slice_unchecked, + borsh1::try_from_slice_unchecked, hash::Hash, instruction::{AccountMeta, Instruction}, }, @@ -136,9 +135,10 @@ async fn fail_without_signature() { let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_authority) = setup().await; - let data = instruction::StakePoolInstruction::SetFundingAuthority(FundingType::StakeDeposit) - .try_to_vec() - .unwrap(); + let data = borsh::to_vec(&instruction::StakePoolInstruction::SetFundingAuthority( + FundingType::StakeDeposit, + )) + .unwrap(); let accounts = vec![ AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), AccountMeta::new_readonly(stake_pool_accounts.manager.pubkey(), false), diff --git a/program/tests/set_manager.rs b/program/tests/set_manager.rs index e0163e84..3172d3bf 100644 --- a/program/tests/set_manager.rs +++ b/program/tests/set_manager.rs @@ -4,10 +4,9 @@ mod helpers; use { - borsh::BorshSerialize, helpers::*, solana_program::{ - borsh0_10::try_from_slice_unchecked, + borsh1::try_from_slice_unchecked, hash::Hash, instruction::{AccountMeta, Instruction}, }, @@ -134,9 +133,7 @@ async fn test_set_manager_without_existing_signature() { let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_pool_fee, new_manager) = setup().await; - let data = instruction::StakePoolInstruction::SetManager - .try_to_vec() - .unwrap(); + let data = borsh::to_vec(&instruction::StakePoolInstruction::SetManager).unwrap(); let accounts = vec![ AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), AccountMeta::new_readonly(stake_pool_accounts.manager.pubkey(), false), @@ -177,9 +174,7 @@ async fn test_set_manager_without_new_signature() { let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_pool_fee, new_manager) = setup().await; - let data = instruction::StakePoolInstruction::SetManager - .try_to_vec() - .unwrap(); + let data = borsh::to_vec(&instruction::StakePoolInstruction::SetManager).unwrap(); let accounts = vec![ AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), AccountMeta::new_readonly(stake_pool_accounts.manager.pubkey(), true), diff --git a/program/tests/set_preferred.rs b/program/tests/set_preferred.rs index 13a93ace..1a1e3c0f 100644 --- a/program/tests/set_preferred.rs +++ b/program/tests/set_preferred.rs @@ -8,7 +8,7 @@ use { solana_program::hash::Hash, solana_program_test::*, solana_sdk::{ - borsh0_10::try_from_slice_unchecked, + borsh1::try_from_slice_unchecked, instruction::InstructionError, pubkey::Pubkey, signature::{Keypair, Signer}, diff --git a/program/tests/set_referral_fee.rs b/program/tests/set_referral_fee.rs index 45d3ced9..7221e978 100644 --- a/program/tests/set_referral_fee.rs +++ b/program/tests/set_referral_fee.rs @@ -7,7 +7,7 @@ use { helpers::*, solana_program_test::*, solana_sdk::{ - borsh0_10::try_from_slice_unchecked, + borsh1::try_from_slice_unchecked, instruction::InstructionError, signature::{Keypair, Signer}, transaction::{Transaction, TransactionError}, diff --git a/program/tests/set_staker.rs b/program/tests/set_staker.rs index 30d3d491..bef7c883 100644 --- a/program/tests/set_staker.rs +++ b/program/tests/set_staker.rs @@ -4,10 +4,9 @@ mod helpers; use { - borsh::BorshSerialize, helpers::*, solana_program::{ - borsh0_10::try_from_slice_unchecked, + borsh1::try_from_slice_unchecked, hash::Hash, instruction::{AccountMeta, Instruction}, }, @@ -150,9 +149,7 @@ async fn fail_set_staker_without_signature() { let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_staker) = setup().await; - let data = instruction::StakePoolInstruction::SetStaker - .try_to_vec() - .unwrap(); + let data = borsh::to_vec(&instruction::StakePoolInstruction::SetStaker).unwrap(); let accounts = vec![ AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), AccountMeta::new_readonly(stake_pool_accounts.manager.pubkey(), false), diff --git a/program/tests/set_withdrawal_fee.rs b/program/tests/set_withdrawal_fee.rs index a88a9ecc..b36ac693 100644 --- a/program/tests/set_withdrawal_fee.rs +++ b/program/tests/set_withdrawal_fee.rs @@ -7,7 +7,7 @@ use { helpers::*, solana_program_test::*, solana_sdk::{ - borsh0_10::try_from_slice_unchecked, + borsh1::try_from_slice_unchecked, instruction::InstructionError, signature::{Keypair, Signer}, transaction::{Transaction, TransactionError}, diff --git a/program/tests/update_stake_pool_balance.rs b/program/tests/update_stake_pool_balance.rs index 92dd797e..f242e143 100644 --- a/program/tests/update_stake_pool_balance.rs +++ b/program/tests/update_stake_pool_balance.rs @@ -5,7 +5,7 @@ mod helpers; use { helpers::*, - solana_program::{borsh0_10::try_from_slice_unchecked, instruction::InstructionError}, + solana_program::{borsh1::try_from_slice_unchecked, instruction::InstructionError}, solana_program_test::*, solana_sdk::{ hash::Hash, diff --git a/program/tests/update_validator_list_balance.rs b/program/tests/update_validator_list_balance.rs index 31b4e484..7d5d431a 100644 --- a/program/tests/update_validator_list_balance.rs +++ b/program/tests/update_validator_list_balance.rs @@ -5,7 +5,7 @@ mod helpers; use { helpers::*, - solana_program::{borsh0_10::try_from_slice_unchecked, program_pack::Pack}, + solana_program::{borsh1::try_from_slice_unchecked, program_pack::Pack}, solana_program_test::*, solana_sdk::{hash::Hash, signature::Signer, stake::state::StakeStateV2}, spl_stake_pool::{ diff --git a/program/tests/update_validator_list_balance_hijack.rs b/program/tests/update_validator_list_balance_hijack.rs index 973dc59c..66a2ab36 100644 --- a/program/tests/update_validator_list_balance_hijack.rs +++ b/program/tests/update_validator_list_balance_hijack.rs @@ -7,7 +7,7 @@ mod helpers; use { helpers::*, - solana_program::{borsh0_10::try_from_slice_unchecked, pubkey::Pubkey, stake}, + solana_program::{borsh1::try_from_slice_unchecked, pubkey::Pubkey, stake}, solana_program_test::*, solana_sdk::{ hash::Hash, diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index e32a7623..3016a28d 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -5,10 +5,9 @@ mod helpers; use { bincode::deserialize, - borsh::BorshSerialize, helpers::*, solana_program::{ - borsh0_10::try_from_slice_unchecked, + borsh1::try_from_slice_unchecked, hash::Hash, instruction::{AccountMeta, Instruction, InstructionError}, pubkey::Pubkey, @@ -292,13 +291,12 @@ async fn fail_without_signature() { let instruction = Instruction { program_id: id(), accounts, - data: instruction::StakePoolInstruction::AddValidatorToPool( + data: borsh::to_vec(&instruction::StakePoolInstruction::AddValidatorToPool( validator_stake .validator_stake_seed .map(|s| s.get()) .unwrap_or(0), - ) - .try_to_vec() + )) .unwrap(), }; @@ -348,13 +346,12 @@ async fn fail_with_wrong_stake_program_id() { let instruction = Instruction { program_id: id(), accounts, - data: instruction::StakePoolInstruction::AddValidatorToPool( + data: borsh::to_vec(&instruction::StakePoolInstruction::AddValidatorToPool( validator_stake .validator_stake_seed .map(|s| s.get()) .unwrap_or(0), - ) - .try_to_vec() + )) .unwrap(), }; let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); @@ -402,13 +399,12 @@ async fn fail_with_wrong_system_program_id() { let instruction = Instruction { program_id: id(), accounts, - data: instruction::StakePoolInstruction::AddValidatorToPool( + data: borsh::to_vec(&instruction::StakePoolInstruction::AddValidatorToPool( validator_stake .validator_stake_seed .map(|s| s.get()) .unwrap_or(0), - ) - .try_to_vec() + )) .unwrap(), }; let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 0a90f344..46571865 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -5,10 +5,9 @@ mod helpers; use { bincode::deserialize, - borsh::BorshSerialize, helpers::*, solana_program::{ - borsh0_10::try_from_slice_unchecked, + borsh1::try_from_slice_unchecked, instruction::{AccountMeta, Instruction, InstructionError}, pubkey::Pubkey, stake, system_instruction, sysvar, @@ -139,9 +138,7 @@ async fn fail_with_wrong_stake_program_id() { let instruction = Instruction { program_id: id(), accounts, - data: instruction::StakePoolInstruction::RemoveValidatorFromPool - .try_to_vec() - .unwrap(), + data: borsh::to_vec(&instruction::StakePoolInstruction::RemoveValidatorFromPool).unwrap(), }; let mut transaction = @@ -356,9 +353,7 @@ async fn fail_no_signature() { let instruction = Instruction { program_id: id(), accounts, - data: instruction::StakePoolInstruction::RemoveValidatorFromPool - .try_to_vec() - .unwrap(), + data: borsh::to_vec(&instruction::StakePoolInstruction::RemoveValidatorFromPool).unwrap(), }; let transaction = Transaction::new_signed_with_payer( diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index c0154cbd..84401a1e 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -4,10 +4,9 @@ mod helpers; use { - borsh::BorshSerialize, helpers::*, solana_program::{ - borsh0_10::try_from_slice_unchecked, + borsh1::try_from_slice_unchecked, instruction::{AccountMeta, Instruction, InstructionError}, pubkey::Pubkey, sysvar, @@ -291,9 +290,10 @@ async fn fail_with_wrong_stake_program() { let instruction = Instruction { program_id: id(), accounts, - data: instruction::StakePoolInstruction::WithdrawStake(tokens_to_burn) - .try_to_vec() - .unwrap(), + data: borsh::to_vec(&instruction::StakePoolInstruction::WithdrawStake( + tokens_to_burn, + )) + .unwrap(), }; let transaction = Transaction::new_signed_with_payer( diff --git a/program/tests/withdraw_edge_cases.rs b/program/tests/withdraw_edge_cases.rs index 919d2107..8abdc2f8 100644 --- a/program/tests/withdraw_edge_cases.rs +++ b/program/tests/withdraw_edge_cases.rs @@ -8,7 +8,7 @@ use { bincode::deserialize, helpers::*, solana_program::{ - borsh0_10::try_from_slice_unchecked, instruction::InstructionError, pubkey::Pubkey, stake, + borsh1::try_from_slice_unchecked, instruction::InstructionError, pubkey::Pubkey, stake, }, solana_program_test::*, solana_sdk::{signature::Signer, transaction::TransactionError}, diff --git a/program/tests/withdraw_sol.rs b/program/tests/withdraw_sol.rs index e8eb2423..623aa82c 100644 --- a/program/tests/withdraw_sol.rs +++ b/program/tests/withdraw_sol.rs @@ -6,7 +6,7 @@ mod helpers; use { helpers::*, solana_program::{ - borsh0_10::try_from_slice_unchecked, instruction::InstructionError, pubkey::Pubkey, stake, + borsh1::try_from_slice_unchecked, instruction::InstructionError, pubkey::Pubkey, stake, }, solana_program_test::*, solana_sdk::{ From 30b8b965f307952ce4de4f6a93ed4891693322dc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Feb 2024 12:43:40 +0100 Subject: [PATCH 0748/1076] build(deps-dev): bump @types/node from 20.11.21 to 20.11.22 (#6311) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.21 to 20.11.22. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 3fda1d3c..5060afd5 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.11.21", + "@types/node": "^20.11.22", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.1.0", "@typescript-eslint/parser": "^7.1.0", From 7c447eab12383ca754793c0248d247da77afb33e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Mar 2024 12:19:46 +0100 Subject: [PATCH 0749/1076] build(deps-dev): bump @types/node from 20.11.22 to 20.11.24 (#6315) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.22 to 20.11.24. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 5060afd5..b279a68c 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.11.22", + "@types/node": "^20.11.24", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.1.0", "@typescript-eslint/parser": "^7.1.0", From 89a15342ca3b7f6cf00af11c71b3ca6d316c63f3 Mon Sep 17 00:00:00 2001 From: cui fliter Date: Sun, 3 Mar 2024 11:59:21 +0800 Subject: [PATCH 0750/1076] fix some comments (#6318) Signed-off-by: cui fliter --- clients/cli/scripts/withdraw.sh | 2 +- clients/js-legacy/src/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/scripts/withdraw.sh b/clients/cli/scripts/withdraw.sh index 733acec6..6ad2e327 100755 --- a/clients/cli/scripts/withdraw.sh +++ b/clients/cli/scripts/withdraw.sh @@ -68,7 +68,7 @@ create_keypair $authority echo "Withdrawing stakes from stake pool" withdraw_stakes "$stake_pool_pubkey" "$validator_list" "$withdraw_sol_amount" -echo "Withdrawing stakes from stake pool to recieve it in stake receiver account" +echo "Withdrawing stakes from stake pool to receive it in stake receiver account" withdraw_stakes_to_stake_receiver "$stake_pool_pubkey" "$validator_list" "$withdraw_sol_amount" echo "Withdrawing SOL from stake pool to authority" diff --git a/clients/js-legacy/src/index.ts b/clients/js-legacy/src/index.ts index 702bbd18..30791842 100644 --- a/clients/js-legacy/src/index.ts +++ b/clients/js-legacy/src/index.ts @@ -394,7 +394,7 @@ export async function withdrawStake( }); } else if (stakeReceiverAccount && stakeReceiverAccount?.type == 'delegated') { const voteAccount = stakeReceiverAccount.info?.stake?.delegation.voter; - if (!voteAccount) throw new Error(`Invalid stake reciever ${stakeReceiver} delegation`); + if (!voteAccount) throw new Error(`Invalid stake receiver ${stakeReceiver} delegation`); const validatorListAccount = await connection.getAccountInfo( stakePool.account.data.validatorList, ); From f207f1a7dc2b45cabae592896567f42ea37b805a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Mar 2024 13:58:47 +0100 Subject: [PATCH 0751/1076] build(deps): bump @solana/web3.js from 1.90.0 to 1.90.1 (#6322) * build(deps): bump @solana/web3.js from 1.90.0 to 1.90.1 Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.90.0 to 1.90.1. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.90.0...v1.90.1) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Do the upgrade properly * Also update account-compression --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index b279a68c..a1b68d08 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -46,7 +46,7 @@ "@coral-xyz/borsh": "^0.29.0", "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "0.4.0", - "@solana/web3.js": "^1.90.0", + "@solana/web3.js": "^1.90.1", "bn.js": "^5.2.0", "buffer": "^6.0.3", "superstruct": "^1.0.3" From 3ef7a1a89ee036732046878baabde21c6c6b9491 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Mar 2024 13:26:12 +0100 Subject: [PATCH 0752/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 7.1.0 to 7.1.1 (#6333) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.1.0 to 7.1.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.1.1/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index a1b68d08..c91976f0 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.12", "@types/node": "^20.11.24", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^7.1.0", + "@typescript-eslint/eslint-plugin": "^7.1.1", "@typescript-eslint/parser": "^7.1.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", From 4a554d7e5289f8b41b04ad758fa42779105c779a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Mar 2024 13:39:29 +0100 Subject: [PATCH 0753/1076] build(deps-dev): bump @typescript-eslint/parser from 7.1.0 to 7.1.1 (#6334) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.1.0 to 7.1.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.1.1/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index c91976f0..87fdd79d 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.11.24", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.1.1", - "@typescript-eslint/parser": "^7.1.0", + "@typescript-eslint/parser": "^7.1.1", "cross-env": "^7.0.3", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", From 53dc94baff4869b64385103a87b44bde754cb223 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Mar 2024 13:01:21 +0100 Subject: [PATCH 0754/1076] build(deps-dev): bump rollup from 4.12.0 to 4.12.1 (#6341) Bumps [rollup](https://github.com/rollup/rollup) from 4.12.0 to 4.12.1. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.12.0...v4.12.1) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 87fdd79d..cf6414f7 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.2.5", "rimraf": "^5.0.0", - "rollup": "^4.12.0", + "rollup": "^4.12.1", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.1.2", "typescript": "^5.3.3" From 181c8275582fc203840d1dcddf450591ca5deb30 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Mar 2024 12:53:29 +0100 Subject: [PATCH 0755/1076] build(deps-dev): bump typescript from 5.3.3 to 5.4.2 (#6351) Bumps [typescript](https://github.com/Microsoft/TypeScript) from 5.3.3 to 5.4.2. - [Release notes](https://github.com/Microsoft/TypeScript/releases) - [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml) - [Commits](https://github.com/Microsoft/TypeScript/compare/v5.3.3...v5.4.2) --- updated-dependencies: - dependency-name: typescript dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index cf6414f7..c4441e08 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -75,7 +75,7 @@ "rollup": "^4.12.1", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.1.2", - "typescript": "^5.3.3" + "typescript": "^5.4.2" }, "jest": { "moduleFileExtensions": [ From 5c800f1d417f37e4fa7de82d987c0fa1a797da38 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Mar 2024 13:12:52 +0100 Subject: [PATCH 0756/1076] build(deps-dev): bump @types/node from 20.11.24 to 20.11.25 (#6356) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.24 to 20.11.25. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index c4441e08..0fbb365e 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.11.24", + "@types/node": "^20.11.25", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.1.1", "@typescript-eslint/parser": "^7.1.1", From 1a3b001c3939c2395dd5bacf6c145f430d398453 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 Mar 2024 13:39:14 +0100 Subject: [PATCH 0757/1076] build(deps): bump @solana/web3.js from 1.90.1 to 1.91.0 (#6360) * build(deps): bump @solana/web3.js from 1.90.1 to 1.91.0 Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.90.1 to 1.91.0. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.90.1...v1.91.0) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Fixup packages --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 0fbb365e..0e239df2 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -46,7 +46,7 @@ "@coral-xyz/borsh": "^0.29.0", "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "0.4.0", - "@solana/web3.js": "^1.90.1", + "@solana/web3.js": "^1.91.0", "bn.js": "^5.2.0", "buffer": "^6.0.3", "superstruct": "^1.0.3" From 4416a8b87492dd6bfd6d839841648be1066e7ad6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Mar 2024 12:29:33 +0100 Subject: [PATCH 0758/1076] build(deps-dev): bump @typescript-eslint/parser from 7.1.1 to 7.2.0 (#6397) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.1.1 to 7.2.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.2.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 0e239df2..fee81944 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.11.25", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.1.1", - "@typescript-eslint/parser": "^7.1.1", + "@typescript-eslint/parser": "^7.2.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", From 7c21b4e512e125637838846c92078d7f12e974f1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Mar 2024 12:29:43 +0100 Subject: [PATCH 0759/1076] build(deps-dev): bump @types/node from 20.11.25 to 20.11.26 (#6399) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.25 to 20.11.26. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index fee81944..75a8b5df 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.11.25", + "@types/node": "^20.11.26", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.1.1", "@typescript-eslint/parser": "^7.2.0", From 958846fc76c9d2c79e28c0f7a0cb22923d505967 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Mar 2024 12:29:54 +0100 Subject: [PATCH 0760/1076] build(deps-dev): bump rollup from 4.12.1 to 4.13.0 (#6400) Bumps [rollup](https://github.com/rollup/rollup) from 4.12.1 to 4.13.0. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.12.1...v4.13.0) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 75a8b5df..9660b28a 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.2.5", "rimraf": "^5.0.0", - "rollup": "^4.12.1", + "rollup": "^4.13.0", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.1.2", "typescript": "^5.4.2" From 4c9d2fa74d0a155e13b729c1439ebcfba1c13669 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Mar 2024 12:30:05 +0100 Subject: [PATCH 0761/1076] build(deps): bump superstruct from 1.0.3 to 1.0.4 (#6402) Bumps [superstruct](https://github.com/ianstormtaylor/superstruct) from 1.0.3 to 1.0.4. - [Release notes](https://github.com/ianstormtaylor/superstruct/releases) - [Changelog](https://github.com/ianstormtaylor/superstruct/blob/main/Changelog.md) - [Commits](https://github.com/ianstormtaylor/superstruct/compare/v1.0.3...v1.0.4) --- updated-dependencies: - dependency-name: superstruct dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 9660b28a..fe35f74c 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -49,7 +49,7 @@ "@solana/web3.js": "^1.91.0", "bn.js": "^5.2.0", "buffer": "^6.0.3", - "superstruct": "^1.0.3" + "superstruct": "^1.0.4" }, "devDependencies": { "@rollup/plugin-alias": "^5.1.0", From 488451086e71558239d2628c309d53d7ef26c0a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Mar 2024 13:08:26 +0100 Subject: [PATCH 0762/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 7.1.1 to 7.2.0 (#6403) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.1.1 to 7.2.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.2.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index fe35f74c..4ae684bf 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.12", "@types/node": "^20.11.26", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^7.1.1", + "@typescript-eslint/eslint-plugin": "^7.2.0", "@typescript-eslint/parser": "^7.2.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", From 12f25154c0fe5ba4832ed3e4cf1e15f24e261bcd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Mar 2024 12:38:01 +0100 Subject: [PATCH 0763/1076] build(deps): bump bytemuck from 1.14.3 to 1.15.0 (#6415) Bumps [bytemuck](https://github.com/Lokathor/bytemuck) from 1.14.3 to 1.15.0. - [Changelog](https://github.com/Lokathor/bytemuck/blob/main/changelog.md) - [Commits](https://github.com/Lokathor/bytemuck/compare/v1.14.3...v1.15.0) --- updated-dependencies: - dependency-name: bytemuck dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index cf9a13fe..78c19415 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -14,7 +14,7 @@ test-sbf = [] [dependencies] arrayref = "0.3.7" borsh = "1.2.1" -bytemuck = "1.14" +bytemuck = "1.15" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.2" From 869a111bf06a10b461d4ee27142bc9ec32329efe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Mar 2024 11:59:28 +0100 Subject: [PATCH 0764/1076] build(deps-dev): bump @types/node from 20.11.26 to 20.11.27 (#6436) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.26 to 20.11.27. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 4ae684bf..3ab72d9f 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.11.26", + "@types/node": "^20.11.27", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.2.0", "@typescript-eslint/parser": "^7.2.0", From 0bea44789aee30229dfd9451b1c9184f16ec7332 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Mar 2024 13:12:35 +0100 Subject: [PATCH 0765/1076] build(deps): bump @solana/web3.js from 1.91.0 to 1.91.1 (#6435) * build(deps): bump @solana/web3.js from 1.91.0 to 1.91.1 Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.91.0 to 1.91.1. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.91.0...v1.91.1) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Do the upgrade correctly --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 3ab72d9f..5a8b1063 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -46,7 +46,7 @@ "@coral-xyz/borsh": "^0.29.0", "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "0.4.0", - "@solana/web3.js": "^1.91.0", + "@solana/web3.js": "^1.91.1", "bn.js": "^5.2.0", "buffer": "^6.0.3", "superstruct": "^1.0.4" From 6f347b389ace8709f87d19c6328282aaa7c850e9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Mar 2024 01:25:25 +0100 Subject: [PATCH 0766/1076] build(deps-dev): bump @types/node from 20.11.27 to 20.11.28 (#6438) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.27 to 20.11.28. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 5a8b1063..df869d04 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.11.27", + "@types/node": "^20.11.28", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.2.0", "@typescript-eslint/parser": "^7.2.0", From 0abc13db14d5a752457b5c94abf94e5fb45a46ee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Mar 2024 12:50:27 +0100 Subject: [PATCH 0767/1076] build(deps-dev): bump @typescript-eslint/parser from 7.2.0 to 7.3.1 (#6455) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.2.0 to 7.3.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.3.1/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index df869d04..95ee5955 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.11.28", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.2.0", - "@typescript-eslint/parser": "^7.2.0", + "@typescript-eslint/parser": "^7.3.1", "cross-env": "^7.0.3", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", From 0d17de814bb78a2b216930ebd4368971260c441a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Mar 2024 12:50:37 +0100 Subject: [PATCH 0768/1076] build(deps-dev): bump @types/node from 20.11.28 to 20.11.29 (#6457) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.28 to 20.11.29. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 95ee5955..1d9aa5e9 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.11.28", + "@types/node": "^20.11.29", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.2.0", "@typescript-eslint/parser": "^7.3.1", From 077b505d9a743cdf1c3762af328303e477c094e9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Mar 2024 13:06:36 +0100 Subject: [PATCH 0769/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 7.2.0 to 7.3.1 (#6456) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.2.0 to 7.3.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.3.1/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 1d9aa5e9..2dff028a 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.12", "@types/node": "^20.11.29", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^7.2.0", + "@typescript-eslint/eslint-plugin": "^7.3.1", "@typescript-eslint/parser": "^7.3.1", "cross-env": "^7.0.3", "eslint": "^8.57.0", From 56fcb15babc4445aa78420ff6bd25f2f6b53041e Mon Sep 17 00:00:00 2001 From: Max Kaplan Date: Tue, 19 Mar 2024 19:18:06 -0400 Subject: [PATCH 0770/1076] stake-pool: supporting AddValidatorToPool in js library (#6459) --- clients/js-legacy/src/index.ts | 49 +++++++++++ clients/js-legacy/src/instructions.ts | 58 ++++++++++++- .../js-legacy/src/utils/program-address.ts | 7 +- clients/js-legacy/src/utils/stake.ts | 1 + clients/js-legacy/test/instructions.test.ts | 83 ++++++++++++++++++- 5 files changed, 195 insertions(+), 3 deletions(-) diff --git a/clients/js-legacy/src/index.ts b/clients/js-legacy/src/index.ts index 30791842..4b498194 100644 --- a/clients/js-legacy/src/index.ts +++ b/clients/js-legacy/src/index.ts @@ -649,6 +649,55 @@ export async function withdrawSol( }; } +export async function addValidatorToPool( + connection: Connection, + stakePoolAddress: PublicKey, + validatorVote: PublicKey, + seed?: number, +) { + const stakePoolAccount = await getStakePoolAccount(connection, stakePoolAddress); + const stakePool = stakePoolAccount.account.data; + const { reserveStake, staker, validatorList } = stakePool; + + const validatorListAccount = await getValidatorListAccount(connection, validatorList); + + const validatorInfo = validatorListAccount.account.data.validators.find( + (v) => v.voteAccountAddress.toBase58() == validatorVote.toBase58(), + ); + + if (validatorInfo) { + throw new Error('Vote account is already in validator list'); + } + + const withdrawAuthority = await findWithdrawAuthorityProgramAddress( + STAKE_POOL_PROGRAM_ID, + stakePoolAddress, + ); + + const validatorStake = await findStakeProgramAddress( + STAKE_POOL_PROGRAM_ID, + validatorVote, + stakePoolAddress, + seed, + ); + + const instructions: TransactionInstruction[] = [ + StakePoolInstruction.addValidatorToPool({ + stakePool: stakePoolAddress, + staker: staker, + reserveStake: reserveStake, + withdrawAuthority: withdrawAuthority, + validatorList: validatorList, + validatorStake: validatorStake, + validatorVote: validatorVote, + }), + ]; + + return { + instructions, + }; +} + /** * Creates instructions required to increase validator stake. */ diff --git a/clients/js-legacy/src/instructions.ts b/clients/js-legacy/src/instructions.ts index 9891f17b..d758a3c9 100644 --- a/clients/js-legacy/src/instructions.ts +++ b/clients/js-legacy/src/instructions.ts @@ -36,7 +36,8 @@ export type StakePoolInstructionType = | 'IncreaseAdditionalValidatorStake' | 'DecreaseAdditionalValidatorStake' | 'DecreaseValidatorStakeWithReserve' - | 'Redelegate'; + | 'Redelegate' + | 'AddValidatorToPool'; // 'UpdateTokenMetadata' and 'CreateTokenMetadata' have dynamic layouts @@ -91,6 +92,10 @@ export function tokenMetadataLayout( export const STAKE_POOL_INSTRUCTION_LAYOUTS: { [type in StakePoolInstructionType]: InstructionType; } = Object.freeze({ + AddValidatorToPool: { + index: 1, + layout: BufferLayout.struct([BufferLayout.u8('instruction'), BufferLayout.u32('seed')]), + }, DecreaseValidatorStake: { index: 3, layout: MOVE_STAKE_LAYOUT, @@ -376,10 +381,61 @@ export type UpdateTokenMetadataParams = { uri: string; }; +export type AddValidatorToPoolParams = { + stakePool: PublicKey; + staker: PublicKey; + reserveStake: PublicKey; + withdrawAuthority: PublicKey; + validatorList: PublicKey; + validatorStake: PublicKey; + validatorVote: PublicKey; + seed?: number; +}; + /** * Stake Pool Instruction class */ export class StakePoolInstruction { + /** + * Creates instruction to add a validator into the stake pool. + */ + static addValidatorToPool(params: AddValidatorToPoolParams): TransactionInstruction { + const { + stakePool, + staker, + reserveStake, + withdrawAuthority, + validatorList, + validatorStake, + validatorVote, + seed, + } = params; + const type = STAKE_POOL_INSTRUCTION_LAYOUTS.AddValidatorToPool; + const data = encodeData(type, { seed: seed == undefined ? 0 : seed }); + + const keys = [ + { pubkey: stakePool, isSigner: false, isWritable: true }, + { pubkey: staker, isSigner: true, isWritable: false }, + { pubkey: reserveStake, isSigner: false, isWritable: true }, + { pubkey: withdrawAuthority, isSigner: false, isWritable: false }, + { pubkey: validatorList, isSigner: false, isWritable: true }, + { pubkey: validatorStake, isSigner: false, isWritable: true }, + { pubkey: validatorVote, isSigner: false, isWritable: false }, + { pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false }, + { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false }, + { pubkey: SYSVAR_STAKE_HISTORY_PUBKEY, isSigner: false, isWritable: false }, + { pubkey: STAKE_CONFIG_ID, isSigner: false, isWritable: false }, + { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, + { pubkey: StakeProgram.programId, isSigner: false, isWritable: false }, + ]; + + return new TransactionInstruction({ + programId: STAKE_POOL_PROGRAM_ID, + keys, + data, + }); + } + /** * Creates instruction to update a set of validators in the stake pool. */ diff --git a/clients/js-legacy/src/utils/program-address.ts b/clients/js-legacy/src/utils/program-address.ts index 5b95ca18..827f4021 100644 --- a/clients/js-legacy/src/utils/program-address.ts +++ b/clients/js-legacy/src/utils/program-address.ts @@ -28,9 +28,14 @@ export async function findStakeProgramAddress( programId: PublicKey, voteAccountAddress: PublicKey, stakePoolAddress: PublicKey, + seed?: number, ) { const [publicKey] = await PublicKey.findProgramAddress( - [voteAccountAddress.toBuffer(), stakePoolAddress.toBuffer()], + [ + voteAccountAddress.toBuffer(), + stakePoolAddress.toBuffer(), + seed ? new BN(seed).toArrayLike(Buffer, 'le', 4) : Buffer.alloc(0), + ], programId, ); return publicKey; diff --git a/clients/js-legacy/src/utils/stake.ts b/clients/js-legacy/src/utils/stake.ts index 25535431..55debbf6 100644 --- a/clients/js-legacy/src/utils/stake.ts +++ b/clients/js-legacy/src/utils/stake.ts @@ -25,6 +25,7 @@ export async function getValidatorListAccount(connection: Connection, pubkey: Pu if (!account) { throw new Error('Invalid validator list account'); } + return { pubkey, account: { diff --git a/clients/js-legacy/test/instructions.test.ts b/clients/js-legacy/test/instructions.test.ts index 1a39ddff..6f4b564c 100644 --- a/clients/js-legacy/test/instructions.test.ts +++ b/clients/js-legacy/test/instructions.test.ts @@ -12,14 +12,16 @@ import { Connection, Keypair, SystemProgram, + StakeProgram, AccountInfo, LAMPORTS_PER_SOL, } from '@solana/web3.js'; import { TOKEN_PROGRAM_ID, TokenAccountNotFoundError } from '@solana/spl-token'; -import { StakePoolLayout } from '../src/layouts'; +import { StakePoolLayout, ValidatorListLayout } from '../src/layouts'; import { STAKE_POOL_INSTRUCTION_LAYOUTS, DepositSolParams, + AddValidatorToPoolParams, StakePoolInstruction, depositSol, withdrawSol, @@ -29,6 +31,7 @@ import { createPoolTokenMetadata, updatePoolTokenMetadata, tokenMetadataLayout, + addValidatorToPool, } from '../src'; import { decodeData } from '../src/utils'; @@ -42,6 +45,7 @@ import { CONSTANTS, stakeAccountData, uninitializedStakeAccount, + validatorListMock, } from './mocks'; describe('StakePoolProgram', () => { @@ -61,6 +65,40 @@ describe('StakePoolProgram', () => { data, }; + it('StakePoolInstruction.addValidatorToPool', () => { + const payload: AddValidatorToPoolParams = { + stakePool: stakePoolAddress, + staker: Keypair.generate().publicKey, + reserveStake: Keypair.generate().publicKey, + withdrawAuthority: Keypair.generate().publicKey, + validatorList: Keypair.generate().publicKey, + validatorStake: Keypair.generate().publicKey, + validatorVote: PublicKey.default, + seed: 0, + }; + + const instruction = StakePoolInstruction.addValidatorToPool(payload); + expect(instruction.keys).toHaveLength(13); + expect(instruction.keys[0].pubkey).toEqual(payload.stakePool); + expect(instruction.keys[1].pubkey).toEqual(payload.staker); + expect(instruction.keys[2].pubkey).toEqual(payload.reserveStake); + expect(instruction.keys[3].pubkey).toEqual(payload.withdrawAuthority); + expect(instruction.keys[4].pubkey).toEqual(payload.validatorList); + expect(instruction.keys[5].pubkey).toEqual(payload.validatorStake); + expect(instruction.keys[6].pubkey).toEqual(payload.validatorVote); + expect(instruction.keys[11].pubkey).toEqual(SystemProgram.programId); + expect(instruction.keys[12].pubkey).toEqual(StakeProgram.programId); + + const decodedData = decodeData( + STAKE_POOL_INSTRUCTION_LAYOUTS.AddValidatorToPool, + instruction.data, + ); + expect(decodedData.instruction).toEqual( + STAKE_POOL_INSTRUCTION_LAYOUTS.AddValidatorToPool.index, + ); + expect(decodedData.seed).toEqual(payload.seed); + }); + it('StakePoolInstruction.depositSol', () => { const payload: DepositSolParams = { stakePool: stakePoolAddress, @@ -99,6 +137,49 @@ describe('StakePoolProgram', () => { expect(instruction2.keys[10].pubkey).toEqual(payload.depositAuthority); }); + describe('addValidatorToPool', () => { + const validatorList = mockValidatorList(); + const decodedValidatorList = ValidatorListLayout.decode(validatorList.data); + const voteAccount = decodedValidatorList.validators[0].voteAccountAddress; + + it('should throw an error when trying to add an existing validator', async () => { + connection.getAccountInfo = jest.fn(async (pubKey) => { + if (pubKey === stakePoolAddress) { + return stakePoolAccount; + } + return mockValidatorList(); + }); + await expect(addValidatorToPool(connection, stakePoolAddress, voteAccount)).rejects.toThrow( + Error('Vote account is already in validator list'), + ); + }); + + it('should successfully add a validator', async () => { + connection.getAccountInfo = jest.fn(async (pubKey) => { + if (pubKey === stakePoolAddress) { + return stakePoolAccount; + } + return >{ + executable: true, + owner: new PublicKey(0), + lamports: 0, + data, + }; + }); + const res = await addValidatorToPool( + connection, + stakePoolAddress, + validatorListMock.validators[0].voteAccountAddress, + ); + expect((connection.getAccountInfo as jest.Mock).mock.calls.length).toBe(2); + expect(res.instructions).toHaveLength(1); + // Make sure that the validator vote account being added is the one we passed + expect(res.instructions[0].keys[6].pubkey).toEqual( + validatorListMock.validators[0].voteAccountAddress, + ); + }); + }); + describe('depositSol', () => { const from = Keypair.generate().publicKey; const balance = 10000; From 50da7328b83acb3f0eafd66e7f7c2f5aff2e5746 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Mar 2024 13:21:49 +0100 Subject: [PATCH 0771/1076] build(deps-dev): bump @types/node from 20.11.29 to 20.11.30 (#6462) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.29 to 20.11.30. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 2dff028a..9aa5f9d3 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.11.29", + "@types/node": "^20.11.30", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.3.1", "@typescript-eslint/parser": "^7.3.1", From 1c9f724ce695c50832d8b8d2306e71cf844d53e2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Mar 2024 12:27:17 +0100 Subject: [PATCH 0772/1076] build(deps-dev): bump typescript from 5.4.2 to 5.4.3 (#6471) Bumps [typescript](https://github.com/Microsoft/TypeScript) from 5.4.2 to 5.4.3. - [Release notes](https://github.com/Microsoft/TypeScript/releases) - [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml) - [Commits](https://github.com/Microsoft/TypeScript/compare/v5.4.2...v5.4.3) --- updated-dependencies: - dependency-name: typescript dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 9aa5f9d3..c0fa98d6 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -75,7 +75,7 @@ "rollup": "^4.13.0", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.1.2", - "typescript": "^5.4.2" + "typescript": "^5.4.3" }, "jest": { "moduleFileExtensions": [ From cea4a6cffd524f78d9f6178aba60452a827a5b04 Mon Sep 17 00:00:00 2001 From: SolBlaze Date: Thu, 21 Mar 2024 11:13:54 -0700 Subject: [PATCH 0773/1076] stake-pool: Add RemoveValidatorFromPool instruction in JS bindings (#6468) * Add instruction for removeValidatorFromPool to spl-stake-pool JS bindings * Fix imports * Fix test case * Fix test case * Fix incorrect index * Update stake-pool/js/test/instructions.test.ts Co-authored-by: Joe C * Fix linter issues --------- Co-authored-by: Joe C --- clients/js-legacy/src/index.ts | 57 +++++++++++++ clients/js-legacy/src/instructions.ts | 43 +++++++++- clients/js-legacy/test/instructions.test.ts | 90 ++++++++++++++++++++- 3 files changed, 188 insertions(+), 2 deletions(-) diff --git a/clients/js-legacy/src/index.ts b/clients/js-legacy/src/index.ts index 4b498194..ae20fe4e 100644 --- a/clients/js-legacy/src/index.ts +++ b/clients/js-legacy/src/index.ts @@ -698,6 +698,63 @@ export async function addValidatorToPool( }; } +export async function removeValidatorFromPool( + connection: Connection, + stakePoolAddress: PublicKey, + validatorVote: PublicKey, + seed?: number, +) { + const stakePoolAccount = await getStakePoolAccount(connection, stakePoolAddress); + const stakePool = stakePoolAccount.account.data; + const { staker, validatorList } = stakePool; + + const validatorListAccount = await getValidatorListAccount(connection, validatorList); + + const validatorInfo = validatorListAccount.account.data.validators.find( + (v) => v.voteAccountAddress.toBase58() == validatorVote.toBase58(), + ); + + if (!validatorInfo) { + throw new Error('Vote account is not already in validator list'); + } + + const withdrawAuthority = await findWithdrawAuthorityProgramAddress( + STAKE_POOL_PROGRAM_ID, + stakePoolAddress, + ); + + const validatorStake = await findStakeProgramAddress( + STAKE_POOL_PROGRAM_ID, + validatorVote, + stakePoolAddress, + seed, + ); + + const transientStakeSeed = validatorInfo.transientSeedSuffixStart; + + const transientStake = await findTransientStakeProgramAddress( + STAKE_POOL_PROGRAM_ID, + validatorInfo.voteAccountAddress, + stakePoolAddress, + transientStakeSeed, + ); + + const instructions: TransactionInstruction[] = [ + StakePoolInstruction.removeValidatorFromPool({ + stakePool: stakePoolAddress, + staker: staker, + withdrawAuthority, + validatorList, + validatorStake, + transientStake, + }), + ]; + + return { + instructions, + }; +} + /** * Creates instructions required to increase validator stake. */ diff --git a/clients/js-legacy/src/instructions.ts b/clients/js-legacy/src/instructions.ts index d758a3c9..970d6736 100644 --- a/clients/js-legacy/src/instructions.ts +++ b/clients/js-legacy/src/instructions.ts @@ -37,7 +37,8 @@ export type StakePoolInstructionType = | 'DecreaseAdditionalValidatorStake' | 'DecreaseValidatorStakeWithReserve' | 'Redelegate' - | 'AddValidatorToPool'; + | 'AddValidatorToPool' + | 'RemoveValidatorFromPool'; // 'UpdateTokenMetadata' and 'CreateTokenMetadata' have dynamic layouts @@ -96,6 +97,10 @@ export const STAKE_POOL_INSTRUCTION_LAYOUTS: { index: 1, layout: BufferLayout.struct([BufferLayout.u8('instruction'), BufferLayout.u32('seed')]), }, + RemoveValidatorFromPool: { + index: 2, + layout: BufferLayout.struct([BufferLayout.u8('instruction')]), + }, DecreaseValidatorStake: { index: 3, layout: MOVE_STAKE_LAYOUT, @@ -392,6 +397,15 @@ export type AddValidatorToPoolParams = { seed?: number; }; +export type RemoveValidatorFromPoolParams = { + stakePool: PublicKey; + staker: PublicKey; + withdrawAuthority: PublicKey; + validatorList: PublicKey; + validatorStake: PublicKey; + transientStake: PublicKey; +}; + /** * Stake Pool Instruction class */ @@ -436,6 +450,33 @@ export class StakePoolInstruction { }); } + /** + * Creates instruction to remove a validator from the stake pool. + */ + static removeValidatorFromPool(params: RemoveValidatorFromPoolParams): TransactionInstruction { + const { stakePool, staker, withdrawAuthority, validatorList, validatorStake, transientStake } = + params; + const type = STAKE_POOL_INSTRUCTION_LAYOUTS.RemoveValidatorFromPool; + const data = encodeData(type); + + const keys = [ + { pubkey: stakePool, isSigner: false, isWritable: true }, + { pubkey: staker, isSigner: true, isWritable: false }, + { pubkey: withdrawAuthority, isSigner: false, isWritable: false }, + { pubkey: validatorList, isSigner: false, isWritable: true }, + { pubkey: validatorStake, isSigner: false, isWritable: true }, + { pubkey: transientStake, isSigner: false, isWritable: true }, + { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false }, + { pubkey: StakeProgram.programId, isSigner: false, isWritable: false }, + ]; + + return new TransactionInstruction({ + programId: STAKE_POOL_PROGRAM_ID, + keys, + data, + }); + } + /** * Creates instruction to update a set of validators in the stake pool. */ diff --git a/clients/js-legacy/test/instructions.test.ts b/clients/js-legacy/test/instructions.test.ts index 6f4b564c..490e777f 100644 --- a/clients/js-legacy/test/instructions.test.ts +++ b/clients/js-legacy/test/instructions.test.ts @@ -22,6 +22,7 @@ import { STAKE_POOL_INSTRUCTION_LAYOUTS, DepositSolParams, AddValidatorToPoolParams, + RemoveValidatorFromPoolParams, StakePoolInstruction, depositSol, withdrawSol, @@ -32,9 +33,11 @@ import { updatePoolTokenMetadata, tokenMetadataLayout, addValidatorToPool, + removeValidatorFromPool, } from '../src'; +import { STAKE_POOL_PROGRAM_ID } from '../src/constants'; -import { decodeData } from '../src/utils'; +import { decodeData, findStakeProgramAddress } from '../src/utils'; import { mockRpc, @@ -99,6 +102,35 @@ describe('StakePoolProgram', () => { expect(decodedData.seed).toEqual(payload.seed); }); + it('StakePoolInstruction.removeValidatorFromPool', () => { + const payload: RemoveValidatorFromPoolParams = { + stakePool: stakePoolAddress, + staker: Keypair.generate().publicKey, + withdrawAuthority: Keypair.generate().publicKey, + validatorList: Keypair.generate().publicKey, + validatorStake: Keypair.generate().publicKey, + transientStake: Keypair.generate().publicKey, + }; + + const instruction = StakePoolInstruction.removeValidatorFromPool(payload); + expect(instruction.keys).toHaveLength(8); + expect(instruction.keys[0].pubkey).toEqual(payload.stakePool); + expect(instruction.keys[1].pubkey).toEqual(payload.staker); + expect(instruction.keys[2].pubkey).toEqual(payload.withdrawAuthority); + expect(instruction.keys[3].pubkey).toEqual(payload.validatorList); + expect(instruction.keys[4].pubkey).toEqual(payload.validatorStake); + expect(instruction.keys[5].pubkey).toEqual(payload.transientStake); + expect(instruction.keys[7].pubkey).toEqual(StakeProgram.programId); + + const decodedData = decodeData( + STAKE_POOL_INSTRUCTION_LAYOUTS.RemoveValidatorFromPool, + instruction.data, + ); + expect(decodedData.instruction).toEqual( + STAKE_POOL_INSTRUCTION_LAYOUTS.RemoveValidatorFromPool.index, + ); + }); + it('StakePoolInstruction.depositSol', () => { const payload: DepositSolParams = { stakePool: stakePoolAddress, @@ -180,6 +212,62 @@ describe('StakePoolProgram', () => { }); }); + describe('removeValidatorFromPool', () => { + const voteAccount = Keypair.generate().publicKey; + + it('should throw an error when trying to remove a non-existing validator', async () => { + connection.getAccountInfo = jest.fn(async (pubKey) => { + if (pubKey === stakePoolAddress) { + return stakePoolAccount; + } + if (pubKey.equals(stakePoolMock.validatorList)) { + return mockValidatorList(); + } + return >{ + executable: true, + owner: new PublicKey(0), + lamports: 0, + data, + }; + }); + await expect( + removeValidatorFromPool(connection, stakePoolAddress, voteAccount), + ).rejects.toThrow(Error('Vote account is not already in validator list')); + }); + + it('should successfully remove a validator', async () => { + connection.getAccountInfo = jest.fn(async (pubKey) => { + if (pubKey === stakePoolAddress) { + return stakePoolAccount; + } + if (pubKey.equals(stakePoolMock.validatorList)) { + return mockValidatorList(); + } + return >{ + executable: true, + owner: new PublicKey(0), + lamports: 0, + data, + }; + }); + const res = await removeValidatorFromPool( + connection, + stakePoolAddress, + validatorListMock.validators[0].voteAccountAddress, + ); + expect((connection.getAccountInfo as jest.Mock).mock.calls.length).toBe(2); + expect(res.instructions).toHaveLength(1); + // Make sure that the validator stake account being removed is the one we passed + const validatorStake = await findStakeProgramAddress( + STAKE_POOL_PROGRAM_ID, + validatorListMock.validators[0].voteAccountAddress, + stakePoolAddress, + 0, + ); + expect(res.instructions[0].keys[4].pubkey).toEqual(validatorStake); + }); + }); + describe('depositSol', () => { const from = Keypair.generate().publicKey; const balance = 10000; From 8f2383b9c898e8af605b62d282e03d9bc951a075 Mon Sep 17 00:00:00 2001 From: Jon C Date: Fri, 22 Mar 2024 13:57:14 +0100 Subject: [PATCH 0774/1076] stake-pool-js: Bump to 1.1.0 for release (#6480) --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index c0fa98d6..a2be2a2c 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-stake-pool", - "version": "1.0.1", + "version": "1.1.0", "description": "SPL Stake Pool Program JS API", "scripts": { "build": "tsc && cross-env NODE_ENV=production rollup -c", From 6b1a7c37857d4bd86e32e573ffaf12b60ded325c Mon Sep 17 00:00:00 2001 From: Jon C Date: Mon, 25 Mar 2024 12:16:38 +0100 Subject: [PATCH 0775/1076] stake-pool-js: Remove `divideBnToNumber`, use BNs more (#6482) * stake-pool-js: Remove `divideBnToNumber`, use BNs more * Add defensive check for negative number * Revert ceil on calc --- clients/js-legacy/src/index.ts | 29 +++++---- clients/js-legacy/src/layouts.ts | 7 ++- clients/js-legacy/src/utils/stake.ts | 68 +++++++++------------- clients/js-legacy/test/calculation.test.ts | 15 +++++ 4 files changed, 67 insertions(+), 52 deletions(-) create mode 100644 clients/js-legacy/test/calculation.test.ts diff --git a/clients/js-legacy/src/index.ts b/clients/js-legacy/src/index.ts index ae20fe4e..7b4c4b38 100644 --- a/clients/js-legacy/src/index.ts +++ b/clients/js-legacy/src/index.ts @@ -60,7 +60,7 @@ export interface StakePoolAccount { export interface WithdrawAccount { stakeAddress: PublicKey; voteAddress?: PublicKey; - poolAmount: number; + poolAmount: BN; } /** @@ -354,7 +354,7 @@ export async function withdrawStake( validatorComparator?: (_a: ValidatorAccount, _b: ValidatorAccount) => number, ) { const stakePool = await getStakePoolAccount(connection, stakePoolAddress); - const poolAmount = solToLamports(amount); + const poolAmount = new BN(solToLamports(amount)); if (!poolTokenAccount) { poolTokenAccount = getAssociatedTokenAddressSync(stakePool.account.data.poolMint, tokenOwner); @@ -363,7 +363,7 @@ export async function withdrawStake( const tokenAccount = await getAccount(connection, poolTokenAccount); // Check withdrawFrom balance - if (tokenAccount.amount < poolAmount) { + if (tokenAccount.amount < poolAmount.toNumber()) { throw new Error( `Not enough token balance to withdraw ${lamportsToSol(poolAmount)} pool tokens. Maximum withdraw amount is ${lamportsToSol(tokenAccount.amount)} pool tokens.`, @@ -420,10 +420,10 @@ export async function withdrawStake( const availableForWithdrawal = calcLamportsWithdrawAmount( stakePool.account.data, - stakeAccount.lamports - MINIMUM_ACTIVE_STAKE - stakeAccountRentExemption, + new BN(stakeAccount.lamports - MINIMUM_ACTIVE_STAKE - stakeAccountRentExemption), ); - if (availableForWithdrawal < poolAmount) { + if (availableForWithdrawal.lt(poolAmount)) { throw new Error( `Not enough lamports available for withdrawal from ${stakeAccountAddress}, ${poolAmount} asked, ${availableForWithdrawal} available.`, @@ -450,12 +450,18 @@ export async function withdrawStake( throw new Error('Invalid Stake Account'); } + const availableLamports = new BN( + stakeAccount.lamports - MINIMUM_ACTIVE_STAKE - stakeAccountRentExemption, + ); + if (availableLamports.lt(new BN(0))) { + throw new Error('Invalid Stake Account'); + } const availableForWithdrawal = calcLamportsWithdrawAmount( stakePool.account.data, - stakeAccount.lamports - MINIMUM_ACTIVE_STAKE - stakeAccountRentExemption, + availableLamports, ); - if (availableForWithdrawal < poolAmount) { + if (availableForWithdrawal.lt(poolAmount)) { // noinspection ExceptionCaughtLocallyJS throw new Error( `Not enough lamports available for withdrawal from ${stakeAccountAddress}, @@ -492,7 +498,7 @@ export async function withdrawStake( poolTokenAccount, userTransferAuthority.publicKey, tokenOwner, - poolAmount, + poolAmount.toNumber(), ), ); @@ -508,8 +514,9 @@ export async function withdrawStake( break; } // Convert pool tokens amount to lamports - const solWithdrawAmount = Math.ceil( - calcLamportsWithdrawAmount(stakePool.account.data, withdrawAccount.poolAmount), + const solWithdrawAmount = calcLamportsWithdrawAmount( + stakePool.account.data, + withdrawAccount.poolAmount, ); let infoMsg = `Withdrawing â—Ž${solWithdrawAmount}, @@ -542,7 +549,7 @@ export async function withdrawStake( sourcePoolAccount: poolTokenAccount, managerFeeAccount: stakePool.account.data.managerFeeAccount, poolMint: stakePool.account.data.poolMint, - poolTokens: withdrawAccount.poolAmount, + poolTokens: withdrawAccount.poolAmount.toNumber(), withdrawAuthority, }), ); diff --git a/clients/js-legacy/src/layouts.ts b/clients/js-legacy/src/layouts.ts index 020a8c37..60d84155 100644 --- a/clients/js-legacy/src/layouts.ts +++ b/clients/js-legacy/src/layouts.ts @@ -1,5 +1,5 @@ import { publicKey, struct, u32, u64, u8, option, vec } from '@coral-xyz/borsh'; -import { Lockup, PublicKey } from '@solana/web3.js'; +import { PublicKey } from '@solana/web3.js'; import BN from 'bn.js'; import { Infer, @@ -76,6 +76,11 @@ export const StakeAccount = type({ type: StakeAccountType, info: optional(StakeAccountInfo), }); +export interface Lockup { + unixTimestamp: BN; + epoch: BN; + custodian: PublicKey; +} export interface StakePool { accountType: AccountType; diff --git a/clients/js-legacy/src/utils/stake.ts b/clients/js-legacy/src/utils/stake.ts index 55debbf6..ed4fc1e8 100644 --- a/clients/js-legacy/src/utils/stake.ts +++ b/clients/js-legacy/src/utils/stake.ts @@ -41,14 +41,14 @@ export interface ValidatorAccount { type: 'preferred' | 'active' | 'transient' | 'reserve'; voteAddress?: PublicKey | undefined; stakeAddress: PublicKey; - lamports: number; + lamports: BN; } export async function prepareWithdrawAccounts( connection: Connection, stakePool: StakePool, stakePoolAddress: PublicKey, - amount: number, + amount: BN, compareFn?: (a: ValidatorAccount, b: ValidatorAccount) => number, skipFee?: boolean, ): Promise { @@ -62,13 +62,13 @@ export async function prepareWithdrawAccounts( const minBalanceForRentExemption = await connection.getMinimumBalanceForRentExemption( StakeProgram.space, ); - const minBalance = minBalanceForRentExemption + MINIMUM_ACTIVE_STAKE; + const minBalance = new BN(minBalanceForRentExemption + MINIMUM_ACTIVE_STAKE); let accounts = [] as Array<{ type: 'preferred' | 'active' | 'transient' | 'reserve'; voteAddress?: PublicKey | undefined; stakeAddress: PublicKey; - lamports: number; + lamports: BN; }>; // Prepare accounts @@ -91,12 +91,12 @@ export async function prepareWithdrawAccounts( type: isPreferred ? 'preferred' : 'active', voteAddress: validator.voteAccountAddress, stakeAddress: stakeAccountAddress, - lamports: validator.activeStakeLamports.toNumber(), + lamports: validator.activeStakeLamports, }); } - const transientStakeLamports = validator.transientStakeLamports.toNumber() - minBalance; - if (transientStakeLamports > 0) { + const transientStakeLamports = validator.transientStakeLamports.sub(minBalance); + if (transientStakeLamports.gt(new BN(0))) { const transientStakeAccountAddress = await findTransientStakeProgramAddress( STAKE_POOL_PROGRAM_ID, validator.voteAccountAddress, @@ -113,11 +113,11 @@ export async function prepareWithdrawAccounts( } // Sort from highest to lowest balance - accounts = accounts.sort(compareFn ? compareFn : (a, b) => b.lamports - a.lamports); + accounts = accounts.sort(compareFn ? compareFn : (a, b) => b.lamports.sub(a.lamports).toNumber()); const reserveStake = await connection.getAccountInfo(stakePool.reserveStake); - const reserveStakeBalance = (reserveStake?.lamports ?? 0) - minBalanceForRentExemption; - if (reserveStakeBalance > 0) { + const reserveStakeBalance = new BN((reserveStake?.lamports ?? 0) - minBalanceForRentExemption); + if (reserveStakeBalance.gt(new BN(0))) { accounts.push({ type: 'reserve', stakeAddress: stakePool.reserveStake, @@ -127,7 +127,7 @@ export async function prepareWithdrawAccounts( // Prepare the list of accounts to withdraw from const withdrawFrom: WithdrawAccount[] = []; - let remainingAmount = amount; + let remainingAmount = new BN(amount); const fee = stakePool.stakeWithdrawalFee; const inverseFee: Fee = { @@ -139,40 +139,39 @@ export async function prepareWithdrawAccounts( const filteredAccounts = accounts.filter((a) => a.type == type); for (const { stakeAddress, voteAddress, lamports } of filteredAccounts) { - if (lamports <= minBalance && type == 'transient') { + if (lamports.lte(minBalance) && type == 'transient') { continue; } let availableForWithdrawal = calcPoolTokensForDeposit(stakePool, lamports); if (!skipFee && !inverseFee.numerator.isZero()) { - availableForWithdrawal = divideBnToNumber( - new BN(availableForWithdrawal).mul(inverseFee.denominator), - inverseFee.numerator, - ); + availableForWithdrawal = availableForWithdrawal + .mul(inverseFee.denominator) + .div(inverseFee.numerator); } - const poolAmount = Math.min(availableForWithdrawal, remainingAmount); - if (poolAmount <= 0) { + const poolAmount = BN.min(availableForWithdrawal, remainingAmount); + if (poolAmount.lte(new BN(0))) { continue; } // Those accounts will be withdrawn completely with `claim` instruction withdrawFrom.push({ stakeAddress, voteAddress, poolAmount }); - remainingAmount -= poolAmount; + remainingAmount = remainingAmount.sub(poolAmount); - if (remainingAmount == 0) { + if (remainingAmount.isZero()) { break; } } - if (remainingAmount == 0) { + if (remainingAmount.isZero()) { break; } } // Not enough stake to withdraw the specified amount - if (remainingAmount > 0) { + if (remainingAmount.gt(new BN(0))) { throw new Error( `No stake accounts found in this pool with enough balance to withdraw ${lamportsToSol( amount, @@ -186,35 +185,24 @@ export async function prepareWithdrawAccounts( /** * Calculate the pool tokens that should be minted for a deposit of `stakeLamports` */ -export function calcPoolTokensForDeposit(stakePool: StakePool, stakeLamports: number): number { +export function calcPoolTokensForDeposit(stakePool: StakePool, stakeLamports: BN): BN { if (stakePool.poolTokenSupply.isZero() || stakePool.totalLamports.isZero()) { return stakeLamports; } - return Math.floor( - divideBnToNumber(new BN(stakeLamports).mul(stakePool.poolTokenSupply), stakePool.totalLamports), - ); + const numerator = stakeLamports.mul(stakePool.poolTokenSupply); + return numerator.div(stakePool.totalLamports); } /** * Calculate lamports amount on withdrawal */ -export function calcLamportsWithdrawAmount(stakePool: StakePool, poolTokens: number): number { - const numerator = new BN(poolTokens).mul(stakePool.totalLamports); +export function calcLamportsWithdrawAmount(stakePool: StakePool, poolTokens: BN): BN { + const numerator = poolTokens.mul(stakePool.totalLamports); const denominator = stakePool.poolTokenSupply; if (numerator.lt(denominator)) { - return 0; - } - return divideBnToNumber(numerator, denominator); -} - -export function divideBnToNumber(numerator: BN, denominator: BN): number { - if (denominator.isZero()) { - return 0; + return new BN(0); } - const quotient = numerator.div(denominator).toNumber(); - const rem = numerator.umod(denominator); - const gcd = rem.gcd(denominator); - return quotient + rem.div(gcd).toNumber() / denominator.div(gcd).toNumber(); + return numerator.div(denominator); } export function newStakeAccount( diff --git a/clients/js-legacy/test/calculation.test.ts b/clients/js-legacy/test/calculation.test.ts new file mode 100644 index 00000000..dd6083ec --- /dev/null +++ b/clients/js-legacy/test/calculation.test.ts @@ -0,0 +1,15 @@ +import { LAMPORTS_PER_SOL } from '@solana/web3.js'; +import { stakePoolMock } from './mocks'; +import { calcPoolTokensForDeposit } from '../src/utils/stake'; +import BN from 'bn.js'; + +describe('calculations', () => { + it('should successfully calculate pool tokens for a pool with a lot of stake', () => { + const lamports = new BN(LAMPORTS_PER_SOL * 100); + const bigStakePoolMock = stakePoolMock; + bigStakePoolMock.totalLamports = new BN('11000000000000000'); // 11 million SOL + bigStakePoolMock.poolTokenSupply = new BN('10000000000000000'); // 10 million tokens + const availableForWithdrawal = calcPoolTokensForDeposit(bigStakePoolMock, lamports); + expect(availableForWithdrawal.toNumber()).toEqual(90909090909); + }); +}); From 6b51ba6ca4d62f614514dbb290a84d82e1812d62 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Mar 2024 11:52:54 +0100 Subject: [PATCH 0776/1076] build(deps): bump serde_json from 1.0.114 to 1.0.115 (#6495) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.114 to 1.0.115. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.114...v1.0.115) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index e7dd84f0..339999fa 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ borsh = "1.2.1" clap = "2.33.3" serde = "1.0.197" serde_derive = "1.0.130" -serde_json = "1.0.114" +serde_json = "1.0.115" solana-account-decoder = ">=1.18.2,<=2" solana-clap-utils = ">=1.18.2,<=2" solana-cli-config = ">=1.18.2,<=2" From cc983b6b32e205ed939a1153ad4a27e507f2fb6a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Mar 2024 12:10:13 +0100 Subject: [PATCH 0777/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 7.3.1 to 7.4.0 (#6496) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.3.1 to 7.4.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.4.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index a2be2a2c..5b5aba40 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.12", "@types/node": "^20.11.30", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^7.3.1", + "@typescript-eslint/eslint-plugin": "^7.4.0", "@typescript-eslint/parser": "^7.3.1", "cross-env": "^7.0.3", "eslint": "^8.57.0", From 620e6c0deefa90568204226fd25e09272b6d09da Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Mar 2024 12:27:57 +0100 Subject: [PATCH 0778/1076] build(deps-dev): bump @typescript-eslint/parser from 7.3.1 to 7.4.0 (#6497) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.3.1 to 7.4.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.4.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 5b5aba40..0756627f 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.11.30", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.4.0", - "@typescript-eslint/parser": "^7.3.1", + "@typescript-eslint/parser": "^7.4.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", From 798c73704c2596bba27187d0ffb86ce9bd5b30d2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 27 Mar 2024 12:04:13 +0100 Subject: [PATCH 0779/1076] build(deps-dev): bump rollup from 4.13.0 to 4.13.1 (#6504) Bumps [rollup](https://github.com/rollup/rollup) from 4.13.0 to 4.13.1. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.13.0...v4.13.1) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 0756627f..05933bd4 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.2.5", "rimraf": "^5.0.0", - "rollup": "^4.13.0", + "rollup": "^4.13.1", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.1.2", "typescript": "^5.4.3" From 70704ccbf877b8d5e1607bcf1f1e918488b6dfc1 Mon Sep 17 00:00:00 2001 From: Jon C Date: Thu, 28 Mar 2024 01:04:40 +0100 Subject: [PATCH 0780/1076] bump: Bump everything up for new token cli (#6507) --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 339999fa..dd9045c4 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -23,7 +23,7 @@ solana-logger = ">=1.18.2,<=2" solana-program = ">=1.18.2,<=2" solana-remote-wallet = ">=1.18.2,<=2" solana-sdk = ">=1.18.2,<=2" -spl-associated-token-account = { version = "=2.3", path = "../../associated-token-account/program", features = [ +spl-associated-token-account = { version = "=3.0", path = "../../associated-token-account/program", features = [ "no-entrypoint", ] } spl-stake-pool = { version = "=1.0.0", path = "../program", features = [ diff --git a/program/Cargo.toml b/program/Cargo.toml index 78c19415..3dd521ea 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -28,7 +28,7 @@ spl-math = { version = "0.2", path = "../../libraries/math", features = [ spl-pod = { version = "0.1", path = "../../libraries/pod", features = [ "borsh", ] } -spl-token-2022 = { version = "2.0", path = "../../token/program-2022", features = [ +spl-token-2022 = { version = "3.0", path = "../../token/program-2022", features = [ "no-entrypoint", ] } thiserror = "1.0" From dff895c33d90aa81c6a53e0d38bcad4f9da74e70 Mon Sep 17 00:00:00 2001 From: Jon C Date: Thu, 28 Mar 2024 12:34:33 +0100 Subject: [PATCH 0781/1076] pod: Bump to 0.2.0 --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 3dd521ea..5e8c213a 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -25,7 +25,7 @@ solana-security-txt = "1.1.1" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint", ] } -spl-pod = { version = "0.1", path = "../../libraries/pod", features = [ +spl-pod = { version = "0.2", path = "../../libraries/pod", features = [ "borsh", ] } spl-token-2022 = { version = "3.0", path = "../../token/program-2022", features = [ From d0f7b1e878f8de96da86d759bd43dd957736404b Mon Sep 17 00:00:00 2001 From: Jon C Date: Thu, 28 Mar 2024 23:46:27 +0100 Subject: [PATCH 0782/1076] Bump all crates for token-cli release (#6516) * Bump pod to 0.2.2 * Bump program-error and derive to 0.4.0 * Bump type-length-value to 0.4.3 * Bump tlv-account-resolution to 0.6.3 * Bump token-group-interface to 0.2.3 * Bump token-metadata-interface to 0.3.3 * Bump token-2022 to 3.0.2 * Bump transfer-hook-interface to 0.6.3 * Bump token-client to 0.9.2 * Bump associated-token-account to 3.0.2 * Bump discriminator, derive, and syn to 0.2.x --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index dd9045c4..ffbd5e57 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -23,7 +23,7 @@ solana-logger = ">=1.18.2,<=2" solana-program = ">=1.18.2,<=2" solana-remote-wallet = ">=1.18.2,<=2" solana-sdk = ">=1.18.2,<=2" -spl-associated-token-account = { version = "=3.0", path = "../../associated-token-account/program", features = [ +spl-associated-token-account = { version = "=3.0.2", path = "../../associated-token-account/program", features = [ "no-entrypoint", ] } spl-stake-pool = { version = "=1.0.0", path = "../program", features = [ diff --git a/program/Cargo.toml b/program/Cargo.toml index 5e8c213a..4e7d98f3 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -25,10 +25,10 @@ solana-security-txt = "1.1.1" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint", ] } -spl-pod = { version = "0.2", path = "../../libraries/pod", features = [ +spl-pod = { version = "0.2.2", path = "../../libraries/pod", features = [ "borsh", ] } -spl-token-2022 = { version = "3.0", path = "../../token/program-2022", features = [ +spl-token-2022 = { version = "3.0.2", path = "../../token/program-2022", features = [ "no-entrypoint", ] } thiserror = "1.0" From 25770bcab8e0b1e8edd6e67616264d16977d1b59 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 Mar 2024 12:08:57 +0100 Subject: [PATCH 0783/1076] build(deps): bump borsh from 1.2.1 to 1.4.0 (#6520) Bumps [borsh](https://github.com/near/borsh-rs) from 1.2.1 to 1.4.0. - [Release notes](https://github.com/near/borsh-rs/releases) - [Changelog](https://github.com/near/borsh-rs/blob/master/CHANGELOG.md) - [Commits](https://github.com/near/borsh-rs/compare/borsh-v1.2.1...borsh-v1.4.0) --- updated-dependencies: - dependency-name: borsh dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index ffbd5e57..b7367da8 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/solana-labs/solana-program-library" version = "1.0.0" [dependencies] -borsh = "1.2.1" +borsh = "1.4.0" clap = "2.33.3" serde = "1.0.197" serde_derive = "1.0.130" diff --git a/program/Cargo.toml b/program/Cargo.toml index 4e7d98f3..f9281643 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -13,7 +13,7 @@ test-sbf = [] [dependencies] arrayref = "0.3.7" -borsh = "1.2.1" +borsh = "1.4.0" bytemuck = "1.15" num-derive = "0.4" num-traits = "0.2" From 6e047cfe2e25eab699c5d78b553bdf10455b24b1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 Mar 2024 12:41:43 +0100 Subject: [PATCH 0784/1076] build(deps-dev): bump rollup from 4.13.1 to 4.13.2 (#6522) Bumps [rollup](https://github.com/rollup/rollup) from 4.13.1 to 4.13.2. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.13.1...v4.13.2) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 05933bd4..98f28f09 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.2.5", "rimraf": "^5.0.0", - "rollup": "^4.13.1", + "rollup": "^4.13.2", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.1.2", "typescript": "^5.4.3" From bd327aa8a1d4a93a4872a3f429a09db28bf97368 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 Mar 2024 13:05:13 +0100 Subject: [PATCH 0785/1076] build(deps): bump @solana/web3.js from 1.91.1 to 1.91.2 (#6505) * build(deps): bump @solana/web3.js from 1.91.1 to 1.91.2 Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.91.1 to 1.91.2. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.91.1...v1.91.2) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Do it right --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 98f28f09..96830e1f 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -46,7 +46,7 @@ "@coral-xyz/borsh": "^0.29.0", "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "0.4.0", - "@solana/web3.js": "^1.91.1", + "@solana/web3.js": "^1.91.2", "bn.js": "^5.2.0", "buffer": "^6.0.3", "superstruct": "^1.0.4" From 6de14b5c05cd7ad696a0f64c48839565f3865470 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Apr 2024 13:24:47 +0200 Subject: [PATCH 0786/1076] build(deps-dev): bump @types/node from 20.11.30 to 20.12.2 (#6529) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.30 to 20.12.2. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 96830e1f..dfb6d599 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.11.30", + "@types/node": "^20.12.2", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.4.0", "@typescript-eslint/parser": "^7.4.0", From 3a3b498175580737915c627b1027508629549be7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Apr 2024 12:24:19 +0200 Subject: [PATCH 0787/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 7.4.0 to 7.5.0 (#6530) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.4.0 to 7.5.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.5.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index dfb6d599..d0b1e5c7 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.12", "@types/node": "^20.12.2", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^7.4.0", + "@typescript-eslint/eslint-plugin": "^7.5.0", "@typescript-eslint/parser": "^7.4.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", From e541330aae0281c4017dbd9dd443378212ff8ef2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Apr 2024 12:40:08 +0200 Subject: [PATCH 0788/1076] build(deps-dev): bump @typescript-eslint/parser from 7.4.0 to 7.5.0 (#6534) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.4.0 to 7.5.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.5.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index d0b1e5c7..a3678b51 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.12.2", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.5.0", - "@typescript-eslint/parser": "^7.4.0", + "@typescript-eslint/parser": "^7.5.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", From fa59e1eac4cb1cc07bb7d14f0b51f112855ebc99 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Apr 2024 12:44:07 +0200 Subject: [PATCH 0789/1076] build(deps-dev): bump rollup from 4.13.2 to 4.14.0 (#6539) Bumps [rollup](https://github.com/rollup/rollup) from 4.13.2 to 4.14.0. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.13.2...v4.14.0) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index a3678b51..8ca9a12b 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.2.5", "rimraf": "^5.0.0", - "rollup": "^4.13.2", + "rollup": "^4.14.0", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.1.2", "typescript": "^5.4.3" From b5c94352fffc741fdff37d9f613386cb3a98c89d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Apr 2024 12:44:17 +0200 Subject: [PATCH 0790/1076] build(deps-dev): bump @types/node from 20.12.2 to 20.12.3 (#6540) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.12.2 to 20.12.3. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 8ca9a12b..138e20ab 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.12.2", + "@types/node": "^20.12.3", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.5.0", "@typescript-eslint/parser": "^7.5.0", From ee211203c0cfda6ad761592e7263830dbdd2d498 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Apr 2024 12:58:21 +0200 Subject: [PATCH 0791/1076] build(deps): bump @solana/web3.js from 1.91.2 to 1.91.3 (#6531) * build(deps): bump @solana/web3.js from 1.91.2 to 1.91.3 Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.91.2 to 1.91.3. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.91.2...v1.91.3) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Do it right --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 138e20ab..42e1eb47 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -46,7 +46,7 @@ "@coral-xyz/borsh": "^0.29.0", "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "0.4.0", - "@solana/web3.js": "^1.91.2", + "@solana/web3.js": "^1.91.3", "bn.js": "^5.2.0", "buffer": "^6.0.3", "superstruct": "^1.0.4" From e760e7fbfd00cf640f97f0baec9386add29d4701 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Apr 2024 13:19:22 +0200 Subject: [PATCH 0792/1076] build(deps-dev): bump @types/node from 20.12.3 to 20.12.4 (#6548) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.12.3 to 20.12.4. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 42e1eb47..6109ac6f 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.12.3", + "@types/node": "^20.12.4", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.5.0", "@typescript-eslint/parser": "^7.5.0", From f9634395b05671dea90e110b945b16f45f5d61e4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Apr 2024 13:45:39 +0200 Subject: [PATCH 0793/1076] build(deps): bump @solana/web3.js from 1.91.3 to 1.91.4 (#6546) * build(deps): bump @solana/web3.js from 1.91.3 to 1.91.4 Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.91.3 to 1.91.4. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.91.3...v1.91.4) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Do it right --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 6109ac6f..8efef40c 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -46,7 +46,7 @@ "@coral-xyz/borsh": "^0.29.0", "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "0.4.0", - "@solana/web3.js": "^1.91.3", + "@solana/web3.js": "^1.91.4", "bn.js": "^5.2.0", "buffer": "^6.0.3", "superstruct": "^1.0.4" From 9f2361906d00e01b588ef325b53969e2a3997b30 Mon Sep 17 00:00:00 2001 From: Ashwin Sekar Date: Thu, 4 Apr 2024 13:51:33 -0700 Subject: [PATCH 0794/1076] Remove usage of VoteStateVersions::vote_state_size_of (#6549) --- program/tests/helpers/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index b68d7c8c..eb785ff6 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -626,7 +626,7 @@ pub async fn create_vote( }, rent_voter, vote_instruction::CreateVoteAccountConfig { - space: VoteStateVersions::vote_state_size_of(true) as u64, + space: VoteState::size_of() as u64, ..Default::default() }, )); From c3a96b4dd6105ceeffb0abdc98103166fc3d374b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 Apr 2024 17:16:58 +0200 Subject: [PATCH 0795/1076] build(deps-dev): bump typescript from 5.4.3 to 5.4.4 (#6551) Bumps [typescript](https://github.com/Microsoft/TypeScript) from 5.4.3 to 5.4.4. - [Release notes](https://github.com/Microsoft/TypeScript/releases) - [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml) - [Commits](https://github.com/Microsoft/TypeScript/compare/v5.4.3...v5.4.4) --- updated-dependencies: - dependency-name: typescript dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 8efef40c..8d5ad916 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -75,7 +75,7 @@ "rollup": "^4.14.0", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.1.2", - "typescript": "^5.4.3" + "typescript": "^5.4.4" }, "jest": { "moduleFileExtensions": [ From ecb57d299a7370cfb54c89c0941932a1fdd6dbea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Apr 2024 09:00:30 -0500 Subject: [PATCH 0796/1076] build(deps-dev): bump @types/node from 20.12.4 to 20.12.5 (#6552) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.12.4 to 20.12.5. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 8d5ad916..b8a7e63e 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.12.4", + "@types/node": "^20.12.5", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.5.0", "@typescript-eslint/parser": "^7.5.0", From e9ed97461108b8491cfc5554b10c7b6ea6ad7332 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Apr 2024 09:00:47 -0500 Subject: [PATCH 0797/1076] build(deps-dev): bump rollup from 4.14.0 to 4.14.1 (#6554) Bumps [rollup](https://github.com/rollup/rollup) from 4.14.0 to 4.14.1. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.14.0...v4.14.1) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index b8a7e63e..a987c361 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.2.5", "rimraf": "^5.0.0", - "rollup": "^4.14.0", + "rollup": "^4.14.1", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.1.2", "typescript": "^5.4.4" From c184a2a56887ed35c232bb0b08aa32b41140cb33 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Apr 2024 09:07:13 -0500 Subject: [PATCH 0798/1076] build(deps-dev): bump @types/node from 20.12.5 to 20.12.6 (#6559) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.12.5 to 20.12.6. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index a987c361..bb0582e7 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.12.5", + "@types/node": "^20.12.6", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.5.0", "@typescript-eslint/parser": "^7.5.0", From b8634683423c025144773b3259e23a72137ca2dd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Apr 2024 16:21:50 +0200 Subject: [PATCH 0799/1076] build(deps-dev): bump @typescript-eslint/parser from 7.5.0 to 7.6.0 (#6560) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.5.0 to 7.6.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.6.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index bb0582e7..ca76c6ca 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.12.6", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.5.0", - "@typescript-eslint/parser": "^7.5.0", + "@typescript-eslint/parser": "^7.6.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", From 5ef94b7b29191f8099e4f1a2e53b36518f61f81c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Apr 2024 09:34:10 -0500 Subject: [PATCH 0800/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 7.5.0 to 7.6.0 (#6558) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.5.0 to 7.6.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.6.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index ca76c6ca..bd7b341e 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.12", "@types/node": "^20.12.6", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^7.5.0", + "@typescript-eslint/eslint-plugin": "^7.6.0", "@typescript-eslint/parser": "^7.6.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", From e03d3f46b66a11cc0edd5386be84748c7346533d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Apr 2024 08:55:19 -0500 Subject: [PATCH 0801/1076] build(deps-dev): bump @types/node from 20.12.6 to 20.12.7 (#6564) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.12.6 to 20.12.7. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index bd7b341e..e245bd4e 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.12.6", + "@types/node": "^20.12.7", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.6.0", "@typescript-eslint/parser": "^7.6.0", From 23f80549afe8c4400cae08e70f0493c8b0835b76 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Apr 2024 10:24:43 -0500 Subject: [PATCH 0802/1076] build(deps-dev): bump typescript from 5.4.4 to 5.4.5 (#6566) Bumps [typescript](https://github.com/Microsoft/TypeScript) from 5.4.4 to 5.4.5. - [Release notes](https://github.com/Microsoft/TypeScript/releases) - [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml) - [Commits](https://github.com/Microsoft/TypeScript/compare/v5.4.4...v5.4.5) --- updated-dependencies: - dependency-name: typescript dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index e245bd4e..58b580e8 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -75,7 +75,7 @@ "rollup": "^4.14.1", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.1.2", - "typescript": "^5.4.4" + "typescript": "^5.4.5" }, "jest": { "moduleFileExtensions": [ From 14320071c8aba6d1506cbc8ab632a25fa155920d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Apr 2024 17:53:13 -0500 Subject: [PATCH 0803/1076] build(deps): bump idna from 3.3 to 3.7 in /stake-pool/py (#6571) Bumps [idna](https://github.com/kjd/idna) from 3.3 to 3.7. - [Release notes](https://github.com/kjd/idna/releases) - [Changelog](https://github.com/kjd/idna/blob/master/HISTORY.rst) - [Commits](https://github.com/kjd/idna/compare/v3.3...v3.7) --- updated-dependencies: - dependency-name: idna dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/py/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/py/requirements.txt b/clients/py/requirements.txt index b14e6920..1994fa99 100644 --- a/clients/py/requirements.txt +++ b/clients/py/requirements.txt @@ -8,7 +8,7 @@ construct==2.10.68 h11==0.12.0 httpcore==0.15.0 httpx==0.23.0 -idna==3.3 +idna==3.7 pycparser==2.21 PyNaCl==1.5.0 requests==2.31.0 From 372663c05ed84c82f9068d2e5510233219f35926 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 12 Apr 2024 09:53:34 -0500 Subject: [PATCH 0804/1076] build(deps-dev): bump rollup from 4.14.1 to 4.14.2 (#6574) Bumps [rollup](https://github.com/rollup/rollup) from 4.14.1 to 4.14.2. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.14.1...v4.14.2) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 58b580e8..753a22b9 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.2.5", "rimraf": "^5.0.0", - "rollup": "^4.14.1", + "rollup": "^4.14.2", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.1.2", "typescript": "^5.4.5" From eb8d88061e82a2ca7cf66df9f82d858558a69730 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Apr 2024 13:20:33 +0200 Subject: [PATCH 0805/1076] build(deps-dev): bump rollup from 4.14.2 to 4.14.3 (#6580) Bumps [rollup](https://github.com/rollup/rollup) from 4.14.2 to 4.14.3. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.14.2...v4.14.3) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 753a22b9..12d76624 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.2.5", "rimraf": "^5.0.0", - "rollup": "^4.14.2", + "rollup": "^4.14.3", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.1.2", "typescript": "^5.4.5" From 3397c7631dec4da8f07ab5f68427de2bc6514ff8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Apr 2024 12:03:22 +0200 Subject: [PATCH 0806/1076] build(deps): bump serde_json from 1.0.115 to 1.0.116 (#6584) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.115 to 1.0.116. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.115...v1.0.116) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index b7367da8..4c7997a4 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ borsh = "1.4.0" clap = "2.33.3" serde = "1.0.197" serde_derive = "1.0.130" -serde_json = "1.0.115" +serde_json = "1.0.116" solana-account-decoder = ">=1.18.2,<=2" solana-clap-utils = ">=1.18.2,<=2" solana-cli-config = ">=1.18.2,<=2" From 5be247b2a1edb58e228717ed1a18bc2b47e8e7d7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Apr 2024 14:02:21 +0200 Subject: [PATCH 0807/1076] build(deps-dev): bump @typescript-eslint/parser from 7.6.0 to 7.7.0 (#6585) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.6.0 to 7.7.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.7.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 12d76624..0f6d6d82 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.12.7", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.6.0", - "@typescript-eslint/parser": "^7.6.0", + "@typescript-eslint/parser": "^7.7.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", From f80c6576aab0954e3fc4c6aef37dac83551b7a85 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Apr 2024 14:02:47 +0200 Subject: [PATCH 0808/1076] build(deps): bump @coral-xyz/borsh from 0.29.0 to 0.30.0 (#6587) Bumps @coral-xyz/borsh from 0.29.0 to 0.30.0. --- updated-dependencies: - dependency-name: "@coral-xyz/borsh" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 0f6d6d82..a7e32e34 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -43,7 +43,7 @@ ], "license": "ISC", "dependencies": { - "@coral-xyz/borsh": "^0.29.0", + "@coral-xyz/borsh": "^0.30.0", "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "0.4.0", "@solana/web3.js": "^1.91.4", From 0173cfa2907951c8dc2d4cc2b9a2ba1efd7673cd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Apr 2024 14:23:44 +0200 Subject: [PATCH 0809/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 7.6.0 to 7.7.0 (#6586) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.6.0 to 7.7.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.7.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index a7e32e34..feb32c9c 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.12", "@types/node": "^20.12.7", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^7.6.0", + "@typescript-eslint/eslint-plugin": "^7.7.0", "@typescript-eslint/parser": "^7.7.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", From 7a76fd397551104b0eb7c20612d3b5522c52abda Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Apr 2024 12:33:26 +0200 Subject: [PATCH 0810/1076] build(deps): bump serde from 1.0.197 to 1.0.198 (#6589) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.197 to 1.0.198. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.197...v1.0.198) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 4c7997a4..daac531b 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "1.0.0" [dependencies] borsh = "1.4.0" clap = "2.33.3" -serde = "1.0.197" +serde = "1.0.198" serde_derive = "1.0.130" serde_json = "1.0.116" solana-account-decoder = ">=1.18.2,<=2" diff --git a/program/Cargo.toml b/program/Cargo.toml index f9281643..3c09c0a4 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,7 +18,7 @@ bytemuck = "1.15" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.2" -serde = "1.0.197" +serde = "1.0.198" serde_derive = "1.0.103" solana-program = ">=1.18.2,<=2" solana-security-txt = "1.1.1" From 994fb77c02c4912de824de5ed4aa0dbf2f03db20 Mon Sep 17 00:00:00 2001 From: steveluscher Date: Wed, 17 Apr 2024 23:17:30 +0000 Subject: [PATCH 0811/1076] build(deps): bump @solana/web3.js from 1.91.4 to 1.91.6 --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index feb32c9c..5f6e6b86 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -46,7 +46,7 @@ "@coral-xyz/borsh": "^0.30.0", "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "0.4.0", - "@solana/web3.js": "^1.91.4", + "@solana/web3.js": "^1.91.6", "bn.js": "^5.2.0", "buffer": "^6.0.3", "superstruct": "^1.0.4" From 60645275bc44a65f9669b3a8f4fcedc095c359bb Mon Sep 17 00:00:00 2001 From: Steven Luscher Date: Thu, 18 Apr 2024 10:57:16 -0700 Subject: [PATCH 0812/1076] build(deps): bump all JS client versions to publish versions having `e5506e3` (#6593) build(deps): bump all JS client versions to publish versions having e5506e3 --- clients/js-legacy/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 5f6e6b86..61017586 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-stake-pool", - "version": "1.1.0", + "version": "1.1.1", "description": "SPL Stake Pool Program JS API", "scripts": { "build": "tsc && cross-env NODE_ENV=production rollup -c", @@ -45,7 +45,7 @@ "dependencies": { "@coral-xyz/borsh": "^0.30.0", "@solana/buffer-layout": "^4.0.1", - "@solana/spl-token": "0.4.0", + "@solana/spl-token": "0.4.4", "@solana/web3.js": "^1.91.6", "bn.js": "^5.2.0", "buffer": "^6.0.3", From f78f585b0db41f99cb49c932f1fe3a34b32563a6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Apr 2024 14:43:07 +0200 Subject: [PATCH 0813/1076] build(deps): bump @solana/web3.js from 1.91.6 to 1.91.7 (#6598) * build(deps): bump @solana/web3.js from 1.91.6 to 1.91.7 Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.91.6 to 1.91.7. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.91.6...v1.91.7) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Do it right --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 61017586..6e60e86a 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -46,7 +46,7 @@ "@coral-xyz/borsh": "^0.30.0", "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "0.4.4", - "@solana/web3.js": "^1.91.6", + "@solana/web3.js": "^1.91.7", "bn.js": "^5.2.0", "buffer": "^6.0.3", "superstruct": "^1.0.4" From cc0ed78657d445623163fe2ec2fd890bf57c09a6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Apr 2024 13:27:07 +0200 Subject: [PATCH 0814/1076] build(deps-dev): bump rollup from 4.14.3 to 4.16.1 (#6607) Bumps [rollup](https://github.com/rollup/rollup) from 4.14.3 to 4.16.1. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.14.3...v4.16.1) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 6e60e86a..1743dad3 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.2.5", "rimraf": "^5.0.0", - "rollup": "^4.14.3", + "rollup": "^4.16.1", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.1.2", "typescript": "^5.4.5" From d390da59f75f63097dff716dc1e943568b726f69 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Apr 2024 14:22:59 +0200 Subject: [PATCH 0815/1076] build(deps-dev): bump @typescript-eslint/parser from 7.7.0 to 7.7.1 (#6620) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.7.0 to 7.7.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.7.1/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 1743dad3..a3ce6d30 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.12.7", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.7.0", - "@typescript-eslint/parser": "^7.7.0", + "@typescript-eslint/parser": "^7.7.1", "cross-env": "^7.0.3", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", From f31a1d9040465767163c1ec48f826034a180f992 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Apr 2024 20:10:31 +0200 Subject: [PATCH 0816/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 7.7.0 to 7.7.1 (#6619) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.7.0 to 7.7.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.7.1/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index a3ce6d30..2ef19bb5 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.12", "@types/node": "^20.12.7", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^7.7.0", + "@typescript-eslint/eslint-plugin": "^7.7.1", "@typescript-eslint/parser": "^7.7.1", "cross-env": "^7.0.3", "eslint": "^8.57.0", From 4a7c1db31ae49f7d152a4519f8d56d421bab0f2f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Apr 2024 20:10:40 +0200 Subject: [PATCH 0817/1076] build(deps-dev): bump rollup from 4.16.1 to 4.16.4 (#6622) Bumps [rollup](https://github.com/rollup/rollup) from 4.16.1 to 4.16.4. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.16.1...v4.16.4) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 2ef19bb5..d30081b6 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.2.5", "rimraf": "^5.0.0", - "rollup": "^4.16.1", + "rollup": "^4.16.4", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.1.2", "typescript": "^5.4.5" From 0d554d25e30c5bf91f5d8b725b519c9b026ccbc1 Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Wed, 24 Apr 2024 12:01:47 +0900 Subject: [PATCH 0818/1076] Bump solana version to 1.18.11 (#6624) upgrade solana version to 1.18.11 --- clients/cli/Cargo.toml | 18 +++++++++--------- program/Cargo.toml | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index daac531b..c972cc47 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -14,15 +14,15 @@ clap = "2.33.3" serde = "1.0.198" serde_derive = "1.0.130" serde_json = "1.0.116" -solana-account-decoder = ">=1.18.2,<=2" -solana-clap-utils = ">=1.18.2,<=2" -solana-cli-config = ">=1.18.2,<=2" -solana-cli-output = ">=1.18.2,<=2" -solana-client = ">=1.18.2,<=2" -solana-logger = ">=1.18.2,<=2" -solana-program = ">=1.18.2,<=2" -solana-remote-wallet = ">=1.18.2,<=2" -solana-sdk = ">=1.18.2,<=2" +solana-account-decoder = ">=1.18.11,<=2" +solana-clap-utils = ">=1.18.11,<=2" +solana-cli-config = ">=1.18.11,<=2" +solana-cli-output = ">=1.18.11,<=2" +solana-client = ">=1.18.11,<=2" +solana-logger = ">=1.18.11,<=2" +solana-program = ">=1.18.11,<=2" +solana-remote-wallet = ">=1.18.11,<=2" +solana-sdk = ">=1.18.11,<=2" spl-associated-token-account = { version = "=3.0.2", path = "../../associated-token-account/program", features = [ "no-entrypoint", ] } diff --git a/program/Cargo.toml b/program/Cargo.toml index 3c09c0a4..22b220a8 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -20,7 +20,7 @@ num-traits = "0.2" num_enum = "0.7.2" serde = "1.0.198" serde_derive = "1.0.103" -solana-program = ">=1.18.2,<=2" +solana-program = ">=1.18.11,<=2" solana-security-txt = "1.1.1" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint", @@ -37,9 +37,9 @@ bincode = "1.3.1" [dev-dependencies] assert_matches = "1.5.0" proptest = "1.4" -solana-program-test = ">=1.18.2,<=2" -solana-sdk = ">=1.18.2,<=2" -solana-vote-program = ">=1.18.2,<=2" +solana-program-test = ">=1.18.11,<=2" +solana-sdk = ">=1.18.11,<=2" +solana-vote-program = ">=1.18.11,<=2" spl-token = { version = "4.0", path = "../../token/program", features = [ "no-entrypoint", ] } From bde6b7a4144bbf20e90ab239df6c40839c68d5e4 Mon Sep 17 00:00:00 2001 From: Jon C Date: Fri, 26 Apr 2024 00:54:08 +0200 Subject: [PATCH 0819/1076] stake-pool-cli: Add support for priority fees (#6499) * stake-pool-cli: Add function to simulate tx for CUs used * Add compute unit price and limit args * Refactor to always use `checked_transaction_*` * Add compute budget instructions * Fix creation to create second transaction *after* sending first one * Address feedback * Specify "SIMULATED" explicitly --- clients/cli/src/client.rs | 40 ++++- clients/cli/src/main.rs | 338 ++++++++++++++++++++++---------------- 2 files changed, 236 insertions(+), 142 deletions(-) diff --git a/clients/cli/src/client.rs b/clients/cli/src/client.rs index 62916d5d..5d3974a5 100644 --- a/clients/cli/src/client.rs +++ b/clients/cli/src/client.rs @@ -7,7 +7,11 @@ use { rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig}, rpc_filter::{Memcmp, RpcFilterType}, }, - solana_program::{borsh1::try_from_slice_unchecked, program_pack::Pack, pubkey::Pubkey, stake}, + solana_program::{ + borsh1::try_from_slice_unchecked, hash::Hash, instruction::Instruction, message::Message, + program_pack::Pack, pubkey::Pubkey, stake, + }, + solana_sdk::{compute_budget::ComputeBudgetInstruction, transaction::Transaction}, spl_stake_pool::{ find_withdraw_authority_program_address, state::{StakePool, ValidatorList}, @@ -15,7 +19,7 @@ use { std::collections::HashSet, }; -type Error = Box; +pub(crate) type Error = Box; pub fn get_stake_pool( rpc_client: &RpcClient, @@ -146,3 +150,35 @@ pub(crate) fn get_all_stake( .map(|(address, _)| address) .collect()) } + +/// Helper function to add a compute unit limit instruction to a given set +/// of instructions +pub(crate) fn add_compute_unit_limit_from_simulation( + rpc_client: &RpcClient, + instructions: &mut Vec, + payer: &Pubkey, + blockhash: &Hash, +) -> Result<(), Error> { + // add a max compute unit limit instruction for the simulation + const MAX_COMPUTE_UNIT_LIMIT: u32 = 1_400_000; + instructions.push(ComputeBudgetInstruction::set_compute_unit_limit( + MAX_COMPUTE_UNIT_LIMIT, + )); + + let transaction = Transaction::new_unsigned(Message::new_with_blockhash( + instructions, + Some(payer), + blockhash, + )); + let simulation_result = rpc_client.simulate_transaction(&transaction)?.value; + let units_consumed = simulation_result + .units_consumed + .ok_or("No units consumed on simulation")?; + // Overwrite the compute unit limit instruction with the actual units consumed + let compute_unit_limit = u32::try_from(units_consumed)?; + instructions + .last_mut() + .expect("Compute budget instruction was added earlier") + .data = ComputeBudgetInstruction::set_compute_unit_limit(compute_unit_limit).data; + Ok(()) +} diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index c764dc9d..c695f351 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -16,12 +16,14 @@ use { Arg, ArgGroup, ArgMatches, SubCommand, }, solana_clap_utils::{ + compute_unit_price::{compute_unit_price_arg, COMPUTE_UNIT_PRICE_ARG}, input_parsers::{keypair_of, pubkey_of}, input_validators::{ is_amount, is_keypair_or_ask_keyword, is_parsable, is_pubkey, is_url, is_valid_percentage, is_valid_pubkey, is_valid_signer, }, keypair::{signer_from_path_with_config, SignerFromPathConfig}, + ArgConstant, }, solana_cli_output::OutputFormat, solana_client::rpc_client::RpcClient, @@ -35,6 +37,7 @@ use { solana_remote_wallet::remote_wallet::RemoteWalletManager, solana_sdk::{ commitment_config::CommitmentConfig, + compute_budget::ComputeBudgetInstruction, hash::Hash, message::Message, native_token::{self, Sol}, @@ -66,9 +69,10 @@ pub(crate) struct Config { fee_payer: Box, dry_run: bool, no_update: bool, + compute_unit_price: Option, + compute_unit_limit: ComputeUnitLimit, } -type Error = Box; type CommandResult = Result<(), Error>; const STAKE_STATE_LEN: usize = 200; @@ -101,6 +105,44 @@ const FEES_REFERENCE: &str = "Consider setting a minimal fee. \ aware of the possible risks of a stake pool with no fees, \ you may force pool creation with the --unsafe-fees flag."; +enum ComputeUnitLimit { + Default, + Static(u32), + Simulated, +} +const COMPUTE_UNIT_LIMIT_ARG: ArgConstant<'static> = ArgConstant { + name: "compute_unit_limit", + long: "--with-compute-unit-limit", + help: "Set compute unit limit for transaction, in compute units; also accepts \ + keyword SIMULATED to use compute units from transaction simulation prior \ + to sending. Note that SIMULATED may fail if accounts are modified by another \ + transaction between simulation and execution.", +}; +fn is_compute_unit_limit_or_simulated(string: T) -> Result<(), String> +where + T: AsRef + std::fmt::Display, +{ + if string.as_ref().parse::().is_ok() || string.as_ref() == "SIMULATED" { + Ok(()) + } else { + Err(format!( + "Unable to parse input compute unit limit as integer or SIMULATED, provided: {string}" + )) + } +} +fn parse_compute_unit_limit(string: T) -> Result +where + T: AsRef + std::fmt::Display, +{ + match string.as_ref().parse::() { + Ok(compute_unit_limit) => Ok(ComputeUnitLimit::Static(compute_unit_limit)), + Err(_) if string.as_ref() == "SIMULATED" => Ok(ComputeUnitLimit::Simulated), + _ => Err(format!( + "Unable to parse compute unit limit, provided: {string}" + )), + } +} + fn check_stake_pool_fees( epoch_fee: &Fee, withdrawal_fee: &Fee, @@ -177,22 +219,56 @@ fn send_transaction( Ok(()) } -fn checked_transaction_with_signers( +fn checked_transaction_with_signers_and_additional_fee( config: &Config, instructions: &[Instruction], signers: &T, + additional_fee: u64, ) -> Result { let recent_blockhash = get_latest_blockhash(&config.rpc_client)?; + let mut instructions = instructions.to_vec(); + if let Some(compute_unit_price) = config.compute_unit_price { + instructions.push(ComputeBudgetInstruction::set_compute_unit_price( + compute_unit_price, + )); + } + match config.compute_unit_limit { + ComputeUnitLimit::Default => {} + ComputeUnitLimit::Static(compute_unit_limit) => { + instructions.push(ComputeBudgetInstruction::set_compute_unit_limit( + compute_unit_limit, + )); + } + ComputeUnitLimit::Simulated => { + add_compute_unit_limit_from_simulation( + &config.rpc_client, + &mut instructions, + &config.fee_payer.pubkey(), + &recent_blockhash, + )?; + } + } let message = Message::new_with_blockhash( - instructions, + &instructions, Some(&config.fee_payer.pubkey()), &recent_blockhash, ); - check_fee_payer_balance(config, config.rpc_client.get_fee_for_message(&message)?)?; + check_fee_payer_balance( + config, + additional_fee.saturating_add(config.rpc_client.get_fee_for_message(&message)?), + )?; let transaction = Transaction::new(signers, message, recent_blockhash); Ok(transaction) } +fn checked_transaction_with_signers( + config: &Config, + instructions: &[Instruction], + signers: &T, +) -> Result { + checked_transaction_with_signers_and_additional_fee(config, instructions, signers, 0) +} + fn new_stake_account( fee_payer: &Pubkey, instructions: &mut Vec, @@ -284,7 +360,7 @@ fn command_create_pool( println!("Stake pool withdraw authority {}", withdraw_authority); } - let mut instructions = vec![ + let mut setup_instructions = vec![ // Account for the stake pool reserve system_instruction::create_account( &config.fee_payer.pubkey(), @@ -323,94 +399,93 @@ fn command_create_pool( config, &mint_keypair.pubkey(), &config.manager.pubkey(), - &mut instructions, + &mut setup_instructions, &mut total_rent_free_balances, ); println!("Creating pool fee collection account {}", pool_fee_account); - let recent_blockhash = get_latest_blockhash(&config.rpc_client)?; - let setup_message = Message::new_with_blockhash( - &instructions, - Some(&config.fee_payer.pubkey()), - &recent_blockhash, - ); - let initialize_message = Message::new_with_blockhash( - &[ - // Validator stake account list storage - system_instruction::create_account( - &config.fee_payer.pubkey(), - &validator_list_keypair.pubkey(), - validator_list_balance, - validator_list_size as u64, - &spl_stake_pool::id(), - ), - // Account for the stake pool - system_instruction::create_account( - &config.fee_payer.pubkey(), - &stake_pool_keypair.pubkey(), - stake_pool_account_lamports, - get_packed_len::() as u64, - &spl_stake_pool::id(), - ), - // Initialize stake pool - spl_stake_pool::instruction::initialize( - &spl_stake_pool::id(), - &stake_pool_keypair.pubkey(), - &config.manager.pubkey(), - &config.staker.pubkey(), - &withdraw_authority, - &validator_list_keypair.pubkey(), - &reserve_keypair.pubkey(), - &mint_keypair.pubkey(), - &pool_fee_account, - &spl_token::id(), - deposit_authority.as_ref().map(|x| x.pubkey()), - epoch_fee, - withdrawal_fee, - deposit_fee, - referral_fee, - max_validators, - ), - ], - Some(&config.fee_payer.pubkey()), - &recent_blockhash, - ); - check_fee_payer_balance( - config, - total_rent_free_balances - + config.rpc_client.get_fee_for_message(&setup_message)? - + config.rpc_client.get_fee_for_message(&initialize_message)?, - )?; - let mut setup_signers = vec![config.fee_payer.as_ref(), &mint_keypair, &reserve_keypair]; - unique_signers!(setup_signers); - let setup_transaction = Transaction::new(&setup_signers, setup_message, recent_blockhash); - let mut initialize_signers = vec![ - config.fee_payer.as_ref(), - &stake_pool_keypair, - &validator_list_keypair, - config.manager.as_ref(), + let initialize_instructions = &[ + // Validator stake account list storage + system_instruction::create_account( + &config.fee_payer.pubkey(), + &validator_list_keypair.pubkey(), + validator_list_balance, + validator_list_size as u64, + &spl_stake_pool::id(), + ), + // Account for the stake pool + system_instruction::create_account( + &config.fee_payer.pubkey(), + &stake_pool_keypair.pubkey(), + stake_pool_account_lamports, + get_packed_len::() as u64, + &spl_stake_pool::id(), + ), + // Initialize stake pool + spl_stake_pool::instruction::initialize( + &spl_stake_pool::id(), + &stake_pool_keypair.pubkey(), + &config.manager.pubkey(), + &config.staker.pubkey(), + &withdraw_authority, + &validator_list_keypair.pubkey(), + &reserve_keypair.pubkey(), + &mint_keypair.pubkey(), + &pool_fee_account, + &spl_token::id(), + deposit_authority.as_ref().map(|x| x.pubkey()), + epoch_fee, + withdrawal_fee, + deposit_fee, + referral_fee, + max_validators, + ), ]; - let initialize_transaction = if let Some(deposit_authority) = deposit_authority { + + { + let mut setup_signers = vec![config.fee_payer.as_ref(), &mint_keypair, &reserve_keypair]; + unique_signers!(setup_signers); + + let setup_transaction = + checked_transaction_with_signers(config, &setup_instructions, &setup_signers)?; + println!( - "Deposits will be restricted to {} only, this can be changed using the set-funding-authority command.", - deposit_authority.pubkey() + "Setting up required accounts for stake pool: reserve stake {} and mint {}", + reserve_keypair.pubkey(), + mint_keypair.pubkey() ); - let mut initialize_signers = initialize_signers.clone(); - initialize_signers.push(&deposit_authority); - unique_signers!(initialize_signers); - Transaction::new(&initialize_signers, initialize_message, recent_blockhash) - } else { - unique_signers!(initialize_signers); - Transaction::new(&initialize_signers, initialize_message, recent_blockhash) - }; - send_transaction(config, setup_transaction)?; + send_transaction(config, setup_transaction)?; + } + + { + let mut initialize_signers = vec![ + config.fee_payer.as_ref(), + &stake_pool_keypair, + &validator_list_keypair, + config.manager.as_ref(), + ]; + let initialize_transaction = if let Some(deposit_authority) = deposit_authority { + println!( + "Deposits will be restricted to {} only, this can be changed using the set-funding-authority command.", + deposit_authority.pubkey() + ); + let mut initialize_signers = initialize_signers.clone(); + initialize_signers.push(&deposit_authority); + unique_signers!(initialize_signers); + checked_transaction_with_signers(config, initialize_instructions, &initialize_signers)? + } else { + unique_signers!(initialize_signers); + checked_transaction_with_signers(config, initialize_instructions, &initialize_signers)? + }; + + println!( + "Creating stake pool {} with validator list {}", + stake_pool_keypair.pubkey(), + validator_list_keypair.pubkey() + ); + send_transaction(config, initialize_transaction)?; + } - println!( - "Creating stake pool {} with validator list {}", - stake_pool_keypair.pubkey(), - validator_list_keypair.pubkey() - ); - send_transaction(config, initialize_transaction)?; Ok(()) } @@ -777,18 +852,13 @@ fn command_deposit_stake( instructions.append(&mut deposit_instructions); - let recent_blockhash = get_latest_blockhash(&config.rpc_client)?; - let message = Message::new_with_blockhash( - &instructions, - Some(&config.fee_payer.pubkey()), - &recent_blockhash, - ); - check_fee_payer_balance( + unique_signers!(signers); + let transaction = checked_transaction_with_signers_and_additional_fee( config, - total_rent_free_balances + config.rpc_client.get_fee_for_message(&message)?, + &instructions, + &signers, + total_rent_free_balances, )?; - unique_signers!(signers); - let transaction = Transaction::new(&signers, message, recent_blockhash); send_transaction(config, transaction)?; Ok(()) } @@ -820,17 +890,12 @@ fn command_deposit_all_stake( &mut total_rent_free_balances, )); if !create_token_account_instructions.is_empty() { - let recent_blockhash = get_latest_blockhash(&config.rpc_client)?; - let message = Message::new_with_blockhash( - &create_token_account_instructions, - Some(&config.fee_payer.pubkey()), - &recent_blockhash, - ); - check_fee_payer_balance( + let transaction = checked_transaction_with_signers_and_additional_fee( config, - total_rent_free_balances + config.rpc_client.get_fee_for_message(&message)?, + &create_token_account_instructions, + &[config.fee_payer.as_ref()], + total_rent_free_balances, )?; - let transaction = Transaction::new(&[config.fee_payer.as_ref()], message, recent_blockhash); send_transaction(config, transaction)?; } @@ -923,14 +988,7 @@ fn command_deposit_all_stake( ) }; - let recent_blockhash = get_latest_blockhash(&config.rpc_client)?; - let message = Message::new_with_blockhash( - &instructions, - Some(&config.fee_payer.pubkey()), - &recent_blockhash, - ); - check_fee_payer_balance(config, config.rpc_client.get_fee_for_message(&message)?)?; - let transaction = Transaction::new(&signers, message, recent_blockhash); + let transaction = checked_transaction_with_signers(config, &instructions, &signers)?; send_transaction(config, transaction)?; } Ok(()) @@ -1045,18 +1103,13 @@ fn command_deposit_sol( instructions.push(deposit_instruction); - let recent_blockhash = get_latest_blockhash(&config.rpc_client)?; - let message = Message::new_with_blockhash( - &instructions, - Some(&config.fee_payer.pubkey()), - &recent_blockhash, - ); - check_fee_payer_balance( + unique_signers!(signers); + let transaction = checked_transaction_with_signers_and_additional_fee( config, - total_rent_free_balances + config.rpc_client.get_fee_for_message(&message)?, + &instructions, + &signers, + total_rent_free_balances, )?; - unique_signers!(signers); - let transaction = Transaction::new(&signers, message, recent_blockhash); send_transaction(config, transaction)?; Ok(()) } @@ -1615,21 +1668,16 @@ fn command_withdraw_stake( } } - let recent_blockhash = get_latest_blockhash(&config.rpc_client)?; - let message = Message::new_with_blockhash( - &instructions, - Some(&config.fee_payer.pubkey()), - &recent_blockhash, - ); for new_stake_keypair in &new_stake_keypairs { signers.push(new_stake_keypair); } - check_fee_payer_balance( + unique_signers!(signers); + let transaction = checked_transaction_with_signers_and_additional_fee( config, - total_rent_free_balances + config.rpc_client.get_fee_for_message(&message)?, + &instructions, + &signers, + total_rent_free_balances, )?; - unique_signers!(signers); - let transaction = Transaction::new(&signers, message, recent_blockhash); send_transaction(config, transaction)?; Ok(()) } @@ -1739,15 +1787,8 @@ fn command_withdraw_sol( instructions.push(withdraw_instruction); - let recent_blockhash = get_latest_blockhash(&config.rpc_client)?; - let message = Message::new_with_blockhash( - &instructions, - Some(&config.fee_payer.pubkey()), - &recent_blockhash, - ); - check_fee_payer_balance(config, config.rpc_client.get_fee_for_message(&message)?)?; unique_signers!(signers); - let transaction = Transaction::new(&signers, message, recent_blockhash); + let transaction = checked_transaction_with_signers(config, &instructions, &signers)?; send_transaction(config, transaction)?; Ok(()) } @@ -1999,6 +2040,16 @@ fn main() { .global(true) .help("Transaction fee payer account [default: cli config keypair]"), ) + .arg(compute_unit_price_arg().validator(is_parsable::).requires(COMPUTE_UNIT_LIMIT_ARG.name).global(true)) + .arg( + Arg::with_name(COMPUTE_UNIT_LIMIT_ARG.name) + .long(COMPUTE_UNIT_LIMIT_ARG.long) + .takes_value(true) + .value_name("COMPUTE-UNIT-LIMIT") + .help(COMPUTE_UNIT_LIMIT_ARG.help) + .validator(is_compute_unit_limit_or_simulated) + .global(true) + ) .subcommand(SubCommand::with_name("create-pool") .about("Create a new stake pool") .arg( @@ -2779,6 +2830,11 @@ fn main() { }); let dry_run = matches.is_present("dry_run"); let no_update = matches.is_present("no_update"); + let compute_unit_price = value_t!(matches, COMPUTE_UNIT_PRICE_ARG.name, u64).ok(); + let compute_unit_limit = matches + .value_of(COMPUTE_UNIT_LIMIT_ARG.name) + .map(|x| parse_compute_unit_limit(x).unwrap()) + .unwrap_or(ComputeUnitLimit::Default); Config { rpc_client: RpcClient::new_with_commitment(json_rpc_url, CommitmentConfig::confirmed()), @@ -2791,6 +2847,8 @@ fn main() { fee_payer, dry_run, no_update, + compute_unit_price, + compute_unit_limit, } }; From 961c3061dd29037e279f4a41e7da36c31b671094 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 12:51:40 +0200 Subject: [PATCH 0820/1076] build(deps): bump serde from 1.0.198 to 1.0.199 (#6647) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.198 to 1.0.199. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.198...v1.0.199) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index c972cc47..56fb04ce 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "1.0.0" [dependencies] borsh = "1.4.0" clap = "2.33.3" -serde = "1.0.198" +serde = "1.0.199" serde_derive = "1.0.130" serde_json = "1.0.116" solana-account-decoder = ">=1.18.11,<=2" diff --git a/program/Cargo.toml b/program/Cargo.toml index 22b220a8..23a8b838 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,7 +18,7 @@ bytemuck = "1.15" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.2" -serde = "1.0.198" +serde = "1.0.199" serde_derive = "1.0.103" solana-program = ">=1.18.11,<=2" solana-security-txt = "1.1.1" From 2673d0642314827abf20bc0d872644ad7852fb8a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 13:03:32 +0200 Subject: [PATCH 0821/1076] build(deps-dev): bump rollup from 4.16.4 to 4.17.1 (#6650) Bumps [rollup](https://github.com/rollup/rollup) from 4.16.4 to 4.17.1. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.16.4...v4.17.1) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index d30081b6..9e4368ac 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.2.5", "rimraf": "^5.0.0", - "rollup": "^4.16.4", + "rollup": "^4.17.1", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.1.2", "typescript": "^5.4.5" From 8b66680b6a23f319859076e58ea3dacc00758bc9 Mon Sep 17 00:00:00 2001 From: Steven Luscher Date: Mon, 29 Apr 2024 11:04:18 -0700 Subject: [PATCH 0822/1076] Bump version of `@solana/spl-token` to 0.4.6 and bump dependent packages (#6657) --- clients/js-legacy/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 9e4368ac..434c20c1 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-stake-pool", - "version": "1.1.1", + "version": "1.1.3", "description": "SPL Stake Pool Program JS API", "scripts": { "build": "tsc && cross-env NODE_ENV=production rollup -c", @@ -45,7 +45,7 @@ "dependencies": { "@coral-xyz/borsh": "^0.30.0", "@solana/buffer-layout": "^4.0.1", - "@solana/spl-token": "0.4.4", + "@solana/spl-token": "0.4.6", "@solana/web3.js": "^1.91.7", "bn.js": "^5.2.0", "buffer": "^6.0.3", From 012a92d41f797b73457f511bd046862e506daddd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Apr 2024 12:16:15 +0200 Subject: [PATCH 0823/1076] build(deps): bump borsh from 1.4.0 to 1.5.0 (#6659) Bumps [borsh](https://github.com/near/borsh-rs) from 1.4.0 to 1.5.0. - [Release notes](https://github.com/near/borsh-rs/releases) - [Changelog](https://github.com/near/borsh-rs/blob/master/CHANGELOG.md) - [Commits](https://github.com/near/borsh-rs/compare/borsh-v1.4.0...borsh-v1.5.0) --- updated-dependencies: - dependency-name: borsh dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 56fb04ce..346030de 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/solana-labs/solana-program-library" version = "1.0.0" [dependencies] -borsh = "1.4.0" +borsh = "1.5.0" clap = "2.33.3" serde = "1.0.199" serde_derive = "1.0.130" diff --git a/program/Cargo.toml b/program/Cargo.toml index 23a8b838..1180bf5f 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -13,7 +13,7 @@ test-sbf = [] [dependencies] arrayref = "0.3.7" -borsh = "1.4.0" +borsh = "1.5.0" bytemuck = "1.15" num-derive = "0.4" num-traits = "0.2" From c0b3d553206c00706dbac3da16642cf25ed30ad3 Mon Sep 17 00:00:00 2001 From: Jon C Date: Tue, 30 Apr 2024 12:33:14 +0200 Subject: [PATCH 0824/1076] stake-pool-cli: Default to simulated compute units (#6635) * stake-pool-cli: Default to simulated compute units * stake-pool-cli: Fix compute limit logic --------- Co-authored-by: hanako mumei <81144685+2501babe@users.noreply.github.com> --- clients/cli/src/main.rs | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index c695f351..a7bd4cfa 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -114,19 +114,21 @@ const COMPUTE_UNIT_LIMIT_ARG: ArgConstant<'static> = ArgConstant { name: "compute_unit_limit", long: "--with-compute-unit-limit", help: "Set compute unit limit for transaction, in compute units; also accepts \ - keyword SIMULATED to use compute units from transaction simulation prior \ - to sending. Note that SIMULATED may fail if accounts are modified by another \ - transaction between simulation and execution.", + keyword DEFAULT to use the default compute unit limit, which is 200k per \ + top-level instruction, with a maximum of 1.4 million. \ + If nothing is set, transactions are simulated prior to sending, and the \ + compute units consumed are set as the limit. This may may fail if accounts \ + are modified by another transaction between simulation and execution.", }; fn is_compute_unit_limit_or_simulated(string: T) -> Result<(), String> where T: AsRef + std::fmt::Display, { - if string.as_ref().parse::().is_ok() || string.as_ref() == "SIMULATED" { + if string.as_ref().parse::().is_ok() || string.as_ref() == "DEFAULT" { Ok(()) } else { Err(format!( - "Unable to parse input compute unit limit as integer or SIMULATED, provided: {string}" + "Unable to parse input compute unit limit as integer or DEFAULT, provided: {string}" )) } } @@ -136,7 +138,7 @@ where { match string.as_ref().parse::() { Ok(compute_unit_limit) => Ok(ComputeUnitLimit::Static(compute_unit_limit)), - Err(_) if string.as_ref() == "SIMULATED" => Ok(ComputeUnitLimit::Simulated), + Err(_) if string.as_ref() == "DEFAULT" => Ok(ComputeUnitLimit::Default), _ => Err(format!( "Unable to parse compute unit limit, provided: {string}" )), @@ -2040,7 +2042,7 @@ fn main() { .global(true) .help("Transaction fee payer account [default: cli config keypair]"), ) - .arg(compute_unit_price_arg().validator(is_parsable::).requires(COMPUTE_UNIT_LIMIT_ARG.name).global(true)) + .arg(compute_unit_price_arg().validator(is_parsable::).global(true)) .arg( Arg::with_name(COMPUTE_UNIT_LIMIT_ARG.name) .long(COMPUTE_UNIT_LIMIT_ARG.long) @@ -2834,7 +2836,13 @@ fn main() { let compute_unit_limit = matches .value_of(COMPUTE_UNIT_LIMIT_ARG.name) .map(|x| parse_compute_unit_limit(x).unwrap()) - .unwrap_or(ComputeUnitLimit::Default); + .unwrap_or_else(|| { + if compute_unit_price.is_some() { + ComputeUnitLimit::Simulated + } else { + ComputeUnitLimit::Default + } + }); Config { rpc_client: RpcClient::new_with_commitment(json_rpc_url, CommitmentConfig::confirmed()), From 93e5112382957c44bfe051db64eee0c214f6df94 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Apr 2024 13:37:38 +0200 Subject: [PATCH 0825/1076] build(deps-dev): bump @typescript-eslint/parser from 7.7.1 to 7.8.0 (#6664) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.7.1 to 7.8.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.8.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 434c20c1..aa43f802 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.12.7", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.7.1", - "@typescript-eslint/parser": "^7.7.1", + "@typescript-eslint/parser": "^7.8.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", From e2bf1ecc7855c30771486909ce5f374b517af268 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Apr 2024 13:37:45 +0200 Subject: [PATCH 0826/1076] build(deps-dev): bump rollup from 4.17.1 to 4.17.2 (#6662) Bumps [rollup](https://github.com/rollup/rollup) from 4.17.1 to 4.17.2. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.17.1...v4.17.2) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index aa43f802..0226203f 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.2.5", "rimraf": "^5.0.0", - "rollup": "^4.17.1", + "rollup": "^4.17.2", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.1.2", "typescript": "^5.4.5" From 7e4f0ab639d95fcf68b1bfee503fe708e08693cd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Apr 2024 14:01:36 +0200 Subject: [PATCH 0827/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 7.7.1 to 7.8.0 (#6661) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.7.1 to 7.8.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.8.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 0226203f..8d008130 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.12", "@types/node": "^20.12.7", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^7.7.1", + "@typescript-eslint/eslint-plugin": "^7.8.0", "@typescript-eslint/parser": "^7.8.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", From 1d90a85b99da4da87c860db753d818a2db983874 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 May 2024 13:17:53 +0200 Subject: [PATCH 0828/1076] build(deps-dev): bump @types/node from 20.12.7 to 20.12.8 (#6675) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.12.7 to 20.12.8. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 8d008130..d55d3c72 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.12.7", + "@types/node": "^20.12.8", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.8.0", "@typescript-eslint/parser": "^7.8.0", From b1462109c3ef4ac849dade4de7a03aefd11b50f7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 May 2024 12:52:05 +0200 Subject: [PATCH 0829/1076] build(deps): bump serde from 1.0.199 to 1.0.200 (#6679) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.199 to 1.0.200. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.199...v1.0.200) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 346030de..ffd2945e 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "1.0.0" [dependencies] borsh = "1.5.0" clap = "2.33.3" -serde = "1.0.199" +serde = "1.0.200" serde_derive = "1.0.130" serde_json = "1.0.116" solana-account-decoder = ">=1.18.11,<=2" diff --git a/program/Cargo.toml b/program/Cargo.toml index 1180bf5f..7134c077 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,7 +18,7 @@ bytemuck = "1.15" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.2" -serde = "1.0.199" +serde = "1.0.200" serde_derive = "1.0.103" solana-program = ">=1.18.11,<=2" solana-security-txt = "1.1.1" From 17fd9b572c4d1341f59912744a6df428dbc65624 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 May 2024 13:45:54 +0200 Subject: [PATCH 0830/1076] build(deps): bump @solana/web3.js from 1.91.7 to 1.91.8 (#6693) * build(deps): bump @solana/web3.js from 1.91.7 to 1.91.8 Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.91.7 to 1.91.8. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.91.7...v1.91.8) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Do it right --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index d55d3c72..879f0eb2 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -46,7 +46,7 @@ "@coral-xyz/borsh": "^0.30.0", "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "0.4.6", - "@solana/web3.js": "^1.91.7", + "@solana/web3.js": "^1.91.8", "bn.js": "^5.2.0", "buffer": "^6.0.3", "superstruct": "^1.0.4" From faed9e067cceb1f0929b1989b78d8385dc9b2515 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 May 2024 14:27:12 +0200 Subject: [PATCH 0831/1076] build(deps-dev): bump @types/node from 20.12.8 to 20.12.10 (#6699) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.12.8 to 20.12.10. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 879f0eb2..ac33bc9c 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.12.8", + "@types/node": "^20.12.10", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.8.0", "@typescript-eslint/parser": "^7.8.0", From ce49d82db46d161f79e00568fff9854fb45d6eb0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 May 2024 12:51:47 +0200 Subject: [PATCH 0832/1076] build(deps): bump serde_json from 1.0.116 to 1.0.117 (#6705) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.116 to 1.0.117. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.116...v1.0.117) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index ffd2945e..3538be7c 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ borsh = "1.5.0" clap = "2.33.3" serde = "1.0.200" serde_derive = "1.0.130" -serde_json = "1.0.116" +serde_json = "1.0.117" solana-account-decoder = ">=1.18.11,<=2" solana-clap-utils = ">=1.18.11,<=2" solana-cli-config = ">=1.18.11,<=2" From 27e7c22f4e0e34db9292eafa2d91344570e51dbe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 May 2024 13:20:31 +0200 Subject: [PATCH 0833/1076] build(deps): bump serde from 1.0.200 to 1.0.201 (#6706) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.200 to 1.0.201. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.200...v1.0.201) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 3538be7c..0944bac0 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "1.0.0" [dependencies] borsh = "1.5.0" clap = "2.33.3" -serde = "1.0.200" +serde = "1.0.201" serde_derive = "1.0.130" serde_json = "1.0.117" solana-account-decoder = ">=1.18.11,<=2" diff --git a/program/Cargo.toml b/program/Cargo.toml index 7134c077..4f5e8495 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,7 +18,7 @@ bytemuck = "1.15" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.2" -serde = "1.0.200" +serde = "1.0.201" serde_derive = "1.0.103" solana-program = ">=1.18.11,<=2" solana-security-txt = "1.1.1" From 9f28eec24b3e3bb352b69edf54e8df09aa29619c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 May 2024 19:09:46 +0200 Subject: [PATCH 0834/1076] build(deps-dev): bump @types/node from 20.12.10 to 20.12.11 (#6711) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.12.10 to 20.12.11. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index ac33bc9c..a16b9bd0 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.12.10", + "@types/node": "^20.12.11", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.8.0", "@typescript-eslint/parser": "^7.8.0", From 30a3d348fd30a5253b1be64efa3217167e8de6ce Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 14:01:03 +0200 Subject: [PATCH 0835/1076] build(deps-dev): bump rimraf from 5.0.5 to 5.0.7 (#6723) Bumps [rimraf](https://github.com/isaacs/rimraf) from 5.0.5 to 5.0.7. - [Changelog](https://github.com/isaacs/rimraf/blob/main/CHANGELOG.md) - [Commits](https://github.com/isaacs/rimraf/compare/v5.0.5...v5.0.7) --- updated-dependencies: - dependency-name: rimraf dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index a16b9bd0..d4cb7f03 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -71,7 +71,7 @@ "eslint-plugin-prettier": "^5.1.3", "jest": "^29.0.0", "prettier": "^3.2.5", - "rimraf": "^5.0.0", + "rimraf": "^5.0.7", "rollup": "^4.17.2", "rollup-plugin-dts": "^6.1.0", "ts-jest": "^29.1.2", From 3af332a078646d5a597e5959afd297991d44b483 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 May 2024 21:52:02 +0200 Subject: [PATCH 0836/1076] build(deps-dev): bump @typescript-eslint/parser from 7.8.0 to 7.9.0 (#6726) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.8.0 to 7.9.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.9.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index d4cb7f03..d17e9455 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.12.11", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.8.0", - "@typescript-eslint/parser": "^7.8.0", + "@typescript-eslint/parser": "^7.9.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", From 9d5e202dfd42ce22f258df7d640f63db28fc9e48 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 May 2024 21:52:11 +0200 Subject: [PATCH 0837/1076] build(deps-dev): bump @types/node from 20.12.11 to 20.12.12 (#6727) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.12.11 to 20.12.12. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index d17e9455..d2959a4a 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.12.11", + "@types/node": "^20.12.12", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.8.0", "@typescript-eslint/parser": "^7.9.0", From 274a6b3ee8a75e8fca5261af6cb506a20f18be9d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 May 2024 22:20:09 +0200 Subject: [PATCH 0838/1076] build(deps): bump bytemuck from 1.15.0 to 1.16.0 (#6729) Bumps [bytemuck](https://github.com/Lokathor/bytemuck) from 1.15.0 to 1.16.0. - [Changelog](https://github.com/Lokathor/bytemuck/blob/main/changelog.md) - [Commits](https://github.com/Lokathor/bytemuck/compare/v1.15.0...v1.16.0) --- updated-dependencies: - dependency-name: bytemuck dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 4f5e8495..13fc6dcf 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -14,7 +14,7 @@ test-sbf = [] [dependencies] arrayref = "0.3.7" borsh = "1.5.0" -bytemuck = "1.15" +bytemuck = "1.16" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.2" From 04367baf4a8d46f0cdc178de6f0ed544384ced69 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 May 2024 22:34:24 +0200 Subject: [PATCH 0839/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 7.8.0 to 7.9.0 (#6728) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.8.0 to 7.9.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.9.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index d2959a4a..da9afd0d 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.12", "@types/node": "^20.12.12", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^7.8.0", + "@typescript-eslint/eslint-plugin": "^7.9.0", "@typescript-eslint/parser": "^7.9.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", From 7ad1a3067a950c28da2302fba865a29d43bf04a0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 May 2024 12:24:00 +0200 Subject: [PATCH 0840/1076] build(deps): bump serde from 1.0.201 to 1.0.202 (#6733) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.201 to 1.0.202. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.201...v1.0.202) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 0944bac0..3492ccd0 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "1.0.0" [dependencies] borsh = "1.5.0" clap = "2.33.3" -serde = "1.0.201" +serde = "1.0.202" serde_derive = "1.0.130" serde_json = "1.0.117" solana-account-decoder = ">=1.18.11,<=2" diff --git a/program/Cargo.toml b/program/Cargo.toml index 13fc6dcf..031f5ac2 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,7 +18,7 @@ bytemuck = "1.16" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.2" -serde = "1.0.201" +serde = "1.0.202" serde_derive = "1.0.103" solana-program = ">=1.18.11,<=2" solana-security-txt = "1.1.1" From 8b5557be88f0f7579ea48a2a0f070b175234cbcc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 May 2024 13:04:39 +0200 Subject: [PATCH 0841/1076] build(deps-dev): bump rollup-plugin-dts from 6.1.0 to 6.1.1 (#6742) Bumps [rollup-plugin-dts](https://github.com/Swatinem/rollup-plugin-dts) from 6.1.0 to 6.1.1. - [Changelog](https://github.com/Swatinem/rollup-plugin-dts/blob/master/CHANGELOG.md) - [Commits](https://github.com/Swatinem/rollup-plugin-dts/compare/v6.1.0...v6.1.1) --- updated-dependencies: - dependency-name: rollup-plugin-dts dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index da9afd0d..26b06dd8 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -73,7 +73,7 @@ "prettier": "^3.2.5", "rimraf": "^5.0.7", "rollup": "^4.17.2", - "rollup-plugin-dts": "^6.1.0", + "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.1.2", "typescript": "^5.4.5" }, From 722741ff091544fe86caf89830f945dfc052e7c7 Mon Sep 17 00:00:00 2001 From: Jon C Date: Mon, 20 May 2024 20:53:38 +0200 Subject: [PATCH 0842/1076] stake-pool-js: Add deserializer for `FutureEpoch` (#6745) * stake-pool-js: Add deserializer for `FutureEpoch` * Fixup for new types --- clients/js-legacy/package.json | 1 + clients/js-legacy/src/index.ts | 67 ++++++++++--------- clients/js-legacy/src/layouts.ts | 53 +++++++++++++-- .../js-legacy/src/types/buffer-layout.d.ts | 30 ++++++--- 4 files changed, 105 insertions(+), 46 deletions(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 26b06dd8..7d105c59 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -49,6 +49,7 @@ "@solana/web3.js": "^1.91.8", "bn.js": "^5.2.0", "buffer": "^6.0.3", + "buffer-layout": "^1.2.2", "superstruct": "^1.0.4" }, "devDependencies": { diff --git a/clients/js-legacy/src/index.ts b/clients/js-legacy/src/index.ts index 7b4c4b38..27b75f2f 100644 --- a/clients/js-legacy/src/index.ts +++ b/clients/js-legacy/src/index.ts @@ -139,43 +139,46 @@ export async function getStakeAccount( export async function getStakePoolAccounts( connection: Connection, stakePoolProgramAddress: PublicKey, -): Promise<(StakePoolAccount | ValidatorListAccount)[] | undefined> { +): Promise<(StakePoolAccount | ValidatorListAccount | undefined)[] | undefined> { const response = await connection.getProgramAccounts(stakePoolProgramAddress); - return response.map((a) => { - let decodedData; - - if (a.account.data.readUInt8() === 1) { + return response + .map((a) => { try { - decodedData = StakePoolLayout.decode(a.account.data); + if (a.account.data.readUInt8() === 1) { + const data = StakePoolLayout.decode(a.account.data); + return { + pubkey: a.pubkey, + account: { + data, + executable: a.account.executable, + lamports: a.account.lamports, + owner: a.account.owner, + }, + }; + } else if (a.account.data.readUInt8() === 2) { + const data = ValidatorListLayout.decode(a.account.data); + return { + pubkey: a.pubkey, + account: { + data, + executable: a.account.executable, + lamports: a.account.lamports, + owner: a.account.owner, + }, + }; + } else { + console.error( + `Could not decode. StakePoolAccount Enum is ${a.account.data.readUInt8()}, expected 1 or 2!`, + ); + return undefined; + } } catch (error) { - console.log('Could not decode StakeAccount. Error:', error); - decodedData = undefined; + console.error('Could not decode account. Error:', error); + return undefined; } - } else if (a.account.data.readUInt8() === 2) { - try { - decodedData = ValidatorListLayout.decode(a.account.data); - } catch (error) { - console.log('Could not decode ValidatorList. Error:', error); - decodedData = undefined; - } - } else { - console.error( - `Could not decode. StakePoolAccount Enum is ${a.account.data.readUInt8()}, expected 1 or 2!`, - ); - decodedData = undefined; - } - - return { - pubkey: a.pubkey, - account: { - data: decodedData, - executable: a.account.executable, - lamports: a.account.lamports, - owner: a.account.owner, - }, - }; - }); + }) + .filter((a) => a !== undefined); } /** diff --git a/clients/js-legacy/src/layouts.ts b/clients/js-legacy/src/layouts.ts index 60d84155..86feebdd 100644 --- a/clients/js-legacy/src/layouts.ts +++ b/clients/js-legacy/src/layouts.ts @@ -1,4 +1,5 @@ -import { publicKey, struct, u32, u64, u8, option, vec } from '@coral-xyz/borsh'; +import { Layout, publicKey, struct, u32, u64, u8, option, vec } from '@coral-xyz/borsh'; +import { Layout as LayoutCls, u8 as u8Cls } from 'buffer-layout'; import { PublicKey } from '@solana/web3.js'; import BN from 'bn.js'; import { @@ -37,6 +38,50 @@ export const PublicKeyFromString = coerce( (value) => new PublicKey(value), ); +export class FutureEpochLayout extends LayoutCls { + layout: Layout; + discriminator: Layout; + + constructor(layout: Layout, property?: string) { + super(-1, property); + this.layout = layout; + this.discriminator = u8Cls(); + } + + encode(src: T | null, b: Buffer, offset = 0): number { + if (src === null || src === undefined) { + return this.discriminator.encode(0, b, offset); + } + // This isn't right, but we don't typically encode outside of tests + this.discriminator.encode(2, b, offset); + return this.layout.encode(src, b, offset + 1) + 1; + } + + decode(b: Buffer, offset = 0): T | null { + const discriminator = this.discriminator.decode(b, offset); + if (discriminator === 0) { + return null; + } else if (discriminator === 1 || discriminator === 2) { + return this.layout.decode(b, offset + 1); + } + throw new Error('Invalid future epoch ' + this.property); + } + + getSpan(b: Buffer, offset = 0): number { + const discriminator = this.discriminator.decode(b, offset); + if (discriminator === 0) { + return 1; + } else if (discriminator === 1 || discriminator === 2) { + return this.layout.getSpan(b, offset + 1) + 1; + } + throw new Error('Invalid future epoch ' + this.property); + } +} + +export function futureEpoch(layout: Layout, property?: string): Layout { + return new FutureEpochLayout(layout, property); +} + export type StakeAccountType = Infer; export const StakeAccountType = enums(['uninitialized', 'initialized', 'delegated', 'rewardsPool']); @@ -131,19 +176,19 @@ export const StakePoolLayout = struct([ u64('lastUpdateEpoch'), struct([u64('unixTimestamp'), u64('epoch'), publicKey('custodian')], 'lockup'), struct(feeFields, 'epochFee'), - option(struct(feeFields), 'nextEpochFee'), + futureEpoch(struct(feeFields), 'nextEpochFee'), option(publicKey(), 'preferredDepositValidatorVoteAddress'), option(publicKey(), 'preferredWithdrawValidatorVoteAddress'), struct(feeFields, 'stakeDepositFee'), struct(feeFields, 'stakeWithdrawalFee'), - option(struct(feeFields), 'nextStakeWithdrawalFee'), + futureEpoch(struct(feeFields), 'nextStakeWithdrawalFee'), u8('stakeReferralFee'), option(publicKey(), 'solDepositAuthority'), struct(feeFields, 'solDepositFee'), u8('solReferralFee'), option(publicKey(), 'solWithdrawAuthority'), struct(feeFields, 'solWithdrawalFee'), - option(struct(feeFields), 'nextSolWithdrawalFee'), + futureEpoch(struct(feeFields), 'nextSolWithdrawalFee'), u64('lastEpochPoolTokenSupply'), u64('lastEpochTotalLamports'), ]); diff --git a/clients/js-legacy/src/types/buffer-layout.d.ts b/clients/js-legacy/src/types/buffer-layout.d.ts index 54773bba..90538bf0 100644 --- a/clients/js-legacy/src/types/buffer-layout.d.ts +++ b/clients/js-legacy/src/types/buffer-layout.d.ts @@ -1,12 +1,22 @@ declare module 'buffer-layout' { - export class Layout {} - export class UInt {} - /* eslint-disable @typescript-eslint/no-unused-vars */ - export function struct(fields: any, property?: string, decodePrefixes?: boolean): any; - export function s32(property?: string): UInt; - export function u32(property?: string): UInt; - export function s16(property?: string): UInt; - export function u16(property?: string): UInt; - export function s8(property?: string): UInt; - export function u8(property?: string): UInt; + export class Layout { + span: number; + property?: string; + constructor(span: number, property?: string); + decode(b: Buffer | undefined, offset?: number): T; + encode(src: T, b: Buffer, offset?: number): number; + getSpan(b: Buffer, offset?: number): number; + replicate(name: string): this; + } + export function struct( + fields: Layout[], + property?: string, + decodePrefixes?: boolean, + ): Layout; + export function s32(property?: string): Layout; + export function u32(property?: string): Layout; + export function s16(property?: string): Layout; + export function u16(property?: string): Layout; + export function s8(property?: string): Layout; + export function u8(property?: string): Layout; } From dfe4e96e6156d02cd53326732bd23ca27c3f43c0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 May 2024 12:11:10 +0200 Subject: [PATCH 0843/1076] build(deps): bump requests from 2.31.0 to 2.32.0 in /stake-pool/py (#6746) --- updated-dependencies: - dependency-name: requests dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/py/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/py/requirements.txt b/clients/py/requirements.txt index 1994fa99..c2b25c73 100644 --- a/clients/py/requirements.txt +++ b/clients/py/requirements.txt @@ -11,7 +11,7 @@ httpx==0.23.0 idna==3.7 pycparser==2.21 PyNaCl==1.5.0 -requests==2.31.0 +requests==2.32.0 rfc3986==1.5.0 sniffio==1.2.0 solana==0.18.1 From e75747016095a82c18423f4566aa786e698571a1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 May 2024 12:44:32 +0200 Subject: [PATCH 0844/1076] build(deps-dev): bump ts-jest from 29.1.2 to 29.1.3 (#6749) --- updated-dependencies: - dependency-name: ts-jest dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 7d105c59..d9c16994 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -75,7 +75,7 @@ "rimraf": "^5.0.7", "rollup": "^4.17.2", "rollup-plugin-dts": "^6.1.1", - "ts-jest": "^29.1.2", + "ts-jest": "^29.1.3", "typescript": "^5.4.5" }, "jest": { From 1f3e789677ef501ff2fcc7a24d9a14ceb2568200 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 May 2024 12:44:40 +0200 Subject: [PATCH 0845/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 7.9.0 to 7.10.0 (#6750) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index d9c16994..eaddb5f2 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/jest": "^29.5.12", "@types/node": "^20.12.12", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^7.9.0", + "@typescript-eslint/eslint-plugin": "^7.10.0", "@typescript-eslint/parser": "^7.9.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", From 4969055c57b520fe77028bc6bee7d9f00cdfe989 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 May 2024 13:19:03 +0200 Subject: [PATCH 0846/1076] build(deps-dev): bump @typescript-eslint/parser from 7.9.0 to 7.10.0 (#6752) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index eaddb5f2..2060d73b 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -65,7 +65,7 @@ "@types/node": "^20.12.12", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.10.0", - "@typescript-eslint/parser": "^7.9.0", + "@typescript-eslint/parser": "^7.10.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", From 9747f64c3eda5b0d38a275f5c34d0f09d670f797 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 May 2024 12:43:44 +0200 Subject: [PATCH 0847/1076] build(deps-dev): bump rollup from 4.17.2 to 4.18.0 (#6754) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 2060d73b..ac0b8322 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -73,7 +73,7 @@ "jest": "^29.0.0", "prettier": "^3.2.5", "rimraf": "^5.0.7", - "rollup": "^4.17.2", + "rollup": "^4.18.0", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.1.3", "typescript": "^5.4.5" From 5045fbb552f309494894135e743003907a204f14 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 May 2024 12:56:15 +0200 Subject: [PATCH 0848/1076] build(deps-dev): bump @rollup/plugin-commonjs from 25.0.7 to 25.0.8 (#6758) Bumps [@rollup/plugin-commonjs](https://github.com/rollup/plugins/tree/HEAD/packages/commonjs) from 25.0.7 to 25.0.8. - [Changelog](https://github.com/rollup/plugins/blob/master/packages/commonjs/CHANGELOG.md) - [Commits](https://github.com/rollup/plugins/commits/commonjs-v25.0.8/packages/commonjs) --- updated-dependencies: - dependency-name: "@rollup/plugin-commonjs" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index ac0b8322..e85f851c 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -54,7 +54,7 @@ }, "devDependencies": { "@rollup/plugin-alias": "^5.1.0", - "@rollup/plugin-commonjs": "^25.0.0", + "@rollup/plugin-commonjs": "^25.0.8", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-multi-entry": "^6.0.0", "@rollup/plugin-node-resolve": "^15.0.2", From a6da8a17a9119f75273cc760f07272c99f6d2fd4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 May 2024 17:02:42 +0200 Subject: [PATCH 0849/1076] build(deps): bump serde from 1.0.202 to 1.0.203 (#6763) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.202 to 1.0.203. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.202...v1.0.203) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 3492ccd0..f7f2e8d3 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "1.0.0" [dependencies] borsh = "1.5.0" clap = "2.33.3" -serde = "1.0.202" +serde = "1.0.203" serde_derive = "1.0.130" serde_json = "1.0.117" solana-account-decoder = ">=1.18.11,<=2" diff --git a/program/Cargo.toml b/program/Cargo.toml index 031f5ac2..a1021b86 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,7 +18,7 @@ bytemuck = "1.16" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.2" -serde = "1.0.202" +serde = "1.0.203" serde_derive = "1.0.103" solana-program = ">=1.18.11,<=2" solana-security-txt = "1.1.1" From 94193cfed92ccec77004773f42f6d9ad952b29a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 May 2024 13:58:41 +0200 Subject: [PATCH 0850/1076] build(deps-dev): bump ts-jest from 29.1.3 to 29.1.4 (#6767) Bumps [ts-jest](https://github.com/kulshekhar/ts-jest) from 29.1.3 to 29.1.4. - [Release notes](https://github.com/kulshekhar/ts-jest/releases) - [Changelog](https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md) - [Commits](https://github.com/kulshekhar/ts-jest/compare/v29.1.3...v29.1.4) --- updated-dependencies: - dependency-name: ts-jest dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index e85f851c..36ed3273 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -75,7 +75,7 @@ "rimraf": "^5.0.7", "rollup": "^4.18.0", "rollup-plugin-dts": "^6.1.1", - "ts-jest": "^29.1.3", + "ts-jest": "^29.1.4", "typescript": "^5.4.5" }, "jest": { From fb88deeaebfd6816a991c2b0c189e7c11883a73f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 May 2024 13:58:50 +0200 Subject: [PATCH 0851/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 7.10.0 to 7.11.0 (#6768) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.10.0 to 7.11.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.11.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 36ed3273..8cd729ec 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/jest": "^29.5.12", "@types/node": "^20.12.12", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^7.10.0", + "@typescript-eslint/eslint-plugin": "^7.11.0", "@typescript-eslint/parser": "^7.10.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", From a17c57e96840cd0a77181d7ed45644b36528b3ed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 May 2024 14:21:32 +0200 Subject: [PATCH 0852/1076] build(deps-dev): bump @typescript-eslint/parser from 7.10.0 to 7.11.0 (#6769) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.10.0 to 7.11.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.11.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 8cd729ec..f08b545b 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -65,7 +65,7 @@ "@types/node": "^20.12.12", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.11.0", - "@typescript-eslint/parser": "^7.10.0", + "@typescript-eslint/parser": "^7.11.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", From b43053ab4a1fab02a792b39418e1a8d6af5baeb6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 30 May 2024 18:25:58 +0200 Subject: [PATCH 0853/1076] build(deps-dev): bump @types/node from 20.12.12 to 20.12.13 (#6773) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.12.12 to 20.12.13. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index f08b545b..e7e2ed35 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -62,7 +62,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.12.12", + "@types/node": "^20.12.13", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.11.0", "@typescript-eslint/parser": "^7.11.0", From dbed222c9d1efaae1af891a178da8832d6b327e8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 14:12:05 +0200 Subject: [PATCH 0854/1076] build(deps): bump borsh from 1.5.0 to 1.5.1 (#6778) Bumps [borsh](https://github.com/near/borsh-rs) from 1.5.0 to 1.5.1. - [Release notes](https://github.com/near/borsh-rs/releases) - [Changelog](https://github.com/near/borsh-rs/blob/master/CHANGELOG.md) - [Commits](https://github.com/near/borsh-rs/compare/borsh-v1.5.0...borsh-v1.5.1) --- updated-dependencies: - dependency-name: borsh dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index f7f2e8d3..16a5debb 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/solana-labs/solana-program-library" version = "1.0.0" [dependencies] -borsh = "1.5.0" +borsh = "1.5.1" clap = "2.33.3" serde = "1.0.203" serde_derive = "1.0.130" diff --git a/program/Cargo.toml b/program/Cargo.toml index a1021b86..eb6aa4ab 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -13,7 +13,7 @@ test-sbf = [] [dependencies] arrayref = "0.3.7" -borsh = "1.5.0" +borsh = "1.5.1" bytemuck = "1.16" num-derive = "0.4" num-traits = "0.2" From 21392724581fea7685facb1c78ae36b895447f9d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 14:12:39 +0200 Subject: [PATCH 0855/1076] build(deps-dev): bump prettier from 3.2.5 to 3.3.0 (#6781) Bumps [prettier](https://github.com/prettier/prettier) from 3.2.5 to 3.3.0. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/3.2.5...3.3.0) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index e7e2ed35..c9e4f0ae 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -71,7 +71,7 @@ "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", "jest": "^29.0.0", - "prettier": "^3.2.5", + "prettier": "^3.3.0", "rimraf": "^5.0.7", "rollup": "^4.18.0", "rollup-plugin-dts": "^6.1.1", From ca0ed55796b44bc42197ef6e3b2fc15a061fa254 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 14:12:50 +0200 Subject: [PATCH 0856/1076] build(deps-dev): bump @types/node from 20.12.13 to 20.14.0 (#6782) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.12.13 to 20.14.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index c9e4f0ae..c8414f4b 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -62,7 +62,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.12.13", + "@types/node": "^20.14.0", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.11.0", "@typescript-eslint/parser": "^7.11.0", From 77b4108a4ce882bc8826c178a0a86d1735bdfaa6 Mon Sep 17 00:00:00 2001 From: Jon C Date: Mon, 3 Jun 2024 19:12:24 +0200 Subject: [PATCH 0857/1076] stake-pool-js: Bump version to 1.1.4 for release (#6786) --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index c8414f4b..4003f4ad 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-stake-pool", - "version": "1.1.3", + "version": "1.1.4", "description": "SPL Stake Pool Program JS API", "scripts": { "build": "tsc && cross-env NODE_ENV=production rollup -c", From 9d77539d39da91c3d16edafbfe2c454f110f31e4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Jun 2024 12:37:31 +0200 Subject: [PATCH 0858/1076] build(deps-dev): bump @types/node from 20.14.0 to 20.14.1 (#6787) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.14.0 to 20.14.1. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 4003f4ad..211f87b2 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -62,7 +62,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.14.0", + "@types/node": "^20.14.1", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.11.0", "@typescript-eslint/parser": "^7.11.0", From 3d48e545ffb917f78f1cd2db9a5c6d784c22f48b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Jun 2024 12:37:50 +0200 Subject: [PATCH 0859/1076] build(deps-dev): bump @typescript-eslint/parser from 7.11.0 to 7.12.0 (#6788) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.11.0 to 7.12.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.12.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 211f87b2..fca992e4 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -65,7 +65,7 @@ "@types/node": "^20.14.1", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.11.0", - "@typescript-eslint/parser": "^7.11.0", + "@typescript-eslint/parser": "^7.12.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", From 8a427f4197cbb523d73e137c937421fba26358a2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Jun 2024 13:04:46 +0200 Subject: [PATCH 0860/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 7.11.0 to 7.12.0 (#6789) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.11.0 to 7.12.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.12.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index fca992e4..862006f1 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/jest": "^29.5.12", "@types/node": "^20.14.1", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^7.11.0", + "@typescript-eslint/eslint-plugin": "^7.12.0", "@typescript-eslint/parser": "^7.12.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", From 201a9b926711c298a27497643be4cba0be748848 Mon Sep 17 00:00:00 2001 From: Jon C Date: Tue, 4 Jun 2024 22:27:12 +0200 Subject: [PATCH 0861/1076] stake-pool-js: Fix build for downstream users (#6793) * stake-pool-js: Remove borsh to fix downstream usage * Bump version to 1.1.5 --- clients/js-legacy/package.json | 3 +- clients/js-legacy/rollup.config.mjs | 4 +- clients/js-legacy/src/codecs.ts | 159 ++++++++++++++++++ clients/js-legacy/src/layouts.ts | 8 +- .../js-legacy/src/types/buffer-layout.d.ts | 7 + 5 files changed, 173 insertions(+), 8 deletions(-) create mode 100644 clients/js-legacy/src/codecs.ts diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 862006f1..9883e57a 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-stake-pool", - "version": "1.1.4", + "version": "1.1.5", "description": "SPL Stake Pool Program JS API", "scripts": { "build": "tsc && cross-env NODE_ENV=production rollup -c", @@ -43,7 +43,6 @@ ], "license": "ISC", "dependencies": { - "@coral-xyz/borsh": "^0.30.0", "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "0.4.6", "@solana/web3.js": "^1.91.8", diff --git a/clients/js-legacy/rollup.config.mjs b/clients/js-legacy/rollup.config.mjs index 1742dcd1..f1ceb7e4 100644 --- a/clients/js-legacy/rollup.config.mjs +++ b/clients/js-legacy/rollup.config.mjs @@ -66,12 +66,12 @@ function generateConfig(configType, format) { // Prevent dependencies from being bundled config.external = [ - '@coral-xyz/borsh', '@solana/buffer-layout', '@solana/spl-token', '@solana/web3.js', 'bn.js', 'buffer', + 'buffer-layout', ]; } @@ -94,12 +94,12 @@ function generateConfig(configType, format) { // Prevent dependencies from being bundled config.external = [ - '@coral-xyz/borsh', '@solana/buffer-layout', '@solana/spl-token', '@solana/web3.js', 'bn.js', 'buffer', + 'buffer-layout', ]; } diff --git a/clients/js-legacy/src/codecs.ts b/clients/js-legacy/src/codecs.ts new file mode 100644 index 00000000..0dbbde55 --- /dev/null +++ b/clients/js-legacy/src/codecs.ts @@ -0,0 +1,159 @@ +import { blob, Layout as LayoutCls, offset, seq, struct, u32, u8 } from 'buffer-layout'; +import { PublicKey } from '@solana/web3.js'; +import BN from 'bn.js'; + +export interface Layout { + span: number; + property?: string; + + decode(b: Buffer, offset?: number): T; + + encode(src: T, b: Buffer, offset?: number): number; + + getSpan(b: Buffer, offset?: number): number; + + replicate(name: string): this; +} + +class BNLayout extends LayoutCls { + blob: Layout; + signed: boolean; + + constructor(span: number, signed: boolean, property?: string) { + super(span, property); + this.blob = blob(span); + this.signed = signed; + } + + decode(b: Buffer, offset = 0) { + const num = new BN(this.blob.decode(b, offset), 10, 'le'); + if (this.signed) { + return num.fromTwos(this.span * 8).clone(); + } + return num; + } + + encode(src: BN, b: Buffer, offset = 0) { + if (this.signed) { + src = src.toTwos(this.span * 8); + } + return this.blob.encode(src.toArrayLike(Buffer, 'le', this.span), b, offset); + } +} + +export function u64(property?: string): Layout { + return new BNLayout(8, false, property); +} + +class WrappedLayout extends LayoutCls { + layout: Layout; + decoder: (data: T) => U; + encoder: (src: U) => T; + + constructor( + layout: Layout, + decoder: (data: T) => U, + encoder: (src: U) => T, + property?: string, + ) { + super(layout.span, property); + this.layout = layout; + this.decoder = decoder; + this.encoder = encoder; + } + + decode(b: Buffer, offset?: number): U { + return this.decoder(this.layout.decode(b, offset)); + } + + encode(src: U, b: Buffer, offset?: number): number { + return this.layout.encode(this.encoder(src), b, offset); + } + + getSpan(b: Buffer, offset?: number): number { + return this.layout.getSpan(b, offset); + } +} + +export function publicKey(property?: string): Layout { + return new WrappedLayout( + blob(32), + (b: Buffer) => new PublicKey(b), + (key: PublicKey) => key.toBuffer(), + property, + ); +} + +class OptionLayout extends LayoutCls { + layout: Layout; + discriminator: Layout; + + constructor(layout: Layout, property?: string) { + super(-1, property); + this.layout = layout; + this.discriminator = u8(); + } + + encode(src: T | null, b: Buffer, offset = 0): number { + if (src === null || src === undefined) { + return this.discriminator.encode(0, b, offset); + } + this.discriminator.encode(1, b, offset); + return this.layout.encode(src, b, offset + 1) + 1; + } + + decode(b: Buffer, offset = 0): T | null { + const discriminator = this.discriminator.decode(b, offset); + if (discriminator === 0) { + return null; + } else if (discriminator === 1) { + return this.layout.decode(b, offset + 1); + } + throw new Error('Invalid option ' + this.property); + } + + getSpan(b: Buffer, offset = 0): number { + const discriminator = this.discriminator.decode(b, offset); + if (discriminator === 0) { + return 1; + } else if (discriminator === 1) { + return this.layout.getSpan(b, offset + 1) + 1; + } + throw new Error('Invalid option ' + this.property); + } +} + +export function option(layout: Layout, property?: string): Layout { + return new OptionLayout(layout, property); +} + +export function bool(property?: string): Layout { + return new WrappedLayout(u8(), decodeBool, encodeBool, property); +} + +function decodeBool(value: number): boolean { + if (value === 0) { + return false; + } else if (value === 1) { + return true; + } + throw new Error('Invalid bool: ' + value); +} + +function encodeBool(value: boolean): number { + return value ? 1 : 0; +} + +export function vec(elementLayout: Layout, property?: string): Layout { + const length = u32('length'); + const layout: Layout<{ values: T[] }> = struct([ + length, + seq(elementLayout, offset(length, -length.span), 'values'), + ]); + return new WrappedLayout( + layout, + ({ values }) => values, + (values) => ({ values }), + property, + ); +} diff --git a/clients/js-legacy/src/layouts.ts b/clients/js-legacy/src/layouts.ts index 86feebdd..bc6c3cd3 100644 --- a/clients/js-legacy/src/layouts.ts +++ b/clients/js-legacy/src/layouts.ts @@ -1,5 +1,5 @@ -import { Layout, publicKey, struct, u32, u64, u8, option, vec } from '@coral-xyz/borsh'; -import { Layout as LayoutCls, u8 as u8Cls } from 'buffer-layout'; +import { Layout, publicKey, u64, option, vec } from './codecs'; +import { struct, Layout as LayoutCls, u8, u32 } from 'buffer-layout'; import { PublicKey } from '@solana/web3.js'; import BN from 'bn.js'; import { @@ -45,7 +45,7 @@ export class FutureEpochLayout extends LayoutCls { constructor(layout: Layout, property?: string) { super(-1, property); this.layout = layout; - this.discriminator = u8Cls(); + this.discriminator = u8(); } encode(src: T | null, b: Buffer, offset = 0): number { @@ -78,7 +78,7 @@ export class FutureEpochLayout extends LayoutCls { } } -export function futureEpoch(layout: Layout, property?: string): Layout { +export function futureEpoch(layout: Layout, property?: string): LayoutCls { return new FutureEpochLayout(layout, property); } diff --git a/clients/js-legacy/src/types/buffer-layout.d.ts b/clients/js-legacy/src/types/buffer-layout.d.ts index 90538bf0..5ef8ba4c 100644 --- a/clients/js-legacy/src/types/buffer-layout.d.ts +++ b/clients/js-legacy/src/types/buffer-layout.d.ts @@ -13,6 +13,13 @@ declare module 'buffer-layout' { property?: string, decodePrefixes?: boolean, ): Layout; + export function seq( + elementLayout: Layout, + count: number | Layout, + property?: string, + ): Layout; + export function offset(layout: Layout, offset?: number, property?: string): Layout; + export function blob(length: number | Layout, property?: string): Layout; export function s32(property?: string): Layout; export function u32(property?: string): Layout; export function s16(property?: string): Layout; From 93220aaf1c8b2795e57f6ddec280f169faed27a2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Jun 2024 12:53:33 +0200 Subject: [PATCH 0862/1076] build(deps-dev): bump @types/node from 20.14.1 to 20.14.2 (#6804) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.14.1 to 20.14.2. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 9883e57a..58e23531 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.14.1", + "@types/node": "^20.14.2", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.12.0", "@typescript-eslint/parser": "^7.12.0", From 8c38596dee0b310fefb7b338d6838acf0e81796e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Jun 2024 13:11:11 +0200 Subject: [PATCH 0863/1076] build(deps-dev): bump prettier from 3.3.0 to 3.3.1 (#6801) Bumps [prettier](https://github.com/prettier/prettier) from 3.3.0 to 3.3.1. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/3.3.0...3.3.1) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 58e23531..96a47855 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -70,7 +70,7 @@ "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", "jest": "^29.0.0", - "prettier": "^3.3.0", + "prettier": "^3.3.1", "rimraf": "^5.0.7", "rollup": "^4.18.0", "rollup-plugin-dts": "^6.1.1", From 826d0dca68a96309e781b4fa6ed62cdb92006120 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Jun 2024 00:08:31 +0200 Subject: [PATCH 0864/1076] build(deps-dev): bump @rollup/plugin-commonjs from 25.0.8 to 26.0.1 (#6810) Bumps [@rollup/plugin-commonjs](https://github.com/rollup/plugins/tree/HEAD/packages/commonjs) from 25.0.8 to 26.0.1. - [Changelog](https://github.com/rollup/plugins/blob/master/packages/commonjs/CHANGELOG.md) - [Commits](https://github.com/rollup/plugins/commits/commonjs-v26.0.1/packages/commonjs) --- updated-dependencies: - dependency-name: "@rollup/plugin-commonjs" dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 96a47855..2dfcbd27 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -53,7 +53,7 @@ }, "devDependencies": { "@rollup/plugin-alias": "^5.1.0", - "@rollup/plugin-commonjs": "^25.0.8", + "@rollup/plugin-commonjs": "^26.0.1", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-multi-entry": "^6.0.0", "@rollup/plugin-node-resolve": "^15.0.2", From 1da47232f9d818237488735cd99a2c6a7c0ae846 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Jun 2024 00:57:23 +0200 Subject: [PATCH 0865/1076] build(deps): bump @solana/web3.js from 1.91.8 to 1.92.3 (#6813) * build(deps): bump @solana/web3.js from 1.91.8 to 1.92.3 Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.91.8 to 1.92.3. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.91.8...v1.92.3) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Do it right --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 2dfcbd27..f4d73110 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -45,7 +45,7 @@ "dependencies": { "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "0.4.6", - "@solana/web3.js": "^1.91.8", + "@solana/web3.js": "^1.92.3", "bn.js": "^5.2.0", "buffer": "^6.0.3", "buffer-layout": "^1.2.2", From 828798d7c6a9c79fa88eb91a101c79eed0329f64 Mon Sep 17 00:00:00 2001 From: Sense Date: Sat, 8 Jun 2024 22:25:04 +0200 Subject: [PATCH 0866/1076] Add Create & Update Token Commands to Stake-Pool CLI (#6805) * Add token metadata commands * Update stake-pool/cli/src/main.rs Co-authored-by: Jon C * Update stake-pool/cli/src/main.rs Co-authored-by: Jon C * Fix formatting --------- Co-authored-by: Jon C --- clients/cli/src/main.rs | 137 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index a7bd4cfa..3c8e4af5 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -491,6 +491,57 @@ fn command_create_pool( Ok(()) } +fn create_token_metadata( + config: &Config, + stake_pool_address: &Pubkey, + name: String, + symbol: String, + uri: String, +) -> CommandResult { + let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; + + let mut signers = vec![config.fee_payer.as_ref(), config.manager.as_ref()]; + let instructions = vec![spl_stake_pool::instruction::create_token_metadata( + &spl_stake_pool::id(), + stake_pool_address, + &stake_pool.manager, + &stake_pool.pool_mint, + &config.fee_payer.pubkey(), + name, + symbol, + uri, + )]; + unique_signers!(signers); + let transaction = checked_transaction_with_signers(config, &instructions, &signers)?; + send_transaction(config, transaction)?; + Ok(()) +} + +fn update_token_metadata( + config: &Config, + stake_pool_address: &Pubkey, + name: String, + symbol: String, + uri: String, +) -> CommandResult { + let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; + + let mut signers = vec![config.fee_payer.as_ref(), config.manager.as_ref()]; + let instructions = vec![spl_stake_pool::instruction::update_token_metadata( + &spl_stake_pool::id(), + stake_pool_address, + &stake_pool.manager, + &stake_pool.pool_mint, + name, + symbol, + uri, + )]; + unique_signers!(signers); + let transaction = checked_transaction_with_signers(config, &instructions, &signers)?; + send_transaction(config, transaction)?; + Ok(()) +} + fn command_vsa_add( config: &Config, stake_pool_address: &Pubkey, @@ -2175,6 +2226,78 @@ fn main() { .help("Bypass fee checks, allowing pool to be created with unsafe fees"), ) ) + .subcommand(SubCommand::with_name("create-token-metadata") + .about("Creates stake pool token metadata") + .arg( + Arg::with_name("pool") + .index(1) + .validator(is_pubkey) + .value_name("POOL_ADDRESS") + .takes_value(true) + .required(true) + .help("Stake pool address"), + ) + .arg( + Arg::with_name("name") + .index(2) + .value_name("TOKEN_NAME") + .takes_value(true) + .required(true) + .help("Name of the token"), + ) + .arg( + Arg::with_name("symbol") + .index(3) + .value_name("TOKEN_SYMBOL") + .takes_value(true) + .required(true) + .help("Symbol of the token"), + ) + .arg( + Arg::with_name("uri") + .index(4) + .value_name("TOKEN_URI") + .takes_value(true) + .required(true) + .help("URI of the token metadata json"), + ) + ) + .subcommand(SubCommand::with_name("update-token-metadata") + .about("Updates stake pool token metadata") + .arg( + Arg::with_name("pool") + .index(1) + .validator(is_pubkey) + .value_name("POOL_ADDRESS") + .takes_value(true) + .required(true) + .help("Stake pool address"), + ) + .arg( + Arg::with_name("name") + .index(2) + .value_name("TOKEN_NAME") + .takes_value(true) + .required(true) + .help("Name of the token"), + ) + .arg( + Arg::with_name("symbol") + .index(3) + .value_name("TOKEN_SYMBOL") + .takes_value(true) + .required(true) + .help("Symbol of the token"), + ) + .arg( + Arg::with_name("uri") + .index(4) + .value_name("TOKEN_URI") + .takes_value(true) + .required(true) + .help("URI of the token metadata json"), + ) + ) .subcommand(SubCommand::with_name("add-validator") .about("Add validator account to the stake pool. Must be signed by the pool staker.") .arg( @@ -2900,6 +3023,20 @@ fn main() { unsafe_fees, ) } + ("create-token-metadata", Some(arg_matches)) => { + let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); + let name = value_t_or_exit!(arg_matches, "name", String); + let symbol = value_t_or_exit!(arg_matches, "symbol", String); + let uri = value_t_or_exit!(arg_matches, "uri", String); + create_token_metadata(&config, &stake_pool_address, name, symbol, uri) + } + ("update-token-metadata", Some(arg_matches)) => { + let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); + let name = value_t_or_exit!(arg_matches, "name", String); + let symbol = value_t_or_exit!(arg_matches, "symbol", String); + let uri = value_t_or_exit!(arg_matches, "uri", String); + update_token_metadata(&config, &stake_pool_address, name, symbol, uri) + } ("add-validator", Some(arg_matches)) => { let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); let vote_account_address = pubkey_of(arg_matches, "vote_account").unwrap(); From d1c5098dbeed332a2e9684d65ed480a374d08724 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Jun 2024 13:08:21 +0200 Subject: [PATCH 0867/1076] build(deps-dev): bump prettier from 3.3.1 to 3.3.2 (#6830) Bumps [prettier](https://github.com/prettier/prettier) from 3.3.1 to 3.3.2. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/3.3.1...3.3.2) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index f4d73110..408653eb 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -70,7 +70,7 @@ "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", "jest": "^29.0.0", - "prettier": "^3.3.1", + "prettier": "^3.3.2", "rimraf": "^5.0.7", "rollup": "^4.18.0", "rollup-plugin-dts": "^6.1.1", From b5578a25bb7ea04bfcd54364fd4cc3d66a3c69f0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Jun 2024 13:08:29 +0200 Subject: [PATCH 0868/1076] build(deps-dev): bump @typescript-eslint/parser from 7.12.0 to 7.13.0 (#6831) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.12.0 to 7.13.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.13.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 408653eb..0ded7985 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.14.2", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.12.0", - "@typescript-eslint/parser": "^7.12.0", + "@typescript-eslint/parser": "^7.13.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", From cb99a79178fe29ab2bcdbba65d00838fcab75c1a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Jun 2024 14:43:08 +0200 Subject: [PATCH 0869/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 7.12.0 to 7.13.0 (#6833) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.12.0 to 7.13.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.13.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 0ded7985..396107f0 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.12", "@types/node": "^20.14.2", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^7.12.0", + "@typescript-eslint/eslint-plugin": "^7.13.0", "@typescript-eslint/parser": "^7.13.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", From e7d36097ab9cb81c90624a73cdc5c90cc3562a0c Mon Sep 17 00:00:00 2001 From: Jon C Date: Wed, 12 Jun 2024 01:02:27 +0200 Subject: [PATCH 0870/1076] stake-pool-cli: Add metaplex program to setup script (#6837) script: Add metaplex program to setup script --- clients/cli/scripts/setup-stake-pool.sh | 11 ++++++++++- clients/cli/scripts/setup-test-validator.sh | 15 ++++++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/clients/cli/scripts/setup-stake-pool.sh b/clients/cli/scripts/setup-stake-pool.sh index d196a93f..9bcb5b8b 100755 --- a/clients/cli/scripts/setup-stake-pool.sh +++ b/clients/cli/scripts/setup-stake-pool.sh @@ -71,7 +71,16 @@ $spl_stake_pool \ --reserve-keypair "$reserve_keyfile" set +ex -echo "Depositing SOL into stake pool" stake_pool_pubkey=$(solana-keygen pubkey "$stake_pool_keyfile") set -ex + +echo "Creating token metadata" +$spl_stake_pool \ + create-token-metadata \ + "$stake_pool_pubkey" \ + NAME \ + SYMBOL \ + URI + +echo "Depositing SOL into stake pool" $spl_stake_pool deposit-sol "$stake_pool_pubkey" "$sol_amount" diff --git a/clients/cli/scripts/setup-test-validator.sh b/clients/cli/scripts/setup-test-validator.sh index c0414c6e..073e9f01 100755 --- a/clients/cli/scripts/setup-test-validator.sh +++ b/clients/cli/scripts/setup-test-validator.sh @@ -16,14 +16,23 @@ create_keypair () { } setup_test_validator() { - solana-test-validator -c SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy -c EmiU8AQkB2sswTxVB6aCmsAJftoowZGGDXuytm6X65R3 --url devnet --slots-per-epoch 32 --quiet --reset & + solana-test-validator \ + --clone-upgradeable-program SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy \ + --clone-upgradeable-program metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s \ + --url mainnet-beta \ + --slots-per-epoch 32 \ + --quiet --reset & # Uncomment to use a locally built stake program - #solana-test-validator --bpf-program SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy ../../../target/deploy/spl_stake_pool.so --slots-per-epoch 32 --quiet --reset & + #solana-test-validator \ + # --bpf-program SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy ../../../target/deploy/spl_stake_pool.so \ + # --bpf-program metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s ../../program/tests/fixtures/mpl_token_metadata.so \ + # --slots-per-epoch 32 \ + # --quiet --reset & pid=$! solana config set --url http://127.0.0.1:8899 solana config set --commitment confirmed echo "waiting for solana-test-validator, pid: $pid" - sleep 5 + sleep 15 } create_vote_accounts () { From 755eca3bf9154c9c13577e674334cb83dc6e3696 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Jun 2024 13:48:44 +0200 Subject: [PATCH 0871/1076] build(deps): bump @solana/web3.js from 1.92.3 to 1.93.0 (#6841) * build(deps): bump @solana/web3.js from 1.92.3 to 1.93.0 Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.92.3 to 1.93.0. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.92.3...v1.93.0) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Do it right --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon Cinque --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 396107f0..77332d39 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -45,7 +45,7 @@ "dependencies": { "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "0.4.6", - "@solana/web3.js": "^1.92.3", + "@solana/web3.js": "^1.93.0", "bn.js": "^5.2.0", "buffer": "^6.0.3", "buffer-layout": "^1.2.2", From f0898f7fc97a864688f595960df21e6d4049fb0f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jun 2024 13:01:15 +0200 Subject: [PATCH 0872/1076] build(deps-dev): bump ts-jest from 29.1.4 to 29.1.5 (#6855) Bumps [ts-jest](https://github.com/kulshekhar/ts-jest) from 29.1.4 to 29.1.5. - [Release notes](https://github.com/kulshekhar/ts-jest/releases) - [Changelog](https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md) - [Commits](https://github.com/kulshekhar/ts-jest/compare/v29.1.4...v29.1.5) --- updated-dependencies: - dependency-name: ts-jest dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 77332d39..5d17c6b3 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -74,7 +74,7 @@ "rimraf": "^5.0.7", "rollup": "^4.18.0", "rollup-plugin-dts": "^6.1.1", - "ts-jest": "^29.1.4", + "ts-jest": "^29.1.5", "typescript": "^5.4.5" }, "jest": { From 1f557663f28d315f9d786e10235050d31d021930 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Jun 2024 16:17:22 +0200 Subject: [PATCH 0873/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 7.13.0 to 7.13.1 (#6872) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.13.0 to 7.13.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.13.1/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 5d17c6b3..f64cbd62 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.12", "@types/node": "^20.14.2", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^7.13.0", + "@typescript-eslint/eslint-plugin": "^7.13.1", "@typescript-eslint/parser": "^7.13.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", From 84879e029d57989b7ff49e4cdba5137f9a4df349 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Jun 2024 17:35:51 +0200 Subject: [PATCH 0874/1076] build(deps-dev): bump @typescript-eslint/parser from 7.13.0 to 7.13.1 (#6870) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.13.0 to 7.13.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.13.1/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index f64cbd62..5d07e1fd 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.14.2", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.13.1", - "@typescript-eslint/parser": "^7.13.0", + "@typescript-eslint/parser": "^7.13.1", "cross-env": "^7.0.3", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", From 524901645dbfa6ace39603804796401e329097ab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Jun 2024 17:36:03 +0200 Subject: [PATCH 0875/1076] build(deps-dev): bump @types/node from 20.14.2 to 20.14.5 (#6869) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.14.2 to 20.14.5. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 5d07e1fd..9f562919 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.14.2", + "@types/node": "^20.14.5", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.13.1", "@typescript-eslint/parser": "^7.13.1", From 597d8af2b94c48e688c03f761cdea034c02320cd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Jun 2024 14:15:35 +0200 Subject: [PATCH 0876/1076] build(deps-dev): bump @types/node from 20.14.5 to 20.14.6 (#6888) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.14.5 to 20.14.6. Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 9f562919..9e1eccaf 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.14.5", + "@types/node": "^20.14.6", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.13.1", "@typescript-eslint/parser": "^7.13.1", From 5004a672923fbaed3e052547f8a8d62f9d95c928 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Jun 2024 15:05:09 +0200 Subject: [PATCH 0877/1076] build(deps): bump urllib3 from 1.26.18 to 1.26.19 in /stake-pool/py (#6891) Bumps [urllib3](https://github.com/urllib3/urllib3) from 1.26.18 to 1.26.19. - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/1.26.19/CHANGES.rst) - [Commits](https://github.com/urllib3/urllib3/compare/1.26.18...1.26.19) --- updated-dependencies: - dependency-name: urllib3 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/py/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/py/requirements.txt b/clients/py/requirements.txt index c2b25c73..905008f1 100644 --- a/clients/py/requirements.txt +++ b/clients/py/requirements.txt @@ -16,4 +16,4 @@ rfc3986==1.5.0 sniffio==1.2.0 solana==0.18.1 typing_extensions==4.3.0 -urllib3==1.26.18 +urllib3==1.26.19 From f0249d62a1f76a3ebe504a4c421124afd0471053 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Jun 2024 13:32:19 +0200 Subject: [PATCH 0878/1076] build(deps-dev): bump @types/node from 20.14.6 to 20.14.7 (#6892) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.14.6 to 20.14.7. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 9e1eccaf..8cd90e16 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.14.6", + "@types/node": "^20.14.7", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.13.1", "@typescript-eslint/parser": "^7.13.1", From eb3b2ff0f587855088062abdab065d733f4cfb31 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jun 2024 13:29:48 +0200 Subject: [PATCH 0879/1076] build(deps): bump proptest from 1.4.0 to 1.5.0 (#6899) Bumps [proptest](https://github.com/proptest-rs/proptest) from 1.4.0 to 1.5.0. - [Release notes](https://github.com/proptest-rs/proptest/releases) - [Changelog](https://github.com/proptest-rs/proptest/blob/master/CHANGELOG.md) - [Commits](https://github.com/proptest-rs/proptest/compare/v1.4.0...v1.5.0) --- updated-dependencies: - dependency-name: proptest dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index eb6aa4ab..d36bb8a4 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -36,7 +36,7 @@ bincode = "1.3.1" [dev-dependencies] assert_matches = "1.5.0" -proptest = "1.4" +proptest = "1.5" solana-program-test = ">=1.18.11,<=2" solana-sdk = ">=1.18.11,<=2" solana-vote-program = ">=1.18.11,<=2" From d3826e4592008d056ceed4a749d962139d72b8ce Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jun 2024 13:30:01 +0200 Subject: [PATCH 0880/1076] build(deps-dev): bump @types/node from 20.14.7 to 20.14.8 (#6906) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.14.7 to 20.14.8. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 8cd90e16..76ef5f07 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.14.7", + "@types/node": "^20.14.8", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.13.1", "@typescript-eslint/parser": "^7.13.1", From 37b958396df2af2206051f2482a6a6eff9a99f47 Mon Sep 17 00:00:00 2001 From: Jon C Date: Mon, 24 Jun 2024 14:37:09 +0200 Subject: [PATCH 0881/1076] token: Update to v5 for solana-program 2.0 compatibility (#6907) Updating to allow for version <= 2.0 of the solana crates can appear as a breaking change for new projects, since cargo pulls in the latest version of all dependencies, and once there's an attempt to mix v1 and v2, downstream users will see errors. This is made worse that the patch versions will quietly pick up the v2 dependency, so if someone doesn't know how to manipulate a cargo lockfile, they will get build errors and won't know how to resolve them. All other SPL crates contain a new breaking version (new major for crates on v1 or more, new minor for crates on v0.X), except for spl-token. Bump spl-token to v5. --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 16a5debb..c64bcf7d 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -29,7 +29,7 @@ spl-associated-token-account = { version = "=3.0.2", path = "../../associated-to spl-stake-pool = { version = "=1.0.0", path = "../program", features = [ "no-entrypoint", ] } -spl-token = { version = "=4.0", path = "../../token/program", features = [ +spl-token = { version = "=5.0", path = "../../token/program", features = [ "no-entrypoint", ] } bs58 = "0.4.0" diff --git a/program/Cargo.toml b/program/Cargo.toml index d36bb8a4..b41db543 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -40,7 +40,7 @@ proptest = "1.5" solana-program-test = ">=1.18.11,<=2" solana-sdk = ">=1.18.11,<=2" solana-vote-program = ">=1.18.11,<=2" -spl-token = { version = "4.0", path = "../../token/program", features = [ +spl-token = { version = "5.0", path = "../../token/program", features = [ "no-entrypoint", ] } test-case = "3.3" From 701f77c7f2a6875cfb59d97f8852013fd26aeb8f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jun 2024 14:37:53 +0200 Subject: [PATCH 0882/1076] build(deps): bump @solana/web3.js from 1.93.0 to 1.93.1 (#6905) * build(deps): bump @solana/web3.js from 1.93.0 to 1.93.1 Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.93.0 to 1.93.1. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.93.0...v1.93.1) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Do it right --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon C --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 76ef5f07..0e4894f9 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -45,7 +45,7 @@ "dependencies": { "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "0.4.6", - "@solana/web3.js": "^1.93.0", + "@solana/web3.js": "^1.93.1", "bn.js": "^5.2.0", "buffer": "^6.0.3", "buffer-layout": "^1.2.2", From 1f98a0de0e20dced54ab4ac8e82e96833a7ee7eb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jun 2024 15:16:50 +0200 Subject: [PATCH 0883/1076] build(deps-dev): bump typescript from 5.4.5 to 5.5.2 (#6894) * build(deps-dev): bump typescript from 5.4.5 to 5.5.2 Bumps [typescript](https://github.com/Microsoft/TypeScript) from 5.4.5 to 5.5.2. - [Release notes](https://github.com/Microsoft/TypeScript/releases) - [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml) - [Commits](https://github.com/Microsoft/TypeScript/compare/v5.4.5...v5.5.2) --- updated-dependencies: - dependency-name: typescript dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Explicitly specify @types/node dep in account-compression --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon C --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 0e4894f9..4052ccb0 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -75,7 +75,7 @@ "rollup": "^4.18.0", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.1.5", - "typescript": "^5.4.5" + "typescript": "^5.5.2" }, "jest": { "moduleFileExtensions": [ From b4f8163b893ccef18e30ef1f2d448eacc844f8fd Mon Sep 17 00:00:00 2001 From: Jon C Date: Tue, 25 Jun 2024 11:11:23 +0200 Subject: [PATCH 0884/1076] deps: Upgrade to Solana v2 (#6908) * solana: Update deps to 2.0.0 * Update lockfile * Update toolchain version * Update nightly version * Fix check issues * Fix clippy * Revert upgrade for account compression libs * Install build deps for serde test * Fixup versions * Fixup twoxtx build * Revert solana install version * Actually, get version 2.0.0 from the correct place --- clients/cli/Cargo.toml | 18 +++++++++--------- program/Cargo.toml | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index c64bcf7d..83994d6a 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -14,15 +14,15 @@ clap = "2.33.3" serde = "1.0.203" serde_derive = "1.0.130" serde_json = "1.0.117" -solana-account-decoder = ">=1.18.11,<=2" -solana-clap-utils = ">=1.18.11,<=2" -solana-cli-config = ">=1.18.11,<=2" -solana-cli-output = ">=1.18.11,<=2" -solana-client = ">=1.18.11,<=2" -solana-logger = ">=1.18.11,<=2" -solana-program = ">=1.18.11,<=2" -solana-remote-wallet = ">=1.18.11,<=2" -solana-sdk = ">=1.18.11,<=2" +solana-account-decoder = "2.0.0" +solana-clap-utils = "2.0.0" +solana-cli-config = "2.0.0" +solana-cli-output = "2.0.0" +solana-client = "2.0.0" +solana-logger = "2.0.0" +solana-program = "2.0.0" +solana-remote-wallet = "2.0.0" +solana-sdk = "2.0.0" spl-associated-token-account = { version = "=3.0.2", path = "../../associated-token-account/program", features = [ "no-entrypoint", ] } diff --git a/program/Cargo.toml b/program/Cargo.toml index b41db543..7d7b32aa 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -20,7 +20,7 @@ num-traits = "0.2" num_enum = "0.7.2" serde = "1.0.203" serde_derive = "1.0.103" -solana-program = ">=1.18.11,<=2" +solana-program = "2.0.0" solana-security-txt = "1.1.1" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint", @@ -37,9 +37,9 @@ bincode = "1.3.1" [dev-dependencies] assert_matches = "1.5.0" proptest = "1.5" -solana-program-test = ">=1.18.11,<=2" -solana-sdk = ">=1.18.11,<=2" -solana-vote-program = ">=1.18.11,<=2" +solana-program-test = "2.0.0" +solana-sdk = "2.0.0" +solana-vote-program = "2.0.0" spl-token = { version = "5.0", path = "../../token/program", features = [ "no-entrypoint", ] } From ea672308e77170a4f672ba85f7b8b3ce55334263 Mon Sep 17 00:00:00 2001 From: Jon C Date: Tue, 25 Jun 2024 13:17:22 +0200 Subject: [PATCH 0885/1076] token: Bump to v6 for Solana v2 compatibility (#6918) --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 83994d6a..f0784d2a 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -29,7 +29,7 @@ spl-associated-token-account = { version = "=3.0.2", path = "../../associated-to spl-stake-pool = { version = "=1.0.0", path = "../program", features = [ "no-entrypoint", ] } -spl-token = { version = "=5.0", path = "../../token/program", features = [ +spl-token = { version = "=6.0", path = "../../token/program", features = [ "no-entrypoint", ] } bs58 = "0.4.0" diff --git a/program/Cargo.toml b/program/Cargo.toml index 7d7b32aa..a4d49184 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -40,7 +40,7 @@ proptest = "1.5" solana-program-test = "2.0.0" solana-sdk = "2.0.0" solana-vote-program = "2.0.0" -spl-token = { version = "5.0", path = "../../token/program", features = [ +spl-token = { version = "6.0", path = "../../token/program", features = [ "no-entrypoint", ] } test-case = "3.3" From a39a92a18e379e110acea864cf9358a4e3c46796 Mon Sep 17 00:00:00 2001 From: Jon C Date: Tue, 25 Jun 2024 13:41:25 +0200 Subject: [PATCH 0886/1076] pod: Bump to 0.3.0 for Solana v2 compat (#6917) --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index a4d49184..15d03731 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -25,7 +25,7 @@ solana-security-txt = "1.1.1" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint", ] } -spl-pod = { version = "0.2.2", path = "../../libraries/pod", features = [ +spl-pod = { version = "0.3.0", path = "../../libraries/pod", features = [ "borsh", ] } spl-token-2022 = { version = "3.0.2", path = "../../token/program-2022", features = [ From c67b6ca93c3a046950fb9aa5e384af41d2310397 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Jun 2024 14:46:03 +0200 Subject: [PATCH 0887/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 7.13.1 to 7.14.1 (#6927) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.13.1 to 7.14.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.14.1/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 4052ccb0..82aabf8a 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.12", "@types/node": "^20.14.8", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^7.13.1", + "@typescript-eslint/eslint-plugin": "^7.14.1", "@typescript-eslint/parser": "^7.13.1", "cross-env": "^7.0.3", "eslint": "^8.57.0", From 26ceb98f3e6bcc6fc3693ebc24fc1284a6d88354 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Jun 2024 15:02:44 +0200 Subject: [PATCH 0888/1076] build(deps-dev): bump @typescript-eslint/parser from 7.13.1 to 7.14.1 (#6922) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.13.1 to 7.14.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.14.1/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 82aabf8a..57574ea4 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.14.8", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.14.1", - "@typescript-eslint/parser": "^7.13.1", + "@typescript-eslint/parser": "^7.14.1", "cross-env": "^7.0.3", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", From d48983696ab91324e463b39a426ecb4fc9f1733d Mon Sep 17 00:00:00 2001 From: Jon C Date: Tue, 25 Jun 2024 15:42:18 +0200 Subject: [PATCH 0889/1076] token-2022: Bump to v4 for Solana v2 compatibility (#6930) --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 15d03731..31bc06cf 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -28,7 +28,7 @@ spl-math = { version = "0.2", path = "../../libraries/math", features = [ spl-pod = { version = "0.3.0", path = "../../libraries/pod", features = [ "borsh", ] } -spl-token-2022 = { version = "3.0.2", path = "../../token/program-2022", features = [ +spl-token-2022 = { version = "4.0.0", path = "../../token/program-2022", features = [ "no-entrypoint", ] } thiserror = "1.0" From 14c9e1ee296771f607cc5556ee1d2983b26a8eff Mon Sep 17 00:00:00 2001 From: Jon C Date: Wed, 26 Jun 2024 01:13:42 +0200 Subject: [PATCH 0890/1076] associated-token-account: Bump to v4 for Solana v2 (#6933) --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index f0784d2a..b39be805 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -23,7 +23,7 @@ solana-logger = "2.0.0" solana-program = "2.0.0" solana-remote-wallet = "2.0.0" solana-sdk = "2.0.0" -spl-associated-token-account = { version = "=3.0.2", path = "../../associated-token-account/program", features = [ +spl-associated-token-account = { version = "=4.0.0", path = "../../associated-token-account/program", features = [ "no-entrypoint", ] } spl-stake-pool = { version = "=1.0.0", path = "../program", features = [ From 36833df4eadd83eab8808e2cb9fa00833521b197 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 26 Jun 2024 02:21:40 +0200 Subject: [PATCH 0891/1076] build(deps): bump serde_json from 1.0.117 to 1.0.118 (#6909) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.117 to 1.0.118. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.117...v1.0.118) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index b39be805..172b7544 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ borsh = "1.5.1" clap = "2.33.3" serde = "1.0.203" serde_derive = "1.0.130" -serde_json = "1.0.117" +serde_json = "1.0.118" solana-account-decoder = "2.0.0" solana-clap-utils = "2.0.0" solana-cli-config = "2.0.0" From 83b01bb731fe824ffe18e3705fc63879565fab35 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 26 Jun 2024 12:04:31 +0200 Subject: [PATCH 0892/1076] build(deps): bump bs58 from 0.4.0 to 0.5.1 (#6935) Bumps [bs58](https://github.com/Nullus157/bs58-rs) from 0.4.0 to 0.5.1. - [Changelog](https://github.com/Nullus157/bs58-rs/blob/main/CHANGELOG.md) - [Commits](https://github.com/Nullus157/bs58-rs/compare/0.4.0...0.5.1) --- updated-dependencies: - dependency-name: bs58 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 172b7544..36f9a79d 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -32,7 +32,7 @@ spl-stake-pool = { version = "=1.0.0", path = "../program", features = [ spl-token = { version = "=6.0", path = "../../token/program", features = [ "no-entrypoint", ] } -bs58 = "0.4.0" +bs58 = "0.5.1" bincode = "1.3.1" [[bin]] From 342eff6c52fdea8a2f58476ffb1ad8c2d746e291 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 26 Jun 2024 13:03:04 +0200 Subject: [PATCH 0893/1076] build(deps-dev): bump @types/node from 20.14.8 to 20.14.9 (#6936) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.14.8 to 20.14.9. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 57574ea4..2f4f1371 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.14.8", + "@types/node": "^20.14.9", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.14.1", "@typescript-eslint/parser": "^7.14.1", From 436ee3eba05f81fd5788e881bdf127519f6c37c0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2024 01:29:54 +0200 Subject: [PATCH 0894/1076] build(deps): bump @solana/web3.js from 1.93.1 to 1.93.2 (#6939) * build(deps): bump @solana/web3.js from 1.93.1 to 1.93.2 Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.93.1 to 1.93.2. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.93.1...v1.93.2) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Fixup types --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon C --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 2f4f1371..d74d64f0 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -45,7 +45,7 @@ "dependencies": { "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "0.4.6", - "@solana/web3.js": "^1.93.1", + "@solana/web3.js": "^1.93.2", "bn.js": "^5.2.0", "buffer": "^6.0.3", "buffer-layout": "^1.2.2", From f3c5887692df4287a936095247365f4c35fb5de8 Mon Sep 17 00:00:00 2001 From: Jon C Date: Thu, 27 Jun 2024 23:09:26 +0200 Subject: [PATCH 0895/1076] stake-pool: Bump to v2 for Solana v2 compatibility (#6943) --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 36f9a79d..9f1f6038 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -26,7 +26,7 @@ solana-sdk = "2.0.0" spl-associated-token-account = { version = "=4.0.0", path = "../../associated-token-account/program", features = [ "no-entrypoint", ] } -spl-stake-pool = { version = "=1.0.0", path = "../program", features = [ +spl-stake-pool = { version = "=2.0.0", path = "../program", features = [ "no-entrypoint", ] } spl-token = { version = "=6.0", path = "../../token/program", features = [ diff --git a/program/Cargo.toml b/program/Cargo.toml index 31bc06cf..9833fef7 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "spl-stake-pool" -version = "1.0.0" +version = "2.0.0" description = "Solana Program Library Stake Pool" authors = ["Solana Labs Maintainers "] repository = "https://github.com/solana-labs/solana-program-library" From 588eb918fbd451e033cab48f0cfbeb1bc6ca73d5 Mon Sep 17 00:00:00 2001 From: Jon C Date: Thu, 27 Jun 2024 23:52:09 +0200 Subject: [PATCH 0896/1076] stake-pool-cli: Bump to v2 for Solana v2 compatibility (#6944) --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 9f1f6038..dab65125 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -6,7 +6,7 @@ homepage = "https://spl.solana.com/stake-pool" license = "Apache-2.0" name = "spl-stake-pool-cli" repository = "https://github.com/solana-labs/solana-program-library" -version = "1.0.0" +version = "2.0.0" [dependencies] borsh = "1.5.1" From 7401c0f3b03cc3994dc97aea3fd0dd7b1d211f47 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Jun 2024 23:21:33 +0200 Subject: [PATCH 0897/1076] build(deps): bump @solana/web3.js from 1.93.2 to 1.93.4 (#6947) * build(deps): bump @solana/web3.js from 1.93.2 to 1.93.4 Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.93.2 to 1.93.4. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.93.2...v1.93.4) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Do it right * Kick CI * Really kick it --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon C --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index d74d64f0..56148693 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -45,7 +45,7 @@ "dependencies": { "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "0.4.6", - "@solana/web3.js": "^1.93.2", + "@solana/web3.js": "^1.93.4", "bn.js": "^5.2.0", "buffer": "^6.0.3", "buffer-layout": "^1.2.2", From e8eaabe3116593d16fb963e7df9ef3080bfddc37 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 23:20:42 +0200 Subject: [PATCH 0898/1076] build(deps): bump serde_json from 1.0.118 to 1.0.119 (#6957) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.118 to 1.0.119. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.118...v1.0.119) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index dab65125..fb503919 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ borsh = "1.5.1" clap = "2.33.3" serde = "1.0.203" serde_derive = "1.0.130" -serde_json = "1.0.118" +serde_json = "1.0.119" solana-account-decoder = "2.0.0" solana-clap-utils = "2.0.0" solana-cli-config = "2.0.0" From 0f0d36c3f8b3c228b89c79ea8865e9582e22913f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jul 2024 22:37:48 +0200 Subject: [PATCH 0899/1076] build(deps-dev): bump @typescript-eslint/parser from 7.14.1 to 7.15.0 (#6967) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.14.1 to 7.15.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.15.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 56148693..759e22f4 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.14.9", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.14.1", - "@typescript-eslint/parser": "^7.14.1", + "@typescript-eslint/parser": "^7.15.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", From 2568872a52a63401106eff3600e0cc2c5a028c89 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jul 2024 22:38:22 +0200 Subject: [PATCH 0900/1076] build(deps): bump serde_json from 1.0.119 to 1.0.120 (#6966) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.119 to 1.0.120. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.119...v1.0.120) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index fb503919..309c09ff 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ borsh = "1.5.1" clap = "2.33.3" serde = "1.0.203" serde_derive = "1.0.130" -serde_json = "1.0.119" +serde_json = "1.0.120" solana-account-decoder = "2.0.0" solana-clap-utils = "2.0.0" solana-cli-config = "2.0.0" From d6552e5eec4a18810961d38f95304e6c694a7ad4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jul 2024 22:52:07 +0200 Subject: [PATCH 0901/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 7.14.1 to 7.15.0 (#6969) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.14.1 to 7.15.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.15.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 759e22f4..cf83f27b 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.12", "@types/node": "^20.14.9", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^7.14.1", + "@typescript-eslint/eslint-plugin": "^7.15.0", "@typescript-eslint/parser": "^7.15.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", From f016aa19dee80e7105d97113deceb1758f65be82 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jul 2024 23:08:09 +0200 Subject: [PATCH 0902/1076] build(deps-dev): bump typescript from 5.5.2 to 5.5.3 (#6971) Bumps [typescript](https://github.com/Microsoft/TypeScript) from 5.5.2 to 5.5.3. - [Release notes](https://github.com/Microsoft/TypeScript/releases) - [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml) - [Commits](https://github.com/Microsoft/TypeScript/compare/v5.5.2...v5.5.3) --- updated-dependencies: - dependency-name: typescript dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index cf83f27b..05f36294 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -75,7 +75,7 @@ "rollup": "^4.18.0", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.1.5", - "typescript": "^5.5.2" + "typescript": "^5.5.3" }, "jest": { "moduleFileExtensions": [ From 3c5804ec4cef71005953446833f5445d029b16dd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 Jul 2024 23:37:14 +0100 Subject: [PATCH 0903/1076] build(deps): bump superstruct from 1.0.4 to 2.0.0 (#6981) Bumps [superstruct](https://github.com/ianstormtaylor/superstruct) from 1.0.4 to 2.0.0. - [Release notes](https://github.com/ianstormtaylor/superstruct/releases) - [Changelog](https://github.com/ianstormtaylor/superstruct/blob/main/Changelog.md) - [Commits](https://github.com/ianstormtaylor/superstruct/compare/v1.0.4...v2.0.0) --- updated-dependencies: - dependency-name: superstruct dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 05f36294..898eb73c 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -49,7 +49,7 @@ "bn.js": "^5.2.0", "buffer": "^6.0.3", "buffer-layout": "^1.2.2", - "superstruct": "^1.0.4" + "superstruct": "^2.0.0" }, "devDependencies": { "@rollup/plugin-alias": "^5.1.0", From 37a733b6e7008079a3db8fd7b0812c3158d826a0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 Jul 2024 23:37:29 +0100 Subject: [PATCH 0904/1076] build(deps): bump certifi from 2023.7.22 to 2024.7.4 in /stake-pool/py (#6982) Bumps [certifi](https://github.com/certifi/python-certifi) from 2023.7.22 to 2024.7.4. - [Commits](https://github.com/certifi/python-certifi/compare/2023.07.22...2024.07.04) --- updated-dependencies: - dependency-name: certifi dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/py/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/py/requirements.txt b/clients/py/requirements.txt index 905008f1..668602a5 100644 --- a/clients/py/requirements.txt +++ b/clients/py/requirements.txt @@ -1,7 +1,7 @@ anyio==3.6.1 base58==2.1.1 cachetools==4.2.4 -certifi==2023.7.22 +certifi==2024.7.4 cffi==1.15.1 charset-normalizer==2.1.0 construct==2.10.68 From 2d4368faa6e9c1eaf14ed78d0a2361bd3095e734 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 Jul 2024 23:54:14 +0100 Subject: [PATCH 0905/1076] build(deps): bump @solana/web3.js from 1.93.4 to 1.94.0 (#6963) * build(deps): bump @solana/web3.js from 1.93.4 to 1.94.0 Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.93.4 to 1.94.0. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.93.4...v1.94.0) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Do it right --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon C --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 898eb73c..797ad8a8 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -45,7 +45,7 @@ "dependencies": { "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "0.4.6", - "@solana/web3.js": "^1.93.4", + "@solana/web3.js": "^1.94.0", "bn.js": "^5.2.0", "buffer": "^6.0.3", "buffer-layout": "^1.2.2", From 0dff7ca9b8eeacf2179e0ba370b8bf92ef8be431 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 21:54:31 +0200 Subject: [PATCH 0906/1076] build(deps): bump serde from 1.0.203 to 1.0.204 (#6983) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.203 to 1.0.204. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.203...v1.0.204) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 309c09ff..8258e32b 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "2.0.0" [dependencies] borsh = "1.5.1" clap = "2.33.3" -serde = "1.0.203" +serde = "1.0.204" serde_derive = "1.0.130" serde_json = "1.0.120" solana-account-decoder = "2.0.0" diff --git a/program/Cargo.toml b/program/Cargo.toml index 9833fef7..9fa3c29e 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,7 +18,7 @@ bytemuck = "1.16" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.2" -serde = "1.0.203" +serde = "1.0.204" serde_derive = "1.0.103" solana-program = "2.0.0" solana-security-txt = "1.1.1" From aa2f999b13e85779b6d0be84a43c12342b68c0ca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 21:54:51 +0200 Subject: [PATCH 0907/1076] build(deps-dev): bump rimraf from 5.0.7 to 5.0.8 (#6985) Bumps [rimraf](https://github.com/isaacs/rimraf) from 5.0.7 to 5.0.8. - [Changelog](https://github.com/isaacs/rimraf/blob/main/CHANGELOG.md) - [Commits](https://github.com/isaacs/rimraf/compare/v5.0.7...v5.0.8) --- updated-dependencies: - dependency-name: rimraf dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 797ad8a8..4ba86010 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -71,7 +71,7 @@ "eslint-plugin-prettier": "^5.1.3", "jest": "^29.0.0", "prettier": "^3.3.2", - "rimraf": "^5.0.7", + "rimraf": "^5.0.8", "rollup": "^4.18.0", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.1.5", From d8c6ab60674458bcaa82e051c2acb5ce7fbab942 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 21:54:59 +0200 Subject: [PATCH 0908/1076] build(deps): bump superstruct from 2.0.0 to 2.0.2 (#6986) Bumps [superstruct](https://github.com/ianstormtaylor/superstruct) from 2.0.0 to 2.0.2. - [Release notes](https://github.com/ianstormtaylor/superstruct/releases) - [Changelog](https://github.com/ianstormtaylor/superstruct/blob/main/Changelog.md) - [Commits](https://github.com/ianstormtaylor/superstruct/compare/v2.0.0...v2.0.2) --- updated-dependencies: - dependency-name: superstruct dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 4ba86010..e2dc94fa 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -49,7 +49,7 @@ "bn.js": "^5.2.0", "buffer": "^6.0.3", "buffer-layout": "^1.2.2", - "superstruct": "^2.0.0" + "superstruct": "^2.0.2" }, "devDependencies": { "@rollup/plugin-alias": "^5.1.0", From 342df2b768d7b769d8c2568ed9884963be4718e6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 21:55:07 +0200 Subject: [PATCH 0909/1076] build(deps-dev): bump @types/node from 20.14.9 to 20.14.10 (#6987) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.14.9 to 20.14.10. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index e2dc94fa..436d6af9 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.14.9", + "@types/node": "^20.14.10", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.15.0", "@typescript-eslint/parser": "^7.15.0", From a1e8ef519c682f2d5527e62b86599a08273ee99a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Jul 2024 17:51:59 +0200 Subject: [PATCH 0910/1076] build(deps-dev): bump rimraf from 5.0.8 to 6.0.0 (#6995) Bumps [rimraf](https://github.com/isaacs/rimraf) from 5.0.8 to 6.0.0. - [Changelog](https://github.com/isaacs/rimraf/blob/main/CHANGELOG.md) - [Commits](https://github.com/isaacs/rimraf/compare/v5.0.8...v6.0.0) --- updated-dependencies: - dependency-name: rimraf dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 436d6af9..070bf263 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -71,7 +71,7 @@ "eslint-plugin-prettier": "^5.1.3", "jest": "^29.0.0", "prettier": "^3.3.2", - "rimraf": "^5.0.8", + "rimraf": "^6.0.0", "rollup": "^4.18.0", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.1.5", From 630c9efc3f56edb9a798f408f28b48490d2d1cfb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Jul 2024 18:23:59 +0200 Subject: [PATCH 0911/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 7.15.0 to 7.16.0 (#6996) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.15.0 to 7.16.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.16.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 070bf263..30f98486 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.12", "@types/node": "^20.14.10", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^7.15.0", + "@typescript-eslint/eslint-plugin": "^7.16.0", "@typescript-eslint/parser": "^7.15.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", From 36536f1e2341854f4cafcff755e97ef1081b2809 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Jul 2024 18:24:30 +0200 Subject: [PATCH 0912/1076] build(deps-dev): bump rollup from 4.18.0 to 4.18.1 (#6998) Bumps [rollup](https://github.com/rollup/rollup) from 4.18.0 to 4.18.1. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.18.0...v4.18.1) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 30f98486..a1a53e27 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.3.2", "rimraf": "^6.0.0", - "rollup": "^4.18.0", + "rollup": "^4.18.1", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.1.5", "typescript": "^5.5.3" From 5001a343cecdc6aa6f4a4e7010ff02d452941cf0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Jul 2024 18:24:47 +0200 Subject: [PATCH 0913/1076] build(deps-dev): bump ts-jest from 29.1.5 to 29.2.1 (#7002) Bumps [ts-jest](https://github.com/kulshekhar/ts-jest) from 29.1.5 to 29.2.1. - [Release notes](https://github.com/kulshekhar/ts-jest/releases) - [Changelog](https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md) - [Commits](https://github.com/kulshekhar/ts-jest/compare/v29.1.5...v29.2.1) --- updated-dependencies: - dependency-name: ts-jest dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index a1a53e27..a2fc1bca 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -74,7 +74,7 @@ "rimraf": "^6.0.0", "rollup": "^4.18.1", "rollup-plugin-dts": "^6.1.1", - "ts-jest": "^29.1.5", + "ts-jest": "^29.2.1", "typescript": "^5.5.3" }, "jest": { From 1d8429ec6d504fdc87475f792b274b6430424a68 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jul 2024 20:03:31 +0200 Subject: [PATCH 0914/1076] build(deps-dev): bump @typescript-eslint/parser from 7.15.0 to 7.16.0 (#6999) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.15.0 to 7.16.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.16.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index a2fc1bca..45fa2a4f 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.14.10", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.16.0", - "@typescript-eslint/parser": "^7.15.0", + "@typescript-eslint/parser": "^7.16.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", From 46d4d4a126fdd9ada4f3e07896ec62eb128e0773 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jul 2024 20:03:44 +0200 Subject: [PATCH 0915/1076] build(deps-dev): bump ts-jest from 29.2.1 to 29.2.2 (#7007) Bumps [ts-jest](https://github.com/kulshekhar/ts-jest) from 29.2.1 to 29.2.2. - [Release notes](https://github.com/kulshekhar/ts-jest/releases) - [Changelog](https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md) - [Commits](https://github.com/kulshekhar/ts-jest/compare/v29.2.1...v29.2.2) --- updated-dependencies: - dependency-name: ts-jest dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 45fa2a4f..b6b55ef8 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -74,7 +74,7 @@ "rimraf": "^6.0.0", "rollup": "^4.18.1", "rollup-plugin-dts": "^6.1.1", - "ts-jest": "^29.2.1", + "ts-jest": "^29.2.2", "typescript": "^5.5.3" }, "jest": { From ad002faf609c7e05208bd102e8b0ab4128709610 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jul 2024 20:03:55 +0200 Subject: [PATCH 0916/1076] build(deps-dev): bump rimraf from 6.0.0 to 6.0.1 (#7008) Bumps [rimraf](https://github.com/isaacs/rimraf) from 6.0.0 to 6.0.1. - [Changelog](https://github.com/isaacs/rimraf/blob/main/CHANGELOG.md) - [Commits](https://github.com/isaacs/rimraf/compare/v6.0.0...v6.0.1) --- updated-dependencies: - dependency-name: rimraf dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index b6b55ef8..7100a203 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -71,7 +71,7 @@ "eslint-plugin-prettier": "^5.1.3", "jest": "^29.0.0", "prettier": "^3.3.2", - "rimraf": "^6.0.0", + "rimraf": "^6.0.1", "rollup": "^4.18.1", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.2.2", From aba6b4119dc91b78cd4cbaaa7732a5b3ac79bf2b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 13:53:25 +0200 Subject: [PATCH 0917/1076] build(deps-dev): bump prettier from 3.3.2 to 3.3.3 (#7015) Bumps [prettier](https://github.com/prettier/prettier) from 3.3.2 to 3.3.3. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/3.3.2...3.3.3) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 7100a203..3dc199bd 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -70,7 +70,7 @@ "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", "jest": "^29.0.0", - "prettier": "^3.3.2", + "prettier": "^3.3.3", "rimraf": "^6.0.1", "rollup": "^4.18.1", "rollup-plugin-dts": "^6.1.1", From e5f9be64ae95d73f6ca9801fad7670921a14f1f4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Jul 2024 14:06:03 +0200 Subject: [PATCH 0918/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 7.16.0 to 7.16.1 (#7018) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.16.0 to 7.16.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.16.1/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 3dc199bd..9ac20ef3 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.12", "@types/node": "^20.14.10", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^7.16.0", + "@typescript-eslint/eslint-plugin": "^7.16.1", "@typescript-eslint/parser": "^7.16.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", From 33a9afa7ee04fda7c76ef1ae70d307f610d423e4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Jul 2024 14:26:04 +0200 Subject: [PATCH 0919/1076] build(deps-dev): bump @typescript-eslint/parser from 7.16.0 to 7.16.1 (#7017) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.16.0 to 7.16.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.16.1/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 9ac20ef3..d5fd1605 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.14.10", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.16.1", - "@typescript-eslint/parser": "^7.16.0", + "@typescript-eslint/parser": "^7.16.1", "cross-env": "^7.0.3", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", From bdc2847fc1d1c93f24d4b28c0cebd67d09ec8c34 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Jul 2024 15:15:50 +0200 Subject: [PATCH 0920/1076] build(deps): bump @solana/web3.js from 1.94.0 to 1.95.0 (#6997) * build(deps): bump @solana/web3.js from 1.94.0 to 1.95.0 Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.94.0 to 1.95.0. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.94.0...v1.95.0) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Do it right --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon C --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index d5fd1605..2e4b6fb7 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -45,7 +45,7 @@ "dependencies": { "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "0.4.6", - "@solana/web3.js": "^1.94.0", + "@solana/web3.js": "^1.95.0", "bn.js": "^5.2.0", "buffer": "^6.0.3", "buffer-layout": "^1.2.2", From 27947c56a230fafa7b7bfc0731503479ddf37b16 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Jul 2024 14:16:41 +0200 Subject: [PATCH 0921/1076] build(deps-dev): bump @types/node from 20.14.10 to 20.14.11 (#7024) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.14.10 to 20.14.11. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 2e4b6fb7..d679ac4f 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.14.10", + "@types/node": "^20.14.11", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.16.1", "@typescript-eslint/parser": "^7.16.1", From 35a25a6bc3f0d578e70306194f15ab8973c8a0ca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Jul 2024 12:40:29 +0200 Subject: [PATCH 0922/1076] build(deps-dev): bump eslint-plugin-prettier from 5.1.3 to 5.2.1 (#7029) Bumps [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) from 5.1.3 to 5.2.1. - [Release notes](https://github.com/prettier/eslint-plugin-prettier/releases) - [Changelog](https://github.com/prettier/eslint-plugin-prettier/blob/master/CHANGELOG.md) - [Commits](https://github.com/prettier/eslint-plugin-prettier/compare/v5.1.3...v5.2.1) --- updated-dependencies: - dependency-name: eslint-plugin-prettier dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index d679ac4f..f09e2d64 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -68,7 +68,7 @@ "cross-env": "^7.0.3", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", - "eslint-plugin-prettier": "^5.1.3", + "eslint-plugin-prettier": "^5.2.1", "jest": "^29.0.0", "prettier": "^3.3.3", "rimraf": "^6.0.1", From cf4a5dc8fb25a7fcb8290501cfc83f07ae3ad674 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Jul 2024 16:04:04 +0200 Subject: [PATCH 0923/1076] build(deps): bump @solana/web3.js from 1.95.0 to 1.95.1 (#7028) * build(deps): bump @solana/web3.js from 1.95.0 to 1.95.1 Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.95.0 to 1.95.1. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.95.0...v1.95.1) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Do it right --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon C --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index f09e2d64..2c50b528 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -45,7 +45,7 @@ "dependencies": { "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "0.4.6", - "@solana/web3.js": "^1.95.0", + "@solana/web3.js": "^1.95.1", "bn.js": "^5.2.0", "buffer": "^6.0.3", "buffer-layout": "^1.2.2", From 16a457ba664fb8a9866289ef8a184dc7eddace80 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jul 2024 13:47:56 +0200 Subject: [PATCH 0924/1076] build(deps-dev): bump ts-jest from 29.2.2 to 29.2.3 (#7030) Bumps [ts-jest](https://github.com/kulshekhar/ts-jest) from 29.2.2 to 29.2.3. - [Release notes](https://github.com/kulshekhar/ts-jest/releases) - [Changelog](https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md) - [Commits](https://github.com/kulshekhar/ts-jest/compare/v29.2.2...v29.2.3) --- updated-dependencies: - dependency-name: ts-jest dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 2c50b528..31d8f1ee 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -74,7 +74,7 @@ "rimraf": "^6.0.1", "rollup": "^4.18.1", "rollup-plugin-dts": "^6.1.1", - "ts-jest": "^29.2.2", + "ts-jest": "^29.2.3", "typescript": "^5.5.3" }, "jest": { From 3b11c3fd7e9210b926fbdcf0167d8ce9539d655e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 13:14:12 +0200 Subject: [PATCH 0925/1076] build(deps): bump arrayref from 0.3.7 to 0.3.8 (#7034) Bumps [arrayref](https://github.com/droundy/arrayref) from 0.3.7 to 0.3.8. - [Commits](https://github.com/droundy/arrayref/commits) --- updated-dependencies: - dependency-name: arrayref dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 9fa3c29e..ffc4056b 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -12,7 +12,7 @@ no-entrypoint = [] test-sbf = [] [dependencies] -arrayref = "0.3.7" +arrayref = "0.3.8" borsh = "1.5.1" bytemuck = "1.16" num-derive = "0.4" From dd4771c0d9e62a9d14d4932eb6ef8f9e2ba3b399 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 13:14:25 +0200 Subject: [PATCH 0926/1076] build(deps-dev): bump rollup from 4.18.1 to 4.19.0 (#7037) Bumps [rollup](https://github.com/rollup/rollup) from 4.18.1 to 4.19.0. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.18.1...v4.19.0) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 31d8f1ee..aafc6b8c 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.3.3", "rimraf": "^6.0.1", - "rollup": "^4.18.1", + "rollup": "^4.19.0", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.2.3", "typescript": "^5.5.3" From 6414223a165bbe630df411c4cb9508f1e156753a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jul 2024 13:26:15 +0200 Subject: [PATCH 0927/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 7.16.1 to 7.17.0 (#7044) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.16.1 to 7.17.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.17.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index aafc6b8c..51c48aee 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.12", "@types/node": "^20.14.11", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^7.16.1", + "@typescript-eslint/eslint-plugin": "^7.17.0", "@typescript-eslint/parser": "^7.16.1", "cross-env": "^7.0.3", "eslint": "^8.57.0", From 434cb9d02da77556dc5f74d07bd2457181851138 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jul 2024 13:39:04 +0200 Subject: [PATCH 0928/1076] build(deps-dev): bump @typescript-eslint/parser from 7.16.1 to 7.17.0 (#7046) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.16.1 to 7.17.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.17.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 51c48aee..c58bf31f 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^20.14.11", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.17.0", - "@typescript-eslint/parser": "^7.16.1", + "@typescript-eslint/parser": "^7.17.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", From 986d0b6a402a878e149e37d580200f4a4b6bcab6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jul 2024 14:00:57 +0200 Subject: [PATCH 0929/1076] build(deps-dev): bump typescript from 5.5.3 to 5.5.4 (#7045) Bumps [typescript](https://github.com/Microsoft/TypeScript) from 5.5.3 to 5.5.4. - [Release notes](https://github.com/Microsoft/TypeScript/releases) - [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml) - [Commits](https://github.com/Microsoft/TypeScript/compare/v5.5.3...v5.5.4) --- updated-dependencies: - dependency-name: typescript dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index c58bf31f..b19b9056 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -75,7 +75,7 @@ "rollup": "^4.19.0", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.2.3", - "typescript": "^5.5.3" + "typescript": "^5.5.4" }, "jest": { "moduleFileExtensions": [ From 6763e1ce16355356b64c16961e5d116ef101e4d7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 Jul 2024 13:29:50 +0200 Subject: [PATCH 0930/1076] build(deps-dev): bump @types/node from 20.14.11 to 20.14.12 (#7049) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.14.11 to 20.14.12. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index b19b9056..c1a75dad 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.14.11", + "@types/node": "^20.14.12", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.17.0", "@typescript-eslint/parser": "^7.17.0", From 5cd09ca75594fc616090a809e593698c823cb3ad Mon Sep 17 00:00:00 2001 From: Jon C Date: Thu, 25 Jul 2024 15:01:50 +0200 Subject: [PATCH 0931/1076] stake-pool-py: Update to newer solana-py / solders (#7050) * stake-pool-py: Update to newer solana-py / solders * Harden tests further --- clients/py/bot/rebalance.py | 34 +- clients/py/optional-requirements.txt | 24 +- clients/py/requirements.txt | 27 +- clients/py/spl_token/actions.py | 41 +- clients/py/stake/actions.py | 66 ++- clients/py/stake/constants.py | 6 +- clients/py/stake/instructions.py | 48 +- clients/py/stake/state.py | 16 +- clients/py/stake_pool/actions.py | 340 +++++------ clients/py/stake_pool/constants.py | 56 +- clients/py/stake_pool/instructions.py | 554 +++++++++--------- clients/py/stake_pool/state.py | 61 +- clients/py/system/actions.py | 9 +- clients/py/tests/conftest.py | 26 +- clients/py/tests/test_a_time_sensitive.py | 28 +- clients/py/tests/test_add_remove.py | 10 +- clients/py/tests/test_bot_rebalance.py | 26 +- clients/py/tests/test_create.py | 30 +- .../test_create_update_token_metadata.py | 26 +- clients/py/tests/test_deposit_withdraw_sol.py | 17 +- .../py/tests/test_deposit_withdraw_stake.py | 26 +- clients/py/tests/test_stake.py | 16 +- clients/py/tests/test_system.py | 8 +- clients/py/tests/test_token.py | 8 +- clients/py/tests/test_vote.py | 9 +- clients/py/vote/actions.py | 34 +- clients/py/vote/constants.py | 4 +- clients/py/vote/instructions.py | 30 +- 28 files changed, 788 insertions(+), 792 deletions(-) diff --git a/clients/py/bot/rebalance.py b/clients/py/bot/rebalance.py index bc656a87..e12a6a9a 100644 --- a/clients/py/bot/rebalance.py +++ b/clients/py/bot/rebalance.py @@ -2,8 +2,8 @@ import asyncio import json -from solana.keypair import Keypair -from solana.publickey import PublicKey +from solders.keypair import Keypair +from solders.pubkey import Pubkey from solana.rpc.async_api import AsyncClient from solana.rpc.commitment import Confirmed @@ -27,30 +27,30 @@ async def get_client(endpoint: str) -> AsyncClient: return async_client -async def rebalance(endpoint: str, stake_pool_address: PublicKey, staker: Keypair, retained_reserve_amount: float): +async def rebalance(endpoint: str, stake_pool_address: Pubkey, staker: Keypair, retained_reserve_amount: float): async_client = await get_client(endpoint) - resp = await async_client.get_epoch_info(commitment=Confirmed) - epoch = resp['result']['epoch'] + epoch_resp = await async_client.get_epoch_info(commitment=Confirmed) + epoch = epoch_resp.value.epoch resp = await async_client.get_account_info(stake_pool_address, commitment=Confirmed) - data = resp['result']['value']['data'] - stake_pool = StakePool.decode(data[0], data[1]) + data = resp.value.data if resp.value else bytes() + stake_pool = StakePool.decode(data) print(f'Stake pool last update epoch {stake_pool.last_update_epoch}, current epoch {epoch}') if stake_pool.last_update_epoch != epoch: print('Updating stake pool') await update_stake_pool(async_client, staker, stake_pool_address) resp = await async_client.get_account_info(stake_pool_address, commitment=Confirmed) - data = resp['result']['value']['data'] - stake_pool = StakePool.decode(data[0], data[1]) + data = resp.value.data if resp.value else bytes() + stake_pool = StakePool.decode(data) - resp = await async_client.get_minimum_balance_for_rent_exemption(STAKE_LEN) - stake_rent_exemption = resp['result'] + rent_resp = await async_client.get_minimum_balance_for_rent_exemption(STAKE_LEN) + stake_rent_exemption = rent_resp.value retained_reserve_lamports = int(retained_reserve_amount * LAMPORTS_PER_SOL) - resp = await async_client.get_account_info(stake_pool.validator_list, commitment=Confirmed) - data = resp['result']['value']['data'] - validator_list = ValidatorList.decode(data[0], data[1]) + val_resp = await async_client.get_account_info(stake_pool.validator_list, commitment=Confirmed) + data = val_resp.value.data if val_resp.value else bytes() + validator_list = ValidatorList.decode(data) print('Stake pool stats:') print(f'* {stake_pool.total_lamports} total lamports') @@ -107,7 +107,7 @@ def keypair_from_file(keyfile_name: str) -> Keypair: data = keyfile.read() int_list = json.loads(data) bytes_list = [value.to_bytes(1, 'little') for value in int_list] - return Keypair.from_secret_key(b''.join(bytes_list)) + return Keypair.from_seed(b''.join(bytes_list)) if __name__ == "__main__": @@ -124,9 +124,9 @@ def keypair_from_file(keyfile_name: str) -> Keypair: help='RPC endpoint to use, e.g. https://api.mainnet-beta.solana.com') args = parser.parse_args() - stake_pool = PublicKey(args.stake_pool) + stake_pool = Pubkey(args.stake_pool) staker = keypair_from_file(args.staker) print(f'Rebalancing stake pool {stake_pool}') - print(f'Staker public key: {staker.public_key}') + print(f'Staker public key: {staker.pubkey()}') print(f'Amount to leave in the reserve: {args.reserve_amount} SOL') asyncio.run(rebalance(args.endpoint, stake_pool, staker, args.reserve_amount)) diff --git a/clients/py/optional-requirements.txt b/clients/py/optional-requirements.txt index 5aa59319..5f08be95 100644 --- a/clients/py/optional-requirements.txt +++ b/clients/py/optional-requirements.txt @@ -1,15 +1,11 @@ -attrs==22.1.0 -flake8==5.0.3 -iniconfig==1.1.1 +flake8==7.1.0 +iniconfig==2.0.0 mccabe==0.7.0 -mypy==0.971 -mypy-extensions==0.4.3 -packaging==21.3 -pluggy==1.0.0 -py==1.11.0 -pycodestyle==2.9.0 -pyflakes==2.5.0 -pyparsing==3.0.9 -pytest==7.1.2 -pytest-asyncio==0.19.0 -tomli==2.0.1 +mypy==1.11.0 +mypy-extensions==1.0.0 +packaging==24.1 +pluggy==1.5.0 +pycodestyle==2.12.0 +pyflakes==3.2.0 +pytest==8.3.1 +pytest-asyncio==0.23.8 diff --git a/clients/py/requirements.txt b/clients/py/requirements.txt index 668602a5..9b0f39a3 100644 --- a/clients/py/requirements.txt +++ b/clients/py/requirements.txt @@ -1,19 +1,14 @@ -anyio==3.6.1 -base58==2.1.1 -cachetools==4.2.4 +anyio==4.4.0 certifi==2024.7.4 -cffi==1.15.1 -charset-normalizer==2.1.0 construct==2.10.68 -h11==0.12.0 -httpcore==0.15.0 -httpx==0.23.0 +construct-typing==0.5.6 +h11==0.14.0 +httpcore==1.0.5 +httpx==0.27.0 idna==3.7 -pycparser==2.21 -PyNaCl==1.5.0 -requests==2.32.0 -rfc3986==1.5.0 -sniffio==1.2.0 -solana==0.18.1 -typing_extensions==4.3.0 -urllib3==1.26.19 +jsonalias==0.1.1 +sniffio==1.3.1 +solana==0.34.2 +solders==0.21.0 +typing_extensions==4.12.2 +websockets==11.0.3 diff --git a/clients/py/spl_token/actions.py b/clients/py/spl_token/actions.py index 6c00a928..99a03fd0 100644 --- a/clients/py/spl_token/actions.py +++ b/clients/py/spl_token/actions.py @@ -1,10 +1,10 @@ -from solana.publickey import PublicKey -from solana.keypair import Keypair +from solders.pubkey import Pubkey +from solders.keypair import Keypair from solana.rpc.async_api import AsyncClient from solana.rpc.commitment import Confirmed from solana.rpc.types import TxOpts from solana.transaction import Transaction -import solana.system_program as sys +import solders.system_program as sys from spl.token.constants import TOKEN_PROGRAM_ID from spl.token.async_client import AsyncToken @@ -12,33 +12,37 @@ import spl.token.instructions as spl_token +OPTS = TxOpts(skip_confirmation=False, preflight_commitment=Confirmed) + + async def create_associated_token_account( client: AsyncClient, payer: Keypair, - owner: PublicKey, - mint: PublicKey -) -> PublicKey: - txn = Transaction() + owner: Pubkey, + mint: Pubkey +) -> Pubkey: + txn = Transaction(fee_payer=payer.pubkey()) create_txn = spl_token.create_associated_token_account( - payer=payer.public_key, owner=owner, mint=mint + payer=payer.pubkey(), owner=owner, mint=mint ) txn.add(create_txn) - await client.send_transaction(txn, payer, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) - return create_txn.keys[1].pubkey + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash + await client.send_transaction(txn, payer, recent_blockhash=recent_blockhash, opts=OPTS) + return create_txn.accounts[1].pubkey -async def create_mint(client: AsyncClient, payer: Keypair, mint: Keypair, mint_authority: PublicKey): +async def create_mint(client: AsyncClient, payer: Keypair, mint: Keypair, mint_authority: Pubkey): mint_balance = await AsyncToken.get_min_balance_rent_for_exempt_for_mint(client) - print(f"Creating pool token mint {mint.public_key}") - txn = Transaction() + print(f"Creating pool token mint {mint.pubkey()}") + txn = Transaction(fee_payer=payer.pubkey()) txn.add( sys.create_account( sys.CreateAccountParams( - from_pubkey=payer.public_key, - new_account_pubkey=mint.public_key, + from_pubkey=payer.pubkey(), + to_pubkey=mint.pubkey(), lamports=mint_balance, space=MINT_LAYOUT.sizeof(), - program_id=TOKEN_PROGRAM_ID, + owner=TOKEN_PROGRAM_ID, ) ) ) @@ -46,12 +50,13 @@ async def create_mint(client: AsyncClient, payer: Keypair, mint: Keypair, mint_a spl_token.initialize_mint( spl_token.InitializeMintParams( program_id=TOKEN_PROGRAM_ID, - mint=mint.public_key, + mint=mint.pubkey(), decimals=9, mint_authority=mint_authority, freeze_authority=None, ) ) ) + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash await client.send_transaction( - txn, payer, mint, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + txn, payer, mint, recent_blockhash=recent_blockhash, opts=OPTS) diff --git a/clients/py/stake/actions.py b/clients/py/stake/actions.py index 2963a43d..1147a56d 100644 --- a/clients/py/stake/actions.py +++ b/clients/py/stake/actions.py @@ -1,36 +1,40 @@ -from solana.publickey import PublicKey -from solana.keypair import Keypair +from solders.pubkey import Pubkey +from solders.keypair import Keypair +import solders.system_program as sys +from solana.constants import SYSTEM_PROGRAM_ID from solana.rpc.async_api import AsyncClient from solana.rpc.commitment import Confirmed from solana.rpc.types import TxOpts -from solana.sysvar import SYSVAR_CLOCK_PUBKEY, SYSVAR_STAKE_HISTORY_PUBKEY +from solders.sysvar import CLOCK, STAKE_HISTORY from solana.transaction import Transaction -import solana.system_program as sys from stake.constants import STAKE_LEN, STAKE_PROGRAM_ID, SYSVAR_STAKE_CONFIG_ID from stake.state import Authorized, Lockup, StakeAuthorize import stake.instructions as st -async def create_stake(client: AsyncClient, payer: Keypair, stake: Keypair, authority: PublicKey, lamports: int): - print(f"Creating stake {stake.public_key}") +OPTS = TxOpts(skip_confirmation=False, preflight_commitment=Confirmed) + + +async def create_stake(client: AsyncClient, payer: Keypair, stake: Keypair, authority: Pubkey, lamports: int): + print(f"Creating stake {stake.pubkey()}") resp = await client.get_minimum_balance_for_rent_exemption(STAKE_LEN) - txn = Transaction() + txn = Transaction(fee_payer=payer.pubkey()) txn.add( sys.create_account( sys.CreateAccountParams( - from_pubkey=payer.public_key, - new_account_pubkey=stake.public_key, - lamports=resp['result'] + lamports, + from_pubkey=payer.pubkey(), + to_pubkey=stake.pubkey(), + lamports=resp.value + lamports, space=STAKE_LEN, - program_id=STAKE_PROGRAM_ID, + owner=STAKE_PROGRAM_ID, ) ) ) txn.add( st.initialize( st.InitializeParams( - stake=stake.public_key, + stake=stake.pubkey(), authorized=Authorized( staker=authority, withdrawer=authority, @@ -38,50 +42,50 @@ async def create_stake(client: AsyncClient, payer: Keypair, stake: Keypair, auth lockup=Lockup( unix_timestamp=0, epoch=0, - custodian=sys.SYS_PROGRAM_ID, + custodian=SYSTEM_PROGRAM_ID, ) ) ) ) - await client.send_transaction( - txn, payer, stake, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash + await client.send_transaction(txn, payer, stake, recent_blockhash=recent_blockhash, opts=OPTS) -async def delegate_stake(client: AsyncClient, payer: Keypair, staker: Keypair, stake: PublicKey, vote: PublicKey): - txn = Transaction() +async def delegate_stake(client: AsyncClient, payer: Keypair, staker: Keypair, stake: Pubkey, vote: Pubkey): + txn = Transaction(fee_payer=payer.pubkey()) txn.add( st.delegate_stake( st.DelegateStakeParams( stake=stake, vote=vote, - clock_sysvar=SYSVAR_CLOCK_PUBKEY, - stake_history_sysvar=SYSVAR_STAKE_HISTORY_PUBKEY, + clock_sysvar=CLOCK, + stake_history_sysvar=STAKE_HISTORY, stake_config_id=SYSVAR_STAKE_CONFIG_ID, - staker=staker.public_key, + staker=staker.pubkey(), ) ) ) - signers = [payer, staker] if payer != staker else [payer] - await client.send_transaction( - txn, *signers, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + signers = [payer, staker] if payer.pubkey() != staker.pubkey() else [payer] + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash + await client.send_transaction(txn, *signers, recent_blockhash=recent_blockhash, opts=OPTS) async def authorize( - client: AsyncClient, payer: Keypair, authority: Keypair, stake: PublicKey, - new_authority: PublicKey, stake_authorize: StakeAuthorize + client: AsyncClient, payer: Keypair, authority: Keypair, stake: Pubkey, + new_authority: Pubkey, stake_authorize: StakeAuthorize ): - txn = Transaction() + txn = Transaction(fee_payer=payer.pubkey()) txn.add( st.authorize( st.AuthorizeParams( stake=stake, - clock_sysvar=SYSVAR_CLOCK_PUBKEY, - authority=authority.public_key, + clock_sysvar=CLOCK, + authority=authority.pubkey(), new_authority=new_authority, stake_authorize=stake_authorize, ) ) ) - signers = [payer, authority] if payer != authority else [payer] - await client.send_transaction( - txn, *signers, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + signers = [payer, authority] if payer.pubkey() != authority.pubkey() else [payer] + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash + await client.send_transaction(txn, *signers, recent_blockhash=recent_blockhash, opts=OPTS) diff --git a/clients/py/stake/constants.py b/clients/py/stake/constants.py index 344a8a5e..da1c644c 100644 --- a/clients/py/stake/constants.py +++ b/clients/py/stake/constants.py @@ -1,11 +1,11 @@ """Stake Program Constants.""" -from solana.publickey import PublicKey +from solders.pubkey import Pubkey -STAKE_PROGRAM_ID: PublicKey = PublicKey("Stake11111111111111111111111111111111111111") +STAKE_PROGRAM_ID = Pubkey.from_string("Stake11111111111111111111111111111111111111") """Public key that identifies the Stake program.""" -SYSVAR_STAKE_CONFIG_ID: PublicKey = PublicKey("StakeConfig11111111111111111111111111111111") +SYSVAR_STAKE_CONFIG_ID = Pubkey.from_string("StakeConfig11111111111111111111111111111111") """Public key that identifies the Stake config sysvar.""" STAKE_LEN: int = 200 diff --git a/clients/py/stake/instructions.py b/clients/py/stake/instructions.py index f4b116ba..91e7e7dc 100644 --- a/clients/py/stake/instructions.py +++ b/clients/py/stake/instructions.py @@ -7,9 +7,9 @@ from construct import Int32ul, Pass # type: ignore from construct import Bytes, Struct -from solana.publickey import PublicKey -from solana.sysvar import SYSVAR_RENT_PUBKEY -from solana.transaction import AccountMeta, TransactionInstruction +from solders.pubkey import Pubkey +from solders.sysvar import RENT +from solders.instruction import AccountMeta, Instruction from stake.constants import STAKE_PROGRAM_ID from stake.state import AUTHORIZED_LAYOUT, LOCKUP_LAYOUT, Authorized, Lockup, StakeAuthorize @@ -20,7 +20,7 @@ class InitializeParams(NamedTuple): """Initialize stake transaction params.""" - stake: PublicKey + stake: Pubkey """`[w]` Uninitialized stake account.""" authorized: Authorized """Information about the staker and withdrawer keys.""" @@ -31,32 +31,32 @@ class InitializeParams(NamedTuple): class DelegateStakeParams(NamedTuple): """Initialize stake transaction params.""" - stake: PublicKey + stake: Pubkey """`[w]` Uninitialized stake account.""" - vote: PublicKey + vote: Pubkey """`[]` Vote account to which this stake will be delegated.""" - clock_sysvar: PublicKey + clock_sysvar: Pubkey """`[]` Clock sysvar.""" - stake_history_sysvar: PublicKey + stake_history_sysvar: Pubkey """`[]` Stake history sysvar that carries stake warmup/cooldown history.""" - stake_config_id: PublicKey + stake_config_id: Pubkey """`[]` Address of config account that carries stake config.""" - staker: PublicKey + staker: Pubkey """`[s]` Stake authority.""" class AuthorizeParams(NamedTuple): """Authorize stake transaction params.""" - stake: PublicKey + stake: Pubkey """`[w]` Initialized stake account to modify.""" - clock_sysvar: PublicKey + clock_sysvar: Pubkey """`[]` Clock sysvar.""" - authority: PublicKey + authority: Pubkey """`[s]` Current stake authority.""" # Params - new_authority: PublicKey + new_authority: Pubkey """New authority's public key.""" stake_authorize: StakeAuthorize """Type of authority to modify, staker or withdrawer.""" @@ -116,12 +116,12 @@ class InstructionType(IntEnum): ) -def initialize(params: InitializeParams) -> TransactionInstruction: +def initialize(params: InitializeParams) -> Instruction: """Creates a transaction instruction to initialize a new stake.""" - return TransactionInstruction( - keys=[ + return Instruction( + accounts=[ AccountMeta(pubkey=params.stake, is_signer=False, is_writable=True), - AccountMeta(pubkey=SYSVAR_RENT_PUBKEY, is_signer=False, is_writable=False), + AccountMeta(pubkey=RENT, is_signer=False, is_writable=False), ], program_id=STAKE_PROGRAM_ID, data=INSTRUCTIONS_LAYOUT.build( @@ -136,10 +136,10 @@ def initialize(params: InitializeParams) -> TransactionInstruction: ) -def delegate_stake(params: DelegateStakeParams) -> TransactionInstruction: +def delegate_stake(params: DelegateStakeParams) -> Instruction: """Creates an instruction to delegate a stake account.""" - return TransactionInstruction( - keys=[ + return Instruction( + accounts=[ AccountMeta(pubkey=params.stake, is_signer=False, is_writable=True), AccountMeta(pubkey=params.vote, is_signer=False, is_writable=False), AccountMeta(pubkey=params.clock_sysvar, is_signer=False, is_writable=False), @@ -157,10 +157,10 @@ def delegate_stake(params: DelegateStakeParams) -> TransactionInstruction: ) -def authorize(params: AuthorizeParams) -> TransactionInstruction: +def authorize(params: AuthorizeParams) -> Instruction: """Creates an instruction to change the authority on a stake account.""" - return TransactionInstruction( - keys=[ + return Instruction( + accounts=[ AccountMeta(pubkey=params.stake, is_signer=False, is_writable=True), AccountMeta(pubkey=params.clock_sysvar, is_signer=False, is_writable=False), AccountMeta(pubkey=params.authority, is_signer=True, is_writable=False), diff --git a/clients/py/stake/state.py b/clients/py/stake/state.py index 8d8ac81f..45d1942a 100644 --- a/clients/py/stake/state.py +++ b/clients/py/stake/state.py @@ -4,8 +4,7 @@ from typing import NamedTuple, Dict from construct import Bytes, Container, Struct, Float64l, Int32ul, Int64ul # type: ignore -from solana.publickey import PublicKey -from solana.utils.helpers import decode_byte_string +from solders.pubkey import Pubkey PUBLIC_KEY_LAYOUT = Bytes(32) @@ -14,14 +13,14 @@ class Lockup(NamedTuple): """Lockup for a stake account.""" unix_timestamp: int epoch: int - custodian: PublicKey + custodian: Pubkey @classmethod def decode_container(cls, container: Container): return Lockup( unix_timestamp=container['unix_timestamp'], epoch=container['epoch'], - custodian=PublicKey(container['custodian']), + custodian=Pubkey(container['custodian']), ) def as_bytes_dict(self) -> Dict: @@ -32,8 +31,8 @@ def as_bytes_dict(self) -> Dict: class Authorized(NamedTuple): """Define who is authorized to change a stake.""" - staker: PublicKey - withdrawer: PublicKey + staker: Pubkey + withdrawer: Pubkey def as_bytes_dict(self) -> Dict: return { @@ -62,9 +61,8 @@ class StakeStake(NamedTuple): """Stake state.""" @classmethod - def decode(cls, data: str, encoding: str): - data_bytes = decode_byte_string(data, encoding) - parsed = STAKE_STATE_LAYOUT.parse(data_bytes) + def decode(cls, data: bytes): + parsed = STAKE_STATE_LAYOUT.parse(data) return StakeStake( state_type=parsed['state_type'], state=parsed['state'], diff --git a/clients/py/stake_pool/actions.py b/clients/py/stake_pool/actions.py index e44afba4..400f9252 100644 --- a/clients/py/stake_pool/actions.py +++ b/clients/py/stake_pool/actions.py @@ -1,13 +1,13 @@ from typing import Optional, Tuple -from solana.keypair import Keypair -from solana.publickey import PublicKey +from solders.keypair import Keypair +from solders.pubkey import Pubkey from solana.rpc.async_api import AsyncClient from solana.rpc.commitment import Confirmed from solana.rpc.types import TxOpts -from solana.sysvar import SYSVAR_CLOCK_PUBKEY, SYSVAR_RENT_PUBKEY, SYSVAR_STAKE_HISTORY_PUBKEY +from solders.sysvar import CLOCK, RENT, STAKE_HISTORY from solana.transaction import Transaction -import solana.system_program as sys +import solders.system_program as sys from spl.token.constants import TOKEN_PROGRAM_ID @@ -31,54 +31,58 @@ from spl_token.actions import create_mint, create_associated_token_account +OPTS = TxOpts(skip_confirmation=False, preflight_commitment=Confirmed) + + async def create(client: AsyncClient, manager: Keypair, stake_pool: Keypair, validator_list: Keypair, - pool_mint: PublicKey, reserve_stake: PublicKey, - manager_fee_account: PublicKey, fee: Fee, referral_fee: int): + pool_mint: Pubkey, reserve_stake: Pubkey, + manager_fee_account: Pubkey, fee: Fee, referral_fee: int): resp = await client.get_minimum_balance_for_rent_exemption(STAKE_POOL_LAYOUT.sizeof()) - pool_balance = resp['result'] - txn = Transaction() + pool_balance = resp.value + txn = Transaction(fee_payer=manager.pubkey()) txn.add( sys.create_account( sys.CreateAccountParams( - from_pubkey=manager.public_key, - new_account_pubkey=stake_pool.public_key, + from_pubkey=manager.pubkey(), + to_pubkey=stake_pool.pubkey(), lamports=pool_balance, space=STAKE_POOL_LAYOUT.sizeof(), - program_id=STAKE_POOL_PROGRAM_ID, + owner=STAKE_POOL_PROGRAM_ID, ) ) ) max_validators = 2950 # current supported max by the program, go big! validator_list_size = ValidatorList.calculate_validator_list_size(max_validators) resp = await client.get_minimum_balance_for_rent_exemption(validator_list_size) - validator_list_balance = resp['result'] + validator_list_balance = resp.value txn.add( sys.create_account( sys.CreateAccountParams( - from_pubkey=manager.public_key, - new_account_pubkey=validator_list.public_key, + from_pubkey=manager.pubkey(), + to_pubkey=validator_list.pubkey(), lamports=validator_list_balance, space=validator_list_size, - program_id=STAKE_POOL_PROGRAM_ID, + owner=STAKE_POOL_PROGRAM_ID, ) ) ) + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash await client.send_transaction( - txn, manager, stake_pool, validator_list, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + txn, manager, stake_pool, validator_list, recent_blockhash=recent_blockhash, opts=OPTS) (withdraw_authority, seed) = find_withdraw_authority_program_address( - STAKE_POOL_PROGRAM_ID, stake_pool.public_key) - txn = Transaction() + STAKE_POOL_PROGRAM_ID, stake_pool.pubkey()) + txn = Transaction(fee_payer=manager.pubkey()) txn.add( sp.initialize( sp.InitializeParams( program_id=STAKE_POOL_PROGRAM_ID, - stake_pool=stake_pool.public_key, - manager=manager.public_key, - staker=manager.public_key, + stake_pool=stake_pool.pubkey(), + manager=manager.pubkey(), + staker=manager.pubkey(), withdraw_authority=withdraw_authority, - validator_list=validator_list.public_key, + validator_list=validator_list.pubkey(), reserve_stake=reserve_stake, pool_mint=pool_mint, manager_fee_account=manager_fee_account, @@ -91,17 +95,17 @@ async def create(client: AsyncClient, manager: Keypair, ) ) ) - await client.send_transaction( - txn, manager, validator_list, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash + await client.send_transaction(txn, manager, recent_blockhash=recent_blockhash, opts=OPTS) async def create_all( client: AsyncClient, manager: Keypair, fee: Fee, referral_fee: int -) -> Tuple[PublicKey, PublicKey, PublicKey]: +) -> Tuple[Pubkey, Pubkey, Pubkey]: stake_pool = Keypair() validator_list = Keypair() (pool_withdraw_authority, seed) = find_withdraw_authority_program_address( - STAKE_POOL_PROGRAM_ID, stake_pool.public_key) + STAKE_POOL_PROGRAM_ID, stake_pool.pubkey()) reserve_stake = Keypair() await create_stake(client, manager, reserve_stake, pool_withdraw_authority, MINIMUM_RESERVE_LAMPORTS) @@ -112,26 +116,26 @@ async def create_all( manager_fee_account = await create_associated_token_account( client, manager, - manager.public_key, - pool_mint.public_key, + manager.pubkey(), + pool_mint.pubkey(), ) fee = Fee(numerator=1, denominator=1000) referral_fee = 20 await create( - client, manager, stake_pool, validator_list, pool_mint.public_key, - reserve_stake.public_key, manager_fee_account, fee, referral_fee) - return (stake_pool.public_key, validator_list.public_key, pool_mint.public_key) + client, manager, stake_pool, validator_list, pool_mint.pubkey(), + reserve_stake.pubkey(), manager_fee_account, fee, referral_fee) + return (stake_pool.pubkey(), validator_list.pubkey(), pool_mint.pubkey()) async def add_validator_to_pool( client: AsyncClient, staker: Keypair, - stake_pool_address: PublicKey, validator: PublicKey + stake_pool_address: Pubkey, validator: Pubkey ): resp = await client.get_account_info(stake_pool_address, commitment=Confirmed) - data = resp['result']['value']['data'] - stake_pool = StakePool.decode(data[0], data[1]) - txn = Transaction() + data = resp.value.data if resp.value else bytes() + stake_pool = StakePool.decode(data) + txn = Transaction(fee_payer=staker.pubkey()) txn.add( sp.add_validator_to_pool_with_vote( STAKE_POOL_PROGRAM_ID, @@ -143,22 +147,22 @@ async def add_validator_to_pool( None, ) ) - await client.send_transaction( - txn, staker, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash + await client.send_transaction(txn, staker, recent_blockhash=recent_blockhash, opts=OPTS) async def remove_validator_from_pool( client: AsyncClient, staker: Keypair, - stake_pool_address: PublicKey, validator: PublicKey + stake_pool_address: Pubkey, validator: Pubkey ): resp = await client.get_account_info(stake_pool_address, commitment=Confirmed) - data = resp['result']['value']['data'] - stake_pool = StakePool.decode(data[0], data[1]) + data = resp.value.data if resp.value else bytes() + stake_pool = StakePool.decode(data) resp = await client.get_account_info(stake_pool.validator_list, commitment=Confirmed) - data = resp['result']['value']['data'] - validator_list = ValidatorList.decode(data[0], data[1]) + data = resp.value.data if resp.value else bytes() + validator_list = ValidatorList.decode(data) validator_info = next(x for x in validator_list.validators if x.vote_account_address == validator) - txn = Transaction() + txn = Transaction(fee_payer=staker.pubkey()) txn.add( sp.remove_validator_from_pool_with_vote( STAKE_POOL_PROGRAM_ID, @@ -170,22 +174,21 @@ async def remove_validator_from_pool( validator_info.transient_seed_suffix, ) ) - await client.send_transaction( - txn, staker, - opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash + await client.send_transaction(txn, staker, recent_blockhash=recent_blockhash, opts=OPTS) async def deposit_sol( - client: AsyncClient, funder: Keypair, stake_pool_address: PublicKey, - destination_token_account: PublicKey, amount: int, + client: AsyncClient, funder: Keypair, stake_pool_address: Pubkey, + destination_token_account: Pubkey, amount: int, ): resp = await client.get_account_info(stake_pool_address, commitment=Confirmed) - data = resp['result']['value']['data'] - stake_pool = StakePool.decode(data[0], data[1]) + data = resp.value.data if resp.value else bytes() + stake_pool = StakePool.decode(data) (withdraw_authority, seed) = find_withdraw_authority_program_address(STAKE_POOL_PROGRAM_ID, stake_pool_address) - txn = Transaction() + txn = Transaction(fee_payer=funder.pubkey()) txn.add( sp.deposit_sol( sp.DepositSolParams( @@ -193,47 +196,47 @@ async def deposit_sol( stake_pool=stake_pool_address, withdraw_authority=withdraw_authority, reserve_stake=stake_pool.reserve_stake, - funding_account=funder.public_key, + funding_account=funder.pubkey(), destination_pool_account=destination_token_account, manager_fee_account=stake_pool.manager_fee_account, referral_pool_account=destination_token_account, pool_mint=stake_pool.pool_mint, - system_program_id=sys.SYS_PROGRAM_ID, + system_program_id=sys.ID, token_program_id=stake_pool.token_program_id, amount=amount, deposit_authority=None, ) ) ) - await client.send_transaction( - txn, funder, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash + await client.send_transaction(txn, funder, recent_blockhash=recent_blockhash, opts=OPTS) async def withdraw_sol( - client: AsyncClient, owner: Keypair, source_token_account: PublicKey, - stake_pool_address: PublicKey, destination_system_account: PublicKey, amount: int, + client: AsyncClient, owner: Keypair, source_token_account: Pubkey, + stake_pool_address: Pubkey, destination_system_account: Pubkey, amount: int, ): resp = await client.get_account_info(stake_pool_address, commitment=Confirmed) - data = resp['result']['value']['data'] - stake_pool = StakePool.decode(data[0], data[1]) + data = resp.value.data if resp.value else bytes() + stake_pool = StakePool.decode(data) (withdraw_authority, seed) = find_withdraw_authority_program_address(STAKE_POOL_PROGRAM_ID, stake_pool_address) - txn = Transaction() + txn = Transaction(fee_payer=owner.pubkey()) txn.add( sp.withdraw_sol( sp.WithdrawSolParams( program_id=STAKE_POOL_PROGRAM_ID, stake_pool=stake_pool_address, withdraw_authority=withdraw_authority, - source_transfer_authority=owner.public_key, + source_transfer_authority=owner.pubkey(), source_pool_account=source_token_account, reserve_stake=stake_pool.reserve_stake, destination_system_account=destination_system_account, manager_fee_account=stake_pool.manager_fee_account, pool_mint=stake_pool.pool_mint, - clock_sysvar=SYSVAR_CLOCK_PUBKEY, - stake_history_sysvar=SYSVAR_STAKE_HISTORY_PUBKEY, + clock_sysvar=CLOCK, + stake_history_sysvar=STAKE_HISTORY, stake_program_id=STAKE_PROGRAM_ID, token_program_id=stake_pool.token_program_id, amount=amount, @@ -241,25 +244,25 @@ async def withdraw_sol( ) ) ) - await client.send_transaction( - txn, owner, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash + await client.send_transaction(txn, owner, recent_blockhash=recent_blockhash, opts=OPTS) async def deposit_stake( client: AsyncClient, deposit_stake_authority: Keypair, - stake_pool_address: PublicKey, - validator_vote: PublicKey, - deposit_stake: PublicKey, - destination_pool_account: PublicKey, + stake_pool_address: Pubkey, + validator_vote: Pubkey, + deposit_stake: Pubkey, + destination_pool_account: Pubkey, ): resp = await client.get_account_info(stake_pool_address, commitment=Confirmed) - data = resp['result']['value']['data'] - stake_pool = StakePool.decode(data[0], data[1]) + data = resp.value.data if resp.value else bytes() + stake_pool = StakePool.decode(data) resp = await client.get_account_info(stake_pool.validator_list, commitment=Confirmed) - data = resp['result']['value']['data'] - validator_list = ValidatorList.decode(data[0], data[1]) + data = resp.value.data if resp.value else bytes() + validator_list = ValidatorList.decode(data) validator_info = next(x for x in validator_list.validators if x.vote_account_address == validator_vote) @@ -271,13 +274,13 @@ async def deposit_stake( validator_info.validator_seed_suffix or None, ) - txn = Transaction() + txn = Transaction(fee_payer=deposit_stake_authority.pubkey()) txn.add( st.authorize( st.AuthorizeParams( stake=deposit_stake, - clock_sysvar=SYSVAR_CLOCK_PUBKEY, - authority=deposit_stake_authority.public_key, + clock_sysvar=CLOCK, + authority=deposit_stake_authority.pubkey(), new_authority=stake_pool.stake_deposit_authority, stake_authorize=StakeAuthorize.STAKER, ) @@ -287,8 +290,8 @@ async def deposit_stake( st.authorize( st.AuthorizeParams( stake=deposit_stake, - clock_sysvar=SYSVAR_CLOCK_PUBKEY, - authority=deposit_stake_authority.public_key, + clock_sysvar=CLOCK, + authority=deposit_stake_authority.pubkey(), new_authority=stake_pool.stake_deposit_authority, stake_authorize=StakeAuthorize.WITHDRAWER, ) @@ -309,15 +312,15 @@ async def deposit_stake( manager_fee_account=stake_pool.manager_fee_account, referral_pool_account=destination_pool_account, pool_mint=stake_pool.pool_mint, - clock_sysvar=SYSVAR_CLOCK_PUBKEY, - stake_history_sysvar=SYSVAR_STAKE_HISTORY_PUBKEY, + clock_sysvar=CLOCK, + stake_history_sysvar=STAKE_HISTORY, token_program_id=stake_pool.token_program_id, stake_program_id=STAKE_PROGRAM_ID, ) ) ) - await client.send_transaction( - txn, deposit_stake_authority, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash + await client.send_transaction(txn, deposit_stake_authority, recent_blockhash=recent_blockhash, opts=OPTS) async def withdraw_stake( @@ -325,19 +328,19 @@ async def withdraw_stake( payer: Keypair, source_transfer_authority: Keypair, destination_stake: Keypair, - stake_pool_address: PublicKey, - validator_vote: PublicKey, - destination_stake_authority: PublicKey, - source_pool_account: PublicKey, + stake_pool_address: Pubkey, + validator_vote: Pubkey, + destination_stake_authority: Pubkey, + source_pool_account: Pubkey, amount: int, ): resp = await client.get_account_info(stake_pool_address, commitment=Confirmed) - data = resp['result']['value']['data'] - stake_pool = StakePool.decode(data[0], data[1]) + data = resp.value.data if resp.value else bytes() + stake_pool = StakePool.decode(data) resp = await client.get_account_info(stake_pool.validator_list, commitment=Confirmed) - data = resp['result']['value']['data'] - validator_list = ValidatorList.decode(data[0], data[1]) + data = resp.value.data if resp.value else bytes() + validator_list = ValidatorList.decode(data) validator_info = next(x for x in validator_list.validators if x.vote_account_address == validator_vote) @@ -349,18 +352,18 @@ async def withdraw_stake( validator_info.validator_seed_suffix or None, ) - resp = await client.get_minimum_balance_for_rent_exemption(STAKE_LEN) - stake_rent_exemption = resp['result'] + rent_resp = await client.get_minimum_balance_for_rent_exemption(STAKE_LEN) + stake_rent_exemption = rent_resp.value - txn = Transaction() + txn = Transaction(fee_payer=payer.pubkey()) txn.add( sys.create_account( sys.CreateAccountParams( - from_pubkey=payer.public_key, - new_account_pubkey=destination_stake.public_key, + from_pubkey=payer.pubkey(), + to_pubkey=destination_stake.pubkey(), lamports=stake_rent_exemption, space=STAKE_LEN, - program_id=STAKE_PROGRAM_ID, + owner=STAKE_PROGRAM_ID, ) ) ) @@ -372,13 +375,13 @@ async def withdraw_stake( validator_list=stake_pool.validator_list, withdraw_authority=withdraw_authority, validator_stake=validator_stake, - destination_stake=destination_stake.public_key, + destination_stake=destination_stake.pubkey(), destination_stake_authority=destination_stake_authority, - source_transfer_authority=source_transfer_authority.public_key, + source_transfer_authority=source_transfer_authority.pubkey(), source_pool_account=source_pool_account, manager_fee_account=stake_pool.manager_fee_account, pool_mint=stake_pool.pool_mint, - clock_sysvar=SYSVAR_CLOCK_PUBKEY, + clock_sysvar=CLOCK, token_program_id=stake_pool.token_program_id, stake_program_id=STAKE_PROGRAM_ID, amount=amount, @@ -387,18 +390,18 @@ async def withdraw_stake( ) signers = [payer, source_transfer_authority, destination_stake] \ if payer != source_transfer_authority else [payer, destination_stake] - await client.send_transaction( - txn, *signers, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash + await client.send_transaction(txn, *signers, recent_blockhash=recent_blockhash, opts=OPTS) -async def update_stake_pool(client: AsyncClient, payer: Keypair, stake_pool_address: PublicKey): +async def update_stake_pool(client: AsyncClient, payer: Keypair, stake_pool_address: Pubkey): """Create and send all instructions to completely update a stake pool after epoch change.""" resp = await client.get_account_info(stake_pool_address, commitment=Confirmed) - data = resp['result']['value']['data'] - stake_pool = StakePool.decode(data[0], data[1]) + data = resp.value.data if resp.value else bytes() + stake_pool = StakePool.decode(data) resp = await client.get_account_info(stake_pool.validator_list, commitment=Confirmed) - data = resp['result']['value']['data'] - validator_list = ValidatorList.decode(data[0], data[1]) + data = resp.value.data if resp.value else bytes() + validator_list = ValidatorList.decode(data) (withdraw_authority, seed) = find_withdraw_authority_program_address(STAKE_POOL_PROGRAM_ID, stake_pool_address) update_list_instructions = [] validator_chunks = [ @@ -431,8 +434,8 @@ async def update_stake_pool(client: AsyncClient, payer: Keypair, stake_pool_addr withdraw_authority=withdraw_authority, validator_list=stake_pool.validator_list, reserve_stake=stake_pool.reserve_stake, - clock_sysvar=SYSVAR_CLOCK_PUBKEY, - stake_history_sysvar=SYSVAR_STAKE_HISTORY_PUBKEY, + clock_sysvar=CLOCK, + stake_history_sysvar=STAKE_HISTORY, stake_program_id=STAKE_PROGRAM_ID, validator_and_transient_stake_pairs=validator_and_transient_stake_pairs, start_index=start_index, @@ -444,15 +447,16 @@ async def update_stake_pool(client: AsyncClient, payer: Keypair, stake_pool_addr if update_list_instructions: last_instruction = update_list_instructions.pop() for update_list_instruction in update_list_instructions: - txn = Transaction() + txn = Transaction(fee_payer=payer.pubkey()) txn.add(update_list_instruction) - await client.send_transaction( - txn, payer, opts=TxOpts(skip_confirmation=True, preflight_commitment=Confirmed)) - txn = Transaction() + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash + await client.send_transaction(txn, payer, recent_blockhash=recent_blockhash, + opts=TxOpts(skip_confirmation=True, preflight_commitment=Confirmed)) + txn = Transaction(fee_payer=payer.pubkey()) txn.add(last_instruction) - await client.send_transaction( - txn, payer, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) - txn = Transaction() + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash + await client.send_transaction(txn, payer, recent_blockhash=recent_blockhash, opts=OPTS) + txn = Transaction(fee_payer=payer.pubkey()) txn.add( sp.update_stake_pool_balance( sp.UpdateStakePoolBalanceParams( @@ -476,26 +480,26 @@ async def update_stake_pool(client: AsyncClient, payer: Keypair, stake_pool_addr ) ) ) - await client.send_transaction( - txn, payer, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash + await client.send_transaction(txn, payer, recent_blockhash=recent_blockhash, opts=OPTS) async def increase_validator_stake( client: AsyncClient, payer: Keypair, staker: Keypair, - stake_pool_address: PublicKey, - validator_vote: PublicKey, + stake_pool_address: Pubkey, + validator_vote: Pubkey, lamports: int, ephemeral_stake_seed: Optional[int] = None ): resp = await client.get_account_info(stake_pool_address, commitment=Confirmed) - data = resp['result']['value']['data'] - stake_pool = StakePool.decode(data[0], data[1]) + data = resp.value.data if resp.value else bytes() + stake_pool = StakePool.decode(data) resp = await client.get_account_info(stake_pool.validator_list, commitment=Confirmed) - data = resp['result']['value']['data'] - validator_list = ValidatorList.decode(data[0], data[1]) + data = resp.value.data if resp.value else bytes() + validator_list = ValidatorList.decode(data) (withdraw_authority, seed) = find_withdraw_authority_program_address(STAKE_POOL_PROGRAM_ID, stake_pool_address) validator_info = next(x for x in validator_list.validators if x.vote_account_address == validator_vote) @@ -520,7 +524,7 @@ async def increase_validator_stake( validator_stake_seed ) - txn = Transaction() + txn = Transaction(fee_payer=payer.pubkey()) if ephemeral_stake_seed is not None: # We assume there is an existing transient account that we will update @@ -534,18 +538,18 @@ async def increase_validator_stake( sp.IncreaseAdditionalValidatorStakeParams( program_id=STAKE_POOL_PROGRAM_ID, stake_pool=stake_pool_address, - staker=staker.public_key, + staker=staker.pubkey(), withdraw_authority=withdraw_authority, validator_list=stake_pool.validator_list, reserve_stake=stake_pool.reserve_stake, transient_stake=transient_stake, validator_stake=validator_stake, validator_vote=validator_vote, - clock_sysvar=SYSVAR_CLOCK_PUBKEY, - rent_sysvar=SYSVAR_RENT_PUBKEY, - stake_history_sysvar=SYSVAR_STAKE_HISTORY_PUBKEY, + clock_sysvar=CLOCK, + rent_sysvar=RENT, + stake_history_sysvar=STAKE_HISTORY, stake_config_sysvar=SYSVAR_STAKE_CONFIG_ID, - system_program_id=sys.SYS_PROGRAM_ID, + system_program_id=sys.ID, stake_program_id=STAKE_PROGRAM_ID, lamports=lamports, transient_stake_seed=transient_stake_seed, @@ -561,18 +565,18 @@ async def increase_validator_stake( sp.IncreaseValidatorStakeParams( program_id=STAKE_POOL_PROGRAM_ID, stake_pool=stake_pool_address, - staker=staker.public_key, + staker=staker.pubkey(), withdraw_authority=withdraw_authority, validator_list=stake_pool.validator_list, reserve_stake=stake_pool.reserve_stake, transient_stake=transient_stake, validator_stake=validator_stake, validator_vote=validator_vote, - clock_sysvar=SYSVAR_CLOCK_PUBKEY, - rent_sysvar=SYSVAR_RENT_PUBKEY, - stake_history_sysvar=SYSVAR_STAKE_HISTORY_PUBKEY, + clock_sysvar=CLOCK, + rent_sysvar=RENT, + stake_history_sysvar=STAKE_HISTORY, stake_config_sysvar=SYSVAR_STAKE_CONFIG_ID, - system_program_id=sys.SYS_PROGRAM_ID, + system_program_id=sys.ID, stake_program_id=STAKE_PROGRAM_ID, lamports=lamports, transient_stake_seed=transient_stake_seed, @@ -581,26 +585,26 @@ async def increase_validator_stake( ) signers = [payer, staker] if payer != staker else [payer] - await client.send_transaction( - txn, *signers, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash + await client.send_transaction(txn, *signers, recent_blockhash=recent_blockhash, opts=OPTS) async def decrease_validator_stake( client: AsyncClient, payer: Keypair, staker: Keypair, - stake_pool_address: PublicKey, - validator_vote: PublicKey, + stake_pool_address: Pubkey, + validator_vote: Pubkey, lamports: int, ephemeral_stake_seed: Optional[int] = None ): resp = await client.get_account_info(stake_pool_address, commitment=Confirmed) - data = resp['result']['value']['data'] - stake_pool = StakePool.decode(data[0], data[1]) + data = resp.value.data if resp.value else bytes() + stake_pool = StakePool.decode(data) resp = await client.get_account_info(stake_pool.validator_list, commitment=Confirmed) - data = resp['result']['value']['data'] - validator_list = ValidatorList.decode(data[0], data[1]) + data = resp.value.data if resp.value else bytes() + validator_list = ValidatorList.decode(data) (withdraw_authority, seed) = find_withdraw_authority_program_address(STAKE_POOL_PROGRAM_ID, stake_pool_address) validator_info = next(x for x in validator_list.validators if x.vote_account_address == validator_vote) @@ -625,7 +629,7 @@ async def decrease_validator_stake( transient_stake_seed, ) - txn = Transaction() + txn = Transaction(fee_payer=payer.pubkey()) if ephemeral_stake_seed is not None: @@ -640,16 +644,16 @@ async def decrease_validator_stake( sp.DecreaseAdditionalValidatorStakeParams( program_id=STAKE_POOL_PROGRAM_ID, stake_pool=stake_pool_address, - staker=staker.public_key, + staker=staker.pubkey(), withdraw_authority=withdraw_authority, validator_list=stake_pool.validator_list, reserve_stake=stake_pool.reserve_stake, validator_stake=validator_stake, transient_stake=transient_stake, - clock_sysvar=SYSVAR_CLOCK_PUBKEY, - rent_sysvar=SYSVAR_RENT_PUBKEY, - stake_history_sysvar=SYSVAR_STAKE_HISTORY_PUBKEY, - system_program_id=sys.SYS_PROGRAM_ID, + clock_sysvar=CLOCK, + rent_sysvar=RENT, + stake_history_sysvar=STAKE_HISTORY, + system_program_id=sys.ID, stake_program_id=STAKE_PROGRAM_ID, lamports=lamports, transient_stake_seed=transient_stake_seed, @@ -666,15 +670,15 @@ async def decrease_validator_stake( sp.DecreaseValidatorStakeWithReserveParams( program_id=STAKE_POOL_PROGRAM_ID, stake_pool=stake_pool_address, - staker=staker.public_key, + staker=staker.pubkey(), withdraw_authority=withdraw_authority, validator_list=stake_pool.validator_list, reserve_stake=stake_pool.reserve_stake, validator_stake=validator_stake, transient_stake=transient_stake, - clock_sysvar=SYSVAR_CLOCK_PUBKEY, - stake_history_sysvar=SYSVAR_STAKE_HISTORY_PUBKEY, - system_program_id=sys.SYS_PROGRAM_ID, + clock_sysvar=CLOCK, + stake_history_sysvar=STAKE_HISTORY, + system_program_id=sys.ID, stake_program_id=STAKE_PROGRAM_ID, lamports=lamports, transient_stake_seed=transient_stake_seed, @@ -683,20 +687,20 @@ async def decrease_validator_stake( ) signers = [payer, staker] if payer != staker else [payer] - await client.send_transaction( - txn, *signers, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash + await client.send_transaction(txn, *signers, recent_blockhash=recent_blockhash, opts=OPTS) -async def create_token_metadata(client: AsyncClient, payer: Keypair, stake_pool_address: PublicKey, +async def create_token_metadata(client: AsyncClient, payer: Keypair, stake_pool_address: Pubkey, name: str, symbol: str, uri: str): resp = await client.get_account_info(stake_pool_address, commitment=Confirmed) - data = resp['result']['value']['data'] - stake_pool = StakePool.decode(data[0], data[1]) + data = resp.value.data if resp.value else bytes() + stake_pool = StakePool.decode(data) (withdraw_authority, _seed) = find_withdraw_authority_program_address(STAKE_POOL_PROGRAM_ID, stake_pool_address) (token_metadata, _seed) = find_metadata_account(stake_pool.pool_mint) - txn = Transaction() + txn = Transaction(fee_payer=payer.pubkey()) txn.add( sp.create_token_metadata( sp.CreateTokenMetadataParams( @@ -704,31 +708,31 @@ async def create_token_metadata(client: AsyncClient, payer: Keypair, stake_pool_ stake_pool=stake_pool_address, manager=stake_pool.manager, pool_mint=stake_pool.pool_mint, - payer=payer.public_key, + payer=payer.pubkey(), name=name, symbol=symbol, uri=uri, withdraw_authority=withdraw_authority, token_metadata=token_metadata, metadata_program_id=METADATA_PROGRAM_ID, - system_program_id=sys.SYS_PROGRAM_ID, + system_program_id=sys.ID, ) ) ) + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash + await client.send_transaction(txn, payer, recent_blockhash=recent_blockhash, opts=OPTS) - await client.send_transaction(txn, payer, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) - -async def update_token_metadata(client: AsyncClient, payer: Keypair, stake_pool_address: PublicKey, +async def update_token_metadata(client: AsyncClient, payer: Keypair, stake_pool_address: Pubkey, name: str, symbol: str, uri: str): resp = await client.get_account_info(stake_pool_address, commitment=Confirmed) - data = resp['result']['value']['data'] - stake_pool = StakePool.decode(data[0], data[1]) + data = resp.value.data if resp.value else bytes() + stake_pool = StakePool.decode(data) (withdraw_authority, _seed) = find_withdraw_authority_program_address(STAKE_POOL_PROGRAM_ID, stake_pool_address) (token_metadata, _seed) = find_metadata_account(stake_pool.pool_mint) - txn = Transaction() + txn = Transaction(fee_payer=payer.pubkey()) txn.add( sp.update_token_metadata( sp.UpdateTokenMetadataParams( @@ -745,5 +749,5 @@ async def update_token_metadata(client: AsyncClient, payer: Keypair, stake_pool_ ) ) ) - - await client.send_transaction(txn, payer, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash + await client.send_transaction(txn, payer, recent_blockhash=recent_blockhash, opts=OPTS) diff --git a/clients/py/stake_pool/constants.py b/clients/py/stake_pool/constants.py index ff1f1dbe..8a09dfbb 100644 --- a/clients/py/stake_pool/constants.py +++ b/clients/py/stake_pool/constants.py @@ -2,10 +2,10 @@ from typing import Optional, Tuple -from solana.publickey import PublicKey +from solders.pubkey import Pubkey from stake.constants import MINIMUM_DELEGATION -STAKE_POOL_PROGRAM_ID: PublicKey = PublicKey("SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy") +STAKE_POOL_PROGRAM_ID = Pubkey.from_string("SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy") """Public key that identifies the SPL Stake Pool program.""" MAX_VALIDATORS_TO_UPDATE: int = 5 @@ -17,40 +17,40 @@ MINIMUM_ACTIVE_STAKE: int = MINIMUM_DELEGATION """Minimum active delegated staked required in a stake account""" -METADATA_PROGRAM_ID: PublicKey = PublicKey("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s") +METADATA_PROGRAM_ID = Pubkey.from_string("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s") """Public key that identifies the Metaplex Token Metadata program.""" def find_deposit_authority_program_address( - program_id: PublicKey, - stake_pool_address: PublicKey, -) -> Tuple[PublicKey, int]: + program_id: Pubkey, + stake_pool_address: Pubkey, +) -> Tuple[Pubkey, int]: """Generates the deposit authority program address for the stake pool""" - return PublicKey.find_program_address( + return Pubkey.find_program_address( [bytes(stake_pool_address), AUTHORITY_DEPOSIT], program_id, ) def find_withdraw_authority_program_address( - program_id: PublicKey, - stake_pool_address: PublicKey, -) -> Tuple[PublicKey, int]: + program_id: Pubkey, + stake_pool_address: Pubkey, +) -> Tuple[Pubkey, int]: """Generates the withdraw authority program address for the stake pool""" - return PublicKey.find_program_address( + return Pubkey.find_program_address( [bytes(stake_pool_address), AUTHORITY_WITHDRAW], program_id, ) def find_stake_program_address( - program_id: PublicKey, - vote_account_address: PublicKey, - stake_pool_address: PublicKey, + program_id: Pubkey, + vote_account_address: Pubkey, + stake_pool_address: Pubkey, seed: Optional[int] -) -> Tuple[PublicKey, int]: +) -> Tuple[Pubkey, int]: """Generates the stake program address for a validator's vote account""" - return PublicKey.find_program_address( + return Pubkey.find_program_address( [ bytes(vote_account_address), bytes(stake_pool_address), @@ -61,13 +61,13 @@ def find_stake_program_address( def find_transient_stake_program_address( - program_id: PublicKey, - vote_account_address: PublicKey, - stake_pool_address: PublicKey, + program_id: Pubkey, + vote_account_address: Pubkey, + stake_pool_address: Pubkey, seed: int, -) -> Tuple[PublicKey, int]: +) -> Tuple[Pubkey, int]: """Generates the stake program address for a validator's vote account""" - return PublicKey.find_program_address( + return Pubkey.find_program_address( [ TRANSIENT_STAKE_SEED_PREFIX, bytes(vote_account_address), @@ -79,13 +79,13 @@ def find_transient_stake_program_address( def find_ephemeral_stake_program_address( - program_id: PublicKey, - stake_pool_address: PublicKey, + program_id: Pubkey, + stake_pool_address: Pubkey, seed: int -) -> Tuple[PublicKey, int]: +) -> Tuple[Pubkey, int]: """Generates the ephemeral program address for stake pool redelegation""" - return PublicKey.find_program_address( + return Pubkey.find_program_address( [ EPHEMERAL_STAKE_SEED_PREFIX, bytes(stake_pool_address), @@ -96,10 +96,10 @@ def find_ephemeral_stake_program_address( def find_metadata_account( - mint_key: PublicKey -) -> Tuple[PublicKey, int]: + mint_key: Pubkey +) -> Tuple[Pubkey, int]: """Generates the metadata account program address""" - return PublicKey.find_program_address( + return Pubkey.find_program_address( [ METADATA_SEED_PREFIX, bytes(METADATA_PROGRAM_ID), diff --git a/clients/py/stake_pool/instructions.py b/clients/py/stake_pool/instructions.py index 8a3ae4cf..e5d9199c 100644 --- a/clients/py/stake_pool/instructions.py +++ b/clients/py/stake_pool/instructions.py @@ -4,10 +4,10 @@ from typing import List, NamedTuple, Optional from construct import Prefixed, GreedyString, Struct, Switch, Int8ul, Int32ul, Int64ul, Pass # type: ignore -from solana.publickey import PublicKey -from solana.transaction import AccountMeta, TransactionInstruction -from solana.system_program import SYS_PROGRAM_ID -from solana.sysvar import SYSVAR_CLOCK_PUBKEY, SYSVAR_RENT_PUBKEY, SYSVAR_STAKE_HISTORY_PUBKEY +from solana.constants import SYSTEM_PROGRAM_ID +from solders.pubkey import Pubkey +from solders.instruction import AccountMeta, Instruction +from solders.sysvar import CLOCK, RENT, STAKE_HISTORY from spl.token.constants import TOKEN_PROGRAM_ID from stake.constants import STAKE_PROGRAM_ID, SYSVAR_STAKE_CONFIG_ID @@ -41,25 +41,25 @@ class InitializeParams(NamedTuple): """Initialize token mint transaction params.""" # Accounts - program_id: PublicKey + program_id: Pubkey """SPL Stake Pool program account.""" - stake_pool: PublicKey + stake_pool: Pubkey """[w] Stake Pool account to initialize.""" - manager: PublicKey + manager: Pubkey """[s] Manager for new stake pool.""" - staker: PublicKey + staker: Pubkey """[] Staker for the new stake pool.""" - withdraw_authority: PublicKey + withdraw_authority: Pubkey """[] Withdraw authority for the new stake pool.""" - validator_list: PublicKey + validator_list: Pubkey """[w] Uninitialized validator list account for the new stake pool.""" - reserve_stake: PublicKey + reserve_stake: Pubkey """[] Reserve stake account.""" - pool_mint: PublicKey + pool_mint: Pubkey """[w] Pool token mint account.""" - manager_fee_account: PublicKey + manager_fee_account: Pubkey """[w] Manager's fee account""" - token_program_id: PublicKey + token_program_id: Pubkey """[] SPL Token program id.""" # Params @@ -75,40 +75,40 @@ class InitializeParams(NamedTuple): """Maximum number of possible validators in the pool.""" # Optional - deposit_authority: Optional[PublicKey] = None + deposit_authority: Optional[Pubkey] = None """[] Optional deposit authority that must sign all deposits.""" class AddValidatorToPoolParams(NamedTuple): """(Staker only) Adds stake account delegated to validator to the pool's list of managed validators.""" - program_id: PublicKey + program_id: Pubkey """SPL Stake Pool program account.""" - stake_pool: PublicKey + stake_pool: Pubkey """`[w]` Stake pool.""" - staker: PublicKey + staker: Pubkey """`[s]` Staker.""" - reserve_stake: PublicKey + reserve_stake: Pubkey """`[w]` Reserve stake account.""" - withdraw_authority: PublicKey + withdraw_authority: Pubkey """`[]` Stake pool withdraw authority.""" - validator_list: PublicKey + validator_list: Pubkey """`[w]` Validator stake list storage account.""" - validator_stake: PublicKey + validator_stake: Pubkey """`[w]` Stake account to add to the pool.""" - validator_vote: PublicKey + validator_vote: Pubkey """`[]` Validator this stake account will be delegated to.""" - rent_sysvar: PublicKey + rent_sysvar: Pubkey """`[]` Rent sysvar.""" - clock_sysvar: PublicKey + clock_sysvar: Pubkey """`[]` Clock sysvar.""" - stake_history_sysvar: PublicKey + stake_history_sysvar: Pubkey """'[]' Stake history sysvar.""" - stake_config_sysvar: PublicKey + stake_config_sysvar: Pubkey """'[]' Stake config sysvar.""" - system_program_id: PublicKey + system_program_id: Pubkey """`[]` System program.""" - stake_program_id: PublicKey + stake_program_id: Pubkey """`[]` Stake program.""" # Params @@ -119,23 +119,23 @@ class AddValidatorToPoolParams(NamedTuple): class RemoveValidatorFromPoolParams(NamedTuple): """(Staker only) Removes validator from the pool.""" - program_id: PublicKey + program_id: Pubkey """SPL Stake Pool program account.""" - stake_pool: PublicKey + stake_pool: Pubkey """`[w]` Stake pool.""" - staker: PublicKey + staker: Pubkey """`[s]` Staker.""" - withdraw_authority: PublicKey + withdraw_authority: Pubkey """`[]` Stake pool withdraw authority.""" - validator_list: PublicKey + validator_list: Pubkey """`[w]` Validator stake list storage account.""" - validator_stake: PublicKey + validator_stake: Pubkey """`[w]` Stake account to remove from the pool.""" - transient_stake: PublicKey + transient_stake: Pubkey """`[]` Transient stake account, to check that there's no activation ongoing.""" - clock_sysvar: PublicKey + clock_sysvar: Pubkey """'[]' Stake config sysvar.""" - stake_program_id: PublicKey + stake_program_id: Pubkey """`[]` Stake program.""" @@ -143,27 +143,27 @@ class DecreaseValidatorStakeParams(NamedTuple): """(Staker only) Decrease active stake on a validator, eventually moving it to the reserve""" # Accounts - program_id: PublicKey + program_id: Pubkey """SPL Stake Pool program account.""" - stake_pool: PublicKey + stake_pool: Pubkey """`[]` Stake pool.""" - staker: PublicKey + staker: Pubkey """`[s]` Staker.""" - withdraw_authority: PublicKey + withdraw_authority: Pubkey """`[]` Stake pool withdraw authority.""" - validator_list: PublicKey + validator_list: Pubkey """`[w]` Validator stake list storage account.""" - validator_stake: PublicKey + validator_stake: Pubkey """`[w]` Canonical stake to split from.""" - transient_stake: PublicKey + transient_stake: Pubkey """`[w]` Transient stake account to receive split.""" - clock_sysvar: PublicKey + clock_sysvar: Pubkey """`[]` Clock sysvar.""" - rent_sysvar: PublicKey + rent_sysvar: Pubkey """`[]` Rent sysvar.""" - system_program_id: PublicKey + system_program_id: Pubkey """`[]` System program.""" - stake_program_id: PublicKey + stake_program_id: Pubkey """`[]` Stake program.""" # Params @@ -177,29 +177,29 @@ class DecreaseValidatorStakeWithReserveParams(NamedTuple): """(Staker only) Decrease active stake on a validator, eventually moving it to the reserve""" # Accounts - program_id: PublicKey + program_id: Pubkey """SPL Stake Pool program account.""" - stake_pool: PublicKey + stake_pool: Pubkey """`[]` Stake pool.""" - staker: PublicKey + staker: Pubkey """`[s]` Staker.""" - withdraw_authority: PublicKey + withdraw_authority: Pubkey """`[]` Stake pool withdraw authority.""" - validator_list: PublicKey + validator_list: Pubkey """`[w]` Validator stake list storage account.""" - reserve_stake: PublicKey + reserve_stake: Pubkey """`[w]` Stake pool's reserve.""" - validator_stake: PublicKey + validator_stake: Pubkey """`[w]` Canonical stake to split from.""" - transient_stake: PublicKey + transient_stake: Pubkey """`[w]` Transient stake account to receive split.""" - clock_sysvar: PublicKey + clock_sysvar: Pubkey """`[]` Clock sysvar.""" - stake_history_sysvar: PublicKey + stake_history_sysvar: Pubkey """'[]' Stake history sysvar.""" - system_program_id: PublicKey + system_program_id: Pubkey """`[]` System program.""" - stake_program_id: PublicKey + stake_program_id: Pubkey """`[]` Stake program.""" # Params @@ -213,35 +213,35 @@ class IncreaseValidatorStakeParams(NamedTuple): """(Staker only) Increase stake on a validator from the reserve account.""" # Accounts - program_id: PublicKey + program_id: Pubkey """SPL Stake Pool program account.""" - stake_pool: PublicKey + stake_pool: Pubkey """`[]` Stake pool.""" - staker: PublicKey + staker: Pubkey """`[s]` Staker.""" - withdraw_authority: PublicKey + withdraw_authority: Pubkey """`[]` Stake pool withdraw authority.""" - validator_list: PublicKey + validator_list: Pubkey """`[w]` Validator stake list storage account.""" - reserve_stake: PublicKey + reserve_stake: Pubkey """`[w]` Stake pool's reserve.""" - transient_stake: PublicKey + transient_stake: Pubkey """`[w]` Transient stake account to receive split.""" - validator_stake: PublicKey + validator_stake: Pubkey """`[]` Canonical stake account to check.""" - validator_vote: PublicKey + validator_vote: Pubkey """`[]` Validator vote account to delegate to.""" - clock_sysvar: PublicKey + clock_sysvar: Pubkey """`[]` Clock sysvar.""" - rent_sysvar: PublicKey + rent_sysvar: Pubkey """`[]` Rent sysvar.""" - stake_history_sysvar: PublicKey + stake_history_sysvar: Pubkey """'[]' Stake history sysvar.""" - stake_config_sysvar: PublicKey + stake_config_sysvar: Pubkey """'[]' Stake config sysvar.""" - system_program_id: PublicKey + system_program_id: Pubkey """`[]` System program.""" - stake_program_id: PublicKey + stake_program_id: Pubkey """`[]` Stake program.""" # Params @@ -259,23 +259,23 @@ class UpdateValidatorListBalanceParams(NamedTuple): """Updates balances of validator and transient stake accounts in the pool.""" # Accounts - program_id: PublicKey + program_id: Pubkey """SPL Stake Pool program account.""" - stake_pool: PublicKey + stake_pool: Pubkey """`[]` Stake pool.""" - withdraw_authority: PublicKey + withdraw_authority: Pubkey """`[]` Stake pool withdraw authority.""" - validator_list: PublicKey + validator_list: Pubkey """`[w]` Validator stake list storage account.""" - reserve_stake: PublicKey + reserve_stake: Pubkey """`[w]` Stake pool's reserve.""" - clock_sysvar: PublicKey + clock_sysvar: Pubkey """`[]` Clock sysvar.""" - stake_history_sysvar: PublicKey + stake_history_sysvar: Pubkey """'[]' Stake history sysvar.""" - stake_program_id: PublicKey + stake_program_id: Pubkey """`[]` Stake program.""" - validator_and_transient_stake_pairs: List[PublicKey] + validator_and_transient_stake_pairs: List[Pubkey] """[] N pairs of validator and transient stake accounts""" # Params @@ -288,102 +288,102 @@ class UpdateValidatorListBalanceParams(NamedTuple): class UpdateStakePoolBalanceParams(NamedTuple): """Updates total pool balance based on balances in the reserve and validator list.""" - program_id: PublicKey + program_id: Pubkey """SPL Stake Pool program account.""" - stake_pool: PublicKey + stake_pool: Pubkey """`[w]` Stake pool.""" - withdraw_authority: PublicKey + withdraw_authority: Pubkey """`[]` Stake pool withdraw authority.""" - validator_list: PublicKey + validator_list: Pubkey """`[w]` Validator stake list storage account.""" - reserve_stake: PublicKey + reserve_stake: Pubkey """`[w]` Stake pool's reserve.""" - manager_fee_account: PublicKey + manager_fee_account: Pubkey """`[w]` Account to receive pool fee tokens.""" - pool_mint: PublicKey + pool_mint: Pubkey """`[w]` Pool mint account.""" - token_program_id: PublicKey + token_program_id: Pubkey """`[]` Pool token program.""" class CleanupRemovedValidatorEntriesParams(NamedTuple): """Cleans up validator stake account entries marked as `ReadyForRemoval`""" - program_id: PublicKey + program_id: Pubkey """SPL Stake Pool program account.""" - stake_pool: PublicKey + stake_pool: Pubkey """`[w]` Stake pool.""" - validator_list: PublicKey + validator_list: Pubkey """`[w]` Validator stake list storage account.""" class DepositStakeParams(NamedTuple): """Deposits a stake account into the pool in exchange for pool tokens""" - program_id: PublicKey + program_id: Pubkey """SPL Stake Pool program account.""" - stake_pool: PublicKey + stake_pool: Pubkey """`[w]` Stake pool""" - validator_list: PublicKey + validator_list: Pubkey """`[w]` Validator stake list storage account""" - deposit_authority: PublicKey + deposit_authority: Pubkey """`[s]/[]` Stake pool deposit authority""" - withdraw_authority: PublicKey + withdraw_authority: Pubkey """`[]` Stake pool withdraw authority""" - deposit_stake: PublicKey + deposit_stake: Pubkey """`[w]` Stake account to join the pool (stake's withdraw authority set to the stake pool deposit authority)""" - validator_stake: PublicKey + validator_stake: Pubkey """`[w]` Validator stake account for the stake account to be merged with""" - reserve_stake: PublicKey + reserve_stake: Pubkey """`[w]` Reserve stake account, to withdraw rent exempt reserve""" - destination_pool_account: PublicKey + destination_pool_account: Pubkey """`[w]` User account to receive pool tokens""" - manager_fee_account: PublicKey + manager_fee_account: Pubkey """`[w]` Account to receive pool fee tokens""" - referral_pool_account: PublicKey + referral_pool_account: Pubkey """`[w]` Account to receive a portion of pool fee tokens as referral fees""" - pool_mint: PublicKey + pool_mint: Pubkey """`[w]` Pool token mint account""" - clock_sysvar: PublicKey + clock_sysvar: Pubkey """`[]` Sysvar clock account""" - stake_history_sysvar: PublicKey + stake_history_sysvar: Pubkey """`[]` Sysvar stake history account""" - token_program_id: PublicKey + token_program_id: Pubkey """`[]` Pool token program id""" - stake_program_id: PublicKey + stake_program_id: Pubkey """`[]` Stake program id""" class WithdrawStakeParams(NamedTuple): """Withdraws a stake account from the pool in exchange for pool tokens""" - program_id: PublicKey + program_id: Pubkey """SPL Stake Pool program account.""" - stake_pool: PublicKey + stake_pool: Pubkey """`[w]` Stake pool""" - validator_list: PublicKey + validator_list: Pubkey """`[w]` Validator stake list storage account""" - withdraw_authority: PublicKey + withdraw_authority: Pubkey """`[]` Stake pool withdraw authority""" - validator_stake: PublicKey + validator_stake: Pubkey """`[w]` Validator or reserve stake account to split""" - destination_stake: PublicKey + destination_stake: Pubkey """`[w]` Unitialized stake account to receive withdrawal""" - destination_stake_authority: PublicKey + destination_stake_authority: Pubkey """`[]` User account to set as a new withdraw authority""" - source_transfer_authority: PublicKey + source_transfer_authority: Pubkey """`[s]` User transfer authority, for pool token account""" - source_pool_account: PublicKey + source_pool_account: Pubkey """`[w]` User account with pool tokens to burn from""" - manager_fee_account: PublicKey + manager_fee_account: Pubkey """`[w]` Account to receive pool fee tokens""" - pool_mint: PublicKey + pool_mint: Pubkey """`[w]` Pool token mint account""" - clock_sysvar: PublicKey + clock_sysvar: Pubkey """`[]` Sysvar clock account""" - token_program_id: PublicKey + token_program_id: Pubkey """`[]` Pool token program id""" - stake_program_id: PublicKey + stake_program_id: Pubkey """`[]` Stake program id""" # Params @@ -408,27 +408,27 @@ class DepositSolParams(NamedTuple): representing ownership into the pool. Inputs are converted to the current ratio.""" # Accounts - program_id: PublicKey + program_id: Pubkey """SPL Stake Pool program account.""" - stake_pool: PublicKey + stake_pool: Pubkey """`[w]` Stake pool.""" - withdraw_authority: PublicKey + withdraw_authority: Pubkey """`[]` Stake pool withdraw authority.""" - reserve_stake: PublicKey + reserve_stake: Pubkey """`[w]` Stake pool's reserve.""" - funding_account: PublicKey + funding_account: Pubkey """`[ws]` Funding account (must be a system account).""" - destination_pool_account: PublicKey + destination_pool_account: Pubkey """`[w]` User account to receive pool tokens.""" - manager_fee_account: PublicKey + manager_fee_account: Pubkey """`[w]` Manager's pool token account to receive deposit fee.""" - referral_pool_account: PublicKey + referral_pool_account: Pubkey """`[w]` Referrer pool token account to receive referral fee.""" - pool_mint: PublicKey + pool_mint: Pubkey """`[w]` Pool token mint.""" - system_program_id: PublicKey + system_program_id: Pubkey """`[]` System program.""" - token_program_id: PublicKey + token_program_id: Pubkey """`[]` Token program.""" # Params @@ -436,7 +436,7 @@ class DepositSolParams(NamedTuple): """Amount of SOL to deposit""" # Optional - deposit_authority: Optional[PublicKey] = None + deposit_authority: Optional[Pubkey] = None """`[s]` (Optional) Stake pool sol deposit authority.""" @@ -448,31 +448,31 @@ class WithdrawSolParams(NamedTuple): """Withdraw SOL directly from the pool's reserve account.""" # Accounts - program_id: PublicKey + program_id: Pubkey """SPL Stake Pool program account.""" - stake_pool: PublicKey + stake_pool: Pubkey """`[w]` Stake pool.""" - withdraw_authority: PublicKey + withdraw_authority: Pubkey """`[]` Stake pool withdraw authority.""" - source_transfer_authority: PublicKey + source_transfer_authority: Pubkey """`[s]` Transfer authority for user pool token account.""" - source_pool_account: PublicKey + source_pool_account: Pubkey """`[w]` User's pool token account to burn pool tokens.""" - reserve_stake: PublicKey + reserve_stake: Pubkey """`[w]` Stake pool's reserve.""" - destination_system_account: PublicKey + destination_system_account: Pubkey """`[w]` Destination system account to receive lamports from the reserve.""" - manager_fee_account: PublicKey + manager_fee_account: Pubkey """`[w]` Manager's pool token account to receive fee.""" - pool_mint: PublicKey + pool_mint: Pubkey """`[w]` Pool token mint.""" - clock_sysvar: PublicKey + clock_sysvar: Pubkey """`[]` Clock sysvar.""" - stake_history_sysvar: PublicKey + stake_history_sysvar: Pubkey """'[]' Stake history sysvar.""" - stake_program_id: PublicKey + stake_program_id: Pubkey """`[]` Stake program.""" - token_program_id: PublicKey + token_program_id: Pubkey """`[]` Token program.""" # Params @@ -480,7 +480,7 @@ class WithdrawSolParams(NamedTuple): """Amount of pool tokens to burn""" # Optional - sol_withdraw_authority: Optional[PublicKey] = None + sol_withdraw_authority: Optional[Pubkey] = None """`[s]` (Optional) Stake pool sol withdraw authority.""" @@ -488,23 +488,23 @@ class CreateTokenMetadataParams(NamedTuple): """Create token metadata for the stake-pool token in the metaplex-token program.""" # Accounts - program_id: PublicKey + program_id: Pubkey """SPL Stake Pool program account.""" - stake_pool: PublicKey + stake_pool: Pubkey """`[]` Stake pool.""" - manager: PublicKey + manager: Pubkey """`[s]` Manager.""" - withdraw_authority: PublicKey + withdraw_authority: Pubkey """`[]` Stake pool withdraw authority.""" - pool_mint: PublicKey + pool_mint: Pubkey """`[]` Pool token mint account.""" - payer: PublicKey + payer: Pubkey """`[s, w]` Payer for creation of token metadata account.""" - token_metadata: PublicKey + token_metadata: Pubkey """`[w]` Token metadata program account.""" - metadata_program_id: PublicKey + metadata_program_id: Pubkey """`[]` Metadata program id""" - system_program_id: PublicKey + system_program_id: Pubkey """`[]` System program id""" # Params @@ -519,19 +519,19 @@ class CreateTokenMetadataParams(NamedTuple): class UpdateTokenMetadataParams(NamedTuple): """Update token metadata for the stake-pool token in the metaplex-token program.""" # Accounts - program_id: PublicKey + program_id: Pubkey """SPL Stake Pool program account.""" - stake_pool: PublicKey + stake_pool: Pubkey """`[]` Stake pool.""" - manager: PublicKey + manager: Pubkey """`[s]` Manager.""" - withdraw_authority: PublicKey + withdraw_authority: Pubkey """`[]` Stake pool withdraw authority.""" - pool_mint: PublicKey + pool_mint: Pubkey """`[]` Pool token mint account.""" - token_metadata: PublicKey + token_metadata: Pubkey """`[w]` Token metadata program account.""" - metadata_program_id: PublicKey + metadata_program_id: Pubkey """`[]` Metadata program id""" # Params @@ -547,37 +547,37 @@ class IncreaseAdditionalValidatorStakeParams(NamedTuple): """(Staker only) Increase stake on a validator from the reserve account.""" # Accounts - program_id: PublicKey + program_id: Pubkey """SPL Stake Pool program account.""" - stake_pool: PublicKey + stake_pool: Pubkey """`[]` Stake pool.""" - staker: PublicKey + staker: Pubkey """`[s]` Staker.""" - withdraw_authority: PublicKey + withdraw_authority: Pubkey """`[]` Stake pool withdraw authority.""" - validator_list: PublicKey + validator_list: Pubkey """`[w]` Validator stake list storage account.""" - reserve_stake: PublicKey + reserve_stake: Pubkey """`[w]` Stake pool's reserve.""" - ephemeral_stake: PublicKey + ephemeral_stake: Pubkey """The ephemeral stake account used during the operation.""" - transient_stake: PublicKey + transient_stake: Pubkey """`[w]` Transient stake account to receive split.""" - validator_stake: PublicKey + validator_stake: Pubkey """`[]` Canonical stake account to check.""" - validator_vote: PublicKey + validator_vote: Pubkey """`[]` Validator vote account to delegate to.""" - clock_sysvar: PublicKey + clock_sysvar: Pubkey """`[]` Clock sysvar.""" - rent_sysvar: PublicKey + rent_sysvar: Pubkey """`[]` Rent sysvar.""" - stake_history_sysvar: PublicKey + stake_history_sysvar: Pubkey """'[]' Stake history sysvar.""" - stake_config_sysvar: PublicKey + stake_config_sysvar: Pubkey """'[]' Stake config sysvar.""" - system_program_id: PublicKey + system_program_id: Pubkey """`[]` System program.""" - stake_program_id: PublicKey + stake_program_id: Pubkey """`[]` Stake program.""" # Params @@ -593,33 +593,33 @@ class DecreaseAdditionalValidatorStakeParams(NamedTuple): """(Staker only) Decrease active stake on a validator, eventually moving it to the reserve""" # Accounts - program_id: PublicKey + program_id: Pubkey """SPL Stake Pool program account.""" - stake_pool: PublicKey + stake_pool: Pubkey """`[]` Stake pool.""" - staker: PublicKey + staker: Pubkey """`[s]` Staker.""" - withdraw_authority: PublicKey + withdraw_authority: Pubkey """`[]` Stake pool withdraw authority.""" - validator_list: PublicKey + validator_list: Pubkey """`[w]` Validator stake list storage account.""" - reserve_stake: PublicKey + reserve_stake: Pubkey """The reserve stake account to move the stake to.""" - validator_stake: PublicKey + validator_stake: Pubkey """`[w]` Canonical stake to split from.""" - ephemeral_stake: PublicKey + ephemeral_stake: Pubkey """The ephemeral stake account used during the operation.""" - transient_stake: PublicKey + transient_stake: Pubkey """`[w]` Transient stake account to receive split.""" - clock_sysvar: PublicKey + clock_sysvar: Pubkey """`[]` Clock sysvar.""" - rent_sysvar: PublicKey + rent_sysvar: Pubkey """`[]` Rent sysvar.""" - stake_history_sysvar: PublicKey + stake_history_sysvar: Pubkey """'[]' Stake history sysvar.""" - system_program_id: PublicKey + system_program_id: Pubkey """`[]` System program.""" - stake_program_id: PublicKey + stake_program_id: Pubkey """`[]` Stake program.""" # Params @@ -730,7 +730,7 @@ class InstructionType(IntEnum): ) -def initialize(params: InitializeParams) -> TransactionInstruction: +def initialize(params: InitializeParams) -> Instruction: """Creates a transaction instruction to initialize a new stake pool.""" data = INSTRUCTIONS_LAYOUT.build( @@ -745,7 +745,7 @@ def initialize(params: InitializeParams) -> TransactionInstruction: ), ) ) - keys = [ + accounts = [ AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=True), AccountMeta(pubkey=params.manager, is_signer=True, is_writable=False), AccountMeta(pubkey=params.staker, is_signer=False, is_writable=False), @@ -757,20 +757,20 @@ def initialize(params: InitializeParams) -> TransactionInstruction: AccountMeta(pubkey=TOKEN_PROGRAM_ID, is_signer=False, is_writable=False), ] if params.deposit_authority: - keys.append( + accounts.append( AccountMeta(pubkey=params.deposit_authority, is_signer=True, is_writable=False), ) - return TransactionInstruction( - keys=keys, + return Instruction( + accounts=accounts, program_id=params.program_id, data=data, ) -def add_validator_to_pool(params: AddValidatorToPoolParams) -> TransactionInstruction: +def add_validator_to_pool(params: AddValidatorToPoolParams) -> Instruction: """Creates instruction to add a validator to the pool.""" - return TransactionInstruction( - keys=[ + return Instruction( + accounts=[ AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=True), AccountMeta(pubkey=params.staker, is_signer=True, is_writable=False), AccountMeta(pubkey=params.reserve_stake, is_signer=False, is_writable=True), @@ -796,14 +796,14 @@ def add_validator_to_pool(params: AddValidatorToPoolParams) -> TransactionInstru def add_validator_to_pool_with_vote( - program_id: PublicKey, - stake_pool: PublicKey, - staker: PublicKey, - validator_list: PublicKey, - reserve_stake: PublicKey, - validator: PublicKey, + program_id: Pubkey, + stake_pool: Pubkey, + staker: Pubkey, + validator_list: Pubkey, + reserve_stake: Pubkey, + validator: Pubkey, validator_stake_seed: Optional[int], -) -> TransactionInstruction: +) -> Instruction: """Creates instruction to add a validator based on their vote account address.""" (withdraw_authority, _seed) = find_withdraw_authority_program_address(program_id, stake_pool) (validator_stake, _seed) = find_stake_program_address(program_id, validator, stake_pool, validator_stake_seed) @@ -817,21 +817,21 @@ def add_validator_to_pool_with_vote( validator_list=validator_list, validator_stake=validator_stake, validator_vote=validator, - rent_sysvar=SYSVAR_RENT_PUBKEY, - clock_sysvar=SYSVAR_CLOCK_PUBKEY, - stake_history_sysvar=SYSVAR_STAKE_HISTORY_PUBKEY, + rent_sysvar=RENT, + clock_sysvar=CLOCK, + stake_history_sysvar=STAKE_HISTORY, stake_config_sysvar=SYSVAR_STAKE_CONFIG_ID, - system_program_id=SYS_PROGRAM_ID, + system_program_id=SYSTEM_PROGRAM_ID, stake_program_id=STAKE_PROGRAM_ID, seed=validator_stake_seed, ) ) -def remove_validator_from_pool(params: RemoveValidatorFromPoolParams) -> TransactionInstruction: +def remove_validator_from_pool(params: RemoveValidatorFromPoolParams) -> Instruction: """Creates instruction to remove a validator from the pool.""" - return TransactionInstruction( - keys=[ + return Instruction( + accounts=[ AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=True), AccountMeta(pubkey=params.staker, is_signer=True, is_writable=False), AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), @@ -852,14 +852,14 @@ def remove_validator_from_pool(params: RemoveValidatorFromPoolParams) -> Transac def remove_validator_from_pool_with_vote( - program_id: PublicKey, - stake_pool: PublicKey, - staker: PublicKey, - validator_list: PublicKey, - validator: PublicKey, + program_id: Pubkey, + stake_pool: Pubkey, + staker: Pubkey, + validator_list: Pubkey, + validator: Pubkey, validator_stake_seed: Optional[int], transient_stake_seed: int, -) -> TransactionInstruction: +) -> Instruction: """Creates instruction to remove a validator based on their vote account address.""" (withdraw_authority, seed) = find_withdraw_authority_program_address(program_id, stake_pool) (validator_stake, seed) = find_stake_program_address(program_id, validator, stake_pool, validator_stake_seed) @@ -874,15 +874,15 @@ def remove_validator_from_pool_with_vote( validator_list=validator_list, validator_stake=validator_stake, transient_stake=transient_stake, - clock_sysvar=SYSVAR_CLOCK_PUBKEY, + clock_sysvar=CLOCK, stake_program_id=STAKE_PROGRAM_ID, ) ) -def deposit_stake(params: DepositStakeParams) -> TransactionInstruction: +def deposit_stake(params: DepositStakeParams) -> Instruction: """Creates a transaction instruction to deposit a stake account into a stake pool.""" - keys = [ + accounts = [ AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=True), AccountMeta(pubkey=params.validator_list, is_signer=False, is_writable=True), AccountMeta(pubkey=params.deposit_authority, is_signer=False, is_writable=False), @@ -899,8 +899,8 @@ def deposit_stake(params: DepositStakeParams) -> TransactionInstruction: AccountMeta(pubkey=params.token_program_id, is_signer=False, is_writable=False), AccountMeta(pubkey=params.stake_program_id, is_signer=False, is_writable=False), ] - return TransactionInstruction( - keys=keys, + return Instruction( + accounts=accounts, program_id=params.program_id, data=INSTRUCTIONS_LAYOUT.build( dict( @@ -911,10 +911,10 @@ def deposit_stake(params: DepositStakeParams) -> TransactionInstruction: ) -def withdraw_stake(params: WithdrawStakeParams) -> TransactionInstruction: +def withdraw_stake(params: WithdrawStakeParams) -> Instruction: """Creates a transaction instruction to withdraw active stake from a stake pool.""" - return TransactionInstruction( - keys=[ + return Instruction( + accounts=[ AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=True), AccountMeta(pubkey=params.validator_list, is_signer=False, is_writable=True), AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), @@ -939,9 +939,9 @@ def withdraw_stake(params: WithdrawStakeParams) -> TransactionInstruction: ) -def deposit_sol(params: DepositSolParams) -> TransactionInstruction: +def deposit_sol(params: DepositSolParams) -> Instruction: """Creates a transaction instruction to deposit SOL into a stake pool.""" - keys = [ + accounts = [ AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=True), AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), AccountMeta(pubkey=params.reserve_stake, is_signer=False, is_writable=True), @@ -954,9 +954,9 @@ def deposit_sol(params: DepositSolParams) -> TransactionInstruction: AccountMeta(pubkey=params.token_program_id, is_signer=False, is_writable=False), ] if params.deposit_authority: - keys.append(AccountMeta(pubkey=params.deposit_authority, is_signer=True, is_writable=False)) - return TransactionInstruction( - keys=keys, + accounts.append(AccountMeta(pubkey=params.deposit_authority, is_signer=True, is_writable=False)) + return Instruction( + accounts=accounts, program_id=params.program_id, data=INSTRUCTIONS_LAYOUT.build( dict( @@ -967,9 +967,9 @@ def deposit_sol(params: DepositSolParams) -> TransactionInstruction: ) -def withdraw_sol(params: WithdrawSolParams) -> TransactionInstruction: +def withdraw_sol(params: WithdrawSolParams) -> Instruction: """Creates a transaction instruction to withdraw SOL from a stake pool.""" - keys = [ + accounts = [ AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=True), AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), AccountMeta(pubkey=params.source_transfer_authority, is_signer=True, is_writable=False), @@ -987,8 +987,8 @@ def withdraw_sol(params: WithdrawSolParams) -> TransactionInstruction: if params.sol_withdraw_authority: AccountMeta(pubkey=params.sol_withdraw_authority, is_signer=True, is_writable=False) - return TransactionInstruction( - keys=keys, + return Instruction( + accounts=accounts, program_id=params.program_id, data=INSTRUCTIONS_LAYOUT.build( dict( @@ -999,9 +999,9 @@ def withdraw_sol(params: WithdrawSolParams) -> TransactionInstruction: ) -def update_validator_list_balance(params: UpdateValidatorListBalanceParams) -> TransactionInstruction: +def update_validator_list_balance(params: UpdateValidatorListBalanceParams) -> Instruction: """Creates instruction to update a set of validators in the stake pool.""" - keys = [ + accounts = [ AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=False), AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), AccountMeta(pubkey=params.validator_list, is_signer=False, is_writable=True), @@ -1010,12 +1010,12 @@ def update_validator_list_balance(params: UpdateValidatorListBalanceParams) -> T AccountMeta(pubkey=params.stake_history_sysvar, is_signer=False, is_writable=False), AccountMeta(pubkey=params.stake_program_id, is_signer=False, is_writable=False), ] - keys.extend([ + accounts.extend([ AccountMeta(pubkey=pubkey, is_signer=False, is_writable=True) for pubkey in params.validator_and_transient_stake_pairs ]) - return TransactionInstruction( - keys=keys, + return Instruction( + accounts=accounts, program_id=params.program_id, data=INSTRUCTIONS_LAYOUT.build( dict( @@ -1026,10 +1026,10 @@ def update_validator_list_balance(params: UpdateValidatorListBalanceParams) -> T ) -def update_stake_pool_balance(params: UpdateStakePoolBalanceParams) -> TransactionInstruction: +def update_stake_pool_balance(params: UpdateStakePoolBalanceParams) -> Instruction: """Creates instruction to update the overall stake pool balance.""" - return TransactionInstruction( - keys=[ + return Instruction( + accounts=[ AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=True), AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), AccountMeta(pubkey=params.validator_list, is_signer=False, is_writable=True), @@ -1048,10 +1048,10 @@ def update_stake_pool_balance(params: UpdateStakePoolBalanceParams) -> Transacti ) -def cleanup_removed_validator_entries(params: CleanupRemovedValidatorEntriesParams) -> TransactionInstruction: +def cleanup_removed_validator_entries(params: CleanupRemovedValidatorEntriesParams) -> Instruction: """Creates instruction to cleanup removed validator entries.""" - return TransactionInstruction( - keys=[ + return Instruction( + accounts=[ AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=False), AccountMeta(pubkey=params.validator_list, is_signer=False, is_writable=True), ], @@ -1065,10 +1065,10 @@ def cleanup_removed_validator_entries(params: CleanupRemovedValidatorEntriesPara ) -def increase_validator_stake(params: IncreaseValidatorStakeParams) -> TransactionInstruction: +def increase_validator_stake(params: IncreaseValidatorStakeParams) -> Instruction: """Creates instruction to increase the stake on a validator.""" - return TransactionInstruction( - keys=[ + return Instruction( + accounts=[ AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=False), AccountMeta(pubkey=params.staker, is_signer=True, is_writable=False), AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), @@ -1099,11 +1099,11 @@ def increase_validator_stake(params: IncreaseValidatorStakeParams) -> Transactio def increase_additional_validator_stake( params: IncreaseAdditionalValidatorStakeParams, - ) -> TransactionInstruction: + ) -> Instruction: """Creates `IncreaseAdditionalValidatorStake` instruction (rebalance from reserve account to transient account)""" - return TransactionInstruction( - keys=[ + return Instruction( + accounts=[ AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=False), AccountMeta(pubkey=params.staker, is_signer=True, is_writable=False), AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), @@ -1133,10 +1133,10 @@ def increase_additional_validator_stake( ) -def decrease_validator_stake(params: DecreaseValidatorStakeParams) -> TransactionInstruction: +def decrease_validator_stake(params: DecreaseValidatorStakeParams) -> Instruction: """Creates instruction to decrease the stake on a validator.""" - return TransactionInstruction( - keys=[ + return Instruction( + accounts=[ AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=False), AccountMeta(pubkey=params.staker, is_signer=True, is_writable=False), AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), @@ -1161,11 +1161,11 @@ def decrease_validator_stake(params: DecreaseValidatorStakeParams) -> Transactio ) -def decrease_additional_validator_stake(params: DecreaseAdditionalValidatorStakeParams) -> TransactionInstruction: +def decrease_additional_validator_stake(params: DecreaseAdditionalValidatorStakeParams) -> Instruction: """ Creates `DecreaseAdditionalValidatorStake` instruction (rebalance from validator account to transient account).""" - return TransactionInstruction( - keys=[ + return Instruction( + accounts=[ AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=False), AccountMeta(pubkey=params.staker, is_signer=True, is_writable=False), AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), @@ -1193,10 +1193,10 @@ def decrease_additional_validator_stake(params: DecreaseAdditionalValidatorStake ) -def decrease_validator_stake_with_reserve(params: DecreaseValidatorStakeWithReserveParams) -> TransactionInstruction: +def decrease_validator_stake_with_reserve(params: DecreaseValidatorStakeWithReserveParams) -> Instruction: """Creates instruction to decrease the stake on a validator.""" - return TransactionInstruction( - keys=[ + return Instruction( + accounts=[ AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=False), AccountMeta(pubkey=params.staker, is_signer=True, is_writable=False), AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), @@ -1222,10 +1222,10 @@ def decrease_validator_stake_with_reserve(params: DecreaseValidatorStakeWithRese ) -def create_token_metadata(params: CreateTokenMetadataParams) -> TransactionInstruction: +def create_token_metadata(params: CreateTokenMetadataParams) -> Instruction: """Creates an instruction to create metadata using the mpl token metadata program for the pool token.""" - keys = [ + accounts = [ AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=False), AccountMeta(pubkey=params.manager, is_signer=True, is_writable=False), AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), @@ -1235,8 +1235,8 @@ def create_token_metadata(params: CreateTokenMetadataParams) -> TransactionInstr AccountMeta(pubkey=params.metadata_program_id, is_signer=False, is_writable=False), AccountMeta(pubkey=params.system_program_id, is_signer=False, is_writable=False), ] - return TransactionInstruction( - keys=keys, + return Instruction( + accounts=accounts, program_id=params.program_id, data=INSTRUCTIONS_LAYOUT.build( dict( @@ -1251,18 +1251,18 @@ def create_token_metadata(params: CreateTokenMetadataParams) -> TransactionInstr ) -def update_token_metadata(params: UpdateTokenMetadataParams) -> TransactionInstruction: +def update_token_metadata(params: UpdateTokenMetadataParams) -> Instruction: """Creates an instruction to update metadata in the mpl token metadata program account for the pool token.""" - keys = [ + accounts = [ AccountMeta(pubkey=params.stake_pool, is_signer=False, is_writable=False), AccountMeta(pubkey=params.manager, is_signer=True, is_writable=False), AccountMeta(pubkey=params.withdraw_authority, is_signer=False, is_writable=False), AccountMeta(pubkey=params.token_metadata, is_signer=False, is_writable=True), AccountMeta(pubkey=params.metadata_program_id, is_signer=False, is_writable=False) ] - return TransactionInstruction( - keys=keys, + return Instruction( + accounts=accounts, program_id=params.program_id, data=INSTRUCTIONS_LAYOUT.build( dict( diff --git a/clients/py/stake_pool/state.py b/clients/py/stake_pool/state.py index 36be8a11..b0bc5cbc 100644 --- a/clients/py/stake_pool/state.py +++ b/clients/py/stake_pool/state.py @@ -4,16 +4,15 @@ from typing import List, NamedTuple, Optional from construct import Bytes, Container, Struct, Switch, Int8ul, Int32ul, Int64ul, Pass # type: ignore -from solana.publickey import PublicKey -from solana.utils.helpers import decode_byte_string +from solders.pubkey import Pubkey from stake.state import Lockup, LOCKUP_LAYOUT PUBLIC_KEY_LAYOUT = Bytes(32) -def decode_optional_publickey(container: Container) -> Optional[PublicKey]: +def decode_optional_publickey(container: Container) -> Optional[Pubkey]: if container: - return PublicKey(container.popitem()[1]) + return Pubkey(container.popitem()[1]) else: return None @@ -40,50 +39,49 @@ def decode_optional_container(cls, container: Container): class StakePool(NamedTuple): """Stake pool and all its data.""" - manager: PublicKey - staker: PublicKey - stake_deposit_authority: PublicKey + manager: Pubkey + staker: Pubkey + stake_deposit_authority: Pubkey stake_withdraw_bump_seed: int - validator_list: PublicKey - reserve_stake: PublicKey - pool_mint: PublicKey - manager_fee_account: PublicKey - token_program_id: PublicKey + validator_list: Pubkey + reserve_stake: Pubkey + pool_mint: Pubkey + manager_fee_account: Pubkey + token_program_id: Pubkey total_lamports: int pool_token_supply: int last_update_epoch: int lockup: Lockup epoch_fee: Fee next_epoch_fee: Optional[Fee] - preferred_deposit_validator: Optional[PublicKey] - preferred_withdraw_validator: Optional[PublicKey] + preferred_deposit_validator: Optional[Pubkey] + preferred_withdraw_validator: Optional[Pubkey] stake_deposit_fee: Fee stake_withdrawal_fee: Fee next_stake_withdrawal_fee: Optional[Fee] stake_referral_fee: int - sol_deposit_authority: Optional[PublicKey] + sol_deposit_authority: Optional[Pubkey] sol_deposit_fee: Fee sol_referral_fee: int - sol_withdraw_authority: Optional[PublicKey] + sol_withdraw_authority: Optional[Pubkey] sol_withdrawal_fee: Fee next_sol_withdrawal_fee: Optional[Fee] last_epoch_pool_token_supply: int last_epoch_total_lamports: int @classmethod - def decode(cls, data: str, encoding: str): - data_bytes = decode_byte_string(data, encoding) - parsed = DECODE_STAKE_POOL_LAYOUT.parse(data_bytes) + def decode(cls, data: bytes): + parsed = DECODE_STAKE_POOL_LAYOUT.parse(data) return StakePool( - manager=PublicKey(parsed['manager']), - staker=PublicKey(parsed['staker']), - stake_deposit_authority=PublicKey(parsed['stake_deposit_authority']), + manager=Pubkey(parsed['manager']), + staker=Pubkey(parsed['staker']), + stake_deposit_authority=Pubkey(parsed['stake_deposit_authority']), stake_withdraw_bump_seed=parsed['stake_withdraw_bump_seed'], - validator_list=PublicKey(parsed['validator_list']), - reserve_stake=PublicKey(parsed['reserve_stake']), - pool_mint=PublicKey(parsed['pool_mint']), - manager_fee_account=PublicKey(parsed['manager_fee_account']), - token_program_id=PublicKey(parsed['token_program_id']), + validator_list=Pubkey(parsed['validator_list']), + reserve_stake=Pubkey(parsed['reserve_stake']), + pool_mint=Pubkey(parsed['pool_mint']), + manager_fee_account=Pubkey(parsed['manager_fee_account']), + token_program_id=Pubkey(parsed['token_program_id']), total_lamports=parsed['total_lamports'], pool_token_supply=parsed['pool_token_supply'], last_update_epoch=parsed['last_update_epoch'], @@ -144,7 +142,7 @@ class ValidatorStakeInfo(NamedTuple): status: StakeStatus """Status of the validator stake account.""" - vote_account_address: PublicKey + vote_account_address: Pubkey """Validator vote account address.""" @classmethod @@ -157,7 +155,7 @@ def decode_container(cls, container: Container): unused=container['unused'], validator_seed_suffix=container['validator_seed_suffix'], status=container['status'], - vote_account_address=PublicKey(container['vote_account_address']), + vote_account_address=Pubkey(container['vote_account_address']), ) @@ -176,9 +174,8 @@ def calculate_validator_list_size(max_validators: int) -> int: return layout.sizeof() @classmethod - def decode(cls, data: str, encoding: str): - data_bytes = decode_byte_string(data, encoding) - parsed = DECODE_VALIDATOR_LIST_LAYOUT.parse(data_bytes) + def decode(cls, data: bytes): + parsed = DECODE_VALIDATOR_LIST_LAYOUT.parse(data) return ValidatorList( max_validators=parsed['max_validators'], validators=[ValidatorStakeInfo.decode_container(container) for container in parsed['validators']], diff --git a/clients/py/system/actions.py b/clients/py/system/actions.py index 0b16a045..c4c02549 100644 --- a/clients/py/system/actions.py +++ b/clients/py/system/actions.py @@ -1,9 +1,8 @@ -from solana.publickey import PublicKey +from solders.pubkey import Pubkey from solana.rpc.async_api import AsyncClient -from solana.rpc.commitment import Confirmed -async def airdrop(client: AsyncClient, receiver: PublicKey, lamports: int): +async def airdrop(client: AsyncClient, receiver: Pubkey, lamports: int): print(f"Airdropping {lamports} lamports to {receiver}...") - resp = await client.request_airdrop(receiver, lamports, Confirmed) - await client.confirm_transaction(resp['result'], Confirmed) + resp = await client.request_airdrop(receiver, lamports) + await client.confirm_transaction(resp.value) diff --git a/clients/py/tests/conftest.py b/clients/py/tests/conftest.py index 24212678..647e9594 100644 --- a/clients/py/tests/conftest.py +++ b/clients/py/tests/conftest.py @@ -7,8 +7,8 @@ from typing import AsyncIterator, List, Tuple from subprocess import Popen -from solana.keypair import Keypair -from solana.publickey import PublicKey +from solders.keypair import Keypair +from solders.pubkey import Pubkey from solana.rpc.async_api import AsyncClient from solana.rpc.commitment import Confirmed @@ -44,29 +44,28 @@ def solana_test_validator(): @pytest_asyncio.fixture -async def validators(async_client, payer) -> List[PublicKey]: +async def validators(async_client, payer) -> List[Pubkey]: num_validators = 3 validators = [] for i in range(num_validators): vote = Keypair() node = Keypair() - await create_vote(async_client, payer, vote, node, payer.public_key, payer.public_key, 10) - validators.append(vote.public_key) + await create_vote(async_client, payer, vote, node, payer.pubkey(), payer.pubkey(), 10) + validators.append(vote.pubkey()) return validators @pytest_asyncio.fixture async def stake_pool_addresses( async_client, payer, validators, waiter -) -> Tuple[PublicKey, PublicKey, PublicKey]: +) -> Tuple[Pubkey, Pubkey, Pubkey]: fee = Fee(numerator=1, denominator=1000) referral_fee = 20 - # Change back to `wait_for_next_epoch_if_soon` once https://github.com/solana-labs/solana/pull/26851 is available - await waiter.wait_for_next_epoch(async_client) + await waiter.wait_for_next_epoch_if_soon(async_client) stake_pool_addresses = await create_all(async_client, payer, fee, referral_fee) stake_pool = stake_pool_addresses[0] pool_mint = stake_pool_addresses[2] - token_account = get_associated_token_address(payer.public_key, pool_mint) + token_account = get_associated_token_address(payer.pubkey(), pool_mint) await deposit_sol(async_client, payer, stake_pool, token_account, AIRDROP_LAMPORTS // 2) for validator in validators: await add_validator_to_pool(async_client, payer, stake_pool, validator) @@ -91,7 +90,7 @@ async def async_client(solana_test_validator) -> AsyncIterator[AsyncClient]: @pytest_asyncio.fixture async def payer(async_client) -> Keypair: payer = Keypair() - await airdrop(async_client, payer.public_key, AIRDROP_LAMPORTS) + await airdrop(async_client, payer.pubkey(), AIRDROP_LAMPORTS) return payer @@ -99,17 +98,18 @@ class Waiter: @staticmethod async def wait_for_next_epoch(async_client: AsyncClient): resp = await async_client.get_epoch_info(commitment=Confirmed) - current_epoch = resp['result']['epoch'] + current_epoch = resp.value.epoch next_epoch = current_epoch while current_epoch == next_epoch: await asyncio.sleep(1.0) resp = await async_client.get_epoch_info(commitment=Confirmed) - next_epoch = resp['result']['epoch'] + next_epoch = resp.value.epoch + await asyncio.sleep(0.4) # wait one more block to avoid reward payout time @staticmethod async def wait_for_next_epoch_if_soon(async_client: AsyncClient): resp = await async_client.get_epoch_info(commitment=Confirmed) - if resp['result']['slotsInEpoch'] - resp['result']['slotIndex'] < NUM_SLOTS_PER_EPOCH // 2: + if resp.value.slots_in_epoch - resp.value.slot_index < NUM_SLOTS_PER_EPOCH // 2: await Waiter.wait_for_next_epoch(async_client) return True else: diff --git a/clients/py/tests/test_a_time_sensitive.py b/clients/py/tests/test_a_time_sensitive.py index 682d1202..59e59e9e 100644 --- a/clients/py/tests/test_a_time_sensitive.py +++ b/clients/py/tests/test_a_time_sensitive.py @@ -15,16 +15,16 @@ async def test_increase_decrease_this_is_very_slow(async_client, validators, pay (stake_pool_address, validator_list_address, _) = stake_pool_addresses resp = await async_client.get_minimum_balance_for_rent_exemption(STAKE_LEN) - stake_rent_exemption = resp['result'] + stake_rent_exemption = resp.value minimum_amount = MINIMUM_ACTIVE_STAKE + stake_rent_exemption increase_amount = MINIMUM_ACTIVE_STAKE * 4 decrease_amount = increase_amount // 2 deposit_amount = (increase_amount + stake_rent_exemption) * len(validators) resp = await async_client.get_account_info(stake_pool_address, commitment=Confirmed) - data = resp['result']['value']['data'] - stake_pool = StakePool.decode(data[0], data[1]) - token_account = get_associated_token_address(payer.public_key, stake_pool.pool_mint) + data = resp.value.data if resp.value else bytes() + stake_pool = StakePool.decode(data) + token_account = get_associated_token_address(payer.pubkey(), stake_pool.pool_mint) await deposit_sol(async_client, payer, stake_pool_address, token_account, deposit_amount) # increase to all @@ -36,8 +36,8 @@ async def test_increase_decrease_this_is_very_slow(async_client, validators, pay # validate the increase is now on the transient account resp = await async_client.get_account_info(validator_list_address, commitment=Confirmed) - data = resp['result']['value']['data'] - validator_list = ValidatorList.decode(data[0], data[1]) + data = resp.value.data if resp.value else bytes() + validator_list = ValidatorList.decode(data) for validator in validator_list.validators: assert validator.transient_stake_lamports == increase_amount // 2 + stake_rent_exemption assert validator.active_stake_lamports == minimum_amount @@ -52,8 +52,8 @@ async def test_increase_decrease_this_is_very_slow(async_client, validators, pay # validate the additional increase is now on the transient account resp = await async_client.get_account_info(validator_list_address, commitment=Confirmed) - data = resp['result']['value']['data'] - validator_list = ValidatorList.decode(data[0], data[1]) + data = resp.value.data if resp.value else bytes() + validator_list = ValidatorList.decode(data) for validator in validator_list.validators: assert validator.transient_stake_lamports == increase_amount + stake_rent_exemption * 2 assert validator.active_stake_lamports == minimum_amount @@ -63,8 +63,8 @@ async def test_increase_decrease_this_is_very_slow(async_client, validators, pay await update_stake_pool(async_client, payer, stake_pool_address) resp = await async_client.get_account_info(validator_list_address, commitment=Confirmed) - data = resp['result']['value']['data'] - validator_list = ValidatorList.decode(data[0], data[1]) + data = resp.value.data if resp.value else bytes() + validator_list = ValidatorList.decode(data) for validator in validator_list.validators: assert validator.last_update_epoch != 0 assert validator.transient_stake_lamports == 0 @@ -79,8 +79,8 @@ async def test_increase_decrease_this_is_very_slow(async_client, validators, pay # validate the decrease is now on the transient account resp = await async_client.get_account_info(validator_list_address, commitment=Confirmed) - data = resp['result']['value']['data'] - validator_list = ValidatorList.decode(data[0], data[1]) + data = resp.value.data if resp.value else bytes() + validator_list = ValidatorList.decode(data) for validator in validator_list.validators: assert validator.transient_stake_lamports == decrease_amount + stake_rent_exemption assert validator.active_stake_lamports == increase_amount - decrease_amount + minimum_amount + \ @@ -96,8 +96,8 @@ async def test_increase_decrease_this_is_very_slow(async_client, validators, pay await update_stake_pool(async_client, payer, stake_pool_address) resp = await async_client.get_account_info(validator_list_address, commitment=Confirmed) - data = resp['result']['value']['data'] - validator_list = ValidatorList.decode(data[0], data[1]) + data = resp.value.data if resp.value else bytes() + validator_list = ValidatorList.decode(data) for validator in validator_list.validators: assert validator.transient_stake_lamports == 0 assert validator.active_stake_lamports == expected_active_stake_lamports diff --git a/clients/py/tests/test_add_remove.py b/clients/py/tests/test_add_remove.py index b2d96af3..abf47871 100644 --- a/clients/py/tests/test_add_remove.py +++ b/clients/py/tests/test_add_remove.py @@ -12,11 +12,11 @@ async def test_add_remove_validators(async_client, validators, payer, stake_pool_addresses): (stake_pool_address, validator_list_address, _) = stake_pool_addresses resp = await async_client.get_account_info(validator_list_address, commitment=Confirmed) - data = resp['result']['value']['data'] - validator_list = ValidatorList.decode(data[0], data[1]) + data = resp.value.data if resp.value else bytes() + validator_list = ValidatorList.decode(data) assert len(validator_list.validators) == len(validators) resp = await async_client.get_minimum_balance_for_rent_exemption(STAKE_LEN) - stake_rent_exemption = resp['result'] + stake_rent_exemption = resp.value futures = [] for validator_info in validator_list.validators: assert validator_info.vote_account_address in validators @@ -29,7 +29,7 @@ async def test_add_remove_validators(async_client, validators, payer, stake_pool await asyncio.gather(*futures) resp = await async_client.get_account_info(validator_list_address, commitment=Confirmed) - data = resp['result']['value']['data'] - validator_list = ValidatorList.decode(data[0], data[1]) + data = resp.value.data if resp.value else bytes() + validator_list = ValidatorList.decode(data) for validator_info in validator_list.validators: assert validator_info.status == StakeStatus.DEACTIVATING_VALIDATOR diff --git a/clients/py/tests/test_bot_rebalance.py b/clients/py/tests/test_bot_rebalance.py index c0283ef5..c7da3f82 100644 --- a/clients/py/tests/test_bot_rebalance.py +++ b/clients/py/tests/test_bot_rebalance.py @@ -18,7 +18,7 @@ async def test_rebalance_this_is_very_slow(async_client, validators, payer, stake_pool_addresses, waiter): (stake_pool_address, validator_list_address, _) = stake_pool_addresses resp = await async_client.get_minimum_balance_for_rent_exemption(STAKE_LEN) - stake_rent_exemption = resp['result'] + stake_rent_exemption = resp.value # With minimum delegation at MINIMUM_DELEGATION + rent-exemption, when # decreasing, we'll need rent exemption + minimum delegation delegated to # cover all movements @@ -27,10 +27,10 @@ async def test_rebalance_this_is_very_slow(async_client, validators, payer, stak deposit_amount = (increase_amount + stake_rent_exemption) * len(validators) resp = await async_client.get_account_info(stake_pool_address, commitment=Confirmed) - data = resp['result']['value']['data'] - stake_pool = StakePool.decode(data[0], data[1]) + data = resp.value.data if resp.value else bytes() + stake_pool = StakePool.decode(data) total_lamports = stake_pool.total_lamports + deposit_amount - token_account = get_associated_token_address(payer.public_key, stake_pool.pool_mint) + token_account = get_associated_token_address(payer.pubkey(), stake_pool.pool_mint) await deposit_sol(async_client, payer, stake_pool_address, token_account, deposit_amount) # Test case 1: Increase everywhere @@ -38,12 +38,12 @@ async def test_rebalance_this_is_very_slow(async_client, validators, payer, stak # should only have minimum left resp = await async_client.get_account_info(stake_pool.reserve_stake, commitment=Confirmed) - assert resp['result']['value']['lamports'] == stake_rent_exemption + MINIMUM_RESERVE_LAMPORTS + assert resp.value.lamports == stake_rent_exemption + MINIMUM_RESERVE_LAMPORTS # should all be the same resp = await async_client.get_account_info(validator_list_address, commitment=Confirmed) - data = resp['result']['value']['data'] - validator_list = ValidatorList.decode(data[0], data[1]) + data = resp.value.data if resp.value else bytes() + validator_list = ValidatorList.decode(data) for validator in validator_list.validators: assert validator.active_stake_lamports == minimum_amount assert validator.transient_stake_lamports == total_lamports / len(validators) - minimum_amount @@ -56,13 +56,13 @@ async def test_rebalance_this_is_very_slow(async_client, validators, payer, stak # should still only have minimum left resp = await async_client.get_account_info(stake_pool.reserve_stake, commitment=Confirmed) - reserve_lamports = resp['result']['value']['lamports'] + reserve_lamports = resp.value.lamports assert reserve_lamports == stake_rent_exemption + MINIMUM_RESERVE_LAMPORTS # should all be decreasing now resp = await async_client.get_account_info(validator_list_address, commitment=Confirmed) - data = resp['result']['value']['data'] - validator_list = ValidatorList.decode(data[0], data[1]) + data = resp.value.data if resp.value else bytes() + validator_list = ValidatorList.decode(data) for validator in validator_list.validators: assert validator.active_stake_lamports == minimum_amount assert validator.transient_stake_lamports == max_in_reserve / len(validators) @@ -74,13 +74,13 @@ async def test_rebalance_this_is_very_slow(async_client, validators, payer, stak # should still only have minimum left + rent exemptions from increase resp = await async_client.get_account_info(stake_pool.reserve_stake, commitment=Confirmed) - reserve_lamports = resp['result']['value']['lamports'] + reserve_lamports = resp.value.lamports assert reserve_lamports == stake_rent_exemption + max_in_reserve + MINIMUM_RESERVE_LAMPORTS # should all be decreased now resp = await async_client.get_account_info(validator_list_address, commitment=Confirmed) - data = resp['result']['value']['data'] - validator_list = ValidatorList.decode(data[0], data[1]) + data = resp.value.data if resp.value else bytes() + validator_list = ValidatorList.decode(data) for validator in validator_list.validators: assert validator.active_stake_lamports == minimum_amount assert validator.transient_stake_lamports == 0 diff --git a/clients/py/tests/test_create.py b/clients/py/tests/test_create.py index 97600ae3..3b5a42a1 100644 --- a/clients/py/tests/test_create.py +++ b/clients/py/tests/test_create.py @@ -1,5 +1,5 @@ import pytest -from solana.keypair import Keypair +from solders.keypair import Keypair from solana.rpc.commitment import Confirmed from spl.token.constants import TOKEN_PROGRAM_ID @@ -19,7 +19,7 @@ async def test_create_stake_pool(async_client, payer): stake_pool = Keypair() validator_list = Keypair() (pool_withdraw_authority, seed) = find_withdraw_authority_program_address( - STAKE_POOL_PROGRAM_ID, stake_pool.public_key) + STAKE_POOL_PROGRAM_ID, stake_pool.pubkey()) reserve_stake = Keypair() await create_stake(async_client, payer, reserve_stake, pool_withdraw_authority, MINIMUM_RESERVE_LAMPORTS) @@ -30,25 +30,25 @@ async def test_create_stake_pool(async_client, payer): manager_fee_account = await create_associated_token_account( async_client, payer, - payer.public_key, - pool_mint.public_key, + payer.pubkey(), + pool_mint.pubkey(), ) fee = Fee(numerator=1, denominator=1000) referral_fee = 20 await create( - async_client, payer, stake_pool, validator_list, pool_mint.public_key, - reserve_stake.public_key, manager_fee_account, fee, referral_fee) - resp = await async_client.get_account_info(stake_pool.public_key, commitment=Confirmed) - assert resp['result']['value']['owner'] == str(STAKE_POOL_PROGRAM_ID) - data = resp['result']['value']['data'] - pool_data = StakePool.decode(data[0], data[1]) - assert pool_data.manager == payer.public_key - assert pool_data.staker == payer.public_key + async_client, payer, stake_pool, validator_list, pool_mint.pubkey(), + reserve_stake.pubkey(), manager_fee_account, fee, referral_fee) + resp = await async_client.get_account_info(stake_pool.pubkey(), commitment=Confirmed) + assert resp.value.owner == STAKE_POOL_PROGRAM_ID + data = resp.value.data if resp.value else bytes() + pool_data = StakePool.decode(data) + assert pool_data.manager == payer.pubkey() + assert pool_data.staker == payer.pubkey() assert pool_data.stake_withdraw_bump_seed == seed - assert pool_data.validator_list == validator_list.public_key - assert pool_data.reserve_stake == reserve_stake.public_key - assert pool_data.pool_mint == pool_mint.public_key + assert pool_data.validator_list == validator_list.pubkey() + assert pool_data.reserve_stake == reserve_stake.pubkey() + assert pool_data.pool_mint == pool_mint.pubkey() assert pool_data.manager_fee_account == manager_fee_account assert pool_data.token_program_id == TOKEN_PROGRAM_ID assert pool_data.total_lamports == 0 diff --git a/clients/py/tests/test_create_update_token_metadata.py b/clients/py/tests/test_create_update_token_metadata.py index 10ae24f6..2ee0a7db 100644 --- a/clients/py/tests/test_create_update_token_metadata.py +++ b/clients/py/tests/test_create_update_token_metadata.py @@ -2,20 +2,18 @@ from stake_pool.actions import create_all, create_token_metadata, update_token_metadata from stake_pool.state import Fee, StakePool from solana.rpc.commitment import Confirmed -from solana.rpc.async_api import AsyncClient -from solana.keypair import Keypair from stake_pool.constants import find_metadata_account -from solana.utils.helpers import decode_byte_string @pytest.mark.asyncio -async def test_create_metadata_success(async_client: AsyncClient, payer: Keypair): +async def test_create_metadata_success(async_client, waiter, payer): fee = Fee(numerator=1, denominator=1000) referral_fee = 20 + await waiter.wait_for_next_epoch_if_soon(async_client) (stake_pool_address, _validator_list_address, _) = await create_all(async_client, payer, fee, referral_fee) resp = await async_client.get_account_info(stake_pool_address, commitment=Confirmed) - data = resp['result']['value']['data'] - stake_pool = StakePool.decode(data[0], data[1]) + data = resp.value.data if resp.value else bytes() + stake_pool = StakePool.decode(data) name = "test_name" symbol = "SYM" @@ -24,21 +22,21 @@ async def test_create_metadata_success(async_client: AsyncClient, payer: Keypair (metadata_program_address, _seed) = find_metadata_account(stake_pool.pool_mint) resp = await async_client.get_account_info(metadata_program_address, commitment=Confirmed) - data = resp['result']['value']['data'] - raw_data = decode_byte_string(data[0], data[1]) + raw_data = resp.value.data if resp.value else bytes() assert name == str(raw_data[69:101], "utf-8")[:len(name)] assert symbol == str(raw_data[105:115], "utf-8")[:len(symbol)] assert uri == str(raw_data[119:319], "utf-8")[:len(uri)] @pytest.mark.asyncio -async def test_update_metadata_success(async_client: AsyncClient, payer: Keypair): +async def test_update_metadata_success(async_client, waiter, payer): fee = Fee(numerator=1, denominator=1000) referral_fee = 20 + await waiter.wait_for_next_epoch_if_soon(async_client) (stake_pool_address, _validator_list_address, _) = await create_all(async_client, payer, fee, referral_fee) resp = await async_client.get_account_info(stake_pool_address, commitment=Confirmed) - data = resp['result']['value']['data'] - stake_pool = StakePool.decode(data[0], data[1]) + data = resp.value.data if resp.value else bytes() + stake_pool = StakePool.decode(data) name = "test_name" symbol = "SYM" @@ -47,8 +45,7 @@ async def test_update_metadata_success(async_client: AsyncClient, payer: Keypair (metadata_program_address, _seed) = find_metadata_account(stake_pool.pool_mint) resp = await async_client.get_account_info(metadata_program_address, commitment=Confirmed) - data = resp['result']['value']['data'] - raw_data = decode_byte_string(data[0], data[1]) + raw_data = resp.value.data if resp.value else bytes() assert name == str(raw_data[69:101], "utf-8")[:len(name)] assert symbol == str(raw_data[105:115], "utf-8")[:len(symbol)] assert uri == str(raw_data[119:319], "utf-8")[:len(uri)] @@ -60,8 +57,7 @@ async def test_update_metadata_success(async_client: AsyncClient, payer: Keypair (metadata_program_address, _seed) = find_metadata_account(stake_pool.pool_mint) resp = await async_client.get_account_info(metadata_program_address, commitment=Confirmed) - data = resp['result']['value']['data'] - raw_data = decode_byte_string(data[0], data[1]) + raw_data = resp.value.data if resp.value else bytes() assert updated_name == str(raw_data[69:101], "utf-8")[:len(updated_name)] assert updated_symbol == str(raw_data[105:115], "utf-8")[:len(updated_symbol)] assert updated_uri == str(raw_data[119:319], "utf-8")[:len(updated_uri)] diff --git a/clients/py/tests/test_deposit_withdraw_sol.py b/clients/py/tests/test_deposit_withdraw_sol.py index 8057101e..438c4afd 100644 --- a/clients/py/tests/test_deposit_withdraw_sol.py +++ b/clients/py/tests/test_deposit_withdraw_sol.py @@ -1,6 +1,6 @@ import pytest from solana.rpc.commitment import Confirmed, Processed -from solana.keypair import Keypair +from solders.keypair import Keypair from spl.token.instructions import get_associated_token_address from stake_pool.state import Fee, StakePool @@ -8,20 +8,21 @@ @pytest.mark.asyncio -async def test_deposit_withdraw_sol(async_client, payer): +async def test_deposit_withdraw_sol(async_client, waiter, payer): fee = Fee(numerator=1, denominator=1000) referral_fee = 20 + await waiter.wait_for_next_epoch(async_client) (stake_pool_address, validator_list_address, _) = await create_all(async_client, payer, fee, referral_fee) resp = await async_client.get_account_info(stake_pool_address, commitment=Confirmed) - data = resp['result']['value']['data'] - stake_pool = StakePool.decode(data[0], data[1]) - token_account = get_associated_token_address(payer.public_key, stake_pool.pool_mint) + data = resp.value.data if resp.value else bytes() + stake_pool = StakePool.decode(data) + token_account = get_associated_token_address(payer.pubkey(), stake_pool.pool_mint) deposit_amount = 100_000_000 await deposit_sol(async_client, payer, stake_pool_address, token_account, deposit_amount) pool_token_balance = await async_client.get_token_account_balance(token_account, Confirmed) - assert pool_token_balance['result']['value']['amount'] == str(deposit_amount) + assert pool_token_balance.value.amount == str(deposit_amount) recipient = Keypair() - await withdraw_sol(async_client, payer, token_account, stake_pool_address, recipient.public_key, deposit_amount) + await withdraw_sol(async_client, payer, token_account, stake_pool_address, recipient.pubkey(), deposit_amount) # for some reason, this is not always in sync when running all tests pool_token_balance = await async_client.get_token_account_balance(token_account, Processed) - assert pool_token_balance['result']['value']['amount'] == str('0') + assert pool_token_balance.value.amount == str('0') diff --git a/clients/py/tests/test_deposit_withdraw_stake.py b/clients/py/tests/test_deposit_withdraw_stake.py index 890fb9d1..63b9e07d 100644 --- a/clients/py/tests/test_deposit_withdraw_stake.py +++ b/clients/py/tests/test_deposit_withdraw_stake.py @@ -1,6 +1,6 @@ import pytest from solana.rpc.commitment import Confirmed -from solana.keypair import Keypair +from solders.keypair import Keypair from spl.token.instructions import get_associated_token_address from stake.actions import create_stake, delegate_stake @@ -15,20 +15,20 @@ async def test_deposit_withdraw_stake(async_client, validators, payer, stake_pool_addresses, waiter): (stake_pool_address, validator_list_address, _) = stake_pool_addresses resp = await async_client.get_account_info(stake_pool_address, commitment=Confirmed) - data = resp['result']['value']['data'] - stake_pool = StakePool.decode(data[0], data[1]) + data = resp.value.data if resp.value else bytes() + stake_pool = StakePool.decode(data) validator = next(iter(validators)) stake_amount = MINIMUM_ACTIVE_STAKE stake = Keypair() - await create_stake(async_client, payer, stake, payer.public_key, stake_amount) - stake = stake.public_key + await create_stake(async_client, payer, stake, payer.pubkey(), stake_amount) + stake = stake.pubkey() await delegate_stake(async_client, payer, payer, stake, validator) resp = await async_client.get_account_info(stake, commitment=Confirmed) - data = resp['result']['value']['data'] - stake_state = StakeStake.decode(data[0], data[1]) - token_account = get_associated_token_address(payer.public_key, stake_pool.pool_mint) + data = resp.value.data if resp.value else bytes() + stake_state = StakeStake.decode(data) + token_account = get_associated_token_address(payer.pubkey(), stake_pool.pool_mint) pre_pool_token_balance = await async_client.get_token_account_balance(token_account, Confirmed) - pre_pool_token_balance = int(pre_pool_token_balance['result']['value']['amount']) + pre_pool_token_balance = int(pre_pool_token_balance.value.amount) print(stake_state) await waiter.wait_for_next_epoch(async_client) @@ -36,17 +36,17 @@ async def test_deposit_withdraw_stake(async_client, validators, payer, stake_poo await update_stake_pool(async_client, payer, stake_pool_address) await deposit_stake(async_client, payer, stake_pool_address, validator, stake, token_account) pool_token_balance = await async_client.get_token_account_balance(token_account, Confirmed) - pool_token_balance = pool_token_balance['result']['value']['amount'] + pool_token_balance = pool_token_balance.value.amount resp = await async_client.get_minimum_balance_for_rent_exemption(STAKE_LEN) - stake_rent_exemption = resp['result'] + stake_rent_exemption = resp.value assert pool_token_balance == str(stake_amount + stake_rent_exemption + pre_pool_token_balance) destination_stake = Keypair() await withdraw_stake( async_client, payer, payer, destination_stake, stake_pool_address, validator, - payer.public_key, token_account, stake_amount + payer.pubkey(), token_account, stake_amount ) pool_token_balance = await async_client.get_token_account_balance(token_account, Confirmed) - pool_token_balance = pool_token_balance['result']['value']['amount'] + pool_token_balance = pool_token_balance.value.amount assert pool_token_balance == str(stake_rent_exemption + pre_pool_token_balance) diff --git a/clients/py/tests/test_stake.py b/clients/py/tests/test_stake.py index ab7cc3a4..7f89b8a7 100644 --- a/clients/py/tests/test_stake.py +++ b/clients/py/tests/test_stake.py @@ -1,6 +1,6 @@ import asyncio import pytest -from solana.keypair import Keypair +from solders.keypair import Keypair from stake.actions import authorize, create_stake, delegate_stake from stake.constants import MINIMUM_DELEGATION @@ -10,24 +10,24 @@ @pytest.mark.asyncio async def test_create_stake(async_client, payer): stake = Keypair() - await create_stake(async_client, payer, stake, payer.public_key, 1) + await create_stake(async_client, payer, stake, payer.pubkey(), 1) @pytest.mark.asyncio async def test_delegate_stake(async_client, validators, payer): validator = validators[0] stake = Keypair() - await create_stake(async_client, payer, stake, payer.public_key, MINIMUM_DELEGATION) - await delegate_stake(async_client, payer, payer, stake.public_key, validator) + await create_stake(async_client, payer, stake, payer.pubkey(), MINIMUM_DELEGATION) + await delegate_stake(async_client, payer, payer, stake.pubkey(), validator) @pytest.mark.asyncio async def test_authorize_stake(async_client, payer): stake = Keypair() new_authority = Keypair() - await create_stake(async_client, payer, stake, payer.public_key, MINIMUM_DELEGATION) + await create_stake(async_client, payer, stake, payer.pubkey(), MINIMUM_DELEGATION) await asyncio.gather( - authorize(async_client, payer, payer, stake.public_key, new_authority.public_key, StakeAuthorize.STAKER), - authorize(async_client, payer, payer, stake.public_key, new_authority.public_key, StakeAuthorize.WITHDRAWER) + authorize(async_client, payer, payer, stake.pubkey(), new_authority.pubkey(), StakeAuthorize.STAKER), + authorize(async_client, payer, payer, stake.pubkey(), new_authority.pubkey(), StakeAuthorize.WITHDRAWER) ) - await authorize(async_client, payer, new_authority, stake.public_key, payer.public_key, StakeAuthorize.WITHDRAWER) + await authorize(async_client, payer, new_authority, stake.pubkey(), payer.pubkey(), StakeAuthorize.WITHDRAWER) diff --git a/clients/py/tests/test_system.py b/clients/py/tests/test_system.py index 31d2af34..f3b578ae 100644 --- a/clients/py/tests/test_system.py +++ b/clients/py/tests/test_system.py @@ -1,5 +1,5 @@ import pytest -from solana.keypair import Keypair +from solders.keypair import Keypair from solana.rpc.commitment import Confirmed import system.actions @@ -9,6 +9,6 @@ async def test_airdrop(async_client): manager = Keypair() airdrop_lamports = 1_000_000 - await system.actions.airdrop(async_client, manager.public_key, airdrop_lamports) - resp = await async_client.get_balance(manager.public_key, commitment=Confirmed) - assert resp['result']['value'] == airdrop_lamports + await system.actions.airdrop(async_client, manager.pubkey(), airdrop_lamports) + resp = await async_client.get_balance(manager.pubkey(), commitment=Confirmed) + assert resp.value == airdrop_lamports diff --git a/clients/py/tests/test_token.py b/clients/py/tests/test_token.py index 1d92c179..835feb15 100644 --- a/clients/py/tests/test_token.py +++ b/clients/py/tests/test_token.py @@ -1,5 +1,5 @@ import pytest -from solana.keypair import Keypair +from solders.keypair import Keypair from spl_token.actions import create_mint, create_associated_token_account @@ -7,10 +7,10 @@ @pytest.mark.asyncio async def test_create_mint(async_client, payer): pool_mint = Keypair() - await create_mint(async_client, payer, pool_mint, payer.public_key) + await create_mint(async_client, payer, pool_mint, payer.pubkey()) await create_associated_token_account( async_client, payer, - payer.public_key, - pool_mint.public_key, + payer.pubkey(), + pool_mint.pubkey(), ) diff --git a/clients/py/tests/test_vote.py b/clients/py/tests/test_vote.py index b0861d46..3b3ff460 100644 --- a/clients/py/tests/test_vote.py +++ b/clients/py/tests/test_vote.py @@ -1,6 +1,5 @@ import pytest -from solana.keypair import Keypair -from solana.publickey import PublicKey +from solders.keypair import Keypair from solana.rpc.commitment import Confirmed from vote.actions import create_vote @@ -11,6 +10,6 @@ async def test_create_vote(async_client, payer): vote = Keypair() node = Keypair() - await create_vote(async_client, payer, vote, node, payer.public_key, payer.public_key, 10) - resp = await async_client.get_account_info(vote.public_key, commitment=Confirmed) - assert PublicKey(resp['result']['value']['owner']) == VOTE_PROGRAM_ID + await create_vote(async_client, payer, vote, node, payer.pubkey(), payer.pubkey(), 10) + resp = await async_client.get_account_info(vote.pubkey(), commitment=Confirmed) + assert resp.value.owner == VOTE_PROGRAM_ID diff --git a/clients/py/vote/actions.py b/clients/py/vote/actions.py index 9f3fc49f..305d79a4 100644 --- a/clients/py/vote/actions.py +++ b/clients/py/vote/actions.py @@ -1,11 +1,11 @@ -from solana.publickey import PublicKey -from solana.keypair import Keypair +from solders.pubkey import Pubkey +from solders.keypair import Keypair from solana.rpc.async_api import AsyncClient from solana.rpc.commitment import Confirmed from solana.rpc.types import TxOpts -from solana.sysvar import SYSVAR_CLOCK_PUBKEY, SYSVAR_RENT_PUBKEY +from solders.sysvar import CLOCK, RENT from solana.transaction import Transaction -import solana.system_program as sys +import solders.system_program as sys from vote.constants import VOTE_PROGRAM_ID, VOTE_STATE_LEN from vote.instructions import initialize, InitializeParams @@ -13,33 +13,35 @@ async def create_vote( client: AsyncClient, payer: Keypair, vote: Keypair, node: Keypair, - voter: PublicKey, withdrawer: PublicKey, commission: int): - print(f"Creating vote account {vote.public_key}") + voter: Pubkey, withdrawer: Pubkey, commission: int): + print(f"Creating vote account {vote.pubkey()}") resp = await client.get_minimum_balance_for_rent_exemption(VOTE_STATE_LEN) - txn = Transaction() + txn = Transaction(fee_payer=payer.pubkey()) txn.add( sys.create_account( sys.CreateAccountParams( - from_pubkey=payer.public_key, - new_account_pubkey=vote.public_key, - lamports=resp['result'], + from_pubkey=payer.pubkey(), + to_pubkey=vote.pubkey(), + lamports=resp.value, space=VOTE_STATE_LEN, - program_id=VOTE_PROGRAM_ID, + owner=VOTE_PROGRAM_ID, ) ) ) txn.add( initialize( InitializeParams( - vote=vote.public_key, - rent_sysvar=SYSVAR_RENT_PUBKEY, - clock_sysvar=SYSVAR_CLOCK_PUBKEY, - node=node.public_key, + vote=vote.pubkey(), + rent_sysvar=RENT, + clock_sysvar=CLOCK, + node=node.pubkey(), authorized_voter=voter, authorized_withdrawer=withdrawer, commission=commission, ) ) ) + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash await client.send_transaction( - txn, payer, vote, node, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) + txn, payer, vote, node, recent_blockhash=recent_blockhash, + opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) diff --git a/clients/py/vote/constants.py b/clients/py/vote/constants.py index 701c90a0..0da3846b 100644 --- a/clients/py/vote/constants.py +++ b/clients/py/vote/constants.py @@ -1,7 +1,7 @@ -from solana.publickey import PublicKey +from solders.pubkey import Pubkey -VOTE_PROGRAM_ID = PublicKey("Vote111111111111111111111111111111111111111") +VOTE_PROGRAM_ID = Pubkey.from_string("Vote111111111111111111111111111111111111111") """Program id for the native vote program.""" VOTE_STATE_LEN: int = 3762 diff --git a/clients/py/vote/instructions.py b/clients/py/vote/instructions.py index 267aeb4a..c8a0a69d 100644 --- a/clients/py/vote/instructions.py +++ b/clients/py/vote/instructions.py @@ -5,9 +5,9 @@ from construct import Bytes, Struct, Switch, Int8ul, Int32ul, Pass # type: ignore -from solana.publickey import PublicKey -from solana.sysvar import SYSVAR_CLOCK_PUBKEY, SYSVAR_RENT_PUBKEY -from solana.transaction import AccountMeta, TransactionInstruction +from solders.pubkey import Pubkey +from solders.sysvar import CLOCK, RENT +from solders.instruction import AccountMeta, Instruction from vote.constants import VOTE_PROGRAM_ID @@ -17,18 +17,18 @@ class InitializeParams(NamedTuple): """Initialize vote account params.""" - vote: PublicKey + vote: Pubkey """`[w]` Uninitialized vote account""" - rent_sysvar: PublicKey + rent_sysvar: Pubkey """`[]` Rent sysvar.""" - clock_sysvar: PublicKey + clock_sysvar: Pubkey """`[]` Clock sysvar.""" - node: PublicKey + node: Pubkey """`[s]` New validator identity.""" - authorized_voter: PublicKey + authorized_voter: Pubkey """The authorized voter for this vote account.""" - authorized_withdrawer: PublicKey + authorized_withdrawer: Pubkey """The authorized withdrawer for this vote account.""" commission: int """Commission, represented as a percentage""" @@ -73,7 +73,7 @@ class InstructionType(IntEnum): ) -def initialize(params: InitializeParams) -> TransactionInstruction: +def initialize(params: InitializeParams) -> Instruction: """Creates a transaction instruction to initialize a new stake.""" data = INSTRUCTIONS_LAYOUT.build( dict( @@ -86,13 +86,13 @@ def initialize(params: InitializeParams) -> TransactionInstruction: ), ) ) - return TransactionInstruction( - keys=[ + return Instruction( + program_id=VOTE_PROGRAM_ID, + accounts=[ AccountMeta(pubkey=params.vote, is_signer=False, is_writable=True), - AccountMeta(pubkey=params.rent_sysvar or SYSVAR_RENT_PUBKEY, is_signer=False, is_writable=False), - AccountMeta(pubkey=params.clock_sysvar or SYSVAR_CLOCK_PUBKEY, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.rent_sysvar or RENT, is_signer=False, is_writable=False), + AccountMeta(pubkey=params.clock_sysvar or CLOCK, is_signer=False, is_writable=False), AccountMeta(pubkey=params.node, is_signer=True, is_writable=False), ], - program_id=VOTE_PROGRAM_ID, data=data, ) From 221bd47ed0af4c67a37f1420cf5481e537cb2d3e Mon Sep 17 00:00:00 2001 From: Jon C Date: Thu, 25 Jul 2024 16:53:13 +0200 Subject: [PATCH 0932/1076] ci: Bump crates to Solana 2.0.3 (#7047) * Run script * Update lockfile * Use "processed" instead of deprecated "recent" * Fixup account compression tests * account-compression: Remove `only` in test --- clients/cli/Cargo.toml | 18 +++++++++--------- program/Cargo.toml | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 8258e32b..b21b344a 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -14,15 +14,15 @@ clap = "2.33.3" serde = "1.0.204" serde_derive = "1.0.130" serde_json = "1.0.120" -solana-account-decoder = "2.0.0" -solana-clap-utils = "2.0.0" -solana-cli-config = "2.0.0" -solana-cli-output = "2.0.0" -solana-client = "2.0.0" -solana-logger = "2.0.0" -solana-program = "2.0.0" -solana-remote-wallet = "2.0.0" -solana-sdk = "2.0.0" +solana-account-decoder = "2.0.3" +solana-clap-utils = "2.0.3" +solana-cli-config = "2.0.3" +solana-cli-output = "2.0.3" +solana-client = "2.0.3" +solana-logger = "2.0.3" +solana-program = "2.0.3" +solana-remote-wallet = "2.0.3" +solana-sdk = "2.0.3" spl-associated-token-account = { version = "=4.0.0", path = "../../associated-token-account/program", features = [ "no-entrypoint", ] } diff --git a/program/Cargo.toml b/program/Cargo.toml index ffc4056b..94b1be94 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -20,7 +20,7 @@ num-traits = "0.2" num_enum = "0.7.2" serde = "1.0.204" serde_derive = "1.0.103" -solana-program = "2.0.0" +solana-program = "2.0.3" solana-security-txt = "1.1.1" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint", @@ -37,9 +37,9 @@ bincode = "1.3.1" [dev-dependencies] assert_matches = "1.5.0" proptest = "1.5" -solana-program-test = "2.0.0" -solana-sdk = "2.0.0" -solana-vote-program = "2.0.0" +solana-program-test = "2.0.3" +solana-sdk = "2.0.3" +solana-vote-program = "2.0.3" spl-token = { version = "6.0", path = "../../token/program", features = [ "no-entrypoint", ] } From dfb1489284ae1efce5142ae56a6cd759bcd8a92c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jul 2024 13:01:30 +0200 Subject: [PATCH 0933/1076] build(deps-dev): bump rollup from 4.19.0 to 4.19.1 (#7067) Bumps [rollup](https://github.com/rollup/rollup) from 4.19.0 to 4.19.1. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.19.0...v4.19.1) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index c1a75dad..0d2ebea3 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.3.3", "rimraf": "^6.0.1", - "rollup": "^4.19.0", + "rollup": "^4.19.1", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.2.3", "typescript": "^5.5.4" From 266a685d2ddf066cb31b084090a314e56da7565a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jul 2024 13:01:39 +0200 Subject: [PATCH 0934/1076] build(deps-dev): bump @types/node from 20.14.12 to 22.0.0 (#7065) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.14.12 to 22.0.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 0d2ebea3..064afa8c 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.14.12", + "@types/node": "^22.0.0", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.17.0", "@typescript-eslint/parser": "^7.17.0", From c6d9ab84b218cfcb1ed751144673b55a802e3ff2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jul 2024 13:02:05 +0200 Subject: [PATCH 0935/1076] build(deps): bump serde_json from 1.0.120 to 1.0.121 (#7062) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.120 to 1.0.121. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.120...v1.0.121) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index b21b344a..3c6dd8e7 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ borsh = "1.5.1" clap = "2.33.3" serde = "1.0.204" serde_derive = "1.0.130" -serde_json = "1.0.120" +serde_json = "1.0.121" solana-account-decoder = "2.0.3" solana-clap-utils = "2.0.3" solana-cli-config = "2.0.3" From 30cd16a3af5cf30e2297d8b6c90f41d6fe692507 Mon Sep 17 00:00:00 2001 From: Jon C Date: Mon, 29 Jul 2024 16:19:25 +0200 Subject: [PATCH 0936/1076] stake-pool: Remove redelegate instruction from program and JS (#7033) * stake-pool: Remove redelegate from program * Remove redelegate from js package --- clients/js-legacy/src/index.ts | 91 -- clients/js-legacy/src/instructions.ts | 95 +- clients/js-legacy/test/instructions.test.ts | 26 - program/src/instruction.rs | 11 + program/src/processor.rs | 423 +------ program/tests/helpers/mod.rs | 48 - program/tests/redelegate.rs | 1213 ------------------- 7 files changed, 16 insertions(+), 1891 deletions(-) delete mode 100644 program/tests/redelegate.rs diff --git a/clients/js-legacy/src/index.ts b/clients/js-legacy/src/index.ts index 27b75f2f..a3f31d4b 100644 --- a/clients/js-legacy/src/index.ts +++ b/clients/js-legacy/src/index.ts @@ -72,17 +72,6 @@ export interface StakePoolAccounts { validatorList: ValidatorListAccount | undefined; } -interface RedelegateProps { - connection: Connection; - stakePoolAddress: PublicKey; - sourceVoteAccount: PublicKey; - destinationVoteAccount: PublicKey; - sourceTransientStakeSeed: number | BN; - destinationTransientStakeSeed: number | BN; - ephemeralStakeSeed: number | BN; - lamports: number | BN; -} - /** * Retrieves and deserializes a StakePool account using a web3js connection and the stake pool address. * @param connection: An active web3js connection. @@ -1160,86 +1149,6 @@ export async function stakePoolInfo(connection: Connection, stakePoolAddress: Pu }; } -/** - * Creates instructions required to redelegate stake. - */ -export async function redelegate(props: RedelegateProps) { - const { - connection, - stakePoolAddress, - sourceVoteAccount, - sourceTransientStakeSeed, - destinationVoteAccount, - destinationTransientStakeSeed, - ephemeralStakeSeed, - lamports, - } = props; - const stakePool = await getStakePoolAccount(connection, stakePoolAddress); - - const stakePoolWithdrawAuthority = await findWithdrawAuthorityProgramAddress( - STAKE_POOL_PROGRAM_ID, - stakePoolAddress, - ); - - const sourceValidatorStake = await findStakeProgramAddress( - STAKE_POOL_PROGRAM_ID, - sourceVoteAccount, - stakePoolAddress, - ); - - const sourceTransientStake = await findTransientStakeProgramAddress( - STAKE_POOL_PROGRAM_ID, - sourceVoteAccount, - stakePoolAddress, - new BN(sourceTransientStakeSeed), - ); - - const destinationValidatorStake = await findStakeProgramAddress( - STAKE_POOL_PROGRAM_ID, - destinationVoteAccount, - stakePoolAddress, - ); - - const destinationTransientStake = await findTransientStakeProgramAddress( - STAKE_POOL_PROGRAM_ID, - destinationVoteAccount, - stakePoolAddress, - new BN(destinationTransientStakeSeed), - ); - - const ephemeralStake = await findEphemeralStakeProgramAddress( - STAKE_POOL_PROGRAM_ID, - stakePoolAddress, - new BN(ephemeralStakeSeed), - ); - - const instructions: TransactionInstruction[] = []; - - instructions.push( - StakePoolInstruction.redelegate({ - stakePool: stakePool.pubkey, - staker: stakePool.account.data.staker, - validatorList: stakePool.account.data.validatorList, - reserveStake: stakePool.account.data.reserveStake, - stakePoolWithdrawAuthority, - ephemeralStake, - ephemeralStakeSeed, - sourceValidatorStake, - sourceTransientStake, - sourceTransientStakeSeed, - destinationValidatorStake, - destinationTransientStake, - destinationTransientStakeSeed, - validator: destinationVoteAccount, - lamports, - }), - ); - - return { - instructions, - }; -} - /** * Creates instructions required to create pool token metadata. */ diff --git a/clients/js-legacy/src/instructions.ts b/clients/js-legacy/src/instructions.ts index 970d6736..e792dd12 100644 --- a/clients/js-legacy/src/instructions.ts +++ b/clients/js-legacy/src/instructions.ts @@ -11,7 +11,6 @@ import { import * as BufferLayout from '@solana/buffer-layout'; import { TOKEN_PROGRAM_ID } from '@solana/spl-token'; import { InstructionType, encodeData, decodeData } from './utils'; -import BN from 'bn.js'; import { METADATA_MAX_NAME_LENGTH, METADATA_MAX_SYMBOL_LENGTH, @@ -175,19 +174,7 @@ export const STAKE_POOL_INSTRUCTION_LAYOUTS: { }, Redelegate: { index: 22, - layout: BufferLayout.struct([ - BufferLayout.u8('instruction'), - /// Amount of lamports to redelegate - BufferLayout.ns64('lamports'), - /// Seed used to create source transient stake account - BufferLayout.ns64('sourceTransientStakeSeed'), - /// Seed used to create destination ephemeral account. - BufferLayout.ns64('ephemeralStakeSeed'), - /// Seed used to create destination transient stake account. If there is - /// already transient stake, this must match the current seed, otherwise - /// it can be anything - BufferLayout.ns64('destinationTransientStakeSeed'), - ]), + layout: BufferLayout.struct([BufferLayout.u8('instruction')]), }, }); @@ -340,30 +327,6 @@ export type DepositSolParams = { lamports: number; }; -export type RedelegateParams = { - stakePool: PublicKey; - staker: PublicKey; - stakePoolWithdrawAuthority: PublicKey; - validatorList: PublicKey; - reserveStake: PublicKey; - sourceValidatorStake: PublicKey; - sourceTransientStake: PublicKey; - ephemeralStake: PublicKey; - destinationTransientStake: PublicKey; - destinationValidatorStake: PublicKey; - validator: PublicKey; - // Amount of lamports to redelegate - lamports: number | BN; - // Seed used to create source transient stake account - sourceTransientStakeSeed: number | BN; - // Seed used to create destination ephemeral account - ephemeralStakeSeed: number | BN; - // Seed used to create destination transient stake account. If there is - // already transient stake, this must match the current seed, otherwise - // it can be anything - destinationTransientStakeSeed: number | BN; -}; - export type CreateTokenMetadataParams = { stakePool: PublicKey; manager: PublicKey; @@ -984,62 +947,6 @@ export class StakePoolInstruction { }); } - /** - * Creates `Redelegate` instruction (rebalance from one validator account to another) - * @param params - */ - static redelegate(params: RedelegateParams): TransactionInstruction { - const { - stakePool, - staker, - stakePoolWithdrawAuthority, - validatorList, - reserveStake, - sourceValidatorStake, - sourceTransientStake, - ephemeralStake, - destinationTransientStake, - destinationValidatorStake, - validator, - lamports, - sourceTransientStakeSeed, - ephemeralStakeSeed, - destinationTransientStakeSeed, - } = params; - - const keys = [ - { pubkey: stakePool, isSigner: false, isWritable: false }, - { pubkey: staker, isSigner: true, isWritable: false }, - { pubkey: stakePoolWithdrawAuthority, isSigner: false, isWritable: false }, - { pubkey: validatorList, isSigner: false, isWritable: true }, - { pubkey: reserveStake, isSigner: false, isWritable: true }, - { pubkey: sourceValidatorStake, isSigner: false, isWritable: true }, - { pubkey: sourceTransientStake, isSigner: false, isWritable: true }, - { pubkey: ephemeralStake, isSigner: false, isWritable: true }, - { pubkey: destinationTransientStake, isSigner: false, isWritable: true }, - { pubkey: destinationValidatorStake, isSigner: false, isWritable: false }, - { pubkey: validator, isSigner: false, isWritable: false }, - { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false }, - { pubkey: SYSVAR_STAKE_HISTORY_PUBKEY, isSigner: false, isWritable: false }, - { pubkey: STAKE_CONFIG_ID, isSigner: false, isWritable: false }, - { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, - { pubkey: StakeProgram.programId, isSigner: false, isWritable: false }, - ]; - - const data = encodeData(STAKE_POOL_INSTRUCTION_LAYOUTS.Redelegate, { - lamports, - sourceTransientStakeSeed, - ephemeralStakeSeed, - destinationTransientStakeSeed, - }); - - return new TransactionInstruction({ - programId: STAKE_POOL_PROGRAM_ID, - keys, - data, - }); - } - /** * Creates an instruction to create metadata * using the mpl token metadata program for the pool token diff --git a/clients/js-legacy/test/instructions.test.ts b/clients/js-legacy/test/instructions.test.ts index 490e777f..c3e9b7c9 100644 --- a/clients/js-legacy/test/instructions.test.ts +++ b/clients/js-legacy/test/instructions.test.ts @@ -27,7 +27,6 @@ import { depositSol, withdrawSol, withdrawStake, - redelegate, getStakeAccount, createPoolTokenMetadata, updatePoolTokenMetadata, @@ -498,31 +497,6 @@ describe('StakePoolProgram', () => { }); }); - describe('redelegation', () => { - it('should call successfully', async () => { - const data = { - connection, - stakePoolAddress, - sourceVoteAccount: PublicKey.default, - sourceTransientStakeSeed: 10, - destinationVoteAccount: PublicKey.default, - destinationTransientStakeSeed: 20, - ephemeralStakeSeed: 100, - lamports: 100, - }; - const res = await redelegate(data); - - const decodedData = STAKE_POOL_INSTRUCTION_LAYOUTS.Redelegate.layout.decode( - res.instructions[0].data, - ); - - expect(decodedData.instruction).toBe(22); - expect(decodedData.lamports).toBe(data.lamports); - expect(decodedData.sourceTransientStakeSeed).toBe(data.sourceTransientStakeSeed); - expect(decodedData.destinationTransientStakeSeed).toBe(data.destinationTransientStakeSeed); - expect(decodedData.ephemeralStakeSeed).toBe(data.ephemeralStakeSeed); - }); - }); describe('createPoolTokenMetadata', () => { it('should create pool token metadata', async () => { connection.getAccountInfo = jest.fn(async (pubKey: PublicKey) => { diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 313afd93..5b370a93 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -1,5 +1,8 @@ //! Instruction types +// Remove the following `allow` when `Redelegate` is removed, required to avoid +// warnings from uses of deprecated types during trait derivations. +#![allow(deprecated)] #![allow(clippy::too_many_arguments)] use { @@ -599,6 +602,10 @@ pub enum StakePoolInstruction { /// 13. `[]` Stake Config sysvar /// 14. `[]` System program /// 15. `[]` Stake program + #[deprecated( + since = "2.0.0", + note = "The stake redelegate instruction used in this will not be enabled." + )] Redelegate { /// Amount of lamports to redelegate #[allow(dead_code)] // but it's not @@ -1051,6 +1058,10 @@ pub fn increase_additional_validator_stake( /// Creates `Redelegate` instruction (rebalance from one validator account to /// another) +#[deprecated( + since = "2.0.0", + note = "The stake redelegate instruction used in this will not be enabled." +)] pub fn redelegate( program_id: &Pubkey, stake_pool: &Pubkey, diff --git a/program/src/processor.rs b/program/src/processor.rs index 893346eb..24887f26 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -308,35 +308,6 @@ fn check_validator_stake_account( Ok(()) } -/// Checks if a transient stake account is valid, which means that it's usable -/// by the pool and delegated to the expected validator. These conditions can be -/// violated if a validator was force destaked during a cluster restart. -fn check_transient_stake_account( - stake_account_info: &AccountInfo, - program_id: &Pubkey, - stake_pool: &Pubkey, - withdraw_authority: &Pubkey, - vote_account_address: &Pubkey, - seed: u64, - lockup: &stake::state::Lockup, -) -> Result<(), ProgramError> { - check_account_owner(stake_account_info, &stake::program::id())?; - check_transient_stake_address( - program_id, - stake_pool, - stake_account_info.key, - vote_account_address, - seed, - )?; - check_stake_state( - stake_account_info, - withdraw_authority, - vote_account_address, - lockup, - )?; - Ok(()) -} - /// Create a stake account on a PDA without transferring lamports fn create_stake_account( stake_account_info: AccountInfo<'_>, @@ -592,41 +563,6 @@ impl Processor { ) } - /// Issue stake::instruction::redelegate instruction to redelegate stake - #[allow(clippy::too_many_arguments)] - fn stake_redelegate<'a>( - stake_pool: &Pubkey, - source_account: AccountInfo<'a>, - authority: AccountInfo<'a>, - authority_type: &[u8], - bump_seed: u8, - destination_account: AccountInfo<'a>, - vote_account: AccountInfo<'a>, - stake_config: AccountInfo<'a>, - ) -> Result<(), ProgramError> { - let authority_signature_seeds = [stake_pool.as_ref(), authority_type, &[bump_seed]]; - let signers = &[&authority_signature_seeds[..]]; - - let redelegate_instruction = &stake::instruction::redelegate( - source_account.key, - authority.key, - vote_account.key, - destination_account.key, - )[2]; - - invoke_signed( - redelegate_instruction, - &[ - source_account, - destination_account, - vote_account, - stake_config, - authority, - ], - signers, - ) - } - /// Issue a spl_token `Burn` instruction. #[allow(clippy::too_many_arguments)] fn token_burn<'a>( @@ -1842,346 +1778,6 @@ impl Processor { Ok(()) } - /// Processes `Redelegate` instruction. - #[inline(never)] // needed due to stack size violation - fn process_redelegate( - program_id: &Pubkey, - accounts: &[AccountInfo], - lamports: u64, - source_transient_stake_seed: u64, - ephemeral_stake_seed: u64, - destination_transient_stake_seed: u64, - ) -> ProgramResult { - let account_info_iter = &mut accounts.iter(); - let stake_pool_info = next_account_info(account_info_iter)?; - let staker_info = next_account_info(account_info_iter)?; - let withdraw_authority_info = next_account_info(account_info_iter)?; - let validator_list_info = next_account_info(account_info_iter)?; - let reserve_stake_info = next_account_info(account_info_iter)?; - let source_validator_stake_account_info = next_account_info(account_info_iter)?; - let source_transient_stake_account_info = next_account_info(account_info_iter)?; - let ephemeral_stake_account_info = next_account_info(account_info_iter)?; - let destination_transient_stake_account_info = next_account_info(account_info_iter)?; - let destination_validator_stake_account_info = next_account_info(account_info_iter)?; - let validator_vote_account_info = next_account_info(account_info_iter)?; - let clock_info = next_account_info(account_info_iter)?; - let clock = &Clock::from_account_info(clock_info)?; - let stake_history_info = next_account_info(account_info_iter)?; - let stake_config_info = next_account_info(account_info_iter)?; - let system_program_info = next_account_info(account_info_iter)?; - let stake_program_info = next_account_info(account_info_iter)?; - - check_system_program(system_program_info.key)?; - check_stake_program(stake_program_info.key)?; - check_account_owner(stake_pool_info, program_id)?; - - let stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; - if !stake_pool.is_valid() { - msg!("Expected valid stake pool"); - return Err(StakePoolError::InvalidState.into()); - } - - stake_pool.check_authority_withdraw( - withdraw_authority_info.key, - program_id, - stake_pool_info.key, - )?; - stake_pool.check_staker(staker_info)?; - - if stake_pool.last_update_epoch < clock.epoch { - return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); - } - - stake_pool.check_validator_list(validator_list_info)?; - check_account_owner(validator_list_info, program_id)?; - stake_pool.check_reserve_stake(reserve_stake_info)?; - - let mut validator_list_data = validator_list_info.data.borrow_mut(); - let (header, mut validator_list) = - ValidatorListHeader::deserialize_vec(&mut validator_list_data)?; - if !header.is_valid() { - return Err(StakePoolError::InvalidState.into()); - } - - let rent = Rent::get()?; - let stake_space = std::mem::size_of::(); - let stake_rent = rent.minimum_balance(stake_space); - let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; - let current_minimum_delegation = minimum_delegation(stake_minimum_delegation); - - // check that we're redelegating enough - { - // redelegation requires that the source account maintains rent exemption and - // that the destination account has rent-exemption and minimum - // delegation - let minimum_redelegation_lamports = - current_minimum_delegation.saturating_add(stake_rent); - if lamports < minimum_redelegation_lamports { - msg!( - "Need more than {} lamports for redelegated stake and transient stake to meet minimum delegation requirement, {} provided", - minimum_redelegation_lamports, - lamports - ); - return Err(ProgramError::Custom( - stake::instruction::StakeError::InsufficientDelegation as u32, - )); - } - - // check that we're not draining the source account - let current_minimum_lamports = stake_rent.saturating_add(current_minimum_delegation); - if source_validator_stake_account_info - .lamports() - .saturating_sub(lamports) - < current_minimum_lamports - { - let max_split_amount = source_validator_stake_account_info - .lamports() - .saturating_sub(current_minimum_lamports); - msg!( - "Source stake does not have {} lamports for redelegation, must be {} at most", - lamports, - max_split_amount, - ); - return Err(ProgramError::InsufficientFunds); - } - } - - // check source account state - let (_, stake) = get_stake_state(source_validator_stake_account_info)?; - let vote_account_address = stake.delegation.voter_pubkey; - { - let maybe_validator_stake_info = - validator_list.find_mut::(|x| { - ValidatorStakeInfo::memcmp_pubkey(x, &vote_account_address) - }); - if maybe_validator_stake_info.is_none() { - msg!( - "Source vote account {} not found in stake pool", - vote_account_address - ); - return Err(StakePoolError::ValidatorNotFound.into()); - } - let validator_stake_info = maybe_validator_stake_info.unwrap(); - check_validator_stake_address( - program_id, - stake_pool_info.key, - source_validator_stake_account_info.key, - &vote_account_address, - NonZeroU32::new(validator_stake_info.validator_seed_suffix.into()), - )?; - if u64::from(validator_stake_info.transient_stake_lamports) > 0 { - return Err(StakePoolError::TransientAccountInUse.into()); - } - if validator_stake_info.status != StakeStatus::Active.into() { - msg!("Validator is marked for removal and no longer allows redelegation"); - return Err(StakePoolError::ValidatorNotFound.into()); - } - validator_stake_info.active_stake_lamports = - u64::from(validator_stake_info.active_stake_lamports) - .checked_sub(lamports) - .ok_or(StakePoolError::CalculationFailure)? - .into(); - validator_stake_info.transient_stake_lamports = stake_rent.into(); - validator_stake_info.transient_seed_suffix = source_transient_stake_seed.into(); - } - - // split from source, into source transient - { - // check transient account - let source_transient_stake_bump_seed = check_transient_stake_address( - program_id, - stake_pool_info.key, - source_transient_stake_account_info.key, - &vote_account_address, - source_transient_stake_seed, - )?; - let source_transient_stake_account_signer_seeds: &[&[_]] = &[ - TRANSIENT_STAKE_SEED_PREFIX, - vote_account_address.as_ref(), - stake_pool_info.key.as_ref(), - &source_transient_stake_seed.to_le_bytes(), - &[source_transient_stake_bump_seed], - ]; - - create_stake_account( - source_transient_stake_account_info.clone(), - source_transient_stake_account_signer_seeds, - stake_space, - )?; - - // if needed, pre-fund the rent-exempt reserve from the reserve stake - let required_lamports_for_rent_exemption = - stake_rent.saturating_sub(source_transient_stake_account_info.lamports()); - if required_lamports_for_rent_exemption > 0 { - if required_lamports_for_rent_exemption >= reserve_stake_info.lamports() { - return Err(StakePoolError::ReserveDepleted.into()); - } - Self::stake_withdraw( - stake_pool_info.key, - reserve_stake_info.clone(), - withdraw_authority_info.clone(), - AUTHORITY_WITHDRAW, - stake_pool.stake_withdraw_bump_seed, - source_transient_stake_account_info.clone(), - clock_info.clone(), - stake_history_info.clone(), - required_lamports_for_rent_exemption, - )?; - } - Self::stake_split( - stake_pool_info.key, - source_validator_stake_account_info.clone(), - withdraw_authority_info.clone(), - AUTHORITY_WITHDRAW, - stake_pool.stake_withdraw_bump_seed, - lamports, - source_transient_stake_account_info.clone(), - )?; - } - - // redelegate from source transient to ephemeral - { - let ephemeral_stake_bump_seed = check_ephemeral_stake_address( - program_id, - stake_pool_info.key, - ephemeral_stake_account_info.key, - ephemeral_stake_seed, - )?; - let ephemeral_stake_account_signer_seeds: &[&[_]] = &[ - EPHEMERAL_STAKE_SEED_PREFIX, - stake_pool_info.key.as_ref(), - &ephemeral_stake_seed.to_le_bytes(), - &[ephemeral_stake_bump_seed], - ]; - create_stake_account( - ephemeral_stake_account_info.clone(), - ephemeral_stake_account_signer_seeds, - stake_space, - )?; - Self::stake_redelegate( - stake_pool_info.key, - source_transient_stake_account_info.clone(), - withdraw_authority_info.clone(), - AUTHORITY_WITHDRAW, - stake_pool.stake_withdraw_bump_seed, - ephemeral_stake_account_info.clone(), - validator_vote_account_info.clone(), - stake_config_info.clone(), - )?; - } - - { - // check destination stake and transient stake accounts - let vote_account_address = validator_vote_account_info.key; - let maybe_validator_stake_info = - validator_list.find_mut::(|x| { - ValidatorStakeInfo::memcmp_pubkey(x, vote_account_address) - }); - if maybe_validator_stake_info.is_none() { - msg!( - "Destination vote account {} not found in stake pool", - vote_account_address - ); - return Err(StakePoolError::ValidatorNotFound.into()); - } - let validator_stake_info = maybe_validator_stake_info.unwrap(); - check_validator_stake_account( - destination_validator_stake_account_info, - program_id, - stake_pool_info.key, - withdraw_authority_info.key, - vote_account_address, - validator_stake_info.validator_seed_suffix.into(), - &stake_pool.lockup, - )?; - if validator_stake_info.status != StakeStatus::Active.into() { - msg!( - "Destination validator is marked for removal and no longer allows redelegation" - ); - return Err(StakePoolError::ValidatorNotFound.into()); - } - let transient_account_exists = - u64::from(validator_stake_info.transient_stake_lamports) > 0; - validator_stake_info.transient_stake_lamports = - u64::from(validator_stake_info.transient_stake_lamports) - .checked_add(lamports) - .ok_or(StakePoolError::CalculationFailure)? - .into(); - - if transient_account_exists { - // if transient stake exists, make sure it's the right one and that it's - // usable by the pool - if u64::from(validator_stake_info.transient_seed_suffix) - != destination_transient_stake_seed - { - msg!("Provided seed {} does not match current seed {} for transient stake account", - destination_transient_stake_seed, - u64::from(validator_stake_info.transient_seed_suffix) - ); - return Err(StakePoolError::InvalidStakeAccountAddress.into()); - } - check_transient_stake_account( - destination_transient_stake_account_info, - program_id, - stake_pool_info.key, - withdraw_authority_info.key, - vote_account_address, - destination_transient_stake_seed, - &stake_pool.lockup, - )?; - check_if_stake_activating( - destination_transient_stake_account_info, - vote_account_address, - clock.epoch, - )?; - Self::stake_merge( - stake_pool_info.key, - ephemeral_stake_account_info.clone(), - withdraw_authority_info.clone(), - AUTHORITY_WITHDRAW, - stake_pool.stake_withdraw_bump_seed, - destination_transient_stake_account_info.clone(), - clock_info.clone(), - stake_history_info.clone(), - )?; - } else { - // otherwise, create the new account and split into it - let destination_transient_stake_bump_seed = check_transient_stake_address( - program_id, - stake_pool_info.key, - destination_transient_stake_account_info.key, - vote_account_address, - destination_transient_stake_seed, - )?; - let destination_transient_stake_account_signer_seeds: &[&[_]] = &[ - TRANSIENT_STAKE_SEED_PREFIX, - vote_account_address.as_ref(), - stake_pool_info.key.as_ref(), - &destination_transient_stake_seed.to_le_bytes(), - &[destination_transient_stake_bump_seed], - ]; - create_stake_account( - destination_transient_stake_account_info.clone(), - destination_transient_stake_account_signer_seeds, - stake_space, - )?; - Self::stake_split( - stake_pool_info.key, - ephemeral_stake_account_info.clone(), - withdraw_authority_info.clone(), - AUTHORITY_WITHDRAW, - stake_pool.stake_withdraw_bump_seed, - lamports, - destination_transient_stake_account_info.clone(), - )?; - validator_stake_info.transient_seed_suffix = - destination_transient_stake_seed.into(); - } - } - - Ok(()) - } - /// Process `SetPreferredValidator` instruction #[inline(never)] // needed due to stack size violation fn process_set_preferred_validator( @@ -4012,21 +3608,10 @@ impl Processor { msg!("Instruction: UpdateTokenMetadata"); Self::process_update_pool_token_metadata(program_id, accounts, name, symbol, uri) } - StakePoolInstruction::Redelegate { - lamports, - source_transient_stake_seed, - ephemeral_stake_seed, - destination_transient_stake_seed, - } => { - msg!("Instruction: Redelegate"); - Self::process_redelegate( - program_id, - accounts, - lamports, - source_transient_stake_seed, - ephemeral_stake_seed, - destination_transient_stake_seed, - ) + #[allow(deprecated)] + StakePoolInstruction::Redelegate { .. } => { + msg!("Instruction: Redelegate will not be enabled"); + Err(ProgramError::InvalidInstructionData) } StakePoolInstruction::DepositStakeWithSlippage { minimum_pool_tokens_out, diff --git a/program/tests/helpers/mod.rs b/program/tests/helpers/mod.rs index eb785ff6..89baa021 100644 --- a/program/tests/helpers/mod.rs +++ b/program/tests/helpers/mod.rs @@ -1942,54 +1942,6 @@ impl StakePoolAccounts { } } - #[allow(clippy::too_many_arguments)] - pub async fn redelegate( - &self, - banks_client: &mut BanksClient, - payer: &Keypair, - recent_blockhash: &Hash, - source_validator_stake: &Pubkey, - source_transient_stake: &Pubkey, - ephemeral_stake: &Pubkey, - destination_transient_stake: &Pubkey, - destination_validator_stake: &Pubkey, - validator: &Pubkey, - lamports: u64, - source_transient_stake_seed: u64, - ephemeral_stake_seed: u64, - destination_transient_stake_seed: u64, - ) -> Option { - let transaction = Transaction::new_signed_with_payer( - &[instruction::redelegate( - &id(), - &self.stake_pool.pubkey(), - &self.staker.pubkey(), - &self.withdraw_authority, - &self.validator_list.pubkey(), - &self.reserve_stake.pubkey(), - source_validator_stake, - source_transient_stake, - ephemeral_stake, - destination_transient_stake, - destination_validator_stake, - validator, - lamports, - source_transient_stake_seed, - ephemeral_stake_seed, - destination_transient_stake_seed, - )], - Some(&payer.pubkey()), - &[payer, &self.staker], - *recent_blockhash, - ); - #[allow(clippy::useless_conversion)] // Remove during upgrade to 1.10 - banks_client - .process_transaction(transaction) - .await - .map_err(|e| e.into()) - .err() - } - pub async fn set_preferred_validator( &self, banks_client: &mut BanksClient, diff --git a/program/tests/redelegate.rs b/program/tests/redelegate.rs deleted file mode 100644 index 3256eef1..00000000 --- a/program/tests/redelegate.rs +++ /dev/null @@ -1,1213 +0,0 @@ -#![allow(clippy::arithmetic_side_effects)] -#![cfg(feature = "test-sbf")] - -mod helpers; - -use { - bincode::deserialize, - helpers::*, - solana_program::{ - clock::Epoch, hash::Hash, instruction::InstructionError, pubkey::Pubkey, stake, - }, - solana_program_test::*, - solana_sdk::{ - signature::{Keypair, Signer}, - stake::instruction::StakeError, - transaction::{Transaction, TransactionError}, - }, - spl_stake_pool::{ - error::StakePoolError, find_ephemeral_stake_program_address, - find_transient_stake_program_address, id, instruction, MINIMUM_RESERVE_LAMPORTS, - }, -}; - -async fn setup( - do_warp: bool, -) -> ( - ProgramTestContext, - Hash, - StakePoolAccounts, - ValidatorStakeAccount, - ValidatorStakeAccount, - u64, - u64, -) { - let mut context = program_test().start_with_context().await; - let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); - let current_minimum_delegation = stake_pool_get_minimum_delegation( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - ) - .await; - - let stake_pool_accounts = StakePoolAccounts::default(); - stake_pool_accounts - .initialize_stake_pool( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - MINIMUM_RESERVE_LAMPORTS + current_minimum_delegation + stake_rent * 2, - ) - .await - .unwrap(); - - let source_validator_stake = simple_add_validator_to_pool( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts, - None, - ) - .await; - - let destination_validator_stake = simple_add_validator_to_pool( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts, - None, - ) - .await; - - let minimum_redelegate_lamports = current_minimum_delegation + stake_rent; - simple_deposit_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &stake_pool_accounts, - &source_validator_stake, - minimum_redelegate_lamports, - ) - .await - .unwrap(); - - let mut slot = 1; - if do_warp { - slot += context.genesis_config().epoch_schedule.first_normal_slot; - context.warp_to_slot(slot).unwrap(); - stake_pool_accounts - .update_all( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - false, - ) - .await; - } - - let last_blockhash = context - .banks_client - .get_new_latest_blockhash(&context.last_blockhash) - .await - .unwrap(); - - ( - context, - last_blockhash, - stake_pool_accounts, - source_validator_stake, - destination_validator_stake, - minimum_redelegate_lamports, - slot, - ) -} - -#[tokio::test] -async fn success() { - let ( - mut context, - last_blockhash, - stake_pool_accounts, - source_validator_stake, - destination_validator_stake, - redelegate_lamports, - mut slot, - ) = setup(true).await; - - // Save validator stake - let pre_validator_stake_account = get_account( - &mut context.banks_client, - &source_validator_stake.stake_account, - ) - .await; - - // Save validator stake - let pre_destination_validator_stake_account = get_account( - &mut context.banks_client, - &destination_validator_stake.stake_account, - ) - .await; - - // Check no transient stake - let transient_account = context - .banks_client - .get_account(source_validator_stake.transient_stake_account) - .await - .unwrap(); - assert!(transient_account.is_none()); - - let ephemeral_stake_seed = 100; - let ephemeral_stake = find_ephemeral_stake_program_address( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - ephemeral_stake_seed, - ) - .0; - let error = stake_pool_accounts - .redelegate( - &mut context.banks_client, - &context.payer, - &last_blockhash, - &source_validator_stake.stake_account, - &source_validator_stake.transient_stake_account, - &ephemeral_stake, - &destination_validator_stake.transient_stake_account, - &destination_validator_stake.stake_account, - &destination_validator_stake.vote.pubkey(), - redelegate_lamports, - source_validator_stake.transient_stake_seed, - ephemeral_stake_seed, - destination_validator_stake.transient_stake_seed, - ) - .await; - assert!(error.is_none(), "{:?}", error); - - // Check validator stake account balance - let validator_stake_account = get_account( - &mut context.banks_client, - &source_validator_stake.stake_account, - ) - .await; - let validator_stake_state = - deserialize::(&validator_stake_account.data).unwrap(); - assert_eq!( - pre_validator_stake_account.lamports - redelegate_lamports, - validator_stake_account.lamports - ); - assert_eq!( - validator_stake_state - .delegation() - .unwrap() - .deactivation_epoch, - Epoch::MAX - ); - - // Check source transient stake account state and balance - let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); - - let source_transient_stake_account = get_account( - &mut context.banks_client, - &source_validator_stake.transient_stake_account, - ) - .await; - let transient_stake_state = - deserialize::(&source_transient_stake_account.data).unwrap(); - assert_eq!(source_transient_stake_account.lamports, stake_rent); - let transient_delegation = transient_stake_state.delegation().unwrap(); - assert_ne!(transient_delegation.deactivation_epoch, Epoch::MAX); - assert_eq!(transient_delegation.stake, redelegate_lamports); - - // Check reserve stake - let current_minimum_delegation = stake_pool_get_minimum_delegation( - &mut context.banks_client, - &context.payer, - &last_blockhash, - ) - .await; - let reserve_lamports = MINIMUM_RESERVE_LAMPORTS + current_minimum_delegation + stake_rent * 2; - let reserve_stake_account = get_account( - &mut context.banks_client, - &stake_pool_accounts.reserve_stake.pubkey(), - ) - .await; - assert_eq!(reserve_stake_account.lamports, reserve_lamports); - - // Check ephemeral account doesn't exist - let maybe_account = context - .banks_client - .get_account(ephemeral_stake) - .await - .unwrap(); - assert!(maybe_account.is_none()); - - // Check destination transient stake account - let destination_transient_stake_account = get_account( - &mut context.banks_client, - &destination_validator_stake.transient_stake_account, - ) - .await; - let transient_stake_state = - deserialize::(&destination_transient_stake_account.data) - .unwrap(); - assert_eq!( - destination_transient_stake_account.lamports, - redelegate_lamports - ); - let transient_delegation = transient_stake_state.delegation().unwrap(); - assert_eq!(transient_delegation.deactivation_epoch, Epoch::MAX); - assert_ne!(transient_delegation.activation_epoch, Epoch::MAX); - assert_eq!(transient_delegation.stake, redelegate_lamports - stake_rent); - - // Check validator list - let validator_list = stake_pool_accounts - .get_validator_list(&mut context.banks_client) - .await; - let source_item = validator_list - .find(&source_validator_stake.vote.pubkey()) - .unwrap(); - assert_eq!( - u64::from(source_item.active_stake_lamports), - validator_stake_account.lamports - ); - assert_eq!( - u64::from(source_item.transient_stake_lamports), - source_transient_stake_account.lamports - ); - assert_eq!( - u64::from(source_item.transient_seed_suffix), - source_validator_stake.transient_stake_seed - ); - - let destination_item = validator_list - .find(&destination_validator_stake.vote.pubkey()) - .unwrap(); - assert_eq!( - u64::from(destination_item.transient_stake_lamports), - destination_transient_stake_account.lamports - ); - assert_eq!( - u64::from(destination_item.transient_seed_suffix), - destination_validator_stake.transient_stake_seed - ); - - // Warp forward and merge all - let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; - slot += slots_per_epoch; - context.warp_to_slot(slot).unwrap(); - stake_pool_accounts - .update_all( - &mut context.banks_client, - &context.payer, - &last_blockhash, - false, - ) - .await; - - // Check transient accounts are gone - let maybe_account = context - .banks_client - .get_account(destination_validator_stake.transient_stake_account) - .await - .unwrap(); - assert!(maybe_account.is_none()); - let maybe_account = context - .banks_client - .get_account(source_validator_stake.transient_stake_account) - .await - .unwrap(); - assert!(maybe_account.is_none()); - - // Check validator list - let validator_list = stake_pool_accounts - .get_validator_list(&mut context.banks_client) - .await; - let source_item = validator_list - .find(&source_validator_stake.vote.pubkey()) - .unwrap(); - assert_eq!( - u64::from(source_item.active_stake_lamports), - validator_stake_account.lamports - ); - assert_eq!(u64::from(source_item.transient_stake_lamports), 0); - - let destination_item = validator_list - .find(&destination_validator_stake.vote.pubkey()) - .unwrap(); - assert_eq!(u64::from(destination_item.transient_stake_lamports), 0); - assert_eq!( - u64::from(destination_item.active_stake_lamports), - pre_destination_validator_stake_account.lamports + redelegate_lamports - stake_rent - ); - let post_destination_validator_stake_account = get_account( - &mut context.banks_client, - &destination_validator_stake.stake_account, - ) - .await; - assert_eq!( - post_destination_validator_stake_account.lamports, - pre_destination_validator_stake_account.lamports + redelegate_lamports - stake_rent - ); - - // Check reserve stake, which has claimed back all rent-exempt reserves - let reserve_stake_account = get_account( - &mut context.banks_client, - &stake_pool_accounts.reserve_stake.pubkey(), - ) - .await; - assert_eq!( - reserve_stake_account.lamports, - reserve_lamports + stake_rent * 2 - ); -} - -#[tokio::test] -async fn success_with_increasing_stake() { - let ( - mut context, - last_blockhash, - stake_pool_accounts, - source_validator_stake, - destination_validator_stake, - redelegate_lamports, - mut slot, - ) = setup(true).await; - - // Save validator stake - let pre_validator_stake_account = get_account( - &mut context.banks_client, - &destination_validator_stake.stake_account, - ) - .await; - - let current_minimum_delegation = stake_pool_get_minimum_delegation( - &mut context.banks_client, - &context.payer, - &last_blockhash, - ) - .await; - let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); - - let error = stake_pool_accounts - .increase_validator_stake( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &destination_validator_stake.transient_stake_account, - &destination_validator_stake.stake_account, - &destination_validator_stake.vote.pubkey(), - current_minimum_delegation, - destination_validator_stake.transient_stake_seed, - ) - .await; - assert!(error.is_none(), "{:?}", error); - - let validator_list = stake_pool_accounts - .get_validator_list(&mut context.banks_client) - .await; - let destination_item = validator_list - .find(&destination_validator_stake.vote.pubkey()) - .unwrap(); - assert_eq!( - u64::from(destination_item.transient_stake_lamports), - current_minimum_delegation + stake_rent - ); - let pre_transient_stake_account = get_account( - &mut context.banks_client, - &destination_validator_stake.transient_stake_account, - ) - .await; - assert_eq!( - pre_transient_stake_account.lamports, - current_minimum_delegation + stake_rent - ); - - let ephemeral_stake_seed = 10; - let ephemeral_stake = find_ephemeral_stake_program_address( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - ephemeral_stake_seed, - ) - .0; - - // fail with incorrect transient stake derivation - let wrong_transient_stake_seed = destination_validator_stake - .transient_stake_seed - .wrapping_add(1); - let (wrong_transient_stake_account, _) = find_transient_stake_program_address( - &id(), - &destination_validator_stake.vote.pubkey(), - &stake_pool_accounts.stake_pool.pubkey(), - wrong_transient_stake_seed, - ); - let error = stake_pool_accounts - .redelegate( - &mut context.banks_client, - &context.payer, - &last_blockhash, - &source_validator_stake.stake_account, - &source_validator_stake.transient_stake_account, - &ephemeral_stake, - &wrong_transient_stake_account, - &destination_validator_stake.stake_account, - &destination_validator_stake.vote.pubkey(), - redelegate_lamports, - source_validator_stake.transient_stake_seed, - ephemeral_stake_seed, - wrong_transient_stake_seed, - ) - .await - .unwrap() - .unwrap(); - assert_eq!( - error, - TransactionError::InstructionError( - 0, - InstructionError::Custom(StakePoolError::InvalidStakeAccountAddress as u32) - ) - ); - - let last_blockhash = context - .banks_client - .get_new_latest_blockhash(&context.last_blockhash) - .await - .unwrap(); - - let error = stake_pool_accounts - .redelegate( - &mut context.banks_client, - &context.payer, - &last_blockhash, - &source_validator_stake.stake_account, - &source_validator_stake.transient_stake_account, - &ephemeral_stake, - &destination_validator_stake.transient_stake_account, - &destination_validator_stake.stake_account, - &destination_validator_stake.vote.pubkey(), - redelegate_lamports, - source_validator_stake.transient_stake_seed, - ephemeral_stake_seed, - destination_validator_stake.transient_stake_seed, - ) - .await; - assert!(error.is_none(), "{:?}", error); - - // Check destination transient stake account - let destination_transient_stake_account = get_account( - &mut context.banks_client, - &destination_validator_stake.transient_stake_account, - ) - .await; - let transient_stake_state = - deserialize::(&destination_transient_stake_account.data) - .unwrap(); - assert_eq!( - destination_transient_stake_account.lamports, - redelegate_lamports + current_minimum_delegation + stake_rent - ); - - let transient_delegation = transient_stake_state.delegation().unwrap(); - assert_eq!(transient_delegation.deactivation_epoch, Epoch::MAX); - assert_ne!(transient_delegation.activation_epoch, Epoch::MAX); - assert_eq!( - transient_delegation.stake, - redelegate_lamports + current_minimum_delegation - ); - - // Check reserve stake - let reserve_stake_account = get_account( - &mut context.banks_client, - &stake_pool_accounts.reserve_stake.pubkey(), - ) - .await; - assert_eq!(reserve_stake_account.lamports, stake_rent); - - // Check validator list - let validator_list = stake_pool_accounts - .get_validator_list(&mut context.banks_client) - .await; - let destination_item = validator_list - .find(&destination_validator_stake.vote.pubkey()) - .unwrap(); - assert_eq!( - u64::from(destination_item.transient_stake_lamports), - destination_transient_stake_account.lamports - ); - assert_eq!( - u64::from(destination_item.transient_seed_suffix), - destination_validator_stake.transient_stake_seed - ); - - // Warp forward and merge all - let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch; - slot += slots_per_epoch; - context.warp_to_slot(slot).unwrap(); - stake_pool_accounts - .update_all( - &mut context.banks_client, - &context.payer, - &last_blockhash, - false, - ) - .await; - - // Check transient account is gone - let maybe_account = context - .banks_client - .get_account(destination_validator_stake.transient_stake_account) - .await - .unwrap(); - assert!(maybe_account.is_none()); - - // Check validator list - let validator_list = stake_pool_accounts - .get_validator_list(&mut context.banks_client) - .await; - let destination_item = validator_list - .find(&destination_validator_stake.vote.pubkey()) - .unwrap(); - assert_eq!(u64::from(destination_item.transient_stake_lamports), 0); - // redelegate is smart enough to activate *everything*, so there's no - // rent-exemption worth of inactive stake! - assert_eq!( - u64::from(destination_item.active_stake_lamports), - pre_validator_stake_account.lamports + redelegate_lamports + current_minimum_delegation - ); - let post_validator_stake_account = get_account( - &mut context.banks_client, - &destination_validator_stake.stake_account, - ) - .await; - assert_eq!( - post_validator_stake_account.lamports, - pre_validator_stake_account.lamports + redelegate_lamports + current_minimum_delegation - ); - - // Check reserve has claimed back rent-exempt reserve from both transient - // accounts - let reserve_stake_account = get_account( - &mut context.banks_client, - &stake_pool_accounts.reserve_stake.pubkey(), - ) - .await; - assert_eq!(reserve_stake_account.lamports, stake_rent * 3); -} - -#[tokio::test] -async fn fail_with_decreasing_stake() { - let ( - mut context, - last_blockhash, - stake_pool_accounts, - source_validator_stake, - destination_validator_stake, - redelegate_lamports, - mut slot, - ) = setup(false).await; - - let current_minimum_delegation = stake_pool_get_minimum_delegation( - &mut context.banks_client, - &context.payer, - &last_blockhash, - ) - .await; - let rent = context.banks_client.get_rent().await.unwrap(); - let stake_rent = rent.minimum_balance(std::mem::size_of::()); - let minimum_decrease_lamports = current_minimum_delegation + stake_rent; - - simple_deposit_stake( - &mut context.banks_client, - &context.payer, - &last_blockhash, - &stake_pool_accounts, - &destination_validator_stake, - redelegate_lamports, - ) - .await - .unwrap(); - - slot += context.genesis_config().epoch_schedule.first_normal_slot; - context.warp_to_slot(slot).unwrap(); - stake_pool_accounts - .update_all( - &mut context.banks_client, - &context.payer, - &last_blockhash, - false, - ) - .await; - - let last_blockhash = context - .banks_client - .get_new_latest_blockhash(&last_blockhash) - .await - .unwrap(); - - let error = stake_pool_accounts - .decrease_validator_stake_either( - &mut context.banks_client, - &context.payer, - &context.last_blockhash, - &destination_validator_stake.stake_account, - &destination_validator_stake.transient_stake_account, - minimum_decrease_lamports, - destination_validator_stake.transient_stake_seed, - DecreaseInstruction::Reserve, - ) - .await; - assert!(error.is_none(), "{:?}", error); - - let ephemeral_stake_seed = 20; - let ephemeral_stake = find_ephemeral_stake_program_address( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - ephemeral_stake_seed, - ) - .0; - - let error = stake_pool_accounts - .redelegate( - &mut context.banks_client, - &context.payer, - &last_blockhash, - &source_validator_stake.stake_account, - &source_validator_stake.transient_stake_account, - &ephemeral_stake, - &destination_validator_stake.transient_stake_account, - &destination_validator_stake.stake_account, - &destination_validator_stake.vote.pubkey(), - redelegate_lamports, - source_validator_stake.transient_stake_seed, - ephemeral_stake_seed, - destination_validator_stake.transient_stake_seed, - ) - .await - .unwrap() - .unwrap(); - assert_eq!( - error, - TransactionError::InstructionError( - 0, - InstructionError::Custom(StakePoolError::WrongStakeStake as u32) - ) - ); -} - -#[tokio::test] -async fn fail_with_wrong_withdraw_authority() { - let ( - mut context, - last_blockhash, - stake_pool_accounts, - source_validator_stake, - destination_validator_stake, - redelegate_lamports, - _, - ) = setup(true).await; - - let ephemeral_stake_seed = 2; - let ephemeral_stake = find_ephemeral_stake_program_address( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - ephemeral_stake_seed, - ) - .0; - - let wrong_withdraw_authority = Pubkey::new_unique(); - let transaction = Transaction::new_signed_with_payer( - &[instruction::redelegate( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.staker.pubkey(), - &wrong_withdraw_authority, - &stake_pool_accounts.validator_list.pubkey(), - &stake_pool_accounts.reserve_stake.pubkey(), - &source_validator_stake.stake_account, - &source_validator_stake.transient_stake_account, - &ephemeral_stake, - &destination_validator_stake.transient_stake_account, - &destination_validator_stake.stake_account, - &destination_validator_stake.vote.pubkey(), - redelegate_lamports, - source_validator_stake.transient_stake_seed, - ephemeral_stake_seed, - destination_validator_stake.transient_stake_seed, - )], - Some(&context.payer.pubkey()), - &[&context.payer, &stake_pool_accounts.staker], - last_blockhash, - ); - let error = context - .banks_client - .process_transaction(transaction) - .await - .err() - .unwrap() - .unwrap(); - - assert_eq!( - error, - TransactionError::InstructionError( - 0, - InstructionError::Custom(StakePoolError::InvalidProgramAddress as u32) - ) - ); -} - -#[tokio::test] -async fn fail_with_wrong_validator_list() { - let ( - mut context, - last_blockhash, - stake_pool_accounts, - source_validator_stake, - destination_validator_stake, - redelegate_lamports, - _, - ) = setup(true).await; - - let ephemeral_stake_seed = 2; - let ephemeral_stake = find_ephemeral_stake_program_address( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - ephemeral_stake_seed, - ) - .0; - - let wrong_validator_list = Pubkey::new_unique(); - let transaction = Transaction::new_signed_with_payer( - &[instruction::redelegate( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.staker.pubkey(), - &stake_pool_accounts.withdraw_authority, - &wrong_validator_list, - &stake_pool_accounts.reserve_stake.pubkey(), - &source_validator_stake.stake_account, - &source_validator_stake.transient_stake_account, - &ephemeral_stake, - &destination_validator_stake.transient_stake_account, - &destination_validator_stake.stake_account, - &destination_validator_stake.vote.pubkey(), - redelegate_lamports, - source_validator_stake.transient_stake_seed, - ephemeral_stake_seed, - destination_validator_stake.transient_stake_seed, - )], - Some(&context.payer.pubkey()), - &[&context.payer, &stake_pool_accounts.staker], - last_blockhash, - ); - let error = context - .banks_client - .process_transaction(transaction) - .await - .err() - .unwrap() - .unwrap(); - - assert_eq!( - error, - TransactionError::InstructionError( - 0, - InstructionError::Custom(StakePoolError::InvalidValidatorStakeList as u32) - ) - ); -} - -#[tokio::test] -async fn fail_with_wrong_reserve() { - let ( - mut context, - last_blockhash, - stake_pool_accounts, - source_validator_stake, - destination_validator_stake, - redelegate_lamports, - _, - ) = setup(true).await; - - let ephemeral_stake_seed = 2; - let ephemeral_stake = find_ephemeral_stake_program_address( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - ephemeral_stake_seed, - ) - .0; - - let wrong_reserve = Keypair::new(); - let transaction = Transaction::new_signed_with_payer( - &[instruction::redelegate( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &stake_pool_accounts.staker.pubkey(), - &stake_pool_accounts.withdraw_authority, - &stake_pool_accounts.validator_list.pubkey(), - &wrong_reserve.pubkey(), - &source_validator_stake.stake_account, - &source_validator_stake.transient_stake_account, - &ephemeral_stake, - &destination_validator_stake.transient_stake_account, - &destination_validator_stake.stake_account, - &destination_validator_stake.vote.pubkey(), - redelegate_lamports, - source_validator_stake.transient_stake_seed, - ephemeral_stake_seed, - destination_validator_stake.transient_stake_seed, - )], - Some(&context.payer.pubkey()), - &[&context.payer, &stake_pool_accounts.staker], - last_blockhash, - ); - let error = context - .banks_client - .process_transaction(transaction) - .await - .err() - .unwrap() - .unwrap(); - - assert_eq!( - error, - TransactionError::InstructionError( - 0, - InstructionError::Custom(StakePoolError::InvalidProgramAddress as u32) - ) - ); -} - -#[tokio::test] -async fn fail_with_wrong_staker() { - let ( - mut context, - last_blockhash, - stake_pool_accounts, - source_validator_stake, - destination_validator_stake, - redelegate_lamports, - _, - ) = setup(true).await; - - let ephemeral_stake_seed = 2; - let ephemeral_stake = find_ephemeral_stake_program_address( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - ephemeral_stake_seed, - ) - .0; - - let wrong_staker = Keypair::new(); - let transaction = Transaction::new_signed_with_payer( - &[instruction::redelegate( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - &wrong_staker.pubkey(), - &stake_pool_accounts.withdraw_authority, - &stake_pool_accounts.validator_list.pubkey(), - &stake_pool_accounts.reserve_stake.pubkey(), - &source_validator_stake.stake_account, - &source_validator_stake.transient_stake_account, - &ephemeral_stake, - &destination_validator_stake.transient_stake_account, - &destination_validator_stake.stake_account, - &destination_validator_stake.vote.pubkey(), - redelegate_lamports, - source_validator_stake.transient_stake_seed, - ephemeral_stake_seed, - destination_validator_stake.transient_stake_seed, - )], - Some(&context.payer.pubkey()), - &[&context.payer, &wrong_staker], - last_blockhash, - ); - let error = context - .banks_client - .process_transaction(transaction) - .await - .err() - .unwrap() - .unwrap(); - - assert_eq!( - error, - TransactionError::InstructionError( - 0, - InstructionError::Custom(StakePoolError::WrongStaker as u32) - ) - ); -} - -#[tokio::test] -async fn fail_with_unknown_validator() { - let ( - mut context, - last_blockhash, - stake_pool_accounts, - source_validator_stake, - destination_validator_stake, - redelegate_lamports, - _, - ) = setup(true).await; - - let unknown_validator_stake = create_unknown_validator_stake( - &mut context.banks_client, - &context.payer, - &last_blockhash, - &stake_pool_accounts.stake_pool.pubkey(), - redelegate_lamports, - ) - .await; - - let ephemeral_stake_seed = 42; - let ephemeral_stake = find_ephemeral_stake_program_address( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - ephemeral_stake_seed, - ) - .0; - let error = stake_pool_accounts - .redelegate( - &mut context.banks_client, - &context.payer, - &last_blockhash, - &source_validator_stake.stake_account, - &source_validator_stake.transient_stake_account, - &ephemeral_stake, - &unknown_validator_stake.transient_stake_account, - &unknown_validator_stake.stake_account, - &unknown_validator_stake.vote.pubkey(), - redelegate_lamports, - source_validator_stake.transient_stake_seed, - ephemeral_stake_seed, - unknown_validator_stake.transient_stake_seed, - ) - .await - .unwrap() - .unwrap(); - assert_eq!( - error, - TransactionError::InstructionError( - 0, - InstructionError::Custom(StakePoolError::ValidatorNotFound as u32) - ) - ); - - let error = stake_pool_accounts - .redelegate( - &mut context.banks_client, - &context.payer, - &last_blockhash, - &unknown_validator_stake.stake_account, - &unknown_validator_stake.transient_stake_account, - &ephemeral_stake, - &destination_validator_stake.transient_stake_account, - &destination_validator_stake.stake_account, - &destination_validator_stake.vote.pubkey(), - redelegate_lamports, - unknown_validator_stake.transient_stake_seed, - ephemeral_stake_seed, - destination_validator_stake.transient_stake_seed, - ) - .await - .unwrap() - .unwrap(); - assert_eq!( - error, - TransactionError::InstructionError( - 0, - InstructionError::Custom(StakePoolError::ValidatorNotFound as u32) - ) - ); -} - -#[tokio::test] -async fn fail_redelegate_twice() { - let ( - mut context, - last_blockhash, - stake_pool_accounts, - source_validator_stake, - destination_validator_stake, - redelegate_lamports, - mut slot, - ) = setup(false).await; - - simple_deposit_stake( - &mut context.banks_client, - &context.payer, - &last_blockhash, - &stake_pool_accounts, - &source_validator_stake, - redelegate_lamports, - ) - .await - .unwrap(); - - slot += context.genesis_config().epoch_schedule.first_normal_slot; - context.warp_to_slot(slot).unwrap(); - stake_pool_accounts - .update_all( - &mut context.banks_client, - &context.payer, - &last_blockhash, - false, - ) - .await; - - let last_blockhash = context - .banks_client - .get_new_latest_blockhash(&last_blockhash) - .await - .unwrap(); - - let ephemeral_stake_seed = 100; - let ephemeral_stake = find_ephemeral_stake_program_address( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - ephemeral_stake_seed, - ) - .0; - let error = stake_pool_accounts - .redelegate( - &mut context.banks_client, - &context.payer, - &last_blockhash, - &source_validator_stake.stake_account, - &source_validator_stake.transient_stake_account, - &ephemeral_stake, - &destination_validator_stake.transient_stake_account, - &destination_validator_stake.stake_account, - &destination_validator_stake.vote.pubkey(), - redelegate_lamports, - source_validator_stake.transient_stake_seed, - ephemeral_stake_seed, - destination_validator_stake.transient_stake_seed, - ) - .await; - assert!(error.is_none(), "{:?}", error); - - let last_blockhash = context - .banks_client - .get_new_latest_blockhash(&last_blockhash) - .await - .unwrap(); - - let error = stake_pool_accounts - .redelegate( - &mut context.banks_client, - &context.payer, - &last_blockhash, - &source_validator_stake.stake_account, - &source_validator_stake.transient_stake_account, - &ephemeral_stake, - &destination_validator_stake.transient_stake_account, - &destination_validator_stake.stake_account, - &destination_validator_stake.vote.pubkey(), - redelegate_lamports, - source_validator_stake.transient_stake_seed, - ephemeral_stake_seed, - destination_validator_stake.transient_stake_seed, - ) - .await - .unwrap() - .unwrap(); - assert_eq!( - error, - TransactionError::InstructionError( - 0, - InstructionError::Custom(StakePoolError::TransientAccountInUse as u32) - ) - ); -} - -#[tokio::test] -async fn fail_with_small_lamport_amount() { - let ( - mut context, - last_blockhash, - stake_pool_accounts, - source_validator_stake, - destination_validator_stake, - redelegate_lamports, - _, - ) = setup(true).await; - - let ephemeral_stake_seed = 7_000; - let ephemeral_stake = find_ephemeral_stake_program_address( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - ephemeral_stake_seed, - ) - .0; - - let error = stake_pool_accounts - .redelegate( - &mut context.banks_client, - &context.payer, - &last_blockhash, - &source_validator_stake.stake_account, - &source_validator_stake.transient_stake_account, - &ephemeral_stake, - &destination_validator_stake.transient_stake_account, - &destination_validator_stake.stake_account, - &destination_validator_stake.vote.pubkey(), - redelegate_lamports - 1, - source_validator_stake.transient_stake_seed, - ephemeral_stake_seed, - destination_validator_stake.transient_stake_seed, - ) - .await - .unwrap() - .unwrap(); - assert_eq!( - error, - TransactionError::InstructionError( - 0, - InstructionError::Custom(StakeError::InsufficientDelegation as u32) - ) - ); -} - -#[tokio::test] -async fn fail_drain_source_account() { - let ( - mut context, - last_blockhash, - stake_pool_accounts, - source_validator_stake, - destination_validator_stake, - _, - _, - ) = setup(true).await; - - let validator_stake_account = get_account( - &mut context.banks_client, - &source_validator_stake.stake_account, - ) - .await; - - let ephemeral_stake_seed = 2; - let ephemeral_stake = find_ephemeral_stake_program_address( - &id(), - &stake_pool_accounts.stake_pool.pubkey(), - ephemeral_stake_seed, - ) - .0; - - let error = stake_pool_accounts - .redelegate( - &mut context.banks_client, - &context.payer, - &last_blockhash, - &source_validator_stake.stake_account, - &source_validator_stake.transient_stake_account, - &ephemeral_stake, - &destination_validator_stake.transient_stake_account, - &destination_validator_stake.stake_account, - &destination_validator_stake.vote.pubkey(), - validator_stake_account.lamports, - source_validator_stake.transient_stake_seed, - ephemeral_stake_seed, - destination_validator_stake.transient_stake_seed, - ) - .await - .unwrap() - .unwrap(); - assert_eq!( - error, - TransactionError::InstructionError(0, InstructionError::InsufficientFunds) - ); -} From 29b2c5bdf30919f6526c7aedb8b74020cc989f8a Mon Sep 17 00:00:00 2001 From: Gabriel Hicks <60371583+gabrielhicks@users.noreply.github.com> Date: Mon, 29 Jul 2024 10:52:19 -0500 Subject: [PATCH 0937/1076] stake-pool: CLI QOL improvements (#7051) * feat(add): step through checks for stake-pool cli when creating pool * Implement nits and suggestions * Remove comments * Fix clippy, resolve last comment for stake pool data check --- clients/cli/src/main.rs | 453 ++++++++++++++++++++++++++++------------ 1 file changed, 323 insertions(+), 130 deletions(-) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index 3c8e4af5..a777d8f6 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -2,9 +2,6 @@ mod client; mod output; -// use instruction::create_associated_token_account once ATA 1.0.5 is released -#[allow(deprecated)] -use spl_associated_token_account::create_associated_token_account; use { crate::{ client::*, @@ -46,7 +43,9 @@ use { system_instruction, transaction::Transaction, }, - spl_associated_token_account::get_associated_token_address, + spl_associated_token_account::{ + get_associated_token_address, instruction::create_associated_token_account, + }, spl_stake_pool::{ self, find_stake_program_address, find_transient_stake_program_address, find_withdraw_authority_program_address, @@ -298,6 +297,290 @@ fn new_stake_account( stake_receiver_keypair } +fn setup_reserve_stake_account( + config: &Config, + reserve_keypair: &Keypair, + reserve_stake_balance: u64, + withdraw_authority: &Pubkey, +) -> CommandResult { + let reserve_account_info = config.rpc_client.get_account(&reserve_keypair.pubkey()); + if let Ok(account) = reserve_account_info { + if account.owner == stake::program::id() { + if account.data.iter().any(|&x| x != 0) { + println!( + "Reserve stake account {} already exists and is initialized", + reserve_keypair.pubkey() + ); + return Ok(()); + } else { + let instructions = vec![stake::instruction::initialize( + &reserve_keypair.pubkey(), + &stake::state::Authorized { + staker: *withdraw_authority, + withdrawer: *withdraw_authority, + }, + &stake::state::Lockup::default(), + )]; + let signers = vec![config.fee_payer.as_ref()]; + let transaction = + checked_transaction_with_signers(config, &instructions, &signers)?; + println!( + "Initializing existing reserve stake account {}", + reserve_keypair.pubkey() + ); + send_transaction(config, transaction)?; + return Ok(()); + } + } + } + + let instructions = vec![ + system_instruction::create_account( + &config.fee_payer.pubkey(), + &reserve_keypair.pubkey(), + reserve_stake_balance, + STAKE_STATE_LEN as u64, + &stake::program::id(), + ), + stake::instruction::initialize( + &reserve_keypair.pubkey(), + &stake::state::Authorized { + staker: *withdraw_authority, + withdrawer: *withdraw_authority, + }, + &stake::state::Lockup::default(), + ), + ]; + + let signers = vec![config.fee_payer.as_ref(), reserve_keypair]; + let transaction = checked_transaction_with_signers(config, &instructions, &signers)?; + + println!( + "Creating and initializing reserve stake account {}", + reserve_keypair.pubkey() + ); + send_transaction(config, transaction)?; + Ok(()) +} + +fn setup_mint_account( + config: &Config, + mint_keypair: &Keypair, + mint_account_balance: u64, + withdraw_authority: &Pubkey, + default_decimals: u8, +) -> CommandResult { + let mint_account_info = config.rpc_client.get_account(&mint_keypair.pubkey()); + if let Ok(account) = mint_account_info { + if account.owner == spl_token::id() { + if account.data.iter().any(|&x| x != 0) { + println!( + "Mint account {} already exists and is initialized", + mint_keypair.pubkey() + ); + return Ok(()); + } else { + let instructions = vec![spl_token::instruction::initialize_mint( + &spl_token::id(), + &mint_keypair.pubkey(), + withdraw_authority, + None, + default_decimals, + )?]; + let signers = vec![config.fee_payer.as_ref()]; + let transaction = + checked_transaction_with_signers(config, &instructions, &signers)?; + println!( + "Initializing existing mint account {}", + mint_keypair.pubkey() + ); + send_transaction(config, transaction)?; + return Ok(()); + } + } + } + + let instructions = vec![ + system_instruction::create_account( + &config.fee_payer.pubkey(), + &mint_keypair.pubkey(), + mint_account_balance, + spl_token::state::Mint::LEN as u64, + &spl_token::id(), + ), + spl_token::instruction::initialize_mint( + &spl_token::id(), + &mint_keypair.pubkey(), + withdraw_authority, + None, + default_decimals, + )?, + ]; + + let signers = vec![config.fee_payer.as_ref(), mint_keypair]; + let transaction = checked_transaction_with_signers(config, &instructions, &signers)?; + + println!( + "Creating and initializing mint account {}", + mint_keypair.pubkey() + ); + send_transaction(config, transaction)?; + Ok(()) +} + +fn setup_pool_fee_account( + config: &Config, + mint_pubkey: &Pubkey, + total_rent_free_balances: &mut u64, +) -> CommandResult { + let pool_fee_account = get_associated_token_address(&config.manager.pubkey(), mint_pubkey); + let pool_fee_account_info = config.rpc_client.get_account(&pool_fee_account); + if let Ok(account) = pool_fee_account_info { + if account.owner == spl_token::id() { + println!("Pool fee account {} already exists", pool_fee_account); + return Ok(()); + } + } + // Create pool fee account + let mut instructions = vec![]; + add_associated_token_account( + config, + mint_pubkey, + &config.manager.pubkey(), + &mut instructions, + total_rent_free_balances, + ); + + println!("Creating pool fee collection account {}", pool_fee_account); + + let signers = vec![config.fee_payer.as_ref()]; + let transaction = checked_transaction_with_signers(config, &instructions, &signers)?; + + send_transaction(config, transaction)?; + Ok(()) +} + +#[allow(clippy::too_many_arguments)] +fn setup_and_initialize_validator_list_with_stake_pool( + config: &Config, + stake_pool_keypair: &Keypair, + validator_list_keypair: &Keypair, + reserve_keypair: &Keypair, + mint_keypair: &Keypair, + pool_fee_account: &Pubkey, + deposit_authority: Option, + epoch_fee: Fee, + withdrawal_fee: Fee, + deposit_fee: Fee, + referral_fee: u8, + max_validators: u32, + withdraw_authority: &Pubkey, + validator_list_balance: u64, + validator_list_size: usize, +) -> CommandResult { + let stake_pool_account_info = config.rpc_client.get_account(&stake_pool_keypair.pubkey()); + let validator_list_account_info = config + .rpc_client + .get_account(&validator_list_keypair.pubkey()); + + let stake_pool_account_lamports = config + .rpc_client + .get_minimum_balance_for_rent_exemption(get_packed_len::())?; + + let mut instructions = vec![]; + let mut signers = vec![config.fee_payer.as_ref(), config.manager.as_ref()]; + + if let Ok(account) = validator_list_account_info { + if account.owner == spl_stake_pool::id() { + if account.data.iter().all(|&x| x == 0) { + println!( + "Validator list account {} already exists and is ready to be initialized", + validator_list_keypair.pubkey() + ); + } else { + println!( + "Validator list account {} already exists and is initialized", + validator_list_keypair.pubkey() + ); + return Ok(()); + } + } + } else { + instructions.push(system_instruction::create_account( + &config.fee_payer.pubkey(), + &validator_list_keypair.pubkey(), + validator_list_balance, + validator_list_size as u64, + &spl_stake_pool::id(), + )); + signers.push(validator_list_keypair); + } + + if let Ok(account) = stake_pool_account_info { + if account.owner == spl_stake_pool::id() { + if account.data.iter().all(|&x| x == 0) { + println!( + "Stake pool account {} already exists but is not initialized", + stake_pool_keypair.pubkey() + ); + } else { + println!( + "Stake pool account {} already exists and is initialized", + stake_pool_keypair.pubkey() + ); + return Ok(()); + } + } + } else { + instructions.push(system_instruction::create_account( + &config.fee_payer.pubkey(), + &stake_pool_keypair.pubkey(), + stake_pool_account_lamports, + get_packed_len::() as u64, + &spl_stake_pool::id(), + )); + } + instructions.push(spl_stake_pool::instruction::initialize( + &spl_stake_pool::id(), + &stake_pool_keypair.pubkey(), + &config.manager.pubkey(), + &config.staker.pubkey(), + withdraw_authority, + &validator_list_keypair.pubkey(), + &reserve_keypair.pubkey(), + &mint_keypair.pubkey(), + pool_fee_account, + &spl_token::id(), + deposit_authority.as_ref().map(|x| x.pubkey()), + epoch_fee, + withdrawal_fee, + deposit_fee, + referral_fee, + max_validators, + )); + signers.push(stake_pool_keypair); + + if let Some(ref deposit_auth) = deposit_authority { + signers.push(deposit_auth); + println!( + "Deposits will be restricted to {} only, this can be changed using the set-funding-authority command.", + deposit_auth.pubkey() + ); + } + + unique_signers!(signers); + let transaction = checked_transaction_with_signers(config, &instructions, &signers)?; + + println!( + "Setting up and initializing stake pool account {} with validator list {}", + stake_pool_keypair.pubkey(), + validator_list_keypair.pubkey() + ); + send_transaction(config, transaction)?; + + Ok(()) +} + #[allow(clippy::too_many_arguments)] fn command_create_pool( config: &Config, @@ -316,14 +599,10 @@ fn command_create_pool( if !unsafe_fees { check_stake_pool_fees(&epoch_fee, &withdrawal_fee, &deposit_fee)?; } - let reserve_keypair = reserve_keypair.unwrap_or_else(Keypair::new); - println!("Creating reserve stake {}", reserve_keypair.pubkey()); + let reserve_keypair = reserve_keypair.unwrap_or_else(Keypair::new); let mint_keypair = mint_keypair.unwrap_or_else(Keypair::new); - println!("Creating mint {}", mint_keypair.pubkey()); - let stake_pool_keypair = stake_pool_keypair.unwrap_or_else(Keypair::new); - let validator_list_keypair = validator_list_keypair.unwrap_or_else(Keypair::new); let reserve_stake_balance = config @@ -362,131 +641,45 @@ fn command_create_pool( println!("Stake pool withdraw authority {}", withdraw_authority); } - let mut setup_instructions = vec![ - // Account for the stake pool reserve - system_instruction::create_account( - &config.fee_payer.pubkey(), - &reserve_keypair.pubkey(), - reserve_stake_balance, - STAKE_STATE_LEN as u64, - &stake::program::id(), - ), - stake::instruction::initialize( - &reserve_keypair.pubkey(), - &stake::state::Authorized { - staker: withdraw_authority, - withdrawer: withdraw_authority, - }, - &stake::state::Lockup::default(), - ), - // Account for the stake pool mint - system_instruction::create_account( - &config.fee_payer.pubkey(), - &mint_keypair.pubkey(), - mint_account_balance, - spl_token::state::Mint::LEN as u64, - &spl_token::id(), - ), - // Initialize pool token mint account - spl_token::instruction::initialize_mint( - &spl_token::id(), - &mint_keypair.pubkey(), - &withdraw_authority, - None, - default_decimals, - )?, - ]; - - let pool_fee_account = add_associated_token_account( + setup_reserve_stake_account( + config, + &reserve_keypair, + reserve_stake_balance, + &withdraw_authority, + )?; + setup_mint_account( + config, + &mint_keypair, + mint_account_balance, + &withdraw_authority, + default_decimals, + )?; + setup_pool_fee_account( config, &mint_keypair.pubkey(), - &config.manager.pubkey(), - &mut setup_instructions, &mut total_rent_free_balances, - ); - println!("Creating pool fee collection account {}", pool_fee_account); - - let initialize_instructions = &[ - // Validator stake account list storage - system_instruction::create_account( - &config.fee_payer.pubkey(), - &validator_list_keypair.pubkey(), - validator_list_balance, - validator_list_size as u64, - &spl_stake_pool::id(), - ), - // Account for the stake pool - system_instruction::create_account( - &config.fee_payer.pubkey(), - &stake_pool_keypair.pubkey(), - stake_pool_account_lamports, - get_packed_len::() as u64, - &spl_stake_pool::id(), - ), - // Initialize stake pool - spl_stake_pool::instruction::initialize( - &spl_stake_pool::id(), - &stake_pool_keypair.pubkey(), - &config.manager.pubkey(), - &config.staker.pubkey(), - &withdraw_authority, - &validator_list_keypair.pubkey(), - &reserve_keypair.pubkey(), - &mint_keypair.pubkey(), - &pool_fee_account, - &spl_token::id(), - deposit_authority.as_ref().map(|x| x.pubkey()), - epoch_fee, - withdrawal_fee, - deposit_fee, - referral_fee, - max_validators, - ), - ]; - - { - let mut setup_signers = vec![config.fee_payer.as_ref(), &mint_keypair, &reserve_keypair]; - unique_signers!(setup_signers); - - let setup_transaction = - checked_transaction_with_signers(config, &setup_instructions, &setup_signers)?; - - println!( - "Setting up required accounts for stake pool: reserve stake {} and mint {}", - reserve_keypair.pubkey(), - mint_keypair.pubkey() - ); - send_transaction(config, setup_transaction)?; - } + )?; - { - let mut initialize_signers = vec![ - config.fee_payer.as_ref(), - &stake_pool_keypair, - &validator_list_keypair, - config.manager.as_ref(), - ]; - let initialize_transaction = if let Some(deposit_authority) = deposit_authority { - println!( - "Deposits will be restricted to {} only, this can be changed using the set-funding-authority command.", - deposit_authority.pubkey() - ); - let mut initialize_signers = initialize_signers.clone(); - initialize_signers.push(&deposit_authority); - unique_signers!(initialize_signers); - checked_transaction_with_signers(config, initialize_instructions, &initialize_signers)? - } else { - unique_signers!(initialize_signers); - checked_transaction_with_signers(config, initialize_instructions, &initialize_signers)? - }; + let pool_fee_account = + get_associated_token_address(&config.manager.pubkey(), &mint_keypair.pubkey()); - println!( - "Creating stake pool {} with validator list {}", - stake_pool_keypair.pubkey(), - validator_list_keypair.pubkey() - ); - send_transaction(config, initialize_transaction)?; - } + setup_and_initialize_validator_list_with_stake_pool( + config, + &stake_pool_keypair, + &validator_list_keypair, + &reserve_keypair, + &mint_keypair, + &pool_fee_account, + deposit_authority, + epoch_fee, + withdrawal_fee, + deposit_fee, + referral_fee, + max_validators, + &withdraw_authority, + validator_list_balance, + validator_list_size, + )?; Ok(()) } @@ -775,11 +968,11 @@ fn add_associated_token_account( .get_minimum_balance_for_rent_exemption(spl_token::state::Account::LEN) .unwrap(); - #[allow(deprecated)] instructions.push(create_associated_token_account( &config.fee_payer.pubkey(), owner, mint, + &spl_token::id(), )); *rent_free_balances += min_account_balance; From 1987011ed3a83982a65d21e42fc793482d4b5d21 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jul 2024 18:25:30 +0200 Subject: [PATCH 0938/1076] build(deps): bump @solana/web3.js from 1.95.1 to 1.95.2 (#7068) * build(deps): bump @solana/web3.js from 1.95.1 to 1.95.2 Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.95.1 to 1.95.2. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.95.1...v1.95.2) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Do it right --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon C --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 064afa8c..7e791d4b 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -45,7 +45,7 @@ "dependencies": { "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "0.4.6", - "@solana/web3.js": "^1.95.1", + "@solana/web3.js": "^1.95.2", "bn.js": "^5.2.0", "buffer": "^6.0.3", "buffer-layout": "^1.2.2", From 7c33d9a5620fbd7786d9dd3c69cb9878d7f64a11 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Jul 2024 11:33:42 +0200 Subject: [PATCH 0939/1076] build(deps): bump num_enum from 0.7.2 to 0.7.3 (#7071) Bumps [num_enum](https://github.com/illicitonion/num_enum) from 0.7.2 to 0.7.3. - [Commits](https://github.com/illicitonion/num_enum/compare/0.7.2...0.7.3) --- updated-dependencies: - dependency-name: num_enum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 94b1be94..260ea90b 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -17,7 +17,7 @@ borsh = "1.5.1" bytemuck = "1.16" num-derive = "0.4" num-traits = "0.2" -num_enum = "0.7.2" +num_enum = "0.7.3" serde = "1.0.204" serde_derive = "1.0.103" solana-program = "2.0.3" From 752e62d232a532886773ae75efde106441799439 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Jul 2024 12:52:36 +0200 Subject: [PATCH 0940/1076] build(deps-dev): bump @typescript-eslint/parser from 7.17.0 to 7.18.0 (#7072) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.17.0 to 7.18.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.18.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 7e791d4b..a49c8145 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^22.0.0", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.17.0", - "@typescript-eslint/parser": "^7.17.0", + "@typescript-eslint/parser": "^7.18.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", From aad2214a8c37341b665c0b40fa57867fb2d92603 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Aug 2024 13:24:24 +0200 Subject: [PATCH 0941/1076] build(deps-dev): bump @types/node from 22.0.0 to 22.0.2 (#7088) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.0.0 to 22.0.2. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index a49c8145..59be6b90 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^22.0.0", + "@types/node": "^22.0.2", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.17.0", "@typescript-eslint/parser": "^7.18.0", From 7739e9f93699e168396c326c58a88445869fdac6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Aug 2024 13:24:52 +0200 Subject: [PATCH 0942/1076] build(deps-dev): bump ts-jest from 29.2.3 to 29.2.4 (#7094) Bumps [ts-jest](https://github.com/kulshekhar/ts-jest) from 29.2.3 to 29.2.4. - [Release notes](https://github.com/kulshekhar/ts-jest/releases) - [Changelog](https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md) - [Commits](https://github.com/kulshekhar/ts-jest/compare/v29.2.3...v29.2.4) --- updated-dependencies: - dependency-name: ts-jest dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 59be6b90..bfc3dea5 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -74,7 +74,7 @@ "rimraf": "^6.0.1", "rollup": "^4.19.1", "rollup-plugin-dts": "^6.1.1", - "ts-jest": "^29.2.3", + "ts-jest": "^29.2.4", "typescript": "^5.5.4" }, "jest": { From 188127e7f41149866879f9eeb7f9ef353a1f7e67 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Aug 2024 13:25:06 +0200 Subject: [PATCH 0943/1076] build(deps-dev): bump rollup from 4.19.1 to 4.19.2 (#7095) Bumps [rollup](https://github.com/rollup/rollup) from 4.19.1 to 4.19.2. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.19.1...v4.19.2) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index bfc3dea5..07bd2c1e 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.3.3", "rimraf": "^6.0.1", - "rollup": "^4.19.1", + "rollup": "^4.19.2", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.2.4", "typescript": "^5.5.4" From e6c8a623451f745493005a71f39913feeb0102f6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 2 Aug 2024 12:34:29 +0200 Subject: [PATCH 0944/1076] build(deps): bump serde_json from 1.0.121 to 1.0.122 (#7102) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.121 to 1.0.122. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.121...v1.0.122) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 3c6dd8e7..f1e47dc1 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ borsh = "1.5.1" clap = "2.33.3" serde = "1.0.204" serde_derive = "1.0.130" -serde_json = "1.0.121" +serde_json = "1.0.122" solana-account-decoder = "2.0.3" solana-clap-utils = "2.0.3" solana-cli-config = "2.0.3" From 4ab62950090d2d5020f535c419c29e69c22e304e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 2 Aug 2024 13:50:55 +0200 Subject: [PATCH 0945/1076] build(deps-dev): bump @types/node from 22.0.2 to 22.0.3 (#7103) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.0.2 to 22.0.3. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 07bd2c1e..b2bd71a0 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^22.0.2", + "@types/node": "^22.0.3", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.17.0", "@typescript-eslint/parser": "^7.18.0", From 1344ec42ac7a9fc531b3ad444233758cff8d66ba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Aug 2024 16:25:33 +0200 Subject: [PATCH 0946/1076] build(deps-dev): bump rollup from 4.19.2 to 4.20.0 (#7108) Bumps [rollup](https://github.com/rollup/rollup) from 4.19.2 to 4.20.0. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.19.2...v4.20.0) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index b2bd71a0..93e4ac19 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "jest": "^29.0.0", "prettier": "^3.3.3", "rimraf": "^6.0.1", - "rollup": "^4.19.2", + "rollup": "^4.20.0", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.2.4", "typescript": "^5.5.4" From ff272afef870f56c0522191fd3dec58466e04fd1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Aug 2024 16:25:57 +0200 Subject: [PATCH 0947/1076] build(deps-dev): bump @types/node from 22.0.3 to 22.1.0 (#7111) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.0.3 to 22.1.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 93e4ac19..ceb00685 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^22.0.3", + "@types/node": "^22.1.0", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.17.0", "@typescript-eslint/parser": "^7.18.0", From 1c52e10f42859b2a99ecb9eb77111fbd0bcf3af5 Mon Sep 17 00:00:00 2001 From: Jon C Date: Mon, 5 Aug 2024 23:52:55 +0200 Subject: [PATCH 0948/1076] pnpm: Use workspace-wide prettier configuration (#7115) #### Problem There are still prettier configurations for each JS package in the repo. #### Solution Create repo-wide `.prettierignore` and `.prettierrc` files --- clients/js-legacy/package.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index ceb00685..613a7bec 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -67,10 +67,7 @@ "@typescript-eslint/parser": "^7.18.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-prettier": "^5.2.1", "jest": "^29.0.0", - "prettier": "^3.3.3", "rimraf": "^6.0.1", "rollup": "^4.20.0", "rollup-plugin-dts": "^6.1.1", From 641b36f9666712e98ff272d29077c3e8ff0ad150 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 Aug 2024 12:11:42 +0200 Subject: [PATCH 0949/1076] build(deps): bump serde from 1.0.204 to 1.0.205 (#7124) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.204 to 1.0.205. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.204...v1.0.205) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index f1e47dc1..23b83407 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "2.0.0" [dependencies] borsh = "1.5.1" clap = "2.33.3" -serde = "1.0.204" +serde = "1.0.205" serde_derive = "1.0.130" serde_json = "1.0.122" solana-account-decoder = "2.0.3" diff --git a/program/Cargo.toml b/program/Cargo.toml index 260ea90b..6a658fe3 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,7 +18,7 @@ bytemuck = "1.16" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.3" -serde = "1.0.204" +serde = "1.0.205" serde_derive = "1.0.103" solana-program = "2.0.3" solana-security-txt = "1.1.1" From f7421fb7c2f0a34a10ee821eb7c081be52bb1c5a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 12:28:40 +0200 Subject: [PATCH 0950/1076] build(deps): bump serde from 1.0.205 to 1.0.206 (#7131) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.205 to 1.0.206. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.205...v1.0.206) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 23b83407..8ba3b86e 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "2.0.0" [dependencies] borsh = "1.5.1" clap = "2.33.3" -serde = "1.0.205" +serde = "1.0.206" serde_derive = "1.0.130" serde_json = "1.0.122" solana-account-decoder = "2.0.3" diff --git a/program/Cargo.toml b/program/Cargo.toml index 6a658fe3..c23d0036 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,7 +18,7 @@ bytemuck = "1.16" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.3" -serde = "1.0.205" +serde = "1.0.206" serde_derive = "1.0.103" solana-program = "2.0.3" solana-security-txt = "1.1.1" From f4c174d1370947198f9a71c83fb125ccb24ab65b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 12:28:56 +0200 Subject: [PATCH 0951/1076] build(deps-dev): bump @types/node from 22.1.0 to 22.2.0 (#7133) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.1.0 to 22.2.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 613a7bec..ff582ef0 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^22.1.0", + "@types/node": "^22.2.0", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.17.0", "@typescript-eslint/parser": "^7.18.0", From 72ff94f7675bfbfc4bae0644d35a4a510a66c7d5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 13:17:06 +0200 Subject: [PATCH 0952/1076] build(deps): bump serde_json from 1.0.122 to 1.0.124 (#7132) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.122 to 1.0.124. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.122...v1.0.124) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 8ba3b86e..77167eea 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ borsh = "1.5.1" clap = "2.33.3" serde = "1.0.206" serde_derive = "1.0.130" -serde_json = "1.0.122" +serde_json = "1.0.124" solana-account-decoder = "2.0.3" solana-clap-utils = "2.0.3" solana-cli-config = "2.0.3" From fb8ba290532d47ed52de81cfb7efd18d370357e6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Aug 2024 12:22:01 +0200 Subject: [PATCH 0953/1076] build(deps): bump serde from 1.0.206 to 1.0.207 (#7139) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.206 to 1.0.207. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.206...v1.0.207) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 77167eea..ba294580 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "2.0.0" [dependencies] borsh = "1.5.1" clap = "2.33.3" -serde = "1.0.206" +serde = "1.0.207" serde_derive = "1.0.130" serde_json = "1.0.124" solana-account-decoder = "2.0.3" diff --git a/program/Cargo.toml b/program/Cargo.toml index c23d0036..f3a3efb3 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,7 +18,7 @@ bytemuck = "1.16" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.3" -serde = "1.0.206" +serde = "1.0.207" serde_derive = "1.0.103" solana-program = "2.0.3" solana-security-txt = "1.1.1" From 5124f123da87ded95bdc368117f30f77f7d62791 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Aug 2024 13:31:53 +0200 Subject: [PATCH 0954/1076] build(deps-dev): bump @typescript-eslint/parser from 7.18.0 to 8.1.0 (#7140) * build(deps-dev): bump @typescript-eslint/parser from 7.18.0 to 8.1.0 Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.18.0 to 8.1.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.1.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Allow in one place --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon C --- clients/js-legacy/package.json | 2 +- clients/js-legacy/src/instructions.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index ff582ef0..b9fb4f5d 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^22.2.0", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^7.17.0", - "@typescript-eslint/parser": "^7.18.0", + "@typescript-eslint/parser": "^8.1.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", "jest": "^29.0.0", diff --git a/clients/js-legacy/src/instructions.ts b/clients/js-legacy/src/instructions.ts index e792dd12..eba2f149 100644 --- a/clients/js-legacy/src/instructions.ts +++ b/clients/js-legacy/src/instructions.ts @@ -90,6 +90,7 @@ export function tokenMetadataLayout( * @internal */ export const STAKE_POOL_INSTRUCTION_LAYOUTS: { + /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ [type in StakePoolInstructionType]: InstructionType; } = Object.freeze({ AddValidatorToPool: { From b2218dd7d0583db48d592f6f92f881293c19a378 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Aug 2024 14:57:30 +0200 Subject: [PATCH 0955/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 7.17.0 to 8.1.0 (#7141) * build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.17.0 to 8.1.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.1.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Fix all new lints * Trigger CI --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon C --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index b9fb4f5d..83f72c69 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.12", "@types/node": "^22.2.0", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^7.17.0", + "@typescript-eslint/eslint-plugin": "^8.1.0", "@typescript-eslint/parser": "^8.1.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", From 6c5dfae6d9d2fb4cdaa4b816f2d673fa5adb2d72 Mon Sep 17 00:00:00 2001 From: Hrushikesh Date: Tue, 13 Aug 2024 23:04:35 +0530 Subject: [PATCH 0956/1076] stake-pool: Add instruction creators that re-use existing seeds (#7129) * increase_additional_validator_stake_with_vote, decrease_additional_validator_stake_with_vote Signed-off-by: Hrushi20 * fix formatting issue * address review comments Signed-off-by: Hrushi20 --------- Signed-off-by: Hrushi20 --- program/src/instruction.rs | 56 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 5b370a93..9709bef0 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -1323,6 +1323,62 @@ pub fn decrease_validator_stake_with_vote( ) } +/// Create a `IncreaseAdditionalValidatorStake` instruction given an existing +/// stake pool, valiator list and vote account +pub fn increase_additional_validator_stake_with_list( + program_id: &Pubkey, + stake_pool: &StakePool, + validator_list: &ValidatorList, + stake_pool_address: &Pubkey, + vote_account_address: &Pubkey, + lamports: u64, + ephemeral_stake_seed: u64, +) -> Result { + let validator_info = validator_list + .find(vote_account_address) + .ok_or(ProgramError::InvalidInstructionData)?; + let transient_stake_seed = u64::from(validator_info.transient_seed_suffix); + let validator_stake_seed = NonZeroU32::new(validator_info.validator_seed_suffix.into()); + Ok(increase_additional_validator_stake_with_vote( + program_id, + stake_pool, + stake_pool_address, + vote_account_address, + lamports, + validator_stake_seed, + transient_stake_seed, + ephemeral_stake_seed, + )) +} + +/// Create a `DecreaseAdditionalValidatorStake` instruction given an existing +/// stake pool, valiator list and vote account +pub fn decrease_additional_validator_stake_with_list( + program_id: &Pubkey, + stake_pool: &StakePool, + validator_list: &ValidatorList, + stake_pool_address: &Pubkey, + vote_account_address: &Pubkey, + lamports: u64, + ephemeral_stake_seed: u64, +) -> Result { + let validator_info = validator_list + .find(vote_account_address) + .ok_or(ProgramError::InvalidInstructionData)?; + let transient_stake_seed = u64::from(validator_info.transient_seed_suffix); + let validator_stake_seed = NonZeroU32::new(validator_info.validator_seed_suffix.into()); + Ok(decrease_additional_validator_stake_with_vote( + program_id, + stake_pool, + stake_pool_address, + vote_account_address, + lamports, + validator_stake_seed, + transient_stake_seed, + ephemeral_stake_seed, + )) +} + /// Create a `DecreaseAdditionalValidatorStake` instruction given an existing /// stake pool and vote account pub fn decrease_additional_validator_stake_with_vote( From c9068dba08e44e8202e8816f3478c37c932bf08d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 18:24:17 -0400 Subject: [PATCH 0957/1076] build(deps-dev): bump @types/node from 22.2.0 to 22.3.0 (#7149) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.2.0 to 22.3.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 83f72c69..b11d6f03 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^22.2.0", + "@types/node": "^22.3.0", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^8.1.0", "@typescript-eslint/parser": "^8.1.0", From c59793af0ae97b296ff2f2871c57918eb26b6296 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Aug 2024 08:48:10 -0400 Subject: [PATCH 0958/1076] build(deps): bump serde_json from 1.0.124 to 1.0.125 (#7157) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.124 to 1.0.125. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.124...1.0.125) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index ba294580..3daf88ac 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ borsh = "1.5.1" clap = "2.33.3" serde = "1.0.207" serde_derive = "1.0.130" -serde_json = "1.0.124" +serde_json = "1.0.125" solana-account-decoder = "2.0.3" solana-clap-utils = "2.0.3" solana-cli-config = "2.0.3" From fbbfb6f72ada3bfad5236904f66402ed9689f9b4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Aug 2024 08:48:26 -0400 Subject: [PATCH 0959/1076] build(deps): bump bytemuck from 1.16.3 to 1.17.0 (#7159) Bumps [bytemuck](https://github.com/Lokathor/bytemuck) from 1.16.3 to 1.17.0. - [Changelog](https://github.com/Lokathor/bytemuck/blob/main/changelog.md) - [Commits](https://github.com/Lokathor/bytemuck/compare/v1.16.3...v1.17.0) --- updated-dependencies: - dependency-name: bytemuck dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index f3a3efb3..ac17a6b7 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -14,7 +14,7 @@ test-sbf = [] [dependencies] arrayref = "0.3.8" borsh = "1.5.1" -bytemuck = "1.16" +bytemuck = "1.17" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.3" From 52fd1d5a1a6f44913b1fd474a6cc182584a90080 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Aug 2024 10:22:10 -0400 Subject: [PATCH 0960/1076] build(deps): bump serde from 1.0.207 to 1.0.208 (#7158) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.207 to 1.0.208. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.207...v1.0.208) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 3daf88ac..1b2f2134 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "2.0.0" [dependencies] borsh = "1.5.1" clap = "2.33.3" -serde = "1.0.207" +serde = "1.0.208" serde_derive = "1.0.130" serde_json = "1.0.125" solana-account-decoder = "2.0.3" diff --git a/program/Cargo.toml b/program/Cargo.toml index ac17a6b7..2a1ff42e 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,7 +18,7 @@ bytemuck = "1.17" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.3" -serde = "1.0.207" +serde = "1.0.208" serde_derive = "1.0.103" solana-program = "2.0.3" solana-security-txt = "1.1.1" From d816434f242afca3a359c41a739526b965943691 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 08:51:54 -0400 Subject: [PATCH 0961/1076] build(deps-dev): bump @types/node from 22.3.0 to 22.4.1 (#7170) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.3.0 to 22.4.1. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index b11d6f03..0151429c 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^22.3.0", + "@types/node": "^22.4.1", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^8.1.0", "@typescript-eslint/parser": "^8.1.0", From b6b3dd8732c2fbdd989495bba91f880dc6a37712 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 08:52:05 -0400 Subject: [PATCH 0962/1076] build(deps-dev): bump rollup from 4.20.0 to 4.21.0 (#7169) Bumps [rollup](https://github.com/rollup/rollup) from 4.20.0 to 4.21.0. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.20.0...v4.21.0) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 0151429c..54a03dcb 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -69,7 +69,7 @@ "eslint": "^8.57.0", "jest": "^29.0.0", "rimraf": "^6.0.1", - "rollup": "^4.20.0", + "rollup": "^4.21.0", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.2.4", "typescript": "^5.5.4" From 641393dd01c192cffbf4a314c480feec5db424a2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Aug 2024 07:11:55 -0400 Subject: [PATCH 0963/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 8.1.0 to 8.2.0 (#7172) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 8.1.0 to 8.2.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.2.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 54a03dcb..c1585e2e 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.12", "@types/node": "^22.4.1", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^8.1.0", + "@typescript-eslint/eslint-plugin": "^8.2.0", "@typescript-eslint/parser": "^8.1.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", From a038a85e19dc178cefdfc5667b0e9ef35651090a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Aug 2024 13:58:18 +0200 Subject: [PATCH 0964/1076] build(deps-dev): bump @typescript-eslint/parser from 8.1.0 to 8.2.0 (#7173) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 8.1.0 to 8.2.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.2.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index c1585e2e..aeb0b3cc 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^22.4.1", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^8.2.0", - "@typescript-eslint/parser": "^8.1.0", + "@typescript-eslint/parser": "^8.2.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", "jest": "^29.0.0", From 8d3967fd9ea5e70efc41b6f14235d6450870ed70 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Aug 2024 13:45:11 +0200 Subject: [PATCH 0965/1076] build(deps): bump @solana/web3.js from 1.95.2 to 1.95.3 (#7177) Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.95.2 to 1.95.3. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.95.2...v1.95.3) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index aeb0b3cc..1b6e4cdd 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -45,7 +45,7 @@ "dependencies": { "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "0.4.6", - "@solana/web3.js": "^1.95.2", + "@solana/web3.js": "^1.95.3", "bn.js": "^5.2.0", "buffer": "^6.0.3", "buffer-layout": "^1.2.2", From 2463e955c19592c4aebba501ec63309093a1bf7d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Aug 2024 13:45:20 +0200 Subject: [PATCH 0966/1076] build(deps-dev): bump @types/node from 22.4.1 to 22.4.2 (#7176) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.4.1 to 22.4.2. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 1b6e4cdd..98bcea1a 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^22.4.1", + "@types/node": "^22.4.2", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^8.2.0", "@typescript-eslint/parser": "^8.2.0", From f9e68c4b2d70176792d0e17563d69e54ce4327bf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Aug 2024 18:35:46 +0200 Subject: [PATCH 0967/1076] build(deps-dev): bump @types/node from 22.4.2 to 22.5.0 (#7180) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.4.2 to 22.5.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 98bcea1a..28ac8277 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^22.4.2", + "@types/node": "^22.5.0", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^8.2.0", "@typescript-eslint/parser": "^8.2.0", From c7c660139391f5e2b9a7f95e34c86ae6aaba68e0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 12:57:55 +0200 Subject: [PATCH 0968/1076] build(deps): bump serde from 1.0.208 to 1.0.209 (#7187) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.208 to 1.0.209. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.208...v1.0.209) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 1b2f2134..2a314db6 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "2.0.0" [dependencies] borsh = "1.5.1" clap = "2.33.3" -serde = "1.0.208" +serde = "1.0.209" serde_derive = "1.0.130" serde_json = "1.0.125" solana-account-decoder = "2.0.3" diff --git a/program/Cargo.toml b/program/Cargo.toml index 2a1ff42e..06700823 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,7 +18,7 @@ bytemuck = "1.17" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.3" -serde = "1.0.208" +serde = "1.0.209" serde_derive = "1.0.103" solana-program = "2.0.3" solana-security-txt = "1.1.1" From fe099424ca59a4da0e9b089a05f03fd4df8ee659 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 12:58:25 +0200 Subject: [PATCH 0969/1076] build(deps-dev): bump ts-jest from 29.2.4 to 29.2.5 (#7191) Bumps [ts-jest](https://github.com/kulshekhar/ts-jest) from 29.2.4 to 29.2.5. - [Release notes](https://github.com/kulshekhar/ts-jest/releases) - [Changelog](https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md) - [Commits](https://github.com/kulshekhar/ts-jest/compare/v29.2.4...v29.2.5) --- updated-dependencies: - dependency-name: ts-jest dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 28ac8277..8d04e263 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -71,7 +71,7 @@ "rimraf": "^6.0.1", "rollup": "^4.21.0", "rollup-plugin-dts": "^6.1.1", - "ts-jest": "^29.2.4", + "ts-jest": "^29.2.5", "typescript": "^5.5.4" }, "jest": { From f84887eaa8292b70c739b9c63a5722043c6a7edc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 13:36:36 +0200 Subject: [PATCH 0970/1076] build(deps): bump serde_json from 1.0.125 to 1.0.127 (#7188) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.125 to 1.0.127. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/1.0.125...1.0.127) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 2a314db6..f16adccd 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ borsh = "1.5.1" clap = "2.33.3" serde = "1.0.209" serde_derive = "1.0.130" -serde_json = "1.0.125" +serde_json = "1.0.127" solana-account-decoder = "2.0.3" solana-clap-utils = "2.0.3" solana-cli-config = "2.0.3" From d4c2c5c6c125fa7c47456482fecf20ad8758efd7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Aug 2024 14:11:59 +0200 Subject: [PATCH 0971/1076] build(deps-dev): bump @typescript-eslint/parser from 8.2.0 to 8.3.0 (#7198) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 8.2.0 to 8.3.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.3.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 8d04e263..f822ea4d 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^22.5.0", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^8.2.0", - "@typescript-eslint/parser": "^8.2.0", + "@typescript-eslint/parser": "^8.3.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", "jest": "^29.0.0", From fe10c0c00d52433c5b8c52cb296019dc20009760 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Aug 2024 14:12:08 +0200 Subject: [PATCH 0972/1076] build(deps-dev): bump rollup from 4.21.0 to 4.21.1 (#7199) Bumps [rollup](https://github.com/rollup/rollup) from 4.21.0 to 4.21.1. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.21.0...v4.21.1) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index f822ea4d..d9b1afba 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -69,7 +69,7 @@ "eslint": "^8.57.0", "jest": "^29.0.0", "rimraf": "^6.0.1", - "rollup": "^4.21.0", + "rollup": "^4.21.1", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.2.5", "typescript": "^5.5.4" From 653d7da3179786e4bc52503353c4ee5c57ae629b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Aug 2024 14:24:02 +0200 Subject: [PATCH 0973/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 8.2.0 to 8.3.0 (#7200) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 8.2.0 to 8.3.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.3.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index d9b1afba..89a56b64 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.12", "@types/node": "^22.5.0", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^8.2.0", + "@typescript-eslint/eslint-plugin": "^8.3.0", "@typescript-eslint/parser": "^8.3.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", From 2637a1eb9a79274137667bac35de86dec5d090ea Mon Sep 17 00:00:00 2001 From: Kevin Heavey Date: Tue, 27 Aug 2024 17:38:15 +0400 Subject: [PATCH 0974/1076] ATA: Extract associated-token-account-client crate from associated-token-account crate (#7005) * extract associated-token-address crate * use spl_associated_token_address in spl crates * use spl-program-ids in associated-token-address crate * update imports in repo * use solana-inline-spl instead of spl-program-ids * remove remaining references to spl-program-ids * Rename associated-token-address -> associated-token-account-client * Use the new package everywhere * Remove solana-inline-spl dependency * Remove dependency on ata program from token-client * Add #[doc(hidden)] attribute to internal function * Remove ATA from token upgrade CLI * Add program module for program id --------- Co-authored-by: Jon C --- clients/cli/Cargo.toml | 1 + clients/cli/src/main.rs | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index f16adccd..22a9397f 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -26,6 +26,7 @@ solana-sdk = "2.0.3" spl-associated-token-account = { version = "=4.0.0", path = "../../associated-token-account/program", features = [ "no-entrypoint", ] } +spl-associated-token-account-client = { version = "=1.0.0", path = "../../associated-token-account/client" } spl-stake-pool = { version = "=2.0.0", path = "../program", features = [ "no-entrypoint", ] } diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index a777d8f6..e56990f1 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -43,9 +43,8 @@ use { system_instruction, transaction::Transaction, }, - spl_associated_token_account::{ - get_associated_token_address, instruction::create_associated_token_account, - }, + spl_associated_token_account::instruction::create_associated_token_account, + spl_associated_token_account_client::address::get_associated_token_address, spl_stake_pool::{ self, find_stake_program_address, find_transient_stake_program_address, find_withdraw_authority_program_address, From 68ce2a7b5ffdbb117a8328ed2a018a5fdeba0899 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 27 Aug 2024 14:07:57 +0000 Subject: [PATCH 0975/1076] Publish pod v0.3.2 --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 06700823..55263a31 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -25,7 +25,7 @@ solana-security-txt = "1.1.1" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint", ] } -spl-pod = { version = "0.3.0", path = "../../libraries/pod", features = [ +spl-pod = { version = "0.3.2", path = "../../libraries/pod", features = [ "borsh", ] } spl-token-2022 = { version = "4.0.0", path = "../../token/program-2022", features = [ From 2353b06079085e026d4bfc6ee559977834df6f36 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 27 Aug 2024 21:49:52 +0000 Subject: [PATCH 0976/1076] Publish token-2022 v5.0.0 --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 55263a31..e918b7e7 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -28,7 +28,7 @@ spl-math = { version = "0.2", path = "../../libraries/math", features = [ spl-pod = { version = "0.3.2", path = "../../libraries/pod", features = [ "borsh", ] } -spl-token-2022 = { version = "4.0.0", path = "../../token/program-2022", features = [ +spl-token-2022 = { version = "5.0.0", path = "../../token/program-2022", features = [ "no-entrypoint", ] } thiserror = "1.0" From 432a52351fca8130ecdb73758a636d070e0b3e63 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 28 Aug 2024 10:11:21 +0000 Subject: [PATCH 0977/1076] Publish pod v0.4.0 --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index e918b7e7..eb5b2a88 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -25,7 +25,7 @@ solana-security-txt = "1.1.1" spl-math = { version = "0.2", path = "../../libraries/math", features = [ "no-entrypoint", ] } -spl-pod = { version = "0.3.2", path = "../../libraries/pod", features = [ +spl-pod = { version = "0.4.0", path = "../../libraries/pod", features = [ "borsh", ] } spl-token-2022 = { version = "5.0.0", path = "../../token/program-2022", features = [ From 3eb62a7680ba3375ababd92f88c373b65cda0b73 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Aug 2024 12:48:36 +0200 Subject: [PATCH 0978/1076] build(deps-dev): bump @types/node from 22.5.0 to 22.5.1 (#7210) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.5.0 to 22.5.1. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 89a56b64..c2c79f8b 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^22.5.0", + "@types/node": "^22.5.1", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^8.3.0", "@typescript-eslint/parser": "^8.3.0", From 15d2295e15b89fb6fee31978272ef628fe2c035f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 28 Aug 2024 12:34:07 +0000 Subject: [PATCH 0979/1076] Publish token-2022 v5.0.1 --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index eb5b2a88..5fdae0bb 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -28,7 +28,7 @@ spl-math = { version = "0.2", path = "../../libraries/math", features = [ spl-pod = { version = "0.4.0", path = "../../libraries/pod", features = [ "borsh", ] } -spl-token-2022 = { version = "5.0.0", path = "../../token/program-2022", features = [ +spl-token-2022 = { version = "5.0.1", path = "../../token/program-2022", features = [ "no-entrypoint", ] } thiserror = "1.0" From 34a260fd09f4384044eb4a11026e8ac4a90115b2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 30 Aug 2024 13:06:21 +0200 Subject: [PATCH 0980/1076] build(deps-dev): bump rollup from 4.21.1 to 4.21.2 (#7219) Bumps [rollup](https://github.com/rollup/rollup) from 4.21.1 to 4.21.2. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.21.1...v4.21.2) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index c2c79f8b..19f33121 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -69,7 +69,7 @@ "eslint": "^8.57.0", "jest": "^29.0.0", "rimraf": "^6.0.1", - "rollup": "^4.21.1", + "rollup": "^4.21.2", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.2.5", "typescript": "^5.5.4" From a0106e4a1f627a53a90fbe62aa85b5819f621069 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 21:55:15 +0200 Subject: [PATCH 0981/1076] build(deps-dev): bump @types/node from 22.5.1 to 22.5.2 (#7228) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.5.1 to 22.5.2. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 19f33121..21e2a11d 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^22.5.1", + "@types/node": "^22.5.2", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^8.3.0", "@typescript-eslint/parser": "^8.3.0", From 459569e0be3b02a1045c2620db7967feb83b241a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 12:46:07 +0200 Subject: [PATCH 0982/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 8.3.0 to 8.4.0 (#7231) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 8.3.0 to 8.4.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.4.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 21e2a11d..a6556b9d 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.12", "@types/node": "^22.5.2", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^8.3.0", + "@typescript-eslint/eslint-plugin": "^8.4.0", "@typescript-eslint/parser": "^8.3.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", From c41ffb7ecbc24db530ddf64e9b03721f9e5b2b78 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 12:59:05 +0200 Subject: [PATCH 0983/1076] build(deps-dev): bump @typescript-eslint/parser from 8.3.0 to 8.4.0 (#7232) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 8.3.0 to 8.4.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.4.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index a6556b9d..5641e7b2 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^22.5.2", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^8.4.0", - "@typescript-eslint/parser": "^8.3.0", + "@typescript-eslint/parser": "^8.4.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", "jest": "^29.0.0", From 0b83a8ede8812a8c5efd5369d38bf4112decc01e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 14:48:37 +0000 Subject: [PATCH 0984/1076] Publish token-2022 v5.0.2 --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 5fdae0bb..fd8dde55 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -28,7 +28,7 @@ spl-math = { version = "0.2", path = "../../libraries/math", features = [ spl-pod = { version = "0.4.0", path = "../../libraries/pod", features = [ "borsh", ] } -spl-token-2022 = { version = "5.0.1", path = "../../token/program-2022", features = [ +spl-token-2022 = { version = "5.0.2", path = "../../token/program-2022", features = [ "no-entrypoint", ] } thiserror = "1.0" From af03d152f0113a156f322a9e79bde50f6aac5783 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 17:17:26 +0000 Subject: [PATCH 0985/1076] Publish associated-token-account v4.0.1 --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 22a9397f..3ddcbfd8 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -23,7 +23,7 @@ solana-logger = "2.0.3" solana-program = "2.0.3" solana-remote-wallet = "2.0.3" solana-sdk = "2.0.3" -spl-associated-token-account = { version = "=4.0.0", path = "../../associated-token-account/program", features = [ +spl-associated-token-account = { version = "=4.0.1", path = "../../associated-token-account/program", features = [ "no-entrypoint", ] } spl-associated-token-account-client = { version = "=1.0.0", path = "../../associated-token-account/client" } From 50bb0fd80f28811e6dc5b6cc224041f723be575c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 18:23:48 +0000 Subject: [PATCH 0986/1076] Publish associated-token-account v5.0.1 --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 3ddcbfd8..e3bf1436 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -23,7 +23,7 @@ solana-logger = "2.0.3" solana-program = "2.0.3" solana-remote-wallet = "2.0.3" solana-sdk = "2.0.3" -spl-associated-token-account = { version = "=4.0.1", path = "../../associated-token-account/program", features = [ +spl-associated-token-account = { version = "=5.0.1", path = "../../associated-token-account/program", features = [ "no-entrypoint", ] } spl-associated-token-account-client = { version = "=1.0.0", path = "../../associated-token-account/client" } From 5b37e118b111d1aa1ed5a77668f4f44ea3294cbe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Sep 2024 13:52:35 +0200 Subject: [PATCH 0987/1076] build(deps-dev): bump @types/node from 22.5.2 to 22.5.3 (#7239) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.5.2 to 22.5.3. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 5641e7b2..43951f5c 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^22.5.2", + "@types/node": "^22.5.3", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^8.4.0", "@typescript-eslint/parser": "^8.4.0", From 96d8013c98d9bcde7c23b73ec15ab0b544eba97d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Sep 2024 12:15:35 +0200 Subject: [PATCH 0988/1076] build(deps): bump serde_json from 1.0.127 to 1.0.128 (#7241) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.127 to 1.0.128. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/1.0.127...1.0.128) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index e3bf1436..b73912ac 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ borsh = "1.5.1" clap = "2.33.3" serde = "1.0.209" serde_derive = "1.0.130" -serde_json = "1.0.127" +serde_json = "1.0.128" solana-account-decoder = "2.0.3" solana-clap-utils = "2.0.3" solana-cli-config = "2.0.3" From 0c507f53ff6dee29be224df0ce17341c77595efc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Sep 2024 13:34:36 +0200 Subject: [PATCH 0989/1076] build(deps-dev): bump @types/node from 22.5.3 to 22.5.4 (#7242) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.5.3 to 22.5.4. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 43951f5c..1453d8f3 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.12", - "@types/node": "^22.5.3", + "@types/node": "^22.5.4", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^8.4.0", "@typescript-eslint/parser": "^8.4.0", From b286e45264b384621c6122a1311d18aba79a2f01 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Sep 2024 12:27:55 +0200 Subject: [PATCH 0990/1076] build(deps): bump bytemuck from 1.17.1 to 1.18.0 (#7244) Bumps [bytemuck](https://github.com/Lokathor/bytemuck) from 1.17.1 to 1.18.0. - [Changelog](https://github.com/Lokathor/bytemuck/blob/main/changelog.md) - [Commits](https://github.com/Lokathor/bytemuck/compare/v1.17.1...v1.18.0) --- updated-dependencies: - dependency-name: bytemuck dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index fd8dde55..69a09f60 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -14,7 +14,7 @@ test-sbf = [] [dependencies] arrayref = "0.3.8" borsh = "1.5.1" -bytemuck = "1.17" +bytemuck = "1.18" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.3" From c6fcaee656c427b5294fb2951ec83f127f312ad6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 12:36:00 +0200 Subject: [PATCH 0991/1076] build(deps): bump serde from 1.0.209 to 1.0.210 (#7250) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.209 to 1.0.210. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.209...v1.0.210) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index b73912ac..58e8f0b9 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "2.0.0" [dependencies] borsh = "1.5.1" clap = "2.33.3" -serde = "1.0.209" +serde = "1.0.210" serde_derive = "1.0.130" serde_json = "1.0.128" solana-account-decoder = "2.0.3" diff --git a/program/Cargo.toml b/program/Cargo.toml index 69a09f60..1141cae5 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,7 +18,7 @@ bytemuck = "1.18" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.3" -serde = "1.0.209" +serde = "1.0.210" serde_derive = "1.0.103" solana-program = "2.0.3" solana-security-txt = "1.1.1" From 06bc907a8fe17a03495f37f35438d3e54513ff35 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Sep 2024 15:09:04 +0200 Subject: [PATCH 0992/1076] build(deps-dev): bump typescript from 5.5.4 to 5.6.2 (#7255) Bumps [typescript](https://github.com/microsoft/TypeScript) from 5.5.4 to 5.6.2. - [Release notes](https://github.com/microsoft/TypeScript/releases) - [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml) - [Commits](https://github.com/microsoft/TypeScript/compare/v5.5.4...v5.6.2) --- updated-dependencies: - dependency-name: typescript dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 1453d8f3..d0d6a610 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "rollup": "^4.21.2", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.2.5", - "typescript": "^5.5.4" + "typescript": "^5.6.2" }, "jest": { "moduleFileExtensions": [ From 13b5d721b5e67adc2e6aa50083cee85f218411e3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Sep 2024 16:41:12 +0200 Subject: [PATCH 0993/1076] build(deps-dev): bump @typescript-eslint/eslint-plugin from 8.4.0 to 8.5.0 (#7258) build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 8.4.0 to 8.5.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.5.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index d0d6a610..645d0cb4 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,7 +63,7 @@ "@types/jest": "^29.5.12", "@types/node": "^22.5.4", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^8.4.0", + "@typescript-eslint/eslint-plugin": "^8.5.0", "@typescript-eslint/parser": "^8.4.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", From 15727f0d29d14e35e69e54171b61454bc73f6249 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Sep 2024 17:01:49 +0200 Subject: [PATCH 0994/1076] build(deps-dev): bump @typescript-eslint/parser from 8.4.0 to 8.5.0 (#7257) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 8.4.0 to 8.5.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.5.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 645d0cb4..b58d63fd 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -64,7 +64,7 @@ "@types/node": "^22.5.4", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^8.5.0", - "@typescript-eslint/parser": "^8.4.0", + "@typescript-eslint/parser": "^8.5.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", "jest": "^29.0.0", From b8de1c84198d6d628b3cfd59e4102cf88435168d Mon Sep 17 00:00:00 2001 From: Joe C Date: Thu, 12 Sep 2024 18:12:47 +0800 Subject: [PATCH 0995/1076] Revert ESLint plugin bump (#7260) * Revert "build(deps-dev): bump @typescript-eslint/parser from 8.4.0 to 8.5.0 (#7257)" This reverts commit fc896b0f3c8019fdd48eca5182910e411e359c35. * Revert "build(deps-dev): bump @typescript-eslint/eslint-plugin from 8.4.0 to 8.5.0 (#7258)" This reverts commit 5ecb1e9cd4cb15b254e37aab3624d03e8df95f93. --- clients/js-legacy/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index b58d63fd..d0d6a610 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -63,8 +63,8 @@ "@types/jest": "^29.5.12", "@types/node": "^22.5.4", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^8.5.0", - "@typescript-eslint/parser": "^8.5.0", + "@typescript-eslint/eslint-plugin": "^8.4.0", + "@typescript-eslint/parser": "^8.4.0", "cross-env": "^7.0.3", "eslint": "^8.57.0", "jest": "^29.0.0", From 3b5b5c5b319403e8e70e79d6b1b96e43077039a8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Sep 2024 13:53:21 +0200 Subject: [PATCH 0996/1076] build(deps-dev): bump rollup from 4.21.2 to 4.21.3 (#7268) Bumps [rollup](https://github.com/rollup/rollup) from 4.21.2 to 4.21.3. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.21.2...v4.21.3) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index d0d6a610..0fdd517a 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -69,7 +69,7 @@ "eslint": "^8.57.0", "jest": "^29.0.0", "rimraf": "^6.0.1", - "rollup": "^4.21.2", + "rollup": "^4.21.3", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.2.5", "typescript": "^5.6.2" From 41fb1e1c1211e650c29439127508521c5895fac8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Sep 2024 13:02:13 +0200 Subject: [PATCH 0997/1076] build(deps-dev): bump @types/jest from 29.5.12 to 29.5.13 (#7274) Bumps [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) from 29.5.12 to 29.5.13. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest) --- updated-dependencies: - dependency-name: "@types/jest" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 0fdd517a..4998f5c1 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -60,7 +60,7 @@ "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", - "@types/jest": "^29.5.12", + "@types/jest": "^29.5.13", "@types/node": "^22.5.4", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^8.4.0", From ec8a8b3ed3a054b79b9c5e4b97b53dfc6ee78755 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 00:38:10 +0800 Subject: [PATCH 0998/1076] build(deps): bump arrayref from 0.3.8 to 0.3.9 (#7278) Bumps [arrayref](https://github.com/droundy/arrayref) from 0.3.8 to 0.3.9. - [Commits](https://github.com/droundy/arrayref/commits) --- updated-dependencies: - dependency-name: arrayref dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 1141cae5..01bf7d58 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -12,7 +12,7 @@ no-entrypoint = [] test-sbf = [] [dependencies] -arrayref = "0.3.8" +arrayref = "0.3.9" borsh = "1.5.1" bytemuck = "1.18" num-derive = "0.4" From 3713e53484198d9fdb90ff1b72487526f06a1647 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 00:38:23 +0800 Subject: [PATCH 0999/1076] build(deps-dev): bump @types/node from 22.5.4 to 22.5.5 (#7279) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.5.4 to 22.5.5. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 4998f5c1..a22eeff0 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.0", "@types/jest": "^29.5.13", - "@types/node": "^22.5.4", + "@types/node": "^22.5.5", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^8.4.0", "@typescript-eslint/parser": "^8.4.0", From 27dfe391d68b9c9bb8a359d580797d32ad17926b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 00:38:46 +0800 Subject: [PATCH 1000/1076] build(deps-dev): bump @types/bn.js from 5.1.5 to 5.1.6 (#7281) Bumps [@types/bn.js](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/bn.js) from 5.1.5 to 5.1.6. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/bn.js) --- updated-dependencies: - dependency-name: "@types/bn.js" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index a22eeff0..772b82d6 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -59,7 +59,7 @@ "@rollup/plugin-node-resolve": "^15.0.2", "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-typescript": "^11.1.6", - "@types/bn.js": "^5.1.0", + "@types/bn.js": "^5.1.6", "@types/jest": "^29.5.13", "@types/node": "^22.5.5", "@types/node-fetch": "^2.6.11", From 3117d0830e24792af635fa52392ef846182d5164 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 21 Sep 2024 01:54:31 +0800 Subject: [PATCH 1001/1076] build(deps-dev): bump rollup from 4.21.3 to 4.22.2 (#7286) Bumps [rollup](https://github.com/rollup/rollup) from 4.21.3 to 4.22.2. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.21.3...v4.22.2) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 772b82d6..e4ff174f 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -69,7 +69,7 @@ "eslint": "^8.57.0", "jest": "^29.0.0", "rimraf": "^6.0.1", - "rollup": "^4.21.3", + "rollup": "^4.22.2", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.2.5", "typescript": "^5.6.2" From 00ec87acf95ce3244d493e0a81a0d2bf6beb6c7f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 16:51:49 +0200 Subject: [PATCH 1002/1076] build(deps-dev): bump @rollup/plugin-node-resolve from 15.2.3 to 15.2.4 (#7293) Bumps [@rollup/plugin-node-resolve](https://github.com/rollup/plugins/tree/HEAD/packages/node-resolve) from 15.2.3 to 15.2.4. - [Changelog](https://github.com/rollup/plugins/blob/master/packages/node-resolve/CHANGELOG.md) - [Commits](https://github.com/rollup/plugins/commits/node-resolve-v15.2.4/packages/node-resolve) --- updated-dependencies: - dependency-name: "@rollup/plugin-node-resolve" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index e4ff174f..d6fad822 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -56,7 +56,7 @@ "@rollup/plugin-commonjs": "^26.0.1", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-multi-entry": "^6.0.0", - "@rollup/plugin-node-resolve": "^15.0.2", + "@rollup/plugin-node-resolve": "^15.2.4", "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-typescript": "^11.1.6", "@types/bn.js": "^5.1.6", From 60bb324958a32fe858ab908fcc14ebc76e9b97bb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 16:52:06 +0200 Subject: [PATCH 1003/1076] build(deps-dev): bump @rollup/plugin-alias from 5.1.0 to 5.1.1 (#7289) Bumps [@rollup/plugin-alias](https://github.com/rollup/plugins/tree/HEAD/packages/alias) from 5.1.0 to 5.1.1. - [Changelog](https://github.com/rollup/plugins/blob/master/packages/alias/CHANGELOG.md) - [Commits](https://github.com/rollup/plugins/commits/wasm-v5.1.1/packages/alias) --- updated-dependencies: - dependency-name: "@rollup/plugin-alias" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index d6fad822..ecb0090c 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -52,7 +52,7 @@ "superstruct": "^2.0.2" }, "devDependencies": { - "@rollup/plugin-alias": "^5.1.0", + "@rollup/plugin-alias": "^5.1.1", "@rollup/plugin-commonjs": "^26.0.1", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-multi-entry": "^6.0.0", From ec78b79d2a06400cf8698147efe39a6d75e126a5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 17:08:00 +0200 Subject: [PATCH 1004/1076] build(deps-dev): bump rollup from 4.22.2 to 4.22.4 (#7291) Bumps [rollup](https://github.com/rollup/rollup) from 4.22.2 to 4.22.4. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.22.2...v4.22.4) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index ecb0090c..7954f260 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -69,7 +69,7 @@ "eslint": "^8.57.0", "jest": "^29.0.0", "rimraf": "^6.0.1", - "rollup": "^4.22.2", + "rollup": "^4.22.4", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.2.5", "typescript": "^5.6.2" From 930a3777b428d1a0fc29fb29c6b88f4f720a9c0b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 17:24:45 +0200 Subject: [PATCH 1005/1076] build(deps-dev): bump @rollup/plugin-typescript from 11.1.6 to 12.1.0 (#7290) Bumps [@rollup/plugin-typescript](https://github.com/rollup/plugins/tree/HEAD/packages/typescript) from 11.1.6 to 12.1.0. - [Changelog](https://github.com/rollup/plugins/blob/master/packages/typescript/CHANGELOG.md) - [Commits](https://github.com/rollup/plugins/commits/typescript-v12.1.0/packages/typescript) --- updated-dependencies: - dependency-name: "@rollup/plugin-typescript" dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 7954f260..7e36aad1 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -58,7 +58,7 @@ "@rollup/plugin-multi-entry": "^6.0.0", "@rollup/plugin-node-resolve": "^15.2.4", "@rollup/plugin-terser": "^0.4.4", - "@rollup/plugin-typescript": "^11.1.6", + "@rollup/plugin-typescript": "^12.1.0", "@types/bn.js": "^5.1.6", "@types/jest": "^29.5.13", "@types/node": "^22.5.5", From 77ec835e579f0db1680172065b1dcb181a68221c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 16:00:25 +0000 Subject: [PATCH 1006/1076] Publish spl-math v0.3.0 --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 01bf7d58..b13eaf14 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -22,7 +22,7 @@ serde = "1.0.210" serde_derive = "1.0.103" solana-program = "2.0.3" solana-security-txt = "1.1.1" -spl-math = { version = "0.2", path = "../../libraries/math", features = [ +spl-math = { version = "0.3", path = "../../libraries/math", features = [ "no-entrypoint", ] } spl-pod = { version = "0.4.0", path = "../../libraries/pod", features = [ From 4af8606d20407463d31c40a9201f0bcdfb8195df Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Sep 2024 12:55:31 +0200 Subject: [PATCH 1007/1076] build(deps-dev): bump @types/node from 22.5.5 to 22.6.1 (#7295) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.5.5 to 22.6.1. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 7e36aad1..be0497b7 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^12.1.0", "@types/bn.js": "^5.1.6", "@types/jest": "^29.5.13", - "@types/node": "^22.5.5", + "@types/node": "^22.6.1", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^8.4.0", "@typescript-eslint/parser": "^8.4.0", From 5bb9ed054ee34615ceca3252aaf5977a3f1ce6a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Sep 2024 12:55:47 +0200 Subject: [PATCH 1008/1076] build(deps-dev): bump @rollup/plugin-commonjs from 26.0.1 to 28.0.0 (#7297) Bumps [@rollup/plugin-commonjs](https://github.com/rollup/plugins/tree/HEAD/packages/commonjs) from 26.0.1 to 28.0.0. - [Changelog](https://github.com/rollup/plugins/blob/master/packages/commonjs/CHANGELOG.md) - [Commits](https://github.com/rollup/plugins/commits/commonjs-v28.0.0/packages/commonjs) --- updated-dependencies: - dependency-name: "@rollup/plugin-commonjs" dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index be0497b7..92c9716f 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -53,7 +53,7 @@ }, "devDependencies": { "@rollup/plugin-alias": "^5.1.1", - "@rollup/plugin-commonjs": "^26.0.1", + "@rollup/plugin-commonjs": "^28.0.0", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-multi-entry": "^6.0.0", "@rollup/plugin-node-resolve": "^15.2.4", From 9db04170f12c2c1b6ccc953996cc8be6c18f1759 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Sep 2024 13:10:57 +0200 Subject: [PATCH 1009/1076] build(deps-dev): bump @rollup/plugin-node-resolve from 15.2.4 to 15.3.0 (#7299) Bumps [@rollup/plugin-node-resolve](https://github.com/rollup/plugins/tree/HEAD/packages/node-resolve) from 15.2.4 to 15.3.0. - [Changelog](https://github.com/rollup/plugins/blob/master/packages/node-resolve/CHANGELOG.md) - [Commits](https://github.com/rollup/plugins/commits/node-resolve-v15.3.0/packages/node-resolve) --- updated-dependencies: - dependency-name: "@rollup/plugin-node-resolve" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 92c9716f..a91491fc 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -56,7 +56,7 @@ "@rollup/plugin-commonjs": "^28.0.0", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-multi-entry": "^6.0.0", - "@rollup/plugin-node-resolve": "^15.2.4", + "@rollup/plugin-node-resolve": "^15.3.0", "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-typescript": "^12.1.0", "@types/bn.js": "^5.1.6", From 6cbfd5355af35ef83b37b53d7097ab1a2d470831 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 25 Sep 2024 13:51:44 +0200 Subject: [PATCH 1010/1076] build(deps-dev): bump @types/node from 22.6.1 to 22.7.0 (#7302) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.6.1 to 22.7.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index a91491fc..4a2c6e6f 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^12.1.0", "@types/bn.js": "^5.1.6", "@types/jest": "^29.5.13", - "@types/node": "^22.6.1", + "@types/node": "^22.7.0", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^8.4.0", "@typescript-eslint/parser": "^8.4.0", From b2fa7202cccac8b358097d44e7132b85031a65a5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Sep 2024 00:19:47 -0400 Subject: [PATCH 1011/1076] build(deps-dev): bump @types/node from 22.7.0 to 22.7.2 (#7307) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.7.0 to 22.7.2. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 4a2c6e6f..93df71e1 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^12.1.0", "@types/bn.js": "^5.1.6", "@types/jest": "^29.5.13", - "@types/node": "^22.7.0", + "@types/node": "^22.7.2", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^8.4.0", "@typescript-eslint/parser": "^8.4.0", From 70f56378200fcedaf8e02ea47041a80bd365412d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 10:45:46 -0400 Subject: [PATCH 1012/1076] build(deps-dev): bump @types/node from 22.7.2 to 22.7.4 (#7310) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.7.2 to 22.7.4. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 93df71e1..e18cde7e 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^12.1.0", "@types/bn.js": "^5.1.6", "@types/jest": "^29.5.13", - "@types/node": "^22.7.2", + "@types/node": "^22.7.4", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^8.4.0", "@typescript-eslint/parser": "^8.4.0", From 21846abf6624835e7dbf1684e3d2dae15b8b1401 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 10:45:57 -0400 Subject: [PATCH 1013/1076] build(deps-dev): bump rollup from 4.22.4 to 4.23.0 (#7313) Bumps [rollup](https://github.com/rollup/rollup) from 4.22.4 to 4.23.0. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.22.4...v4.23.0) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index e18cde7e..2979fb49 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -69,7 +69,7 @@ "eslint": "^8.57.0", "jest": "^29.0.0", "rimraf": "^6.0.1", - "rollup": "^4.22.4", + "rollup": "^4.23.0", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.2.5", "typescript": "^5.6.2" From e59bc15625fc987bebbabe27ca5315fd47b29764 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 2 Oct 2024 20:19:29 -0400 Subject: [PATCH 1014/1076] build(deps-dev): bump rollup from 4.23.0 to 4.24.0 (#7321) Bumps [rollup](https://github.com/rollup/rollup) from 4.23.0 to 4.24.0. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.23.0...v4.24.0) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 2979fb49..b2103a1f 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -69,7 +69,7 @@ "eslint": "^8.57.0", "jest": "^29.0.0", "rimraf": "^6.0.1", - "rollup": "^4.23.0", + "rollup": "^4.24.0", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.2.5", "typescript": "^5.6.2" From d6e44e451c6211335bc2c08a8016384db142b490 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Oct 2024 16:03:53 +0200 Subject: [PATCH 1015/1076] build(deps-dev): bump @types/node from 22.7.4 to 22.7.5 (#7337) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.7.4 to 22.7.5. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index b2103a1f..5fec1b70 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^12.1.0", "@types/bn.js": "^5.1.6", "@types/jest": "^29.5.13", - "@types/node": "^22.7.4", + "@types/node": "^22.7.5", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^8.4.0", "@typescript-eslint/parser": "^8.4.0", From aa05487f8380d974f9e8b4ee0644f65557d67827 Mon Sep 17 00:00:00 2001 From: Tommy Johnson <32071703+tomjohn1028@users.noreply.github.com> Date: Tue, 8 Oct 2024 16:02:48 -0700 Subject: [PATCH 1016/1076] stake-pool-js: export the StakePoolLayout (#7324) * export the StakePoolLayout * export other layouts --- clients/js-legacy/src/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/clients/js-legacy/src/index.ts b/clients/js-legacy/src/index.ts index a3f31d4b..41414eac 100644 --- a/clients/js-legacy/src/index.ts +++ b/clients/js-legacy/src/index.ts @@ -46,6 +46,7 @@ import BN from 'bn.js'; export type { StakePool, AccountType, ValidatorList, ValidatorStakeInfo } from './layouts'; export { STAKE_POOL_PROGRAM_ID } from './constants'; export * from './instructions'; +export { StakePoolLayout, ValidatorListLayout, ValidatorStakeInfoLayout } from './layouts'; export interface ValidatorListAccount { pubkey: PublicKey; From 509e3a95c3a727eb90377bef7872ed6d53fc36fe Mon Sep 17 00:00:00 2001 From: Jon C Date: Tue, 8 Oct 2024 19:08:37 -0400 Subject: [PATCH 1017/1076] stake-pool-js: Bump to release (#7342) #### Problem #7324 exposed some needed types, but it's not released yet. #### Summary of changes Bump the patch version to release a new version. --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 5fec1b70..c7da8994 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-stake-pool", - "version": "1.1.5", + "version": "1.1.6", "description": "SPL Stake Pool Program JS API", "scripts": { "build": "tsc && cross-env NODE_ENV=production rollup -c", From 03ce5db2702bba5e361ba489a7af9e6ed9490154 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Oct 2024 13:53:28 +0200 Subject: [PATCH 1018/1076] build(deps-dev): bump typescript from 5.6.2 to 5.6.3 (#7343) Bumps [typescript](https://github.com/microsoft/TypeScript) from 5.6.2 to 5.6.3. - [Release notes](https://github.com/microsoft/TypeScript/releases) - [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml) - [Commits](https://github.com/microsoft/TypeScript/compare/v5.6.2...v5.6.3) --- updated-dependencies: - dependency-name: typescript dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index c7da8994..514e07b5 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "rollup": "^4.24.0", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.2.5", - "typescript": "^5.6.2" + "typescript": "^5.6.3" }, "jest": { "moduleFileExtensions": [ From 88293e8d6f8e76ed36776b8216cfdc19fc37bc73 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Oct 2024 12:59:51 +0200 Subject: [PATCH 1019/1076] build(deps): bump bytemuck from 1.18.0 to 1.19.0 (#7345) Bumps [bytemuck](https://github.com/Lokathor/bytemuck) from 1.18.0 to 1.19.0. - [Changelog](https://github.com/Lokathor/bytemuck/blob/main/changelog.md) - [Commits](https://github.com/Lokathor/bytemuck/compare/v1.18.0...v1.19.0) --- updated-dependencies: - dependency-name: bytemuck dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index b13eaf14..c3ebe2c8 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -14,7 +14,7 @@ test-sbf = [] [dependencies] arrayref = "0.3.9" borsh = "1.5.1" -bytemuck = "1.18" +bytemuck = "1.19" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.3" From ec351ba8d6e2010776e7c7908e961c260cebb6c4 Mon Sep 17 00:00:00 2001 From: Jon C Date: Mon, 14 Oct 2024 23:05:20 +0200 Subject: [PATCH 1020/1076] stake-pool-js: Bump to 1.1.7 (#7347) #### Problem The 1.1.6 publish didn't work for some reason. #### Summary of changes Bump to 1.1.7 and do it again --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 514e07b5..935ecb6a 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-stake-pool", - "version": "1.1.6", + "version": "1.1.7", "description": "SPL Stake Pool Program JS API", "scripts": { "build": "tsc && cross-env NODE_ENV=production rollup -c", From f22b9cefe7ad4c48fe2c61f3832f48e4cc8c2c9b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Oct 2024 13:12:14 +0200 Subject: [PATCH 1021/1076] build(deps-dev): bump @rollup/plugin-typescript from 12.1.0 to 12.1.1 (#7354) Bumps [@rollup/plugin-typescript](https://github.com/rollup/plugins/tree/HEAD/packages/typescript) from 12.1.0 to 12.1.1. - [Changelog](https://github.com/rollup/plugins/blob/master/packages/typescript/CHANGELOG.md) - [Commits](https://github.com/rollup/plugins/commits/typescript-v12.1.1/packages/typescript) --- updated-dependencies: - dependency-name: "@rollup/plugin-typescript" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 935ecb6a..627b76d9 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -58,7 +58,7 @@ "@rollup/plugin-multi-entry": "^6.0.0", "@rollup/plugin-node-resolve": "^15.3.0", "@rollup/plugin-terser": "^0.4.4", - "@rollup/plugin-typescript": "^12.1.0", + "@rollup/plugin-typescript": "^12.1.1", "@types/bn.js": "^5.1.6", "@types/jest": "^29.5.13", "@types/node": "^22.7.5", From a1e1dcd192ca7dbf4194ac78ed44a9fcaa77c5b1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Oct 2024 13:12:26 +0200 Subject: [PATCH 1022/1076] build(deps-dev): bump @rollup/plugin-commonjs from 28.0.0 to 28.0.1 (#7355) Bumps [@rollup/plugin-commonjs](https://github.com/rollup/plugins/tree/HEAD/packages/commonjs) from 28.0.0 to 28.0.1. - [Changelog](https://github.com/rollup/plugins/blob/master/packages/commonjs/CHANGELOG.md) - [Commits](https://github.com/rollup/plugins/commits/commonjs-v28.0.1/packages/commonjs) --- updated-dependencies: - dependency-name: "@rollup/plugin-commonjs" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 627b76d9..badd181d 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -53,7 +53,7 @@ }, "devDependencies": { "@rollup/plugin-alias": "^5.1.1", - "@rollup/plugin-commonjs": "^28.0.0", + "@rollup/plugin-commonjs": "^28.0.1", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-multi-entry": "^6.0.0", "@rollup/plugin-node-resolve": "^15.3.0", From e0db14e75b0291a0d7d21f9d7b13800373141aa6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 17 Oct 2024 13:40:19 +0200 Subject: [PATCH 1023/1076] build(deps-dev): bump @types/node from 22.7.5 to 22.7.6 (#7362) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.7.5 to 22.7.6. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index badd181d..ad0fb2f4 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^12.1.1", "@types/bn.js": "^5.1.6", "@types/jest": "^29.5.13", - "@types/node": "^22.7.5", + "@types/node": "^22.7.6", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^8.4.0", "@typescript-eslint/parser": "^8.4.0", From 140546a54ec77074d6ab84e9398eb3eaad4db22d Mon Sep 17 00:00:00 2001 From: Steven Luscher Date: Thu, 17 Oct 2024 09:57:55 -0700 Subject: [PATCH 1024/1076] Hardcode the discriminators so that you don't have to compute them at runtime (#7360) * Hardcode the discriminators so that you don't have to compute them at runtime * Don't run tests in libraries on Node older than v20 * Update versions --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index ad0fb2f4..25592950 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -44,7 +44,7 @@ "license": "ISC", "dependencies": { "@solana/buffer-layout": "^4.0.1", - "@solana/spl-token": "0.4.6", + "@solana/spl-token": "0.4.9", "@solana/web3.js": "^1.95.3", "bn.js": "^5.2.0", "buffer": "^6.0.3", From a46479255d6226e1b97894cbf2cc306ba1007b44 Mon Sep 17 00:00:00 2001 From: Steven Luscher Date: Thu, 17 Oct 2024 17:02:47 +0000 Subject: [PATCH 1025/1076] Sync versions with NPM --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 25592950..508e5741 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -1,6 +1,6 @@ { "name": "@solana/spl-stake-pool", - "version": "1.1.7", + "version": "1.1.8", "description": "SPL Stake Pool Program JS API", "scripts": { "build": "tsc && cross-env NODE_ENV=production rollup -c", From eebc0307d63299412728184bcfd6f956f8ec2d68 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 18 Oct 2024 12:40:30 +0200 Subject: [PATCH 1026/1076] build(deps): bump serde_json from 1.0.128 to 1.0.129 (#7364) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.128 to 1.0.129. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/1.0.128...1.0.129) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 58e8f0b9..0c3cad97 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ borsh = "1.5.1" clap = "2.33.3" serde = "1.0.210" serde_derive = "1.0.130" -serde_json = "1.0.128" +serde_json = "1.0.129" solana-account-decoder = "2.0.3" solana-clap-utils = "2.0.3" solana-cli-config = "2.0.3" From 5017ccb1ad70cd029ded0c6c3fe2d45e57682915 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 18 Oct 2024 13:32:55 +0200 Subject: [PATCH 1027/1076] build(deps): bump @solana/web3.js from 1.95.3 to 1.95.4 (#7366) * build(deps): bump @solana/web3.js from 1.95.3 to 1.95.4 Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.95.3 to 1.95.4. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.95.3...v1.95.4) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Update everywhere --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon C --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 508e5741..14e8ebf9 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -45,7 +45,7 @@ "dependencies": { "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "0.4.9", - "@solana/web3.js": "^1.95.3", + "@solana/web3.js": "^1.95.4", "bn.js": "^5.2.0", "buffer": "^6.0.3", "buffer-layout": "^1.2.2", From 3c4cf4bb53e242fb3e05ce85bd59bed7cfcd7ea2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Oct 2024 11:55:33 +0200 Subject: [PATCH 1028/1076] build(deps): bump serde_json from 1.0.129 to 1.0.132 (#7372) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.129 to 1.0.132. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/1.0.129...1.0.132) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 0c3cad97..fb5109b7 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ borsh = "1.5.1" clap = "2.33.3" serde = "1.0.210" serde_derive = "1.0.130" -serde_json = "1.0.129" +serde_json = "1.0.132" solana-account-decoder = "2.0.3" solana-clap-utils = "2.0.3" solana-cli-config = "2.0.3" From 4ff15de7d820a788e4e37593bb178e3f8829aa20 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Oct 2024 13:18:07 +0200 Subject: [PATCH 1029/1076] build(deps-dev): bump @types/node from 22.7.6 to 22.7.7 (#7373) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.7.6 to 22.7.7. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 14e8ebf9..e7d8f887 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^12.1.1", "@types/bn.js": "^5.1.6", "@types/jest": "^29.5.13", - "@types/node": "^22.7.6", + "@types/node": "^22.7.7", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^8.4.0", "@typescript-eslint/parser": "^8.4.0", From 62d2b1de1d529c259dc4364c77053c69e2478f80 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Oct 2024 12:52:40 +0200 Subject: [PATCH 1030/1076] build(deps): bump serde from 1.0.210 to 1.0.211 (#7380) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.210 to 1.0.211. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.210...v1.0.211) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index fb5109b7..0d90a154 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "2.0.0" [dependencies] borsh = "1.5.1" clap = "2.33.3" -serde = "1.0.210" +serde = "1.0.211" serde_derive = "1.0.130" serde_json = "1.0.132" solana-account-decoder = "2.0.3" diff --git a/program/Cargo.toml b/program/Cargo.toml index c3ebe2c8..e3615f4d 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,7 +18,7 @@ bytemuck = "1.19" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.3" -serde = "1.0.210" +serde = "1.0.211" serde_derive = "1.0.103" solana-program = "2.0.3" solana-security-txt = "1.1.1" From c13d6dd850c8856477cacf7e82ae2ac1cd8bf6da Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Oct 2024 12:53:26 +0200 Subject: [PATCH 1031/1076] build(deps-dev): bump @types/node from 22.7.7 to 22.7.8 (#7384) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.7.7 to 22.7.8. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index e7d8f887..0306b2ec 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^12.1.1", "@types/bn.js": "^5.1.6", "@types/jest": "^29.5.13", - "@types/node": "^22.7.7", + "@types/node": "^22.7.8", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^8.4.0", "@typescript-eslint/parser": "^8.4.0", From 0ea0951ecbc89d1d20167d9cc4be8623ef992ae8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 23 Oct 2024 15:43:59 +0200 Subject: [PATCH 1032/1076] build(deps): bump serde from 1.0.211 to 1.0.213 (#7388) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.211 to 1.0.213. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.211...v1.0.213) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 0d90a154..08f8a5bb 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "2.0.0" [dependencies] borsh = "1.5.1" clap = "2.33.3" -serde = "1.0.211" +serde = "1.0.213" serde_derive = "1.0.130" serde_json = "1.0.132" solana-account-decoder = "2.0.3" diff --git a/program/Cargo.toml b/program/Cargo.toml index e3615f4d..e87cf2ba 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,7 +18,7 @@ bytemuck = "1.19" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.3" -serde = "1.0.211" +serde = "1.0.213" serde_derive = "1.0.103" solana-program = "2.0.3" solana-security-txt = "1.1.1" From 60361b16abd2b8ccd1427091875a4020fae050c5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 23 Oct 2024 15:44:23 +0200 Subject: [PATCH 1033/1076] build(deps-dev): bump @types/node from 22.7.8 to 22.7.9 (#7390) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.7.8 to 22.7.9. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 0306b2ec..c23a1352 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^12.1.1", "@types/bn.js": "^5.1.6", "@types/jest": "^29.5.13", - "@types/node": "^22.7.8", + "@types/node": "^22.7.9", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^8.4.0", "@typescript-eslint/parser": "^8.4.0", From 544c3ab4df7f17503f147572f5ffa8cfbf63403a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 23 Oct 2024 15:59:40 +0200 Subject: [PATCH 1034/1076] build(deps-dev): bump @types/jest from 29.5.13 to 29.5.14 (#7391) Bumps [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) from 29.5.13 to 29.5.14. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest) --- updated-dependencies: - dependency-name: "@types/jest" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index c23a1352..a190a8a3 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -60,7 +60,7 @@ "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-typescript": "^12.1.1", "@types/bn.js": "^5.1.6", - "@types/jest": "^29.5.13", + "@types/jest": "^29.5.14", "@types/node": "^22.7.9", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^8.4.0", From 4e8c6e1876bbd86c59925cee3e51c2702387252b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2024 13:07:08 +0100 Subject: [PATCH 1035/1076] build(deps-dev): bump @types/node from 22.7.9 to 22.8.1 (#7401) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.7.9 to 22.8.1. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index a190a8a3..24870b37 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^12.1.1", "@types/bn.js": "^5.1.6", "@types/jest": "^29.5.14", - "@types/node": "^22.7.9", + "@types/node": "^22.8.1", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^8.4.0", "@typescript-eslint/parser": "^8.4.0", From f539d7e260a698e62a9f784f044b5d8f7f18641b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2024 13:07:17 +0100 Subject: [PATCH 1036/1076] build(deps-dev): bump rollup from 4.24.0 to 4.24.2 (#7402) Bumps [rollup](https://github.com/rollup/rollup) from 4.24.0 to 4.24.2. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.24.0...v4.24.2) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 24870b37..b786928b 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -69,7 +69,7 @@ "eslint": "^8.57.0", "jest": "^29.0.0", "rimraf": "^6.0.1", - "rollup": "^4.24.0", + "rollup": "^4.24.2", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.2.5", "typescript": "^5.6.3" From 0f5ef1dafeb4c66262674c971b6954ba6a507867 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 29 Oct 2024 11:36:21 +0100 Subject: [PATCH 1037/1076] build(deps): bump serde from 1.0.213 to 1.0.214 (#7405) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.213 to 1.0.214. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.213...v1.0.214) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 08f8a5bb..114ced67 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "2.0.0" [dependencies] borsh = "1.5.1" clap = "2.33.3" -serde = "1.0.213" +serde = "1.0.214" serde_derive = "1.0.130" serde_json = "1.0.132" solana-account-decoder = "2.0.3" diff --git a/program/Cargo.toml b/program/Cargo.toml index e87cf2ba..1b5a1130 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,7 +18,7 @@ bytemuck = "1.19" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.3" -serde = "1.0.213" +serde = "1.0.214" serde_derive = "1.0.103" solana-program = "2.0.3" solana-security-txt = "1.1.1" From efb8971a65f7832db6d72359a062de8e20f368f5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 29 Oct 2024 11:36:43 +0100 Subject: [PATCH 1038/1076] build(deps-dev): bump @types/node from 22.8.1 to 22.8.2 (#7407) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.8.1 to 22.8.2. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index b786928b..0c4d0b29 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^12.1.1", "@types/bn.js": "^5.1.6", "@types/jest": "^29.5.14", - "@types/node": "^22.8.1", + "@types/node": "^22.8.2", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^8.4.0", "@typescript-eslint/parser": "^8.4.0", From cbe1ad0fa607e3ec3b18676173f75ccbc92a45c1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 30 Oct 2024 12:10:00 +0100 Subject: [PATCH 1039/1076] build(deps-dev): bump rollup from 4.24.2 to 4.24.3 (#7414) Bumps [rollup](https://github.com/rollup/rollup) from 4.24.2 to 4.24.3. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.24.2...v4.24.3) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 0c4d0b29..6e5d51a5 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -69,7 +69,7 @@ "eslint": "^8.57.0", "jest": "^29.0.0", "rimraf": "^6.0.1", - "rollup": "^4.24.2", + "rollup": "^4.24.3", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.2.5", "typescript": "^5.6.3" From db0dfc28e59cf3746c26c67a759cf6dd16e3aa92 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 30 Oct 2024 12:10:12 +0100 Subject: [PATCH 1040/1076] build(deps-dev): bump @types/node from 22.8.2 to 22.8.4 (#7411) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.8.2 to 22.8.4. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 6e5d51a5..d84d214c 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^12.1.1", "@types/bn.js": "^5.1.6", "@types/jest": "^29.5.14", - "@types/node": "^22.8.2", + "@types/node": "^22.8.4", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^8.4.0", "@typescript-eslint/parser": "^8.4.0", From 7082aa0a222718571cb08ca7029398d3a9192baf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 31 Oct 2024 12:13:40 +0100 Subject: [PATCH 1041/1076] build(deps-dev): bump @types/node from 22.8.4 to 22.8.5 (#7423) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.8.4 to 22.8.5. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index d84d214c..d547108c 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^12.1.1", "@types/bn.js": "^5.1.6", "@types/jest": "^29.5.14", - "@types/node": "^22.8.4", + "@types/node": "^22.8.5", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^8.4.0", "@typescript-eslint/parser": "^8.4.0", From 48e34b20d3b45af084fd65e84658f90368ba60ce Mon Sep 17 00:00:00 2001 From: Ikko Eltociear Ashimine Date: Thu, 31 Oct 2024 20:14:20 +0900 Subject: [PATCH 1042/1076] chore: update instruction.rs (#7420) Unitialized -> Uninitialized --- program/src/instruction.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 9709bef0..ef6a801e 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -320,7 +320,7 @@ pub enum StakePoolInstruction { /// 1. `[w]` Validator stake list storage account /// 2. `[]` Stake pool withdraw authority /// 3. `[w]` Validator or reserve stake account to split - /// 4. `[w]` Unitialized stake account to receive withdrawal + /// 4. `[w]` Uninitialized stake account to receive withdrawal /// 5. `[]` User account to set as a new withdraw authority /// 6. `[s]` User transfer authority, for pool token account /// 7. `[w]` User account with pool tokens to burn from @@ -665,7 +665,7 @@ pub enum StakePoolInstruction { /// 1. `[w]` Validator stake list storage account /// 2. `[]` Stake pool withdraw authority /// 3. `[w]` Validator or reserve stake account to split - /// 4. `[w]` Unitialized stake account to receive withdrawal + /// 4. `[w]` Uninitialized stake account to receive withdrawal /// 5. `[]` User account to set as a new withdraw authority /// 6. `[s]` User transfer authority, for pool token account /// 7. `[w]` User account with pool tokens to burn from From f1b1d34e3a458f537781b573caa58b9bf950c122 Mon Sep 17 00:00:00 2001 From: Jon C Date: Thu, 31 Oct 2024 12:25:30 +0100 Subject: [PATCH 1043/1076] CI: Update to Solana v2.1 crates (#7416) * Run update script, update curve25519-dalek dep, rust * Run clippy + fmt * Add workspace lints, start fixing doc comments * Update doc comments for clippy * Re-run cargo fmt after doc comment update * Update solana-version * Update CI jobs --- clients/cli/Cargo.toml | 18 ++++++------- program/Cargo.toml | 11 +++++--- program/src/big_vec.rs | 8 +++--- program/src/instruction.rs | 28 +++++++++++++-------- program/src/state.rs | 3 +-- program/tests/create_pool_token_metadata.rs | 8 +++--- program/tests/decrease.rs | 12 +++------ program/tests/deposit.rs | 4 +-- program/tests/deposit_edge_cases.rs | 2 +- program/tests/deposit_sol.rs | 6 ++--- program/tests/increase.rs | 4 +-- program/tests/set_deposit_fee.rs | 8 +++--- program/tests/set_epoch_fee.rs | 4 +-- program/tests/set_funding_authority.rs | 6 ++--- program/tests/set_manager.rs | 6 ++--- program/tests/set_preferred.rs | 2 +- program/tests/set_referral_fee.rs | 8 +++--- program/tests/set_staker.rs | 6 ++--- program/tests/set_withdrawal_fee.rs | 12 ++++----- program/tests/update_pool_token_metadata.rs | 4 +-- program/tests/vsa_add.rs | 12 ++++----- program/tests/vsa_remove.rs | 8 +++--- program/tests/withdraw.rs | 4 +-- 23 files changed, 91 insertions(+), 93 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 114ced67..af4834c6 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -14,15 +14,15 @@ clap = "2.33.3" serde = "1.0.214" serde_derive = "1.0.130" serde_json = "1.0.132" -solana-account-decoder = "2.0.3" -solana-clap-utils = "2.0.3" -solana-cli-config = "2.0.3" -solana-cli-output = "2.0.3" -solana-client = "2.0.3" -solana-logger = "2.0.3" -solana-program = "2.0.3" -solana-remote-wallet = "2.0.3" -solana-sdk = "2.0.3" +solana-account-decoder = "2.1.0" +solana-clap-utils = "2.1.0" +solana-cli-config = "2.1.0" +solana-cli-output = "2.1.0" +solana-client = "2.1.0" +solana-logger = "2.1.0" +solana-program = "2.1.0" +solana-remote-wallet = "2.1.0" +solana-sdk = "2.1.0" spl-associated-token-account = { version = "=5.0.1", path = "../../associated-token-account/program", features = [ "no-entrypoint", ] } diff --git a/program/Cargo.toml b/program/Cargo.toml index 1b5a1130..ad4c5c35 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -20,7 +20,7 @@ num-traits = "0.2" num_enum = "0.7.3" serde = "1.0.214" serde_derive = "1.0.103" -solana-program = "2.0.3" +solana-program = "2.1.0" solana-security-txt = "1.1.1" spl-math = { version = "0.3", path = "../../libraries/math", features = [ "no-entrypoint", @@ -37,9 +37,9 @@ bincode = "1.3.1" [dev-dependencies] assert_matches = "1.5.0" proptest = "1.5" -solana-program-test = "2.0.3" -solana-sdk = "2.0.3" -solana-vote-program = "2.0.3" +solana-program-test = "2.1.0" +solana-sdk = "2.1.0" +solana-vote-program = "2.1.0" spl-token = { version = "6.0", path = "../../token/program", features = [ "no-entrypoint", ] } @@ -47,3 +47,6 @@ test-case = "3.3" [lib] crate-type = ["cdylib", "lib"] + +[lints] +workspace = true diff --git a/program/src/big_vec.rs b/program/src/big_vec.rs index 8cf99f80..9ad84ff3 100644 --- a/program/src/big_vec.rs +++ b/program/src/big_vec.rs @@ -83,8 +83,8 @@ impl<'data> BigVec<'data> { } } - let mut vec_len_ref = &mut self.data[0..VEC_SIZE_BYTES]; - borsh::to_writer(&mut vec_len_ref, &vec_len)?; + let vec_len_ref = &mut self.data[0..VEC_SIZE_BYTES]; + borsh::to_writer(vec_len_ref, &vec_len)?; Ok(()) } @@ -127,14 +127,14 @@ impl<'data> BigVec<'data> { /// Add new element to the end pub fn push(&mut self, element: T) -> Result<(), ProgramError> { - let mut vec_len_ref = &mut self.data[0..VEC_SIZE_BYTES]; + let vec_len_ref = &mut self.data[0..VEC_SIZE_BYTES]; let mut vec_len = u32::try_from_slice(vec_len_ref)?; let start_index = VEC_SIZE_BYTES + vec_len as usize * mem::size_of::(); let end_index = start_index + mem::size_of::(); vec_len += 1; - borsh::to_writer(&mut vec_len_ref, &vec_len)?; + borsh::to_writer(vec_len_ref, &vec_len)?; if self.data.len() < end_index { return Err(ProgramError::AccountDataTooSmall); diff --git a/program/src/instruction.rs b/program/src/instruction.rs index ef6a801e..b5d6dc7a 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -192,11 +192,14 @@ pub enum StakePoolInstruction { /// 11. `[]` Stake Config sysvar /// 12. `[]` System program /// 13. `[]` Stake program - /// userdata: amount of lamports to increase on the given validator. - /// The actual amount split into the transient stake account is: - /// `lamports + stake_rent_exemption` - /// The rent-exemption of the stake account is withdrawn back to the - /// reserve after it is merged. + /// + /// userdata: amount of lamports to increase on the given validator. + /// + /// The actual amount split into the transient stake account is: + /// `lamports + stake_rent_exemption`. + /// + /// The rent-exemption of the stake account is withdrawn back to the + /// reserve after it is merged. IncreaseValidatorStake { /// amount of lamports to increase on the given validator lamports: u64, @@ -329,6 +332,7 @@ pub enum StakePoolInstruction { /// 10. `[]` Sysvar clock account (required) /// 11. `[]` Pool token program id /// 12. `[]` Stake program id, + /// /// userdata: amount of pool tokens to withdraw WithdrawStake(u64), @@ -463,11 +467,14 @@ pub enum StakePoolInstruction { /// 11. `[]` Stake Config sysvar /// 12. `[]` System program /// 13. `[]` Stake program - /// userdata: amount of lamports to increase on the given validator. - /// The actual amount split into the transient stake account is: - /// `lamports + stake_rent_exemption` - /// The rent-exemption of the stake account is withdrawn back to the - /// reserve after it is merged. + /// + /// userdata: amount of lamports to increase on the given validator. + /// + /// The actual amount split into the transient stake account is: + /// `lamports + stake_rent_exemption`. + /// + /// The rent-exemption of the stake account is withdrawn back to the + /// reserve after it is merged. IncreaseAdditionalValidatorStake { /// amount of lamports to increase on the given validator lamports: u64, @@ -674,6 +681,7 @@ pub enum StakePoolInstruction { /// 10. `[]` Sysvar clock account (required) /// 11. `[]` Pool token program id /// 12. `[]` Stake program id, + /// /// userdata: amount of pool tokens to withdraw WithdrawStakeWithSlippage { /// Pool tokens to burn in exchange for lamports diff --git a/program/src/state.rs b/program/src/state.rs index e2b79d53..831c1877 100644 --- a/program/src/state.rs +++ b/program/src/state.rs @@ -765,10 +765,9 @@ impl Sealed for ValidatorStakeInfo {} impl Pack for ValidatorStakeInfo { const LEN: usize = 73; fn pack_into_slice(&self, data: &mut [u8]) { - let mut data = data; // Removing this unwrap would require changing from `Pack` to some other // trait or `bytemuck`, so it stays in for now - borsh::to_writer(&mut data, self).unwrap(); + borsh::to_writer(data, self).unwrap(); } fn unpack_from_slice(src: &[u8]) -> Result { let unpacked = Self::try_from_slice(src)?; diff --git a/program/tests/create_pool_token_metadata.rs b/program/tests/create_pool_token_metadata.rs index 147e3928..b56fd655 100644 --- a/program/tests/create_pool_token_metadata.rs +++ b/program/tests/create_pool_token_metadata.rs @@ -83,7 +83,7 @@ async fn success(token_program_id: Pubkey) { #[tokio::test] async fn fail_manager_did_not_sign() { - let (mut context, stake_pool_accounts) = setup(spl_token::id()).await; + let (context, stake_pool_accounts) = setup(spl_token::id()).await; let name = "test_name"; let symbol = "SYM"; @@ -127,7 +127,7 @@ async fn fail_manager_did_not_sign() { #[tokio::test] async fn fail_wrong_manager_signed() { - let (mut context, stake_pool_accounts) = setup(spl_token::id()).await; + let (context, stake_pool_accounts) = setup(spl_token::id()).await; let name = "test_name"; let symbol = "SYM"; @@ -171,7 +171,7 @@ async fn fail_wrong_manager_signed() { #[tokio::test] async fn fail_wrong_mpl_metadata_program() { - let (mut context, stake_pool_accounts) = setup(spl_token::id()).await; + let (context, stake_pool_accounts) = setup(spl_token::id()).await; let name = "test_name"; let symbol = "SYM"; @@ -217,7 +217,7 @@ async fn fail_wrong_mpl_metadata_program() { #[tokio::test] async fn fail_create_metadata_twice() { - let (mut context, stake_pool_accounts) = setup(spl_token::id()).await; + let (context, stake_pool_accounts) = setup(spl_token::id()).await; let name = "test_name"; let symbol = "SYM"; diff --git a/program/tests/decrease.rs b/program/tests/decrease.rs index 2e31c644..495f5d21 100644 --- a/program/tests/decrease.rs +++ b/program/tests/decrease.rs @@ -174,7 +174,7 @@ async fn success(instruction_type: DecreaseInstruction) { #[tokio::test] async fn fail_with_wrong_withdraw_authority() { - let (mut context, stake_pool_accounts, validator_stake, _deposit_info, decrease_lamports, _) = + let (context, stake_pool_accounts, validator_stake, _deposit_info, decrease_lamports, _) = setup().await; let wrong_authority = Pubkey::new_unique(); @@ -215,14 +215,8 @@ async fn fail_with_wrong_withdraw_authority() { #[tokio::test] async fn fail_with_wrong_validator_list() { - let ( - mut context, - mut stake_pool_accounts, - validator_stake, - _deposit_info, - decrease_lamports, - _, - ) = setup().await; + let (context, mut stake_pool_accounts, validator_stake, _deposit_info, decrease_lamports, _) = + setup().await; stake_pool_accounts.validator_list = Keypair::new(); diff --git a/program/tests/deposit.rs b/program/tests/deposit.rs index 0b333e47..752a6bec 100644 --- a/program/tests/deposit.rs +++ b/program/tests/deposit.rs @@ -465,7 +465,7 @@ async fn success_with_extra_stake_lamports() { #[tokio::test] async fn fail_with_wrong_stake_program_id() { let ( - mut context, + context, stake_pool_accounts, validator_stake_account, _user, @@ -522,7 +522,7 @@ async fn fail_with_wrong_stake_program_id() { #[tokio::test] async fn fail_with_wrong_token_program_id() { let ( - mut context, + context, stake_pool_accounts, validator_stake_account, user, diff --git a/program/tests/deposit_edge_cases.rs b/program/tests/deposit_edge_cases.rs index 510e2f94..a11ea428 100644 --- a/program/tests/deposit_edge_cases.rs +++ b/program/tests/deposit_edge_cases.rs @@ -288,7 +288,7 @@ async fn success_with_referral_fee() { #[tokio::test] async fn fail_with_invalid_referrer() { let ( - mut context, + context, stake_pool_accounts, validator_stake_account, user, diff --git a/program/tests/deposit_sol.rs b/program/tests/deposit_sol.rs index fa7ef355..aebeb4f1 100644 --- a/program/tests/deposit_sol.rs +++ b/program/tests/deposit_sol.rs @@ -141,8 +141,7 @@ async fn success(token_program_id: Pubkey) { #[tokio::test] async fn fail_with_wrong_token_program_id() { - let (mut context, stake_pool_accounts, _user, pool_token_account) = - setup(spl_token::id()).await; + let (context, stake_pool_accounts, _user, pool_token_account) = setup(spl_token::id()).await; let wrong_token_program = Keypair::new(); @@ -467,8 +466,7 @@ async fn success_with_referral_fee() { #[tokio::test] async fn fail_with_invalid_referrer() { - let (mut context, stake_pool_accounts, _user, pool_token_account) = - setup(spl_token::id()).await; + let (context, stake_pool_accounts, _user, pool_token_account) = setup(spl_token::id()).await; let invalid_token_account = Keypair::new(); diff --git a/program/tests/increase.rs b/program/tests/increase.rs index 67fac5f1..0d6c4bda 100644 --- a/program/tests/increase.rs +++ b/program/tests/increase.rs @@ -150,7 +150,7 @@ async fn success(use_additional_instruction: bool) { #[tokio::test] async fn fail_with_wrong_withdraw_authority() { - let (mut context, stake_pool_accounts, validator_stake, reserve_lamports) = setup().await; + let (context, stake_pool_accounts, validator_stake, reserve_lamports) = setup().await; let wrong_authority = Pubkey::new_unique(); @@ -191,7 +191,7 @@ async fn fail_with_wrong_withdraw_authority() { #[tokio::test] async fn fail_with_wrong_validator_list() { - let (mut context, stake_pool_accounts, validator_stake, reserve_lamports) = setup().await; + let (context, stake_pool_accounts, validator_stake, reserve_lamports) = setup().await; let wrong_validator_list = Pubkey::new_unique(); diff --git a/program/tests/set_deposit_fee.rs b/program/tests/set_deposit_fee.rs index ba628384..618228aa 100644 --- a/program/tests/set_deposit_fee.rs +++ b/program/tests/set_deposit_fee.rs @@ -112,7 +112,7 @@ async fn success_stake_increase_fee_from_0() { #[tokio::test] async fn fail_stake_wrong_manager() { - let (mut context, stake_pool_accounts, new_deposit_fee) = setup(None).await; + let (context, stake_pool_accounts, new_deposit_fee) = setup(None).await; let wrong_manager = Keypair::new(); let transaction = Transaction::new_signed_with_payer( @@ -145,7 +145,7 @@ async fn fail_stake_wrong_manager() { #[tokio::test] async fn fail_stake_high_deposit_fee() { - let (mut context, stake_pool_accounts, _new_deposit_fee) = setup(None).await; + let (context, stake_pool_accounts, _new_deposit_fee) = setup(None).await; let new_deposit_fee = Fee { numerator: 100001, @@ -211,7 +211,7 @@ async fn success_sol() { #[tokio::test] async fn fail_sol_wrong_manager() { - let (mut context, stake_pool_accounts, new_deposit_fee) = setup(None).await; + let (context, stake_pool_accounts, new_deposit_fee) = setup(None).await; let wrong_manager = Keypair::new(); let transaction = Transaction::new_signed_with_payer( @@ -244,7 +244,7 @@ async fn fail_sol_wrong_manager() { #[tokio::test] async fn fail_sol_high_deposit_fee() { - let (mut context, stake_pool_accounts, _new_deposit_fee) = setup(None).await; + let (context, stake_pool_accounts, _new_deposit_fee) = setup(None).await; let new_deposit_fee = Fee { numerator: 100001, diff --git a/program/tests/set_epoch_fee.rs b/program/tests/set_epoch_fee.rs index c510a813..e7bb6cd5 100644 --- a/program/tests/set_epoch_fee.rs +++ b/program/tests/set_epoch_fee.rs @@ -127,7 +127,7 @@ async fn success() { #[tokio::test] async fn fail_wrong_manager() { - let (mut context, stake_pool_accounts, new_fee) = setup().await; + let (context, stake_pool_accounts, new_fee) = setup().await; let wrong_manager = Keypair::new(); let transaction = Transaction::new_signed_with_payer( @@ -160,7 +160,7 @@ async fn fail_wrong_manager() { #[tokio::test] async fn fail_high_fee() { - let (mut context, stake_pool_accounts, _new_fee) = setup().await; + let (context, stake_pool_accounts, _new_fee) = setup().await; let new_fee = Fee { numerator: 11, diff --git a/program/tests/set_funding_authority.rs b/program/tests/set_funding_authority.rs index ee2722d8..a3cdb619 100644 --- a/program/tests/set_funding_authority.rs +++ b/program/tests/set_funding_authority.rs @@ -97,8 +97,7 @@ async fn success_set_stake_deposit_authority() { #[tokio::test] async fn fail_wrong_manager() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_authority) = - setup().await; + let (banks_client, payer, recent_blockhash, stake_pool_accounts, new_authority) = setup().await; let mut transaction = Transaction::new_with_payer( &[instruction::set_funding_authority( @@ -132,8 +131,7 @@ async fn fail_wrong_manager() { #[tokio::test] async fn fail_without_signature() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_authority) = - setup().await; + let (banks_client, payer, recent_blockhash, stake_pool_accounts, new_authority) = setup().await; let data = borsh::to_vec(&instruction::StakePoolInstruction::SetFundingAuthority( FundingType::StakeDeposit, diff --git a/program/tests/set_manager.rs b/program/tests/set_manager.rs index 3172d3bf..e6f7afad 100644 --- a/program/tests/set_manager.rs +++ b/program/tests/set_manager.rs @@ -95,7 +95,7 @@ async fn test_set_manager() { #[tokio::test] async fn test_set_manager_by_malicious() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_pool_fee, new_manager) = + let (banks_client, payer, recent_blockhash, stake_pool_accounts, new_pool_fee, new_manager) = setup().await; let mut transaction = Transaction::new_with_payer( @@ -130,7 +130,7 @@ async fn test_set_manager_by_malicious() { #[tokio::test] async fn test_set_manager_without_existing_signature() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_pool_fee, new_manager) = + let (banks_client, payer, recent_blockhash, stake_pool_accounts, new_pool_fee, new_manager) = setup().await; let data = borsh::to_vec(&instruction::StakePoolInstruction::SetManager).unwrap(); @@ -171,7 +171,7 @@ async fn test_set_manager_without_existing_signature() { #[tokio::test] async fn test_set_manager_without_new_signature() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_pool_fee, new_manager) = + let (banks_client, payer, recent_blockhash, stake_pool_accounts, new_pool_fee, new_manager) = setup().await; let data = borsh::to_vec(&instruction::StakePoolInstruction::SetManager).unwrap(); diff --git a/program/tests/set_preferred.rs b/program/tests/set_preferred.rs index 1a1e3c0f..c18fd3df 100644 --- a/program/tests/set_preferred.rs +++ b/program/tests/set_preferred.rs @@ -158,7 +158,7 @@ async fn success_unset() { #[tokio::test] async fn fail_wrong_staker() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, _) = setup().await; + let (banks_client, payer, recent_blockhash, stake_pool_accounts, _) = setup().await; let wrong_staker = Keypair::new(); let transaction = Transaction::new_signed_with_payer( diff --git a/program/tests/set_referral_fee.rs b/program/tests/set_referral_fee.rs index 7221e978..19090820 100644 --- a/program/tests/set_referral_fee.rs +++ b/program/tests/set_referral_fee.rs @@ -102,7 +102,7 @@ async fn success_stake_increase_fee_from_0() { #[tokio::test] async fn fail_stake_wrong_manager() { - let (mut context, stake_pool_accounts, new_referral_fee) = setup(None).await; + let (context, stake_pool_accounts, new_referral_fee) = setup(None).await; let wrong_manager = Keypair::new(); let transaction = Transaction::new_signed_with_payer( @@ -135,7 +135,7 @@ async fn fail_stake_wrong_manager() { #[tokio::test] async fn fail_stake_high_referral_fee() { - let (mut context, stake_pool_accounts, _new_referral_fee) = setup(None).await; + let (context, stake_pool_accounts, _new_referral_fee) = setup(None).await; let new_referral_fee = 110u8; let transaction = Transaction::new_signed_with_payer( @@ -198,7 +198,7 @@ async fn success_sol() { #[tokio::test] async fn fail_sol_wrong_manager() { - let (mut context, stake_pool_accounts, new_referral_fee) = setup(None).await; + let (context, stake_pool_accounts, new_referral_fee) = setup(None).await; let wrong_manager = Keypair::new(); let transaction = Transaction::new_signed_with_payer( @@ -231,7 +231,7 @@ async fn fail_sol_wrong_manager() { #[tokio::test] async fn fail_sol_high_referral_fee() { - let (mut context, stake_pool_accounts, _new_referral_fee) = setup(None).await; + let (context, stake_pool_accounts, _new_referral_fee) = setup(None).await; let new_referral_fee = 110u8; let transaction = Transaction::new_signed_with_payer( diff --git a/program/tests/set_staker.rs b/program/tests/set_staker.rs index bef7c883..d3dd61b4 100644 --- a/program/tests/set_staker.rs +++ b/program/tests/set_staker.rs @@ -112,8 +112,7 @@ async fn success_set_staker_as_staker() { #[tokio::test] async fn fail_wrong_manager() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_staker) = - setup().await; + let (banks_client, payer, recent_blockhash, stake_pool_accounts, new_staker) = setup().await; let mut transaction = Transaction::new_with_payer( &[instruction::set_staker( @@ -146,8 +145,7 @@ async fn fail_wrong_manager() { #[tokio::test] async fn fail_set_staker_without_signature() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, new_staker) = - setup().await; + let (banks_client, payer, recent_blockhash, stake_pool_accounts, new_staker) = setup().await; let data = borsh::to_vec(&instruction::StakePoolInstruction::SetStaker).unwrap(); let accounts = vec![ diff --git a/program/tests/set_withdrawal_fee.rs b/program/tests/set_withdrawal_fee.rs index b36ac693..4725685d 100644 --- a/program/tests/set_withdrawal_fee.rs +++ b/program/tests/set_withdrawal_fee.rs @@ -645,7 +645,7 @@ async fn success_increase_fee_from_0() { #[tokio::test] async fn fail_wrong_manager() { - let (mut context, stake_pool_accounts, new_stake_withdrawal_fee) = setup(None).await; + let (context, stake_pool_accounts, new_stake_withdrawal_fee) = setup(None).await; let wrong_manager = Keypair::new(); let transaction = Transaction::new_signed_with_payer( @@ -678,7 +678,7 @@ async fn fail_wrong_manager() { #[tokio::test] async fn fail_high_withdrawal_fee() { - let (mut context, stake_pool_accounts, _new_stake_withdrawal_fee) = setup(None).await; + let (context, stake_pool_accounts, _new_stake_withdrawal_fee) = setup(None).await; let new_stake_withdrawal_fee = Fee { numerator: 11, @@ -714,7 +714,7 @@ async fn fail_high_withdrawal_fee() { #[tokio::test] async fn fail_high_stake_fee_increase() { - let (mut context, stake_pool_accounts, _new_stake_withdrawal_fee) = setup(None).await; + let (context, stake_pool_accounts, _new_stake_withdrawal_fee) = setup(None).await; let new_withdrawal_fee = Fee { numerator: 46, denominator: 10_000, @@ -749,7 +749,7 @@ async fn fail_high_stake_fee_increase() { #[tokio::test] async fn fail_high_sol_fee_increase() { - let (mut context, stake_pool_accounts, _new_stake_withdrawal_fee) = setup(None).await; + let (context, stake_pool_accounts, _new_stake_withdrawal_fee) = setup(None).await; let new_withdrawal_fee = Fee { numerator: 46, denominator: 10_000, @@ -785,7 +785,7 @@ async fn fail_high_sol_fee_increase() { #[tokio::test] async fn fail_high_stake_fee_increase_from_0() { - let (mut context, stake_pool_accounts, _new_stake_withdrawal_fee) = setup(Some(Fee { + let (context, stake_pool_accounts, _new_stake_withdrawal_fee) = setup(Some(Fee { numerator: 0, denominator: 1, })) @@ -824,7 +824,7 @@ async fn fail_high_stake_fee_increase_from_0() { #[tokio::test] async fn fail_high_sol_fee_increase_from_0() { - let (mut context, stake_pool_accounts, _new_stake_withdrawal_fee) = setup(Some(Fee { + let (context, stake_pool_accounts, _new_stake_withdrawal_fee) = setup(Some(Fee { numerator: 0, denominator: 1, })) diff --git a/program/tests/update_pool_token_metadata.rs b/program/tests/update_pool_token_metadata.rs index efe30a96..898366c5 100644 --- a/program/tests/update_pool_token_metadata.rs +++ b/program/tests/update_pool_token_metadata.rs @@ -106,7 +106,7 @@ async fn success_update_pool_token_metadata() { #[tokio::test] async fn fail_manager_did_not_sign() { - let (mut context, stake_pool_accounts) = setup().await; + let (context, stake_pool_accounts) = setup().await; let updated_name = "updated_name"; let updated_symbol = "USYM"; @@ -149,7 +149,7 @@ async fn fail_manager_did_not_sign() { #[tokio::test] async fn fail_wrong_manager_signed() { - let (mut context, stake_pool_accounts) = setup().await; + let (context, stake_pool_accounts) = setup().await; let updated_name = "updated_name"; let updated_symbol = "USYM"; diff --git a/program/tests/vsa_add.rs b/program/tests/vsa_add.rs index 3016a28d..af6bd42e 100644 --- a/program/tests/vsa_add.rs +++ b/program/tests/vsa_add.rs @@ -145,7 +145,7 @@ async fn success() { #[tokio::test] async fn fail_with_wrong_validator_list_account() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = + let (banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = setup(1).await; let wrong_validator_list = Keypair::new(); @@ -228,7 +228,7 @@ async fn fail_double_add() { #[tokio::test] async fn fail_wrong_staker() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = + let (banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = setup(1).await; let malicious = Keypair::new(); @@ -269,7 +269,7 @@ async fn fail_wrong_staker() { #[tokio::test] async fn fail_without_signature() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = + let (banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = setup(1).await; let accounts = vec![ @@ -323,7 +323,7 @@ async fn fail_without_signature() { #[tokio::test] async fn fail_with_wrong_stake_program_id() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = + let (banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = setup(1).await; let wrong_stake_program = Pubkey::new_unique(); @@ -375,7 +375,7 @@ async fn fail_with_wrong_stake_program_id() { #[tokio::test] async fn fail_with_wrong_system_program_id() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = + let (banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = setup(1).await; let wrong_system_program = Pubkey::new_unique(); @@ -634,7 +634,7 @@ async fn fail_with_not_enough_reserve_lamports() { #[tokio::test] async fn fail_with_wrong_reserve() { - let (mut banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = + let (banks_client, payer, recent_blockhash, stake_pool_accounts, validator_stake) = setup(1).await; let wrong_reserve = Pubkey::new_unique(); diff --git a/program/tests/vsa_remove.rs b/program/tests/vsa_remove.rs index 46571865..9cfb5bde 100644 --- a/program/tests/vsa_remove.rs +++ b/program/tests/vsa_remove.rs @@ -121,7 +121,7 @@ async fn success() { #[tokio::test] async fn fail_with_wrong_stake_program_id() { - let (mut context, stake_pool_accounts, validator_stake) = setup().await; + let (context, stake_pool_accounts, validator_stake) = setup().await; let wrong_stake_program = Pubkey::new_unique(); @@ -168,7 +168,7 @@ async fn fail_with_wrong_stake_program_id() { #[tokio::test] async fn fail_with_wrong_validator_list_account() { - let (mut context, stake_pool_accounts, validator_stake) = setup().await; + let (context, stake_pool_accounts, validator_stake) = setup().await; let wrong_validator_list = Keypair::new(); @@ -297,7 +297,7 @@ async fn fail_double_remove() { #[tokio::test] async fn fail_wrong_staker() { - let (mut context, stake_pool_accounts, validator_stake) = setup().await; + let (context, stake_pool_accounts, validator_stake) = setup().await; let malicious = Keypair::new(); @@ -338,7 +338,7 @@ async fn fail_wrong_staker() { #[tokio::test] async fn fail_no_signature() { - let (mut context, stake_pool_accounts, validator_stake) = setup().await; + let (context, stake_pool_accounts, validator_stake) = setup().await; let accounts = vec![ AccountMeta::new(stake_pool_accounts.stake_pool.pubkey(), false), diff --git a/program/tests/withdraw.rs b/program/tests/withdraw.rs index 84401a1e..3420a039 100644 --- a/program/tests/withdraw.rs +++ b/program/tests/withdraw.rs @@ -260,7 +260,7 @@ async fn _success(token_program_id: Pubkey, test_type: SuccessTestType) { #[tokio::test] async fn fail_with_wrong_stake_program() { let ( - mut context, + context, stake_pool_accounts, validator_stake_account, deposit_info, @@ -363,7 +363,7 @@ async fn fail_with_wrong_withdraw_authority() { #[tokio::test] async fn fail_with_wrong_token_program_id() { let ( - mut context, + context, stake_pool_accounts, validator_stake_account, deposit_info, From e4a11afe1343c54e1564643eb21b5cb58b78cea4 Mon Sep 17 00:00:00 2001 From: Kevin Heavey Date: Thu, 31 Oct 2024 23:00:43 +0400 Subject: [PATCH 1044/1076] Extract spl-math-utils from spl-math (#7421) * extract math-utils from spl-math * newline * replace spl-math with spl-math-utils in spl-token-swap * remove now-unused deps from spl-math * remove spl-math from stake-pool deps (it was already unused) * fix math-utils dep in spl-token-swap-fuzz * moce crate dirs * make spl-math the library crate and spl-math-example the program crate --- program/Cargo.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index ad4c5c35..622f6f4a 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -22,9 +22,6 @@ serde = "1.0.214" serde_derive = "1.0.103" solana-program = "2.1.0" solana-security-txt = "1.1.1" -spl-math = { version = "0.3", path = "../../libraries/math", features = [ - "no-entrypoint", -] } spl-pod = { version = "0.4.0", path = "../../libraries/pod", features = [ "borsh", ] } From 770ed4514244338bda9a73e8fbef3e515eef88e5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 01:14:45 +0000 Subject: [PATCH 1045/1076] Publish spl-pod v0.5.0 --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 622f6f4a..48f3e804 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -22,7 +22,7 @@ serde = "1.0.214" serde_derive = "1.0.103" solana-program = "2.1.0" solana-security-txt = "1.1.1" -spl-pod = { version = "0.4.0", path = "../../libraries/pod", features = [ +spl-pod = { version = "0.5.0", path = "../../libraries/pod", features = [ "borsh", ] } spl-token-2022 = { version = "5.0.2", path = "../../token/program-2022", features = [ From 7a8aeedbfc277dd53d5ad48abf50c4a56278df38 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 12:16:08 +0100 Subject: [PATCH 1046/1076] build(deps-dev): bump @types/node from 22.8.5 to 22.8.6 (#7439) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.8.5 to 22.8.6. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index d547108c..1ed0edc4 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^12.1.1", "@types/bn.js": "^5.1.6", "@types/jest": "^29.5.14", - "@types/node": "^22.8.5", + "@types/node": "^22.8.6", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^8.4.0", "@typescript-eslint/parser": "^8.4.0", From f1f629e89191357e2dd87e503d5a9fc40e1d59c6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 14:18:27 +0000 Subject: [PATCH 1047/1076] Publish spl-associated-token-account-client v2.0.0 --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index af4834c6..3a0eb03b 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -26,7 +26,7 @@ solana-sdk = "2.1.0" spl-associated-token-account = { version = "=5.0.1", path = "../../associated-token-account/program", features = [ "no-entrypoint", ] } -spl-associated-token-account-client = { version = "=1.0.0", path = "../../associated-token-account/client" } +spl-associated-token-account-client = { version = "=2.0.0", path = "../../associated-token-account/client" } spl-stake-pool = { version = "=2.0.0", path = "../program", features = [ "no-entrypoint", ] } From 5f29e7c9b6614e5c58fa305332f7651e6fe4fa55 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 15:31:50 +0000 Subject: [PATCH 1048/1076] Publish spl-token v7.0.0 --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 3a0eb03b..ffede52c 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -30,7 +30,7 @@ spl-associated-token-account-client = { version = "=2.0.0", path = "../../associ spl-stake-pool = { version = "=2.0.0", path = "../program", features = [ "no-entrypoint", ] } -spl-token = { version = "=6.0", path = "../../token/program", features = [ +spl-token = { version = "=7.0", path = "../../token/program", features = [ "no-entrypoint", ] } bs58 = "0.5.1" diff --git a/program/Cargo.toml b/program/Cargo.toml index 48f3e804..ae89677f 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -37,7 +37,7 @@ proptest = "1.5" solana-program-test = "2.1.0" solana-sdk = "2.1.0" solana-vote-program = "2.1.0" -spl-token = { version = "6.0", path = "../../token/program", features = [ +spl-token = { version = "7.0", path = "../../token/program", features = [ "no-entrypoint", ] } test-case = "3.3" From 9074227ce688d4b50d0fb8ab4b7e8c4674017aa6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 17:49:26 +0000 Subject: [PATCH 1049/1076] Publish spl-token-2022 v6.0.0 --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index ae89677f..bebff565 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -25,7 +25,7 @@ solana-security-txt = "1.1.1" spl-pod = { version = "0.5.0", path = "../../libraries/pod", features = [ "borsh", ] } -spl-token-2022 = { version = "5.0.2", path = "../../token/program-2022", features = [ +spl-token-2022 = { version = "6.0.0", path = "../../token/program-2022", features = [ "no-entrypoint", ] } thiserror = "1.0" From 79b54b4bda6748bdc8605a4d3abb04167f3d3ec6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 18:22:57 +0000 Subject: [PATCH 1050/1076] Publish spl-associated-token-account v6.0.0 --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index ffede52c..2f4ec627 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -23,7 +23,7 @@ solana-logger = "2.1.0" solana-program = "2.1.0" solana-remote-wallet = "2.1.0" solana-sdk = "2.1.0" -spl-associated-token-account = { version = "=5.0.1", path = "../../associated-token-account/program", features = [ +spl-associated-token-account = { version = "=6.0.0", path = "../../associated-token-account/program", features = [ "no-entrypoint", ] } spl-associated-token-account-client = { version = "=2.0.0", path = "../../associated-token-account/client" } From a2020b8199a32fe34c205301181b8cfba14886b5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Nov 2024 12:46:00 +0100 Subject: [PATCH 1051/1076] build(deps-dev): bump rollup from 4.24.3 to 4.24.4 (#7454) Bumps [rollup](https://github.com/rollup/rollup) from 4.24.3 to 4.24.4. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.24.3...v4.24.4) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 1ed0edc4..5eafe670 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -69,7 +69,7 @@ "eslint": "^8.57.0", "jest": "^29.0.0", "rimraf": "^6.0.1", - "rollup": "^4.24.3", + "rollup": "^4.24.4", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.2.5", "typescript": "^5.6.3" From 60b5407b9ce048692ee617872da924960248135f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Nov 2024 13:00:06 +0100 Subject: [PATCH 1052/1076] build(deps-dev): bump @types/node from 22.8.6 to 22.8.7 (#7452) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.8.6 to 22.8.7. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 5eafe670..5107d9ed 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^12.1.1", "@types/bn.js": "^5.1.6", "@types/jest": "^29.5.14", - "@types/node": "^22.8.6", + "@types/node": "^22.8.7", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^8.4.0", "@typescript-eslint/parser": "^8.4.0", From c690c2b58a9d531b3c86627ad9eb3b24d3427c6f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Nov 2024 12:01:52 +0100 Subject: [PATCH 1053/1076] build(deps-dev): bump @types/node from 22.8.7 to 22.9.0 (#7459) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.8.7 to 22.9.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 5107d9ed..3fc2ee99 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^12.1.1", "@types/bn.js": "^5.1.6", "@types/jest": "^29.5.14", - "@types/node": "^22.8.7", + "@types/node": "^22.9.0", "@types/node-fetch": "^2.6.11", "@typescript-eslint/eslint-plugin": "^8.4.0", "@typescript-eslint/parser": "^8.4.0", From 289f8ababac3558bfb5c8aedd23389c9b2932d3d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Nov 2024 11:44:32 +0100 Subject: [PATCH 1054/1076] build(deps): bump thiserror from 1.0.68 to 2.0.0 (#7462) Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.68 to 2.0.0. - [Release notes](https://github.com/dtolnay/thiserror/releases) - [Commits](https://github.com/dtolnay/thiserror/compare/1.0.68...2.0.0) --- updated-dependencies: - dependency-name: thiserror dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index bebff565..3932014c 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -28,7 +28,7 @@ spl-pod = { version = "0.5.0", path = "../../libraries/pod", features = [ spl-token-2022 = { version = "6.0.0", path = "../../token/program-2022", features = [ "no-entrypoint", ] } -thiserror = "1.0" +thiserror = "2.0" bincode = "1.3.1" [dev-dependencies] From a3b0f4a50a3218de470928a902f6817485836c41 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 Nov 2024 12:45:20 +0100 Subject: [PATCH 1055/1076] build(deps): bump borsh from 1.5.1 to 1.5.2 (#7470) Bumps [borsh](https://github.com/near/borsh-rs) from 1.5.1 to 1.5.2. - [Release notes](https://github.com/near/borsh-rs/releases) - [Changelog](https://github.com/near/borsh-rs/blob/master/CHANGELOG.md) - [Commits](https://github.com/near/borsh-rs/compare/borsh-v1.5.1...borsh-v1.5.2) --- updated-dependencies: - dependency-name: borsh dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 2f4ec627..78ebf608 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/solana-labs/solana-program-library" version = "2.0.0" [dependencies] -borsh = "1.5.1" +borsh = "1.5.2" clap = "2.33.3" serde = "1.0.214" serde_derive = "1.0.130" diff --git a/program/Cargo.toml b/program/Cargo.toml index 3932014c..e6cf171b 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -13,7 +13,7 @@ test-sbf = [] [dependencies] arrayref = "0.3.9" -borsh = "1.5.1" +borsh = "1.5.2" bytemuck = "1.19" num-derive = "0.4" num-traits = "0.2" From a21609a1220d9b1e6ae22c45f83cfa403cf316bd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Nov 2024 15:21:28 +0100 Subject: [PATCH 1056/1076] build(deps-dev): bump rollup from 4.24.4 to 4.25.0 (#7483) Bumps [rollup](https://github.com/rollup/rollup) from 4.24.4 to 4.25.0. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.24.4...v4.25.0) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 3fc2ee99..e1f74add 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -69,7 +69,7 @@ "eslint": "^8.57.0", "jest": "^29.0.0", "rimraf": "^6.0.1", - "rollup": "^4.24.4", + "rollup": "^4.25.0", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.2.5", "typescript": "^5.6.3" From ca1730c485a2689e29e579c5a590a6d03e5bb2a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Nov 2024 11:41:55 +0100 Subject: [PATCH 1057/1076] build(deps): bump serde from 1.0.214 to 1.0.215 (#7485) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.214 to 1.0.215. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.214...v1.0.215) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 78ebf608..4dd74ccc 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -11,7 +11,7 @@ version = "2.0.0" [dependencies] borsh = "1.5.2" clap = "2.33.3" -serde = "1.0.214" +serde = "1.0.215" serde_derive = "1.0.130" serde_json = "1.0.132" solana-account-decoder = "2.1.0" diff --git a/program/Cargo.toml b/program/Cargo.toml index e6cf171b..07e44b50 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -18,7 +18,7 @@ bytemuck = "1.19" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.3" -serde = "1.0.214" +serde = "1.0.215" serde_derive = "1.0.103" solana-program = "2.1.0" solana-security-txt = "1.1.1" From c52eef993adcab195983a39ac4931de171dd761b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Nov 2024 11:42:07 +0100 Subject: [PATCH 1058/1076] build(deps-dev): bump @types/node-fetch from 2.6.11 to 2.6.12 (#7488) Bumps [@types/node-fetch](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node-fetch) from 2.6.11 to 2.6.12. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node-fetch) --- updated-dependencies: - dependency-name: "@types/node-fetch" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index e1f74add..bfc6153d 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -62,7 +62,7 @@ "@types/bn.js": "^5.1.6", "@types/jest": "^29.5.14", "@types/node": "^22.9.0", - "@types/node-fetch": "^2.6.11", + "@types/node-fetch": "^2.6.12", "@typescript-eslint/eslint-plugin": "^8.4.0", "@typescript-eslint/parser": "^8.4.0", "cross-env": "^7.0.3", From 9ca73c0c79560079b44c34eccbcba55d1a2ac792 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Nov 2024 13:00:15 +0100 Subject: [PATCH 1059/1076] build(deps-dev): bump rollup from 4.25.0 to 4.26.0 (#7490) Bumps [rollup](https://github.com/rollup/rollup) from 4.25.0 to 4.26.0. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.25.0...v4.26.0) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index bfc6153d..ce0aa31a 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -69,7 +69,7 @@ "eslint": "^8.57.0", "jest": "^29.0.0", "rimraf": "^6.0.1", - "rollup": "^4.25.0", + "rollup": "^4.26.0", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.2.5", "typescript": "^5.6.3" From 4ed7a155d23afff9dafd4eece92ddc0d7953c6ac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 11:35:40 +0100 Subject: [PATCH 1060/1076] build(deps): bump borsh from 1.5.2 to 1.5.3 (#7491) Bumps [borsh](https://github.com/near/borsh-rs) from 1.5.2 to 1.5.3. - [Release notes](https://github.com/near/borsh-rs/releases) - [Changelog](https://github.com/near/borsh-rs/blob/master/CHANGELOG.md) - [Commits](https://github.com/near/borsh-rs/compare/borsh-v1.5.2...borsh-v1.5.3) --- updated-dependencies: - dependency-name: borsh dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 4dd74ccc..795c5a74 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/solana-labs/solana-program-library" version = "2.0.0" [dependencies] -borsh = "1.5.2" +borsh = "1.5.3" clap = "2.33.3" serde = "1.0.215" serde_derive = "1.0.130" diff --git a/program/Cargo.toml b/program/Cargo.toml index 07e44b50..fb2623cb 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -13,7 +13,7 @@ test-sbf = [] [dependencies] arrayref = "0.3.9" -borsh = "1.5.2" +borsh = "1.5.3" bytemuck = "1.19" num-derive = "0.4" num-traits = "0.2" From cb8de49bb37037063c3578cd11df26f36f23eb13 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Nov 2024 12:52:03 +0100 Subject: [PATCH 1061/1076] build(deps-dev): bump rollup from 4.26.0 to 4.27.0 (#7494) Bumps [rollup](https://github.com/rollup/rollup) from 4.26.0 to 4.27.0. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.26.0...v4.27.0) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index ce0aa31a..a55ebcb9 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -69,7 +69,7 @@ "eslint": "^8.57.0", "jest": "^29.0.0", "rimraf": "^6.0.1", - "rollup": "^4.26.0", + "rollup": "^4.27.0", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.2.5", "typescript": "^5.6.3" From 48f4e47470038b13b594b2843dcaa1ce3ffb1939 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 11:40:08 +0100 Subject: [PATCH 1062/1076] build(deps): bump serde_json from 1.0.132 to 1.0.133 (#7497) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.132 to 1.0.133. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.132...v1.0.133) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 795c5a74..b6778822 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -13,7 +13,7 @@ borsh = "1.5.3" clap = "2.33.3" serde = "1.0.215" serde_derive = "1.0.130" -serde_json = "1.0.132" +serde_json = "1.0.133" solana-account-decoder = "2.1.0" solana-clap-utils = "2.1.0" solana-cli-config = "2.1.0" From 36d07357f4499e715920e3dce5fed2b171213e38 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 13:50:28 +0100 Subject: [PATCH 1063/1076] build(deps-dev): bump rollup from 4.27.0 to 4.27.2 (#7499) Bumps [rollup](https://github.com/rollup/rollup) from 4.27.0 to 4.27.2. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.27.0...v4.27.2) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index a55ebcb9..8f8581e2 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -69,7 +69,7 @@ "eslint": "^8.57.0", "jest": "^29.0.0", "rimraf": "^6.0.1", - "rollup": "^4.27.0", + "rollup": "^4.27.2", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.2.5", "typescript": "^5.6.3" From 1a26d086bb1951691ebb8d94dc9fafd96d4c26a0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Nov 2024 12:04:42 +0100 Subject: [PATCH 1064/1076] build(deps-dev): bump rollup from 4.27.2 to 4.27.3 (#7506) Bumps [rollup](https://github.com/rollup/rollup) from 4.27.2 to 4.27.3. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.27.2...v4.27.3) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 8f8581e2..9927f650 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -69,7 +69,7 @@ "eslint": "^8.57.0", "jest": "^29.0.0", "rimraf": "^6.0.1", - "rollup": "^4.27.2", + "rollup": "^4.27.3", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.2.5", "typescript": "^5.6.3" From a1caf92f6dd8875567f85f7bc92954c8a3d8b77c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 12:04:56 +0100 Subject: [PATCH 1065/1076] build(deps): bump bytemuck from 1.19.0 to 1.20.0 (#7507) Bumps [bytemuck](https://github.com/Lokathor/bytemuck) from 1.19.0 to 1.20.0. - [Changelog](https://github.com/Lokathor/bytemuck/blob/main/changelog.md) - [Commits](https://github.com/Lokathor/bytemuck/compare/v1.19.0...v1.20.0) --- updated-dependencies: - dependency-name: bytemuck dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- program/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index fb2623cb..0dc88584 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -14,7 +14,7 @@ test-sbf = [] [dependencies] arrayref = "0.3.9" borsh = "1.5.3" -bytemuck = "1.19" +bytemuck = "1.20" num-derive = "0.4" num-traits = "0.2" num_enum = "0.7.3" From c85998169eb297413b823ff060812db6ed38a766 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 12:05:04 +0100 Subject: [PATCH 1066/1076] build(deps-dev): bump @types/node from 22.9.0 to 22.9.1 (#7508) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.9.0 to 22.9.1. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 9927f650..e1f89bf0 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^12.1.1", "@types/bn.js": "^5.1.6", "@types/jest": "^29.5.14", - "@types/node": "^22.9.0", + "@types/node": "^22.9.1", "@types/node-fetch": "^2.6.12", "@typescript-eslint/eslint-plugin": "^8.4.0", "@typescript-eslint/parser": "^8.4.0", From 6b4bf1522cd6e26167106baf6c259663cc09970c Mon Sep 17 00:00:00 2001 From: Jon C Date: Wed, 20 Nov 2024 14:07:42 +0100 Subject: [PATCH 1067/1076] stake-pool: Downgrade dependencies for fixed release (#7509) #### Problem The current spl-stake-pool crate doesn't always work due to its dependency on spl-math which still uses the v1 Solana crates. #### Summary of changes Since the spl-math dependency wasn't actually needed, it was removed in #7421. So just to get a new patch release out, downgrade the local dependencies. This will fail CI, but after it lands we can tag the release, and revert this PR. --- program/Cargo.toml | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/program/Cargo.toml b/program/Cargo.toml index 0dc88584..f21bfb85 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "spl-stake-pool" -version = "2.0.0" +version = "2.0.1" description = "Solana Program Library Stake Pool" authors = ["Solana Labs Maintainers "] repository = "https://github.com/solana-labs/solana-program-library" @@ -20,12 +20,12 @@ num-traits = "0.2" num_enum = "0.7.3" serde = "1.0.215" serde_derive = "1.0.103" -solana-program = "2.1.0" +solana-program = "2.0.0" solana-security-txt = "1.1.1" -spl-pod = { version = "0.5.0", path = "../../libraries/pod", features = [ +spl-pod = { version = "0.3.0", features = [ "borsh", ] } -spl-token-2022 = { version = "6.0.0", path = "../../token/program-2022", features = [ +spl-token-2022 = { version = "4.0.0", features = [ "no-entrypoint", ] } thiserror = "2.0" @@ -34,16 +34,13 @@ bincode = "1.3.1" [dev-dependencies] assert_matches = "1.5.0" proptest = "1.5" -solana-program-test = "2.1.0" -solana-sdk = "2.1.0" -solana-vote-program = "2.1.0" -spl-token = { version = "7.0", path = "../../token/program", features = [ +solana-program-test = "2.0.0" +solana-sdk = "2.0.0" +solana-vote-program = "2.0.0" +spl-token = { version = "6.0", features = [ "no-entrypoint", ] } test-case = "3.3" [lib] crate-type = ["cdylib", "lib"] - -[lints] -workspace = true From 100e3f2e2f71b35cebe51d671da4e6ab0b319340 Mon Sep 17 00:00:00 2001 From: Jon C Date: Wed, 20 Nov 2024 14:26:22 +0100 Subject: [PATCH 1068/1076] Revert "stake-pool: Downgrade dependencies for fixed release (#7509)" (#7510) * Revert "stake-pool: Downgrade dependencies for fixed release (#7509)" This reverts commit 7971301908be9800fe1fdd44a1936459e86fcd73. * Bump version to v2.0.1 --- clients/cli/Cargo.toml | 2 +- program/Cargo.toml | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index b6778822..f6bb1e56 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -27,7 +27,7 @@ spl-associated-token-account = { version = "=6.0.0", path = "../../associated-to "no-entrypoint", ] } spl-associated-token-account-client = { version = "=2.0.0", path = "../../associated-token-account/client" } -spl-stake-pool = { version = "=2.0.0", path = "../program", features = [ +spl-stake-pool = { version = "=2.0.1", path = "../program", features = [ "no-entrypoint", ] } spl-token = { version = "=7.0", path = "../../token/program", features = [ diff --git a/program/Cargo.toml b/program/Cargo.toml index f21bfb85..b34fb69a 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -20,12 +20,12 @@ num-traits = "0.2" num_enum = "0.7.3" serde = "1.0.215" serde_derive = "1.0.103" -solana-program = "2.0.0" +solana-program = "2.1.0" solana-security-txt = "1.1.1" -spl-pod = { version = "0.3.0", features = [ +spl-pod = { version = "0.5.0", path = "../../libraries/pod", features = [ "borsh", ] } -spl-token-2022 = { version = "4.0.0", features = [ +spl-token-2022 = { version = "6.0.0", path = "../../token/program-2022", features = [ "no-entrypoint", ] } thiserror = "2.0" @@ -34,13 +34,16 @@ bincode = "1.3.1" [dev-dependencies] assert_matches = "1.5.0" proptest = "1.5" -solana-program-test = "2.0.0" -solana-sdk = "2.0.0" -solana-vote-program = "2.0.0" -spl-token = { version = "6.0", features = [ +solana-program-test = "2.1.0" +solana-sdk = "2.1.0" +solana-vote-program = "2.1.0" +spl-token = { version = "7.0", path = "../../token/program", features = [ "no-entrypoint", ] } test-case = "3.3" [lib] crate-type = ["cdylib", "lib"] + +[lints] +workspace = true From dbac9069e347ca049270962d093b35b48ce30bbf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Nov 2024 13:36:14 +0100 Subject: [PATCH 1069/1076] build(deps): bump @solana/web3.js from 1.95.4 to 1.95.5 (#7512) Bumps [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) from 1.95.4 to 1.95.5. - [Release notes](https://github.com/solana-labs/solana-web3.js/releases) - [Commits](https://github.com/solana-labs/solana-web3.js/compare/v1.95.4...v1.95.5) --- updated-dependencies: - dependency-name: "@solana/web3.js" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index e1f89bf0..f4504547 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -45,7 +45,7 @@ "dependencies": { "@solana/buffer-layout": "^4.0.1", "@solana/spl-token": "0.4.9", - "@solana/web3.js": "^1.95.4", + "@solana/web3.js": "^1.95.5", "bn.js": "^5.2.0", "buffer": "^6.0.3", "buffer-layout": "^1.2.2", From b64d5d21a56519c2ff6d3d5a3e8947e23042ceb0 Mon Sep 17 00:00:00 2001 From: Pavel Zaborskii Date: Sat, 23 Nov 2024 00:34:37 +0100 Subject: [PATCH 1070/1076] fix: typos in stake-pool comments and output messages (#7516) * Typo * Typo --- clients/cli/src/output.rs | 4 ++-- clients/py/stake_pool/instructions.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clients/cli/src/output.rs b/clients/cli/src/output.rs index 5eeb81bc..39d85a0b 100644 --- a/clients/cli/src/output.rs +++ b/clients/cli/src/output.rs @@ -116,7 +116,7 @@ impl VerboseDisplay for CliStakePool { match &self.preferred_withdraw_validator_vote_address { None => {} Some(s) => { - writeln!(w, "Preferred Withraw Validator: {}", s)?; + writeln!(w, "Preferred Withdraw Validator: {}", s)?; } } writeln!(w, "Epoch Fee: {} of epoch rewards", &self.epoch_fee)?; @@ -197,7 +197,7 @@ impl Display for CliStakePool { match &self.preferred_withdraw_validator_vote_address { None => {} Some(s) => { - writeln!(f, "Preferred Withraw Validator: {}", s)?; + writeln!(f, "Preferred Withdraw Validator: {}", s)?; } } writeln!(f, "Epoch Fee: {} of epoch rewards", &self.epoch_fee)?; diff --git a/clients/py/stake_pool/instructions.py b/clients/py/stake_pool/instructions.py index e5d9199c..493d2251 100644 --- a/clients/py/stake_pool/instructions.py +++ b/clients/py/stake_pool/instructions.py @@ -368,7 +368,7 @@ class WithdrawStakeParams(NamedTuple): validator_stake: Pubkey """`[w]` Validator or reserve stake account to split""" destination_stake: Pubkey - """`[w]` Unitialized stake account to receive withdrawal""" + """`[w]` Uninitialized stake account to receive withdrawal""" destination_stake_authority: Pubkey """`[]` User account to set as a new withdraw authority""" source_transfer_authority: Pubkey From f43c4cfe97caefd0f0c9a5f6481fb81cf4342248 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 14:31:55 +0100 Subject: [PATCH 1071/1076] build(deps-dev): bump rollup from 4.27.3 to 4.27.4 (#7519) Bumps [rollup](https://github.com/rollup/rollup) from 4.27.3 to 4.27.4. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.27.3...v4.27.4) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index f4504547..e1b6e7d1 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -69,7 +69,7 @@ "eslint": "^8.57.0", "jest": "^29.0.0", "rimraf": "^6.0.1", - "rollup": "^4.27.3", + "rollup": "^4.27.4", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.2.5", "typescript": "^5.6.3" From 78dd24662bba7831c261052ba0ca0f8e39e64f45 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 14:32:12 +0100 Subject: [PATCH 1072/1076] build(deps-dev): bump @types/node from 22.9.1 to 22.9.3 (#7522) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.9.1 to 22.9.3. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index e1b6e7d1..6c515fe6 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^12.1.1", "@types/bn.js": "^5.1.6", "@types/jest": "^29.5.14", - "@types/node": "^22.9.1", + "@types/node": "^22.9.3", "@types/node-fetch": "^2.6.12", "@typescript-eslint/eslint-plugin": "^8.4.0", "@typescript-eslint/parser": "^8.4.0", From 2778612155fd8d0a3a6c06c6d023926fb0243386 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 18:34:45 +0100 Subject: [PATCH 1073/1076] build(deps-dev): bump typescript from 5.6.3 to 5.7.2 (#7521) * build(deps-dev): bump typescript from 5.6.3 to 5.7.2 Bumps [typescript](https://github.com/microsoft/TypeScript) from 5.6.3 to 5.7.2. - [Release notes](https://github.com/microsoft/TypeScript/releases) - [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml) - [Commits](https://github.com/microsoft/TypeScript/compare/v5.6.3...v5.7.2) --- updated-dependencies: - dependency-name: typescript dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Fix build --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jon C --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 6c515fe6..8a334c2f 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -72,7 +72,7 @@ "rollup": "^4.27.4", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.2.5", - "typescript": "^5.6.3" + "typescript": "^5.7.2" }, "jest": { "moduleFileExtensions": [ From ece1ba2783740316ec81b552e5d21fb9a7976298 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Nov 2024 13:05:10 +0100 Subject: [PATCH 1074/1076] build(deps-dev): bump @types/node from 22.9.3 to 22.10.0 (#7534) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.9.3 to 22.10.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 8a334c2f..86f3918a 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^12.1.1", "@types/bn.js": "^5.1.6", "@types/jest": "^29.5.14", - "@types/node": "^22.9.3", + "@types/node": "^22.10.0", "@types/node-fetch": "^2.6.12", "@typescript-eslint/eslint-plugin": "^8.4.0", "@typescript-eslint/parser": "^8.4.0", From 525398c0a7a437a9500cb1e2ca60a768c4b7f274 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 Nov 2024 11:53:44 +0100 Subject: [PATCH 1075/1076] build(deps-dev): bump @types/node from 22.10.0 to 22.10.1 (#7544) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.10.0 to 22.10.1. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index 86f3918a..db27be53 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^12.1.1", "@types/bn.js": "^5.1.6", "@types/jest": "^29.5.14", - "@types/node": "^22.10.0", + "@types/node": "^22.10.1", "@types/node-fetch": "^2.6.12", "@typescript-eslint/eslint-plugin": "^8.4.0", "@typescript-eslint/parser": "^8.4.0", From bad67888d02bb8144b1d249c18ec9774abb408b0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 13:15:07 +0100 Subject: [PATCH 1076/1076] build(deps-dev): bump rollup from 4.27.4 to 4.28.0 (#7547) Bumps [rollup](https://github.com/rollup/rollup) from 4.27.4 to 4.28.0. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.27.4...v4.28.0) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/js-legacy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js-legacy/package.json b/clients/js-legacy/package.json index db27be53..04288746 100644 --- a/clients/js-legacy/package.json +++ b/clients/js-legacy/package.json @@ -69,7 +69,7 @@ "eslint": "^8.57.0", "jest": "^29.0.0", "rimraf": "^6.0.1", - "rollup": "^4.27.4", + "rollup": "^4.28.0", "rollup-plugin-dts": "^6.1.1", "ts-jest": "^29.2.5", "typescript": "^5.7.2"